我们使用 SLF4J(使用 log4j)作为我们的日志框架。我们正在尝试利用 Log4j 支持的在线文档的 MDC 功能。
使用 SLF4J 时 MDC 不起作用。但是,当使用 log4j 时,它工作得很好。文档说明只要底层框架支持MDC,SLF4J就应该支持。
我们正在使用 SLF4J 1.6.4 ( slf4j-api,slf4j-log4j12并slf4j-simple已作为依赖项添加到我们的pom.xml) 中。
某处是否存在差异/不匹配?我们是否缺少任何依赖项?任何输入将不胜感激。
我有一个使用Slf4j和java.util.Logging设置的日志记录机制.我有几个线程,所以我无法从日志中得到一个清晰的想法,因为它们是混合的.现在我尝试使用MDC概念在日志文件中添加更多数据,以便它们清晰.
问题与Slf4j中的一样,虽然它支持MDC java.util.Logging不支持.但它说
如果底层框架不提供MDC,例如java.util.logging,则SLF4J仍将存储MDC数据,但其中的信息需要由自定义用户代码检索.
我正在尝试找到一种方法来执行此自定义代码.谷歌搜索对我没什么帮助.Slf4j中有一个名为"BasicMDCAdapter"的辅助类.但我不知道如何使用它.我无法在任何地方找到示例代码.
这也是一个有助于此的代码,但仍然没有给出一些描述.
我很感激这里的帮助.
谢谢.
我最近发现了在记录时使用MDC的魔力.它完美地运作.
我有以下方法:
public static final String MDC_CLIENT="client";
public static final String MDC_SESSION="session";
public static final String MDC_DEVICE="device";
// Called for every request.
public static void request(final HttpServletRequest request) {
// The MDC is a thread-local storage accessable from the log formatter.
MDC.put(MDC_CLIENT, String.format("%s:%s", request.getRemoteHost(), request.getRemotePort()));
HttpSession session = request.getSession();
MDC.put(MDC_SESSION, session.getId());
MDC.put(MDC_DEVICE, (String)session.getAttribute("device"));
// Also record the context.
setContext(session.getServletContext());
}
Run Code Online (Sandbox Code Playgroud)
这被称为每个jsp中的第一个动作.这使我能够很好地跟踪日志中会话的详细信息.
但是 - 我怎么知道remove这些地图条目的时间?我应该注意哪些事件才能让我整理地图?
我在Tomcat下托管.如果它重新使用线程,那么我不会泄漏内存,因为它们本质上是线程本地的,所以每次put都会覆盖put上次使用线程时的旧内存.如果它没有 - 或者我托管在其他东西之下 - 我本质上可能永远地增长地图 - 或者至少在主机重新启动之前.
我认为我的问题的本质是 …
我们的Akka项目依赖于其他一些非akka代码。从这段代码中,我们获取记录器的方法是通过调用org.slf4j.LoggerFactory.getLogger(ThisClass.class)
我想获得事件发生的时间和地点的实时和真实线程,包括在日志打印中,因此我获取akkaTimestamp和sourceThread的值,如下所示:
log4j.appender.console.layout.ConversionPattern=[%-5p] [%X{akkaTimestamp}] [%X{sourceThread}] %c{5}: %m%n
Run Code Online (Sandbox Code Playgroud)
问题是从MDC提取的这些值在从非Akka记录器发送的打印物中不可用。
他们在这里说
最好在应用程序的非Akka部分中使用sourceThread MDC值,以使此属性在日志中始终可用。
但是他们从不说/
我想在我的AKKA应用程序上实现logback MDC日志记录,以组织并拥有更具信息性的日志; 但是,我还读到MDC可能不适用于AKKA,因为AKKA具有异步日志记录系统(MDC可能存储在不同的线程上).我使用的自定义调度的定义MDC记录在这里希望能解决我的问题,但我不能让我的应用程序.我的应用程序不是一个游戏框架应用程序.
我有一个RequestHandler接收不同类型请求的RequestSpecificHandlerActor,并将其委托给将处理它的Actor.
class RequestHandler() extends Actor with akka.actor.ActorLogging {
def receive: Receive = {
//Requests
case req: RequestA =>
org.slf4j.MDC.put("messageId", req.msgId)
org.slf4j.MDC.put("requestType", req.requestType)
log.debug("FIRST LOG Received a RequestA")
val actorA = context.ActorOf(ActorA.props)
actorA ! req.msg
case req: RequestB => //...
//other requests...
//Response
case res: ResponseA =>
log.debug("Received responseA")
org.slf4j.MDC.remove("messageId")
org.slf4j.MDC.remove("requestType")
//other response
}
}
Run Code Online (Sandbox Code Playgroud)
在我的RequestSpecificHandler演员中,我也创建了新的或引用其他现有的HelperActors
class ActorA () extends Actor with akka.actor.ActorLogging {
val helperA = context.actorSelection("/user/helperA")
val …Run Code Online (Sandbox Code Playgroud) 与在log4j中一样,我们可以选择针对MDC密钥设置默认值-mdc {key:-defaultVal}
我们在log4j 2中有类似的东西吗?
在我的node.js应用程序中,每当我收到请求时,我都想用一些唯一的ID“标记”它,并能够通过该ID跟踪与该请求相关的所有活动(日志语句)。因此,当请求传入并且我将其处理传递给较低的应用程序层(服务、数据库调用等)时,我希望能够收集与给定请求 ID 匹配的所有日志,以重建其通过应用程序的旅程。
有了这张图片,我现在使用request-local模块,但它做了一些让我失败的重大魔法(来自多个请求的日志获得相同的 ID)。
该代码主要基于 Promises(不是普通的旧节点回调),并且我使用高阶函数来提供对我的实际函数的依赖项(在启动期间构建应用程序树)。
第一个也是非常明显的解决方案是将这个请求 ID 传递给每个调用的函数,但这是一场灾难,我不会这样做。
您如何(可靠地)进行这种请求跟踪,而不显式将此 id/上下文作为额外参数传递给所有级别的函数?
我需要在日志中包含映射的诊断上下文数据。应用程序构建:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
Run Code Online (Sandbox Code Playgroud)
为了在日志中获取 MDC,我将其放入application.properties文件中:
logging.pattern.level=%X{mdcData}%5p
Run Code Online (Sandbox Code Playgroud)
并创建一个类
@Component
public class RequestFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try {
// Setup MDC data:
String mdcData = String.format("[userId:%s | requestId:%s] ", "hello", "hello");
MDC.put("mdcData", mdcData); //Variable 'mdcData' is referenced in Spring Boot's logging.pattern.level property
chain.doFilter(request, response);
} finally {
// Tear down MDC data:
// ( Important! Cleans …Run Code Online (Sandbox Code Playgroud) 执行async时CompletableFuture,父线程org.slf4j.MDC上下文以及上下文会丢失。
这很不好,因为我使用某种“鱼标签”来跟踪多个日志文件中一个请求的日志。
MDC.put("fishid", randomId())
问题:一般情况下,我该如何保留该ID CompletableFutures?
List<CompletableFuture<UpdateHotelAllotmentsRsp>> futures =
tasks.stream()
.map(task -> CompletableFuture.supplyAsync(
() -> businesslogic(task))
.collect(Collectors.toList());
List results = futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
public void businesslogic(Task task) {
LOGGER.info("mdc fishtag context is lost here");
}
Run Code Online (Sandbox Code Playgroud) 我试图找出一种在Java中基于反应/事件的异步编程中使用MDC的方法,但找不到。
有人可以解释如何在回调事件/方法中传播MDC变量吗?
在这种情况下,如何像在传统的同步编程中那样跟踪请求,直到响应被提供为止?