spring_使用Spring跟踪应用程序异常

spring

spring

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

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

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

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

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

  • 决不
  • 积极地
  • 主动地

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

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

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

  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对象是文件,则调用文件验证。

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

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

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

spring

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值