· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
mlog

mlog


ÀÛ¼ºÇÒ ÇÁ·Î±×·¥ÀÌ ½ÃÀÛÇÑ ÈÄ ±Ý¹æ ³¡³ª°Å³ª ºü¸¥ ½Ã°£³»¿¡ ¿©·¯¹ø ½ÇÇàÇÏ´Â °ÍÀ̶ó¸é, ¹ö±×°¡ ¹ß»ýÇßÀ» ¶§ µð¹ö±ëÇϱ⠽±½À´Ï´Ù. ¿Ö³ÄÇϸé, ¹ö±×°¡ ¹ß»ýÇÑ ¿øÀÎÀ» »¡¸® ¾Ë ¼ö Àֱ⠶§¹®ÀÔ´Ï´Ù. ¶Ç´Â ¿øÀÎÀ» ¸ð¸¥´Ù ÇÏ´õ¶óµµ ¾î¶² »óȲ¿¡ ¹ö±×°¡ ¹ß»ýÇß´ÂÁö ÆľÇÇϱⰡ ½±½À´Ï´Ù. ±×·¯³ª ³×Æ®¿öÅ· ¼­¹öó·³ ÀÏ´Ü ½ÇÇàÇÑ ´ÙÀ½ ¿À·¡µµ·Ï ½ÇÇàÇÏ´Â µµÁß ¹ö±×°¡ ¹ß»ýÇÑ´Ù¸é, ¿øÀÎÀ» ¾Ë¾Æ³»±âµµ Èûµé »Ó´õ·¯, ¾î¶² »óȲ¿¡ ¹ö±×°¡ ¹ß»ýÇß´ÂÁö ¾Ë¾Æ³»±â°¡ ¸Å¿ì Èûµì´Ï´Ù. µû¶ó¼­ ÀÌ·¯ÇÑ ÇÁ·Î±×·¥ÀÏ °æ¿ì¿¡´Â ÇÁ·Î±×·¥ µ¿ÀÛ °úÁ¤À» ÆÄÀÏÀ̳ª ±âŸ ¹æ¹ýÀ» ÅëÇØ ±â·ÏÇØ µÑ ÇÊ¿ä°¡ ÀÖ½À´Ï´Ù. ÀÌ·± ±â·ÏÀ» º¸Åë log¶ó°í Çϴµ¥, ¿©±â¿¡¼­´Â ÇÁ·Î±×·¥¿¡¼­ ½±°Ô ¾µ ¼ö ÀÖ´Â ·Î±× °ü·Ã ±â´ÉÀ» ¸¸µé¾î º¸µµ·Ï ÇÏ°Ú½À´Ï´Ù. ¸ÕÀú, ¿ì¸®°¡ ¸¸µé ·Î±× ±â´ÉÀÌ °¡Á®¾ß ÇÒ °ÍµéÀº Å©°Ô ´ÙÀ½°ú °°ÀÌ »ý°¢ÇÒ ¼ö ÀÖ½À´Ï´Ù:
  1. ·Î±×¸¦ ¿øÇÏÁö ¾ÊÀ» °æ¿ì, ·Î±× ±â´ÉÀ» ½±°Ô ²ø ¼ö ÀÖ¾î¾ß ÇÑ´Ù.
  2. ·Î±× Á¤º¸¸¦ ÁöÁ¤ÇÑ ÆÄÀÏ¿¡ ±â·ÏÇÒ ¼ö ÀÖ¾î¾ß ÇÑ´Ù.
  3. ·Î±× Á¤º¸¸¦ ÇÊ¿äÇÏ´Ù¸é syslog(3) ÀÎÅÍÆäÀ̽º¸¦ ÅëÇؼ­ ½Ã½ºÅÛ ·Î°Å(logger)¿¡ º¸³¾ ¼ö ÀÖ¾î¾ß ÇÑ´Ù.
ù°, ·Î±× ±â´ÉÀº xassert()¿Í´Â ´Ù¸¨´Ï´Ù. xassert´Â µð¹ö±ëÇÒ ¶§°¡ ¾Æ´Ï¸é, ¸¶Ä¡ xassert()¸¦ ¾²Áö ¾ÊÀº °Íó·³ ¾î¶°ÇÑ ±â°è¾î Äڵ带 ¸¸µé¾î ³»Áö ¾Ê¾Æ¾ß ÇÕ´Ï´Ù. ·Î±× ±â´ÉÀº ÀÌ¿Í´Â ´Þ¸® Ç×»ó ±× ±â´ÉÀ» ¼öÇàÇÏ¿©¾ß ÇÕ´Ï´Ù. ´Ù¸¸ ¿øÇÏÁö ¾ÊÀ» °æ¿ì¿¡´Â ¾Æ¹«·± Àϵµ ÇÏÁö ¾ÊÀ» ¼ö ÀÖ´Â °ÍÀÔ´Ï´Ù. µÑ°, ·Î±× Á¤º¸´Â ÇÊ¿ä¿¡ µû¶ó¼­ ÁöÁ¤ÇÑ ÆÄÀÏ¿¡ ±â·ÏÇÒ ¼ö ÀÖ¾î¾ß ÇÕ´Ï´Ù. ÀÌ ÆÄÀÏÀº Ç×»ó µ¿ÀûÀ¸·Î º¯°æµÉ ¼ö ÀÖÀ¸¸ç, Á¤È®ÇÑ ±â·Ï ½ÃÁ¡À» À§ÇØ ÆÄÀÏ Ã³¸®¿¡ ¹öÆÛ¸¦ »ç¿ëÇÏÁö ¸»¾Æ¾ß ÇÕ´Ï´Ù. ¿ì¸®´Â Ç¥ÁØ ¶óÀ̺귯¸®¿¡¼­ Á¦°øÇÏ´Â ½ºÆ®¸² ÀÔÃâ·Â(Á¤È®È÷ FILE *¸¦ ÅëÇÏ¿©)À» ½á¼­ ÆÄÀÏ·Î ±â·ÏÇÏ°Ô ¸¸µé°Ú½À´Ï´Ù. FILE *¸¦ ¾µ °ÍÀ̹ǷΠ»óȲ¿¡ µû¶ó stdoutÀ̳ª stderr¸¦ ÅëÇÏ¿© Ç¥ÁØ Ãâ·ÂÀ̳ª Ç¥ÁØ ¿¡·¯ Ãâ·ÂÀ¸·Î Ãâ·ÂÇÒ ¼öµµ ÀÖÀ» °ÍÀÔ´Ï´Ù. ¼¼Â°, ½Ã½ºÅÛ ·Î°Å(logger)ÀÎ syslog·Î ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÏ´Â ±â´Éµµ ÀÖÀ¸¸é ³ªÁß¿¡ ´ë¸ó(daemon)°ú °°Àº ¼­¹ö ÇÁ·Î±×·¥À» ¸¸µç´Ù¸é ¸Å¿ì ¾µ¸ðÀÖÀ» °Í °°½À´Ï´Ù. ´ÜÁö syslog°¡ ¸ðµç ½Ã½ºÅÛ¿¡¼­ Áö¿øÇÏ´Â ±â´ÉÀº ¾Æ´Ï±â ¶§¹®¿¡ »óȲ¿¡ µû¶ó ¾µ ¼ö ÀÖµµ·Ï Á¶°ÇºÎ ÄÄÆÄÀÏÀ» Áö¿øÇØ¾ß ÇÒ °ÍÀÔ´Ï´Ù.

´ë°³ÀÇ °æ¿ì, °æÇè»ó, Ç×»ó ·Î±× ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÒ ¶§º¸´Ù´Â ¾î¶² Á¶°Ç¿¡ µû¶ó¼­ ·Î±× ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÒ °ÍÀÎÁö ¾Æ´ÑÁö °áÁ¤ÇÏ°í »óȲ¿¡ µû¶ó¼­ ·Î±× ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÏ´Â °æ¿ì°¡ ¸¹¾Ò½À´Ï´Ù. µû¶ó¼­ ¿ì¸®°¡ »ç¿ëÀڵ鿡°Ô Á¦°øÇÒ ÀÎÅÍÆäÀ̽º´Â ¾î¶² Á¶°Ç x°¡ ÂüÀÏ °æ¿ì¿¡ printf(3)¿Í °°Àº Çü½ÄÀ¸·Î ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÒ ¼ö ÀÖ´Â °ÍÀÔ´Ï´Ù. °á±¹ ´ÙÀ½°ú °°Àº ÀÎÅÍÆäÀ̽º¸¦ Áö´Ï°Ô µË´Ï´Ù:
int message_logger(condition, const char *format, ...);
µÎ¹ø° ÀÌÈÄÀÇ ÀÎÀÚ´Â xassert()¿Í °°±â ¶§¹®¿¡ ´õ ÀÌ»ó ¼³¸íÇÒ ÇÊ¿ä´Â ¾øÀ» °ÍÀ̶ó°í »ý°¢ÇÕ´Ï´Ù. ÀÌÁ¦ ù¹ø° ÀÎÀÚ¿¡ ´ëÇؼ­ Á» ´õ »ý°¢ÇØ º¾½Ã´Ù. ¿ì¸®°¡ »ç¿ëÀÚ¿¡°Ô Á¦°øÇÏ´Â °ÍÀº ¾î¶² ¼ö½Ä(expression)ÀÌ ÂüÀ̳Ä, °ÅÁþÀÌ³Ä ÇÏ´Â °ÍÀ» ¹¯±â À§ÇÑ °ÍÀÔ´Ï´Ù. ¸¸¾à À§ÀÇ ÇÔ¼ö¿¡¼­ ¡®condition¡¯ÀÌ int ŸÀÔÀ̶ó°í °¡Á¤ÇØ º¾½Ã´Ù. ÀÌ °æ¿ì ´ÙÀ½°ú °°ÀÌ ¸í·ÉÀ» ³»¸°´Ù¸é ÄÄÆÄÀÏ·¯¿¡ µû¶ó¼­´Â ŸÀÔ º¯È¯(type conversion)¿¡ µû¸¥ °æ°í¸¦ Ãâ·ÂÇÒ ¼öµµ ÀÖ½À´Ï´Ù:
message_logger(3.2, "some log message");
µû¶ó¼­ conditionÀ» ¾î¶² ƯÁ¤ÇÑ Å¸ÀÔÀÇ ÆĶó¸ÞÅÍ·Î ¾²±â¿¡´Â ¹«¸®°¡ ÀÖ½À´Ï´Ù. »ý°¢Çغ» °á°ú, xassert()ó·³ ¸ÅÅ©·Î·Î ¾²¸é ½±°Ô ÇØ°áµÉ °Í °°½À´Ï´Ù. ±×·¡¼­ ´ÙÀ½°ú °°ÀÌ ¸¸µé¾îº¸¾Ò½À´Ï´Ù:
#define MLOG(condition, ...)    ((condition) ? mlog(__VA_ARGS__) : 0)
Áï, À§¿Í °°ÀÌ ÇÏ¸é ¡®condition¡¯¿¡ Ưº°ÇÑ Å¸ÀÔÀ» ÁöÁ¤ÇÑ °ÍÀÌ ¾Æ´Ï±â ¶§¹®¿¡ ÄÄÆÄÀÏ·¯°¡ °æ°í¸¦ ÁÖ´Â °æ¿ì´Â ¾øÀ» °Í °°½À´Ï´Ù. ¿©±â¿¡¼­ mlog()´Â ´Ü¼øÈ÷ printf(3)¿Í °°Àº ÆĶó¸ÞÅ͸¦ ¹Þ½À´Ï´Ù.

Stream Buffer

mlog() ÇÔ¼ö´Â Á¶±Ý À̵û°¡ ¸¸µé¾î º¸±â·Î ÇÏ°í, ÀÌ ¸ðµâÀÌ Á¦°øÇØ¾ß ÇÒ °ÍµéÀ» Á» ´õ »ý°¢ÇØ º¸±â·Î ÇսôÙ. ÀÏ´Ü »ç¿ëÀÚ°¡ Ưº°È÷ ÁöÁ¤ÇÏÁö ¾Ê¾Ò´Ù¸é ·Î±×´Â ÁöÁ¤ÇÑ ½ºÆ®¸²À¸·Î Ãâ·ÂµÇ°Ô ÇսôÙ. ÀÌ·¸°Ô Çϱâ À§ÇÏ¿©, ´ÙÀ½°ú °°ÀÌ ·Î±×¿ë ½ºÆ®¸²À» °¡Áö°í ÀÖ´Â °Ô ÁÁÀ» °Í °°½À´Ï´Ù:
static FILE *mlog_stream;
±×·¡¼­ ¡®mlog_stream¡¯ÀÌ ³Î(null)ÀÎ °æ¿ì¿¡ ·Î±×¸¦ Ãâ·ÂÇÏÁö ¾Êµµ·Ï ¸¸µé °ÍÀÔ´Ï´Ù. ±×¸®°í ÀÌ ¡®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;
}
mlog_get_stream()Àº ¼³¸íÇÒ ÇÊ¿äµµ ¾ø´Â °£´ÜÇÑ ÇÔ¼öÀÔ´Ï´Ù. mlog_set_stream()ÀÇ °æ¿ì, setvbuf(3)¸¦ ºÎ¸£´Â °ÍÀ» »©³õ°í´Â ´Ü¼øÈ÷ ¡®mlog_stream¡¯¿¡ ÁÖ¾îÁø ÀÎÀÚ¸¦ ´ëÀÔÇÏ´Â ÇÔ¼öÀÔ´Ï´Ù. ¿©±â¿¡¼­ setvbuf()°¡ ÇÏ´Â ÀÏÀº ÁÖ¾îÁø ½ºÆ®¸²¿¡ ´ëÇÑ ³»ºÎ ¹öÆÛ¸¦ ¼³Á¤ÇÏ´Â °ÍÀÔ´Ï´Ù.

¿©·¯ºÐÀº Ç¥ÁØ ÀÔ·Â ½ºÆ®¸², ¡®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;
}
À§ ÇÁ·Î±×·¥(tmp.c)À» Á¦ ½Ã½ºÅÛ¿¡¼­ ÄÄÆÄÀÏÇÏ°í ½ÇÇàÇÑ °á°ú´Â ´ÙÀ½°ú °°½À´Ï´Ù:
$ 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);
ÀÏ´Ü syslog(3)´Â printf(3)¿Í ºñ½ÁÇÑ ÀÎÅÍÆäÀ̽º¸¦ Á¦°øÇϸç, ¸¶Áö¸· vsyslog(3)ÀÇ °æ¿ì, vprintf(3)¿Í À¯»çÇÑ ÀÎÅÍÆäÀ̽º¸¦ Á¦°øÇÕ´Ï´Ù. ½Ã½ºÅÛ¿¡ µû¶ó¼­ vsyslog(3)¸¦ Á¦°øÇÏÁö ¾Ê´Â °æ¿ìµµ ÀÖ½À´Ï´Ù. ÀÏ´Ü syslog(3)·Î ¸Þ½ÃÁö¸¦ Ãâ·ÂÇϱâ Àü¿¡ openlog(3)¸¦ ºÒ·¯¼­ ÃʱâÈ­ÇØ¾ß Çϸç, ¸ðµç ·Î±×¸¦ ´Ù Ãâ·ÂÇÑ ÈÄ¿¡´Â closelog(3)·Î Á¾·áÇÕ´Ï´Ù. ÀÚ¼¼ÇÑ »çÇ×Àº ¸Å´º¾ó ÆäÀÌÁö¸¦ Âü°íÇϱ⠹ٶø´Ï´Ù.

mlog()

´Ù½Ã º»·ÐÀ¸·Î µ¹¾Æ¿Í¼­, ÀÌÁ¦ mlog()¸¦ ¸¸µé¾î º¸°Ú½À´Ï´Ù. ¸ÕÀú, mlog()ÀÇ Ãâ·ÂÀº ´ÙÀ½ ²Ã·Î Ãâ·ÂµÉ °ÍÀÔ´Ï´Ù: ½Ã°£: ÇÁ·Î±×·¥À̸§ [PID]: ¸Þ½ÃÁö ½Ã°£À» Ãâ·ÂÇϱâ À§ÇØ, ¿ì¸®´Â time(2), localtime(3), strftime(3)À» ¾²·Á°í ÇÕ´Ï´Ù. ÇÁ·Î±×·¥ À̸§Àº Àü¿ª º¯¼ö ¡®program_name¡¯¿¡ ÀúÀåµÇ¾î ÀÖ´Ù°í °¡Á¤ÇÏ°Ú½À´Ï´Ù. ÇÁ·Î¼¼½º id(pid)´Â getpid(2)¸¦ ½á¼­ ¾òÀ¸·Á°í ÇÕ´Ï´Ù. ½Ã°£À» ¾ò¾î³»´Â ÇÔ¼ö´Â ´ÙÀ½°ú °°ÀÌ ¸¸µé°Ú½À´Ï´Ù:
static const char *current_time(void);
mlog()´Â ½ºÆ®¸²°ú syslog(3) ÀÎÅÍÆäÀ̽º µÑ Áß Çϳª·Î Ãâ·ÂÀ» Çϱ⠶§¹®¿¡, ¾î´À ÂÊÀ¸·Î Ãâ·ÂÀ» ÇÒ Áö Á¤Ã¥(policy)À» °áÁ¤ÇØ¾ß ÇÕ´Ï´Ù. ´ÙÀ½°ú °°ÀÌ using_stream()À» ¸¸µé¾î¼­ ÀÌ ÇÔ¼ö°¡ ÂüÀ» ¸®ÅÏÇÏ¸é ½ºÆ®¸²À¸·Î Ãâ·ÂÇϵµ·Ï ÇÏ°Ú½À´Ï´Ù.
static int using_stream(void);
À§ µÎ ÇÔ¼ö¸¦ ÀÌ¹Ì ¸¸µé¾ú´Ù°í °¡Á¤ÇÏ°í, syslog(3) ÀÎÅÍÆäÀ̽ºµµ ÃʱâÈ­µÇ¾î ÀÖ´Ù°í °¡Á¤ÇÏ°í, mlog()¸¦ ¸¸µé¾î º¾½Ã´Ù. ¾îÂ÷ÇÇ printf(3)¿Í ºñ½ÁÇÑ ÀÏÀ» Çϱ⠶§¹®¿¡, ¾Õ¿¡¼­ ¸¸µç ASSERT()¿Í ¸Å¿ì ºñ½ÁÇÕ´Ï´Ù. ¸ÕÀú Àüü mlog()ÀÇ »À´ë´Â ´ÙÀ½°ú °°½À´Ï´Ù:

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);
syslogd(8)·Î ¸Þ½ÃÁö¸¦ º¸³¾ °æ¿ì (Áï, using_stream()ÀÌ °ÅÁþÀ» ¸®ÅÏÇÒ °æ¿ì)¸¦ »ý°¢ÇØ º¾½Ã´Ù. ¸ÕÀú vsyslog()°¡ Á¦°øµÇÁö ¾Ê´Â´Ù¸é, ¿ì¸®´Â mlog()ÀÇ °¡º¯ ÀÎÀÚ ºÎºÐÀ» syslog(3)·Î ÀüÇØÁÙ ¹æ¹ýÀÌ ¾ø½À´Ï´Ù. µû¶ó¼­ ÇϳªÀÇ ¹öÆÛ¸¦ ¸¸µé¾î¼­ ¿©±â¿¡´Ù ·Î±× ¸Þ½ÃÁö¸¦ Æ÷¸ÅÆÃÇÏ¿© ÀúÀåÇÑ ´ÙÀ½, ÀÌ ¹öÆÛ¸¦ syslog(3)¿¡ Àü´ÞÇØ¾ß ÇÕ´Ï´Ù. À̸¦ À§Çؼ­ ¿ì¸®´Â ¹öÆÛ¸¦ ÁغñÇØ¾ß Çϸç, ¹öÆÛ¿¡ Æ÷¸ÅÆÃÇÑ ¸Þ½ÃÁö¸¦ ÀúÀåÇϱâ À§Çؼ­ vsnprintf(3)¸¦ ½á¾ß ÇÕ´Ï´Ù.
#define MLOG_BUFFER_MAX      1024
static char mlog_buffer[MLOG_BUFFER_MAX];
¶ÇÇÑ vsyslog()°¡ Á¦°øµÇÁö ¾Ê´Â °æ¿ì¿Í Á¦°øµÇ´Â °æ¿ì¸¦ ±¸º°Çϱâ À§ÇØ, ¿ì¸®´Â HAVE_VSYSLOG¶ó´Â ¸ÅÅ©·Î¸¦ µÎ°í Á¦°øµÇ´Â °æ¿ì¿¡¸¸ ÀÌ ¸ÅÅ©·Î¸¦ Á¤ÀÇÇÒ °ÍÀÔ´Ï´Ù. ±× °á°ú ½ÇÁ¦ ÄÚµå ºÎºÐÀº ´ÙÀ½°ú °°½À´Ï´Ù:
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 */
vsprintf(3)¸¦ ¾²Áö ¾Ê°í, Á¶±Ý ´õ º¹ÀâÇÑ vsnprintf(3)¸¦ ¾´ ÀÌÀ¯´Â °£´ÜÇÕ´Ï´Ù. ÁÖ¾îÁø ¹öÆÛ, mlog_buffer°¡ ¿À¹öÇ÷ο찡 ÀϾ °æ¿ì ¹ß»ýÇÒ ¼ö ÀÖ´Â ¿Àµ¿ÀÛÀ» ¸·±â À§Çؼ­ÀÔ´Ï´Ù. À§ Äڵ忡¼­ va_end()¸¦ ºÎ¸¥ ´ÙÀ½ÀÇ ¡®if¡¯´Â ÀÌ ¿À¹öÇ÷ο찡 ÀϾ´ÂÁö °Ë»çÇÏ´Â ºÎºÐÀÔ´Ï´Ù. Áï, vsnprintf()ÀÇ ¸®ÅÏ°ªÀÌ ¾ç¼öÀÌ°í, MLOG_BUFFER_MAXº¸´Ù ÀÛÀ¸¸é, mlog_buffer¿¡ ¿¡·¯¾øÀÌ Æ÷¸ÅÆõǾú´Ù°í ÇÒ ¼ö ÀÖ½À´Ï´Ù. ÀÏ´Ü ¸Þ½ÃÁö°¡ mlog_buffer¿¡ ÀúÀåµÇ¾úÀ¸¸é, syslog(3)·Î º¸³À´Ï´Ù. HAVE_VSYSLOG°¡ Á¤ÀÇµÈ °æ¿ìµ¥´Â °£´ÜÇÏ°Ô vsyslog()¸¦ ÅëÇØ ¸Þ½ÃÁö¸¦ Àü´ÞÇÕ´Ï´Ù. mlog()¿¡ ´ëÇÑ ¿ÏÀüÇÑ ÄÚµå´Â ´ÙÀ½°ú °°½À´Ï´Ù:
#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

TODO


ID
Password
Join
Economy makes men independent.


sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2008-04-10 18:26:22
Processing time 0.0081 sec