log4j实现日志集中存储

泛微E9日志管理进阶:自定义路径配置实战 本文详细介绍了泛微E9系统日志管理的进阶实战技巧,重点讲解如何通过修改Log4j配置文件实现自定义日志输出路径。通过将不同业务模块的日志分离存储,可以有效解决默认日志路径导致的磁盘空间管理困难和问题排查效率低下等痛点,提升系统运维的精细化管理水平。 阅读详情


先描述一下问题,多个服务器实现的负载均衡,每个服务器存储在自己的硬盘里。但是现在需要对日志做统一的分析,在多个服务器上统计就麻烦了。思路是把日志统一到一台日志服务器上,再统一做统计分析。怎么统一到一台服务器上,说实话没有特别好的思路,最后尝试了log4j的SocketAppender。查了不少网络资源,都说的有些不明了,还是得亲自尝试之后才见分晓。

1、客户端的配置

客户端的配置比较简单,只需要告诉log4j需要监听哪个远程服务器的哪个端口即可。直接在log4j.properties里直接配置就好。

[html]  view plain copy
  1. log4j.appender.logs=org.apache.log4j.DailyRollingFileAppender  
  2. log4j.appender.logs.File = /data/logs/request/logs.log  
  3. log4j.appender.logs.layout = org.apache.log4j.PatternLayout  
  4. log4j.appender.logs.layout.ConversionPattern=%d [%t] - %m%n  
  5. log4j.appender.logs.DatePattern='.'yyyy-MM-dd'.log'  
  6.   
  7. log4j.appender.socket=org.apache.log4j.net.SocketAppender  
  8. log4j.appender.socket.RemoteHost=172.16.2.152  
  9. log4j.appender.socket.Port=4560  
  10. log4j.appender.socket.LocationInfo=true  
  11. #下面这两句感觉没用  
  12. log4j.appender.socket.layout=org.apache.log4j.PatternLayout  
  13. log4j.appender.socket.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%t%m%n  
  14.   
  15. #将日志写入本地和远程日志服务器  
  16. log4j.logger.com.test.core.filter =DEBUG,socket,logs
 

2、日志服务器的配置

日志服务器需要单独启动一个java进程,接收客户端给自己发送的socket请求。Log4j提供了org.apache.log4j.net.SocketServer类,直接运行其main函数就行了(当然也可以自己写啦)。

java -cp /log4jsocket/serverConfig/log4j-1.2.16.jarorg.apache.log4j.net.SocketServer 4560 /log4jsocket/log4jserver.properties /log4jsocket/clientConfig

/log4jsocket/serverConfig/log4j-1.2.16.jar是log4j jar包存放的位置,org.apache.log4j.net.SocketServer需要三个参数:

1)4560 是监听的端口号

2)/log4jsocket/log4jserver.properties 是记录日志服务器的日志的配置文件

3)/log4jsocket/clientConfig 是客户端配置文件所在的目录(注意是目录)。

着重说一下org.apache.log4j.net.SocketServer的第三个参数,这个文件夹下配置的是各个客户端的日志的配置。配置文件以.lcf结尾,文件名可以用客户端的IP命名,log4j会自己找发送请求的客户端IP对应的那个配置文件,如172.16.2.46服务器发送的socket请求会寻找172.16.2.46.lcf配置文件,并根据配置将日志写入对应的文件。

[html]  view plain copy
  1. #注意logger后面的值要与client的值相同  
  2. log4j.logger.com.test.core.filter=DEBUG,localLogs  
  3.    
  4. log4j.appender.localLogs=org.apache.log4j.DailyRollingFileAppender  
  5. log4j.appender.localLogs.File=/data/logs/request/172.16.2.46/logs.log  
  6. log4j.appender.localLogs.layout=org.apache.log4j.PatternLayout  
  7. log4j.appender.localLogs.layout.ConversionPattern=%d [%t] - %m%n  
  8. log4j.appender.localLogs.DatePattern='.'yyyy-MM-dd'.log'   


这样做的好处是可以根据不同客户端,将日志写入不同的文件夹下的。

其实,配置过程就这么简单,但是当你这么做之后,你会发现运行org.apache.log4j.net.SocketServer后,客户端向日志服务器发送请求时,会报找不到.lcf文件的错误,得不到想要的结果。原因出在org.apache.log4j.net.SocketServer代码中的一个小bug。 

[java]  view plain copy
  1. <span style="font-size:12px;">LoggerRepository configureHierarchy(InetAddress inetAddress)  
  2.   {  
  3.     cat.info("Locating configuration file for " + inetAddress);  
  4.   
  5.     String s = inetAddress.toString();  
  6.     int i = s.indexOf("/");  
  7.     if (i == -1) {  
  8.       cat.warn("Could not parse the inetAddress [" + inetAddress + "]. Using default hierarchy.");  
  9.   
  10.       return genericHierarchy();  
  11.     }  
  12.     String key = s.substring(0,i);  
  13.   
  14.     File configFile = new File(this.dir, key + CONFIG_FILE_EXT);  
  15.     if (configFile.exists()) {  
  16.       Hierarchy h = new Hierarchy(new RootLogger(Level.DEBUG));  
  17.       this.hierarchyMap.put(inetAddress, h);  
  18.   
  19.       new PropertyConfigurator().doConfigure(configFile.getAbsolutePath(), h);  
  20.   
  21.       return h;  
  22.     }  
  23.     cat.warn("Could not find config file [" + configFile + "].");  
  24.     return genericHierarchy();  
  25.   }</span>  

String key = s.substring(0, i);换成String key = s.substring(i+1);就好了。这段代码是解析IP地址,然后寻找对应IP命名的.lcf配置文件;如果找不到,则解析默认的generic.lcf。由于截取的错误,导致找不到172.16.2.46.lcf,文件夹下又没有generic.lcf,所以会抛异常。

org.apache.log4j.net.SocketServer代码中的另外一个bug是,只能接收来自一台客户端的日志请求,一旦客户端停止运行,SocketServer也将关闭。查看代码:

[java]  view plain copy
  1. public static void main(String[] argv)  
  2.   {     
  3.       if (argv.length == 3)  
  4.       init(argv[0], argv[1], argv[2]);  
  5.     else  
  6.       usage("Wrong number of arguments.");  
  7.     try  
  8.     {  
  9.         cat.info("Listening on port " + port);  
  10.         ServerSocket serverSocket = new ServerSocket(port);  
  11.         cat.info("Waiting to accept a new client.");  
  12.     Socket socket = serverSocket.accept();  
  13.     InetAddress inetAddress = socket.getInetAddress();  
  14.     cat.info("Connected to client at " + inetAddress);  
  15.       
  16.     LoggerRepository h = (LoggerRepository)server.hierarchyMap.get(inetAddress);  
  17.     if (h == null) {  
  18.             h = server.configureHierarchy(inetAddress);  
  19.     }  
  20.       
  21.     cat.info("Starting new socket node.");  
  22.     new Thread(new SocketNode(socket, h)).start();  
  23.       }  
  24.     catch (Exception e)  
  25.     {  
  26.       e.printStackTrace();  
  27.     }  
  28.   }  

问题出在只建立了一个socket连接就不在accept了,加上while循环问题就解决了。

[java]  view plain copy
  1. ServerSocket serverSocket = new ServerSocket(port);  
  2. while(true){  
  3.  cat.info("Waiting to accept a new client.");  
  4.  Socket socket = serverSocket.accept();  
  5.  InetAddress inetAddress = socket.getInetAddress();  
  6.  cat.info("Connected to client at " + inetAddress);  
  7.   
  8.  LoggerRepository h = (LoggerRepository)server.hierarchyMap.get(inetAddress);  
  9.  if (h == null) {  
  10.    h = server.configureHierarchy(inetAddress);  
  11.  }  
  12.   
  13.  cat.info("Starting new socket node.");  
  14.  new Thread(new SocketNode(socket, h)).start();  
  15. }  



 

 

好了。Log4j的配置到此结束。

最后一个问题,日志服务器是linux,需要有一个统一的start、shutdown命令来启动和关闭org.apache.log4j.net.SocketServer。那就需要些shell命令了,下面这段代码参考了http://www.cnblogs.com/baibaluo/archive/2011/08/31/2160934.html

catalina.sh

[plain]  view plain copy
  1. <span style="font-size:12px;">#!/bin/bash  
  2. #端口  
  3. LISTEN_PORT=4560  
  4. #服务端log4j配置文件  
  5. SERVER_CONFIG=/log4jsocket/server.properties  
  6. #客户端的配置  
  7. CLIENT_CONFIG_DIR=/log4jsocket/clientConfig  
  8.   
  9. #Java程序所在的目录(classes的上一级目录)  
  10. APP_HOME=/opt/log4jsocket/serverConfig   
  11. #需要启动的Java主程序(main方法类)  
  12. APP_MAINCLASS=org.apache.log4j.net.SocketServer  
  13.    
  14. #拼凑完整的classpath参数,包括指定lib目录下所有的jar  
  15. CLASSPATH=$APP_HOME  
  16. for i in "$APP_HOME"/*.jar; do     
  17.     CLASSPATH="$CLASSPATH":"$i"  
  18. done  
  19.   
  20. #JDK所在路径  
  21. JAVA_HOME="/opt/jdk1.6.0_30"   
  22. #执行程序启动所使用的系统用户,考虑到安全,推荐不使用root帐号  
  23. RUNNING_USER=root  
  24.    
  25. #java虚拟机启动参数  
  26. JAVA_OPTS="-ms512m -mx512m -Xmn256m -Djava.awt.headless=true -XX:MaxPermSize=128m"   
  27.   
  28. #初始化psid变量(全局)  
  29. psid=0  
  30.    
  31. checkpid() {  
  32.    javaps=`$JAVA_HOME/bin/jps -l | grep $APP_MAINCLASS`  
  33.    
  34.    if [ -n "$javaps" ]; then  
  35.       psid=`echo $javaps | awk '{print $1}'`  
  36.    else  
  37.       psid=0  
  38.    fi  
  39. }  
  40.   
  41. start() {  
  42.    checkpid  
  43.    
  44.    if [ $psid -ne 0 ]; then  
  45.       echo "================================"  
  46.       echo "warn: $APP_MAINCLASS already started! (pid=$psid)"  
  47.       echo "================================"  
  48.    else  
  49.       echo -n "Starting $APP_MAINCLASS ..."  
  50.       JAVA_CMD="nohup $JAVA_HOME/bin/java -classpath $CLASSPATH $APP_MAINCLASS $LISTEN_PORT $SERVER_CONFIG $CLIENT_CONFIG_DIR >/dev/null 2>&1 &"  
  51.       su - $RUNNING_USER -c "$JAVA_CMD"  
  52.       checkpid  
  53.       if [ $psid -ne 0 ]; then  
  54.          echo "(pid=$psid) [OK]"  
  55.       else  
  56.          echo "[Failed]"  
  57.       fi  
  58.    fi  
  59. }  
  60.   
  61. stop() {  
  62.    checkpid  
  63.    
  64.    if [ $psid -ne 0 ]; then  
  65.       echo -n "Stopping $APP_MAINCLASS ...(pid=$psid) "  
  66.       su - $RUNNING_USER -c "kill -9 $psid"  
  67.       if [ $? -eq 0 ]; then  
  68.          echo "[OK]"  
  69.       else  
  70.          echo "[Failed]"  
  71.       fi  
  72.    
  73.       checkpid  
  74.       if [ $psid -ne 0 ]; then  
  75.          stop  
  76.       fi  
  77.    else  
  78.       echo "================================"  
  79.       echo "warn: $APP_MAINCLASS is not running"  
  80.       echo "================================"  
  81.    fi  
  82. }  
  83.   
  84. status() {  
  85.    checkpid  
  86.    
  87.    if [ $psid -ne 0 ];  then  
  88.       echo "$APP_MAINCLASS is running! (pid=$psid)"  
  89.    else  
  90.       echo "$APP_MAINCLASS is not running"  
  91.    fi  
  92. }  
  93. info() {  
  94.    echo "System Information:"  
  95.    echo "****************************"  
  96.    echo `head -n 1 /etc/issue`  
  97.    echo `uname -a`  
  98.    echo  
  99.    echo "JAVA_HOME=$JAVA_HOME"  
  100.    echo `$JAVA_HOME/bin/java -version`  
  101.    echo  
  102.    echo "APP_HOME=$APP_HOME"  
  103.    echo "APP_MAINCLASS=$APP_MAINCLASS"  
  104.    echo "****************************"  
  105. }  
  106. case "$1" in  
  107.   
  108.    'start')  
  109.       start  
  110.       ;;  
  111.    'stop')  
  112.      stop  
  113.      ;;  
  114.    'restart')  
  115.      stop  
  116.      start  
  117.      ;;  
  118.    'status')  
  119.      status  
  120.      ;;  
  121.    'info')  
  122.      info  
  123.      ;;  
  124.   *)  
  125.      echo "Usage: $0 {start|stop|restart|status|info}"   
  126.      exit 0   
  127. esac  
  128. </span>  
startup.sh

[plain]  view plain copy
  1. <span style="font-size:12px;">#!/bin/sh  
  2. EXECUTABLE=/log4jsocket/catalina.sh  
  3. exec "$EXECUTABLE" start "$@"</span>  
shutdown.sh

[plain]  view plain copy
  1. <span style="font-size:12px;">EXECUTABLE=/log4jsocket/catalina.sh  
  2. exec "$EXECUTABLE" stop "$@"</span>  


转自:http://blog.csdn.net/kdmhh/article/details/8208522

Log4j2日志审计合规配置与实时告警实战:3天通过等保三级 日志审计是信息安全体系中的核心环节,其原理在于通过系统化记录应用运行状态与用户操作行为,形成可追溯的电子证据链。在Java技术栈中,Log4j2作为主流的日志框架,其配置的合规性直接决定了审计的有效性。从技术价值看,规范的日志不仅是排查故障的利器,更是满足等保合规、实现安全事件追溯与态势感知的基石。尤其在金融、政务等强监管场景下,应用需要满足审计记录完整性、防篡改、集中存储与实时告警等硬性要求。本文聚焦于这一核心需求,深入剖析如何通过定制Log4j2配置模板与集成轻量级告警工具包,快速构建满足等保三级要求的 阅读详情

相关推荐

Java 开发中 log4j日志存储的高可用方案

在现代Java应用开发中,日志系统是监控应用运行状态、排查问题和分析性能的关键基础设施。随着系统规模扩大和业务复杂度提高,传统的单机日志存储方案已无法满足高可用性要求。本文旨在探讨如何基于log4j构建高可用的日志存储系统,确保日志数据不丢失、可追溯且易于分析。介绍日志存储的基本概念和高可用需求分析log4j的核心架构和扩展机制探讨多种高可用日志存储方案提供具体实现和配置示例讨论性能优化和监控策略展望未来发展趋势log4j

Java大师兄的博客 1034

log4j发送日志到远程服务器(Linux服务器) syslog+端口

log4j可以将日志写到远程服务器(Linux服务器)上。

m0_55212193的博客 1383

Java 开发中 log4j日志存储的分布式方案

在分布式系统中,各个服务节点会产生大量的日志信息。这些日志分散在不同的节点上,给日志的管理和分析带来了极大的困难。本方案的目的是提供一种有效的方法,将 log4j 记录的日志集中存储到分布式存储系统中,方便后续的查询、分析和监控。本方案的范围涵盖了从 log4j 配置到分布式存储系统集成的整个过程,包括日志的收集、传输、存储和管理。本文将按照以下结构进行组织:首先介绍核心概念与联系,包括 log4j、分布式存储系统等相关概念;

AI开发架构师 992

log4j 日志服务器

<br />//因为暂时没有时间整理,下面的作为草稿先放着<br /> <br /> <br />利用Log4j 创建日志服务器<br />在J2EE集群运行模式下,日志的记录是一个重要的问题,如果集群中每一个实例均采用自己的日志记录方式,将会在每一台计算机上均有自己的日志文件,对于日志的查看也是一个问题。<br />幸亏我们有Log4JLog4J中有通过网络的日志服务器<br />日志服务器参数的配置<br />#文件名socketserver.properties<br />#log4j.rootCa

cuker919的专栏 3342

log4j通过SocketAppender将日志内容发送到远程服务器

通过log4j可以实现日志内容发送到其他服务器,其他机器可以再对日志做统一处理,比如发送邮件,发送短信,日志分析等等。具体demo如下: 1. 客户端代码          客户端代码分为log4j的配置文件,和客户端记录log4j日志类         log4j.xml内容如下        [html] view plaincopy

yydcj的专栏 3812

【亲测免费】 阿里云日志服务之Log4j Appender:统一日志管理新纪元

阿里云日志服务之Log4j Appender:统一日志管理新纪元 随着微服务架构的普及和大数据时代的到来,高效、可靠的日志管理成为了开发者面临的重大挑战之一。今天,我们要向大家隆重推荐一个开源宝藏——阿里云Log4j Appender。该项目是由阿里巴巴云团队精心打造,旨在无缝对接业界广泛使用的Log4j框架与强大的阿里云日志服务,引领日志收集和分析的新潮流。 项目介绍 阿里云Log4j Appe...

gitblog_00051的博客 589

log4j日志信息写到一个文件里面的方法

寒夜二十五 1172

java日志保存_log4j实现日志集中存储

先描述一下问题,多个服务器实现的负载均衡,每个服务器存储在自己的硬盘里。但是现在需要对日志做统一的分析,在多个服务器上统计就麻烦了。思路是把日志统一到一台日志服务器上,再统一做统计分析。怎么统一到一台服务器上,说实话没有特别好的思路,最后尝试了log4jSocketAppender。查了不少网络资源,都说的有些不明了,还是得亲自尝试之后才见分晓。1、客户端的配置:客户端的配置比较简单,只需要告诉...

weixin_42134117的博客 1378

Spring Boot中使用log4j实现http请求日志入mongodb

之前在《使用AOP统一处理Web请求日志》一文中介绍了如何使用AOP统一记录web请求日志。基本思路是通过aop去切web层的controller实现,获取每个http的内容并通过log4j日志内容写到应用服务器的文件系统中。 但是当我们在集群中部署应用之后,应用请求的日志被分散记录在了不同应用服务器的文件系统上,这样分散的存储并不利于我们对日志内容的检索。解决日志分散问题的方案多种...

abc_1114的博客 122

推荐开源项目:logging-log4j-server

推荐开源项目:logging-log4j-server 1. 项目介绍 logging-log4j-server 是一个基于Apache Log4j的轻量级日志服务器解决方案。随着Log4j框架的广泛使用,该项目旨在提供一个易于集成、功能强大的日志收集和管理平台。尽管原仓库已被迁移到Log4j Samples Repository,但这并不影响其作为高效日志处理工具的价值。 2. 项目技术分析 这...

gitblog_00021的博客 335

微服务架构师封神之路02-为你的微服务应用添加日志

微服务架构师封神之路02-为你的微服务应用添加日志关于Kubernetes日志架构我们的目标helloworld project项目结构pom.xmlDockerfileAppMain.javalog4j2.xml部署测试 关于Kubernetes日志架构 讨论这个话题的技术文章不少,就是废话太多。简单说两个层面, 每个微服务内部:将日志写入到标准输出流中(Standard output stream, stdout and stderr) 整个Kubernetes cluster:在每个node上部署l

b5wang's Workshop 508

[log4j]从零开始如何利用日志分析提升系统性能

集中化存储:使用ELK栈(Elasticsearch、Logstash、Kibana)或Splunk等工具,将分散的日志汇总至统一平台,便于查询与分析。- 选择日志框架:如Log4j、Logback等,配置日志级别(DEBUG、INFO、ERROR)以捕获所需数据。日志分析需长期坚持,通过定期回顾历史数据,预测潜在风险并优化系统架构,形成性能提升的良性循环。通过系统化的日志收集、分析与行动,可显著提升系统性能与可靠性,为业务发展提供坚实支撑。- 错误率:统计ERROR级日志的频率,分析异常根本原因。

HUNXEWIg的博客 324

Flink日志采集、集中存储、可视化查询实践

笔者的开发大数据平台中包含基于Flink的可视化计算管道开发和运维功能。状态存储器中数据的查看和节点的日志查看功能是其重要的辅助支撑功能。它能使得在大数据平台上就能完全实现计算管道的开发、调试、部署,逐渐摆脱Flink的原生界面。Flink分JobManager和TaskManager,JobManager中的日志是总体性的,构建计算管道的过程,就是在JobManager中完成的,而Job的执行则是在TaskManager中。就可以从中找失败原因。

OkGogooXSailboat的博客 1595
上一篇: log4j学习之SocketAppender
下一篇: log4j的简单的例子~以及使用log4j和不使用log4j的对比
ketonfly
博客等级 码龄16年 17粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值