我发布了问题:how to use log4j in Multithread using java?。我得到了回应我尝试了一个解决方案,使用这个解决方案,我为每个线程创建了不同的日志文件,但每个线程的包含将陷入困境。
package com.demo;
import com.arosys.customexception.KeyNotFoundException;
import com.arosys.doqeap.exception.NullObjectFoundException;
import com.arosys.doqeap.exception.ValueNotFoundException;
import com.arosys.doqeap.serviceconfiguration.ServiceConfiguration;
import com.arosys.logger.LoggerFactory;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import java.io.IOException;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
class wokerThread implements Runnable
{
private Connection connection;
private String requestExchangeName = null;
private String requestQueueName = null;
private String requestRoutingKey = null;
private boolean durable = true;
private ServiceConfiguration serviceConfiguration = null;
public wokerThread(ServiceConfiguration config, Connection conn)
{
this.connection=conn;
this.serviceConfiguration=config;
}
public void init() throws KeyNotFoundException, NullObjectFoundException, com.arosys.doqeap.exception.KeyNotFoundException, ValueNotFoundException
{
if(connection == null) throw new NullObjectFoundException("MQConnection object found NULL(First set this Object)");
if(serviceConfiguration == null) throw new NullObjectFoundException("ServiceConfiguration object found NULL(First set this Object)");
requestExchangeName = serviceConfiguration.getValue("request.exchangename");
requestQueueName =serviceConfiguration.getValue("request.queuename");
requestRoutingKey = serviceConfiguration.getValue("request.routekeyname");
} // end of init()
public void run()
{
Channel channel=null;
QueueingConsumer consumer = null;
QueueingConsumer.Delivery delivery = null;
boolean noAck = false;
String exchangeType = "direct";
Logger logger1=LoggerFactory.getLogger(" com.demo.wokerThread","resources/log4j.xml");
logger1.removeAllAppenders();
FileAppender appender = null;
PatternLayout layout = new PatternLayout();
layout.setConversionPattern("%d{yyyy-MM-dd HH:mm:ss} %p %c{1}:%L - %m%n");
try {
appender = new FileAppender(layout,"logs\\worker"+Thread.currentThread().getName()+".log",true);
logger1.addAppender(appender);
logger1.setLevel((Level) Level.DEBUG);
} catch (IOException ex) {
ex.printStackTrace();
}
logger1.info("Thread name-"+ Thread.currentThread().getName());
logger1.info("Appender Name "+appender.getFile());
Thread runThread = Thread.currentThread();
try // try
{
channel = connection.createChannel();
channel.exchangeDeclare(requestExchangeName, exchangeType, durable);
channel.queueDeclare(requestQueueName, durable,false,false,null);
channel.basicQos(1);
channel.queueBind(requestQueueName, requestExchangeName, requestRoutingKey);
consumer = new QueueingConsumer(channel);
channel.basicConsume(requestQueueName, noAck, consumer);
logger1.info(runThread.getName()+" :: Starting to listen to Request Queue. . . . . . . . . . . ."+runThread);
while(true)
{
delivery = consumer.nextDelivery();
logger1.info(runThread+" :: Message picked up from Queue--"+delivery);
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
} // end of stop while loop
}
// end of try 1
catch(Exception e){ logger1.error(e); } // catch 1
} // run
}
package com.demo;
import com.arosys.doqeap.exception.DatabaseException;
import com.arosys.doqeap.exception.FileNotFoundException;
import com.arosys.doqeap.exception.KeyNotFoundException;
import com.arosys.doqeap.exception.MQConnectionNotEstablished;
import com.arosys.doqeap.exception.NullObjectFoundException;
import com.arosys.doqeap.exception.ValidationException;
import com.arosys.doqeap.exception.ValueNotFoundException;
import com.arosys.doqeap.mqmanager.MQConnectionManager;
import com.arosys.doqeap.serviceconfiguration.ServiceConfiguration;
import com.rabbitmq.client.Connection;
import java.io.IOException;
import java.net.URISyntaxException;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ThreadDemo
{
public static void main(String s[])
{
try {
ServiceConfiguration sc=new ServiceConfiguration("e:\\07-10\\Development\\standardizationService\\StandardizeAccountService.xml");
try {
sc.loadProperties();
} catch (IOException ex) {
Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
} catch (ValidationException ex) {
Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
} catch (DatabaseException ex) {
Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
} catch (URISyntaxException ex) {
Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
} catch (FileNotFoundException ex) {
Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
}
MQConnectionManager mq=new MQConnectionManager(sc);
Connection mQConnection = mq.getMQConnection();
wokerThread wr=new wokerThread(sc,mQConnection);
wr.init();
Thread[] worker=new Thread[2];
for(int i=0;i<worker.length;i++)
{
worker[i]=new Thread(wr,""+i);
worker[i].start();
}
} catch (com.arosys.customexception.KeyNotFoundException ex) {
Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
} catch (NullObjectFoundException ex) {
Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
} catch (MQConnectionNotEstablished ex) {
Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
} catch (ValueNotFoundException ex) {
Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
} catch (KeyNotFoundException ex) {
Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
这里ThreadDemo类创建两个线程,而workerTheread类将从队列中侦听消息(RabbitMQ)。每个线程将从队列中读取消息并在指定的日志文件上写入日志消息。
2011-11-24 13:24:35 INFO wokerThread:73 - Thread name-0
2011-11-24 13:24:35 INFO wokerThread:74 - Appender Name logs\worker0.log
2011-11-24 13:24:35 INFO wokerThread:73 - Thread name-1
2011-11-24 13:24:35 INFO wokerThread:74 - Appender Name logs\worker1.log
2011-11-24 13:24:35 INFO wokerThread:88 - 0 :: Starting to listen to Request Queue. . . . . . . . . . . .Thread[0,5,main]
2011-11-24 13:24:35 INFO wokerThread:88 - 1 :: Starting to listen to Request Queue. . . . . . . . . . . .Thread[1,5,main]
2011-11-24 13:24:39 INFO wokerThread:93 - Thread[0,5,main] :: Message picked up from Queue--com.rabbitmq.client.QueueingConsumer$Delivery@cfec48
2011-11-24 13:24:39 INFO wokerThread:93 - Thread[1,5,main] :: Message picked up from Queue--com.rabbitmq.client.QueueingConsumer$Delivery@a17083
2011-11-24 13:24:39 INFO wokerThread:93 - Thread[0,5,main] :: Message picked up from Queue--com.rabbitmq.client.QueueingConsumer$Delivery@e1d5ea
2011-11-24 13:24:39 INFO wokerThread:93 - Thread[0,5,main] :: Message picked up from Queue--com.rabbitmq.client.QueueingConsumer$Delivery@a31e1b
2011-11-24 13:24:40 INFO wokerThread:93 - Thread[1,5,main] :: Message picked up from Queue--com.rabbitmq.client.QueueingConsumer$Delivery@10da5eb
根据我的说法,thread0日志记录在worker0上同样适用于thread1。我无法确定问题所在。请帮助我吗?
此致
答案 0 :(得分:3)
您正在使用相同的wokerThread
实例初始化两个Thread
。这样第一个worker的appender就会被第二个线程删除,并且会添加第二个日志文件(worker1)的appender。
尝试:
// wokerThread wr=new wokerThread(sc,mQConnection); --> move this into the loop
// wr.init(); --> move this into the loop
Thread[] worker=new Thread[2];
for(int i=0;i<worker.length;i++)
{
wokerThread wr=new wokerThread(sc,mQConnection); // --> moved into the loop
wr.init(); // --> moved into the loop
worker[i]=new Thread(wr,""+i);
worker[i].start();
}
等等,这还不够。您应该在每个wokerThread
实例中配置不同的Logger实例。 Logger实例由其名称标识,因此在wokerThread.java
方法的run()
中,您可以使用不同的名称检索不同的Logger
实例。在这里,您可以使用当前线程的名称来区分记录器:
public void run()
{
...
String threadName = Thread.currentThread().getName(); // --> added line
// --> now append thread's name to logger name:
Logger logger1=LoggerFactory.getLogger(" com.demo.wokerThread_" + threadName,"resources/log4j.xml");
logger1.removeAllAppenders();
...
}