标签: mdc

在 JsonLayout 中添加 MDC 变量 - log4j2

如何在log4j2的JsonLayout生成的json日志中添加MDC变量。我已经使用 KeyValuePair 标记将主机名等属性添加到日志中,但我没有找到任何方法将 MDC 变量添加到其中。在模式布局中,我使用了 %X{traceId} 但我确定 JsonLayout 无法解析这些转换字符(据我所知,转换字符仅用于模式布局)。我进入了 JsonLayout 的源代码,但没有找到实际上将所有数据放入日志消息的函数。

谢谢你。

logging mdc log4j2 spring-boot

7
推荐指数
1
解决办法
6467
查看次数

在log4j中使用MDC动态命名日志文件

是否有可能在运行时使用MDC命名日志文件.

我有一个Web应用程序,使用tomcat docbase同时使用不同的名称调用.所以我需要为每个文件都有单独的日志文件.

java log4j mdc

6
推荐指数
3
解决办法
1万
查看次数

slf4j 始终使用 NOPMDCAdapter

我使用 slf4j 登录我的项目。我想使用 MDC 来记录用户 ID 参数。所以我检查教程和文档,并编写如下代码:

MDC.put("key", userId)
Run Code Online (Sandbox Code Playgroud)

userId实际上是一个字符串。

我使用常用​​的 log4j xml 和附加程序等属性。在那里添加 %X{key} 但没有任何反应。我根本没有看到任何东西可以代替 %X{key},但其他参数如 %-5p 或 %c 效果很好。

所以我使用 debug 来观察 MDC.put() 方法中发生的情况,并发现在 MDC 的初始化中使用了:

MDCAdapter mdcAdapter;
mdcAdapter = StaticMDCBinder.SINGLETON.getMDCA();
Run Code Online (Sandbox Code Playgroud)

IDEA 中的调试显示它具有“Log4jMDCAdapter”,类似于 MDCAdapter 的实现之一。但后来我查看 StaticMDCBinder,有如下代码:

public MDCAdapter getMDCA() {
   return new NOPMDCAdapter();
}
Run Code Online (Sandbox Code Playgroud)

那么 slf4j 如何使用适当的适配器(例如 log4j)初始化 MDC ???我没明白。因为它始终使用 NOPMDCAdapter,所以它无法在 MDC 中存储任何内容,也无法在日志记录中显示它。我该如何修复它?

在类路径中我有:

  • log4j-1.2.16.jar
  • slf4j-api-1.6.1.jar
  • slf4j-api-1.6.2.jar
  • slf4j-jcl-1.6.2.jar
  • slf4j-log4j12-1.6.2.jar

java log4j slf4j mdc

6
推荐指数
1
解决办法
2051
查看次数

默认log4j MDC值

有没有人知道如何使用log4j的config xml为MDC中的缺失条目指定默认值?我在我的XML文件中定义了一个appender,如下所示:

<appender name="DBAppender" class="org.apache.log4j.jdbc.JDBCAppender"> 
    <param name="URL" value="jdbc:sqlserver://phenom\\MSSQLSERVER_2012\;databaseName=pickmax_express" /> 
    <param name="Driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" /> 
    <param name="User" value="user" /> 
    <param name="Password" value="password" /> 
    <layout class="org.apache.log4j.PatternLayout"> 
        <param name="ConversionPattern" 
          value="INSERT INTO LOG (source, message, order_id, log_level) VALUES ( 'TESTSOURCE','%m', %X{orderID}, 0)" 
        /> 
    </layout> 
</appender> 
Run Code Online (Sandbox Code Playgroud)

有问题的部分是来自MDC的订单ID(%X {orderID}).我四处搜索,只发现同一个线程的副本说了一些类似于$$ {orderID:-DefaultValue}的内容,但这在这个上下文中不起作用.我需要能够在没有订单ID的上下文中收到日志消息时将值默认为0或-1或其他一些sentinal值

java log4j mdc

6
推荐指数
1
解决办法
1667
查看次数

如何使用 MDC 在 log4j2 中动态创建日志文件名

我正在尝试根据通过MDCin log4j传递的值生成不同的日志文件。尝试了几种方法后,我无法正常工作。

这就是我要怎么做。

在 java 代码中。我在MDC.

public static void addHeadersToMDC(Map<String, String> headers) {
       //headers contains other http headers such as uid,appid, client-type etc.

 if (headers != null) {
            Map<String, String> clonedHeaders =
                    new HashMap<String, String>(headers);
            LogMasker.getInstance().maskHeaders(clonedHeaders);
            clonedHeaders.put("APPNAME", "special");//setting APPNAME to MDC here.
            for (String header : clonedHeaders.keySet()) {
                ThreadContext.put(header, clonedHeaders.get(header))   
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

在 log4j2.xml 中,我试图通过执行 <

Routing name="Routing">
             <Routes pattern="$${ctx:ROUTINGKEY}">
                <Route key="async-perf">
                     <RollingFile name="Rolling-Async-Perf" fileName="/usr/local/logs/${ctx:APPNAME}.log"
            filePattern="./logs/${date:yyyy-MM}/perf-%d{yyyy-MM-dd}-%i.log.gz"  immediateFlush="false">
            <PatternLayout charset="UTF-8">
                <pattern>%d LogLevel=%p my_appid=%X{appid} uid=%X{uid} class=%c %m%n</pattern><!-- …
Run Code Online (Sandbox Code Playgroud)

java logging log4j mdc log4j2

6
推荐指数
1
解决办法
3187
查看次数

从MDC清除requestId的位置

我想要一个添加requestId到我的web应用程序的日志,如图所示这里.

public class MDCFilter implements ContainerRequestFilter, ContainerResponseFilter
{
    private static final String CLIENT_ID = "client-id";

    @Context
    protected HttpServletRequest r;

    @Override
    public void filter(ContainerRequestContext req) throws IOException
    {
        Optional<String> clientId = Optional.fromNullable(r.getHeader("X-Forwarded-For"));
        MDC.put(CLIENT_ID, clientId.or(defaultClientId()));
    }

    @Override
    public void filter(ContainerRequestContext req, ContainerResponseContext resp) throws IOException
    {
        MDC.remove(CLIENT_ID);
    }

    private String defaultClientId()
    {
        return "Direct:" + r.getRemoteAddr();
    }
}
Run Code Online (Sandbox Code Playgroud)

这样做的问题是,它设置和删除 requestIdMDC上述过滤器.我还记录了我的应用程序生成的响应的主体WriterInterceptor.问题是,因为拦截器在过滤器之后运行,所以当我WriterInterceptor执行时,没有requestId MDC.

我的问题是,是否可以MDC.clear()在结束时打电话WriterInterceptor(感觉某种程度上是hacky),还是有更好的方法来实现这一目标?

java jax-rs filter interceptor mdc

6
推荐指数
1
解决办法
729
查看次数

带有 ThreadPools 或 Spring Async 的 Logback MDC

我试图确定MDC使用 Cacheable ThreadPools 或 Spring 的 Async 注释时线程安全的程度。

我有一个方法可以调用多个CompletableFuture<>并使用线程池执行它们

@Async
public CompletableFuture<List> someMethod(String request) {
    try {
        MDC.put("request", request)
        MDC.put("loggable1", "loggable1");
        MDC.put("loggable2", "loggable2");
        log.info("Log Event");
    } finally {
        MDC.clear();
    }
}
Run Code Online (Sandbox Code Playgroud)

Logback 的 MDCAdapter 相关部分

final ThreadLocal<Map<String, String>> copyOnThreadLocal = new ThreadLocal<Map<String, String>>();

public void put(String key, String val) throws IllegalArgumentException {
    if (key == null) {
        throw new IllegalArgumentException("key cannot be null");
    }

    Map<String, String> oldMap = copyOnThreadLocal.get();
    Integer lastOp = getAndSetLastOperation(WRITE_OPERATION);

    if (wasLastOpReadOrNull(lastOp) || …
Run Code Online (Sandbox Code Playgroud)

java logback mdc

6
推荐指数
1
解决办法
1879
查看次数

使用 @Async 和 TaskDecorator 记录 MDC

使用 Spring MVC,我有以下设置:

  1. 用于记录请求的 AbstractRequestLoggingFilter 派生过滤器。
  2. 一个 TaskDecorator,用于将 MDC 上下文映射从 Web 请求线程编组到 @Async 线程。

我正在尝试使用 MDC(或 ThreadLocal 对象)为处理请求所涉及的所有组件收集上下文信息。

我可以从@Async 线程正确检索 MDC 上下文信息。但是,如果@Async 线程要将上下文信息添加到 MDC,我现在如何将 MDC 上下文信息编组到处理响应的线程?

任务装饰器

public class MdcTaskDecorator implements TaskDecorator {
@Override
public Runnable decorate(Runnable runnable) {
    // Web thread context
    // Get the logging MDC context
    Map<String, String> contextMap = MDC.getCopyOfContextMap();

    return () -> {
        try {
            // @Async thread context
            // Restore the web thread MDC context
            if(contextMap != null) {
                MDC.setContextMap(contextMap);
            }
            else {
                MDC.clear(); …
Run Code Online (Sandbox Code Playgroud)

logging spring-mvc logback slf4j mdc

6
推荐指数
3
解决办法
7260
查看次数

如何在spring boot中使用logback和SLF4J的MDC来捕获POST请求json中的唯一跟踪?

我们正在使用:

  • 弹簧靴
  • Slf4J
  • 登录
  • ELK 栈

现在,我们要使用MDC将 POST 请求 JSON 中提供的唯一跟踪号添加到给定请求的每个日志语句中。

我在谷歌上搜索了一些博客文章,这些对我来说没什么用。

下面是logback.xml我们正在使用的

<configuration>
    <property name="PROJECT_ID" value="template-api"/>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
    </appender>

    <root level="INFO">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
Run Code Online (Sandbox Code Playgroud)

任何人都可以提供一些关于如何完成这项工作的帮助吗?

logging logback slf4j mdc spring-boot

6
推荐指数
2
解决办法
1万
查看次数

如何在 Java 和 logback 中将 MDC 与 parallelStream 一起使用

我需要记录请求的一些属性,比如请求 id 和语言环境,但是在使用 parallelStream 时,似乎 MDC 的 ThreadLocal 丢失了信息。

我分析了在创建parallelStream时在线程之间传递MDC上下文的解决方案,但它看起来很脏,我也有很多parallelStream的用法。

有没有其他方法可以做到这一点?

谢谢

java logging multithreading logback mdc

6
推荐指数
1
解决办法
1511
查看次数