多线程,如何根据线程端口来命名log4j日志文件的输出路径

时间:2021-02-04 21:55:19
我的客户端程序是监听服务器端的 n个端口,服务器端的端口同时往外发数据。现在我用log4j日志文件来输出数据,用的是log4j.xml配置文件。但是我想根据端口号,来设置输出路径,我想实现把日志文件写成下面两种情况的一种就行:
1.  .../<端口号>_debug.log     2: .../端口号/debug.log

求高手告诉我怎么弄?
我的log4j.xml中 <param name="File" value="${dir}/debug.log" /> ,
我用过System.setProperty("dir", ...+this.getPort()); 但是这样的话日志都混乱了,真心不知道怎么办了,都弄了好几天了.  

上面两种情况弄出来一种就行! 

9 个解决方案

#1


没人回复啊..... 自己往上顶吧,别帖子让沉底了

#2



package log4j;

import java.util.Enumeration;
import java.util.Random;

import org.apache.log4j.Logger;
import org.apache.log4j.RollingFileAppender;

/**
 * 
 * @author Administrator 我的客户端程序是监听服务器端的 n个端口,服务器端的端口同时往外发数据。
 *         现在我用log4j日志文件来输出数据,用的是log4j.xml配置文件。
 *         但是我想根据端口号,来设置输出路径,我想实现把日志文件写成下面两种情况的一种就行: 1. .../<端口号>_debug.log 2:
 *         .../端口号/debug.log
 */
public class ManyLog {
private static final String FILE_HEAD = "F:/test/_";
private static final String FILE_TAIL = "debug.log";
private static final int BUFFER_SIZE = 8192;

public static void main(String[] args) throws Exception {
Logger log = Logger.getRootLogger();
// 端口号
String[] ports = new String[] { "111", "222", "333", "444", "555",
"666", "777", "888", "999" };
// 这里我log4j.properties只配置了一个Appender
RollingFileAppender rfa = getAppender(log);
for (int i = 0; i < 20; i++) {
// 随机端口号
int index = new Random().nextInt(ports.length);
rfa.setFile(FILE_HEAD + ports[index] + FILE_TAIL, true, false,
BUFFER_SIZE);
// ports[index]端口是否打印相应的文件中
log.debug(ports[index] + " : afdasfadsfdas");
}
}

private static RollingFileAppender getAppender(Logger log) {
Enumeration en = log.getAllAppenders();
return (RollingFileAppender) en.nextElement();
}
}




log4j.rootLogger=DEBUG,R
log4j.appender.R=org.apache.log4j.RollingFileAppender
#log4j.appender.R.File=F:/test/log.txt
log4j.appender.R.MaxFileSize=5000KB
log4j.appender.R.Encoding=UTF-8
log4j.appender.R.MaxBackupIndex=100
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n


希望对你有用 多线程,如何根据线程端口来命名log4j日志文件的输出路径

#3


谢谢了,我的配置文件是log4j.xml,不知道能不能用? 我先试一试吧。
 这个帖子先不结,先放着,过一段时间再结。看看能不能有更好的方法。

#4


你这个是用在单线程中的,我的是多线程,不知道能不能用

#5


引用 2 楼 faping_cao 的回复:
Java code?



1234567891011121314151617181920212223242526272829303132333435363738394041424344

package log4j;   import java.util.Enumeration; import java.util.Random;   import org.apache.log4j.L……

今早上刚刚试了试,这个方法在多线程下,貌似不大行啊,日志还是有混乱啊,有什么好的解决办法吗?

#6


<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">

  <appender name="intffile" class="org.apache.log4j.DailyRollingFileAppender">
      <param name="File" value="D:/log/logic_intf.log"/>
      <param name="Append" value="true"/>
      <param name="DatePattern" value="'.'yyyy-MM-dd"/>
      <param name="Threshold" value="debug"/> 
      <layout class="org.apache.log4j.PatternLayout">
         <!-- The default pattern: Date Priority [Category] Message\n -->
         <param name="ConversionPattern" value="%p|%-d{yyyy-MM-dd HH\:mm\:ss}%m%n"/>
      </layout>
   </appender>

   <root>
      <level  value= "debug"/> 
      <appender-ref ref="intffile"/>
   </root>

</log4j:configuration>
这样试试呢

#7


谢谢了,我们不用DailyRollingFileAppender,我们需要的不是一天产生一个日志文件,而是控制文件大小的,呵呵 ,  关键是我的需求是  只有两个 1.  .../<端口号>_debug.log     2: .../端口号/debug.log   ,主要是怎么处理多线程下的日志混乱问题。
其实 我也能直接File file = new File(“这里面可以根据端口号来设置文件名或路径”); 关键是这不是我想要的,我是想用log4j实现,要不用log4j干啥,你说是吧,呵呵。
元芳,你怎么看?

#8



/**
 * 
 * @author Administrator 我的客户端程序是监听服务器端的 n个端口,服务器端的端口同时往外发数据。
 *         现在我用log4j日志文件来输出数据,用的是log4j.xml配置文件。
 *         但是我想根据端口号,来设置输出路径,我想实现把日志文件写成下面两种情况的一种就行: 1. .../<端口号>_debug.log 2:
 *         .../端口号/debug.log
 * 
 * 多线程客户端,一个端口号对应一个线程
 */
public class ManyLogByThread {

public static void main(String[] args) throws Exception {
Logger log = Logger.getRootLogger();
log.setLevel(Level.DEBUG);
// <端口号,Appender>,保存已经使用过的端口号
Map<String, Appender> appenderMap = new HashMap<String, Appender>();
// 端口号
String[] ports = new String[] { "111", "222", "333", "444", "555",
"666", "777", "888", "999" };
// 线程管理
ExecutorService service = Executors.newCachedThreadPool();
// 共享数据
Data data = new Data(log, appenderMap);
for (int i = 0; i < 100; i++) {
// 随机端口号
int index = new Random().nextInt(ports.length);
service.submit(new Task(data, ports[index]));
}
service.shutdown();
}
}

class Task implements Runnable {
private Data data;
private String port;

public Task(Data data, String port) {
this.data = data;
this.port = port;
}

public void run() {
try {
data.log(port);
} catch (Exception e) {
e.printStackTrace();
}
}
}

class Data {
private Logger log;
//<端口号,Appender>,保存已经使用过的端口号
private Map<String, Appender> appenderMap;
private static final String FILE_HEAD = "F:/test/";
private static final String FILE_TAIL = "_debug.log";
private static final String PATTERN = "%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n";

public Data(Logger log, Map<String, Appender> appenderMap) {
this.log = log;
this.appenderMap = appenderMap;
}

/**
 * 每次打印的rootlogger;里面只有一个appender
 * 
 * @param port
 * @throws FileNotFoundException
 */
public synchronized void log(String port) throws FileNotFoundException {
RollingFileAppender rfa = null;
// 不存在新建,已存在取出
if (appenderMap.containsKey(port)) {
rfa = (RollingFileAppender) appenderMap.get(port);
} else {
rfa = new RollingFileAppender();
rfa.setName(port);
rfa.setLayout(new PatternLayout(PATTERN));
rfa.setWriter(new PrintWriter(
new File(FILE_HEAD + port + FILE_TAIL)));
appenderMap.put(port, rfa);
}
log.addAppender(rfa);
log.debug("appender:" + rfa.getName() + " port:" + port);
// 删除
log.removeAppender(port);
}
}


看看对你有用没 多线程,如何根据线程端口来命名log4j日志文件的输出路径

#9


看见这段代码,感觉还不如不用log4j了,直接用FileWriter 往文件里写 得每次获取文件名字就行了,呵呵,谢谢你了! 我感觉这是log4j的漏洞,从网上查了不少,就是没有简便方法实现log4j日志路径的动态配置,漏洞啊漏洞!   恭祝十八大胜利召开!

#1


没人回复啊..... 自己往上顶吧,别帖子让沉底了

#2



package log4j;

import java.util.Enumeration;
import java.util.Random;

import org.apache.log4j.Logger;
import org.apache.log4j.RollingFileAppender;

/**
 * 
 * @author Administrator 我的客户端程序是监听服务器端的 n个端口,服务器端的端口同时往外发数据。
 *         现在我用log4j日志文件来输出数据,用的是log4j.xml配置文件。
 *         但是我想根据端口号,来设置输出路径,我想实现把日志文件写成下面两种情况的一种就行: 1. .../<端口号>_debug.log 2:
 *         .../端口号/debug.log
 */
public class ManyLog {
private static final String FILE_HEAD = "F:/test/_";
private static final String FILE_TAIL = "debug.log";
private static final int BUFFER_SIZE = 8192;

public static void main(String[] args) throws Exception {
Logger log = Logger.getRootLogger();
// 端口号
String[] ports = new String[] { "111", "222", "333", "444", "555",
"666", "777", "888", "999" };
// 这里我log4j.properties只配置了一个Appender
RollingFileAppender rfa = getAppender(log);
for (int i = 0; i < 20; i++) {
// 随机端口号
int index = new Random().nextInt(ports.length);
rfa.setFile(FILE_HEAD + ports[index] + FILE_TAIL, true, false,
BUFFER_SIZE);
// ports[index]端口是否打印相应的文件中
log.debug(ports[index] + " : afdasfadsfdas");
}
}

private static RollingFileAppender getAppender(Logger log) {
Enumeration en = log.getAllAppenders();
return (RollingFileAppender) en.nextElement();
}
}




log4j.rootLogger=DEBUG,R
log4j.appender.R=org.apache.log4j.RollingFileAppender
#log4j.appender.R.File=F:/test/log.txt
log4j.appender.R.MaxFileSize=5000KB
log4j.appender.R.Encoding=UTF-8
log4j.appender.R.MaxBackupIndex=100
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n


希望对你有用 多线程,如何根据线程端口来命名log4j日志文件的输出路径

#3


谢谢了,我的配置文件是log4j.xml,不知道能不能用? 我先试一试吧。
 这个帖子先不结,先放着,过一段时间再结。看看能不能有更好的方法。

#4


你这个是用在单线程中的,我的是多线程,不知道能不能用

#5


引用 2 楼 faping_cao 的回复:
Java code?



1234567891011121314151617181920212223242526272829303132333435363738394041424344

package log4j;   import java.util.Enumeration; import java.util.Random;   import org.apache.log4j.L……

今早上刚刚试了试,这个方法在多线程下,貌似不大行啊,日志还是有混乱啊,有什么好的解决办法吗?

#6


<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">

  <appender name="intffile" class="org.apache.log4j.DailyRollingFileAppender">
      <param name="File" value="D:/log/logic_intf.log"/>
      <param name="Append" value="true"/>
      <param name="DatePattern" value="'.'yyyy-MM-dd"/>
      <param name="Threshold" value="debug"/> 
      <layout class="org.apache.log4j.PatternLayout">
         <!-- The default pattern: Date Priority [Category] Message\n -->
         <param name="ConversionPattern" value="%p|%-d{yyyy-MM-dd HH\:mm\:ss}%m%n"/>
      </layout>
   </appender>

   <root>
      <level  value= "debug"/> 
      <appender-ref ref="intffile"/>
   </root>

</log4j:configuration>
这样试试呢

#7


谢谢了,我们不用DailyRollingFileAppender,我们需要的不是一天产生一个日志文件,而是控制文件大小的,呵呵 ,  关键是我的需求是  只有两个 1.  .../<端口号>_debug.log     2: .../端口号/debug.log   ,主要是怎么处理多线程下的日志混乱问题。
其实 我也能直接File file = new File(“这里面可以根据端口号来设置文件名或路径”); 关键是这不是我想要的,我是想用log4j实现,要不用log4j干啥,你说是吧,呵呵。
元芳,你怎么看?

#8



/**
 * 
 * @author Administrator 我的客户端程序是监听服务器端的 n个端口,服务器端的端口同时往外发数据。
 *         现在我用log4j日志文件来输出数据,用的是log4j.xml配置文件。
 *         但是我想根据端口号,来设置输出路径,我想实现把日志文件写成下面两种情况的一种就行: 1. .../<端口号>_debug.log 2:
 *         .../端口号/debug.log
 * 
 * 多线程客户端,一个端口号对应一个线程
 */
public class ManyLogByThread {

public static void main(String[] args) throws Exception {
Logger log = Logger.getRootLogger();
log.setLevel(Level.DEBUG);
// <端口号,Appender>,保存已经使用过的端口号
Map<String, Appender> appenderMap = new HashMap<String, Appender>();
// 端口号
String[] ports = new String[] { "111", "222", "333", "444", "555",
"666", "777", "888", "999" };
// 线程管理
ExecutorService service = Executors.newCachedThreadPool();
// 共享数据
Data data = new Data(log, appenderMap);
for (int i = 0; i < 100; i++) {
// 随机端口号
int index = new Random().nextInt(ports.length);
service.submit(new Task(data, ports[index]));
}
service.shutdown();
}
}

class Task implements Runnable {
private Data data;
private String port;

public Task(Data data, String port) {
this.data = data;
this.port = port;
}

public void run() {
try {
data.log(port);
} catch (Exception e) {
e.printStackTrace();
}
}
}

class Data {
private Logger log;
//<端口号,Appender>,保存已经使用过的端口号
private Map<String, Appender> appenderMap;
private static final String FILE_HEAD = "F:/test/";
private static final String FILE_TAIL = "_debug.log";
private static final String PATTERN = "%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n";

public Data(Logger log, Map<String, Appender> appenderMap) {
this.log = log;
this.appenderMap = appenderMap;
}

/**
 * 每次打印的rootlogger;里面只有一个appender
 * 
 * @param port
 * @throws FileNotFoundException
 */
public synchronized void log(String port) throws FileNotFoundException {
RollingFileAppender rfa = null;
// 不存在新建,已存在取出
if (appenderMap.containsKey(port)) {
rfa = (RollingFileAppender) appenderMap.get(port);
} else {
rfa = new RollingFileAppender();
rfa.setName(port);
rfa.setLayout(new PatternLayout(PATTERN));
rfa.setWriter(new PrintWriter(
new File(FILE_HEAD + port + FILE_TAIL)));
appenderMap.put(port, rfa);
}
log.addAppender(rfa);
log.debug("appender:" + rfa.getName() + " port:" + port);
// 删除
log.removeAppender(port);
}
}


看看对你有用没 多线程,如何根据线程端口来命名log4j日志文件的输出路径

#9


看见这段代码,感觉还不如不用log4j了,直接用FileWriter 往文件里写 得每次获取文件名字就行了,呵呵,谢谢你了! 我感觉这是log4j的漏洞,从网上查了不少,就是没有简便方法实现log4j日志路径的动态配置,漏洞啊漏洞!   恭祝十八大胜利召开!