假设我有一个包含 20 个类的程序,每个类都有private static Logger logger = LoggerFactory.getLogger(SomeClass.class);. 这 20 个类将记录警告、信息、调试或错误。
在其中一个类中,我如何才能访问迄今为止在程序中记录的所有错误(跨所有类)?注意我对将所有这些转储到 a 不感兴趣.log,我想从 Java 程序中访问它们。
在我的 Java 应用程序中,Logback 用作日志记录框架。使用以下模式配置的附加程序(简化):
[CORR=%X{CORR}] [MSG=%msg]%n
Run Code Online (Sandbox Code Playgroud)
正如人们所见,CORR值取自MDC。日志条目示例:
[CORR=12342314] [MSG=Some message]
Run Code Online (Sandbox Code Playgroud)
在某些情况下,属性未存储在 中MDC,因此日志条目如下所示:
[CORR=] [MSG=Some message]
Run Code Online (Sandbox Code Playgroud)
但应该是:
[MSG=Some message]
Run Code Online (Sandbox Code Playgroud)
[CORR=]如果在MDC不创建自定义LayoutBase实现的情况下不存在相应的值,有没有办法完全摆脱模式的这一部分?我正在尝试配置评估器:
<evaluator name="DISPLAY_CORR_EVAL">
<expression>((String) mdc.get("CORR")) != null</expression>
</evaluator>
Run Code Online (Sandbox Code Playgroud)
但不知道如何在我的情况下使用它。
我想将不同的日志级别记录到不同的文件中,除此之外,我还希望每个日志级别都具有默认的consoleAppender。
因此输出应为不同的日志级别文件:
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<charset>UTF-8</charset>
<pattern>%d{HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{35}) - %msg %n</pattern>
</encoder>
</appender>
<!-- Logging settings for the info logs -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
</filter>
<file>logs\logFile.html</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>logs\logFile.%d{yyyy-MM-dd}.%i.html</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- or whenever the file size reaches 50MB -->
<maxFileSize>5MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- keep 60 days' worth of history -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<charset>UTF-8</charset> …Run Code Online (Sandbox Code Playgroud) 我正在尝试将日志从基本的 java maven 项目发送到远程计算机上配置的 Fluent-bit。Fluent-bit 然后会将它们写入文件。这是我的基本java配置。
爪哇
private final static Logger logger = LoggerFactory.getLogger(App.class);
public static void main(String[] args) {
for (int i = 0; ; i++) {
logger.debug("Warn msg");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// do nothing now
}
}
}
Run Code Online (Sandbox Code Playgroud)
和 logback.xml
<appender name="fluentd" class="ch.qos.logback.more.appenders.DataFluentAppender">
<remoteHost>xx.xxx.xxx.xxx</remoteHost>
<port>7777</port>
<encoder>
<pattern>%message%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="fluentd" />
</root>
Run Code Online (Sandbox Code Playgroud)
Fluent位配置:
td-agent-bit.conf
[INPUT]
Name tcp
Listen xx.xxx.xxx.xxx
Port 7777
Parsers_File /etc/td-agent-bit/parsers.conf
Parser custom_parser
[OUTPUT]
Name file
Match * …Run Code Online (Sandbox Code Playgroud) 我遇到了一个我想了解的奇怪问题。如果有人有一个很好的解决方案,但我实际上正在寻找一种理解为什么会发生这种情况:
我写了一个自定义的 Logback 布局。我正在扩展ch.qos.logback.contrib.json.classic.JsonLayout和覆盖addCustomDataToJsonMap. 如果在日志事件参数列表中找到某种类型的参数,我想添加其他属性:
protected void addCustomDataToJsonMap(Map<String, Object> map, ILoggingEvent event) {
if (event.getArgumentArray() == null) {
return;
}
for (Object argument : event.getArgumentArray()) {
System.out.println(argument.getClass().getClassLoader()); // 1
System.out.println(JsonAttribute.class.getClassLoader()); // 2
Run Code Online (Sandbox Code Playgroud)
但是参数列表 (1) 中对象的类和静态引用一 (2) 的类由不同的类加载器加载,如输出所示:
org.springframework.boot.devtools.restart.classloader.RestartClassLoader@618157b2
sun.misc.Launcher$AppClassLoader@18b4aac2
Run Code Online (Sandbox Code Playgroud)
因此,我无法将对象强制转换为不需要的类型并访问其方法。我想到的解决方法是通过 Reflecion 访问那些,但我宁愿使用真正的价值。
我想这只是我的开发环境的问题,但正如第一部分所说,我真的很想了解发生了什么。
编辑:
正如预期的那样:在没有 spring 开发工具的“生产”模式下运行应用程序时,所有类都由同一个类加载器加载。
附录:
此函数的堆栈跟踪:
at xxx.ExtendableJsonLayout.addCustomDataToJsonMap(ExtendableJsonLayout.java:26)
at ch.qos.logback.contrib.json.classic.JsonLayout.toJsonMap(Unknown Source)
at ch.qos.logback.contrib.json.classic.JsonLayout.toJsonMap(Unknown Source)
at ch.qos.logback.contrib.json.JsonLayoutBase.doLayout(Unknown Source)
at ch.qos.logback.core.encoder.LayoutWrappingEncoder.encode(LayoutWrappingEncoder.java:115)
at ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:230)
at ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:102)
at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:84)
at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:270)
at ch.qos.logback.classic.Logger.callAppenders(Logger.java:257)
at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:421) …Run Code Online (Sandbox Code Playgroud) 我想格式化结构化日志中的时间戳。目前我定义logback.xml如下:
<configuration>
<appender name="json" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<fieldNames>
<timestamp>timestamp</timestamp>
<logger>[ignore]</logger>
<version>[ignore]</version>
<levelValue>[ignore]</levelValue>
<stackTrace>exception</stackTrace>
</fieldNames>
</encoder>
</appender>
<root name="jsonLogger" level="DEBUG">
<appender-ref ref="json"/>
</root>
</configuration>
Run Code Online (Sandbox Code Playgroud)
使用<fieldNames>我可以更改时间戳字段的名称。
如何通过配置更改时间戳的模式logback.xml?
如何使用带有graylog的slf4j作为包装器?我们可以使用log4j和slf4j.我正在寻找一个好的graylog框架可以说任何我们可以使用graylog与slf4j?
java ×7
logback ×7
logging ×3
slf4j ×2
classloader ×1
fluent-bit ×1
photon-os ×1
spring-boot ×1