mlog
mlog ¶ÀÛ¼ºÇÒ ÇÁ·Î±×·¥ÀÌ ½ÃÀÛÇÑ ÈÄ ±Ý¹æ ³¡³ª°Å³ª ºü¸¥ ½Ã°£³»¿¡ ¿©·¯¹ø ½ÇÇàÇÏ´Â °ÍÀ̶ó¸é, ¹ö±×°¡ ¹ß»ýÇßÀ» ¶§ µð¹ö±ëÇϱ⠽±½À´Ï´Ù. ¿Ö³ÄÇϸé, ¹ö±×°¡ ¹ß»ýÇÑ ¿øÀÎÀ» »¡¸® ¾Ë ¼ö Àֱ⠶§¹®ÀÔ´Ï´Ù. ¶Ç´Â ¿øÀÎÀ» ¸ð¸¥´Ù ÇÏ´õ¶óµµ ¾î¶² »óȲ¿¡ ¹ö±×°¡ ¹ß»ýÇß´ÂÁö ÆľÇÇϱⰡ ½±½À´Ï´Ù. ±×·¯³ª ³×Æ®¿öÅ· ¼¹öó·³ ÀÏ´Ü ½ÇÇàÇÑ ´ÙÀ½ ¿À·¡µµ·Ï ½ÇÇàÇÏ´Â µµÁß ¹ö±×°¡ ¹ß»ýÇÑ´Ù¸é, ¿øÀÎÀ» ¾Ë¾Æ³»±âµµ Èûµé »Ó´õ·¯, ¾î¶² »óȲ¿¡ ¹ö±×°¡ ¹ß»ýÇß´ÂÁö ¾Ë¾Æ³»±â°¡ ¸Å¿ì Èûµì´Ï´Ù. µû¶ó¼ ÀÌ·¯ÇÑ ÇÁ·Î±×·¥ÀÏ °æ¿ì¿¡´Â ÇÁ·Î±×·¥ µ¿ÀÛ °úÁ¤À» ÆÄÀÏÀ̳ª ±âŸ ¹æ¹ýÀ» ÅëÇØ ±â·ÏÇØ µÑ ÇÊ¿ä°¡ ÀÖ½À´Ï´Ù. ÀÌ·± ±â·ÏÀ» º¸Åë log¶ó°í Çϴµ¥, ¿©±â¿¡¼´Â ÇÁ·Î±×·¥¿¡¼ ½±°Ô ¾µ ¼ö ÀÖ´Â ·Î±× °ü·Ã ±â´ÉÀ» ¸¸µé¾î º¸µµ·Ï ÇÏ°Ú½À´Ï´Ù.
¸ÕÀú, ¿ì¸®°¡ ¸¸µé ·Î±× ±â´ÉÀÌ °¡Á®¾ß ÇÒ °ÍµéÀº Å©°Ô ´ÙÀ½°ú °°ÀÌ »ý°¢ÇÒ ¼ö ÀÖ½À´Ï´Ù:
´ë°³ÀÇ °æ¿ì, °æÇè»ó, Ç×»ó ·Î±× ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÒ ¶§º¸´Ù´Â ¾î¶² Á¶°Ç¿¡ µû¶ó¼ ·Î±× ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÒ °ÍÀÎÁö ¾Æ´ÑÁö °áÁ¤ÇÏ°í »óȲ¿¡ µû¶ó¼ ·Î±× ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÏ´Â °æ¿ì°¡ ¸¹¾Ò½À´Ï´Ù. µû¶ó¼ ¿ì¸®°¡ »ç¿ëÀڵ鿡°Ô Á¦°øÇÒ ÀÎÅÍÆäÀ̽º´Â ¾î¶² Á¶°Ç x°¡ ÂüÀÏ °æ¿ì¿¡ printf(3)¿Í °°Àº Çü½ÄÀ¸·Î ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÒ ¼ö ÀÖ´Â °ÍÀÔ´Ï´Ù. °á±¹ ´ÙÀ½°ú °°Àº ÀÎÅÍÆäÀ̽º¸¦ Áö´Ï°Ô µË´Ï´Ù:
int message_logger(condition, const char *format, ...);
message_logger(3.2, "some log message");
#define MLOG(condition, ...) ((condition) ? mlog(__VA_ARGS__) : 0)
Stream Buffer ¶mlog() ÇÔ¼ö´Â Á¶±Ý À̵û°¡ ¸¸µé¾î º¸±â·Î ÇÏ°í, ÀÌ ¸ðµâÀÌ Á¦°øÇØ¾ß ÇÒ °ÍµéÀ» Á» ´õ »ý°¢ÇØ º¸±â·Î ÇսôÙ. ÀÏ´Ü »ç¿ëÀÚ°¡ Ưº°È÷ ÁöÁ¤ÇÏÁö ¾Ê¾Ò´Ù¸é ·Î±×´Â ÁöÁ¤ÇÑ ½ºÆ®¸²À¸·Î Ãâ·ÂµÇ°Ô ÇսôÙ. ÀÌ·¸°Ô Çϱâ À§ÇÏ¿©, ´ÙÀ½°ú °°ÀÌ ·Î±×¿ë ½ºÆ®¸²À» °¡Áö°í ÀÖ´Â °Ô ÁÁÀ» °Í °°½À´Ï´Ù:
static FILE *mlog_stream;
FILE *
mlog_get_stream(void) { return mlog_stream; } int mlog_set_stream(FILE *fp) { fflush(fp); if (setvbuf(fp, 0, _IONBF, 0) != 0) return -1; mlog_stream = fp; return 0; } ¿©·¯ºÐÀº Ç¥ÁØ ÀÔ·Â ½ºÆ®¸², ¡®stdin¡¯°ú Ç¥ÁØ Ãâ·Â ½ºÆ®¸² ¡®stdout¡¯, ±×¸®°í Ç¥ÁØ ¿¡·¯ Ãâ·Â ½ºÆ®¸²ÀÎ ¡®stderr¡¯¸¦ ÀÌ¹Ì ¾Ë°í ÀÖÀ» °ÍÀÔ´Ï´Ù. ±×·±µ¥ ¡®stdout¡¯°ú ¡®stderr¡¯ÀÇ Â÷ÀÌÁ¡À» ¸ð¸£´Â ºÐµµ Àֱ⠶§¹®¿¡ Àá±ñ ±× Â÷ÀÌÁ¡¿¡ ´ëÇØ ´Ù·ç°Ú½À´Ï´Ù. ½ºÆ®¸² ŸÀÔ, Á¤È®È÷ ¸»ÇØ FILE * ŸÀÔÀ¸·Î ¿¬°áµÈ ÆÄÀÏÀº Ç¥ÁØ C ¶óÀ̺귯¸®°¡ ³»ºÎÀûÀ¸·Î ¹öÆÛ¸¦ °¡Áö°í ÀÖ½À´Ï´Ù. µû¶ó¼ ¿©·¯ºÐÀÌ fprintf(3), fputs(3), fputc(3), ¶Ç´Â fwrite(3) µîÀ¸·Î ÆÄÀÏ¿¡ ¾´´Ù(write) ÇÏ´õ¶óµµ ¹Ù·Î ½áÁöÁö ¾ÊÀ» ¼ö ÀÖ½À´Ï´Ù. ´ë°³ÀÇ °æ¿ì, ¾î´À Å©±â±îÁö´Â ¹öÆÛ¿¡ ¾²°Ô µÇ°í, ÀÌ ¹öÆÛ°¡ ´Ù Â÷°Å³ª ¶Ç´Â ¾î¶² Ư¼öÇÑ »óȲÀÌ ¹ß»ýÇÒ °æ¿ì, ½ÇÁ¦ ÆÄÀÏ¿¡ ¾²°Ô µË´Ï´Ù. Ưº°È÷ ÁöÁ¤ÇÏÁö ¾ÊÀº ÇÑ, ¡®stdout¡¯°ú ¡®stderr¡¯´Â ¶È°°ÀÌ Å͹̳ÎÀÇ Ãâ·ÂÀ¸·Î ÁöÁ¤µÇ¾î ÀÖÁö¸¸, ¡®stdout¡¯ÀÇ °æ¿ì, ¹öÆÛ¸µ(buffering)À» ÇÏÁö¸¸, ¡®stderr¡¯´Â ¹öÆÛ¸µÀ» ÇÏÁö ¾Ê°í ¹Ù·Î Ãâ·ÂÇÏ°Ô µË´Ï´Ù. ¾Æ±î ¹öÆÛ°¡ ´Ù Â÷Áö ¾Ê¾Æµµ ¾î¶² Ư¼öÇÑ »óȲÀÌ ¹ß»ýÇÏ¸é ½ÇÁ¦ ÆÄÀÏ¿¡ ¾´´Ù°í Çß½À´Ï´Ù. º¸ÅëÀº newline ¹®ÀÚÀÎ ¡®\n¡¯À» Ãâ·ÂÇÏ¸é ¹öÆÛÀÇ ³»¿ëÀ» Ãâ·ÂÇÏ°Ô µË´Ï´Ù. ´ÙÀ½ ÇÁ·Î±×·¥À» ½ÇÇàÇÏ¸é ±× Â÷À̸¦ ½±°Ô ¾Ë ¼ö ÀÖ½À´Ï´Ù:
#include <stdio.h>
int main(void) { fprintf(stdout, "hello"); fprintf(stderr, "hi"); fprintf(stdout, ", world!\n"); return 0; } $ gcc tmp.c $ ./a.out hihello, world! $ _Ãâ·ÂÀº ¡°hello¡±¸¦ ¸ÕÀú ÇßÁö¸¸, ¡®stdout¡¯À¸·Î Ãâ·ÂµÇ¾î ¹öÆÛ¿¡ ´ë±âÇØ ÀÖ´Â »óÅÂÀÔ´Ï´Ù. ÀÌ ¶§ ¹öÆÛ¸µµÇÁö ¾Ê´Â ¡®stderr¡¯·Î ¡°hi¡±¸¦ Ãâ·ÂÇÏ¸é ¹Ù·Î Ãâ·ÂµÇ°í, ´ÙÀ½À¸·Î ¡®stdout¡¯À¸·Î ¡°, world!\n¡±¸¦ Ãâ·ÂÇϸé, ¾Æ±î ´ë±âÇÏ°í ÀÖ´ø ¡°hello¡±¿Í ÇÔ²² Ãâ·ÂµÇ¾î, ½ÇÁ¦ Å͹̳ηδ ¡°hihello, world!¡±°¡ Ãâ·ÂµË´Ï´Ù. syslog(3) Interface ¶syslog1´Â ½Ã½ºÅÛ ·Î±× ¸Þ½ÃÁö¸¦ ±â·ÏÇÏ´Â ÀÎÅÍÆäÀ̽ºÀÔ´Ï´Ù. ÀϹÝÀûÀ¸·Î ½Ã½ºÅÛ¿¡´Â syslogd(8) µ¥¸ó ÇÁ·Î¼¼½º°¡ Á¸ÀçÇϸç, ¸ðµç syslog ·Î±×µéÀ» ¸ð¾Æ, ÁöÁ¤ÇÑ °÷¿¡ Ãâ·Â ¶Ç´Â ÀúÀåÇÏ°Ô µË´Ï´Ù. µû¶ó¼ syslog(3)À¸·Î Ãâ·ÂÇÑ´Ù´Â °ÍÀº °á±¹ syslogd(8)¿¡ ¸Þ½ÃÁö¸¦ º¸³»°í, syslogd(8) ÇÁ·Î¼¼½º°¡ Á¤ÇØÁø ±ÔÄ¢¿¡ µû¶ó ·Î±×¸¦ ó¸®ÇÕ´Ï´Ù. syslogd(8)·Î ¸Þ½ÃÁö¸¦ º¸³»±â À§ÇØ, ´ë°³ÀÇ ½Ã½ºÅÛ¿¡¼´Â ¾Æ·¡ ÇÔ¼öµéÀ» Á¦°øÇÕ´Ï´Ù:
#include <syslog.h>
void openlog(const char *ident, int option, int facility); void syslog(int priority, const char *format, ...); void closelog(void); #include <stdarg.h> void vsyslog(int priority, const char *format, va_list ap); mlog() ¶´Ù½Ã º»·ÐÀ¸·Î µ¹¾Æ¿Í¼, ÀÌÁ¦ mlog()¸¦ ¸¸µé¾î º¸°Ú½À´Ï´Ù. ¸ÕÀú, mlog()ÀÇ Ãâ·ÂÀº ´ÙÀ½ ²Ã·Î Ãâ·ÂµÉ °ÍÀÔ´Ï´Ù:
½Ã°£: ÇÁ·Î±×·¥À̸§ [PID]: ¸Þ½ÃÁö
½Ã°£À» Ãâ·ÂÇϱâ À§ÇØ, ¿ì¸®´Â time(2), localtime(3), strftime(3)À» ¾²·Á°í ÇÕ´Ï´Ù. ÇÁ·Î±×·¥ À̸§Àº Àü¿ª º¯¼ö ¡®program_name¡¯¿¡ ÀúÀåµÇ¾î ÀÖ´Ù°í °¡Á¤ÇÏ°Ú½À´Ï´Ù. ÇÁ·Î¼¼½º id(pid)´Â getpid(2)¸¦ ½á¼ ¾òÀ¸·Á°í ÇÕ´Ï´Ù. ½Ã°£À» ¾ò¾î³»´Â ÇÔ¼ö´Â ´ÙÀ½°ú °°ÀÌ ¸¸µé°Ú½À´Ï´Ù:
static const char *current_time(void);
static int using_stream(void);
void
mlog(const char *format, ...) { if (using_stream()) { /* ½ºÆ®¸²À¸·Î Ãâ·Â */ } else { /* syslog·Î Ãâ·Â */ } } ÀÌ ÀýÀÇ ¾Õ¿¡¼ ¿ì¸®´Â ÀÌ¹Ì ·Î±×ÀÇ Æ÷¸ËÀ» Á¤Çß½À´Ï´Ù. syslogd(8)´Â ¾Ë¾Æ¼ ¸Þ½ÃÁö¸¦ Æ÷¸Ë½ÃÄÑ ÁֹǷÎ, ¿ì¸®´Â ½ºÆ®¸²À¸·Î Ãâ·ÂÇÒ °æ¿ì¿¡¸¸ Æ÷¸ËÇØÁÖ¸é µË´Ï´Ù. µû¶ó¼ À§ »À´ë¿¡¼ using_stream()ÀÌ ÂüÀÎ °æ¿ì¿¡ ´ÙÀ½°ú °°Àº Äڵ带 ½ÇÇàÇÕ´Ï´Ù.
va_list ap;
fprintf(mlog_stream, "%s: %s[%d]: ", current_time(), program_name, (int)getpid()); va_start(ap, format); vfprintf(mlog_stream, format, ap); va_end(ap); fputc('\n', mlog_stream);
#define MLOG_BUFFER_MAX 1024
static char mlog_buffer[MLOG_BUFFER_MAX];
int ret;
va_list ap; #ifdef HAVE_VSYSLOG vsyslog(LOG_INFO | LOG_USER, format, ap); #else va_start(ap, format); ret = vsnprintf(mlog_buffer, MLOG_BUFFER_MAX, format, ap); va_end(ap); if (ret >= MLOG_BUFFER_MAX || ret < 0) mlog_buffer[MLOG_BUFFER_MAX - 1] = '\0'; syslog(LOG_INFO | LOG_USER, "%s", mlog_buffer); #endif /* HAVE_VSYSLOG */
#define MLOG_BUFFER_MAX 1024
static char mlog_buffer[MLOG_BUFFER_MAX]; void mlog(const char *format, ...) { va_list ap; int ret; if (using_stream()) { fprintf(mlog_stream, "%s: %s[%d]: ", current_time(), program_name, (int)getpid()); va_start(ap, format); vfprintf(mlog_stream, format, ap); va_end(ap); fputc('\n', mlog_stream); } else { #ifdef HAVE_VSYSLOG vsyslog(LOG_INFO | LOG_USER, format, ap); #else va_start(ap, format); ret = vsnprintf(mlog_buffer, MLOG_BUFFER_MAX, format, ap); va_end(ap); if (ret >= MLOG_BUFFER_MAX || ret < 0) mlog_buffer[MLOG_BUFFER_MAX - 1] = '\0'; syslog(LOG_INFO | LOG_USER, "%s", mlog_buffer); #endif /* HAVE_VSYSLOG */ } } mlog.h ¶
/* $Id: mlog,v 1.6 2008/04/10 09:26:22 kss Exp kss $ */
/* * stream/syslog logger module * Copyright (C) 2003, 2004 Seong-Kook Shin <cinsk.shin at samsung.com> */ #ifndef MLOG_H_ #define MLOG_H_ #include <stdio.h> #ifdef HAVE_CONFIG_H # include <config.h> #endif /* This indirect writing of extern "C" { ... } makes Emacs happy */ #ifndef BEGIN_C_DECLS # ifdef __cplusplus # define BEGIN_C_DECLS extern "C" { # define END_C_DECLS } # else # define BEGIN_C_DECLS # define END_C_DECLS # endif #endif /* BEGIN_C_DECLS */ BEGIN_C_DECLS #define MLOG_BUFFER_MAX 4096 /* You should define PROGRAM_NAME somewhere in your code. */ extern const char *program_name; /* Set the stream for logging. * Returns zero on success, otherwise returns -1 */ extern int mlog_set_stream(FILE *fp); /* Get the stream for logging. */ extern FILE *mlog_get_stream(void); extern void mlog(const char *format, ...); #define MLOG(expr, ...) do { if (expr) mlog(__VA_ARGS__); } while (0) END_C_DECLS mlog.c ¶
#include <stdarg.h>
#include <time.h> #include <syslog.h> #include <mlog.h> #define TIME_BUF_MAX 32 static FILE *mlog_stream = 0; static int syslog_opened = 0; #ifndef HAVE_VSYSLOG static char mlog_buffer[MLOG_BUFFER_MAX]; #endif static int using_stream(void) { if (mlog_stream) return 1; if (!syslog_opened) { openlog(program_name, LOG_CONS | LOG_NOWAIT | LOG_PID, LOG_USER); atexit(closelog); syslog_opened = 1; } return 0; } int mlog_set_stream(FILE *fp) { fflush(fp); if (setvbuf(fp, 0, _IONBF, 0) != 0) { /* Warning: cannot empty the stream buffer. */ return -1; } mlog_stream = fp; return 0; } FILE * mlog_get_stream(void) { return mlog_stream; } static const char * current_time() { struct tm *tmptr; time_t t; static char buf[TIME_BUF_MAX]; int ret; t = time(0); tmptr = localtime(&t); ret = strftime(buf, TIME_BUF_MAX, "%b %d %H:%M:%S", tmptr); if (ret == TIME_BUF_MAX || ret == 0) return 0; return buf; } void mlog(const char *format, ...) { va_list ap; int ret; if (using_stream()) { fprintf(mlog_stream, "%s: %s[%d]: ", current_time(), program_name, (int)getpid()); va_start(ap, format); vfprintf(mlog_stream, format, ap); va_end(ap); fputc('\n', mlog_stream); } else { #ifdef HAVE_VSYSLOG vsyslog(LOG_INFO | LOG_USER, format, ap); #else va_start(ap, format); ret = vsnprintf(mlog_buffer, MLOG_BUFFER_MAX, format, ap); va_end(ap); if (ret >= MLOG_BUFFER_MAX || ret < 0) mlog_buffer[MLOG_BUFFER_MAX - 1] = '\0'; syslog(LOG_INFO | LOG_USER, "%s", mlog_buffer); #endif /* HAVE_VSYSLOG */ } } #ifdef MLOG_TEST const char *program_name = "mlog"; int main(int argc, char *argv[]) { FILE *fp; char buf[10]; fp = fopen(argv[1], "a"); if (!fp) return -1; mlog_set_stream(fp); MLOG(1, "hello, %s", "world"); gets(buf); MLOG(1, "hello, %s", "world"); gets(buf); MLOG(1, "hello, %s", "world"); gets(buf); fclose(fp); return 0; } #endif /* MLOG_TEST */ Please see CCodeSnippets
|
Your own qualities will help prevent your advancement in the world. |