활성 로그 파일에서 첫 번째 N 줄 제거


26

N응용 프로그램이 적극적으로 추가하는 로그에서 첫 번째 줄 을 제거하는 방법이 있습니까?

답변:


10

아니요, Linux와 같은 운영 체제 및 파일 시스템은 파일 시작 부분에서 데이터를 제거 할 준비를하지 않습니다. 즉, 파일의 저장 시작점이 고정되어 있습니다.

파일의 시작 부분에서 줄을 제거하는 것은 일반적으로 나머지 데이터를 새 파일에 쓰고 이전 파일을 삭제하여 수행됩니다. 프로그램에 쓰기 위해 이전 파일이 열려 있으면 응용 프로그램이 파일을 닫을 때까지 해당 파일의 삭제가 연기됩니다.


주석가가 언급했듯이, 이전 문장에서 주어진 이유로 인해, 일반적으로 로그를 작성하는 프로그램과 함께 로그 파일 정리를 조정해야합니다. 정확한 방법은 프로그램에 따라 다릅니다. 일부 프로그램은 신호를 보낼 때 로그 파일을 닫았다가 다시 엽니 다 (예 : HUP). 이는 서비스 중단없이 로그 레코드가 '삭제 된'로그 파일에 기록되지 않도록하는 데 사용될 수 있습니다.

로그 파일의 크기를 관리하는 데 사용할 수있는 많은 유틸리티가 있습니다 (예 : logrotate).

일부 프로그램에는 자체 유틸리티가 있습니다. 예를 들어 Apache 웹 서버에는 rotatelogs 유틸리티가 포함되어 있습니다.


3
그러나 아직 삭제 된 파일에 쓰기 때문에 로그 파일을 잃어 버리기 때문에 파일에 여전히 파일이 열려 있고 추가되어있는 동안에는이 작업을 수행하지 않아야합니다.
Tarnay Kálmán

참된. 동일한 파일 이름을 사용하더라도
Hennes

너무 나쁜 OS는 당신을 못하게합니다, 그것은 로그 로터가 회전 후 프로세스를 다시로드 할 필요가 없다는 것을 확신합니다 : |
rogerdpack

25

나는이 작업을 수행 할 수 있다고 생각 sed

sed -i '1,10d' myfile

1 라인 제거 할 일을 10에 선 형태의 파일을.

나는 모든 사람이 적어도이 sed 1 강선을 봐야한다고 생각한다 .

응용 프로그램이 적극적으로 추가하는 로그 파일 (질문에 설명 된대로)에는이 기능이 작동하지 않습니다.

sed -i새 파일을 작성하고 작성중인 파일을 '삭제'합니다. 대부분의 응용 프로그램은 삭제 된 로그 파일에 로그 레코드를 계속 쓰고 디스크 공간을 계속 채 웁니다. 새로운 잘린 로그 파일은 추가되지 않습니다. 응용 프로그램이 다시 시작되거나 로그 파일을 닫았다가 다시 열어야하는 경우에만 중단됩니다. sed 사용과 응용 프로그램 재시작 사이에 기록 가능한 활동이있는 경우 새 로그 파일에 갭 (로그 기록 누락)이 발생합니다.

이렇게하는 안전한 방법은 응용 프로그램을 중지하고 sed를 사용하여 로그를 자른 다음 응용 프로그램을 다시 시작하는 것입니다. 이 접근 방식은 일부 서비스 (예 : 처리량이 높고 서비스 연속성 요구 사항이 높은 웹 서버)에 적합하지 않을 수 있습니다.


2
추가중인 응용 프로그램에 어떤 일이 발생하는지 알고 있습니까?
Adam Matan

1
줄을 추가하고 매번 플러시하는 일반적인 열린 파일 핸들러를 가정 해 봅시다.
Adam Matan

1
나는 sed를 둘러싼 길을 알고 있으며 새 파일로 줄을 추출하는 것은 sed를 사용하는 것은 쉬운 일이 아닙니다. 문제는 모두 같은 파일에 보관하는 것입니다.
Adam Matan

10
아니요, 작동하지 않아야합니다. 편집 된 내용 sed -i으로 새 파일 을 작성하고 이전 파일 을 제거하여 활성 파일을 편집하지 않습니다. $ ls -i --- 6823554 testfile --- $ sed -i 's/test/final/' testfile --- $ ls -i --- 6823560 testfile------ sed -i작동 방식을 확인하십시오 . 왜이 잘못된 답변에 많은 투표가 있습니까?
pabouk

1
이 질문은 "응용 프로그램에 의해 적극적으로 추가되고있는 로그에서"를 나타냅니다. 수술 단어는 "능동적"입니다. 아마도 당신의 대답이 나타난 후에 설명이 추가되었을 것입니다. 그러나 그것이 의미하는 바와 같이, "가장 많이 찬성"하는 것을 좋아하는 독자들은 오도 될 것입니다. 한 번만 공감할 수있었습니다.
Scott Prive

5

아니요. 로그 파일 증가의 일반적인 문제에 대한 해결책은 로그 순환입니다. 여기에는 기존 로그 파일을 다른 파일 이름으로 정기적으로 (일반적으로 매일 또는 매주) 이동하고 빈 로그 파일로 새로 시작하는 작업이 포함됩니다. 일정 기간이 지나면 이전 로그 파일이 삭제됩니다.

참조 : http://www-uxsup.csx.cam.ac.uk/~jw35/courses/apache/html/x1670.htm


2

이것은 해결책 이 아니라 대답 입니다. 이 문제에 대한 해결책은 없습니다. 이 asker 는 "응용 프로그램 이 적극적으로 추가 하는 로그에서"라고 명확하게 표시 합니다. 이 코드가 로깅 모범 사례를 따르지 않는 이유를 추측 하여 더 많이 이해하고 끝까지 건너 뛸 수 있습니다.

분명히 : 여기에 다른 "답변"은 잘못된 약속을 제공합니다 . 이름을 바꾸지 않아도 새 파일을 사용하도록 응용 프로그램을 속일 수는 없습니다. 가장 유용한 정보는 이러한 잘못된 답변에 대한 의견에 묻혀 있습니다.

ACTIVE 파일은 단순히 데이터를 넣는 일종의 컨테이너가 아닙니다. 파일 이름은 ONE inode (파일 시작)를 가리키고 모든 inode에는 다른 inode에 대한 포인터가 있습니다 (데이터가 더있는 경우). 즉, 지속적으로 기록 된 파일에는 일정한 inode 스트림이 추가되고 "파일"이라고 생각하는 것은 실제로 inode의 로그 시퀀스입니다.

Google지도에서 누군가를 추적하고 있고 그 사람이 언제 어디서나 전 세계로 순간 이동할 수 있으며이 점들을 연결하려고한다고 상상해보십시오.

리눅스 툴 "잘라 내기 (truncate)"는 파일의 끝에서 단순히 inode 트리를 걸어서 데이터를 버릴 수 있으며 (지정한 위치 / 크기에서) 스택의 모든 후속 포인터를 버립니다. 역으로 파일을 시작할 때 데이터를 버리는 것은 아이 노드 트리 를 실시간 으로 재 작성하는 끔찍하게 복잡하고 위험한 과정 일 것입니다. 데이터 손실. 위키 아이 노드 짧은 그러나이 개념을 설명합니다.

** 내 충고 :이 문제를 뒤집어 라-왜이 응용 프로그램이 이런 식으로 작동합니까? 로깅 모범 사례가 많이 있지만 로깅 시스템의 실제 상태 (syslog 등)와 관련이있는 경우가 많습니다. 핵심에서 응용 프로그램은 파일에 대한 핸들을 "릴리스"해야하므로 logrotate 등은 이전 데이터의 추가 처리를 처리 할 수 ​​있습니다.

"ACTIVE logfile"을들을 때마다 즉시이 사람에게이 응용 프로그램의 "특별한 이야기"를 말해달라고 요청합니다. 일반적으로 "개발자는 종료하고 코드를 변경할 수 없습니다. 이것은 실제로 안전의 역순이며 자체 위험이 있습니다. 그러나 소스 코드를 건드리지 않는 솔루션을 원합니다. 더 구체적인 질문이 필요합니다.


0

숭고한 텍스트로 열기 파일을 추가하더라도 줄을 삭제하고 파일을 저장하면 어떻게 든 작동하지만 명령 줄 솔루션에 대한 솔루션을 찾기 위해 여기에 왔으므로 여기서는 작동하지만 쓸모없는 솔루션을 남겨 둘 것입니다 !!


-1

어쩌면 복사, 자르기, 복사본을 size = 0 잘라내기로 다시 붙이고 복사본을 삭제 하시겠습니까?

꼬리에서 꼬리까지 복사하는 것이 더 좋으며 원본을 잘라 내고 꼬리를 복사하여 원본으로 만듭니다.

꼬리 길이의 로그에 줄이 있으므로 바이트 길이 제한보다 낫습니다.

의견의 수정 사항 :

먼저 Python3에는 원하는 로거 스크립트가 있습니다.

from time import sleep

idx = 0
while 1 == 1:
    idx = (idx + 1)
    lf = open('tailTrunc.log', 'a')
    lf.write("line to file " + str(idx) + '\n')
    lf.close()
    sleep(0.01)

그런 다음 우리는 잘게 썹니다

#!/usr/bin/env bash

trap "kill 0" EXIT

rm tailTrunc.log
touch tailTrunc.log

python3 logLoop.py &
loggerPID=$!
sleep 1

kill -STOP $loggerPID
tail -10 tailTrunc.log > trimEnd.log
truncate -s 0 tailTrunc.log
kill -CONT $loggerPID
sleep 1

trimEnd.log는 80 ~ 89를 보여줍니다.

로그에 90이 표시됩니다

어쨌든 의지가있는 곳에 방법이 있습니다.

통합 자의 가장 복잡한 예와 쓰기 스트림이 열리거나 닫히는 방법은 CPU 코어 등을 조정해야 할 수도 있습니다. 로깅 프로세스 등의 로거에서 가능하면 쓰기를 일시 중지하고 대기하십시오.


"응용 프로그램이 적극적으로 추가하는 로그에서" 솔루션에서 간과하는 문제는 응용 프로그램에서 로그 파일을 "영구적으로"사용하고 있다는 것입니다. 즉, 로그 파일의 inode가 계속 작동한다는 의미입니다. 솔루션이 로그 파일 데이터를 "백업"하므로이 질문 이외의 용도로 사용될 수 있습니다.
Scott Prive

귀하의 의견과 투표에 감사드립니다. 나는 당신이 당신의 상황에 대해 더 깊이 생각해야 할 것이지만, 의지가있는 곳에 방법이 있다는 생각을위한 음식으로 빠르고 저렴한 예를 수정했습니다.
마스터 제임스

그것이 내 투표라고 생각하지는 않지만 다른 대답의 의견에 요점이 있다고 생각합니다. 로그 파일을 복사하면 더 이상 활성 로그 파일이 아닙니다. 응용 프로그램의 파일 핸들은 항상 원래 로그 파일의 inode를 가리 킵니다. 비표준 로깅 기능을 사용하고 열려있는 파일에 바이트를 계속 추가하는 응용 프로그램이 있습니다.
Scott Prive

1
유감스럽게 생각합니다. 예, inode는 동일한 예를 유지해야합니다. 왜냐하면 주어진 예제 / 증명이 잘리는 것을 사용하고 다시 상황에 따라 다릅니다 (모두 옵션이 일반 사이트에 숨겨져 있음).
마스터 제임스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.