济南网站建设 泉诺,书籍封面设计网站,贵阳专业做网站的公司,阿里云服务器做网站多少钱很久以前#xff0c;我了解了一个称为Log MDC的东西#xff0c;我对此非常感兴趣。 我突然能够理解日志文件中发生的所有事情#xff0c;并指出特定的日志条目#xff0c;并找出对错#xff0c;特别是在调试生产中的错误时。 在2013年#xff0c;我受委托从事一个项目我了解了一个称为Log MDC的东西我对此非常感兴趣。 我突然能够理解日志文件中发生的所有事情并指出特定的日志条目并找出对错特别是在调试生产中的错误时。 在2013年我受委托从事一个项目该项目正在一些麻烦的水域几件事情的结合中运行几乎每个星期我不得不经历几次Java Thread Dump以弄清应用程序中发生的事情以使其停止。 另外有时我不得不将诸如AppDynamicjProfilerjConsole之类的探查器全部连接到应用程序以试图找出问题所在更重要的是是什么引发了问题。 jStack是我使用过的最有用的工具之一但是碰到的线程转储没有我可以使用的上下文信息。 我被困在看到10s个转储的堆栈跟踪中哪些类导致了该块但是没有有关什么是什么以及什么输入导致了该问题的信息并且它很快就令人沮丧。 最终我们找到了问题但是它们主要是在经过数轮深度调试后使用各种数据集对代码进行的。 一旦完成该项目我发誓我再也不会陷入那种境地了。 我探索了可以使用类似于Log4j的NDC但在线程中使用它的方式以便我的转储有意义。 而且我发现我可以更改ThreadName。 我的下一个项目确实非常有效地使用了它。 我最近遇到了一篇文章很好地解释了这个概念。 我不会重写他们所说的所有内容因此这里是他们博客文章的链接 。 所以上周我开始一个新项目当我开始编码框架时使用Spring 4.1和Spring Boot这是我为应用程序编写的第一个类并确保过滤器尽快进入代码。帮助我们进行后期制作但也使我的开发日志有意义。 下面是Log4j NDC和设置ThreadName的代码副本。 import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.filter.OncePerRequestFilter;/*** This is a very Spring opinionated HTTPFilter used for intercepting all requests and decorate the thread name with additional contextual* information. We have extenced the filter from {link OncePerRequestFilter} class provided by Spring Framework to ensure that the filter is absolutely * executd only once per request. * * The following information will be added:* ul* liOld Thread name: to ensure that we are not losing any original context with thread names;/li* liTime when the request was intercepted;/li* liThe RequestURI that proviced information on what RestFUL endpoint was accessed as part of this request;/li* liA Token that was received in the header. This token is encrypted and does not exposes any confidential information. Also, this token provides* context which helps during debugging;/li* liThe Payload from the token. This information will be very helpful when we have to debug for issues that may be happening with a call request* as this holds all the information sent from the called./li* /ul* * This filter will also reset the ThreadName back to its original name once the processing is complete.* * author Kapil Viren Ahuja**/
public class DecorateThreadNameFilter extends OncePerRequestFilter {Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {final Logger LOGGER LoggerFactory.getLogger(DecorateThreadNameFilter.class);final SimpleDateFormat dateFormat new SimpleDateFormat(yyyy-MM-dd HH:mm:ss.SSS);Thread thread Thread.currentThread();String threadOriginalName thread.getName();String uri request.getRequestURI();String time dateFormat.format(new Date());String token request.getHeader(authorization);try {thread.setName(String.format(%s StartTime \%s\ RequestURI \%s\ Token \%s\, threadOriginalName, time, uri, token));} catch (Exception ex) {LOGGER.error(Failed to set the thread name., ex);// this is an internal filter and an error here should not impact// the request processing, hence eat the exception}try {filterChain.doFilter(request, response);} finally {try {thread.setName(threadOriginalName);} catch (Exception ex) {LOGGER.error(Failed to reset the thread name., ex);// this is an internal filter and an error here should not// impact the request processing, hence eat the exception}}}
}/*** Generic filter for intercepting all requests and perform the following generic tasks:* * ul* liIntercepts the request and then pushed the user domain into the session if one exists./li* li Pushes a uniquely generated request identifier to the LOG4J NDC context. This identifier will then be prepended* to all log messages generated using LOG4J. This allows tracing all log messages generated as part of the same* request; /li* li Pushes the HTTP session identifier to the LOG4J NDC context. This identifier will then be prepended to all log* messages generated using LOG4J. This allows tracing all log messages generated as part of the same HTTP session;* /li* li Pushes the IP address of the client to the LOG4J NDC context. The IP address will then be prepended to all log* messages generated using LOG4J. This allows tying back multiple user sessions initiated with the same logon name to* be correctly tied back to their actual origins. /li* /ul*/
public class RequestInterceptorFilter implements Filter
{/*** p* ul* liInitializes the LOG4J NDC context before executing an HTTP requests./li* liPushes the domain into the session/li* /ul* /p*/public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException{HttpServletRequest httpRequest (HttpServletRequest) request;if (httpRequest.isRequestedSessionIdFromCookie() !httpRequest.isRequestedSessionIdValid()){// TODO: Need to define an session expiration page and redirect the application to that page// As of now this is a non-issue as we are handling session expirations on Flex (Front-end) and hence// no request will come to server in case the session timeout occurs// HttpServletResponse httpServletResponse (HttpServletResponse) response;// httpServletResponse.sendRedirect(httpRequest.getContextPath() ?expired);}else{// Create an NDC context string that will be prepended to all log messages written to files.org.apache.log4j.NDC.push(getContextualInformation(httpRequest));// Process the chain of filterschain.doFilter(request, response);// Clear the NDC context string so that if the thread is reused for another request, a new context string is// used.org.apache.log4j.NDC.remove();}}public void init(FilterConfig arg0) throws ServletException{}public void destroy(){}/*** p* Generates the Contextual information to be put in the log4js context. This information helps in tracing requests* /p* * param httpRequest* return*/private String getContextualInformation(HttpServletRequest httpRequest){String httpRequestIdentifier UUID.randomUUID().toString();String httpSessionIdentifier httpRequest.getSession().getId();String clientAddress httpRequest.getRemoteAddr();StringBuffer logNDC new StringBuffer(httpRequestIdentifier | httpSessionIdentifier | clientAddress);String userName (String)httpRequest.getSession().getAttribute(WebConstants.USERNAME);if (userName ! null){logNDC.append( | userName);}String domain (String)httpRequest.getSession().getAttribute(WebConstants.DOMAIN);if (domain ! null){logNDC.append( | domain);}// Create an NDC context string that will be prepended to all log messages written to files.return logNDC.toString();}
}翻译自: https://www.javacodegeeks.com/2015/08/making-thread-dumps-intelligent.html