原创

linux下C语言编程打印log日志

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LS7011846/article/details/52626952
前言

       linux的日志系统一直以来都是在linux上开发必学的一部分内容。之前在学习openstack的时候,在对openstack组件的发生的错误进行调试时,老师就说要多看日志的报错,从这里找到相关线索再去修改配置文件。结果很多的报错都是通过组件对应的日志文件反映出来而修改成功的,因此使用好linux日志系统对了解linux编程有很大的帮助。

日志文件简述

其中日志一般都在/var/log目录下。该目录下有以下几个重要的的日志文件。
       /var/log/maillog:记录邮件的往来信息,其实主要是记录sendmail与dovecot所产生的信息。
       /var/log/dmesg:记录开机开始到现在的内核检测过程所产生的各项信息。如果内核编程的模块中使用printk(),将会把相关信息打印到这里。
       /var/log/messages:系统发生的重要信息或者是错误信息都会记录在这个文件中,如果系统发生错误,这个文件就是需要查阅的文件之一。
       /var/log/httpd:这个文件里面主要记录各种网络服务信息。
       /var/log/cron:这个日志跟例行工作调度有关。即crontab有没有被执行,执行过程中有没有发生错误,在这个日子中均有体现。

打印日志文件

上述的这些日志都是系统进程打印出的log日志。我们怎么能打印出自己的log日志呢?
首先,我们要分清楚需求是什么,是通过内核打印出来?还是非内核应用中打印出来?

1.内核打印日志

相信很多使用过内核模块的朋友已经很清楚,在linux内核模块中编程的话,使用简单的 printk("helloworld");就能达到打印日志的效果。下述是一个使用LSM的linux内核模块的部分代码,在对模块进行加载后,每一次动作的触发,都会在  /var/log/dmesg 文件中打印出相应的日志信息。
#include<linux/security.h>
#include<linux/sysctl.h>
static unsigned long long count = 0;
int task_create_hook(unsigned long clone_flags)
  {
  	printk("[+geek] call task_create(). count=%llu\n", ++count);	
  	return 0;
  }
  
  static struct security_operations geek_ops = {
  	.name = "geek",
  	.task_create = task_create_hook,
  };
  
static __init int geek_init(void)
  {
  	printk("[+geek] loading...\n");	
  	if(register_security(&geek_ops)){
  		printk("[+geek] register faild\n");	
  	}
  	return 0;
  }
  
security_initcall(geek_init);

在linux中使用dmesg命令即可查看内核输出的日志。

2.非内核编程打印日志

若想在非内核的环境下打印日志,就必须要使用syslog这样一个工具了(需要提醒的是ubuntu版本和Red Hat版本有很大区别,ubuntu使用的依旧是syslog,而Redhat和centos等版本则使用rsyslog替换掉系统自带的syslog)。因此我们分两部分对部分日志进行分析。
syslog
若你的系统还是使用的syslog,那就直接运行以下测试代码即可。
#include <syslog.h>
int main(int argc, char **argv)
{
    openlog("MyMsgMARK", LOG_CONS | LOG_PID, 0);
    syslog(LOG_DEBUG,
           "This is a syslog test message generated by program '%s'\n",
           argv[0]);
    closelog();
    return 0;
}

编译生成可执行程序后,运行一次程序将向/var/log/syslog文件添加一行信息如下:

1
    Feb 12 08:48:38 localhost MyMsgMARK[7085]: This is a syslog test message generated by program  './a.out'

   Feb 12 08:48:38 localhost MyMsgMARK[7085]: This is a syslog test message generated by program './a.out'

可以看到的是,此程序导入了syslog库函数,使用了syslog函数向syslog文件输出日志,第一个参数是消息的紧急级别,第二个参数是消息的格式,之后是格式对应的参数。就是printf函数一样使用。。其中,syslog文件过大后,系统就会把文件分割并压缩,如下图所示。


如果我们的程序要使用系统日志功能,只需要在程序启动时使用openlog函数来连接syslogd程序,后面随时用syslog函数写日志就行了。
还需要提醒的是,大家如果想删除日志,千万不要把日志文件直接删除,如果这样很有可能系统找不到文件,就无法再打印日志,恢复起来也是比较麻烦。直接清空日志内容即可  cat /dev/null > syslog  

rsyslog

如果上述方法无法打印syslog,很有可能你的系统已经把rsyslog替换了过去,这样,如果想要打印自己的日志,就需要先对rsyslog配置文件进行修改。
打开  /etc/rsyslog.conf
在最后写下自己日志的文件名称。
#Mylog
local2.* /var/log/mylog
修改完保存后重启rsyslog服务     :/etc/init.d/rsyslog restart    或service rsyslog restart  或systemctl restart rsyslog

接下来就开始编写一个小的测试方法来验证一下。

#include <syslog.h>
int main(int argc, char **argv)
{
    openlog("MyLog", LOG_CONS | LOG_PID, LOG_LOCAL2);
    syslog(LOG_INFO,
           "This is a syslog test message generated by program '%s'\n",
           argv[0]);
    closelog();
    return 0;
}
编译运行上述代码后,就会在 /var/log 目录下多出一个mylog文件

不出什么问题的话,里面的内容应该是LOG_INFO,This is a syslog test message generated by program ./ 。
到现在,我所了解的linux 下c语言编程所能打印日志的方法已经阐述完毕。希望跟大家多多交流。
正文到此结束
Loading...