javascript
spring 异常捕获异常_使用Spring跟踪异常–第2部分–委托模式
spring 異常捕獲異常
在上一個博客中 ,我開始談論需要弄清您的應用程序在生產環境中是否行為異常。 我說過,監視應用程序的一種方法是檢查其日志文件是否存在異常,如果發現異常,則采取適當的措施。 顯然,日志文件可能會占用數百兆的磁盤空間,用手監視它們是不切實際的,而且很無聊。
我還說過,有幾種方法可以自動監視日志文件,并提出了一個基于Spring的實用程序,該實用程序每天都會梳理日志文件,并在發現任何異常時向您發送電子郵件。
我只介紹了第一類: FileLocator ,它將在目錄及其子目錄中搜索日志文件。 找到一個后,將其傳遞給FileValidator 。
FileValidator必須對文件執行多項檢查。 首先,它必須確定文件是否足夠年輕以檢查異常。 想法是,由于應用程序定期運行,因此沒有必要檢查目錄中找到的所有文件是否存在錯誤,我們只希望自應用程序上次運行以來已創建或更新的文件。
這種設計的思想是將同一個接口的多個實現組合在一起,創建一個負責驗證文件的聚合對象。 鷹眼的讀者會注意到,這是Delegate Pattern的實現。
在上面的類圖中,將RegexValidator和FileAgeValidator實例注入FileValidator ,并將其驗證任務委托給這些類。
依次輪流使用它們并首先處理Validator接口…
public interface Validator { /** The validation method */ public <T> boolean validate(T obj); }上面的代碼演示了Validator接口的簡單性。 它具有單個方法validate(T obj) ,這是一個泛型方法調用,可以提高此接口的靈活性和可重用性。 當類實現此接口時,它們可以更改輸入參數類型以適合自己的目的……如下面的第一個實現所示:
public class RegexValidator implements Validator { private static final Logger logger = LoggerFactory.getLogger(RegexValidator.class); private final Pattern pattern; public RegexValidator(String regex) { pattern = Pattern.compile(regex); logger.info("loaded regex: {}", regex); } @Override public <T> boolean validate(T string) { boolean retVal = false; Matcher matcher = pattern.matcher((String) string); retVal = matcher.matches(); if (retVal && logger.isDebugEnabled()) { logger.debug("Found error line: {}", string); } return retVal; } }RegexValidator類具有采用正則表達式字符串的單個參數構造函數。 然后將其轉換為Pattern實例變量,并由validate(T string)方法使用它來測試String輸入參數是否與原始構造函數arg正則表達式匹配。 如果是這樣,那么validate(T string)將返回true。
@Service public class FileAgeValidator implements Validator { @Value("${max.days}") private int maxDays; /** * Validate the age of the file. * * @see com.captaindebug.errortrack.Validator#validate(java.lang.Object) */ @Override public <T> boolean validate(T obj) { File file = (File) obj; Calendar fileDate = getFileDate(file); Calendar ageLimit = getFileAgeLimit(); boolean retVal = false; if (fileDate.after(ageLimit)) { retVal = true; } return retVal; } private Calendar getFileAgeLimit() { Calendar cal = Calendar.getInstance(); cal.add(Calendar.DAY_OF_MONTH, -1 * maxDays); return cal; } private Calendar getFileDate(File file) { long fileDate = file.lastModified(); Calendar when = Calendar.getInstance(); when.setTimeInMillis(fileDate); return when; } }第二個Validator(T obj)實現是FileAgeValidator顯示的FileAgeValidator ,要注意的第一件事是整個過程由max.days屬性驅動。 這被注入到FileAgeValidator的@Value注釋的maxDays實例變量中。 此變量確定文件的最長期限(天)。 該文件早于該值,然后validate(T obj)將返回false。
在此實現中, validate(T obj) 'obj'參數被強制轉換為File對象,然后將其用于將文件的日期轉換為Calendar對象。 下一行代碼將maxDays變量轉換為第二個Calendar對象: ageLimit 。 然后將ageLimit與fileDate對象進行比較。 如果fileDate在ageLimit之后,則validate(T obj)返回true。
validator程序包中的最后一個類是FileValidator ,如上所示,它將很多職責委托給其他三個聚合的驗證程序:一個FileAgeValidator和兩個RegexValidator 。
@Service public class FileValidator implements Validator { private static final Logger logger = LoggerFactory.getLogger(FileValidator.class); @Value("${following.lines}") private Integer extraLineCount; @Autowired @Qualifier("scan-for") private RegexValidator scanForValidator; @Autowired(required = false) @Qualifier("exclude") private RegexValidator excludeValidator; @Autowired private FileAgeValidator fileAgeValidator; @Autowired private Results results; @Override public <T> boolean validate(T obj) { boolean retVal = false; File file = (File) obj; if (fileAgeValidator.validate(file)) { results.addFile(file.getPath()); checkFile(file); retVal = true; } return retVal; } private void checkFile(File file) { try { BufferedReader in = createBufferedReader(file); readLines(in, file); in.close(); } catch (Exception e) { logger.error("Error whilst processing file: " + file.getPath() + " Message: " + e.getMessage(), e); } } @VisibleForTesting BufferedReader createBufferedReader(File file) throws FileNotFoundException { BufferedReader in = new BufferedReader(new FileReader(file)); return in; } private void readLines(BufferedReader in, File file) throws IOException { int lineNumber = 0; String line; do { line = in.readLine(); if (isNotNull(line)) { processLine(line, file.getPath(), ++lineNumber, in); } } while (isNotNull(line)); } private boolean isNotNull(Object obj) { return obj != null; } private int processLine(String line, String filePath, int lineNumber, BufferedReader in) throws IOException { if (canValidateLine(line) && scanForValidator.validate(line)) { List<String> lines = new ArrayList<String>(); lines.add(line); addExtraDetailLines(in, lines); results.addResult(filePath, lineNumber, lines); lineNumber += extraLineCount; } return lineNumber; } private boolean canValidateLine(String line) { boolean retVal = true; if (isNotNull(excludeValidator)) { retVal = !excludeValidator.validate(line); } return retVal; } private void addExtraDetailLines(BufferedReader in, List<String> lines) throws IOException { for (int i = 0; i < extraLineCount; i++) { String line = in.readLine(); if (isNotNull(line)) { lines.add(line); } else { break; } } } }FileValidator的validate(T obj)將File作為參數。 它的首要職責是驗證文件的年齡。 如果該驗證器返回true,則它通知Report類它已找到一個新的有效文件。 然后,它檢查文件中是否有錯誤,并將找到的任何內容添加到Report實例。 它通過使用BufferedReader依次檢查文件的每一行來做到這一點。 在檢查某行是否包含錯誤之前,它會檢查該行是否未從檢查中排除-即,它與排除的異常或我們不感興趣的異常不匹配。如果該行與排除的異常不匹配異常,然后使用RegexValidator的第二個實例檢查是否需要查找異常。 如果該行確實包含錯誤,則會將其添加到List<String>對象。 然后從添加到列表的文件中讀取以下幾行,以使報告更具可讀性。
因此,文件解析將繼續進行,一次檢查每一行以查找錯誤并建立報告,以便稍后進行處理。
該封面的驗證文件使用委托模式添加了發現到Report任何異常,但是此Report對象如何工作? 我沒有提到它,輸出是如何產生的? 下次再說。
- 該博客的代碼可在Github上找到: https : //github.com/roghughe/captaindebug/tree/master/error-track 。
翻譯自: https://www.javacodegeeks.com/2014/03/tracking-exceptions-with-spring-part-2-delegate-pattern.html
spring 異常捕獲異常
總結
以上是生活随笔為你收集整理的spring 异常捕获异常_使用Spring跟踪异常–第2部分–委托模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Opera 浏览器宣布联名 Chess.
- 下一篇: 库迪狂飙300天,现在加盟还能赚到钱吗?