这是定义的一个常量数组,分别和系统日志设备对映起来。在操作的日志文件中,可以看到和这相关的配置,位于/etc/syslog.conf文件中,如:
[cpp]
# Log all kernel messages to the console.
# Logging much else clutters up the screen.
#kern.* /dev/console
# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none;cron.none /var/log/messages
# The authpriv file has restricted access.
authpriv.* /var/log/secure
# Log all the mail messages in one place.
mail.* -/var/log/maillog
# Log cron stuff
cron.* /var/log/cron
# Everybody gets emergency messages
*.emerg *
# Save news errors of level crit and higher in a special file.
uucp,news.crit /var/log/spooler
# Save boot messages also to boot.log
local7.* /var/log/boot.log
local5.* /var/log/client.log
这上面就配置了local7和local5这两个本地日志设备,其实就是两个日志文件。其实在系统的头文件中就是<sys/syslog.h>中,也定义了这样的一个数组:
[cpp]
#ifdef SYSLOG_NAMES
CODE facilitynames[] =
{
{ "auth", LOG_AUTH },
{ "authpriv", LOG_AUTHPRIV },
{ "cron", LOG_CRON },
{ "daemon", LOG_DAEMON },
{ "ftp", LOG_FTP },
{ "kern", LOG_KERN },
{ "lpr", LOG_LPR },
{ "mail", LOG_MAIL },
{ "mark", INTERNAL_MARK }, /* INTERNAL */
{ "news", LOG_NEWS },
{ "security", LOG_AUTH }, /* DEPRECATED */
{ "syslog", LOG_SYSLOG },
{ "user", LOG_USER },
{ "uucp", LOG_UUCP },
{ "local0", LOG_LOCAL0 },
{ "local1", LOG_LOCAL1 },
{ "local2", LOG_LOCAL2 },
{ "local3", LOG_LOCAL3 },
{ "local4", LOG_LOCAL4 },
{ "local5", LOG_LOCAL5 },
{ "local6", LOG_LOCAL6 },
{ "local7", LOG_LOCAL7 },
{ NULL, -1 }
};
#endif
前面说为了便宜传递参数,我们假设我们传递的系统日志设备为local5这种形式,但要求是LOG_LOCAL5这个宏,因此我们根据上面的数组,作个转换:
[cpp]
static int _log_facility(const char *facility) {
log_facility_t *lp;
if (facility == NULL) {
return -1;
}
for (lp = _log_facilities; lp->facility; lp++) {
if (!strcasecmp(lp->facility, facility)) {
break;
}
}
return lp->number;
}
这个函数会根据local5,找到并返回LOG_LOCAL5。
三,创建日志模块
代码如下:
[cpp]
log_t log_new(log_type_t type,const char *ident, const char *facility)
{
log_t log;
int fnum = 0;
log = (log_t) calloc(1, sizeof(struct log_st));
log->type = type;
if(type == log_SYSLOG) { // 系统日志
fnum = _log_facility(facility);
if (fnum < 0)
fnum = LOG_LOCAL7;
openlog(ident, LOG_PID, fnum); // 下面会对openlog系统调用进行说明。
return log;
}
else if(type == log_STDOUT) { // 标准输出。
log->file = stdout;
return log;
}
log->file = fopen(ident, "a+");
if(log->file == NULL) // 文件,如果打开文件失败,会将其定义为标准输出。
{
log->type = log_STDOUT;
log->file = stdout;
}
return log;
}