표준 출력에서 많은 출력을 생성하는 장기 실행 명령이 있습니다. 예를 들어, 지난 3일 또는 지난 1GB만 보존하고(행이 중간에 잘리지 않도록) 가능하다면 파일 블록을 20MiB 이하로 보존하고 싶습니다. 각 파일 블록의 이름은 숫자 접미사 또는 타임스탬프로 지정됩니다.
그것은 다음과 같습니다:
my-cmd | magic-command --output-file-template=my-cmd-%t \
--keep-bytes=1G \
--keep-time=3d \
--max-chunk-size=20M \
--compress=xz
쓰다:
my-cmd-2014-09-05T10:04:23Z
20M에 도달하면 압축하고 새 파일을 여는 등 잠시 후 가장 오래된 파일을 삭제하기 시작합니다.
그런 명령이 존재합니까?
다른 애플리케이션에서 작성된 파일을 관리하는 기능이 있다는 것을 알고 있지만 logrotate
크론 작업 설정, 규칙 지정, 프로세스 일시 중지 등이 필요하지 않은 더 간단한 것을 찾고 있습니다.
답변1
당신은 당신이 원하는 것을 얻을 수 있습니다파이프라인 로그, 이는 "실행 중인 프로세스의 로그를 외부 신호에 응답하는 중간체를 통해 회전하거나 지울 수 있도록 허용합니다." 예를 들면 다음과 같습니다.
spewstuff | pipelog spew.log -p /tmp/spewpipe.pid -x "gzip spew.log.1"
그런 다음 및 에서 pid를 얻을 수 있습니다 /tmp/spewpipe.pid
.
kill -s USR1 $(</tmp/spewpipe.pid)
하지만 cron과 같은 것을 사용하여 설정해야 합니다. 그러나 문제가 있습니다. 참고하세요 gzip spew.log.1
. 이는 -x
로그 회전 후에 명령이 실행되기 때문입니다. 따라서 spew.log.1.gz
gzip을 수행하고 이후에 파일을 이동하는 짧은 스크립트를 작성하고 이를 명령으로 사용하지 않는 한 -x
덮어쓸 때마다 추가 문제가 발생합니다.
전체 공개: 제가 이것을 썼으므로 당연히 작동합니다.완벽한. ;) 버전 0.2의 경우 압축 옵션이나 더 나은 기능을 제공하는 옵션을 염두에 두겠습니다(의도한 목적은 -x
약간 다르지만 위와 같이 작동합니다). 자동 롤오버도 좋은 생각입니다... 첫 번째 버전은 불필요한 기능을 추가하려는 유혹에 저항했기 때문에 의도적으로 최소화되었습니다(결국 이를 위해 크론 작업을 설정하는 것은 그리 어렵지 않습니다).
그 목적은 다음과 같습니다.텍스트-z
출력; 잠재적인 null 바이트가 있는 경우 0을 다른 것으로 바꾸는 --를 사용해야 합니다 . 이는 구현을 단순화하기 위한 절충안입니다.
답변2
댄 번스타인의다중 로그파일 설명자를 통해 콘센트를 제공하면서 그렇게 하는 것이 분명히 가능합니다. 또는 대부분의 경우일 수도 있습니다.! 프로세서원하는 대로 차이점을 구성하세요. 20M/1G 크기 사양에는 약간의 부정 행위가 필요할 수 있지만 16M이 각 로그의 외부 한계인 것처럼 보입니다. 다음의 대부분은 위 링크에서 복사+붙여넣기를 선택하는 것입니다. 단, 해당 링크는 최신 행 일치 항목만 포함하는 추가 파일을 유지하는 행별 타임스탬프와 같은 다른 옵션도 자세히 설명합니다.무늬그리고 더.
상호 작용
multilog script
...스크립트다양한 매개변수로 구성됩니다. 각 매개변수는 작업을 지정합니다. 각 입력 줄에 대해 이러한 작업을 순차적으로 수행합니다.
라인 선택
각 행은 처음에 선택됩니다. 그 행동...
-pattern
...패턴이 행과 일치하는 경우 행을 선택 취소합니다. 그 행동...
+pattern
다음과 같은 경우 행을 선택하세요.무늬행과 일치합니다.
...무늬별과 별이 아닌 문자열입니다. 동일한 순서로 일치하는 모든 별표 및 별표가 아닌 문자로 구성된 모든 문자열 연결과 일치합니다. 별이 아닌 사람들은 자신과 일치합니다. 패턴 끝 앞의 별표는 패턴의 다음 문자를 포함하지 않는 모든 문자열과 일치합니다. 패턴 끝에 있는 별표는 모든 문자열과 일치합니다.
로그 자동 순환
만약에목차점이나 슬래시로 시작한 다음...
dir
...선택한 각 행을 다음 이름의 로그에 추가합니다.목차. 만약에목차존재하지 않는 경우 multilog
작성하십시오.
로그 형식은 다음과 같습니다.
목차특정 개수의 오래된 로그 파일이 포함된 디렉터리입니다. 로그 파일의 이름은 다음과 같습니다.현재의
multilog
및 작업을 추적하는 데 사용되는 기타 파일입니다.각 이전 로그 파일의 이름은 다음으로 끝납니다.@, 파일이 완료된 정확한 타임스탬프를 표시하고 다음 코드 중 하나로 끝납니다.
- .에스: 이 파일은 완전히 처리되어 디스크에 안전하게 기록되었습니다.
- .유: 이 파일은 중단 당시 생성되었습니다. 잘렸을 수도 있습니다. 아직 처리되지 않았습니다.
그 행동...
ssize
...이후 최대 파일 크기 설정목차행동. multilog
결정할 것이다현재의그렇다면 충분히 크다현재의가지다크기바이트.( multilog
또한 최대 파일 크기의 2000바이트 이내에서 개행 문자가 보이면 current가 충분히 큰 것으로 판단합니다. 라인 경계에서 로그 파일을 완성하려고 시도합니다.)4096에서 16777215 사이여야 합니다. 기본 최대 파일 크기는 99999입니다.
0.75 이상: multilog
받은 경우경보신호를 보내면 즉시 결정됩니다.현재의그렇다면 충분히 크다현재의비어 있지 않습니다.
(참고: 원하는 경우 지정된 간격으로 전송 zsh
schedule
하도록 내장 기능을 쉽게 설득할 수 있을 것으로 생각됩니다.)ALRM
그 행동...
nnum
...후속 로그 파일 수 설정목차행동. 이름을 바꾼 후현재의, multilog
네가 본다면일련번호또는 더 많은 오래된 로그 파일을 사용하면 타임스탬프가 가장 작은 오래된 로그 파일이 삭제됩니다.일련번호2개 이상이어야 합니다. 기본 로그 파일 수는 10입니다.
그 행동...
!processor
...다음 작업을 위해 프로세서를 설정합니다.목차행동. multilog
먹일 수 있다현재의통과하다프로세서출력을 대신 이전 로그 파일로 저장합니다.현재의. multilog
프로세서가 설명자 5에 쓴 모든 출력은 프로세서가 다음 로그 파일에서 실행될 때 설명자 4에서 저장되고 읽을 수 있게 됩니다. 신뢰성을 위해,프로세서출력을 생성하는 동안 문제가 발생하면 0이 아닌 값으로 종료해야 합니다. multilog
그런 다음 다시 실행됩니다. 실행중이니 참고하세요프로세서프로그램이 입력을 제공하지 못하게 할 수 있습니다 multilog
.
답변3
다음은 귀하가 요청한 것과 같은 작업을 수행하도록 수정된 Python 스크립트입니다.
#!/bin/sh
''':'
exec python "$0" "$@"
'''
KEEP = 10
MAX_SIZE = 1024 # bytes
LOG_BASE_NAME = 'log'
from sys import stdin
from subprocess import call
log_num = 0
log_size = 0
log_name = LOG_BASE_NAME + '.' + str(log_num)
log_fh = open(log_name, 'w', 1)
while True:
line = stdin.readline()
if len(line) == 0:
log_fh.close()
call(['gzip', '-f', log_name])
break
log_fh.write(line)
log_size += len(line)
if log_size >= MAX_SIZE:
log_fh.close()
call(['gzip', '-f', log_name])
if log_num < KEEP:
log_num += 1
else:
log_num = 0
log_size = 0
log_name = LOG_BASE_NAME + '.' + str(log_num)
log_fh = open(log_name, 'w', 1)
답변4
systemd가 있는 Linux에서는 루트 권한이 있으면 전용통나무예. LogNamespace=
유닛 파일에 있어야 합니다.
/etc/systemd/[email protected]
:
[Journal]
Storage=volatile
RuntimeMaxUse=20M
/etc/systemd/system/myprogram.service
:
[Unit]
Description=My Test Service
[Service]
ExecStart=/home/myuser/myprogram
LogNamespace=myprogram
User=myuser
_
systemctl daemon-reload
systemctl start myprogram
journalctl --namespace=myprogram --follow
바라보다https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html#Journal%20Namespaces