C++日志库log4cplus:SocketAppender记录日志到log Server
来源:互联网 发布:期货数据接口 编辑:程序博客网 时间:2024/06/06 17:54
转载请注明出处:http://blog.csdn.net/jmppok/article/details/17375057
1.问题
C++程序在后台运行时,可通过log4cplus记录日志。当C++程序运行在远程服务器上时,我们就需要远程登陆到该服务器才能查看日志。进一步,如果该C++程序一个并行程序或者分布式程序,为了查看程序的运行状态,我们就需要登陆到N台服务器上,tail -f xx.log.这种情形听起来就很令人不爽,而实际上,很多服务端开发者都遇到过或正在遭受这个问题的困扰。
2.LoggingServer
作为Log4J的翻版,Log4cplus也提供了SockeAppender,可以通过SocketAppender将日志输出到一个指定的log server上,从而解决上述问题。
关于Log4cplus的介绍,请参考C++开源日志库log4cplus
在Log4cplus的源码包中,有一个loggingServer目录,该目录中实现了一个LoggingServer。
在编译Log4cplus时,会自动编译该目录,在目录中生成loggingServer可执行文件,当然可以自己make(需要依赖log4cplus库)。
loggingServer使用方式如下:
./loggingserver 9000 log4cplus.properties
9000表示监听的端口号(不需要地址,默认监听本机地址)
log4cplus.properties是一个log4cplus的配置文件,和普通的log4cplus配置文件相同,loggingserver收到各个socket发来的日志后,根据配置文件信息,将其写入文件。
下面是一个简单的配置文件示例:
log4cplus.rootLogger=DEBUG, STDOUT, ALL_MSGSlog4cplus.appender.STDOUT=log4cplus::ConsoleAppenderlog4cplus.appender.STDOUT.layout=log4cplus::PatternLayout#log4cplus.appender.STDOUT.layout.ConversionPattern=%d{%m/%d/%y %H:%M:%S} [%t] %-5p %c{2} %%%x%% - %m [%l]%nlog4cplus.appender.STDOUT.layout.ConversionPattern=[%-5p %d{%y-%m-%d %H:%M:%S}] [%l]%n%m%n%n#设置日志追加到文件尾log4cplus.appender.ALL_MSGS=log4cplus::RollingFileAppender #设置日志文件大小log4cplus.appender.ALL_MSGS.MaxFileSize=100MB#设置生成日志最大个数log4cplus.appender.ALL_MSGS.MaxBackupIndex=10#设置输出日志路径log4cplus.appender.ALL_MSGS.File=log/test.loglog4cplus.appender.ALL_MSGS.layout=log4cplus::PatternLayout#设置日志打印格式#log4cplus.appender.ALL_MSGS.layout.ConversionPattern=|%D:%d{%Q}|%p|%t|%l|%m|%nlog4cplus.appender.ALL_MSGS.layout.ConversionPattern=[%-5p %d{%y-%m-%d %H:%M:%S}] [%l]%n%m%n%n#匹配相同日志级别,只有debug日志才输入到该文件中#log4cplus.appender.ALL_MSGS.filters.1=log4cplus::spi::LogLevelMatchFilter#log4cplus.appender.DEBUG_MSGS.filters.1.LogLevelToMatch=DEBUG#log4cplus.appender.DEBUG_MSGS.filters.1.AcceptOnMatch=true#log4cplus.appender.DEBUG_MSGS.filters.2=log4cplus::spi::DenyAllFilter
loggingserver本身十分简单,其代码如下(当然如果觉得它不爽,你也可以自己实现一个更cool的):
// Module: LOG4CPLUS// File: loggingserver.cxx// Created: 5/2003// Author: Tad E. Smith////// Copyright 2003-2010 Tad E. Smith//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.#include <cstdlib>#include <iostream>#include <log4cplus/configurator.h>#include <log4cplus/socketappender.h>#include <log4cplus/helpers/socket.h>#include <log4cplus/thread/threads.h>#include <log4cplus/spi/loggingevent.h>namespace loggingserver{class ClientThread : public log4cplus::thread::AbstractThread{public: ClientThread(log4cplus::helpers::Socket clientsock) : clientsock(clientsock) { std::cout << "Received a client connection!!!!" << std::endl; } ~ClientThread() { std::cout << "Client connection closed." << std::endl; } virtual void run();private: log4cplus::helpers::Socket clientsock;};}intmain(int argc, char** argv){ if(argc < 3) { std::cout << "Usage: port config_file" << std::endl; return 1; } int port = std::atoi(argv[1]); const log4cplus::tstring configFile = LOG4CPLUS_C_STR_TO_TSTRING(argv[2]); log4cplus::PropertyConfigurator config(configFile); config.configure(); log4cplus::helpers::ServerSocket serverSocket(port); if (!serverSocket.isOpen()) { std::cout << "Could not open server socket, maybe port " << port << " is already in use." << std::endl; return 2; } while(1) { loggingserver::ClientThread *thr = new loggingserver::ClientThread(serverSocket.accept()); thr->start(); } return 0;}////////////////////////////////////////////////////////////////////////////////// loggingserver::ClientThread implementation////////////////////////////////////////////////////////////////////////////////voidloggingserver::ClientThread::run(){ while(1) { if(!clientsock.isOpen()) { return; } log4cplus::helpers::SocketBuffer msgSizeBuffer(sizeof(unsigned int)); if(!clientsock.read(msgSizeBuffer)) { return; } unsigned int msgSize = msgSizeBuffer.readInt(); log4cplus::helpers::SocketBuffer buffer(msgSize); if(!clientsock.read(buffer)) { return; } log4cplus::spi::InternalLoggingEvent event = log4cplus::helpers::readFromBuffer(buffer); log4cplus::Logger logger = log4cplus::Logger::getInstance(event.getLoggerName()); logger.callAppenders(event); }}
3.应用程序中SocketAppender配置
前面启动了LoggingServer,下面说一下需要收集其日志的各个应用程序中配置。
说白了,就是在原来的基础上加一个SocketAppender,SocketAppender会自动将日志发送给loggingserver。这样直接在loggingserver上就可以查看所有服务器上的日志信息啦。哥终于不用再担心你们的运行状态啦!
log4cplus.rootLogger=DEBUG, STDOUT, ALL_MSGS,RemoteServerlog4cplus.appender.STDOUT=log4cplus::ConsoleAppenderlog4cplus.appender.STDOUT.layout=log4cplus::PatternLayout#log4cplus.appender.STDOUT.layout.ConversionPattern=%d{%m/%d/%y %H:%M:%S} [%t] %-5p %c{2} %%%x%% - %m [%l]%nlog4cplus.appender.STDOUT.layout.ConversionPattern=[%-5p %d{%y-%m-%d %H:%M:%S}] [%l]%n%m%n%n#设置日志追加到文件尾log4cplus.appender.ALL_MSGS=log4cplus::RollingFileAppender #设置日志文件大小log4cplus.appender.ALL_MSGS.MaxFileSize=100MB#设置生成日志最大个数log4cplus.appender.ALL_MSGS.MaxBackupIndex=10#设置输出日志路径log4cplus.appender.ALL_MSGS.File=log/test.loglog4cplus.appender.ALL_MSGS.layout=log4cplus::PatternLayout#设置日志打印格式#log4cplus.appender.ALL_MSGS.layout.ConversionPattern=|%D:%d{%Q}|%p|%t|%l|%m|%nlog4cplus.appender.ALL_MSGS.layout.ConversionPattern=[%-5p %d{%y-%m-%d %H:%M:%S}] [%l]%n%m%n%n#匹配相同日志级别,只有debug日志才输入到该文件中#log4cplus.appender.ALL_MSGS.filters.1=log4cplus::spi::LogLevelMatchFilter#log4cplus.appender.DEBUG_MSGS.filters.1.LogLevelToMatch=DEBUG#log4cplus.appender.DEBUG_MSGS.filters.1.AcceptOnMatch=true#log4cplus.appender.DEBUG_MSGS.filters.2=log4cplus::spi::DenyAllFilterlog4cplus.appender.RemoteServer=log4cplus::SocketAppenderlog4cplus.appender.RemoteServer.host=localhostlog4cplus.appender.RemoteServer.port=9000
上面第一行的RemoteServer和最后三行即为添加一个SocketAppender。将日志发送到远端的loggingserver。
当然对本地的日志记录没有影响,本地仍正常记录。
同时我们还可以设置多个RemoetServer....,不过貌似也没这个必要...
4.更加高端大气上档次
当然我们可以实现自己的loggingserver,更加的高端大气上档次。
a.将来自不同客户端的日志分别存储;
b.不同级别的日志单独存储;
c.在发现错误时,邮件通知;
d.实现一个B/S的日志浏览工具;
e.日志入库;
f.存入HDFS,用Hadoop Map/Reduce挖掘;
g.接入Storm(实时流处理框架)对其进行分析;
...
- C++日志库log4cplus:SocketAppender记录日志到log Server
- log4cplus server client模式、log4cplus、log4cplus库(三)(将日志写入到文件)
- log4j通过SocketAppender将日志内容发送到远程服务器
- log4j通过SocketAppender将日志内容发送到远程服务器
- linux log日志记录到文件里
- C++日志库log4cplus使用手册
- C++ 日志类库 log4cplus
- C++日志库log4cplus使用手册
- 使用C++日志库log4cplus
- Log日志记录类
- Log日志记录buildMessage
- python log 日志记录
- log日志记录是什么
- 使用log记录日志
- log日志记录
- 使用 Exceptionless 作为 Log Server 搭配 NLog 记录系统日志
- C#Log日志
- C/C++log日志库比较
- Linux 内核配置机制(make menuconfig、Kconfig、makefile)讲解
- 查漏补缺,巩固基础——C++Primer之旅day3
- 局部加权线性回归
- hibernate开发步骤
- HDU 1548
- C++日志库log4cplus:SocketAppender记录日志到log Server
- 【C/C++学习】之十七、C++11中我们需要关注的
- android:descendantFocusability用法简析
- Seam - 无缝集成 JSF,第 1 部分: 为 JSF 量身定做的应用程序框架
- Linux source code Makefile分析
- MyBatis-spring和spring JDBC批量插入Mysql的效率比较
- android开源项目和框架2
- SSH集成开发
- eclipse环境下tomcat的配置