로그 처리 시 bash 버퍼링 문제 방지

로그 처리 시 bash 버퍼링 문제 방지

내 bash 버퍼링 문제는 여기에서 찾을 수 있는 문제와 유사합니다.파이프라인에서 버퍼링 끄기

위 질문의 socat 솔루션은 initrd dracut 후크 스크립트에서 이 명령에 액세스할 수 있기 때문에 매우 흥미롭습니다. 불행히도 이를 내 특정 문제에 적용하는 방법을 모르겠습니다. Journalctl json 출력의 "실시간" 구문 분석(버퍼링 방지) ; Journalctl이 출력하는 대로 각 행(각 \n)을 처리합니다.

logmessage() 함수는 버퍼가 가득 찼을 때만 호출되며, 새 저널 행이 인쇄될 때는 호출되지 않습니다. 문제가 jq 이전에 있는지 아니면 "< <(" 리디렉션에 있는지 알 수 없습니다.

(logmessage()는 로그 파일과 Plymouth 콘솔에 메시지를 쓰는 간단한 함수입니다.)

아래 코드에서는 버퍼가 가득 찼을 때만 처리되므로 나에게는 유용하지 않습니다.

{
        SEVERITY=( emerg alert crit err warning notice info debug )
        FACILITY=( kern user mail daemon auth syslog lpr news uucp cron authpriv ftp ntp security console cron local0 local1 local2 local3 local4 local5 local6 local7 )
        while read LOG_FACILITY LOG_SEVERITY LOG_TAG LOG_MESSAGE
        do
                logmessage ${FACILITY[$LOG_FACILITY]}.${SEVERITY[$LOG_SEVERITY]} "$LOG_TAG" "$LOG_MESSAGE"
        done < <( journalctl --follow -o json --no-pager --no-tail | jq -r '"\(.SYSLOG_FACILITY // 3) \(.PRIORITY // 6 ) \(.SYSLOG_IDENTIFIER // "journald") \(.MESSAGE | sub("\\n";" ";"g") // "no message")"' )
}&

이 코드는 특별한 initramfs의 일부입니다. socat 명령을 사용할 수 있습니다. 실시간으로 로그를 구문 분석하고 시설, 우선순위, 태그 및 메시지를 다른 대상(로그 파일, Plymouth 콘솔 플러그인 등)으로 보내야 합니다.

어떤 조언이라도 대단히 감사하겠습니다. (이 코드는 systemimager 소프트웨어(GPL)의 일부가 됩니다.) https://github.com/finley/SystemImager/wiki

어떤 조언이라도 대단히 감사하겠습니다.

답변1

<(...)다음 대신 파이프를 사용하면 무엇을 얻을 수 있는지 잘 모르겠습니다 .

journalctl ... |
jq -r ... |
while read LOG_FACILITY LOG_SEVERITY LOG_TAG LOG_MESSAGE
do logmessage ...
done

물론 두 버전 모두 동일한 버퍼링 문제가 있습니다.

그러나 두 경우 모두 다음을 사용 하여 명령을 socat실행 하려는 경우jqjq -r ...

socat -u EXEC:'jq -r ...',pty,ctty STDIO

그러나 큰 문제가 있습니다. 매개변수를 인용해야 합니다. jq이로 인해 매개변수가 socat약간 엉망이 되고 문자열을 올바르게 전달하기가 어려워집니다. 이 문제를 해결하는 한 가지 방법은 명령을 쉘 변수에 저장하고 나중에 사용하는 것입니다.

export cmd="$(cat <<\! 
jq -r '"\(.SYSLOG_FACILITY // 3) \(.PRIORITY // 6 ) \(.SYSLOG_IDENTIFIER // "journald") \(.MESSAGE | sub("\\n";" ";"g") // "no message")"'
!
)"

socat -u SYSTEM:'eval $cmd',pty,ctty STDIO

그러나 결국에는 jq하나의 옵션을 선택 하면 --unbuffered원하는 효과를 얻을 수 있으므로 이 중 어느 것도 필요하지 않습니다.

관련 정보