2014-12-05 76 views
0

在Java中實現的平安服務中,當出現服務器端錯誤以便稍後診斷並返回適當的HTTP 500代碼之一時,必須記錄堆棧跟蹤。我們是否應該記錄HTTP 400的堆棧跟蹤

但是400年代呢?這樣的例子包括無效輸入,格式錯誤的JSON/XML,認證失敗,資源未找到等。顯然,我們需要記錄錯誤消息本身,但是堆棧跟蹤呢?有沒有人記錄過這些類型的堆棧跟蹤,發現它們有用或甚至是必需的?

編輯: 例如(不限於本除外):

記錄只是例外本身:

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] 
+0

什麼無論如何,這些堆棧痕跡都是這些?例如,你嘗試反序列化JSON輸入並且不這樣做? – fge 2014-12-05 01:12:10

+0

我提供了一個例子。 – 2014-12-05 01:22:08

+0

由於這是JSON,因此在反序列化之前可能需要使用JSON Schema來驗證它;這將允許沒有反序列化錯誤,或者至少大大減少它們的數量 – fge 2014-12-05 01:41:32

回答

1

它可能自己記錄錯誤是一個好主意。這些信息可能是有用的,即可以很好地知道發生了哪種類型的客戶端故障。這可以幫助您改進服務文檔或API以使客戶更容易。

至於特定的堆棧跟蹤。這可能不太有用。您通常知道故障點(即Web服務的入口點)。因此,對於大多數故障,您可能會得到相同的堆棧跟蹤。儘管記錄這些也沒有什麼壞處。

1

當您需要堆棧跟蹤不需要知道錯誤來自何處。如果您在故意使用400故意拒絕輸入時故意自行記錄錯誤,則可以添加一些內容一個序列號,所以你可以找到它來自哪裏,而不是整個堆棧跟蹤,這在這種情況下真的只是浪費空間。

3

我認爲最好儘可能多地獲取引起異常和日誌消息的上下文。不過,在處理複雜的代碼路徑時,Stacktraces肯定會有所幫助。如果有的話,我只會將它們記錄在比默認值更低的級別上,以便在必要時打開/關閉它們。

1

我會說「不」,完整的堆棧跟蹤對「400」錯誤沒有幫助,這通常意味着請求有問題,而不是服務器。有用的是記錄儘可能多的關於違規請求的信息:源IP和端口,登錄用戶(如果有的話),違規數據,部分解碼的違規數據,其他會話變量...