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 aims are high, and you are capable of much. |