几周前,一位同事要求我花一个星期的时间做后援,因为他需要一个掩护,而他度过了一个赚钱的假期,而他找不到其他人。 当我刚完成一个特别复杂的编码项目并感到有些疲倦时,我说“是”。 毕竟,改变对我有好处。

工作的一部分包括监视一组相当关键的支持流程,以查看它们的执行情况以及它们是否出错。

我们的开发人员花费大量时间和精力在我们的应用程序中添加日志记录,以证明它可以正常工作并找出发生异常时出了什么问题。 这些日志文件通常用于告诉我们我们的应用程序每天的运行状况有多好。

我忽略了其他技术,例如通过选择的任何方法(例如HTTP或JMX)向应用程序添加探针。 这些提供有关您的应用程序的即时信息,而不是此处讨论的第二级监视。

至少有三种监视日志文件的方式:

  • 决不
  • 积极地
  • 主动地

“从不”表示它的意思。 我敢打赌,有些应用程序会上线,似乎永远不会失败,也不会被检查。

“反应式”策略非常普遍; Doncaster的Smith夫人打电话给她,抱怨说她试图买一双新鞋时网站崩溃了。 她被起诉了两次,从未收到任何鞋子。 在这个传统的公司中,DEV和OPS的角色完全分开,研究问题的开发人员要求OPS记录事件发生的时间和日期。 当然,开发人员会获取日志中完全不相关的部分,并且不得不重新请求正确的部分-几次。 到那时,已经过去了几个星期,史密斯太太很生气。 日志最终到达,问题得以解决。

在这种“反应性”场景中,我假设当开发人员在没有信任或允许接触实时服务器的情况下,这就是那些公司之一。 这太普遍了,我们大多数人都会去过那里。 开发人员应该可以使用实时系统。 但是,作为开发人员,您应该记住在处理实时系统时有两个黄金法则:

  1. 不要破坏任何东西。
  2. 如果您确实弄坏了东西,请确保您还有其他责任。

“主动”是指定期检查日志文件:每天,每小时或任何时间。 即使您的应用程序包含大量的JMX,http或其他探针,也无法保证它们会发现问题。 探测只能探测您告诉他们要探测的内容,其他任何问题都无法解决。

回到我的支持上来……是出于某种(可能是历史原因)的原因,此监视的大部分内容包括使用一组记录的“ grep”命令通过一些剪切和粘贴手动检查日志文件中的错误。 如果您将花费的时间加在重复的剪切和粘贴工作上,那么我可以确认,它每周大约消耗½人日。

这让我开始思考……我真的不喜欢做这种任务。 我不太擅长,它是手动的,容易出错,重复并且很无聊。 每周要花费½个工作日来完成这项任务,显然会节省成本,只要不花时间在使他的解决方案完美无缺上。 那么,有哪些选择呢?

如果您从专业的角度来看,那么Splunk就是可以监视来自多种来源(例如syslog守护程序)的消息的工具。

这意味着向Splunk发送错误的一种简单方法是简单地设置Log4j syslog附加程序,但这超出了本博客的范围……

在快速而肮脏的范围内,您可以非常Swift地编写一个shell脚本来执行一些“ grep”命令,将结果写入文件并将其邮寄到您的Unix邮箱。

然后我想到了中间立场。 编写一个包含尽可能多的通用可重用类的Spring应用程序有多困难,它会定期运行以检查大量错误日志并通过电子邮件将结果发送给您。 对于这种事情,电子邮件是件好事,因为您通常出于习惯阅读它们。

入门

在任何这样的项目中,都有一些无形的第一步可以推动整个过程。 它们构成了对您需要编写哪些类才能发布此“东西”的问题的答案? 有很多方法可以确定需要编写哪些类,例如,使用UML,快速原型设计或测试驱动设计之类的正式设计技术,凭空挑选它们(胆怯)。 在每种情况下,您真正​​要做的就是提出一些要求,从中弹出某些类的名称。 例如,在这种情况下,我需要:

  1. 搜索给定目录及其子目录(可能)以查找特定类型的文件。
  2. 如果找到文件,请检查其日期:是否需要搜索文件以查找错误?
  3. 如果文件足够年轻以至于无法检查,则对其进行验证,以查找异常。
  4. 如果它包含例外,是我们正在寻找的例外还是被排除在外?
  5. 如果它包含我们所需要的例外类型,则将详细信息添加到报告中。
  6. 检查完所有文件后,格式化报告以准备发布。
  7. 使用电子邮件或其他技术发布报告。
  8. 整个过程每天都会在给定的时间运行

这抛出了几个类的名称。 我需要一个FileLocatorFileValidatorRegexValidatorFileAgeValidator和一个Report

鉴于以上列表中多次出现“ Validator”一词,这表明我可以使用一个接口(大概称为Validator并创建多个实现来执行上述验证任务。 然后可以将这些实现组合在一起以创建一个一致的应用程序。

请注意,这只是想法的初步列表。 如果看一下代码,将找不到名为Report的类,将其重命名为Results并进行重构以创建Formatter接口, TextFormatterHtmlFormatter类以及Publisher接口和EmailPublisher类。

就定期运行此功能而言,有两种选择。 首先,您可以将Java代码与一个简单的脚本一起编写以调用它,并将其提供给Unix机器crontab。 没关系,但这意味着该应用程序无法在Windows上运行,并且只能作为独立应用程序运行。 这可能是一件大事,所以可以选择使用Spring和Quartz时间表。 使制定Cron时间表相当简单。

至于报告的电子邮件发送; 再次,Spring提供了一个非常好的电子邮件模板,可以简化Java电子邮件类的使用。

好的,这就是起点:一组模糊的类想法可以以某种松散耦合的方式链接在一起以创建我们的应用程序。 如果您走了一条正式路线,那么您可能想花时间记录所有这些内容,甚至可能制作一个类图,然后将其添加到Word文档中,并进行多次审查,直到一切都定下来。 但是,我不必为此烦恼……

配置应用程序

与任何应用程序一样,需要弄清楚我们将如何设置通常是整个属性值的数组以及应用程序如何使用它们。 该应用程序通常由src/main/resources目录中的app.properties文件驱动。

# 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服务器日志目录的位置,用作下一节概述的FileLocator类的起点。

搜索文件

在编写FileLocator我超出了要求,并有意进行了一些“镀金” 。

镀金确实是个坏主意。 您应该只编写足以满足功能要求的代码,即可以完成工作。 在这种情况下,作为一个博客……我的博客,我可以说它符合记录我以前使用过多次的技术的非功能性要求,以此来证明它是合理的。

以下代码不仅在指定的日志文件目录中搜索日志文件,还搜索所有/任何子目录。

@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); } }
}

上面的代码使用了古老的递归技术来搜索日志文件。 主要入口是findFile() 。 它通过Spring @Value注释的scanIn实例变量创建一个File对象,并将其传递给search()方法。 然后,它检查此对象是否为目录,如果是,它将获取目录中的所有文件,并循环调用列表中每个File对象的search() 。 如果目录检查显示File对象是文件,则调用文件验证。

到目前为止,到目前为止,使用应用程序的第一类,我们现在可以搜索日志文件目录; 但是,如果您想知道找到文件后会发生什么,则必须等到下一个博客发布为止。

最后一个想法:您是否需要调查系统中的每个错误? 有一句古老的哲学名言:如果一棵树在森林中倒下而没有人听到,它还能发出声音吗? 同样,如果您的应用程序引发异常并且用户不受影响,那么它仍然是错误吗? 您需要花费时间进行调查吗? 让我知道你的想法?

  • 该博客的代码可在Github上找到: https : //github.com/roghughe/captaindebug/tree/master/error-track 。
参考: Captain Debug的Blog博客上的JCG合作伙伴 Roger Hughes 使用Spring跟踪了应用程序异常 。

翻译自: https://www.javacodegeeks.com/2014/03/tracking-application-exceptions-with-spring.html

使用Spring跟踪应用程序异常相关推荐

  1. spring 异常捕获异常_使用Spring跟踪异常–第2部分–委托模式

    spring 异常捕获异常 在上一个博客中 ,我开始谈论需要弄清您的应用程序在生产环境中是否行为异常. 我说过,监视应用程序的一种方法是检查其日志文件是否存在异常,如果发现异常,则采取适当的措施. 显 ...

  2. 使用Spring跟踪异常–第2部分–委托模式

    在上一个博客中 ,我开始谈论需要弄清楚您的应用程序在生产环境中是否行为异常. 我说过,监视应用程序的一种方法是检查其日志文件是否存在异常,如果发现异常,则采取适当的措施. 显然,日志文件会占用数百兆的 ...

  3. Spring Security应用程序中的su和sudo

    很久以前,我从事的项目具有很强大的功能. 有两个角色:用户和主管. 主管可以以任何方式更改系统中的任何文档,而用户则更受工作流约束的限制. 当普通用户对当前正在编辑和存储在HTTP会话中的文档有疑问时 ...

  4. Spring Boot集成Druid异常discard long time none received connection.

    Spring Boot集成Druid异常 在Spring Boot集成Druid项目中,发现错误日志中频繁的出现如下错误信息: discard long time none received conn ...

  5. 利用spring aop统一处理异常和打日志

    利用spring aop统一处理异常和打日志 spring aop的概念,很早就写博客介绍了,现在在工作中真正使用. 我们很容易写出的代码 我们很容易写出带有很多try catch 和 logger. ...

  6. spring_了解Spring Web应用程序体系结构:经典方法

    spring 每个开发人员必须了解两件事: 架构设计是必要的. 精美的架构图并未描述应用程序的真实架构. 真正的体系结构是从开发人员编写的代码中找到的,如果不设计应用程序的体系结构,最终将得到一个具有 ...

  7. spring(5)构建 spring web 应用程序

    [0]README 1)本文部分文字描述转自:"Spring In Action(中/英文版)",旨在review  "spring(5)构建 spring web 应用 ...

  8. java异常——分析堆栈跟踪元素+使用异常机制的技巧

    [0]README 0.1) 本文描述+源代码均 转自 core java volume 1, 旨在理解 java异常--分析堆栈跟踪元素+使用异常机制的技巧 的相关知识: [1]分析堆栈跟踪元素相关 ...

  9. 通过Java和Spring Boot应用程序将Gmail用作SMTP服务器

    Gmail用户可以使用Gmail的SMTP服务器smtp.gmail.com从其Spring Boot应用程序发送电子邮件. 为此,让我们在应用程序中进行一些设置: 在application.prop ...

最新文章

  1. 渐进式Web应用程序的深入概述
  2. linux相对路径列出目录文件,linux – UNIX:列出目录中具有相对路径的文件
  3. 隐藏UITableView当没有数据或数据不够的时候出现的分割线.
  4. jQuery--noConflict()方法
  5. 数据结构与算法基础-数组
  6. Java实现计算器的基本功能
  7. ❤️Spring的静态、动态代理模式
  8. 前台跨站点获取session
  9. HTML5 FileAPI读取实例---(一)
  10. EndNote文献输出引用格式自定义修改与编辑界面解读
  11. 计算机u盘设备无法启动不了怎么办,U盘无法弹出说正在占用怎么办?Windows无法停止设备解决方法...
  12. Matlab中fprintf函数使用
  13. Sencha Architect4.0破解教程
  14. 实力肯定!Coremail邮件网关荣获金融信创优秀解决方案奖
  15. Win7激活后添加grub引导Linux最简单方法
  16. 计算机毕业设计JAVA高校体育场馆预约管理系统设计与实现mybatis+源码+调试部署+系统+数据库+lw
  17. torch.cuda.is_available 返回false
  18. 文件传输工具Xftp5安装图解
  19. 个人站长应该怎么设置服务器才可以无视CC攻击
  20. Nginx的核心原理解析

热门文章

  1. mysql - Docker Wordpress连接到本地主机上的数据库服务器
  2. docker下安装nacos 并使用mysql数据库
  3. Java Web开发与实战_Java Web开发技术与实战项目
  4. 算法运行时间中的对数
  5. spring框架介绍_Spring框架介绍
  6. javafx 动画没效果_通过JavaFX标注制作动画效果
  7. spock 集成测试_使用Spock Mocks进行Grails 3.3集成测试
  8. java8根据某个id删选_Java 8可选
  9. maven的中央存储库_部署到Maven中央存储库
  10. Spring Boot的Spring Data JPA示例