Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在运行时更新log4j2模式_Java_Logging_Log4j_Log4j2 - Fatal编程技术网

Java 在运行时更新log4j2模式

Java 在运行时更新log4j2模式,java,logging,log4j,log4j2,Java,Logging,Log4j,Log4j2,我已经找了很长时间,所以在标记为副本之前一定要先阅读 我有一个函数(Lambda.handle()),它是用参数id调用的。我想将该id作为前缀添加到每个日志消息中。每次调用函数时,它都会更改。因此,我想更新记录器模式,将此id添加为前缀 我读过: SO和log4j论坛上的许多帖子都在谈论如何在运行时更改配置。它们要么已经过时,要么根本不起作用 以下代码基于log4j2文档。它打印: INIT MyLogger handle() - id ONE INIT MyLogger han

我已经找了很长时间,所以在标记为副本之前一定要先阅读

我有一个函数(
Lambda.handle()
),它是用参数
id
调用的。我想将该id作为前缀添加到每个日志消息中。每次调用函数时,它都会更改。因此,我想更新记录器模式,将此id添加为前缀

我读过:

  • SO和log4j论坛上的许多帖子都在谈论如何在运行时更改配置。它们要么已经过时,要么根本不起作用
以下代码基于log4j2文档。它打印:

INIT  MyLogger handle() - id ONE 
INIT  MyLogger handle() - id TWO 
INIT  MyLogger handle() - id THR 
如果我注释掉第行
initLoggerConfig(“INIT”)然后打印:

ERROR StatusLogger No Log4j 2 configuration file found. Using default configuration (logging only errors to the console), or user programmatically provided configurations. Set system property 'log4j2.debug' to show Log4j 2 internal initialization logging. See https://logging.apache.org/log4j/2.x/manual/configuration.html for instructions on how to configure Log4j 2
ONE  MyLogger handle() - id ONE 
ONE  MyLogger handle() - id TWO 
ONE  MyLogger handle() - id THR 
我想把它打印出来:

ONE  MyLogger handle() - id ONE 
TWO  MyLogger handle() - id TWO 
THR  MyLogger handle() - id THR 
是否注释掉
ctxLocal=ctx,无效

我将log4j自己的日志记录级别设置为ALL(
builder.setStatusLevel(level.ALL);

这是密码

package foobar;

import java.util.Arrays;
import java.util.List;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.config.AppenderRef;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.Configurator;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
import org.apache.logging.log4j.core.layout.PatternLayout;

class Lambda {
  private static final String LOGGER_NAME = "MyLogger";
  private LoggerContext ctx;

  public Lambda() {
    initLoggerConfig("INIT ");
  }

  public void handle(String id) {
    updateLoggerConfig(id);
    Logger logger = LogManager.getLogger(LOGGER_NAME);
    logger.error("handle() - id {}", id);
  }

  private void updateLoggerConfig(String prefix) {
    final LoggerContext ctxLocal = (LoggerContext) LogManager.getContext(false);
    // ctxLocal = ctx;
    Configuration config = ctxLocal.getConfiguration();
    Layout<String> layout = PatternLayout.newBuilder().withPattern(prefix + " %c %m\n").withConfiguration(config)
        .build();
    Appender appender = ConsoleAppender.createDefaultAppenderForLayout(layout);
    appender.start();
    config.addAppender(appender);
    AppenderRef ref = AppenderRef.createAppenderRef("File", null, null);
    AppenderRef[] refs = new AppenderRef[] { ref };
    LoggerConfig loggerConfig = LoggerConfig.createLogger(false, Level.ALL, getClass().getName(), "true", refs, null,
        config, null);
    loggerConfig.addAppender(appender, null, null);
    config.addLogger(LOGGER_NAME, loggerConfig);
    ctxLocal.updateLoggers();
  }

  void initLoggerConfig(String prefix) {
    ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
    builder.setStatusLevel(Level.ERROR);
    builder.setConfigurationName("BuilderTest");
    builder.add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.NEUTRAL).addAttribute("level",
        Level.DEBUG));
    AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", "CONSOLE").addAttribute("target",
        ConsoleAppender.Target.SYSTEM_OUT);
    appenderBuilder.add(builder.newLayout("PatternLayout").addAttribute("pattern", prefix + " %c %m\n"));
    appenderBuilder.add(
        builder.newFilter("MarkerFilter", Filter.Result.DENY, Filter.Result.NEUTRAL).addAttribute("marker", "FLOW"));
    builder.add(appenderBuilder);
    builder.add(builder.newLogger(LOGGER_NAME, Level.ALL).add(builder.newAppenderRef("Stdout"))
        .addAttribute("additivity", false));
    builder.add(builder.newRootLogger(Level.ERROR).add(builder.newAppenderRef("Stdout")));
    ctx = Configurator.initialize(builder.build());
  }
}

public class TestMain {
  static Lambda lamb = new Lambda();
  private static Logger logger = LogManager.getLogger();

  public static void main(String[] args) {
    Configurator.setLevel(logger.getName(), Level.ALL);
    List<String> a = Arrays.asList("ONE ", "TWO ", "THR ");
    for (String i : a) {
      lamb.handle(i);
    }

  }
}
packagefoobar;
导入java.util.array;
导入java.util.List;
导入org.apache.logging.log4j.Level;
导入org.apache.logging.log4j.LogManager;
导入org.apache.logging.log4j.Logger;
导入org.apache.logging.log4j.core.Appender;
导入org.apache.logging.log4j.core.Filter;
导入org.apache.logging.log4j.core.Layout;
导入org.apache.logging.log4j.core.LoggerContext;
导入org.apache.logging.log4j.core.appender.ConsoleAppender;
导入org.apache.logging.log4j.core.config.AppenderRef;
导入org.apache.logging.log4j.core.config.Configuration;
导入org.apache.logging.log4j.core.config.Configurator;
导入org.apache.logging.log4j.core.config.LoggerConfig;
导入org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder;
导入org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
导入org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
导入org.apache.logging.log4j.core.config.builder.impl.BuilConfiguration;
导入org.apache.logging.log4j.core.layout.PatternLayout;
Lambda类{
私有静态最终字符串记录器\u NAME=“MyLogger”;
私人LoggerContext ctx;
公共Lambda(){
initLoggerConfig(“INIT”);
}
公共无效句柄(字符串id){
UpdateLogger配置(id);
Logger Logger=LogManager.getLogger(Logger\u名称);
错误(“handle()-id{}”,id);
}
私有void updateLogger配置(字符串前缀){
final LoggerContext ctxLocal=(LoggerContext)LogManager.getContext(false);
//ctxLocal=ctx;
Configuration config=ctxLocal.getConfiguration();
Layout Layout=PatternLayout.newBuilder().withPattern(前缀+%c%m\n”).withConfiguration(配置)
.build();
Appender Appender=ConsoleAppender.createDefaultAppenderForLayout(布局);
appender.start();
config.addAppender(appender);
AppenderRef=AppenderRef.createAppenderRef(“文件”,null,null);
AppenderRef[]refs=新的AppenderRef[]{ref};
LoggerConfig LoggerConfig=LoggerConfig.createLogger(false,Level.ALL,getClass().getName(),“true”,refs,null,
配置,空);
loggerConfig.addAppender(appender,null,null);
config.addLogger(LOGGER_名称,loggerConfig);
ctxLocal.updateLogger();
}
void initLoggerConfig(字符串前缀){
ConfigurationBuilder=ConfigurationBuilderFactory.newConfigurationBuilder();
builder.setStatusLevel(Level.ERROR);
builder.setConfigurationName(“BuilderTest”);
add(builder.newFilter(“ThresholdFilter”、Filter.Result.ACCEPT、Filter.Result.NEUTRAL”).addAttribute(“level”,
级别(调试);
AppenderComponentBuilder appenderBuilder=builder.newAppender(“标准输出”、“控制台”).addAttribute(“目标”,
ConsolePender.Target.SYSTEM_OUT);
add(builder.newLayout(“patterlayout”).addAttribute(“pattern”,前缀+%c%m\n”);
appenderBuilder.add(
newFilter(“MarkerFilter”,Filter.Result.DENY,Filter.Result.NEUTRAL).addAttribute(“marker”,“FLOW”);
builder.add(appenderBuilder);
add(builder.newLogger(LOGGER_NAME,Level.ALL).add(builder.newAppenderRef(“Stdout”))
.addAttribute(“可加性”,false));
add(builder.newRootLogger(Level.ERROR).add(builder.newAppenderRef(“Stdout”));
ctx=Configurator.initialize(builder.build());
}
}
公共类TestMain{
静态Lambda lamb=新Lambda();
私有静态记录器Logger=LogManager.getLogger();
公共静态void main(字符串[]args){
setLevel(logger.getName(),Level.ALL);
列表a=Arrays.asList(“一”、“二”、“THR”);
用于(字符串i:a){
羊肉柄(一);
}
}
}

按照D.B.的建议使用查找。我就是这样修复的

在PatternLayout中添加对“变量”的引用,在下面的示例中,我将其命名为MyVarialbe(您需要使用与%X{}完全相同的语法:

appenderBuilder.add(builder.newLayout(“PatternLayout”) .addAttribute(“模式”,%X{MyVariable}%msg%n%throwable”);

在以后的代码中,您可以通过执行以下操作随时为其设置值:

org.apache.logging.log4j.ThreadContext.put(“MyVariable”,extraInfo);


以编程方式使用log4j2很复杂。因为我也有同样的困难,而且这篇文章已经发表了3个月了,希望这个答案对其他人有所帮助。

我不明白为什么你不能使用上下文映射。你能解释一下为什么这不起作用吗?@D.B.不知道!看起来这将是一个完美的解决方案。c见鬼。这是有道理的,log4j2确实有很多功能,所以很容易忽略其中的一些。希望您可以使用查找来查找您需要的内容,因为这比依赖log4j2实现细节要好得多。@D.B.是的。我使用的代码虽然来自官方文档,所以应该是公共界面。但它不是fri至少可以说是没完没了。