log4j 将javax.net.debug捕获到文件

rqqzpn5f  于 2022-11-06  发布在  Java
关注(0)|答案(4)|浏览(122)

我需要将创建的javax .NET.debug=all输出保存到一个文件中。我正在使用log4j,并尝试创建一个日志代理,如下面的代码示例所示;但是,它没有获取信息。我不确定javax .NET.debug被打印到哪里。我尝试过用这种方法捕获system.out和system.err,但是都不起作用。谢谢你的帮助。

public class StdOutErrLog {

    private static final Logger logger = Logger.getLogger(StdOutErrLog.class);

    public static void tieSystemOutAndErrToLog() {
        System.setOut(createLoggingProxy(System.out));
        System.setErr(createLoggingProxy(System.err));
    }

    public static PrintStream createLoggingProxy(final PrintStream realPrintStream) {
        return new PrintStream(realPrintStream) {
            public void print(final String string) {
                realPrintStream.print(string);
                logger.info(string);
            }
        };
    }
}
kupeojn6

kupeojn61#

也许子系统复制了这些值,而你在切换时已经太晚了。试着先在你的主系统中这样做。
编辑
好吧-我完全错过了你的习惯用法。我认为你不应该使用这个内部类。你应该在OutputStream上定义一个PrintStream示例,在每个“\n”时创建一个新的日志条目。你现在这样做的方式错过了很多“打印”你的示例的可能性。

package de.mit.stackoverflow;

import java.io.IOException;
import java.io.OutputStream;

public class LogOutputStream extends OutputStream {

    private StringBuilder sb = new StringBuilder();

    @Override
    public void write(int b) throws IOException {
        if (b == '\n') {
            log(sb.toString());
            sb.setLength(0);
        } else {
            sb.append((char) b);
        }
    }

}

然后做了

OutputStream os = new LogOutputStream();
    PrintStream ps = new PrintStream(os);
    System.setOut(ps);

您可能还想包括对前一个流的引用-作为exercise:-)

2o7dmzc5

2o7dmzc52#

这是一个很长的尝试,但有可能仅仅覆盖print(String)是不够的。例如,还有print(Object)等,更不用说各种append()format()方法了。

iyzzxitl

iyzzxitl3#

我在运行jdk 8的Tomcat 9应用程序中遇到了这个问题(源代码兼容级别为1.7,配置了LOG4J和Tomcat JULI日志记录),所以我的解决方案就是基于这个问题的,但是这个技巧是通用的:
始终检查文档并调查代码源。
通过一些特定的关键字从ssl跟踪日志中搜索,我发现系统属性“javax .NET.debug”在SSLLogger.java(较新的jdk,即11)和Debug.java(较旧的jdk,即7)中使用。我很幸运地首先找到了jdk 11的源代码,所以我在那里找到了描述性的注解(而较旧的没有):
如果系统属性“javax.net.debug”未定义,则调试日志记录将关闭。如果系统属性“javax.net.debug”定义为空,则调试记录器由System.getLogger指定(“javax .NET.ssl”),应用程序可以自定义和配置日志记录器或使用外部日志记录机制。如果系统属性“javax .NET.debug”已定义且为非空,使用在该类中实现的私有调试记录器。
我在Tomcat服务器中添加了“-Djavax .NET.debug”VM参数,SSL跟踪日志输出略有变化(变得不那么冗长)。
为了控制这个包记录器将输出什么,我修改了Tomcat server logging.properties

  • 添加新的日志记录处理程序(5是序列号,即我以前有4个日志记录处理程序):

5ssl.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
5ssl.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
5ssl.org.apache.juli.FileHandler.prefix = ssl.
5ssl.org.apache.juli.FileHandler.maxDays = 2

  • 将此处理程序添加到处理程序属性:

handlers = 1catalina.org.apache.juli.FileHandler, 2localhost.org.apache.juli.FileHandler, 3manager.org.apache.juli.FileHandler, 4host-manager.org.apache.juli.FileHandler, 5ssl.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler

  • 最后,覆盖SSL默认记录器:

javax.net.ssl.level = FINEST
javax.net.ssl.handlers = 5ssl.org.apache.juli.FileHandler
现在,我的自定义记录器(几乎)与调试级别为“all”的本机SSLLogger的工作方式类似。

重要区别在于缺少更详细消息,如'ssl,trustmanager'或'ssl,plaintext'

本机记录器输出:

javax.net.ssl|FINE|47|http-nio-8081-exec-5|2022-06-28 17:05:43.051 EEST|SSLSocketInputRecord.java:474|Raw read (
  0000: 6B 38 AA 29 C2 5B 2B 22   AD 2B 23 3B A9 EA A8 EA  k8.).[+".+#;....
  0010: E0 BF 64 4A 0E B3 5E 5C   63 2A 63 EC 85 82 40 DA  ..dJ..^\c*c...@.
  0020: 4B 9B 73 BE 49 AE 1C 14   D6 E6 C2 9A 06 96 18 21  K.s.I..........!

自定义记录器输出:

28-Jun-2022 16:26:09.508 FINE [http-nio-8081-exec-5] sun.security.ssl.SSLLogger.log READ: TLSv1.2 handshake, length = 5712
28-Jun-2022 16:26:09.508 FINE [http-nio-8081-exec-5] sun.security.ssl.SSLLogger.log Raw read
28-Jun-2022 16:26:09.508 FINE [http-nio-8081-exec-5] sun.security.ssl.SSLLogger.log Raw read
28-Jun-2022 16:26:09.509 FINE [http-nio-8081-exec-5] sun.security.ssl.SSLLogger.log Raw read
28-Jun-2022 16:26:09.509 FINE [http-nio-8081-exec-5] sun.security.ssl.SSLLogger.log Raw read
28-Jun-2022 16:26:09.510 FINE [http-nio-8081-exec-5] sun.security.ssl.SSLLogger.log Raw read
28-Jun-2022 16:26:09.523 FINE [http-nio-8081-exec-5] sun.security.ssl.SSLLogger.log Raw read
28-Jun-2022 16:26:09.524 FINE [http-nio-8081-exec-5] sun.security.ssl.SSLLogger.log Raw read
28-Jun-2022 16:26:09.524 FINE [http-nio-8081-exec-5] sun.security.ssl.SSLLogger.log READ: TLSv1.2 handshake, length = 5712

在检查本机日志记录器中标记的几个文件的源文件(即SSLSocketInputRecord.javaX509TrustManagerImpl.java)后,我注意到日志记录器帮助中提到的特定日志记录属性(纯文本、记录等)有额外的检查,检查如下:

if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) {
            SSLLogger.fine("adding as trusted certificates",
                    (Object[])trustedCerts.toArray(new X509Certificate[0]));
        }

而且,当使用自定义记录器时,SSLLogger.isOn为true,未定义本机日志记录属性,这意味着配置自定义记录器后,SSLLogger将不会输出特定的详细消息...
另外,我无法将log4j用作SSLLogger的自定义日志记录器(我想,要做到这一点,我需要将Tomcat配置为使用log4j,而不是java.util.logging,用于所有Tomcat的内部日志记录,如docs中所述)。

gwbalxhn

gwbalxhn4#

您需要log4j.properties在类路径(/WEB-INF/classes/)中包含www.example.com文件,并且该文件包含以下内容:
文件log4j.properties

datestamp=yyyy-MM-dd/HH:mm:ss.SSS/zzz
roll.pattern.hourly=.MM-dd-yyyy.HH
roll.pattern.daily=.MM-dd-yyyy

log4j.rootLogger=INFO, Console
log4j.logger=INFO, Console

log4j.appender.Console=org.apache.log4j.DailyRollingFileAppender
log4j.appender.Console.DatePattern=${roll.pattern.daily}
log4j.appender.Console.file=${catalina.home}/logs/Console.log
log4j.appender.Console.MaxFileSize=800KB
log4j.appender.Console.MaxBackupIndex=5
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d{${datestamp}} [%t] %-5p %m%n

log4j.appender.custom=org.apache.log4j.DailyRollingFileAppender
log4j.appender.custom.DatePattern=${roll.pattern.daily}
log4j.appender.custom.File=${catalina.home}/logs/custom.log
log4j.appender.custom.MaxFileSize=800KB
log4j.appender.custom.MaxBackupIndex=5
log4j.appender.custom.layout=org.apache.log4j.PatternLayout
log4j.appender.custom.layout.ConversionPattern=%d{${datestamp}} [%t] %-5p %m%n

log4j.logger.net.javax=DEBUG, custom

这会将日志条目写入tomcat主目录/logs/custom. log
希望这对你有帮助。

相关问题