当前位置: 首页 > 知识库问答 >
问题:

如何使用SL4J将变量包装到Log4j2上

暨弘懿
2023-03-14

目前,我的应用程序需要一些应该附加到日志消息中的值。由于它在SL4J下使用Log4J2,我的第一个想法是对Log4J记录器进行包装,在那里我可以向输出中添加新值。

一些博客指出我应该写一个日志,一个LoggerFactory和一个活页夹。但它们已经相当过时(2011年),并且不希望这些代码与当前的lib一起工作。

我还看到了一些关于线程上下文的东西,看起来像我想要构建这个测试。

所以我的问题是什么是最实用(简单)的方法来扩展日志机制,并在日志消息的开头有一些变量,我可以通过这个包装器从ThreadContext中放入/或恢复。

logger.info("this is a message"); // Custom logger looks the same as usual

但在内部,它与一些ThreadContext一起工作以增加日志消息。

@Override
public void info(final String format) {
    // get some value from ThreadContext
    // add some value that not exist on ThreadContext
    // use it on format string
    // format = container_name + " - " + GUUID + " - " + format;
    logger.logIfEnabled(FQCN, Level.INFO, null, format);
}

密码

package hello;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.stereotype.*;
import org.springframework.web.bind.annotation.*;

@Controller
@EnableAutoConfiguration
public class SampleController {

    final static Logger logger = LoggerFactory.getLogger(SampleController.class);

    @RequestMapping("/")
    @ResponseBody
    String home() {
        logger.info("this is a message");
        return "Hello World!";
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(SampleController.class, args);
    }

}

输出

17:22:13.718 [http-nio-8080-exec-1] INFO  hello.SampleController - this is a message

期望的产出

17:22:13.718 [http-nio-8080-exec-1] INFO  hello.SampleController - CONTAINERXPTO - 0284-8576-9376-8376 - this is a message

参考资料

http://poth-chola.blogspot.com.br/2015/08/custom-slf4j-logger-adapter.htmlhttp://binkley.blogspot.com.br/2010/12/correct-slf4j-logger-wrapping.htmlhttp://javaeenotes.blogspot.com.br/2011/12/custom-slf4j-logger-adapter.html

共有1个答案

谢正初
2023-03-14

下面的博文

http://veerasundar.com/blog/2009/11/log4j-mdc-mapped-diagnostic-context-example-code/

描述一种透明地向日志记录调用添加额外的-请求相关-信息的解决方案。

编辑:

简言之,您需要在web应用程序中添加一个servlet过滤器,用于根据每个请求提取所需信息。

在这个过滤器中,您可以将信息放入名为MDC(映射诊断上下文)/ThreadContext的threadlocal映射中。实现可能如下所示:

public class RequestInformationFilter implements Filter {

   @Override
   public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        try {
            MDC.put("variableName", "variableValue");

            chain.doFilter(request, response);

        } finally {
            MDC.remove("variableName");
        }

    }

}

之后,您可以在日志模式中使用%X{变量名称}来打印变量名称的值。

 类似资料:
  • 问题内容: 我想将几个变量连接成一个字符串变量,但无法使其正常工作。当我编译时,它说“不是声明”和“;预期”。 我的目的是连接“ a”和“ b”并将其分配给resW。 我的最终目标是像这样使用resW … 它应以“ 1 + 2”的格式保存到文件中。我不知道如何正确执行此操作,甚至无法做到。 问题答案: 试试这个..

  • 问题内容: [免责声明:可能会有更多pythonic方法来做我想做的事,但我想知道python的作用域在这里是如何工作的] 我试图找到一种方法来制作装饰器,该装饰器的作用类似于将名称注入另一个函数的作用域(以使名称不会泄漏到装饰器作用域之外)。例如,如果我有一个函数说要打印一个尚未定义的名为的变量,我想在调用它的装饰器中定义它。这是一个中断的示例: 我希望它打印“ ”,但它给出: 追溯甚至指向wh

  • 使用C 14,我试图扩展此实现,以支持将在外部调用的ObserverCallback方法。 MyClass容器使用元组向量,其类型由可变模板指定。然后可以使用Access访问vector 我需要的是实现一个观察器,它应该向向量添加元素。由于元素的类型可以是元组中的任何类型,因此我也对其进行了模板化: 包装器类中似乎有错误: 作为参考,我还附上完整的源代码清单:

  • 问题内容: 我想根据用户选择的值导入一些软件包。 默认值为: 如果用户选择,则应为: 在PHP中,我可以使用变量variable来做到这一点: 如何在Python中执行此操作? 问题答案: Python没有与PHP的“变量变量”直接等效的功能。要获取“变量变量”的值(或任何其他表达式的值),可以使用该函数。 但是,这不能在语句中使用。 可以使用该函数通过变量导入。 相当于

  • 问题内容: 我试图将某些json字段映射到类实例变量。 我的示例 Person 类如下所示: 示例 地址 类为: 要反序列化到我的Person类的json对象不包含“地址”字段。看起来像: 有没有办法将json反序列化为Person pojo,其中Address字段也正确映射? 我已经使用了自定义地址反序列化器,如此处许多文章所述。但是,由于Json对象不包含“地址”字段,因此没有被调用。 我已经

  • 问题内容: 我正在尝试将JavaScript变量作为PHP变量包含在PHP代码中,但是这样做有问题。单击按钮时,将调用以下功能: 可能吗? 问题答案: PHP在服务器端运行。JavaScript在请求页面的用户的浏览器中在客户端运行。到执行JavaScript时,服务器上都无法访问PHP。请阅读本文,了解有关客户端和服务器端编码的详细信息。 简而言之,这是什么: 您在办公桌下方的计算机上的浏览器中