linux c使用syslog记录消息

syslog 工具提供了一个集中式日志工具,系统中的所有应用程序都可以使用这个记录日志消息。如下图

syslogd 从两个不同的源接收日志消息:一个是unix domain docket /dev/log,它保存本地产生的消息。另一个是tcp/udp 514端口,保存通过 tcp/ip 网络发送过来的消息。

#include <syslog.h>

void openlog(const char *ident, int log_options, int facility);

ident 为字符串指针,syslog() 输出的每条消息都会包含这个字符串,这个参数的取值通常为程序名,设为NULL 默认就是程序名。

log_options 部分选项如下:

1.LOG_CONS 同时写入到控制台 /dev/console。
2.LOG_NDELAY 立即打开日志系统的连接,默认情况下在首次调用syslog() 时才会连接到/dev/log,为了防止后面访问不到/dev/log,比如在openlog()之后调用chroot()。
3.LOG_PERROR 将消息写入到标准错误和系统日志。
4.LOG_PID 在每条消息中加上调用者的进程ID。

facility 值和 syslog() 的 priority参数

值 描述 
 LOG_AUTH 安全和验证消息
 LOG_AUTHPRIV 私有的安全和验证消息
 LOG_CRON 来自crond和atd消息
 LOG_DAEMON 其他系统daemon消息
 LOG_FTP ftpd消息
 LOG_KERN 内核消息(用户进程无法生成此类消息)
 LOG_LOCALO 保留给本地使用,包括1-7
 LOG_LPR 来及行打印机消息(lpr,lpd,lpc)
 LOG_MAIL 邮件系统消息
 LOG_NEWS 与usenet网络新闻相关消息
 LOG_SYSLOG 来自syslogd 消息
 LOG_USER 用户进程生成的消息(默认值)
 LOG_UUCP 来自uucp系统的消息


#include <syslog.h>

void syslog(int priority, const char *format, ...);

记录日志消息,如果priority省略,则会用openlog()调用指定的 facility 值,如果也省略,默认为LOG_USER。

syslog中的priority参数的level值如下(严重性从最高到最低)

值 描述 
 LOG_EMERG 紧急或令人恐慌的情况
 LOG_ALERT 需要立即处理的情况(如破坏了系统数据库)
 LOG_CRIT 关键情况
 LOG_ERR 常规错误
 LOG_WARNING 警告
 LOG_NOTICE 可能需要处理的普通情况
 LOG_INFO 情报性消息
 LOG_DEBUG 调试消息


#include <syslog.h>

void closelog(void);

当完成日志记录之后可以调用closelog() 来释放分配给/dev/log socket的文件描述符。


#include <syslog.h>

int setlogmask(int mask_priority);

//Returns previous log priority mask

过滤syslog,所有level不在当前掩码设置中的消息都会被丢弃。

下面只记录LOG_ERR及以上的消息。

setlogmask(LOG_MASK(LOG_EMERG) | LOG_MASK(LOG_ALERT) |
LOG_MASK(LOG_CRIT) | LOG_MASK(LOG_ERR));

setlogmask(LOG_UPTO(LOG_ERR));


配置文件 /etc/rsyslog.conf 解释

kern			内核
user			使用者层级产生的信息
mail			邮件相关
daemon			系统服务相关
auth			认证相关
syslog			rsyslogd产生
cron			crontab信息
authpriv		类似auth,但是记录更多信息
ftp				ftp相关
local0-local7	保留给本机用户

debug,info,notice,warn,err,crit,alert,emerg

mail.					记录全部
mail.info				比mail.info严重的都记录下来
mail.=info				只记录info
mail.!info				记录info以外的

#记录所有但是除去news,cron,mail
.;news,cron,mail.none
.;news.none;cron.none;mail.none	

#代表先存buffer,等数据量够大时再一次性写入文件
#加快写入速度,但是系统崩溃的话可能会丢失数据
mail.*					-/var/log/maillog

#开启udp514端口接收其他服务器的syslog日志
$ModLoad imudp
$UDPServerRun 514

#开启tcp514端口接收其他服务器的syslog日志(如果网络不稳定最好用tcp)
$ModLoad imtcp
$InputTCPServerRun 514

#客户端配置tcp
*.* @@192.168.1.3:514

#客户端配置udp
*.* @192.168.1.3:514

例子

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <pthread.h>
#include <syslog.h>

static void usageError(const char *progName){
    fprintf(stderr, "Usage: %s [-p] [-e] [-l level] \"message\"\n", progName);
    fprintf(stderr, "    -p   log PID\n");
    fprintf(stderr, "    -e   log to stderr also\n");
    fprintf(stderr, "    -l   level (g=EMERG; a=ALERT; c=CRIT; e=ERR\n");
    fprintf(stderr, "                w=WARNING; n=NOTICE; i=INFO; d=DEBUG)\n");
    exit(EXIT_FAILURE);
}

int main(int argc, char *argv[]){
    int level, options, opt;

    options = 0;
    level = LOG_INFO;

    while ((opt = getopt(argc, argv, "l:pe")) != -1) {
        switch (opt) {
        case 'l':
            switch (optarg[0]) {
            case 'a': level = LOG_ALERT;        break;
            case 'c': level = LOG_CRIT;         break;
            case 'e': level = LOG_ERR;          break;
            case 'w': level = LOG_WARNING;      break;
            case 'n': level = LOG_NOTICE;       break;
            case 'i': level = LOG_INFO;         break;
            case 'd': level = LOG_DEBUG;        break;
            default:
                printf("Bad facility: %c\n", optarg[0]);
                return 1;
            }
            break;

        case 'p':
            options |= LOG_PID;
            break;

        case 'e':
            options |= LOG_PERROR;
            break;

        default:
            fprintf(stderr, "Bad option\n");
            usageError(argv[0]);
        }
    }

    if (argc != optind + 1)
        usageError(argv[0]);

    openlog(argv[0], options, LOG_USER);
    syslog(LOG_USER | level, "%s", argv[optind]);
    closelog();

    exit(EXIT_SUCCESS);
}

rsyslog.conf配置如下

*.info;mail.none;authpriv.none;cron.none                /var/log/messages
[root@izj6cfw9yi1iqoik31tqbgz c]# ./a.out -p -la "test-alert"
[root@izj6cfw9yi1iqoik31tqbgz c]# ./a.out -p -li "test-info"
[root@izj6cfw9yi1iqoik31tqbgz c]# ./a.out -p -ld "test-debug"
[root@izj6cfw9yi1iqoik31tqbgz ~]# tail -f /var/log/messages

Jun 14 18:20:22 izj6cfw9yi1iqoik31tqbgz ./a.out[13395]: test-alert
Jun 14 18:20:33 izj6cfw9yi1iqoik31tqbgz ./a.out[13396]: test-info


上一篇: linux c进程调度-CPU亲和力
下一篇: linux c进程资源
作者邮箱: 203328517@qq.com