在我们的软件中,我们广泛使用MDC来跟踪会话ID和Web请求的用户名等内容.这在原始线程中运行时工作正常.但是,有很多事情需要在后台处理.为此,我们使用java.concurrent.ThreadPoolExecutor和java.util.Timer类以及一些自动异步执行服务.所有这些服务都管理自己的线程池.
这就是Logback的手册在这样的环境中使用MDC所要说的:
映射的诊断上下文的副本不能始终由来自启动线程的工作线程继承.当java.util.concurrent.Executors用于线程管理时就是这种情况.例如,newCachedThreadPool方法创建一个ThreadPoolExecutor,就像其他线程池代码一样,它具有复杂的线程创建逻辑.
在这种情况下,建议在将任务提交给执行程序之前,在原始(主)线程上调用MDC.getCopyOfContextMap().当任务运行时,作为其第一个操作,它应调用MDC.setContextMapValues()以将原始MDC值的存储副本与新的Executor托管线程相关联.
这样会很好,但是很容易忘记添加这些调用,并且没有简单的方法来识别问题,直到为时已晚.Log4j的唯一标志是您在日志中丢失了MDC信息,而使用Logback,您会收到过时的MDC信息(因为胎面池中的线程从其上运行的第一个任务继承其MDC).两者都是生产系统中的严重问题.
我不认为我们的情况有任何特殊之处,但我在网上找不到这个问题.显然,这不是很多人碰到的东西,所以必须有办法避免它.我们在这做错了什么?
是否可以根据属性制作部分logbacks模式布局?例如,在%X {bdid}存在的情况下显示bdid(...)?
这个appender
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>bdid\(%X{bdid}\) - %d{HH:mm:ss.SSS} %msg%n</pattern>
</encoder>
</appender>
Run Code Online (Sandbox Code Playgroud)
版画
bdid(0b5d3877-f3dd-4189-8b1b-489c8b617f2a) 18:22:25.206 如果bdid存在,但打印
bdid() 18:22:20.928 如果没有.
如何在日志中省略空bdid()?
我正在使用的软件使用MDC来获取特定数据(用户名,IP,执行时间等).我希望一些日志使用某些MDC使用特定模式,而某些日志使用其他模式使用其他MDC.
我认为标记可以完成这项工作,我设置了不同的标记,比如说:PROFILE_MARKER - 用于配置文件日志AUDIT_MARKER - 用于审计日志
我的logback.xml配置文件中有3个appender,一个用于我的标记,另一个用于所有其他日志:
<configuration>
<appender name="profiler" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d [%t] [%X{USER}] [PROFILER] %-5p %m %X{TIME} ms %n</pattern>
</encoder>
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
<marker>PROFILER</marker>
</evaluator>
<onMismatch>DENY</onMismatch>
<onMatch>ACCEPT</onMatch>
</filter>
</appender>
<appender name="audit" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d [%t] [%X{USER}] [AUDIT] %-5p IP=%X{IP},ID=%X{ID} %m %n</pattern>
</encoder>
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
<marker>AUDIT</marker>
</evaluator>
<onMismatch>DENY</onMismatch>
<onMatch>ACCEPT</onMatch>
</filter>
</appender>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d [%t] [%X{USER}] %-5p %c - %m %n</pattern>
</encoder>
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
<marker>AUDIT</marker>
<marker>PROFILE</marker>
</evaluator>
<onMismatch>ACCEPT</onMismatch>
<onMatch>DENY</onMatch>
</filter>
</appender>
<root …Run Code Online (Sandbox Code Playgroud) 我试图登录的几个值onBeginRequest()的RequestCycle()在检票口.但是这些值未记录在调试文件中.我将值放在MDC中RequestCycleListeners().
以下是代码:
getRequestCycleListeners().add(new AbstractRequestCycleListener()
{
public void onBeginRequest(RequestCycle cycle)
{
if( cycle.getRequest().getContainerRequest() instanceof HttpServletRequest )
{
HttpServletRequest containerRequest =
(HttpServletRequest)cycle.getRequest().getContainerRequest();
MDC.put("serverName", containerRequest.getServerName());
MDC.put("sessionId", containerRequest.getSession().getId());
LOGGER.debug("logging from RequestCycleListeners() !!!");
WebClientInfo webClientInfo = new WebClientInfo(RequestCycle.get());
System.out.println(webClientInfo.getUserAgent());
System.out.println("webClientInfo.getProperties().getBrowserVersionMajor() " +containerRequest.getRemoteAddr());
}
Run Code Online (Sandbox Code Playgroud)
};
我期待'serverName','sessionId'被记录在调试文件中.
我listener在扩展的类中添加了这个WebApplication.
我使用的DEBUG appender是log4j.xml ,如下所示:
<appender name="DEBUG" class="org.apache.log4j.rolling.RollingFileAppender">
<param name="Append" value="true"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%d{ISO8601} %t %5p] %m -- %X{serverName} -- %X{sessionId} -- %X{portNumber}%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param …Run Code Online (Sandbox Code Playgroud) 如何保留在实现的doFilter()方法中添加的 MDC 属性javax.servlet.Filter...
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
MDC.put("token", MyToken.random()); // add the MDC attribute related to the current request processing
chain.doFilter(request, response); // send the request to other filters and the Controller
} finally {
MDC.clear(); // MDC attribute must be removed so future tasks executed on the same thread would not log invalid information
}
}
Run Code Online (Sandbox Code Playgroud)
... 在异常处理期间,如果异常发生在另一个过滤器或控制器中(对 的调用chain.doFilter(...))。
当前,如果发生异常:将执行 finally 块,清除 …
我有一个 Spring-Boot 应用程序,我也在其中启动了 gRPC 服务器/服务。servlet 和 gRPC 代码都将请求发送到一个公共对象来处理请求。当请求进来时,我想更新日志以显示唯一的“ID”,以便我可以通过系统跟踪请求。
在 Spring 方面,我设置了一个“过滤器”,它更新日志记录 MDC 以向日志请求添加一些数据(请参阅此示例)。这工作正常
在 gRPC 方面,我创建了一个“ServerInterceptor”并将其添加到服务中,而拦截器被调用,更新 MDC 的代码不会粘住,因此当请求通过 gRPC 服务时,我没有打印出 ID日志。我意识到这与我在一个线程中拦截调用并且它在另一个线程中由 gRPC 调度这一事实有关,我似乎无法弄清楚如何在执行工作的线程中拦截调用或添加 MDC 信息,以便将其正确传播到执行工作的线程。
我做了很多搜索,很惊讶没有找到这个问题/答案,我只能假设我的查询技巧缺乏:(
我对 gRPC 相当陌生,这是我正在编写的第一个拦截器。我已经尝试以几种不同的方式添加拦截器(通过 ServerInterceptors.intercept、BindableService instance.intercept)。
我看过LogNet 的 Spring Boot gRPC Starter,但我不确定这是否能解决问题。
这是我在拦截器类中添加的代码
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(final ServerCall<ReqT, RespT> call, final Metadata headers, final ServerCallHandler<ReqT, RespT> next) {
try {
final String mdcData = String.format("[requestID=%s]",
UUID.randomUUID().toString());
MDC.put(MDC_DATA_KEY, mdcData);
return next.startCall(call, headers);
} …Run Code Online (Sandbox Code Playgroud) 在a中的appender中logback.xml是否可以执行任何操作,例如迭代MDC,打印整个MDC等等?我能想到的最简单的方法是基本上通过java/groovy代码(我还没有研究过怎么做),想知道是否有简写.
我想将API请求/响应记录为json格式.
预期的LogEntry是这样的
{
"timestamp" : "...",
"level" : "DEBUG",
"headers" : [
"header1" : "value1",
"header2" : "value2",
"header3" : "value3"
],
"requestPayload" : "<Request Json>" // prefereablly as sub-document, worst case string is fine.
"labels" : [ //key fields which can be used for searching the logentry
"searchField1" : "....",
"searchField2" : "....",
"searchField3" : "...."
]
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
使用Logback,如何记录嵌套字段(例如上面示例中的标题,标签,requestPaylod),作为json子文档.我尝试过MDC,但它仅限于'String,String'的Map,并将第一级之后的所有字段视为String.
我讨厌为此编写我的自定义记录器,并希望使用成熟的日志记录框架(logback/log4j)的优点来控制日志记录级别,时间戳记日志事件等.
如何在log4j2的JsonLayout生成的json日志中添加MDC变量。我已经使用 KeyValuePair 标记将主机名等属性添加到日志中,但我没有找到任何方法将 MDC 变量添加到其中。在模式布局中,我使用了 %X{traceId} 但我确定 JsonLayout 无法解析这些转换字符(据我所知,转换字符仅用于模式布局)。我进入了 JsonLayout 的源代码,但没有找到实际上将所有数据放入日志消息的函数。
谢谢你。
网页材料设计。如何设置 mdc.menu 的位置?
我会将 mdc 菜单从左上角移到右上角。距顶部 70 像素,距右侧 25 像素。
请看一下我的截图。如何更改元素样式。
请看一下我的js代码。我必须在哪里进行更改?在 css 中还是在 javascript 中?我对浏览器 chrome 进行了以下更改。
element.style {
right: 25px;
top: 70px;
}
Run Code Online (Sandbox Code Playgroud)
这是完整的 html 代码。
<!DOCTYPE html>
<html>
<head>
<title>App Bar</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="msapplication-tap-highlight" content="no">
<meta name="norobots" content="noindex, nofollow, noarchive">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<link rel="icon" href="favicon.ico" type="image/x-icon">
<!-- import Material Icons from Google Fonts -->
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono|Roboto:400i" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" …Run Code Online (Sandbox Code Playgroud)