注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Tsecer的回音岛

Tsecer的博客

 
 
 

日志

 
 

syslog-ng对log格式解析及内置宏  

2012-09-09 13:13:11|  分类: windows系统编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
一、syslog-ng对于log格式的解析
syslog的格式其实是有专门的rfc文档可以参考的,但是比较复杂,也没时间看。但是可以确定的是syslog存在很多的格式,而syslog-ng作为一个通用的日志工具,它应该能够识别出各种log的格式并进行正确的解析。看一下linux下的syslog格式可以知道,即使是linux下的log,它的格式也不是完全相同的,而对于syslog-ng来说,它包含需要通过一个log信息本身得到这个报文的的信息,能够识别出哪些是日志的头,哪些是日志的实体内容。
二、再次看一下linux下C库对于syslog的实现
__vsyslog_chk(int pri, int flag, const char *fmt, va_list ap)

        __fsetlocking (f, FSETLOCKING_BYCALLER);
        prioff = fprintf (f, "<%d>", pri); 优先级是必须的,使用尖括号保存
        (void) time (&now);
        f->_IO_write_ptr += __strftime_l (f->_IO_write_ptr,
                          f->_IO_write_end
                          - f->_IO_write_ptr,
                          "%h %e %T ",
                          __localtime_r (&now, &now_tm),
                          _nl_C_locobj_ptr);日志时间记录,这个感觉是一个日志的基本功能
        msgoff = ftell (f);
        if (LogTag == NULL)
          LogTag = __progname;
        if (LogTag != NULL)
          fputs_unlocked (LogTag, f);log记录产生问题的进程名,一般都会有,但是也可能没有
        if (LogStat & LOG_PID)
          fprintf (f, "[%d]", (int) __getpid ());是否通过中括号记录进程的pid是可选的
        if (LogTag != NULL)
          {
        putc_unlocked (':', f);
        putc_unlocked (' ', f);
          }
三、通过命令行测试一下这个工具记录内容
[root@Harry ServerAndCLient]# logger tsecer test syslog format
[root@Harry ServerAndCLient]# cat /var/log/messages
Sep  9 11:11:01 localhost kernel: imklog 4.4.1, log source = /proc/kmsg started.
Sep  9 11:11:01 localhost rsyslogd: [origin software="rsyslogd" swVersion="4.4.1" x-pid="1059" x-info="http://www.rsyslog.com"] (re)start
……
Sep  9 12:10:04 localhost root: tsecer test syslog format
其中的一个问题是,在日志的最开始并没有使用 <pri>格式记录的本次日志事件的优先级,通过strace跟踪这个命令,可以发现日志打印的时候是有的,应该是中间的日志工具转发的时候丢掉了这个信息。

[root@Harry ServerAndCLient]# strace logger tsecer test syslog format
execve("/usr/bin/logger", ["logger", "tsecer", "test", "syslog", "format"], [/* 45 vars */]) = 0
brk(0)                                  = 0x9b75000
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb781f000
……
send(1, "<13>Sep  9 12:12:05 root: tsecer"..., 51, MSG_NOSIGNAL) = 51
通过ps看一下系统的日志记录工具,
[root@Harry ServerAndCLient]# ps aux | grep log
root      1059  0.0  0.1  35536  1372 ?        Sl   Sep05   0:03 /sbin/rsyslogd -c 4
root      1350  0.0  0.1   6116  1392 ?        S    Sep05   0:00 /usr/sbin/wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant.conf -u -f /var/log/wpa_supplicant.log
root      1610  0.0  0.3  49096  3208 ?        Sl   Sep05   0:00 /usr/bin/gnome-keyring-daemon --daemonize --login
root      5219  0.0  0.0   4224   704 pts/0    S+   12:13   0:00 grep log
所以应该是这个工具对日志记录内容作了修改,暂且不管。
四、对于syslog-ng的调试
杀死rsyslogd,然后启动syslog-ng命令,使用gdb附加到syslog-ng命令,然后在recvfrom函数打断点,使用logger触发日志记录,此时的调用链信息为
(gdb) bt
#0  0x00693360 in recvfrom () from /lib/libc.so.6
#1  0x00478407 in log_transport_plain_read_method (s=0x8a73958, buf=0x8a789b0,
    buflen=8192, sa=0xbfc90f44) at logtransport.c:106
#2  0x00478675 in log_transport_read (self=0x8a73958, buf=0x8a789b0, count=8192,
    sa=0xbfc90f44) at logtransport.h:60
#3  0x0047a7c0 in log_proto_buffered_server_read_data (self=0x8a73500, buf=
    0x8a789b0 "8\267r", len=8192, sa=0xbfc90f44) at logproto.c:742
#4  0x0047aa84 in log_proto_buffered_server_fetch (s=0x8a73500, msg=0xbfc90f3c,
    msg_len=0xbfc90f38, sa=0xbfc90f44, may_read=0xbfc90f40) at logproto.c:848
#5  0x00472064 in log_proto_fetch (s=0x8a73500, msg=0xbfc90f3c, msg_len=
    0xbfc90f38, sa=0xbfc90f44, may_read=0xbfc90f40) at logproto.h:89
#6  0x004728b7 in log_reader_fetch_log (self=0x8a73560, proto=0x8a73500)
    at logreader.c:332
#7  0x00472615 in log_reader_fd_dispatch (source=0x8a735d8, callback=0, user_data=
    0x0) at logreader.c:231
#8  0x0023f118 in g_main_context_dispatch () from /lib/libglib-2.0.so.0
#9  0x00242a48 in ?? () from /lib/libglib-2.0.so.0
#10 0x00242b74 in g_main_context_iteration () from /lib/libglib-2.0.so.0
#11 0x08049bed in main_loop_run (cfg=0xbfc911b4) at main.c:170
#12 0x0804a349 in main (argc=1, argv=0xbfc91274) at main.c:448
显示读取内容
(gdb) p (char*)buf
$2 = 0x8a789b0 "<13>Sep  9 12:36:01 root: syslogng\247\b\300\211\247\b"
(gdb)
在log_reader_handle_line函数中,该pri信息依然是存在的
Continuing.

Breakpoint 2, log_reader_handle_line (self=0x8a73560, line=
    0x8a789b0 "<13>Sep  9 12:36:01 root: syslogng\247\b\300\211\247\b", length=
    34, saddr=0x0) at logreader.c:273
273      LogPathOptions path_options = LOG_PATH_OPTIONS_INIT;
(gdb) bt
#0  log_reader_handle_line (self=0x8a73560, line=
    0x8a789b0 "<13>Sep  9 12:36:01 root: syslogng\247\b\300\211\247\b", length=
    34, saddr=0x0) at logreader.c:273
#1  0x00472987 in log_reader_fetch_log (self=0x8a73560, proto=0x8a73500)
    at logreader.c:356
#2  0x00472615 in log_reader_fd_dispatch (source=0x8a735d8, callback=0, user_data=
    0x0) at logreader.c:231
#3  0x0023f118 in g_main_context_dispatch () from /lib/libglib-2.0.so.0
#4  0x00242a48 in ?? () from /lib/libglib-2.0.so.0
#5  0x00242b74 in g_main_context_iteration () from /lib/libglib-2.0.so.0
#6  0x08049bed in main_loop_run (cfg=0xbfc911b4) at main.c:170
#7  0x0804a349 in main (argc=1, argv=0xbfc91274) at main.c:448
对于优先级的处理
(gdb) bt
#0  log_msg_parse_pri (self=<value optimized out>, data=<value optimized out>,
    length=<value optimized out>, flags=<value optimized out>,
    default_pri=<value optimized out>) at syslog-format.c:78
#1  0x00409bef in log_msg_parse_legacy (parse_options=<value optimized out>,
    data=<value optimized out>, length=<value optimized out>,
    self=<value optimized out>) at syslog-format.c:872
#2  0x0040a030 in syslog_format_handler (parse_options=<value optimized out>,
    data=<value optimized out>, length=<value optimized out>,
    self=<value optimized out>) at syslog-format.c:1085
#3  0x0046a2b8 in log_msg_new (msg=
    0x8a789b0 "<13>Sep  9 12:36:01 root: syslogng\247\b\300\211\247\b", length=
    34, saddr=0x0, parse_options=0x8a8f4f4) at logmsg.c:726
#4  0x0047277f in log_reader_handle_line (self=0x8a73560, line=
    0x8a789b0 "<13>Sep  9 12:36:01 root: syslogng\247\b\300\211\247\b", length=
    34, saddr=0x0) at logreader.c:280
#5  0x00472987 in log_reader_fetch_log (self=0x8a73560, proto=0x8a73500)
    at logreader.c:356
#6  0x00472615 in log_reader_fd_dispatch (source=0x8a735d8, callback=0, user_data=
    0x0) at logreader.c:231
#7  0x0023f118 in g_main_context_dispatch () from /lib/libglib-2.0.so.0
#8  0x00242a48 in ?? () from /lib/libglib-2.0.so.0
#9  0x00242b74 in g_main_context_iteration () from /lib/libglib-2.0.so.0
#10 0x08049bed in main_loop_run (cfg=0xbfc911b4) at main.c:170
---Type <return> to continue, or q <return> to quit---
#11 0x0804a349 in main (argc=1, argv=0xbfc91274) at main.c:448
(gdb)

其中参数

/* writer constructor flags */
#define LW_DETECT_EOF      0x0001
#define LW_FORMAT_FILE     0x0002
#define LW_FORMAT_PROTO    0x0004
#define LW_ALWAYS_WRITABLE 0x0008
#define LW_SYSLOG_PROTOCOL 0x0010

(gdb) p self->flags
$12 = 10
(gdb)

在记录函数中
(gdb) bt
#0  log_writer_format_log (self=0x8a77f58, lm=0x8a77f08, result=0x8a777d0)
    at logwriter.c:647
#1  0x0047507a in log_writer_flush (self=0x8a77f58, flush_all=0)
    at logwriter.c:722
#2  0x00473da4 in log_writer_fd_dispatch (source=0x8a787b8, callback=0, user_data=
    0x0) at logwriter.c:263
#3  0x0023f118 in g_main_context_dispatch () from /lib/libglib-2.0.so.0
#4  0x00242a48 in ?? () from /lib/libglib-2.0.so.0
#5  0x00242b74 in g_main_context_iteration () from /lib/libglib-2.0.so.0
#6  0x08049bed in main_loop_run (cfg=0xbfc911b4) at main.c:170
#7  0x0804a349 in main (argc=1, argv=0xbfc91274) at main.c:448
(gdb) p self


          if (self->flags & LW_FORMAT_FILE)
            {
              log_stamp_format(stamp, result, self->options->template_options.ts_format,
                               time_zone_info_get_offset(self->options->template_options.time_zone_info[LTZ_SEND], stamp->time.tv_sec),
                               self->options->template_options.frac_digits);
            }
          else if (self->flags & LW_FORMAT_PROTO)
            {
              g_string_sprintf(result, "<%d>", lm->pri);

              /* always use BSD timestamp by default, the use can override this using a custom template */
              log_stamp_append_format(stamp, result, TS_FMT_BSD,
                                      time_zone_info_get_offset(self->options->template_options.time_zone_info[LTZ_SEND], stamp->time.tv_sec),
                                      self->options->template_options.frac_digits);
            }
五、syslog-ng内部宏的处理
void
log_msg_registry_init(void)
{
  gint i;

  logmsg_registry = nv_registry_new(builtin_value_names);
  nv_registry_add_alias(logmsg_registry, LM_V_MESSAGE, "MSG");
  nv_registry_add_alias(logmsg_registry, LM_V_MESSAGE, "MSGONLY");
  nv_registry_add_alias(logmsg_registry, LM_V_HOST, "FULLHOST");
  nv_registry_add_alias(logmsg_registry, LM_V_HOST_FROM, "FULLHOST_FROM");

  for (i = 0; macros[i].name; i++)
    {
      if (nv_registry_get_handle(logmsg_registry, macros[i].name) == 0)
        {
          NVHandle handle;

          handle = nv_registry_alloc_handle(logmsg_registry, macros[i].name);
          nv_registry_set_handle_flags(logmsg_registry, handle, (macros[i].id << 8) + LM_VF_MACRO);
        }
    }

  /* register $0 - $255 in order */
  for (i = 0; i < 255; i++)
    {
      gchar buf[8];

      g_snprintf(buf, sizeof(buf), "%d", i);
      match_handles[i] = nv_registry_alloc_handle(logmsg_registry, buf);
    }
}
其中还定义了另外一些不依赖于日志内容的宏
syslog-ng-3.2.3\lib\templates.c
LogMacroDef macros[] =
{
        { "FACILITY", M_FACILITY },
        { "FACILITY_NUM", M_FACILITY_NUM },
        { "PRIORITY", M_LEVEL },
        { "LEVEL", M_LEVEL },
        { "LEVEL_NUM", M_LEVEL_NUM },
        { "TAG", M_TAG },
        { "TAGS", M_TAGS },
        { "BSDTAG", M_BSDTAG },
        { "PRI", M_PRI },

        { "DATE",           M_DATE },
        { "FULLDATE",       M_FULLDATE },
        { "ISODATE",        M_ISODATE },
        { "STAMP",          M_STAMP },
        { "YEAR",           M_YEAR },
        { "YEAR_DAY",       M_YEAR_DAY },
        { "MONTH",          M_MONTH },
        { "MONTH_WEEK",     M_MONTH_WEEK },
        { "MONTH_ABBREV",   M_MONTH_ABBREV },
        { "MONTH_NAME",     M_MONTH_NAME },
        { "DAY",            M_DAY },
        { "HOUR",           M_HOUR },
        { "MIN",            M_MIN },
        { "SEC",            M_SEC },
        { "WEEKDAY",        M_WEEK_DAY_ABBREV }, /* deprecated */
        { "WEEK_DAY",       M_WEEK_DAY },
        { "WEEK_DAY_ABBREV",M_WEEK_DAY_ABBREV },
        { "WEEK_DAY_NAME",  M_WEEK_DAY_NAME },
        { "WEEK",           M_WEEK },
        { "TZOFFSET",       M_TZOFFSET },
        { "TZ",             M_TZ },
        { "UNIXTIME",       M_UNIXTIME },

        { "R_DATE",           M_RECVD_OFS + M_DATE },
        { "R_FULLDATE",       M_RECVD_OFS + M_FULLDATE },
        { "R_ISODATE",        M_RECVD_OFS + M_ISODATE },
        { "R_STAMP",          M_RECVD_OFS + M_STAMP },
        { "R_YEAR",           M_RECVD_OFS + M_YEAR },
        { "R_YEAR_DAY",       M_RECVD_OFS + M_YEAR_DAY },
        { "R_MONTH",          M_RECVD_OFS + M_MONTH },
        { "R_MONTH_WEEK",     M_RECVD_OFS + M_MONTH_WEEK },
        { "R_MONTH_ABBREV",   M_RECVD_OFS + M_MONTH_ABBREV },
        { "R_MONTH_NAME",     M_RECVD_OFS + M_MONTH_NAME },
        { "R_DAY",            M_RECVD_OFS + M_DAY },
        { "R_HOUR",           M_RECVD_OFS + M_HOUR },
        { "R_MIN",            M_RECVD_OFS + M_MIN },
        { "R_SEC",            M_RECVD_OFS + M_SEC },
        { "R_WEEKDAY",        M_RECVD_OFS + M_WEEK_DAY_ABBREV }, /* deprecated */
        { "R_WEEK_DAY",       M_RECVD_OFS + M_WEEK_DAY },
        { "R_WEEK_DAY_ABBREV",M_RECVD_OFS + M_WEEK_DAY_ABBREV },
        { "R_WEEK_DAY_NAME",  M_RECVD_OFS + M_WEEK_DAY_NAME },
        { "R_WEEK",           M_RECVD_OFS + M_WEEK },
        { "R_TZOFFSET",       M_RECVD_OFS + M_TZOFFSET },
        { "R_TZ",             M_RECVD_OFS + M_TZ },
        { "R_UNIXTIME",       M_RECVD_OFS + M_UNIXTIME },

        { "S_DATE",           M_STAMP_OFS + M_DATE },
        { "S_FULLDATE",       M_STAMP_OFS + M_FULLDATE },
        { "S_ISODATE",        M_STAMP_OFS + M_ISODATE },
        { "S_STAMP",          M_STAMP_OFS + M_STAMP },
        { "S_YEAR",           M_STAMP_OFS + M_YEAR },
        { "S_YEAR_DAY",       M_STAMP_OFS + M_YEAR_DAY },
        { "S_MONTH",          M_STAMP_OFS + M_MONTH },
        { "S_MONTH_WEEK",     M_STAMP_OFS + M_MONTH_WEEK },
        { "S_MONTH_ABBREV",   M_STAMP_OFS + M_MONTH_ABBREV },
        { "S_MONTH_NAME",     M_STAMP_OFS + M_MONTH_NAME },
        { "S_DAY",            M_STAMP_OFS + M_DAY },
        { "S_HOUR",           M_STAMP_OFS + M_HOUR },
        { "S_MIN",            M_STAMP_OFS + M_MIN },
        { "S_SEC",            M_STAMP_OFS + M_SEC },
        { "S_WEEKDAY",        M_STAMP_OFS + M_WEEK_DAY_ABBREV }, /* deprecated */
        { "S_WEEK_DAY",       M_STAMP_OFS + M_WEEK_DAY },
        { "S_WEEK_DAY_ABBREV",M_STAMP_OFS + M_WEEK_DAY_ABBREV },
        { "S_WEEK_DAY_NAME",  M_STAMP_OFS + M_WEEK_DAY_NAME },
        { "S_WEEK",           M_STAMP_OFS + M_WEEK },
        { "S_TZOFFSET",       M_STAMP_OFS + M_TZOFFSET },
        { "S_TZ",             M_STAMP_OFS + M_TZ },
        { "S_UNIXTIME",       M_STAMP_OFS + M_UNIXTIME },

        { "SDATA", M_SDATA },
        { "MSGHDR", M_MSGHDR },
        { "SOURCEIP", M_SOURCE_IP },
        { "SEQNUM", M_SEQNUM },

        /* values that have specific behaviour with older syslog-ng config versions */
        { "MSG", M_MESSAGE },
        { "MESSAGE", M_MESSAGE },
        { "HOST", M_HOST },
        { NULL, 0 }
};
这些宏的展开函数位于
log_macro_expand(GString *result, gint id, gboolean escape, LogTemplateOptions *opts, gint tz, gint32 seq_num, LogMessage *msg)
中。
  评论这张
 
阅读(2355)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017