[C] 로깅 라이브러리 개발

문연수·2024년 6월 22일
0

C

목록 보기
4/4

 유저가 자유롭게 커스터마이징 가능한, 멀티 쓰레딩 로깅 라이브러리를 개발했다. 예전부터 로거가 필요하면 그때그때 작성해서 사용했는데 이럼 중복 코드도 많아지고 다른 프로젝트에서 짠 로거랑 호환이 안되는 등 여러가지 문제들이 많아서 각 잡고 제대로 만들어 보았다.

0. valgrind 통과

valgrind 결과는 에러 없이 완벽하게 통과한다. 사실 몇 가지 Exception Handling 이 부족한 상태이지만, 유저가 API 를 정상적으로 사용한다면 발생할 일이 없기 때문에 나중에 구현할 예정이다.

1. 기능

필자가 만든 로깅 라이브러리는 다음의 기능을 지원한다.

  1. 멀티 쓰레딩 지원
    멀티 쓰레드 환경에서 로그를 찍었을 때 문자열이 잘려 나가는 등의 문제가 발생하지 않고 Atomicity 하게 동작.
  2. 자유로운 커스터마이징
    파일명, 함수명, 라인, 시간 등의 정보를 포맷 문자열로 지정 가능.
  3. 리디렉션 지원
    로그를 표준 입출력 뿐만 아니라 파일로도 출력 가능할 수 있도록 FILE * 를 인자로 받아 설정이 가능.
  4. 로그 레벨 지원
    로그 레벨을 지정할 수 있고, 레벨에 따른 로그 포맷팅 변경과 출력 리디렉션 또한 가능.

2. API

- logger_create()

Logger logger_create(void);

로거를 생성해주는 함수. 실패 시 NULL 반환

- logger_destroy()

void logger_destroy(Logger );

logger_create() 를 통해 생성된 Logger 를 소멸시키는 함수.

- logger_define_level()

bool logger_define_level(Logger, int level, char *name, FILE *fp);

로거의 레벨을 정의하는 함수. 이를 통해 로거의 레벨, 이름, 그리고 출력 방식을 지정할 수 있다.

- logger_set_format()

bool logger_set_format(Logger , int level, char *format);

로거 레벨에 따른 출력 형식을 지정할 수 있다. 출력 형식으로 사용 가능한 placeholder 는 다음과 같다:

place holoder결과
%f함수의 이름
%n파일 이름
%l라인 넘버
%s출력할 문자열
%dLocale 에 따른 로컬 날짜
%tLocale 에 따른 로컬 타임
%p로거 레벨 명

* 예시

포맷 스타일

"[%d %t][%n:%l:%f] (%p) %s\n"

출력 결과

log(... ,"user name: %s", mythos);

대충 위와 같이 출력을 시도하면 이하와 같이 출력된다:

[06/22/24 09:43:30][source/main.c:64:main] (info) user name: mythos

개행 문자는 mythos 뒤에 출력되어 자동으로 개행이 이뤄진다.

- logger_log()

int logger_log(Logger , int level,
	const char *file, const char *funciton, const char *line,
    const char *formatted, ...
);

형태가 복잡하고 채워야 되는 인자가 많은데 매번 로그를 출력할 때마다 이를 다 지정하는 것은 번거롭기 때문에 매크로를 통해 축약형으로 호출할 수 있다:

#define log(LOGGER, LEVEL, FMT, ...)

로거, 레벨, 출력 문자만 지정해주면 된다. 여기에서 로그 레벨은 숫자로 지정할 수 있는데 숫자는 외우기도 불편하고 직관적으로 와닿지 않으므로 이하와 같이 매크로를 정의한 뒤

#define LOGGER_LEVEL_INFO 1

이하와 같이 출력하면 된다:

log(logger, INFO, "no problem."); // INFO 는 자동으로 LOGGER_LEVEL_INFO 로 expand 된다.

3. 라이브러리

https://github.com/Cruzer-S/logger

profile
2000.11.30

0개의 댓글