[server] FIFO를 통해 로그인 한 다음 파일로 리디렉션 하시겠습니까?

각 트랜잭션을 기록해야하는 응용 프로그램이 있습니다. 충돌을 일으키는 원인에 대한 기록이 필요하기 때문에 모든 로그 메시지가 플러시됩니다. 동료들과 나는 로그 메시지가 프로세스를 벗어나도록 보장하면서 버퍼링의 성능 효과를 얻는 방법에 대해 궁금했습니다.

우리가 생각 해낸 것은 :

  • 응용 프로그램이 쓸 수있는 FIFO를 만들고
  • 를 통해 해당 FIFO의 내용을 일반 파일로 리디렉션합니다 cat.

즉, 일반적으로 무엇입니까 :

app --logfile logfile.txt

지금 :

mkfifo logfifo
cat logfifo &> logfile.txt &
app --logfile logfifo

이 접근 방식에 문제가 있습니까? 테스트 할 때 효과가 있었지만 원래 응용 프로그램이 충돌하더라도 메시지가 경로 재 지정 파일로 이동하는지 확인하고 싶습니다.

(우리는 응용 프로그램에 대한 소스 코드가 없으므로 프로그래밍 솔루션에 대해서는 의문의 여지가 없습니다. 또한 응용 프로그램에 쓰지 stdout않으므로 다른 명령에 직접 파이핑하는 것은 문제 syslog가 아닙니다 . .)


업데이트 : 현상금을 추가했습니다. 허용 대답은 할 수 없습니다 포함 logger간단한의 이유 logger입니다 하지 나에 대해 질문 한 내용. 원래 질문에서 알 수 있듯이 FIFO를 사용할 때만 문제를 찾고 있습니다.



답변

fifo는 일반적으로 쓰여진 양이 읽은 양을 초과 할 수있는 프로그래밍에 필요합니다.

이러한 fifo는 예상대로 완벽하게 작동하지 않지만 다른 문제를 소개하면서 주요 문제를 해결할 것입니다.

세 가지 가능한 경고가 있습니다.

  1. 초기화시 다른 쪽 끝을 읽는 것이 없으면 fifo에 쓰기가 무기한 차단됩니다.
  2. fifo의 고정 폭은 64K로, 버퍼가 해당 지점에 의해 채워지면 리더가 따라 올 때까지 추가 쓰기가 차단됩니다.
  3. 독자가 죽거나 나가면 파이프 라이터는 SIGPIPE로 사망합니다.

이는 문제 (버퍼링되지 않은 쓰기에서 버퍼링 된 I / O 에뮬레이션)가 해결됨을 의미합니다. 이는 FIFO의 새로운 ‘제한’이 실제로 파이프에 디스크에있는 내용 (버퍼 입출력이 버퍼링 됨)에 쓰는 유틸리티의 속도가되기 때문입니다.

그럼에도 불구하고 기록기는 작동하기 위해 로그 리더에 의존합니다. 독자가 갑자기 읽는 것을 멈 추면 작가가 차단합니다. 판독기가 갑자기 종료되면 (대상의 디스크 공간이 부족하다고 말하면) 기록기가 SIGPIPE하고 종료 될 수 있습니다.

언급해야 할 또 다른 요점은 서버 패닉과 커널의 응답이 중지되면 해당 버퍼에있는 최대 64k의 데이터가 손실 될 수 있다는 것입니다.

이 문제를 해결하는 또 다른 방법은 로그를 tmpfs (Linux의 경우 / dev / shm)에 기록하고 출력을 고정 디스크 위치에 맞추는 것입니다. 이 작업을 수행하는 메모리 할당에는 제한이 적지 만 (64K가 아니라 일반적으로 2G!) 기록기가 동적으로 로그 파일을 다시 열 수있는 방법이없는 경우에는 작동하지 않을 수 있습니다 (tmpfs에서 정기적으로 로그를 정리해야 함). 이 방법으로 서버 패닉이 발생하면 많은 데이터가 손실 될 수 있습니다.


답변

mkfifo logfifo
cat logfifo &> logfile.txt &
app --logfile logfifo

당신하면 어떻게됩니까 cat logfifo프로세스 다이, 누군가가 사고를 죽이고, 또는 누군가가 실수로 잘못된 위치에 포인트?

내 경험은 app의지가 빨리 막히고 멈추는 것입니다. Tomcat, Apache 및 몇 가지 작은 자체 빌드 응용 프로그램 으로이 작업을 시도했지만 동일한 문제가 발생했습니다. logger간단한 I / O 리디렉션이 원하는 것을 수행 했기 때문에 나는 결코 멀리 조사 하지 않았습니다. 나는 보통 로깅 완성도가 필요하지 않습니다. 이것은 당신이 추구하는 것입니다. 그리고 당신이 말하는 것처럼, 당신은 로거를 원하지 않습니다.

Linux 비 차단 fifo (온 디맨드 로깅) 에서이 문제에 대한 논의가 있습니다 .


답변

옵션은 앱에 의해 상당히 제한적이지만 테스트 한 기능이 작동합니다.

우리는 유용한 로그를 얻기 위해 varnish 및 varnishncsa와 비슷한 것을 수행합니다. 우리는 fifo를 가지고 있으며 syslog-ng로 그것을 읽고 필요한 곳에 보냅니다. 우리는 약 50GB를 처리하고 지금 까지이 방법으로 문제를 겪지 않았습니다.


답변

환경은 CentOS이며 응용 프로그램은 파일에 씁니다 …

일반 파일로 보내는 대신 출력을 syslog로 보내고 syslog 메시지가 로컬 서버뿐만 아니라 중앙 서버로 보내지고 있는지 확인합니다.

다음과 같은 쉘 스크립트를 사용할 수 있어야합니다.

logger -p daemon.notice -t app < fifo

파이프 logger에서 cat또는 tail -f파이프로 입력을받을 수도 있습니다 .

tail -f fifo | logger ...
cat fifo | logger ...

유일한 문제는 로그 메시지의 중요성 (모든 것이 NOTICE )에 따라 구분되지 않지만 최소한 로그되어 호스트 외부로 중앙 서버로 전송된다는 것입니다.

syslog 구성은 사용중인 서버에 따라 다릅니다. 이 rsyslogsyslog-ng(모두 매우 가능).

편집 : 포스터에서 더 많은 정보를 얻은 후 수정되었습니다.


답변

당신은 쓰기:

또한 응용 프로그램에 쓰지 않습니다 stdout

“파일”에 로깅을 시도 했습니까 /dev/stdout? 그러면 다음과 같은 작업을 수행 할 수 있습니다.

app --logfile /dev/stdout | logger -t app


답변

fifo에 기록한 다음 다른 프로세스가 파일에 기록하도록 할 필요는 없습니다. 정상적으로 파일에 직접 쓰면 일단 write()리턴되면 커널의 손에 달려 있습니다. 응용 프로그램이 충돌해도 여전히 디스크에 기록합니다.


답변