标签: mdc

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

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

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

java log4j mdc

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

Logback MDC put()可变对象

我正在使用Vaadin框架,它对截取事件的支持很少,我不知道会话或UI何时被激活,所以我不能将它们的ID放在MDC中.

通常我会:

public void onSessionBegin(){
    MDC.put("session", VaadinSession.getCurrent().toString()); //<-- String is immutable
}
public void onSessionEnd(){
    MDC.remove("session");
}
Run Code Online (Sandbox Code Playgroud)

但我没有这样的事件,所以我想:

// in the servlet init or wherever
MDC.put("session", new Object(){
        public String toString() {
            VaadinSession.getCurrent().toString()
        };
    }); //<-- This is mutable and will be evaluated each time
Run Code Online (Sandbox Code Playgroud)

这样,无论多少时间都会改变会话,在日志中我会得到当前的一个.

这可能吗?如何使用自定义MDC实现替换logback MDC实现?我应该编辑slf4j和logback的来源吗?

java logback slf4j mdc vaadin

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

Scala Akka使用SLF4J MDC进行记录

我正在配置我的Akka应用程序以使用此处指定的SLF4J记录器:

http://doc.akka.io/docs/akka/2.3.4/scala/logging.html

在引擎盖下,我依靠Logback进行日志记录.我正在开发一个用于日志记录目的的通用模块,用户可以在他们的actor系统中使用.主要是,我正在创造一个他们可以混合的特质.

我有一个特点,这样做:

我有这样的东西:

trait ActorLogger {

    val log: DiagnosticLoggingAdapter = Logging(this);

}
Run Code Online (Sandbox Code Playgroud)

我有一些额外的逻辑,它将MDC值添加到DiagnosticLoggingAdapter的MDC.现在的问题是:如果用户想要混合到非演员类,我会完全暴露一个不同的记录器.所以我可能有这样的事情:

trait ClassLogger {

    val log = LoggerFactory getLogger getClass.getName
}
Run Code Online (Sandbox Code Playgroud)

我希望MDC值能够延续到此记录器.因此,例如,如果我将MDC值放入我的DiagnosticAdapterLogger,我应该能够从org.slf4j.MDC获取这些值

如何以干净的方式实现这一目标?

谢谢!

scala slf4j mdc akka

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

如何使用现代logback获取MDC"继承"?

回到一个较旧的项目并开始更新其依赖项之后,我必须意识到自从版本以来,logback不再将MDC传播给子项1.1.5:https://github.com/qos-ch/logback/commit/aa7d584ecdb1638bfc4c7223f4a5ff92d5ee6273

这种变化使得大多数日志几乎无用.

虽然我可以理解链接问题中给出的论点,但我无法理解为什么这种更改不能以更向后兼容的方式进行(如java中通常常见的那样).

:除了必须将所有内容从Runnables子类化为Threads之外,实现相同行为的现在正确的方法是什么?

logback slf4j mdc

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

登录Spring Controller建议期间如何使MDC可用?

我有一个spring-boot Web应用程序,该应用程序利用logback的MDC上下文来用自定义数据丰富日志。我具有以下实现方式,该实现方式可以使用一些与“ customKey”关联的自定义数据,并且在将%X {customKey}添加到logback配置中的日志记录模式后,它会被正确记录:

public class MDCFilter extends OncePerRequestFilter implements Ordered {

@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest,
        HttpServletResponse httpServletResponse,
        FilterChain filterChain) throws ServletException, IOException {
        try {

            MDC.put("customKey", "someValue");          

            filterChain.doFilter(httpServletRequest, httpServletResponse);
        } catch(Throwable t) {
            LOG.error("Uncaught exception occurred", t);
            throw t;
        } finally {
            MDC.remove("customKey");
        }
    }

    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE - 4;
    }
}
Run Code Online (Sandbox Code Playgroud)

只要没有抛出未捕获的异常,此方法就可以正常工作。为了解决这些问题,我准备了控制器建议。遗憾的是,MDC在登录控制器建议期间不再可用,因为它已被清理。如果我正确理解,spring将通过使用HandlerExceptionResolverComposite来确定负责的ExceptionHandler,该实现以最低的优先级进行注册,因此,它是在MDC已清理之后的最后一个。

我现在的困惑是:我应该如何注册我的过滤器,以便在登录控制器建议期间仍可以使用MDC?

我认为一个选择是从过滤器的finally块中删除MDC.remove(...)调用,而是实现一个ServletRequestListener,它在requestDestroyed-方法中清除MDC。但是由于该过滤器用于多个Web模块,所以我需要确保在每个现有的预期模块以及MDCFilter中也声明了ServletRequestListener,这对我来说似乎很容易出错。此外,如果负责将数据添加到MDC的过滤器还负责删除它,我希望使用它。

logback mdc spring-boot

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

如何通过gelf将MDC传输到graylog?

我们有一个日志记录流,其中我们的 java 应用程序填充 MDC,该 MDC 通过 log4j2 传输到 syslog 到中央 rsyslog 安装。在这里,我们广泛使用了 MDC。我们的设置是这样的:

   <Syslog name="syslog" format="RFC5424" host="localhost" port="514" protocol="UDP"
        appName="messaging_platform.${application}" mdcId="mdc" includeMDC="true" facility="LOCAL5" connectTimeoutMillis="100" ignoreExceptions="false">
    <LoggerFields>
        <KeyValuePair key="class" value="%c"/>
        <KeyValuePair key="classname" value="%c{1}"/>
        <KeyValuePair key="exception" value="%ex{full}"/>
        <KeyValuePair key="method" value="%method"/>
        <KeyValuePair key="line" value="%line"/>
        <KeyValuePair key="application_name" value="${application}"/>
        <KeyValuePair key="sequenceNumber" value="%sequenceNumber"/>
        <KeyValuePair key="application_version" value="${application.version}"/>
        <KeyValuePair key="marker" value="%marker"/>
        <KeyValuePair key="thread" value="%thread"/>
        <KeyValuePair key="system_nano_time" value="%nano"/>
        <KeyValuePair key="app_uptime" value="%relative"/>
    </LoggerFields>
</Syslog>
Run Code Online (Sandbox Code Playgroud)

我正在尝试将其转换为使用 graylog,似乎 GELF 是推荐的传输协议。我找到了多个库来做到这一点,并从GelfLayoutlog4j2 的内置开始。但那不支持LoggerFields

那么将这些字段放入 Graylog 的推荐方法是什么?如果我做

   <Socket name="Graylog" protocol="udp" host="localhost" …
Run Code Online (Sandbox Code Playgroud)

mdc graylog2 log4j2 gelf

5
推荐指数
1
解决办法
1863
查看次数

在处理开始时而不是在结束时调用 MDC.clear() 有什么缺点吗?

我喜欢在我的应用程序中使用 MDC 日志记录字段,因为它使查找所有相关日志行变得更加容易。我还发现在处理开始时清除 MDC 上下文要容易得多,因为我知道应用程序的入口点在哪里,但有许多可能的异常路径,我自己或其他开发人员可能忘记调用 MDC.clear( )。

所以我的问题是,我这样做有什么缺点吗?根据经验,始终在处理开始和结束时清除上下文。

为了清楚起见,如果我从头开始编写代码,我会这样做:

MDC.put();
try {
...
} finally {
  MDC.clear();
}
Run Code Online (Sandbox Code Playgroud)

但有时我必须使用基类或库中没有任何 MDC 相关代码的内容,因此我按照我所描述的方式进行操作,因为我不想从库中复制基类只是为了添加几行 MDC 代码...

java logging slf4j mdc

5
推荐指数
1
解决办法
8360
查看次数

Spring Boot 2 和带有反应器的 logback MDC

我有一个用 spring 5 和 reactor 编写的应用程序。我在订阅者上下文中放入了一些信息,例如用户 ID。现在我想记录这个用户 ID。我正在尝试使用 MDC 但如果请求更改线程我丢失了信息。我该如何解决这个问题?有没有办法设置 MDC,以便应用程序周围的所有日志,包括外部库,我使用订阅者上下文放入的数据?我已经尝试过这里描述的内容,但它工作正常,但它不能解决我的外部库日志问题。

https://simonbasle.github.io/2018/02/contextual-logging-with-reactor-context-and-mdc/

logback mdc spring-boot project-reactor

5
推荐指数
1
解决办法
1726
查看次数

如何编写集成测试来检查 MDC 上下文中的内容?

这是我用来向标头添加过滤器并添加 UUID 的代码

@Slf4j
public class ReqTxIdFilterImpl implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        List<String> headerNames = Collections.list(request.getHeaderNames());
        String requestTxId = "";
        if(!headerNames.isEmpty()){
            requestTxId = request.getHeader(
                    headerNames.stream()//
                            .filter(header -> header.contains("txId"))
                            .findAny()
                            .orElse("")//
                    );
        }
        if (StringUtils.isEmpty(requestTxId)) {
            requestTxId = UUID.randomUUID().toString();
        }
        MDC.put("txId", requestTxId);
        filterChain.doFilter(servletRequest, servletResponse);
        MDC.clear();
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用 spring boot 和 MockMvc 来测试 API

@Autowired
    private MockMvc mockMvc;

    @Test
    public void test_generatePolicyNumber() throws Exception { …
Run Code Online (Sandbox Code Playgroud)

java logback mdc spring-boot

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

卡夫卡监听器中的钩子

kafka 监听消息之前/之后是否有任何类型的钩子可用?

使用案例:必须设置 MDC 关联 ID 才能执行日志可追溯性

我在寻找什么?之前/之后回调方法,以便可以在进入时设置 MDC 关联 ID,并最终在退出时清除 MDC。

编辑后的场景: 我将关联 id 作为 Kafka 标头的一部分,并且我想在 Kafka 监听器中收到消息后立即在 MDC 中进行设置

感谢您的帮助

spring slf4j mdc apache-kafka spring-kafka

5
推荐指数
1
解决办法
3605
查看次数