우리 시스템 중 하나에 점점 늘어나는 로그 파일(이 문제를 해결하겠습니다)이 있지만 현재 애플리케이션 소유자는 파일을 삭제한 후 rm
다음 유지 관리 기간이 다시 시작될 때까지 기다립니다. 다음 유지 관리 기간은 몇 주 남았으며 디스크 사용률은 100%입니다.
아래 지침을 따르십시오.이 게시물파일을 찾아서 잘랐습니다. 이제 문제는 프로그램/프로세스가 어디에도 로그를 작성하지 않는 것 같다는 것입니다. 이 프로세스에서 이전 파일 사용을 중지하고 "새 파일" 사용을 시작하는 가장 좋은 방법은 무엇입니까?
# find /proc/*/fd -ls | grep '(deleted)'|grep path
112567191 0 l-wx------ 1 user1 group1 64 Feb 20 14:10 /proc/27312/fd/2 -> /path/file.log\ (deleted)
# > "/proc/27312/fd/2"
# find /proc/*/fd -ls | grep '(deleted)'|grep path
112567191 0 l-wx------ 1 user1 group1 64 Feb 20 14:10 /proc/27312/fd/2 -> /path/file.log\ (deleted)
# stat /path/file.log
File: ‘/path/file.log’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 811h/2065d Inode: 2890717 Links: 1
Access: (0644/-rw-r--r--) Uid: (54322/loc_psoft) Gid: (54321/oinstall)
Context: unconfined_u:object_r:unlabeled_t:s0
Access: 2019-02-20 12:44:42.738686325 -0500
Modify: 2019-02-08 11:38:19.741494973 -0500
Change: 2019-02-08 11:38:19.741494973 -0500
Birth: -
# stat /proc/27312/fd/2
File: ‘/proc/27312/fd/2’ -> ‘/path/file.log (deleted)’
Size: 64 Blocks: 0 IO Block: 1024 symbolic link
Device: 3h/3d Inode: 112567191 Links: 1
Access: (0300/l-wx------) Uid: (54322/loc_psoft) Gid: (54321/oinstall)
Context: unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
Access: 2019-02-20 14:10:45.155518866 -0500
Modify: 2019-02-20 14:10:45.154518886 -0500
Change: 2019-02-20 14:10:45.154518886 -0500
Birth: -
현재는 디스크 공간 문제가 없으며 로그가 기록되지 않는 문제만 있습니다.
업데이트 1:
PID는 를 사용하여 찾을 수 lsof +L1|grep $path
있으며 "hold" 파일 경로에도 있습니다 proc/$PID/fd/N
. 나는 의사결정자에게 혼란 init 6
을 kill 1 $PID
. 나는 이 문제를 다른 곳에서 재현하려고 노력하고 여기에 내가 파헤친 몇 가지 제안을 제시할 것입니다.
답변1
해당 프로그램을 변경하거나 다시 시작해야 합니다.
무슨 일이 일어나고 있는 지는 프로그램이 로그에 쓰기 위해 파일 핸들을 열고 그 동안 동일한 파일 핸들을 열어 두는 것입니다. 설명한 대로 파일이 삭제되면 해당 파일은 "일시 중지"되며 파일 핸들이 닫힐 때까지 실제로 계속 기록됩니다.
프로그램을 (의사 코드)로 변경할 수 있는 경우:
LogFileHandle = OpenFileHandle( Logfile, 'wa' )
UpdateLog( log_entry ) {
LogFileHandle.Write( log_entry )
}
do_literally_everything_forever()
LogFileHandle.Close()
(의사 코드):
UpdateLog( log_entry ) {
LogFileHandle = OpenFileHandle( Logfile, 'wa' )
LogFileHandle.Write( log_entry )
LogFileHandle.Close()
}
do_literally_everything_forever()
이렇게 하면 문제가 해결됩니다.
그렇게 할 수 없는 경우 전체 시스템을 재부팅할 필요가 없습니다. rm
열린 파일 핸들이 있는 모든 프로세스가 닫히면(더 구체적으로 해당 파일 핸들이 닫히면) 편집된 파일이 실제로 사라지게 됩니다.
대부분의 잘 작성된 데몬은 SIGHUP이 전송되면 실수로 파일 핸들을 반복합니다(프로그램 설명서를 읽어보세요!). 그러나 단순히 프로그램을 중지(또는 종료)하고 다시 시작하면 열려 있는 모든 파일 핸들도 해제됩니다.
답변2
디버거를 사용하여 프로세스에 연결하고 파일 설명자 2를 다른 곳으로 강제로 리디렉션할 수 있습니다.
gdb -batch -p PID -ex 'p $f=open("/path/to/log", 01101, 0666), dup2($f, 2), close($f)'
리디렉션되어야 하는 프로세스 및 fd2(stderr) PID
파일로 바꾸십시오 . 예 . 프로세스의 umask가 잘못된 경우 권한을 더 제한적인 것으로 변경할 수 있습니다. 프로세스가 버퍼링 중일 수 있으며 해당 출력이 stderr 리디렉션 파일에 즉시 나타나지 않을 수 있습니다.pid
"/path/to/log"
01101
O_WRONLY|O_CREAT|O_TRUNC
0666
이것은 해킹입니다.청소년MMV.
답변3
근본적인 문제는 삭제 후 파일의 inode가 로그를 작성하는 소프트웨어에서 사용하는 것과 동일하다는 것입니다. 파일을 복원하는 것은 쉽지만 새 inode가 포함된 새 파일이 생성되고 프로세스가 계속해서 원본 파일에 기록됩니다. 로깅 프로그램이 삭제된 파일을 닫고 새 파일을 사용하기 시작하도록 inode를 교환하는 방법을 찾지 못했습니다. 그렇기 때문에 프로세스를 종료하거나 다시 시작해야 합니다.
임시 해결책으로는 현재 컨텍스트를 /proc/$PID/fd/#
원래 로그 위치에 복사하는 것이 가장 좋은 해결책인 것 같습니다. @mosvy가 제안한 솔루션을 시도한 후 다른 방법을 찾았습니다.
# nohup tail -c +0 -f /proc/$PID/fd/# > /path/file.log &
반복되는 두 참조 중 하나는 다음에서 나옵니다.Linux.com발생하는 상황과 정적 파일을 복원하는 방법을 다룹니다. 두 번째는 이 글에서 인용한 것입니다.뿌리우편 엽서.
답변4
애플리케이션 서비스를 다시 시작할 수 있나요? 그렇다면 다시 시작해 보셨나요? 그러면 이전 PID가 해제되고 새 PID가 생성됩니다.
이렇게 하면 애플리케이션 서비스도 재설정되어야 하며 위 파일에 로그를 기록해야 한다고 생각합니다.