내 관심은 주로 프로그래밍에 초점이 맞춰져 있기 때문에 원래 이 글을 StackOverflow에 게시하고 싶었지만, 읽은 후에는역사 태그(그리고그것이 연결되는 질문), 나Softwareengineering.se에 게시하세요.실용적인/오늘날의 "소프트웨어 엔지니어링" 측면에 대한 심층적인 이해를 얻으세요. 그러나 내 질문의 근본적으로 역사적인 성격은 불가피하므로 지금은 여기에 있습니다.
현재 Linux에서 로깅이 작동하는 방식을 배우고 있는데 다루지 않는 것 같은 구현 세부 사항 때문에 약간 혼란스럽습니다.RFC 5424또는RFC 3164: 데이터를 쓰는 데 사용되는 형식입니다 /dev/log
.
간단히 말해서:나는 a) "형식 /dev/log
"이 무엇인지, b) 그 의미가 공식적으로 지정되는 위치를 결정하려고 합니다. RFC나 기타 인용 가능한 참조를 식별할 수 없습니다. 특정 규칙을 구현하는 코드일 뿐이며 운율이나 이유는 없습니다.
syslog()
다른 로깅 전략(stdout/stderr 및/또는 파일에 쓰기, 다른 유형의 로그 서버로 보내기 등)과 비교하여 장단점을 평가하는 동안 처음에는 이 주제에 관심이 있었지만 어느 순간 완전히 확신할 수 없다는 것을 깨달았습니다. " /dev/log
형식"이 더 큰 그림에 어떻게/어디에 들어맞는지. syslog 형식이나 프로토콜에 관한 모든 질문은 RFC에 대해 논의하고 syslog()
데이터가 syslog 서버로 전송되고 전송되는 방식을 제어하는 규칙을 완전히 무시합니다.
이 "형식"(?)을 사용하여 매일 수조 개의 로그 메시지가 기록되는 동안 UNIX의 이 특정 부분은 더 이상 존재하지 않는 것처럼 목공 작업 속으로 완전히 사라진 것과 같습니다.
따라서 이 질문은 이 특정 세부 사항을 명확하게 하고 형식을 설명하고 인용 가능한 참고 문헌을 식별하려는 시도입니다.
로그 줄은 허용되려면 매우 특정한 방식으로 형식을 지정해야 하는 것 같습니다(제 경우에는 systemd-journald - 먼저 우선 순위/시설 정보(에 포함됨 <>
), 그 다음에는 일반적으로 사용되는 것으로 보이는 매우 특정한 형식의 타임스탬프입니다. 로 언급됨상표, 다음 메시지는 다음과 같습니다.
# 로거 -안녕하세요 <13>3월 5일 14:04:11 i336: 안녕하세요 # Journalctl -qn1 -o 짧은 ISO 정밀 2021-03-05T14:04:11.430504+1100 h0nk i336[2505]: 안녕하세요
# 로거 -s-t 태그안녕하세요 <13>3월 5일 14:04:37상표: 안녕하세요 # Journalctl -qn1 -o 짧은 ISO 정밀 2021-03-05T14:04:37.050891+1100 h0nk상표[3151]:안녕하세요
# 로거 -s-t 태그 -나안녕하세요 <13>3월 5일 14:04:40상표[3248]: 안녕하세요 # Journalctl -qn1 -o 짧은 ISO 정밀 2021-03-05T14:04:40.278630+1100 h0nk상표[3248]: 안녕하세요
( stderr로 보내는 내용을 복사하고, -s
레이블 사용 을 내 사용자 이름에서 내가 지정한 대로 변경하고, PID를 추가합니다.)logger
-t tag
logger
-i
제공된 타임스탬프와 PID(제공된 경우)를 구문 분석하고 삭제하고 이 정보 자체를 결정하는 것을 확인했습니다 systemd-journald
(이것이 PID가 항상 존재하는 이유이며 short-iso-precise
제공되지 않은 경우 밀리초를 요청할 수 있는 이유입니다).
# 에코 '<13>1월 1일 00:00:00시험[1234]:안녕'| ncat -uU /dev/log #journalctl-qn1 3월 5일 14:06:12ㅋㅋㅋ 테스트[5593]: 안녕하세요 # Journalctl -qn1 -o 짧은 ISO 정밀 2021-03-05T14:06:12.538712+1100 h0nk 테스트[5593]: 안녕하세요
보안 관점에서 이는 의미가 있습니다.
하지만, 나는 내가 다음에서 벗어나면약간형식에서
<p>Mmm _d HH:MM:SS tagwithnospaces: message
그러면 모든 것이 매우 빨리 나빠집니다.
logger
UDP 또는 TCP를 통해 syslog 서버에 연결하기 위한 모양과 옵션입니다. 데이터를 보낼 때 이러한 옵션을 사용하면 비참한 결과가 발생할 수 있습니다.--rfc5424
--rfc3164
/dev/log
RFC 5424 형식(헤더는 다음에 정의됨)섹션 6) 처음부터 폭발했습니다.
# logger -s --rfc5424 hi
<13>1 2021-03-05T15:05:04.773304+11:00 h0nk i336 - - [timeQuality tzKnown="1" isSynced="1" syncAccuracy="648500"] hi
# journalctl -qn1 -o short-iso-precise
2021-03-05T15:05:04.773384+1100 h0nk logger[29306]: 1 2021-03-05T15:05:04.773304+11:00 h0nk i336 - - [timeQuality tzKnown="1" isSynced="1" syncAccuracy="648500"] hi
이상하게도 RFC 3164 형식(섹션 4.1.2)는 다음과 거의 유사합니다... 어떤 logger
형식을 사용하든지 간에아니요RFC 옵션을 지정하고 RFC 3164의 호스트 이름 필드를 추가하는 것만으로도 문제가 발생할 수 있습니다.
# 로거 -s --rfc3164 안녕하세요 <13>3월 5일 14:20:51 h0nk i336: 안녕하세요 # Journalctl -qn1 -o 짧은 ISO 정밀 2021-03-05T14:20:51.638518+1100 h0nk 알 수 없음[27148]:h0nk i336:안녕하세요 ^오
<nnn>
부가 질문: RFC 형식은 상태 정보("긴급", "긴급" 등)가 항상 올바르게 전송되도록 주요 우선순위 필드를 유지하는 것 같습니다 . 맞습니까?
날짜 자체도 특히 민감한 값인 것 같습니다. 조금만 변경해도 즉시 systemd-journald
전체 줄이 손상된 것으로 간주됩니다.
# echo '<13> 1월 1일 00:00:00 test [1234]: 안녕하세요' | ^두 개의 공백 # Journalctl -qn1 -o 짧은 ISO 정밀 2021-03-05T14:17:04.484309+1100 h0nk 테스트[21585]: 안녕하세요
# echo '<13> 1월 1일 00:00:00 test [1234]: 안녕하세요' | ^우주 # Journalctl -qn1 -o 짧은 ISO 정밀 2021-03-05T14:06:23.414986+1100 h0nk ncat[5877]: 1월 1일 00:00:00 테스트[1234]: 안녕하세요
흥미롭게도 BusyBox의 syslogd는 날짜(syslog.c:829) 특정 문자의 위치에 대해 정확하고 하드 코딩된 가정을 하기 위해:
/* 1월 18일 00:11:22 뉴스... */ /* 01234567890123456 */ if (len >= 16 && msg[3] == ' ' && msg[6] == ' ' && 메시지[9] == ':' && 메시지[12] == ':' && 메시지[15] == ' ' ){
(Busybox syslogd에도 15자 길이가 언급되어 있습니다.L286.)
날짜를 왜 그렇게 주의 깊게 지정해야 하는지 궁금합니다.
glibc 구현을 찾았습니다 syslog()
(syslog.c:223) 통찰력 있는 연구:
%h %e %T
" " 형식을 사용합니다 .%h
->%b
;%b
= 로케일에 따른 약식 월 이름%e
= 날짜, 앞에 공백 포함%T
= 시간은 같다%H:%M:%S
- 타임스탬프 뒤의 후행 공백은
msg[15] == ' '
BusyBox syslogd의 check(!)와 일치합니다(완전히 어리둥절함).
이는 (glibc-internal?) 함수를 사용합니다
strftime_l()
.시간.h:101), "전역 로캘 대신 제공된 로캘에서 정보 가져오기";strftime_l()
여기에 전달됨_nl_C_locobj_ptr
(에 정의됨)locale.h:17), 이는 내부 포인터입니다_nl_C_locobj
(에서 정의됨).xlocale.c:34) C 로케일 정의(또한 내부) glibc에 대한 전역 참조입니다.
logger
호출되는 모드에 따라 다양한 헤더 형식 지정 기능이 사용됩니다.syslog_rfc3164_header()
,syslog_rfc5424_header()
, 그리고syslog_local_header()
. 중요한 부분 syslog_local_header()
은 다음과 같습니다.
if (ctl->pid) snprintf(pid, sizeof(pid), "[%d]", ctl->pid); ... xasprintf(&ctl->hdr, "<%d>%s %s%s: ", ctl->pri, rfc3164_current_time(), ctl->레이블,pid);
이 형식을 다시 사용합니다.우선순위, 시간, 태그, PID.
rfc3164_current_time()
glibc 로케일 댄스에 대한 휴대용 대안으로 축약된 영어 월 이름 목록을 묶는 gettimeofday()
래퍼 입니다 .localtime()
RFC 3164의 날짜 형식이 "기본" "형식"에서 사용되는 형식과 매우 유사하다는 점을 고려하면 /dev/log
날짜 형식 지정 기능을 재사용하는 것이 합리적입니다. 그러나 전체적으로 "네이티브" 형식은 여전히 RFC 3164 형식과 다르기 때문에 이것이 재사용할 수 있는 유일한 형식이라는 점은 주목할 가치가 있습니다.
질문: /dev/log
이 형식의 기원은 무엇입니까?
logger
"네이티브" 정규화는 /dev/log
웹/RFC 형식과 다른 이름으로 형식을 명확하게 하는 데 가장 가까운 방법입니다. 나는 이 구별을 명명하려고 시도하는 다른 곳을 찾지 못했으며 단지 그것을 사용합니다.
다른 syslog 데몬(rsyslog, syslog-ng 등)을 테스트하지 않았으며 이들이 RFC 형식의 텍스트 줄을 허용하는지 여부는 알 수 없지만 /dev/log
BusyBox의 정확성을 고려하면 놀라지 않을 것입니다. 일종의 위반이군요...
...그러나 동시에 이 행동을 애초에 위반으로 정의하는 표준이나 정책은 무엇입니까?
내 인상은 이것이 "관습에 따른" 표준이며 실제로 사용되는 정확한 특정 파서로 인해 명시적인 승인이 회피되었다는 것입니다.
이 가정이 맞나요?
알아채다. 나는 우연히 우연히 발견했다/dev/log
이것은 파일 자체의 의미에 대한 질문에 대한 좋은 답변입니다., 이는 chroot에서 실행 중인 애플리케이션이 상대 /dev/log
경로로 전송될 수 있음을 나타냅니다. 좋은 지적입니다. /dev/log
올바른 이름을 지정해야 하기 때문에 "형식"을 매우 많이 사용합니다.
답변1
어쩌면 man rsyslogd
중요한 팁이 주어질 수도 있습니다:
/dev/log
The Unix domain socket to from where local syslog messages are
read.
노트"현지의syslog 메시지". 이는 RFC 3164의 HOSTNAME이 누락되었지만 나머지는 해당 형식을 따르는 것으로 나타남을 의미합니다. 또한 syslog 데몬은 메시지를 기록하기 전에 누락된 호스트 이름 필드를 추가하는 것으로 나타납니다.
애플리케이션이 syslog 메시지를 생성 하는 경우 strace
다음과 같은 내용을 볼 수 있습니다( 에서 strace -f logger -t demo foobar
).
...
socket(AF_UNIX, SOCK_DGRAM, 0) = 3
connect(3, {sa_family=AF_UNIX, sun_path="/dev/log"}, 110) = 0
...
sendto(3, "<13>Apr 28 11:34:21 demo: foobar", ...) = 32
...
정확한 효과 systemd-journald
는 문서화되어 있지 않으며 아마도 표준이 아닐 것입니다(Lennart Poettering이 메일링 리스트 주제 "Q: Non-ASCII in syslog"에서 인정한 것처럼).