· 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
Many changes of mind and mood; do not hesitate too long.


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.0018 sec