로그 파일을 /dev/null에 연결하고 사용된 공간을 자동으로 복구하는 방법

로그 파일을 /dev/null에 연결하고 사용된 공간을 자동으로 복구하는 방법

매우 커지는 로그 파일이 있습니다. 내가 얻을 수 있는 정보는 미미합니다.

에 연결하고 싶습니다 /dev/null. 그러나 "제거"하더라도(아래 lsof 출력 참조) 하드 드라이브 공간을 모두 소모합니다.

다음을 사용하여 자를 수 있습니다.

: > "/proc/$pid/fd/$fd"
# for instance:
: > "/proc/2456/fd/2"

불행하게도 하드 드라이브가 가득 차면 시스템의 일부 프로세스가 일시 중지되어 수동으로 다시 시작해야 합니다(프로세스가 일시 중지되는 것을 방지하고 싶습니다).

파일이 너무 커지면(예: 1G 이상을 소비하는 경우) 자동으로 파일을 자르는 방법이 있나요?

lsof산출:

program  2456 user    2w   REG    8,5 441433300992     0 21365598 /home/user/file (deleted)

답변1

파일 내용은 해당 파일이 더 이상 참조되지 않는 경우에만 삭제됩니다. 파일에 대한 참조는 디렉터리 항목이거나 열린 파일 핸들일 수 있습니다. rm프로세스(여기서는 이를 기록한 프로세스)에 의해 아직 열려 있는(예: 명령 사용) 파일을 삭제하면 해당 프로세스가 파일을 닫을 때까지 파일 내용이 유지됩니다.

오래된 로그를 제거하는 가장 직접적인 방법은 다음과 같습니다.

  1. 파일을 다른 이름으로 이동하세요.mv foo.log foo.log.old
  2. 로그 파일을 다시 열도록 프로세스에 지시합니다. 프로세스가 이 작업을 수행할 수 없으면 다시 시작하십시오.
  3. 현재 닫힌 오래된 로그 파일을 삭제합니다( rm foo.log.old).

프로그램로그 회전이 메커니즘을 자동화하고 오래된 로그가 보존되는 일수를 구성합니다. 또한 오래된 로그를 압축할 수도 있습니다.

2단계에서 프로그램을 다시 시작할 수 없고 로그 파일을 다시 열 수 없는 경우 디버거를 사용하여 강제로 로그 파일을 다시 열 수 있습니다. 그러나 현재 일관성이 없는 로그 파일에 대한 정보가 프로그램에 남아 있으면 프로그램이 중단될 수 있다는 점에 유의하십시오. 개념 증명(많은 일이 잘못될 수 있다는 점에 유의하세요. 의심스러운 경우에는 이 작업을 수행하지 마세요):

gdb -n $pid -batch -x /dev/stdin <<EOF
call close(2)
call open("/path/to/foo.log", 1)
EOF

로그에 관심이 없는 경우 일부 디스크 공간을 확보하는 또 다른 대략적인 방법은 파일을 자르는 것입니다. 로깅 프로세스는 파일의 동일한 위치에 계속 기록되지만 파일은스파스 파일. 파일을 처음부터 읽으면 널 바이트를 얻게 되지만 이는 디스크에서 몇 kB만 차지합니다.

dd if=/dev/null of=/path/to/foo.log

답변2

program삭제된 파일을 해제하려면 다시 시작하세요 . 로그 데이터를 적절하게 관리하기 위해 조사 logrotate등을 실시하거나, 로그 메시지가 적게 나오도록 프로그램을 조정하세요.

답변3

파일을 삭제할 때 실제로는 "삭제"되지 않습니다. 연결을 해제하세요. 최종 결과는 로그 파일을 연 프로그램이 로그 파일이 닫힐 때까지 계속해서 로그 파일에 액세스할 수 있다는 것입니다(로그 파일의 경우 드문 일입니다).

이제 문제를 제대로 해결하려면 로그 회전 및 로그 필터링을 살펴봐야 합니다.

로그 순환을 사용하면 일련의 규칙에 따라 보관, 압축 및 삭제할 수 있습니다. 예를 들어, 1일보다 오래된 모든 항목은 압축되고 7일보다 오래된 모든 항목은 삭제됩니다.

로그 필터링은 단순히 로그에 들어가는 "항목"의 양을 줄입니다. 일부 프로그램은 프로그램 측에서 필터링을 구현하고 다른 프로그램은 로거 측에서 필터링을 구현합니다. 예를 들어, syslogd를 사용하는 경우 모든 항목에서 중요하지 않은 메시지를 필터링하도록 지시할 수 있습니다(예: 다시 말함).

문제를 신속하게 해결하려면 서비스를 다시 시작하고 매우 일반적인 신호 SIGUSR1 및 SIGHUP에 응답하는지 확인한 다음 해당 신호를 보내거나 컴퓨터를 다시 시작하십시오.

답변4

또는 로 출력하여 로그 파일이 stderr생성되고 로그 파일을 생성한 프로그램(우리가 부르는)이 시작되는 방법을 stdout제어할 수 있는 경우 모든 표준 출력 또는 오류 메시지가 /dev/null로 리디렉션됩니다.barbar &>/dev/null

또는 (이것이 정말 나쁜 습관이라는 것을 알고 있지만 적어도 작동할 것입니다) 로그를 생성한 프로그램을 종료하고 로그 파일을 삭제한 다음 프로그램 백업을 시작하는 시간별 크론 작업을 설정합니다. 시스템에 손상을 주지 않습니다. 실행이 중요합니다. 다시 프로그램 이름을 이라고 가정하면 bar, 이를 수행하는 방법은 입니다 echo "* 0 0 0 0 \"/bin/killall [offending program]; /bin/rm [offending log]; [command to run program];\" 1>[crontab location]".

대괄호는 자리 표시자를 나타내는 데 사용되며 입력한 명령에 표시되어서는 안 됩니다.

다시 한 번 말씀드리지만, 두 번째 해결책은 정말 나쁜 습관이며 전반적으로 붕대를 고치는 것일 뿐이므로 위험 부담은 본인이 감수하고 사용하세요.

관련 정보