文章出处:http://blog.csdn.net/xx77009833/archive/2010/07/30/5776383.aspx

 为了满足某些目的,进行日志记录是很有必要的。

在典型的 LINUX 安装中,/var/log/messages 包含所有的系统消息,/var/log/mail 包含来自邮件系统的其它日志消息, /var/log/debug 可能包含调试消息。根据你的LINUX的版本,你可以在 /etc/syslog.conf 或者 /etc/syslog-ng/syslog-ng.conf 文件里检查你的系统(消息)配置情况。

尽管系统消息的格式和存储位置可能不同,但产生消息的方法却是标准的。UNIX 技术规范(specification)为所有程序生成日志消息提供了一个接口,这通过
syslog() 函数实现:

  1. #include <syslog.h>
  2. void syslog(int priority, const char *message, arguments...);

syslog() 函数向日志设备(日志工具 facility)发送日志消息。每一个消息都有一个 priority(优先级)
参数,这个参数由一个“危险系数”(severity level)和一个程序标识码(facility value)相或(OR)得来。

“危险系数”用来调控(control)如何对这条日志消息做出响应的(以哪一种危险等级来响应);程序标识码记录着发出这条消息是哪一个程序。(The
severity level controls how the log message is acted upon)

程序标识码(定义自 syslog.h)包含 LOG_USER----用来指示这消息是来自用户的应用程序(默认值)的。
LOG_LOCAL0, LOG_LOCAL1...LOG_LOCAL7 --这些都可以由本地管理员来进行赋值。

以下是危险等级的降序排列:

Priority Level                             Description
LOG_EMERG                                紧急状况
LOG_ALERT                                高优先级故障,如数据库损坏
LOG_CRIT                                 关键性(critical)错误,如硬件操作失败
LOG_ERR                                  一般错误
LOG_WARNING                             一般警告
LOG_NOTICE                               需要注意的特殊条件
LOG_INFO                                 通知性消息(Information messages)
LOG_DEBUG                               调试消息

根据系统的配置,LOG_EMERG 消息可能会向所有用户进行广播,LOG_ALERT 消息可能会给管理员发出一个邮件,LOG_DEBUG 消息可能会被忽略,而其它的消息都写到一个消息文件中去。当你想创建一个日志消息时,你可以简单的写一个使用日志工具的程序,这通过调用 syslog() 函数即可。

由 syslog() 函数创建的日志消息由消息标题(message header)和消息内容(message
body)组成。消息标题由设备指示符(facility indicator)、日期和时间来创建。消息内容由syslog() 函数中的
message 参数生成,这个和 printf() 的格式字符串的使用类似。syslog() 后面其他的参数按照 message 字符串里的
printf() 风格转换说明符给出(Further arguments to syslog() are used according to
printf() style conversion specifiers in the message string)。另外,指示符 %m 可用来插入错误信息字符串,这个字符串和当前的错误变量 errno 所对应。这对于日志错误信息记录很有用。

测试代码:

  1. 01 #include <syslog.h>
  2. 02 #include <stdio.h>
  3. 03 #include <stdlib.h>
  4. 04
  5. 05 int main()
  6. 06 {
  7. 07         FILE *f;
  8. 08
  9. 09         f = fopen("not_here", "r");
  10. 10
  11. 11         if(!f)
  12. 12                 syslog(LOG_ERR|LOG_USER, "oops - %m/n");
  13. 13         exit(0);
  14. 14 }

执行输出
没有显示输出,但是会把错误信息写到日志文件中,通过查看 /var/log/messages 可以看得到:
Feb 24 00:49:45 localhost syslog.exe: oops - No such file or directory

%m 转换控制符被一个错误描述信息所替换,在上面的程序中,错误的原因是没有找到需要的文件。这比单纯的报告错误编号要来得有用的多。

其他的用来改变日志功能的行为的函数也定义在 syslog.h 头文件中:

  1. #include <syslog.h>
  2. void closelog(void);
  3. void openlog(const char *ident, int logopt, int facility);
  4. int setlogmask(int maskpri);

你可以通过调用 openlog() 函数改变你的日志消息的呈现方式。这允许你设置一个字符串--ident,这将被加在你的日志消息的最前面。你可以使用这些来指示哪一个程序正在创建这条消息。facility 参数记录了一个默认的程序标识码---这在后来使用 syslog() 里会被用到。
默认的 facility 值为 LOG_USER. logopt 参数配置将来要调用 syslog() 函数的行为。它是0个或多个一下参数的OR运算:

logopt Parameter                             Description
LOG_PID                               加上进程标识符(系统分配给每个进程的一个独一无二的数字标识)
LOG_CONS                             如果消息无法记录到日志文件里则发送消息到控制台
LOG_NDELAY                           在第一次调用 syslog 函数时打开日志功能
LOG_NDELAY                           立即打开日志功能,而不等到第一次记日志时

openlog() 函数将分配和打开一个用来写到日志功能的文件描述符,你也可以通过调用 closelog() 函数来关闭它。注意,你无须在调用 syslog() 之前调用 openlog() ,这是因为如果有需要的话 syslog 它自己也会打开日志功能。

通过设置一个日志掩码(使用 setlogmask()函数 )你可以控制日志消息的优先级。此后, 所有没有在日志掩码里置位的优先级的 syslog()调用都要被丢弃。举例来说,你可以使用这来关闭 LOG_DEBUG 消息而无须影响程序内容。

使用 LOG_MASK(priority) 你可以为日志消息创建一个掩码,通过这样创建的掩码仅由一个优先级组成;或者是 LOG_UPTO(priority)这创建的掩码由指定优先级之前所有优先级组成(也包含指定优先级自身)。

  1. 01 #include <syslog.h>
  2. 02 #include <stdio.h>
  3. 03 #include <unistd.h>
  4. 04 #include <stdlib.h>
  5. 05
  6. 06 int main()
  7. 07 {
  8. 08         int logmask;
  9. 09
  10. 10         openlog("logmask", LOG_PID|LOG_CONS, LOG_USER);
  11. 11         syslog(LOG_INFO, "informative message, pid = %d", getpid());
  12. 12         syslog(LOG_DEBUG, "debug message, should appear");
  13. 13         logmask = setlogmask(LOG_UPTO(LOG_NOTICE));
  14. 14         syslog(LOG_DEBUG,"debug message, should not appear");
  15. 15
  16. 16         exit(0);
  17. 17 }

程序说明
在运行 logmask 程序后不产生任何输出,但在典型的 linux 系统上,在 /var/log/messages 的末尾处,可以看到

  1. Feb 26 17:48:59 localhost logmask[14184]: informative message, pid = 14184

可能在 /var/log/debug (centos5 没这个文件) 或者有时在 /var/log/messages 中会包含如下行:

  1. Feb 26 22:23:42 localhost logmask[11730]: debug message, should appear

10).调用了 openlog() 函数。openlog() 函数的作用是打开一个日志连接。其中参数 ident
是一个字符串指针,它所指向的字符串会放在每个消息的前面,通常的应用都是设置为程序名,用来指示是哪个程序创建里这个消息。所以,这里就为
logmask 这个程序名。

第二个参数 LOG_PID|LOG_CONS 设置就是要告诉后面在调用 syslog() 对日志进行记录时,要包含进程PID号信息,如果无法对日志进行记录操作,则把消息发往控制台。

第三个参数是 facility . facility
参数用来指定是什么程序类型在记录日志。如默认类型是 LOG_USER(通用的用户级消息),LOG_FTP(FTP
守护进程记录的消息<FTP守护进程程序类型>),LOG_KERN(内核消息<内核程序类型>)等等,详见 man
手册。上面举例中用的是 LOG_USER 这个默认类型。

注意:在上面程序中,/var/log/debug 文件原本是没有的,那是因为没有激活这个日志功能,要激活 debug 记录功能,在 /etc/syslog.conf 中添加以下内容:

  1. 引用
  2. #debug messages
  3. *.debug /var/log/debug

编辑并保存文件后,重启计算机即可。

在程序中,debug message, should not appear 这条消息不会出现,因为调用了 setlogmask() 函数,这里忽略了所有低于 LOG_NOTICE 优先级的所有消息,而 LOG_DEBUG 优先级最低,自然不会被记录到 /var/log/debug 文件中。(注意:这种做法在早期的内核中行不通).

这是因为 LOG_UPTO(priority) 是一个宏,这个宏表示:低于 priority 优先级的消息都不会在掩码中被置位,也就是在进一步调用 syslog() 函数时,里面的消息是无法记录到日志文件的。

上面的程序使用了 getpid() 函数,它和一个非常接近的函数 getppid() 的函数定义在一起:

    1. #include <sys/types.h>
    2. #include <unistd.h>
    3. pid_t getpid(void);
    4. pid_t getppid(void);
    5. http://www.groad.net/bbs/read.php?tid-612-fpage-5.html
    6. LOG_ALERT=1
    7. LOG_CRIT=3
    8. LOG_ERR=3

syslog(),closelog()与openlog()--日志操作函数 (1)的更多相关文章

  1. syslog(),closelog()与openlog()--日志操作函数

    在典型的 LINUX 安装中,/var/log/messages 包含所有的系统消息,/var/log/mail 包含来自邮件系统的其它日志消息,/var/log/debug 可能包含调试消息.根据你 ...

  2. syslog(),closelog()与openlog()--日志操作函数 (2)

    文章出处:http://blog.chinaunix.net/uid-26583794-id-3166083.html 守护进程日志的实现 syslogd守护进程用于解决守护进程的日志记录问题,而日志 ...

  3. perl的Sys::Syslog模块(openlog,syslog,closelog函数,setlogsock)-自定义日志

    perl的Sys::Syslog模块(openlog,syslog,closelog函数,setlogsock)-自定义日志 http://blog.chinaunix.net/xmlrpc.php? ...

  4. PHP网络操作函数汇总

    PHP网络操作函数汇总 投稿:junjie 字体:[增加 减小] 类型:转载   这篇文章主要介绍了PHP网络操作函数汇总,本文列举了如gethostbyaddr.gethostbyname.head ...

  5. 使用Log4j进行日志操作

    使用Log4j进行日志操作 一.Log4j简介 (1)概述 Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接字服 ...

  6. 从零开始的Python学习Episode 14——日志操作

    日志操作 一.logging模块 %(message)s 日志信息 %(levelno)s 日志级别 datefmt 设置时间格式 filename 设置日志保存的路径 level 设置日志记录的级别 ...

  7. Python之日志操作(logging)

    import logging   1.自定义日志级别,日志格式,输出位置 logging.basicConfig( level=logging.DEBUG, format='%(asctime)s | ...

  8. 孤荷凌寒自学python第四十九天继续研究跨不同类型数据库的通用数据表操作函数

    孤荷凌寒自学python第四十九天继续研究跨不同类型数据库的通用数据表操作函数 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天继续建构自感觉用起来顺手些的自定义模块和类的代码. 不同类型 ...

  9. 2.NetDh框架之简单高效的日志操作类(附源码和示例代码)

    前言 NetDh框架适用于C/S.B/S的服务端框架,可用于项目开发和学习.目前包含以下四个模块 1.数据库操作层封装Dapper,支持多种数据库类型.多库实例,简单强大: 此部分具体说明可参考博客: ...

随机推荐

  1. JavaWeb学习——获取类路径下的资源

    对于JavaWeb而言,获取类路径下的资源,就是获取classes目录下的资源. 获取资源的方式有两种,利用Class或ClassLoader. Class类的getResourceAsStream( ...

  2. 算法学习--Day5

    其实今天是第六天,不过昨天写的题目有些杂乱,都是贪心的算法,所以昨天的题目就不放上来了. 今天开始入手数据结构吧啦吧啦.. 数据结构当时学的时候感觉挺简单的,不过现在真正上代码之后发现情况并不妙,还是 ...

  3. Lightoj1080 【线段树】

    题意: 给你一个0/1的数组,然后给你n段区间,说这个区间里要反转一次,然后给你Q个询问,问你这个位置是什么: 思路: 我们线段树维护一下就好了额: 其实反转的话,还是算次数是不是,奇偶嘛: #inc ...

  4. [Xcode 实际操作]八、网络与多线程-(11)使用同步Post方式查询IP地址信息

    目录:[Swift]Xcode实际操作 本文将演示如何通过Post请求,同步获取IP地址信息. 一旦发送同步请求,程序将停止用户交互,直至服务器返回数据. 在项目导航区,打开视图控制器的代码文件[Vi ...

  5. lombok常用注解

    简介: Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率.例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器.equ ...

  6. 【源码系列】Eureka源码分析

    对于服务注册中心.服务提供者.服务消费者这个三个主要元素来说,服务提供者和服务消费者(即Eureka客户端)在整个运行机制中是大部分通信行为的主动发起者(服务注册.续约.下线等),而注册中心主要是处理 ...

  7. UINavigationController 的一些坑

    坑一:自定义导航栏返回键 iOS7及之后版本 手势边缘右滑返回失效 解决方案: -(void)viewDidLoad{ [super viewDidLoad]; //self 为 UINavigati ...

  8. 黑马方法引用学习 Stream流 函数式接口 Lambda表达式 方法引用

  9. 用python将多个文档合成一个

    可以参考下以下网址(读写文件):https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/ ...

  10. 12.Maps

    1       Maps 1.1  Map声明和访问 maps中的元素是key-value对儿,key与value之间使用冒号(:)分割.创建一个空value的map,使用[:].默认情况下,map的 ...