在用 Java 实现的 Restful 服务中,当出现服务器端错误时,必须记录堆栈跟踪以供以后诊断,并返回适当的 HTTP 500 代码之一。
但是 400 呢?这些例子包括无效的输入、格式错误的 JSON/XML、身份验证失败、找不到资源等。显然我们需要记录错误消息本身,但是堆栈跟踪呢?有没有人记录过这些类型的堆栈跟踪并发现它们有用甚至必不可少?
已编辑: 例如(不限于此异常(exception)):
仅记录异常本身:
org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Unrecognized field "foo" (class someClass), not marked as ignorable (1 known property: "bar")
at [Source: someClass; line: 14, column: 20] (through reference chain: someClass["foo"]->someClass["bar"]->someClass["bar2"]); nested exception is com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "foo" (class someClass), not marked as ignorable (1 known property: "bar")
at [Source: someClass; line: 14, column: 20] (through reference chain: someClass["foo"]->someClass["bar"]->someClass["bar2"])
记录堆栈跟踪:
at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readJavaType(MappingJackson2HttpMessageConverter.java:181) ~[spring-web-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.read(MappingJackson2HttpMessageConverter.java:173) ~[spring-web-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:143) ~[spring-webmvc-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:180) ~[spring-webmvc-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:95) ~[spring-webmvc-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77) ~[spring-web-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:157) ~[spring-web-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:124) ~[spring-web-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) ~[spring-webmvc-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745) ~[spring-webmvc-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:685) ~[spring-webmvc-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) ~[spring-webmvc-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:919) ~[spring-webmvc-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:851) ~[spring-webmvc-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953) ~[spring-webmvc-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855) ~[spring-webmvc-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) ~[servlet-api-2.5.jar:2.5]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829) ~[spring-webmvc-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65) ~[spring-test-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) ~[servlet-api-2.5.jar:2.5]
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:168) ~[spring-test-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:136) [spring-test-3.2.11.RELEASE.jar:3.2.11.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
最佳答案
我认为最好尽可能多地了解引起异常和日志消息的上下文。不过,在处理复杂的代码路径时,堆栈跟踪肯定会很有帮助。如果有的话,我只会将它们记录在比您的默认级别更低的级别,以便在必要时可以打开/关闭它们。
关于java - 我们是否应该记录 HTTP 400 的堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27307165/