1、系统常用的日志(日志是用来记录重大事件的工具)
/var/log/message 系统信息日志,包含错误信息等
/var/log/secure 系统登录日志
/var/log/cron 定时任务日志
/var/log/maillog 邮件日志
/var/log/boot.log 系统启动日志
2、日志管理服务 rsyslog
【1】作用:主要用来采集日志,不产生日志
【2】配置文件:/etc/rsyslog.conf
3、日志级别分为:
debug ##有调试信息的,日志通信最多
info ##一般信息日志,最常用
notice ##最具有重要性的普通条件的信息
warning ##警告级别
err ##错误级别,阻止某个功能或者模块不能正常工作的信息
crit ##严重级别,阻止整个系统或者整个软件不能正常工作的信息
alert ##需要立刻修改的信息
emerg ##内核崩溃等重要信息
none ##什么都不记录
本文简摘自zlog使用手册,更详细的使用规则请参考:zlog使用手册。
lzl@ubuntu18:~/zlog-master$ ls
Changelog COPYING doc INSTALL makefile README.md src test TODO tools
lzl@ubuntu18:~/zlog-master$ make
lzl@ubuntu18:~/zlog-master$ make install
安装成功后会显示安装到了/usr/local/lib路径下。
error while loading shared libraries: xxx.so.x
这时需要手动给链接器加路径:
$ sudo vim /etc/li.so.conf
加入:
/usr/local/lib
$ sudo ldconfig
ldconfig作用是在默认搜寻目录(/lib和/usr/lib)下, 以及动态库配置文件(/etc/ld.so.conf和/etc/ld.so.conf.d/.conf) 里所列的目录下, 搜索出可共享的动态库(格式如lib*.so*),进而创建出动态装入程序(ld.so)所需的连接和缓存文件. 缓存文件默认为/etc/ld.so.cache, 此文件保存动态库名字列表.
# comments
[global]
strict init = true
buffer min = 1024
buffer max = 2MB
rotate lock file = /tmp/zlog.lock
default format = "%d.%us %-6V (%c:%F:%L) - %m%n"
file perms = 600
[levels]
TRACE = 10
CRIT = 130, LOG_CRIT
[formats]
simple = "%m%n"
normal = "%d %m%n"
[rules]
default.* >stdout; simple
*.* "%12.2E(HOME)/log/%c.log", 1MB*12; simple
my_.INFO >stderr;
my_cat.!ERROR "/var/log/aa.log"
my_dog.=DEBUG >syslog, LOG_LOCAL0; simple
my_mice.* $user_define;
[]代表一个节的开始,四个小节的顺序不能变,依次为global-levels-formats-rules。这一节可以忽略不写。语法为
(key) = (value)
strict init
如果"strict init"是true,zlog_init()将会严格检查所有的格式和规则,任何错误都会导致zlog_init() 失败并且返回-1。当"strict init"是false的时候,zlog_init()会忽略错误的格式和规则。 这个参数默认为true。
buffer min
buffer max
zlog在堆上为每个线程申请缓存。“buffer min"是单个缓存的最小值,zlog_init()的时候申请这个长度的内存。写日志的时候,如果单条日志长度大于缓存,缓存会自动扩充,直到到"buffer max”。 单条日志再长超过"buffer max"就会被截断。如果 “buffer max” 是 0,意味着不限制缓存,每次扩充为原先的2倍,直到这个进程用完所有内存为止。缓存大小可以加上 KB, MB 或 GB这些单位。默认来说"buffer min"是 1K , “buffer max” 是2MB。
rotate lock file
锁文件,确保多线程程序在记录日志时引发的安全问题,默认为日志文件走作为锁。
default format
这个参数是缺省的日志格式,默认值为:"%d %V [%p:%F:%L] %m%n"
这种格式产生的输出类似这样:
2012-02-14 17:03:12 INFO [3758:test_hello.c:39] hello, zlog
用于定义用户自己的日志等级、这一节可以忽略不写。语法为:
(level string) = (level int), (syslog level, optional)
用户自定义等级
在配置文件中定义新的等级
[global]
default format = "%V %v %m%n"
[levels]
TRACE = 30, LOG_DEBUG
[rules]
my_cat.TRACE >stdout;
内置的默认等级是(这些不需要写在配置文件里面)
DEBUG = 20, LOG_DEBUG
INFO = 40, LOG_INFO
NOTICE = 60, LOG_NOTICE
WARN = 80, LOG_WARNING
ERROR = 100, LOG_ERR
FATAL = 120, LOG_ALERT
UNKNOWN = 254, LOG_ERR
这样在zlog看来,一个整数(30)还有一个等级字符串(TRACE)代表了等级。这个整数必须位于[1,253]之间,其他数字是非法的。数字越大代表越重要。现在TRACE比DEBUG重要(30>20),比INFO等级低(30<40)。在这样的定义后,TRACE就可以在下面的配置文件里面用了。例如这句话:
my_cat.TRACE >stdout;
意味着等级>=TRACE的,包括INFO, NOTICE, WARN, ERROR, FATAL会被写到标准输出。
用来定义日志的格式。语法为:
(name) = “(actual formats)”
(name)被后面的规则使用。(name)必须由数字和字母组成,下划线"_"也算字母。(actual format)前后需要有双引号。
用于描述日志是怎么被过滤、格式化以及被输出的。这节可以若忽略不写,日志输没有输出,这也是配置文件中不可缺省的重要部分。
表达式 | 含义 |
---|---|
* | 所有等级 |
aa.debug | 代码内等级>=debug |
aa.=debug | 代码内等级=debug |
aa.!debug | 代码内等级!=debug |
分类必须由数字和字母组成,下划线"_"也算字母。
描述 | 匹配规则 | 匹配样式 | 不匹配样式 |
---|---|---|---|
*表示匹配所有 | *.* | aa, aa_bb, aa_cc, xx, yy … | none |
以_结尾的分类匹配本级及下级分类 | aa_.* | aa, aa_bb, aa_cc, aa_bb_cc | xx, yy |
不以_结尾的精确匹配分类名 | aa.* | aa | aa_bb, aa_cc, aa_bb_cc |
!匹配那些没有找到规则的分类 | !.* | 未定义的都匹配 | aa(as it matches rules above) |
例子:
比如我想将等级大于或等于warn的日志输出到"./test.log"文件中,不等于ERROR 的日志输出到终端。
配置:
[rules]
my.=WARN "./test.log"
my.!error >stdout
API调用:
zc = zlog_get_category("my");
结果:
lzl@ubuntu18:~/my/test/zlog$ ./test
2021-04-18 20:28:22 DEBUG [5879:test.c:44] zlog, debug
2021-04-18 20:28:22 INFO [5879:test.c:45] zlog ,info
2021-04-18 20:28:22 NOTICE [5879:test.c:46] zlog, notice
2021-04-18 20:28:22 WARN [5879:test.c:47] zlog, warn
2021-04-18 20:28:22 FATAL [5879:test.c:49] zlog,fatal
lzl@ubuntu18:~/my/test/zlog$ cat test.log
2021-04-18 20:28:22 WARN [5879:test.c:47] zlog, warn
int zlog_init(const char *confpath);
zlog_init()从配置文件confpath中读取配置信息到内存。如果confpath为NULL,会寻找环境变量ZLOG_CONF_PATH的值作为配置文件名。如果环境变量ZLOG_CONF_PATH也没有,所有日志以内置格式写到标准输出上。每个进程只有第一次调用zlog_init()是有效的,后面的多余调用都会失败并不做任何事情
int zlog_reload(const char *confpath);
zlog_reload()从confpath重载配置,并根据这个配置文件来重计算内部的分类规则匹配、重建每个线程的缓存、并设置原有的用户自定义输出函数。可以在配置文件发生改变后调用这个函数。这个函数使用次数不限。如果confpath为NULL,会重载上一次zlog_init()或者zlog_reload()使用的配置文件。如果zlog_reload()失败,上一次的配置依然有效。所以zlog_reload()具有原子性。
void zlog_fini(void);
zlog_fini()清理所有zlog API申请的内存,关闭它们打开的文件。使用次数不限。
返回值如果成功,zlog_init()和zlog_reload()返回0。失败的话,zlog_init()和zlog_reload()返回-1。详细错误会被写在由环境变量ZLOG_PROFILE_ERROR指定的错误日志里面。
typedef struct zlog_category_s zlog_category_t;
zlog_category_t *zlog_get_category(const char *cname);
zlog_get_category()从zlog的全局分类表里面找到分类,用于以后输出日志。如果没有的话,就建一个。然后它会遍历所有的规则,寻找和cname匹配的规则并绑定。
配置文件规则中的分类名匹配cname的规律描述如下:
返回值
如果成功,返回zlog_category_t的指针。如果失败,返回NULL。详细错误会被写在由环境变量ZLOG_PROFILE_ERROR指定的错误日志里面。
void zlog(zlog_category_t * category,
const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const char *format, ...);
void vzlog(zlog_category_t * category,
const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const char *format, va_list args);
void hzlog(zlog_category_t * category,
const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const void *buf, size_t buflen);
描述
这3个函数是实际写日志的函数,输入的数据对应于配置文件中的%m。category来自于调用zlog_get_category()。
宏原型:
zlog_fatal(cat, format, …)
zlog_error(cat, format, …)
zlog_warn(cat, format, …)
zlog_notice(cat, format, …)
zlog_info(cat, format, …)
zlog_debug(cat, format, …)
配置文件:
[global]
strict init = true
[rules]
my.=WARN "./test.log"
my.!error >stdout
测试代码:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "zlog.h"
int main (char argc, char **argv)
{
zlog_category_t *zc = NULL;
char *conf_file = "./test.conf";
int rv = -1;
int flag = 1;
rv = zlog_init(conf_file);
if(rv)
{
printf("init zlog failed\n");
return -1;
zlog_fini();
}
zc = zlog_get_category("my");
if( !zc ) {
printf("zlog_get_category false\n");
return -2;
}
while(flag)
{
zlog_debug(zc, "zlog, debug\n");
zlog_info(zc, "zlog ,info\n ");
zlog_notice(zc, "zlog, notice\n");
zlog_warn(zc, "zlog, warn\n");
zlog_error(zc, "zlog, error\n");
zlog_fatal(zc, "zlog,fatal\n");
flag--;
}
zlog_fini();
return 0;
}