javascript
使用Spring跟踪应用程序异常
幾周前,一位同事要求我花一個星期的時間做后援,因?yàn)樗枰粋€掩護(hù),而他度過了一個賺錢的假期,而他找不到其他人。 當(dāng)我剛完成一個特別復(fù)雜的編碼項(xiàng)目并感到有些疲倦時,我說“是”。 畢竟,改變對我有好處。
工作的一部分包括監(jiān)視一組相當(dāng)關(guān)鍵的支持流程,以查看它們的執(zhí)行情況以及它們是否出錯。
我們的開發(fā)人員花費(fèi)大量時間和精力在我們的應(yīng)用程序中添加日志記錄,以證明它可以正常工作并找出發(fā)生異常時出了什么問題。 這些日志文件通常用于告訴我們我們的應(yīng)用程序每天的運(yùn)行狀況有多好。
我忽略了其他技術(shù),例如通過選擇的任何方法(例如HTTP或JMX)向應(yīng)用程序添加探針。 這些提供有關(guān)您的應(yīng)用程序的即時信息,而不是此處討論的第二級監(jiān)視。
至少有三種監(jiān)視日志文件的方式:
- 決不
- 積極地
- 主動地
“從不”表示它的意思。 我敢打賭,有些應(yīng)用程序會上線,似乎永遠(yuǎn)不會失敗,也不會被檢查。
“反應(yīng)式”策略非常普遍; Doncaster的Smith夫人打電話給她,抱怨說她試圖買一雙新鞋時網(wǎng)站崩潰了。 她被起訴了兩次,從未收到任何鞋子。 在這個傳統(tǒng)的公司中,DEV和OPS的角色完全分開,研究問題的開發(fā)人員要求OPS記錄事件發(fā)生的時間和日期。 當(dāng)然,開發(fā)人員會獲取日志中完全不相關(guān)的部分,并且不得不重新請求正確的部分-幾次。 到那時,已經(jīng)過去了幾個星期,史密斯太太很生氣。 日志最終到達(dá),問題得以解決。
在這種“反應(yīng)性”場景中,我假設(shè)當(dāng)開發(fā)人員在沒有信任或允許接觸實(shí)時服務(wù)器的情況下,這就是那些公司之一。 這太普遍了,我們大多數(shù)人都會去過那里。 開發(fā)人員應(yīng)該可以使用實(shí)時系統(tǒng)。 但是,作為開發(fā)人員,您應(yīng)該記住在處理實(shí)時系統(tǒng)時有兩個黃金法則:
“主動”是指定期檢查日志文件:每天,每小時或任何時間。 即使您的應(yīng)用程序包含大量的JMX,http或其他探針,也無法保證它們會發(fā)現(xiàn)問題。 探測只能探測您告訴他們要探測的內(nèi)容,其他任何問題都無法解決。
回到我的支持上來……是出于某種(可能是歷史原因)的原因,此監(jiān)視的大部分內(nèi)容包括使用一組記錄的“ grep”命令通過一些剪切和粘貼手動檢查日志文件中的錯誤。 如果您將花費(fèi)的時間加在重復(fù)的剪切和粘貼工作上,那么我可以確認(rèn),它每周大約消耗?人日。
這讓我開始思考……我真的不喜歡做這種任務(wù)。 我不太擅長,它是手動的,容易出錯,重復(fù)并且很無聊。 每周要花費(fèi)?個工作日來完成這項(xiàng)任務(wù),顯然會節(jié)省成本,只要不花時間在使他的解決方案完美無缺上。 那么,有哪些選擇呢?
如果您從專業(yè)的角度來看,那么Splunk就是可以監(jiān)視來自多種來源(例如syslog守護(hù)程序)的消息的工具。
這意味著向Splunk發(fā)送錯誤的一種簡單方法是簡單地設(shè)置Log4j syslog附加程序,但這超出了本博客的范圍……
在快速而骯臟的范圍內(nèi),您可以非常Swift地編寫一個shell腳本來執(zhí)行一些“ grep”命令,將結(jié)果寫入文件并將其郵寄到您的Unix郵箱。
然后我想到了中間立場。 編寫一個包含盡可能多的通用可重用類的Spring應(yīng)用程序有多困難,它會定期運(yùn)行以檢查大量錯誤日志并通過電子郵件將結(jié)果發(fā)送給您。 對于這種事情,電子郵件是件好事,因?yàn)槟ǔ3鲇诹?xí)慣閱讀它們。
入門
在任何這樣的項(xiàng)目中,都有一些無形的第一步可以推動整個過程。 它們構(gòu)成了對您需要編寫哪些類才能發(fā)布此“東西”的問題的答案? 有很多方法可以確定需要編寫哪些類,例如,使用UML,快速原型設(shè)計或測試驅(qū)動設(shè)計之類的正式設(shè)計技術(shù),憑空挑選它們(膽怯)。 在每種情況下,您真正??要做的就是提出一些要求,從中彈出某些類的名稱。 例如,在這種情況下,我需要:
這拋出了幾個類的名稱。 我需要一個FileLocator , FileValidator , RegexValidator , FileAgeValidator和一個Report 。
鑒于以上列表中多次出現(xiàn)“ Validator”一詞,這表明我可以使用一個接口(大概稱為Validator并創(chuàng)建多個實(shí)現(xiàn)來執(zhí)行上述驗(yàn)證任務(wù)。 然后可以將這些實(shí)現(xiàn)組合在一起以創(chuàng)建一個一致的應(yīng)用程序。
請注意,這只是想法的初步列表。 如果看一下代碼,將找不到名為Report的類,將其重命名為Results并進(jìn)行重構(gòu)以創(chuàng)建Formatter接口, TextFormatter和HtmlFormatter類以及Publisher接口和EmailPublisher類。
就定期運(yùn)行此功能而言,有兩種選擇。 首先,您可以將Java代碼與一個簡單的腳本一起編寫以調(diào)用它,并將其提供給Unix機(jī)器crontab。 沒關(guān)系,但這意味著該應(yīng)用程序無法在Windows上運(yùn)行,并且只能作為獨(dú)立應(yīng)用程序運(yùn)行。 這可能是一件大事,所以可以選擇使用Spring和Quartz時間表。 使制定Cron時間表相當(dāng)簡單。
至于報告的電子郵件發(fā)送; 再次,Spring提供了一個非常好的電子郵件模板,可以簡化Java電子郵件類的使用。
好的,這就是起點(diǎn):一組模糊的類想法可以以某種松散耦合的方式鏈接在一起以創(chuàng)建我們的應(yīng)用程序。 如果您走了一條正式路線,那么您可能想花時間記錄所有這些內(nèi)容,甚至可能制作一個類圖,然后將其添加到Word文檔中,并進(jìn)行多次審查,直到一切都定下來。 但是,我不必為此煩惱……
配置應(yīng)用程序
與任何應(yīng)用程序一樣,需要弄清楚我們將如何設(shè)置通常是整個屬性值的數(shù)組以及應(yīng)用程序如何使用它們。 該應(yīng)用程序通常由src/main/resources目錄中的app.properties文件驅(qū)動。
# The path to the log file directory to scan for errors scan.in=/Library/Tomcat/logs # A regex defining what to look for - or what not to include scan.for=^.*Exception.* exclude=^.*IllegalStateException.* # The number of following lines to add to the report following.lines=10 # Where to email the report email.to=info@captaindebug.com # The max age of a file in days max.days=1000我們感興趣的第一個屬性是scan.in屬性。 這是我們Web服務(wù)器日志目錄的位置,用作下一節(jié)概述的FileLocator類的起點(diǎn)。
搜索文件
在編寫FileLocator我超出了要求,并有意進(jìn)行了一些“鍍金” 。
鍍金確實(shí)是個壞主意。 您應(yīng)該只編寫足以滿足功能要求的代碼,即可以完成工作。 在這種情況下,作為一個博客……我的博客,我可以說它符合記錄我以前使用過多次的技術(shù)的非功能性要求,以此來證明它是合理的。
以下代碼不僅在指定的日志文件目錄中搜索日志文件,還搜索所有/任何子目錄。
@Service public class FileLocator { private static final Logger logger = LoggerFactory.getLogger(FileLocator.class); @Value("${scan.in}") private String scanIn; @Autowired @Qualifier("fileValidator") private Validator validator; /** Search for the files requested */ public void findFile() { logger.info("Searching in... {}", scanIn); File file = createFile(scanIn); search(file); } @VisibleForTesting File createFile(String name) { return new File(name); } private void search(File file) { if (file.isDirectory()) { logger.debug("Searching directory: {}", file.getName()); File[] files = file.listFiles(); searchFiles(files); } else { logger.debug("Validating file: {}", file.getName()); validator.validate(file); } } private void searchFiles(File[] files) { for (File file : files) { search(file); } } }上面的代碼使用了古老的遞歸技術(shù)來搜索日志文件。 主要入口是findFile() 。 它通過Spring @Value注釋的scanIn實(shí)例變量創(chuàng)建一個File對象,并將其傳遞給search()方法。 然后,它檢查此對象是否為目錄,如果是,它將獲取目錄中的所有文件,并循環(huán)調(diào)用列表中每個File對象的search() 。 如果目錄檢查顯示File對象是文件,則調(diào)用文件驗(yàn)證。
到目前為止,到目前為止,使用應(yīng)用程序的第一類,我們現(xiàn)在可以搜索日志文件目錄; 但是,如果您想知道找到文件后會發(fā)生什么,則必須等到下一個博客發(fā)布為止。
最后一個想法:您是否需要調(diào)查系統(tǒng)中的每個錯誤? 有一句古老的哲學(xué)名言:如果一棵樹在森林中倒下而沒有人聽到,它還能發(fā)出聲音嗎? 同樣,如果您的應(yīng)用程序引發(fā)異常并且用戶不受影響,那么它仍然是錯誤嗎? 您需要花費(fèi)時間進(jìn)行調(diào)查嗎? 讓我知道你的想法?
- 該博客的代碼可在Github上找到: https : //github.com/roghughe/captaindebug/tree/master/error-track 。
翻譯自: https://www.javacodegeeks.com/2014/03/tracking-application-exceptions-with-spring.html
總結(jié)
以上是生活随笔為你收集整理的使用Spring跟踪应用程序异常的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 哪种面粉适合烙饼 什么面粉适合烙饼
- 下一篇: 斯塔克大厦在什么地方 斯塔克大厦的简介