過濾日志中不相關的堆棧跟蹤行

我喜歡堆棧痕跡。 不是因為我喜歡錯誤,而是因為發生錯誤的那一刻,堆棧跟蹤是無價的信息源。 例如,在Web應用程序中,堆棧跟蹤向您顯示完整的請求處理路徑,從HTTP套接字到過濾器,Servlet,控制器,服務,DAO等,直至發生錯誤的地方。 您可以將它們讀為一本好書,其中每個事件都有因果關系。 我什至在Logback打印異常的方式上實現了一些增強功能,請參閱首先記錄異常的根本原因 。

但是有一件事一直困擾著我一段時間。 臭名昭著的“ 來自地獄的堆棧跟蹤 ”癥狀–堆棧跟蹤包含數百種不相關的,隱秘的,通常是自動生成的方法。 AOP框架和過度設計的庫往往會產生瘋狂的長執行跟蹤。 讓我展示一個真實的例子。 在一個示例應用程序中,我正在使用以下技術堆棧:

顏色很重要。 根據框架/層的顏色,我繪制了一個示例堆棧跟蹤,該堆棧跟蹤是由于嘗試從數據庫中獲取數據時在某處深處拋出異常而引起的:

不再那么愉快,你不覺得嗎? 在第一張圖中,將Spring放在應用程序和Hibernate之間是一個極大的簡化。 Spring框架是一個膠合代碼,用于連接并攔截周圍層的業務邏輯。 這就是為什么應用程序代碼被數十行技術調用分散和交織的原因(請參見綠線)。 我在應用程序中投入了盡可能多的內容(Spring AOP,方法級別的@Secured批注,自定義方面和攔截器等)來強調該問題-但這不是特定于Spring的。 EJB服務器在EJB調用之間生成同樣可怕的堆棧跟蹤(…從地獄)。 我應該在乎嗎? 想想看,當您從BookController.listBooks()無辜地調用BookService.listBooks() ,您希望看到此消息嗎?

at com.blogspot.nurkiewicz.BookService.listBooks()
at com.blogspot.nurkiewicz.BookService$$FastClassByCGLIB$$e7645040.invoke()
at net.sf.cglib.proxy.MethodProxy.invoke()
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed()
at com.blogspot.nurkiewicz.LoggingAspect.logging()
at sun.reflect.NativeMethodAccessorImpl.invoke0()
at sun.reflect.NativeMethodAccessorImpl.invoke()
at sun.reflect.DelegatingMethodAccessorImpl.invoke()
at java.lang.reflect.Method.invoke()
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs()
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod()
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.aop.interceptor.AbstractTraceInterceptor.invoke()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept()
at com.blogspot.nurkiewicz.BookService$$EnhancerByCGLIB$$7cb147e4.listBooks()
at com.blogspot.nurkiewicz.web.BookController.listBooks()

您甚至注意到它們之間存在自定義方面嗎? 事實就是如此,如今堆棧跟蹤中雜亂無章,幾乎不可能遵循實際的業務邏輯。 我們擁有的最好的故障排除工具之一是在99%的情況下都不需要與框架相關的無關內容。

工具和IDE在減少噪聲方面做得很好。 Eclipse具有用于Junit的堆棧跟蹤過濾器模式 , IntelliJ IDEA支持控制臺折疊自定義 。 另請參閱: 從Java堆棧跟蹤中清除噪音 ,這啟發了我寫這篇文章。 那么,為什么在Logback等日志記錄框架中根本沒有這種可能性呢?

我在Logback中實現了一個非常簡單的增強。 基本上,您可以定義一組應該從堆棧跟蹤中排除的堆棧跟蹤框架模式。 通常,您將使用不希望看到的包或類名。 這是啟用了新功能的示例logback.xml摘錄:

<root level="ALL"><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{HH:mm:ss.SSS} | %-5level | %thread | %logger{1} | %m%n%rEx{full,java.lang.reflect.Method,org.apache.catalina,org.springframework.aop,org.springframework.security,org.springframework.transaction,org.springframework.web,sun.reflect,net.sf.cglib,ByCGLIB}</pattern></encoder></appender>
</root>

在過濾幾乎整個Spring框架+ Java反射和CGLIB類時,我有點極端。 但這只是給您一種印象,您可以得到多少。 將我的增強功能應用到Logback后,出現了非常相同的錯誤:

提醒一下,綠色是我們的應用程序。 最終在一個地方,最終您可以真正看到發生錯誤時代碼在做什么:

at com.blogspot.nurkiewicz.DefaultBookHelper.findBooks()
at com.blogspot.nurkiewicz.BookService.listBooks()
at com.blogspot.nurkiewicz.LoggingAspect.logging()
at com.blogspot.nurkiewicz.web.BookController.listBooks()

更簡單? 如果您喜歡此功能,我打開了一張票LBCLASSIC-325 : 篩選出選定的堆棧跟蹤框架 。 投票討論。 這只是一個概念證明,但是如果您想看一下實現(歡迎改進!),可以在我的Logback 分支下找到(大約20行代碼)。

參考:從JCG合作伙伴的 日志中過濾無關的堆棧跟蹤行 ? Java和社區博客中的Tomasz Nurkiewicz。


翻譯自: https://www.javacodegeeks.com/2012/03/filter-irrelevant-stack-trace-lines-in.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/373668.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373668.shtml
英文地址,請注明出處:http://en.pswp.cn/news/373668.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Can't create/write to file '/tmp/#sql_887d_0.MYD' (Errcode: 17)

lsof |grep "#sql_887d_0.MYD" 如果沒有被占用就可以刪掉 。 https://wordpress.org/support/topic/cant-createwrite-to-file-error Hello, just today I saw this kind of error on every page on my blog. WordPress database error: [Cant create/write to file …

python3怎么創建文件_Python3.5 創建文件的簡單實例

實例如下所示&#xff1a;#codingutf-8Created on 2012-5-29author: xiaochouimport osimport timedef nsfile(s):The number of new expected documents#判斷文件夾是否存在&#xff0c;如果不存在則創建b os.path.exists("E:\\testFile\\")if b:print("File …

Dijkstra 最短路算法(只能計算出一條最短路徑,所有路徑用dfs)

上周我們介紹了神奇的只有五行的 Floyd 最短路算法&#xff0c;它可以方便的求得任意兩點的最短路徑&#xff0c;這稱為“多源最短路”。本周來來介紹指定一個點&#xff08;源點&#xff09;到其余各個頂點的最短路徑&#xff0c;也叫做“單源最短路徑”。例如求下圖中的 1 號…

JavaScript學習隨記——錯誤類型

錯誤類型&#xff1a; 執行代碼期間可能會發生的錯誤有多種類型。每種錯誤都有對應的錯誤類型&#xff0c;而當錯誤發生時&#xff0c;就會拋出相應類型的錯誤對象。 ECMA-262定義的7種錯誤類型 Error&#xff1a; 是錯誤的基類型&#xff0c;其他錯誤類型都繼承該類型。Error…

多個集合中的共同和獨特元素

本周&#xff0c;我們將暫時中斷較高級別的問題和技術文章&#xff0c;以解決我們中許多人可能面臨的一些代碼問題。 沒什么花哨的或太辛苦的&#xff0c;但是有一天它可能會節省您15分鐘的時間&#xff0c;偶爾回到基礎上也很不錯。 因此&#xff0c;讓我們開始吧。 有時&…

2016給自己一個交代

一、前言 在關于技術上的學習&#xff0c;常常有這樣那樣的計劃&#xff0c;而最終一個都沒有真正的落實。零散的學習&#xff0c;終究需要系統總結&#xff0c;才能使自己有所沉淀。從畢業至今&#xff0c;我一直在忙碌&#xff0c;為公司付出自己的很多很多&#xff0c;卻只不…

洛克人紅色思考型機器人叫什么_稻船敬二新企劃《紅色灰燼》 依然是機器人風格...

稻船敬二離開CAPCOM之后玩家們紛紛感嘆《洛克人》系列將再無續作&#xff0c;不過在單飛的這段時間里&#xff0c;稻船敬二還是創作了諸如《蒼藍雷霆 剛巴爾特》《Mighty No.9》等類似洛克人風格的作品。其名下的團隊comcept的最新作《Mighty No.9》即將于9月18日發售&#xff…

常見對話框

(1)普通對話框 // 點擊按鈕 彈出一個普通對話框public void click1(View v) {// 構建AlertDialogAlertDialog.Builder builder new Builder(this);builder.setTitle("警告");builder.setMessage("世界上最遙遠的距離是沒有網絡");builder.setPositiveButt…

JavaScript學習隨記——面向對象編程(繼承)

Example:基于原型鏈的繼承 <!DOCTYPE HTML> <html><head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><title>面向對象編程&#xff08;OOP&#xff09;</title></head> <body>…

NSCharacterSet

先上個例子&#xff1a; NSString * str1 [nameInput.textstringByTrimmingCharactersInSet:[NSCharacterSetwhitespaceAndNewlineCharacterSet]]; NSString * str2 [passwdInput.textstringByTrimmingCharactersInSet:[NSCharacterSetwhitespaceAndNewlineCharacterSet]]; […

Apache Mahout:構建垃圾郵件過濾器服務器

Lucene發生了一些相當有趣的事情。 它最初是作為一個庫&#xff0c;然后其開發人員開始基于它添加新項目。 他們開發了另一個開源項目&#xff0c;該項目將向Lucene添加爬網功能&#xff08;以及其他功能&#xff09;。 Nutch實際上是任何人都可以使用或修改的功能齊全的Web Se…

建模步驟_古建設計 | sketchup建模步驟教程(簡易入門版)

前言本篇教程主要是針對古建建模入門者。小N給大家分享一套我相對簡易的建模步驟。(PS&#xff1a;但是估計有些人可能會感覺我做的東西已經繁瑣了……)因為主要是為了讓大家熟悉、入門和好記憶。所以講的東西&#xff0c;小N我會相對簡單&#xff0c;有些細節的內容不會更多展…

JavaScript模塊化

JavaScript模塊化的實現方式&#xff1a; <!DOCTYPE HTML> <html><head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><title>模塊化</title></head> <body><script type&quo…

Linux下面的IO模型

1. Linux下的五種I/O模型 阻塞I/O模型&#xff1a; 一直阻塞 應用程序調用一個IO函數&#xff0c;導致應用程序阻塞&#xff0c;等待數據準備好。 如果數據沒有準備好&#xff0c;一直等待….數據準備好了&#xff0c;從內核拷貝到用戶空間,IO函數返回成功指示。 我們 第一…

改變導航欄上邊的狀態欄顏色

#pragma mark - 改變狀態欄顏色 -(UIStatusBarStyle)preferredStatusBarStyle{ return UIStatusBarStyleLightContent; }轉載于:https://www.cnblogs.com/block123/p/5195203.html

PIT和TestNG突變測試簡介

變異測試是一種技術&#xff0c;它可以發現測試未涵蓋代碼的哪些部分。 它類似于代碼覆蓋范圍 &#xff0c;但變異測試不限于在測試期間執行給定行的事實。 這個想法是修改生產代碼&#xff08;引入突變&#xff09;&#xff0c;這應該改變其行為&#xff08;產生不同的結果&am…

JavaScript內存管理——優化內存占用

使用具備垃圾收集機制的語言編寫程序&#xff0c;開發人員一般不必操心內存管理的問題。但是&#xff0c;JavaScript在進行內存管理及垃圾收集時面臨的問題還是有點與眾不同。其中最主要的一個問題&#xff0c;就是分配給Web瀏覽器的可用內存數量通常要比分配給桌面應用程序的少…

Java 8的烹調方式– Lambda項目

什么是project lambda &#xff1a;Project lambda是用于以Java語言語法啟用lambda表達式的項目。 Lambda表達式是功能編程語言&#xff08;如lisp&#xff09;中的主要語法。 Groovy將是支持lambda表達式&#xff08;也稱為閉包&#xff09;的java的最接近親戚。 那么什么是la…

ffmpeg文檔38-視頻源

38 視頻源 下面是當前有效的視頻源 buffer 緩沖視頻幀&#xff0c;其可以作為濾鏡鏈圖的環節 它通常用于編程&#xff0c;特別是通過libavfilter/vsrc_buffer.h的接口。 接受如下參數&#xff1a; video_size 指定視頻尺寸&#xff0c;(同時指定width 和 height)。語法同于ffmp…

系統架構的演變 -----自 羅文浩

轉自&#xff1a;https://my.oschina.net/lwhmdj0823/blog/617713版權聲明&#xff1a;羅文浩所有摘要: 一個成熟的大型網站&#xff08;如淘寶、京東等&#xff09;的系統架構并不是開始設計就具備完整的高性能、高可用、安全等特性&#xff0c;它總是隨著用戶量的增加&#x…