转载请注明出处: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::ConsoleAppender
log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout
#log4cplus.appender.STDOUT.layout.ConversionPattern=%d{%m/%d/%y %H:%M:%S} [%t] %-5p %c{2} %%%x%% - %m [%l]%n
log4cplus.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.log
log4cplus.appender.ALL_MSGS.layout=log4cplus::PatternLayout
#设置日志打印格式
#log4cplus.appender.ALL_MSGS.layout.ConversionPattern=|%D:%d{%Q}|%p|%t|%l|%m|%n
log4cplus.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;
};}int
main(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 implementationvoid
loggingserver::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::ConsoleAppender
log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout
#log4cplus.appender.STDOUT.layout.ConversionPattern=%d{%m/%d/%y %H:%M:%S} [%t] %-5p %c{2} %%%x%% - %m [%l]%n
log4cplus.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.log
log4cplus.appender.ALL_MSGS.layout=log4cplus::PatternLayout
#设置日志打印格式
#log4cplus.appender.ALL_MSGS.layout.ConversionPattern=|%D:%d{%Q}|%p|%t|%l|%m|%n
log4cplus.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::SocketAppender
log4cplus.appender.RemoteServer.host=localhost
log4cplus.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相关推荐

  1. 开源日志库log4cplus+VS2008使用整理

    一.简介  log4cplus是C++编写的开源的日志系统,功能非常全面.本文介绍如何在Windows+VS2008中使用该日志库.   二.下载   可从网站[url]http://log4cplu ...

  2. C++:日志库log4cplus 2.0的使用说明

    以前在做java开发时一直都在用log4j,它配置灵活,功能强大.如果C++中也存在类似配置的日志库,则可以省去不少学习的时间.在C++中的确有这样的一些库,本文就拿其中用的最多的log4cplus来 ...

  3. c++日志库log4cplus使用

    项目中需要打印log,方便程序调试和问题定位分析.C++实现的log4cplus日志库是一种易于使用的C ++日志记录API,可提供线程安全,灵活且任意粒度的日志管理和配置控制. 下面介绍一下在lin ...

  4. C/C++日志库-log4cplus(log4j的C++版本)

      Log4j以其简单的使用方式(引入一个jar包,一行代码即可调用),灵活(可通过配置文件随意配置),功能强大(多个级别,可配置多个输出目的地,Console,File,系统日志,远端的LogSer ...

  5. android log耗性能吗,一个高性能的Android日志库

    clue 一个高性能的Android日志库. 为什么性能高 通常的Android日志库, 为了获取到class名, 方法名, 行号, 都是通过以下API实现的: StackTraceElement[] ...

  6. go日志库log/zap/logrus

    一个好的日志记录器能够提供下面这些功能: 能够将事件记录到文件中,而不是应用程序控制台. 日志切割-能够根据文件大小.时间或间隔等来切割日志文件. 支持不同的日志级别.例如INFO,DEBUG,ERR ...

  7. 【Rust】日志库log

    日志库一般会实现日志分级.日志过滤.日志输出格式化.日志回滚等功能.本文介绍了Rust log库的使用,并给出了几个常用日志库的使用示例. 一.Rust log 1.log库 这个log库给出了日志库 ...

  8. (1)go web开发之 zap日志库的使用及gin框架配置zap记录日志详细文档讲解分析

    (一)介绍 zap 是go 中比较火的一个日志库,提供不同级别的日志,并且速度快 官方文档: https://pkg.go.dev/go.uber.org/zap#section-readme, 也可 ...

  9. 日志库EasyLogging++学习系列(1)—— 简要介绍

    对于有开发经验的程序员来说,记录程序执行日志是一件必不可少的事情.通过查看和分析日志信息,不仅可以有效地帮助我们调试程序,而且当程序正式发布运行之后,更是可以帮助我们快速.准确地定位问题.在现在这个开 ...

最新文章

  1. JavaScript数据类型
  2. linux hdparm 测试磁盘io,hdparm测试硬盘性能
  3. 初学React,setState后获取到的thisstate没变,还是初始state?
  4. 在Eigrp做不等值路由的负载均衡
  5. 【ArcGIS风暴】ArcGIS10.6获取栅格影像边界范围的三种方法案例详解
  6. 触发键盘_雷蛇这款光轴机械键盘开箱评测,光速触发,颜值爆表
  7. 利用httponly提升应用程序安全性
  8. 比特币可视化工具_这个比特币交易“可视化”网站,用一辆公交车带你“上车”...
  9. 95-170-050-源码-Time-flink的时间及时区问题解决
  10. log4net配置自定义字段存入数据库
  11. Golang 主机字节序的判断
  12. HTTP 500 - 内部服务器错误的解决
  13. 《嵌入式Linux基础教程学习笔记一》
  14. 人工智能(AI)测试方法
  15. 中国智慧园区标准化白皮书 附下载
  16. 固定资产管理系统项目总结
  17. MATLAB学习笔记:求偏导
  18. 21个免费学习编程的网站
  19. SIM卡中ICCID标识与IMSI的区别
  20. 联想笔记本上Ubuntu无线网卡问题

热门文章

  1. 帝国cms 单页面栏目管理
  2. 比亚迪速锐F3专用夏季座套 夏天坐垫 四季坐套
  3. 跨境电商行业:现在新卖家入驻亚马逊还有机会吗?自发货模式又如何?
  4. Java大文件上传(Android亦可)
  5. MySQL in查询优化
  6. 流放者柯南个人服务器怎么修改技能点,流放者柯南常用管理员指令~不足请补充...
  7. 华为nova8pro支持鸿蒙吗,华为nova8pro手机怎么样_华为nova8pro优缺点
  8. okhttp+登录注册
  9. 南卡和漫步者哪款更值得入手?音质高的国产蓝牙耳机推荐
  10. ArrayList排序