`
cuker919
  • 浏览: 86880 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

log4j 日志服务器_项目实际使用日记

 
阅读更多

需求:近期有个项目要用到集群部署 + 话单日志,刚开始项目部署在多台linux服务器上,每台服务器上都生成自己的话单,但是对账系统只到一台服务器上取话单,这时就要把所有的话单日志放到同一台机子上;刚开始是通过linux地址映射到同一台机子上的,现在打算尝试用编码到项目里面实现这个需求。

话单格式:订单号|价格|产品id

注:生成的话单文件里面只能有“010101|5566|888999”等多行这样的信息,其他的信息不能放到话单里面来。

暂时先熟悉下面资料

http://blog.csdn.net/Didizyp/archive/2005/08/28/466730.aspx

主要看:10.org.apache.log4j.net.SocketAppender,以套接字方式向服务器发送日志,然后由服务器将信息输出。

下面的两个连接主要配置log4j服务器和客户端的配置

http://jiangzhengjun.javaeye.com/blog/526364

http://blog.csdn.net/z3h/archive/2005/11/01/520893.aspx

一、 准备

这里需要用到 Log4j、Quartz和java+Socket线程知识准备,下面是对应的入门连接

http://blog.csdn.net/cuker919/category/640785.aspx log4j的相关文章

http://blog.csdn.net/cuker919/archive/2010/06/28/5698691.aspx Quartz任务调度快速入门

java+Socket线程:主要是Socket服务器和客户端知识,这里实现的是一个服务器多个客户端。

二、改写log4j服务器的源代码

这里改写的是SimpleSocketServer(服务器)和SocketNode(起一个线程监听客户端发过来的消息)。

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.xml.DOMConfigurator;

/**
* log4j服务器类,相当于SimpleSocketServer
*/
public class SimpleSocketServerThread {
private static Logger logger = Logger.getLogger(SimpleSocketServerThread.class);
public int port;
public String configFile;
ServerSocket serverSocket = null;
static int count = 0;

Socket socket;
LoggerRepository hierarchy = LogManager.getLoggerRepository();
ObjectInputStream ois;

public SimpleSocketServerThread(){
}

public SimpleSocketServerThread(int port,String configFile){
this.port = port;
this.configFile = configFile;
if(configFile.endsWith(".xml")) {
DOMConfigurator.configure(configFile);
} else {
PropertyConfigurator.configure(configFile);
}

try {
serverSocket = new ServerSocket(port);
while(true){
socket = serverSocket.accept();
ois = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
new ServerToLog4j(hierarchy,ois,socket);
}
} catch (IOException e) {
logger.error(" ServerSocket IOException");
}
}

public static void main(String[] args) {
SimpleSocketServerThread st = new SimpleSocketServerThread(9090,"E:/unipay_workspace/log4jService/WebRoot/WEB-INF/classes/socketserver.properties");
}
}

/**
* 起一个线程监听客户端发过来的消息,并写进log4j ;本类改写了SocketNode类的源代码
*/
class ServerToLog4j extends Thread{
private static Logger logger = Logger.getLogger(ServerToLog4j.class);
private LoggerRepository hierarchy;
ObjectInputStream ois;
Socket socket;
public ServerToLog4j(){

}

public ServerToLog4j(LoggerRepository hierarchy,ObjectInputStream ois,Socket socket){
this.hierarchy = hierarchy;
this.ois = ois;
this.socket = socket;
start();
}

public void run(){
LoggingEvent event;
Logger remoteLogger;

try {
if (ois != null) {
while(true) {
// read an event from the wire
event = (LoggingEvent) ois.readObject();
// get a logger from the hierarchy. The name of the logger is taken to be the name contained in the event.
remoteLogger = hierarchy.getLogger(event.getLoggerName());
//event.logger = remoteLogger;
// apply the logger-level filter
if(event.getLevel().isGreaterOrEqual(remoteLogger.getEffectiveLevel())) {
// finally log the event as if was generated locally
remoteLogger.callAppenders(event);
}
}
}
} catch(java.io.EOFException e) {
//读取的时候到达尾端抛出的异常,屏蔽掉
//logger.error("Caught java.io.EOFException closing conneciton.");
} catch(java.net.SocketException e) {
logger.error("Caught java.net.SocketException closing conneciton.");
} catch(InterruptedIOException e) {
Thread.currentThread().interrupt();
logger.error("Caught java.io.InterruptedIOException: ");
logger.error("Closing connection.");
} catch(IOException e) {
logger.error("Caught java.io.IOException: ");
logger.error("Closing connection.");
} catch(Exception e) {
logger.error("Unexpected exception. Closing conneciton.");
} finally {
if (ois != null) {
try {
ois.close();
} catch(Exception e) {
logger.error("ObjectInputStream Could not close connection.");
}
}
if (socket != null) {
try {
socket.close();
} catch(InterruptedIOException e) {
Thread.currentThread().interrupt();
} catch(IOException ex) {
}
}
}
}
}

三、配置log4j的服务器文件和客户端文件

服务器文件名:socketserver.properties

下面的log4j.MinuteRollingFileAppender是已经把log4j源码修改过了,原因是项目要求按15分钟分割一个话单,原来只能按1分钟分割,经过修改源码之后,可以按n分钟分割话单日志。

MinuteRollingFileAppender实例请看:http://blog.csdn.net/cuker919/archive/2010/01/26/5257330.aspx

log4j.rootLogger=WARN,C2,A3

log4j.appender.A3=org.apache.log4j.RollingFileAppender
log4j.appender.A3.file=e://home//a.txt
log4j.appender.A3.MaxFileSize=1024KB
log4j.appender.A3.MaxBackupIndex=999
log4j.appender.A3.layout=org.apache.log4j.PatternLayout
log4j.appender.A3.layout.ConversionPattern=/n/n[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

#--------------------------------------------
log4j.appender.C2=log4j.MinuteRollingFileAppender
log4j.appender.C2.DatePattern='_'yyyyMMddHHmm00'.log'
log4j.appender.C2.File=/home/vac2/test
log4j.appender.C2.layout=org.apache.log4j.PatternLayout
log4j.appender.C2.layout.ConversionPattern=/ %m%n
log4j.logger.C2=WARN,C2

客户端文件:log4j.properties(默认的log4j文件名)

#soketClient
log4j.rootCategory=,A1
log4j.addivity.org.apache=true
#
log4j.appender.A1=org.apache.log4j.net.SocketAppender
log4j.appender.A1.RemoteHost=127.0.0.1
log4j.appender.A1.Port=9090
log4j.appender.A1.LocationInfo=true

客户端在web.xml文件里面的加载配置:

<!--spring +log4j 加载 -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>60000</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.util.Log4jConfigListener
</listener-class>
</listener>

四、Quartz的配置和相关的处理类

在spring的配置文件里面applicationContext.xml加入Quartz的配置文件

<!-- 定时任务 -->
<import resource="classpath*:job.xml"></import>

Quartz的配置文件job.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<bean id="logDealService" class="log4j.LogDealService">

</bean>
<!-- 下面是话单任务定时访问log4j,为了就是防止到达15(可配)分钟的时候,没有话单生成,强制每隔15分钟分割一个话单 -->
<bean id="billJobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" depends-on="logDealService"><!--依赖那个bean的装载-->
<!--执行的bean-->
<property name="targetObject" ref="logDealService"/>
<!--执行的方法-->
<property name="targetMethod" value="rollOver"/>
<property name="concurrent" value="true"/>
</bean>
<bean id="cronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean" depends-on="billJobDetail">
<property name="jobDetail" ref="billJobDetail"/>
<property name="cronExpression">
<!-- 每隔1min执行一次 -->
<value>0/30 * * * * ?</value>
</property>
</bean>

<!-- 下面是log4j 日志 SocketServer 服务任务,只加载一次-->
<bean id="log4jServerJobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" depends-on="logDealService"><!--依赖那个bean的装载-->
<!--执行的bean-->
<property name="targetObject" ref="logDealService"/>
<!--执行的方法-->
<property name="targetMethod" value="log4jServer"/>
<property name="concurrent" value="true"/>
</bean>
<bean id="simpleTrigger"
class="org.springframework.scheduling.quartz.SimpleTriggerBean" depends-on="log4jServerJobDetail">
<property name="jobDetail" ref="log4jServerJobDetail"/>
<property name="repeatCount">
<!-- 只执行一次 -->
<value>0</value>
</property>
<property name="repeatInterval">
<!-- 重复执行间隔时间1微秒 -->
<value>1</value>
</property>
</bean>

<!-- 将上面的任务调度器进行管理 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">
<property name="triggers">
<list>
<ref bean="cronTrigger"/>
<ref bean="simpleTrigger" />
</list>
</property>
</bean>
</beans>

Quartz任务的处理类:

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import java.io.IOException;

public class LogDealService {
private Logger log2 = LogManager.getLogger(LogDealService.class);

//打印话单日志文件
private static Logger LOG = LogManager.getLogger("A1");

/**
* 定时访问log4j的方法
*/
public void rollOver() throws IOException {

//为了客户端只打印话单所以要屏蔽掉一些不需要的日志,
//这里可以根据你的项目需要配置更高的级别DEBUG, INFO, WARN, ERROR, FATAL
LOG.warn("0000000000000"+" | "+"11111111111111111");
}

/**
* log4j日志服务器
*/
public void log4jServer(){
System.out.println("log4jServer quartz job startup .......");
SimpleSocketServerThread st = new SimpleSocketServerThread(9090,"E:/unipay_workspace/log4jService/WebRoot/WEB-INF/classes/socketserver.properties");
}
}

五、启动tomcat发现报错

是log4j服务器ServerSocket和客户端socket报的错,不影响使用,其实如果把服务器和客户端分开打包,先启动服务器,客户端就不会报错,这里是把他们两都放到一个项目里面了,由于同时加载,服务器还没启动客户端就访问了,所以才报错。

log4j:ERROR Could not connect to remote log4j server at [localhost]. We will try again later.
java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:367)
at java.net.Socket.connect(Socket.java:524)
at java.net.Socket.connect(Socket.java:474)
at java.net.Socket.<init>(Socket.java:371)
at java.net.Socket.<init>(Socket.java:213)

六、o(∩_∩)o...哈哈!!!

后面有时间再完善........

分享到:
评论

相关推荐

    hana log日志空间占满处理.pdf

    HANA在线日志清理方法,不能直接进入/hana/log日志目录下进行删除操作,此种操作会给系统带来极大的灾难,需要根据SAP给出的方法来进行处理

    使用log_format为Nginx服务器设置更详细的日志格式方法

    nginx服务器日志相关指令主要有两条,一条是log_format,用来设置日志格式,另外一条是access_log,用来指定日志文件的存放路径、格式和缓存大小,一般在nginx的配置文件中日记配置(/usr/local/nginx/conf/nginx....

    android日志分析&崩溃拦截

    Android开发的日记打印工具类Log4jForAndroid和LogUtil.rar Android捕获全局异常源码.rar Android控制整个项目Log的打印和关闭.zip Android日志打印类LogUtils.rar android端_手机端日志查看工具.rar app打印...

    分类日记本(含简单加密功能)

    3、请创建日志文件夹“D:\Log\dailyLog\logs” 初次使用请注册一个属于自己的账户吧!(点击用户信息即可注册,一般的功能提交都需要2步才能完成:第一步是请求使用功能,程序修改状态(或者用户编辑修改信息),第...

    SystemdJournal2Gelf:从systemds的日记中导出条目,然后使用gelf将其发送到Graylog服务器

    从systemd的日志中导出条目,然后使用gelf将其发送到Graylog服务器。 该脚本是用Google go编写的,可以更轻松地编译和分发到您的计算机。 依存关系: 此回购包括 谷歌golang 安装/编译 通过签出仓库来编译此...

    学习日志:一种在线日记系统,可让您跟踪已了解的有关特定主题的信息。 用Django构建

    将一个项目的库与其他项目分开是有益的,并且在我们将学习日志部署到第20章的服务器上时是必要的。为您的项目创建一个名为learning_log的新目录,在终端中切换到该目录,然后输入以下代码来创建虚拟环境: ...

    captains-log-api:Captainslog的无服务器后端

    该项目是使用带有无服务器后端的NextJS进行的个人实验创建的。 它是使用引导的。 该项目将基础结构指定为代码。 它利用sst-cli工具在AWS上创建所需的所有资源。 端点由lambda函数提供动力(请参阅/src/ )。 日记...

    artistic-log:艺术家的在线日记应用程序

    艺术日志 该自述文件通常会记录启动和运行应用程序所需的所有步骤。 您可能要讲的内容: Ruby版本 系统依赖 配置 数据库创建 数据库初始化 如何运行测试套件 服务(作业队列,缓存服务器,搜索引擎等) 部署说明...

    asp.net知识库

    也论该不该在项目中使用存储过程代替SQL语句 如何使数据库中的表更有弹性,更易于扩展 存储过程——天使还是魔鬼 如何获取MSSQLServer,Oracel,Access中的数据字典信息 C#中利用GetOleDbSchemaTable获取数据库内表信息...

    linux自动清理日志脚本分享

    2.根据给定日志目录,删除时间 结合crontab进行清理日志,清理完成后,后在/var/log/deltelog/ 生成按照月的清理日志 3.扩展,因为脚本采用mtime(最后修改时间)进行删除,所以可以适用于删除过期备份等,不受文件名称的...

    基于JSP的博客系统论文+源码+数据库

    Blog的内容和目的有很大的不同,从对其他网站的超级链接和评论,有关公司、个人构想到日记、照片、诗歌、散文,甚至科幻小说的发表或张贴都有。而此系统也主导这一思想,主要为了完善地实现注册用户发表文章,访客...

    C#.net_经典编程例子400个

    136 实例099 使用EventLog组件向本机现有日志中添加条目 138 3.4 FileSystemWatcher组件 140 实例100 使用FileSystemWatcher组件监视系统日志文件是否被更改 140 3.5 HelpProvider组件 142 ...

    C#程序开发范例宝典(第2版).part08

    精选570个典型范例,全面覆盖实用和热点技术,涉及面广,实用性强源于实际项目开发,帮助读者短时间掌握更多实用技术,提高编程水平范例经过精心编排,重点、难点突出,易学易懂书后附录提供快速索引,即查、即学、...

    C#程序开发范例宝典(第2版).part13

    精选570个典型范例,全面覆盖实用和热点技术,涉及面广,实用性强源于实际项目开发,帮助读者短时间掌握更多实用技术,提高编程水平范例经过精心编排,重点、难点突出,易学易懂书后附录提供快速索引,即查、即学、...

    C#程序开发范例宝典(第2版).part02

    精选570个典型范例,全面覆盖实用和热点技术,涉及面广,实用性强源于实际项目开发,帮助读者短时间掌握更多实用技术,提高编程水平范例经过精心编排,重点、难点突出,易学易懂书后附录提供快速索引,即查、即学、...

    C#程序开发范例宝典(第2版).part12

    精选570个典型范例,全面覆盖实用和热点技术,涉及面广,实用性强源于实际项目开发,帮助读者短时间掌握更多实用技术,提高编程水平范例经过精心编排,重点、难点突出,易学易懂书后附录提供快速索引,即查、即学、...

Global site tag (gtag.js) - Google Analytics