log4cpp是由C++实现,可输出到控制台、日志文件、syslog
https://sourceforge.net/projects/log4cpp/files/
官网地址:http://log4cpp.sourceforge.net/
tar -zxvf log4cpp-1.1.3.tar.gz
cd log4cpp;mkdir txh
./configure --prefix=/home/tanxiaohai/github_project/log4cpp/txh
make ;make install
可在log4cpp/txh这个目录下看到编译成功的库lib和头文件include
mv lib lib.bak
mkdir lib; mv lib.bak/liblog4cpp.a lib/
在txh目录下创建main.cpp
/**
* @brief log4cpp is library of C++ classes for flexible logging to file,syslog, IDSA and other destinations.
* 官网:http://log4cpp.sourceforge.net/
* 源码下载:https://sourceforge.net/projects/log4cpp/files/
*
* 线程安全
*/
/**
* @brief 需实现以下功能
* 1、日志格式
* 2、输出到console
* 3、输出到file
* 4、输出到syslog
* 5、配置文件控制日志
*/
#include
#include "log4cpp/Category.hh"
#include "log4cpp/Appender.hh"
#include "log4cpp/FileAppender.hh"
#include "log4cpp/OstreamAppender.hh"
#include "log4cpp/Layout.hh"
#include "log4cpp/BasicLayout.hh"
#include "log4cpp/Priority.hh"
#include "log4cpp/PropertyConfigurator.hh"
#include "log4cpp/SyslogAppender.hh"
#include "log4cpp/LoggingEvent.hh"
#include
static void case1()
{
// 控制台标准输出
log4cpp::Appender *appender1 = new log4cpp::OstreamAppender("console", &std::cout);
appender1->setLayout(new log4cpp::BasicLayout());
// 输出到文件program.log
log4cpp::Appender *appender2 = new log4cpp::FileAppender("default", "program.log");
appender2->setLayout(new log4cpp::BasicLayout());
log4cpp::Category& root = log4cpp::Category::getRoot();
root.setPriority(log4cpp::Priority::WARN);
root.addAppender(appender1);
log4cpp::Category& sub1 = log4cpp::Category::getInstance(std::string("sub1"));
sub1.addAppender(appender2);
// use of functions for logging messages
root.error("root error");
root.info("root info");
sub1.error("sub1 error");
sub1.warn("sub1 warn");
// printf-style for logging variables
root.warn("%d + %d == %s ?", 1, 1, "two");
// use of streams for logging messages
root << log4cpp::Priority::ERROR << "Streamed root error";
root << log4cpp::Priority::INFO << "Streamed root info";
sub1 << log4cpp::Priority::ERROR << "Streamed sub1 error";
sub1 << log4cpp::Priority::WARN << "Streamed sub1 warn";
// or this way:
root.errorStream() << "Another streamed error";
}
/**
* @brief 以设置的日志格式输出到标准输出、syslog、日志文件
* 日志格式项
PatternLayout supports following set of format characters:
%% - a single percent sign
%c - the category
%d - the date\n Date format: The date format character may be followed by a date format specifier enclosed between braces. For example, %d{%H:%M:%S,%l} or %d{%d %m %Y %H:%M:%S,%l}. If no date format specifier is given then the following format is used: "Wed Jan 02 02:03:55 1980". The date format specifier admits the same syntax as the ANSI C function strftime, with 1 addition. The addition is the specifier %l for milliseconds, padded with zeros to make 3 digits.
%m - the message
%n - the platform specific line separator
%p - the priority
%r - milliseconds since this layout was created.
%R - seconds since Jan 1, 1970
%u - clock ticks since process start
%x - the NDC
%t - thread name
By default, ConversionPattern for PatternLayout is set to "%m%n".
*/
static void case2()
{
auto getLayout = []()
{
log4cpp::PatternLayout* layout = new log4cpp::PatternLayout();
layout->setConversionPattern("%d{%d %b %Y %H:%M:%S} [%p] %c %m%n"); // 可设置自己喜欢的日志格式
return layout;
};
// 控制台标准输出
log4cpp::Appender *consoleAppender = new log4cpp::OstreamAppender("console", &std::cout);
consoleAppender->setLayout(getLayout());
// 日志文件txh.log
log4cpp::Appender *fileAppender = new log4cpp::FileAppender("default", "txh.log");
fileAppender->setLayout(getLayout());
// linux日志/var/log/syslog
log4cpp::SyslogAppender* syslogAppender = new log4cpp::SyslogAppender("syslog", "txh");
syslogAppender->setLayout(getLayout());
// log4cpp::Category& root = log4cpp::Category::getRoot();
log4cpp::Category& root = log4cpp::Category::getInstance(std::string("txh"));
root.setPriority(log4cpp::Priority::WARN); // 设置日志优先级 FATAL,ALERT,CRIT,ERROR,WARN,NOTICE,INFO,DEBUG
root.addAppender(syslogAppender); // 添加日志输出目标
root.addAppender(consoleAppender);
root.addAppender(fileAppender);
while(1)
{
root.error("%s %d times" , "caonima", 100);
root.warn("%s %d times" , "caonima", 100);
root.info("%s %d times" , "caonima", 100); // Priority之后的不会打印
root.debug("%s %d times" , "caonima", 100);
sleep(1);
}
}
// @brief 根据配置文件设置日志
/*
# log4cpp.properties
log4cpp.rootCategory=DEBUG, rootAppender
log4cpp.category.sub1=DEBUG, A1, A2
log4cpp.category.sub1.sub2=DEBUG, A3
log4cpp.appender.rootAppender=ConsoleAppender
log4cpp.appender.rootAppender.layout=PatternLayout
log4cpp.appender.rootAppender.layout.ConversionPattern=%d [%p] %m%n
log4cpp.appender.A1=FileAppender
log4cpp.appender.A1.fileName=A1.log
log4cpp.appender.A1.layout=BasicLayout
log4cpp.appender.A2=FileAppender
log4cpp.appender.A2.threshold=WARN
log4cpp.appender.A2.fileName=A2.log
log4cpp.appender.A2.layout=PatternLayout
log4cpp.appender.A2.layout.ConversionPattern=%d [%p] %m%n
log4cpp.appender.A3=RollingFileAppender
log4cpp.appender.A3.fileName=A3.log
log4cpp.appender.A3.maxFileSize=200
log4cpp.appender.A3.maxBackupIndex=1
log4cpp.appender.A3.layout=PatternLayout
log4cpp.appender.A3.layout.ConversionPattern=%d [%p] %m%n
*/
static void case3()
{
std::string initFileName = "log4cpp.properties";
log4cpp::PropertyConfigurator::configure(initFileName);
log4cpp::Category& root = log4cpp::Category::getRoot();
log4cpp::Category& sub1 =
log4cpp::Category::getInstance(std::string("sub1"));
log4cpp::Category& sub2 =
log4cpp::Category::getInstance(std::string("sub1.sub2"));
log4cpp::Category& txh =
log4cpp::Category::getInstance(std::string("txhAppender"));
root.warn("storm is coming");
sub1.debug("Received storm warning");
sub1.info("Closing all hatches");
sub2.debug("Hiding solar panels");
sub2.error("Solar panels are blocked");
sub2.debug("Applying protective shield");
sub2.warn("Unfolding protective shield");
sub2.info("Solar panels are shielded");
sub1.info("All hatches closed");
root.info("Ready for storm.");
while(1)
{
txh.info("caonima");
sleep(1);
}
log4cpp::Category::shutdown();
}
int main(int argc, char** argv)
{
int index = 1;
if (argc >= 2)
{
index = atoi(argv[1]);
}
switch (index)
{
case 1:
case1();
break;
case 2:
case2();
break;
case 3:
case3();
break;
default:
std::cout<<"Please input correct test case index"<
在txh目录下创建Makefile
CXX=g++
RM=rm
SRC=main.cpp
CFLAGS=-llog4cpp -lpthread -std=c++11
BIN=main
all:
$(CXX) -Iinclude -Llib $(SRC) $(CFLAGS) -o $(BIN)
clean:
$(RM) -rf $(BIN) *.o
执行make即可生成可执行文件main
(1)./main 1
在标准输出和日志文件program.log生成日志
(2)./main 2
在标准输出、日志文件txh.log、/var/log/syslog中生成日志
(3)创建配置文件
log4cpp.properties
log4cpp.rootCategory=DEBUG, rootAppender
log4cpp.category.sub1=DEBUG, A1, A2
log4cpp.category.sub1.sub2=DEBUG, A3
log4cpp.category.txhAppender=DEBUG, txh
log4cpp.appender.rootAppender=ConsoleAppender
log4cpp.appender.rootAppender.layout=PatternLayout
log4cpp.appender.rootAppender.layout.ConversionPattern=%d [%p] %m%n
log4cpp.appender.A1=FileAppender
log4cpp.appender.A1.fileName=A1.log
log4cpp.appender.A1.layout=BasicLayout
log4cpp.appender.A2=FileAppender
log4cpp.appender.A2.threshold=WARN
log4cpp.appender.A2.fileName=A2.log
log4cpp.appender.A2.layout=PatternLayout
log4cpp.appender.A2.layout.ConversionPattern=%d [%p] %m%n
log4cpp.appender.A3=RollingFileAppender
log4cpp.appender.A3.fileName=A3.log
log4cpp.appender.A3.maxFileSize=200
log4cpp.appender.A3.maxBackupIndex=1
log4cpp.appender.A3.layout=PatternLayout
log4cpp.appender.A3.layout.ConversionPattern=%d [%p] %m%n
log4cpp.appender.txh=SyslogAppender
log4cpp.appender.txh.layout=PatternLayout
log4cpp.appender.txh.layout.ConversionPattern=%d [%p] %m%n
执行./main 3
在标准输出、日志文件A1.log,A2.log,A3.log、/var/log/syslog生成日志文件
欢迎转载请注明出处:海漩涡
http://blog.csdn.net/tanhuifang520