Log4c 是纯C写的第三发开源日志软件
http://sourceforge.net/projects/log4c/ (log4c官网)
安装完成之后为了让你的程序库能找到log4c 动态库
$ sudo vi /etc/ld.so.conf/usr/local/lib$ sudo ldconfig
(我测试了一下没有作用)
解决上述的方法是:
方法一:
1) 将/usr/local/log4c/include的文件拷贝到/usr/include
2) 将/usr/local/log4c/lib 的文件拷贝到/usr/lib
方法二:
编译的时候连接 -I /usr/local/log4c/include 和 -L /usr/local/log4c/lib
Log4c 中有三个重要的概念,Category ,Appender,Layout.
Category用于 区分不同的日志,在一个程序中我们可以通过Category来指定很多日志
Appender 用于描述输出流,通过为Category来指定一个Appender,可以决定将log信息输出到什么地方,比如stdout ,stderr,rollingfile等等
Layout 用于指定日志信息的格式,通过为Appender来指定一个Layout,可以决定log信息以何种格式来输出,比如是否带有时间截止,是否包含文件位置信息等,以及他们在一条log信息中的输出格式等。
Category,Appender,Layout 三者之间的关系,一个Category需要指定一个appender,一个appender需要指定一个Layout
另外,对于文件类型输出还有一个rollingpolicy。Rollingpolicy用于描述文件输出的配置策略
Log4c 依赖的配置文件是log4crc,配置文件示例如下
0
0
1
name:日志的名称
priority:日志的优先级,共有fatal/alert/crit/error/warn/notice/info/debug/trace/notest和unknow 11个级别,其级别逐步递增,记录在日志中的数据小于等于指定级别的数据。
appender:输出流类型名称,为appender节点的name属性的值。
name :输出流名称
type:输出流类型,共有stream/syslog/rollingfile三大类
layout:输出日志的格式的名称,为layout节点的name属性的值。
rollingpolicy:输出日志文件配置策略名称,为rollingpolicy节点的name属性的值。
Rollingpolicy 的timewiin类型的日志输出为自定义类型。
name:输出日志的格式名称
type:输出日志格式的类型,共有base,dated,dated_t等格式类型,对于自定义类型配置在这里,否则不能加载
base:%P %c -%m/n
%P 日志信息的优先级
%c 日志的名称
%m 日志信息内容
dated:%d %P %c -%m/n
%d 日志信息产生的时间,UTC格式为yyymmdd hh:mm:ss:mis
%P 日志信息的优先级
%c 日志的名称
%m 日志信息内容
name:日志文件输出的配置策略名称
type: 日志输出文件策略的类型,有sizewin一种类型
maxsize:输出日志文件的最大值。默认值为20kb
maxnum:保存的历史日志文件总数。默认值为5.
头文件 (直接引用log4c.h程序编译出错,因此只引用需要的头文件)
extern "C" {
#include
#include
}
--------------------------------------------------------log.h------------------------------------------------------------------------------------------
======================================================================
// Name: log.h
// Description: LOG_DEBUG 记录debug日志
// LOG_ERROR 记录error日志
// LOG_FATAL 记录fatal日志
// LOG_INFO 记录info日志
// LOG_NOTICE 记录notice日志
// LOG_WARN 记录warn日志
// LOG_TRACE 记录trace日志
// =================================================================================
#ifndef __LOG_H_
#define __LOG_H_
#include
#include
#ifdef __cplusplus
extern "C"
{
#endif
#include "log4c.h"
#ifdef __cplusplus
}
#endif
#define LOG_PRI_FATAL LOG4C_PRIORITY_FATAL
#define LOG_PRI_ERROR LOG4C_PRIORITY_ERROR
#define LOG_PRI_WARN LOG4C_PRIORITY_WARN
#define LOG_PRI_NOTICE LOG4C_PRIORITY_NOTICE
#define LOG_PRI_INFO LOG4C_PRIORITY_INFO
#define LOG_PRI_DEBUG LOG4C_PRIORITY_DEBUG
#define LOG_PRI_TRACE LOG4C_PRIORITY_TRACE
extern int log_init(const char *category);
extern void log_message(int priority ,
const char *file, int line, const char *fun,
const char *fmt , ...);
extern int log_fini();
#define LOG_FATAL(fmt,args...) \
log_message(LOG_PRI_FATAL,__FILE__ , __LINE__ , __FUNCTION__ , fmt , ##args)
#define LOG_ERROR(fmt , args...) \
log_message(LOG_PRI_ERROR,__FILE__ , __LINE__ , __FUNCTION__ , fmt, ##args)
#define LOG_WARN(fmt, args...) \
log_message(LOG_PRI_WARN,__FILE__ , __LINE__ , __FUNCTION__ , fmt , ##args)
#define LOG_NOTICE(fmt , args...) \
log_message(LOG_PRI_NOTICE,__FILE__ , __LINE__ , __FUNCTION__ , fmt , ##args)
#define LOG_INFO(fmt,args...) \
log_message(LOG_PRI_INFO,__FILE__ , __LINE__ , __FUNCTION__ , fmt , ##args)
#define LOG_DEBUG(fmt , args...) \
log_message(LOG_PRI_DEBUG,__FILE__ , __LINE__ , __FUNCTION__ , fmt , ##args)
#define LOG_TRACE(fmt,args...) \
log_message(LOG_PRI_TRACE, __FILE__ , __LINE__ , __FUNCTION__ , fmt ,##args)
#endif
// === FILE ======================================================================
// Name: log.c
// Description: log_init 初始化logger
// log_fini 关闭打开的资源
// log_message 记录日志信息
// =================================================================================
#include
#include
#include "log.h"
static log4c_category_t *log_category = NULL;
// === FUNCTION ======================================================================
// Name: log_init
// Description: 从配置文件"log4crc"中读取配置信息到内存,使用分类category初始化logger
// @param category [in]: 分类
// =====================================================================================
int log_init(const char *category)
{
if (log4c_init() == 1)
{
return -1;
}
log_category = log4c_category_get(category);
return 0 ;
}
// === FUNCTION ======================================================================
// Name: log_message
// Description: 记录日志信息
// @param priority [in]: 日志类别
// @param file [in]: 文件
// @param line [in]: 行
// @param fun [in]: 函数
// @param fmt [in]: 格式化参数
// =====================================================================================
void log_message(int priority ,
const char *file, int line, const char *fun,
const char *fmt , ...)
{
char new_fmt[2048];
const char * head_fmt = "[file:%s, line:%d, function:%s]";
va_list ap;
int n;
assert(log_category != NULL);
n = sprintf(new_fmt, head_fmt , file , line , fun);
strcat(new_fmt + n , fmt);
va_start(ap , fmt);
log4c_category_vlog(log_category , priority, new_fmt , ap);
va_end(ap);
}
// === FUNCTION ======================================================================
// Name: log_fini
// Description: 清理所有申请的内存,关闭它们打开的文件
// =====================================================================================
int log_fini()
{
return (log4c_fini());
}
//test-log.c
#include
#include "log.h"
int main(void)
{
log_init("file");
while (1)
{
LOG_ERROR("error");
LOG_WARN("warn");
LOG_NOTICE("notice");
LOG_DEBUG("debug");
LOG_INFO("info");
LOG_FATAL("fatal");
LOG_TRACE("trace");
}
log_fini();
return 0;
}
gcc test-log.c log.c -o test-log -llog4c
./test-log