我的客户端程序是监听服务器端的 n个端口,服务器端的端口同时往外发数据。现在我用log4j日志文件来输出数据,用的是log4j.xml配置文件。但是我想根据端口号,来设置输出路径,我想实现把日志文件写成下面两种情况的一种就行:
1.  .../<端口号>_debug.log     2: .../端口号/debug.log求高手告诉我怎么弄?
我的log4j.xml中 <param name="File" value="${dir}/debug.log" /> ,
我用过System.setProperty("dir", ...+this.getPort()); 但是这样的话日志都混乱了,真心不知道怎么办了,都弄了好几天了.  上面两种情况弄出来一种就行! 

解决方案 »

  1.   


    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
    希望对你有用
      

  2.   

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

  3.   

    <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>这样试试呢
      

  4.   

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

  5.   


    /**
     * 
     * @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);
    }
    }
    看看对你有用没
      

  6.   

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