linux syslogd 源码,syslogd 详解二

相关博文:

syslogd 详解一

syslogd 详解三

1. 前言

上一篇博文中详细了分析了syslogd的架构,解析了syslogd的调用过程,以及syslog.conf 的详细使用方法,这一篇通过对syslogd 的源码的解析,进一步分析syslogd 的使用方法以及注意事项。

2. priority

#defineLOG_EMERG0/* system is unusable */

#defineLOG_ALERT1/* action must be taken immediately */

#defineLOG_CRIT2/* critical conditions */

#defineLOG_ERR3/* error conditions */

#defineLOG_WARNING4/* warning conditions */

#defineLOG_NOTICE5/* normal but significant condition */

#defineLOG_INFO6/* informational */

#defineLOG_DEBUG7/* debug-level messages */

syslogd 支持的priority 定义在syslog.h 中,占用3个bit 位。

syslogd 命令行中 -l 选项控制 logLevel 变量,而这个logLevel 体现的就是这里的priority,代码中:

if (LOG_PRI(pri) < G.logLevel) {

#if ENABLE_FEATURE_IPC_SYSLOG

if ((option_mask32 & OPT_circularlog) && G.shbuf) {

log_to_shmem(G.printbuf);

return;

}

#endif

log_locally(now, G.printbuf, &G.logFile);

}

如果定义的priority 比设置的logLevel 大,那么log 会被忽略掉。

3. facility

/* facility codes */

#defineLOG_KERN(0<<3)/* kernel messages */

#defineLOG_USER(1<<3)/* random user-level messages */

#defineLOG_MAIL(2<<3)/* mail system */

#defineLOG_DAEMON(3<<3)/* system daemons */

#defineLOG_AUTH(4<<3)/* security/authorization messages */

#defineLOG_SYSLOG(5<<3)/* messages generated internally by syslogd */

#defineLOG_LPR(6<<3)/* line printer subsystem */

#defineLOG_NEWS(7<<3)/* network news subsystem */

#defineLOG_UUCP(8<<3)/* UUCP subsystem */

#defineLOG_CRON(9<<3)/* clock daemon */

#defineLOG_AUTHPRIV(10<<3)/* security/authorization messages (private) */

#defineLOG_FTP(11<<3)/* ftp daemon */

/* other codes through 15 reserved for system use */

#defineLOG_LOCAL0(16<<3)/* reserved for local use */

#defineLOG_LOCAL1(17<<3)/* reserved for local use */

#defineLOG_LOCAL2(18<<3)/* reserved for local use */

#defineLOG_LOCAL3(19<<3)/* reserved for local use */

#defineLOG_LOCAL4(20<<3)/* reserved for local use */

#defineLOG_LOCAL5(21<<3)/* reserved for local use */

#defineLOG_LOCAL6(22<<3)/* reserved for local use */

#defineLOG_LOCAL7(23<<3)/* reserved for local use */

#defineLOG_NFACILITIES24/* current number of facilities */

#defineLOG_FACMASK0x03f8/* mask to extract facility part */

syslogd 中facility 应该定义了24个,前 16个是系统使用,后8个是用户使用。

但是从LOG_FACMASK 看,实际上syslogd 给facility 7个bit 位的空间,也就是说实际上可以支持 128个facility。除去系统的16个,用户可以定义112 个facility。

4. syslogd 命令行选项

通过代码:

opts = getopt32(argv, "^"OPTION_STR"\0""=0", OPTION_PARAM);

可以得知syslogd 支持的命令行选项有:

#define OPTION_STR "m:nO:l:S" \

IF_FEATURE_ROTATE_LOGFILE("s:" ) \

IF_FEATURE_ROTATE_LOGFILE("b:" ) \

IF_FEATURE_REMOTE_LOG( "R:*") \

IF_FEATURE_REMOTE_LOG( "L" ) \

IF_FEATURE_IPC_SYSLOG( "C::") \

IF_FEATURE_SYSLOGD_DUP( "D" ) \

IF_FEATURE_SYSLOGD_CFG( "f:" ) \

IF_FEATURE_KMSG_SYSLOG( "K" )

即-m -n -O -l -S -s -b -R -L -C -D -f -K。

其中n 、S、L、D 和K 是不带参数的;

其中m、O、l、s、b、R、f是带参数的;

其中C 带可选参数;

-n          运行在前台进程

-O file      log 文件的路径,默认在/var/log/messages

-l N          log 可以扩充到N个

-S           较小的输出

-R host[:port]   远程存放log 的主机地址和端口,port为可选,默认为514

-L            log 保存到本地,还是通过网络。默认值只有在-R 指定时候才是网络,其它则是本地。

-C [size_kb]     log 存放到share memory,通过logread 读取,单位为kb。

-K            log保存到kernel buffer中,通过dmesg读取

-s size     log 文件最大空间为size(kb),默认为200kb,设0是关闭限制

-b N         N 个log 文件滚动保存,默认值为1,最大为99,设0 表示只用一个log 文件

文件的接口会以数字区分,0为最新的log文件,数字越小,文件越新

-D            去除重复log

-f              指定syslogd 的config 路径,默认为/etc/syslog.conf

-m MIN     每隔MIN 分钟在log 中做一次标记

通过代码理解选项:

例如,-K

if (option_mask32 & OPT_kmsg) {

log_to_kmsg(pri, msg);

return;

}

例如,-S

if (option_mask32 & OPT_small)

sprintf(G.printbuf, "%s %s\n", timestamp, msg);

else {

char res[20];

parse_fac_prio_20(pri, res);

sprintf(G.printbuf, "%s %.64s %s %s\n", timestamp, G.hostname, res, msg);

}

如果-S,log格式只是时间戳 + 消息

没有-S,log 格式会多host name  和priority

5. facility 名字不能太长

上面第 3 节中说到facility 可以有128 个,用户可以使用其中的112个,但是在定义facility 名字的时候需要注意长度。

static void parse_fac_prio_20(int pri, char *res20)

{

const CODE *c_pri, *c_fac;

c_fac = find_by_val(LOG_FAC(pri) << 3, bb_facilitynames);

if (c_fac) {

c_pri = find_by_val(LOG_PRI(pri), bb_prioritynames);

if (c_pri) {

snprintf(res20, 20, "%s.%s", c_fac->c_name, c_pri->c_name);

return;

}

}

snprintf(res20, 20, "", pri);

}

facility.priority的长度不能多于20个字节,按照prioriy 最长6个字节,那么要求facility 最多为12个字符。

6. 本地和shmem 不能同时

#if ENABLE_FEATURE_SYSLOGD_CFG

{

bool match = 0;

logRule_t *rule;

uint8_t facility = LOG_FAC(pri);

uint8_t prio_bit = 1 << LOG_PRI(pri);

for (rule = G.log_rules; rule; rule = rule->next) {

if (rule->enabled_facility_priomap[facility] & prio_bit) {

log_locally(now, G.printbuf, rule->file);

match = 1;

}

}

if (match)

return;

}

#endif

if (LOG_PRI(pri) < G.logLevel) {

#if ENABLE_FEATURE_IPC_SYSLOG

if ((option_mask32 & OPT_circularlog) && G.shbuf) {

log_to_shmem(G.printbuf);

return;

}

#endif

log_locally(now, G.printbuf, &G.logFile);

}

源码中如果syslog.conf有配置,并且匹配上,就会调用log_locally (第一次log_locally)进行保存,最后直接return;

如果想要保存到本地的同时,也能使用logread 进行读取,那么源码需要适当的改动;

如果syslog.conf 中的配置没有匹配,会优先确认是否输出到shmem,如果shmem 打开,那么本地(第二次log_locally)不会再做保存。如果需要同时保存到shmem 和本地,逻辑需要适当的改动;

相关博文:

syslogd 详解一

syslogd 详解三

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值