반응형
1. 개요
- glibc(GNU C Library)는 system log를 남기기 위한 라이브러리를 제공하고 있다.
- syslog.h 에서 제공해 주는 system log를 남기는 방법을 정리합니다.
2. syslog.h
- syslog.h는 glibc에 포함되어 있기 때문에 따로 설치가 필요하지 않습니다.
- syslog man page에서 확인이 가능합니다.
- closelog, openlog, syslog, vsyslog - send messages to the system logger
- syslog를 사용하면 /var/log/syslog 파일에 쓰인다.
3. 함수 설명
3.1. openlog()
-
- 함수 원형
- void openlog(const char *ident, int option, int facility);
- 설명
- 시스템 로거와 연결을 생성하는 함수입니다.
- openlog() 사용은 선택 사항입니다. (syslog()에 의해 자동으로 호출되는 경우, ident는 NULL로 설정됩니다.)
- 파라미터 설명
ident - 로그 앞에 추가되는 메시지입니다.
- ident가 NULL로 설정되면 프로그램 이름으로 설정됩니다.
option - 연결 옵션으로 비트 마스크로 구성됩니다.
- 옵션 종류 다음과 같으며, 자세한 설명은 syslog man page 참고합니다.
- LOG_CONS
- LOG_NDELAY
- LOG_NOWAIT
- LOG_ODELAY
- LOG_PERROR
- LOG_PID
facility - 메시지를 기록하는 프로그램 유형을 지정합니다.
- 종류는 다음과 같으며, 자세한 설명은 syslog man page 참고합니다.
- LOG_AUTH
- LOG_AUTHPRIV
- LOG_CRON
- LOG_DAEMON
- LOG_FTP
- LOG_KERN
- LOG_LOCAL0 ~ LOG_LOCAL7
- LOG_LPR
- LOG_MAIL
- LOG_NEWS
- LOG_SYSLOG
- LOG_USER(기본값)
- LOG_UUCP
- 함수 원형
3.2. syslog()
-
- 함수 원형
- void syslog(int priority, const char *format,...);
- 설명
- 로그 메시지를 생성하는 함수입니다.
- 파라미터 설명
priority - 메시지의 중요성을 결정합니다.
- 종류는 다음과 같으며, 자세한 설명은 syslog man page 참고합니다.
- LOG_EMERG
- LOG_ALERT
- LOG_CRIT
- LOG_ERR
- LOG_WARNING
- LOG_NOTICE
- LOG_INFO
- LOG_DEBUG
format - 포맷을 설정하는 파라미터입니다.
- 실제 로그 내용을 작성합니다.
- 함수 원형
3.3. closelog()
-
- 함수 원형
- void closelog(void);
- 설명
- system 로그를 쓰는 데 사용한 파일 디스크립터를 닫아줍니다.
- openlog()를 사용하여 system 로그 파일 디스크립터를 얻었다면 closelog()를 사용하여 system 로그 파일 디스크립터를 닫아줘야 합니다.
- 함수 원형
3.4. vsyslog()
-
- 함수 원형
- void vsyslog(int priority, const char *format, va_list ap);
- 설명
- syslog() 함수와 동일한 작업을 수행하지만 stdarg(3) 가변 인수 목록 매크로를 사용하여 얻은 인수 집합을 사용한다는 차이점이 있습니다.
- 자세한 설명은 syslog와 stdarg(3) man page를 참고합니다.
- 함수 원형
4. 사용 예제
4.1. 예제 1)
-
- 소스 코드
openlog() 함수를 사용하여 로그 앞에 추가할 메시지 "MY LOG 1"을 설정합니다.int fn_TestSystemLog1() { openlog("MY LOG 1", LOG_CONS | LOG_PID, LOG_USER); syslog(LOG_INFO, "seo91_test log print!!!!"); closelog(); return 0; }
syslog() 함수를 사용하여 System Log에 출력할 메시지를 설정합니다.'
closelog() 함수를 사용하여 닫습니다. - 결과 출력
/var/log/syslog 파일에 시스템 로그가 출력되는 것을 확인할 수 있습니다.
- 소스 코드
4.2. 예제 2)
-
- 소스 코드
openlog() 함수를 사용하지 않고 syslog() 함수를 바로 호출하여 System Log에 출력할 메시지를 설정하였습니다.int fn_TestSystemLog2() { syslog(LOG_INFO, "seo91_test log print!!!!"); closelog(); return 0; }
closelog() 함수를 사용하여 닫습니다. - 결과 출력
/var/log/syslog 파일에 시스템 로그가 출력되는 것을 확인할 수 있습니다.
- 소스 코드
4.3. 예제 3)
-
- 소스 코드
예제 2)의 함수를 define 함수로 만들어서 사용하였습니다.#define SYSTEM_LOG(fmt,...) { \ openlog("MY LOG 1", LOG_CONS | LOG_PID, LOG_USER); \ syslog(LOG_INFO, fmt, ##__VA_ARGS__); \ closelog(); \ } ... int fn_TestSystemLog2() { int nData = 1; char szData[10]= "1234"; SYSTEM_LOG("log test1 [%d]", nData); SYSTEM_LOG("log test2 [%s]", szData); SYSTEM_LOG("log test3"); return 0; }
- 결과 출력
/var/log/syslog 파일에 시스템 로그가 출력되는 것을 확인할 수 있습니다.
- 소스 코드
5. syslog message repeated
- syslog에 동일한 로그 메시지를 짧은 기간 내에 기록하면, syslog 데몬은 이를 통합하고 반복 횟수를 나타내는 수를 추가합니다.
- 해당 동작은 "/etc/rsyslog.conf" 또는 "/etc/syslog.conf" 설정 파일에서 "RepeatedMsgReduction" 구성 옵션에 의해 제어되며, 기본적으로 활성화되어 있습니다.
- "message repeated"는 syslog 데몬 설정을 수정하면 비활성화할 수 있지만, 로그의 크기가 증가하고 가독성이 저하될 수 있으므로 권장하지 않습니다.
5.1. 프로그램에서 "message repeated" 증상 확인
-
- 프로그램에서 "syslog.h"에서 제공해 주는 syslog API를 사용하여 동일 log message를 반복적으로 남기는 경우 증상을 확인할 수 있습니다.
- 소스 코드
시스템 로그를 기록하도록 작성한 소스코드입니다.#include <stdio.h> #include <stdlib.h> #include <syslog.h> #define SYSTEM_LOG(ident, fmt,...) { \ openlog(ident, LOG_CONS | LOG_PID | LOG_ODELAY, LOG_USER); \ syslog(LOG_INFO, fmt, ##__VA_ARGS__); \ closelog(); \ } int fn_SyslogTest() { SYSTEM_LOG("system log test", "log test"); return 0; } int main(int argc, char** argv) { int nMenu = 0; while (1) { printf("==== MENU ==== \n"); printf("0 : Quit \n"); printf("1 : Run \n"); printf("============== \n"); printf("cmd no. = "); scanf("%d", &nMenu); switch (nMenu) { case 0: goto LABEL_ESC; case 1: fn_SyslogTest(); break; default: printf("unknown menu... \n"); } } LABEL_ESC: return 0; }
프로그램 실행 후 1을 입력하면 시스템 로그를 기록하여 0을 입력하면 프로그램을 종료합니다. - 실행 확인
1을 입력하면 시스템 로그를 기록합니다. - System Log 확인
짧은 기간 동안 동일한 syslog를 기록하면 최초 한 번 syslog 기록 후 더 이상 기록이 되지 않습니다. - 프로그램 재실행
프로그램 종료 후 재실행하면 "message repeated..." 메시지를 출력합니다.
위 메시지에서 "message repeated 5..."는 동일 메시지를 5번 기록 요청을 했다는 의미입니다.
5.2. 프로그램에서 "message repeated" 우회하기
-
- 짧은 기간에 여러 번의 시스템 로그를 기록해야 하는 경우 message repeated로 인해 확인이 어렵습니다.
- 따라서 이를 우회하기 위해 시스템 로그를 기록할 때 count와 같이 메시지를 변화하여 사용합니다.
- 소스 코드
시스템 로그를 기록할 때마다 count를 증가시킨 값을 메시지에 추가합니다.#include <stdio.h> #include <stdlib.h> #include <syslog.h> #define SYSTEM_LOG(ident, fmt,...) { \ openlog(ident, LOG_CONS | LOG_PID | LOG_ODELAY, LOG_USER); \ syslog(LOG_INFO, fmt, ##__VA_ARGS__); \ closelog(); \ } int fn_SyslogTest(int nData) { SYSTEM_LOG("system log test", "log test"); return 0; } int main(int argc, char** argv) { int i = 0; int nMenu = 0; while (1) { printf("==== MENU ==== \n"); printf("0 : Quit \n"); printf("1 : Run \n"); printf("============== \n"); printf("cmd no. = "); scanf("%d", &nMenu); switch (nMenu) { case 0: goto LABEL_ESC; case 1: fn_SyslogTest(i++); break; default: printf("unknown menu... \n"); } } LABEL_ESC: return 0; }
- 실행 결과
시스테 로그 기록 시 count 값을 증가시키자 짧은 시간에 여러 번의 메시지를 기록하여도 정상적으로 확인할 수 있습니다.
6. 참고
반응형
'C' 카테고리의 다른 글
[C/C++] stat(2), lstat(2), fstat(2) 파일 정보 확인 함수 사용법 (0) | 2024.03.11 |
---|---|
[C/C++] mkdir(2) 디렉터리 생성 함수 사용법 (0) | 2024.03.08 |
[C/C++]임시 변수 없이 두 개의 정수 값을 교환하기 (2) | 2023.11.08 |
[C]Type Casting (0) | 2018.01.11 |
[C]변수 const (0) | 2018.01.11 |