使用ELK管理SpringBoot日志

使用ELK管理SpringBoot日志

当我们开发一个新项目的时候,一个经常遇到的问题是日志的管理。ELK栈(Elastic,Logstash,Kibana)是一个功能强大且免费的日志管理解决方案。在本文中,将为您展示如何安装、如何设置ELK,如何使用它来管理SpringBoot应用程序中的默认格式的日志。

  在本文中,我们设置了一个演示SpringBoot应用程序,并且启用了日志管理,同时使用Logstash配置把日志条目送到了Elasticsearch。

  应用程序会把日志存在一个文件中。Logstash将读取并解析日志文件并将日志条目发送给Elasticsearch实例。最后,我们将使用Kibana4(ElasticsearchWeb前端)来搜索和分析日志。

  步骤一安装Elasticsearch

  下载Elasticsearch,下载地址:https://www.elastic.co/downloads/elasticsearch  解压缩到一个路径(解压缩)

  运行Elasticsearch(bin/elasticsearch或bin/elasticsearch.bat在Windows上)  检查它是在使用curl-XGEThttp://localhost:9200运行  下面是如何操作(下面步骤是为OSX编写的,但其它操作系统大致相同)

  wgethttps://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.7.1.zip  unzipelasticsearch-1.7.1.zip  cdelasticsearch-1.7.1  bin/elasticsearch

现在,Elasticsearch应该已经在运行中了。您可以使用curl命令来验证。在单独的终端窗口中执行Elasticsearch状态页面的GET请求:  curl-XGEThttp://localhost:9200  如果一切正常,你应该得到以下结果:

{  "status":200,  "name":"Tartarus",  "cluster_name":"elasticsearch",  "version":{  "number":"1.7.1",  "build_hash":"b88f43fc40b0bcd7f173a1f9ee2e97816de80b19",  "build_timestamp":"2015-07-29T09:54:16Z",  "build_snapshot":false,  "lucene_version":"4.10.4"  },  "tagline":"YouKnow,forSearch"  }

步骤二安装InstallKibana04

下载Kibana,下载地址:https://www.elastic.co/downloads/kibana(请注意你的系统属性,下载与你系统相匹配的版本,链接给出的是OSX系统的)

解压缩文件  运行Kivana(bin/kibana)

通过把浏览器指向Kibana's来检查它是否在运行

下面是具体的做法:

wgethttps://download.elastic.co/kibana/kibana/kibana-4.1.1-darwin-x64.tar.gz  tarxvzfkibana-4.1.1-darwin-x64.tar.gz  cdkibana-4.1.1-darwin-x64  bin/kibana

将你的浏览器指向http://localhost:5601(如果页面显示正常,说明我做的很好,我们将在稍后配置它)。

步骤三安装Logstash

下载Logstash,下载地址:https://www.elastic.co/downloads/logstash

提取文件(解压缩)  wgethttps://download.elastic.co/logstash/logstash/logstash-1.5.3.zip  unziplogstash-1.5.3.zip

步骤四配置SpringBoot的日志文件

为了让Logstash传递文件到Elasticsearch,我们必须先配置SpringBoot来把日志条目存储到一个文件中。我们将建立以下传递路径:SpringBootApp——日志文件——Logstash——Elasticsearch。这里还有其它的方法可以完成同样的事情,比如配置logback来使用TCP附加器把日志发送到一个远程的Logstash,以及其它的有些配置。但我更喜欢文件方法,因为这样更简单、很自然(你可以很容易的把它添加到已存在的系统中),并且当Logstash停止工作或者Elasticearch宕机的时候,不会丢失或者破坏任何文件。

不管如何,让我们来配置SpringBoot的日志文件。最简单的方法是在application.properties中配置日志文件。添加下面一行就足够了:

logging.file=application.log  现在,SpringBoot将会在application.log中记录ERROR,WARN和INFO级别的信息,并且当信息量达到10M的时候更迭。

步骤五配置Logstash

通过配置Logstash可以了解SpringBoot的日志文件格式。这部分比较棘手。  我们需要创建一个Logstash配置文件。典型的Logstash配置文件包含三个部分:input、filter、output。每个部分包含执行相关部分处理的插件,例如:从文件中读取日志时间的文件输入插件,或者将日志时间发送到Elasticsearch的elasticseatch输出插件。

input部分定义了Logstash从哪里读取输入数据——在我们的例子中它是一个文件,所以我们将使用一个file插件multilinecodec。这基本上意味着我们的输入文件可能每个条目有多行。

  Input部分  下面是输入部分的配置:

 input{  file{  type=>"java"  path=>"/path/to/application.log"  codec=>multiline{  pattern=>"^%{YEAR}-%{MONTHNUM}-%{MONTHDAY}%{TIME}.*"  negate=>"true"  what=>"previous"  }  }  }

  我们将会用到file插件。  type被设置为java——这只是额外的元数据,以备将来使用多种类型的日志文件。  path是日志文件的绝对路径。它必须是绝对的——Logstash对这点很严格。

我们使用multilinecodec意味着多个行可能对应着一个日志事件。  为了检测在逻辑上与前一行分组的行,我们使用检测模式:  pattern=>"^%{YEAR}-%{MONTHNUM}-%{MONTHDAY}%{TIME}.*"→每个新的日志事件都需要以日期开始。  negate=>"true"→如果它不以日期开始......  what=>"previous"→...然后,它应该与前一行分组。  文件输入插件,就像配置的一样,将会跟踪日志文件(例如:只读取文件末尾的新条目)。所以,测试的时候,为了让Logstash读取某些内容,您需要生成新的日志条目。

  Filter部分  Filter部分包含对日志时间执行中间处理的插件。在我们的例子中国,事件可以是根据上述规则分组的单个日志行货多行日志事件。在Filter部分,我们会做几件事情:

  如果一个日志事件包含堆栈跟踪,我们会标记它。这将有助于我们在后面寻找我们所期望的信息。解析出时间戳,日志等级,pid,线程,类名称(记录器实际)和日志信息。指定时间戳的区域和格式——Kibana将会用到它来进行实践的基本搜索。

上面提及的SpringBoot日志格式的过滤器部分看起来是这样的:  filter{  #Ifloglinecontainstabcharacterfollowedby'at'thenwewilltagthatentryasstacktrace  if[message]=~"\tat"{  grok{  match=>["message","^(\tat)"]  add_tag=>["stacktrace"]  }  }  #GrokkingSpringBoot'sdefaultlogformat  grok{  match=>["message",  "(?%{YEAR}-%{MONTHNUM}-%{MONTHDAY}%{TIME})%{LOGLEVEL:level}%{NUMBER:pid}---\[(?[A-Za-z0-9-]+)\][A-Za-z0-9.]*\.(?[A-Za-z0-9#_]+)\s*:\s+(?.*)",  "message",  "(?%{YEAR}-%{MONTHNUM}-%{MONTHDAY}%{TIME})%{LOGLEVEL:level}%{NUMBER:pid}---.+?:\s+(?.*)"  ]  }  #Parsingouttimestampswhichareintimestampfieldthankstopreviousgroksection  date{  match=>["timestamp","yyyy-MM-ddHH:mm:ss.SSS"]  }  }

说明  if[message]=~"\tat"→如果消息包含后面跟着at的tab字符(这是ruby语法),那么......  ...使用grok插件来标记堆栈踪迹:  match=>["message","^(\tat)"]→当message匹配行的开头,后面跟着tab,之后跟着at,然后是...  add_tag=>["stacktrace"]→...用stacktrace标签标记事件。  使用grok插件进行常规的SpringBoot日志消息解析:  第一种模式提取时间戳,级别,pid,线程,类名(实际上是记录器名称)和日志消息。  不幸的是,某些日志消息没有类似于类名的记录器名称(例如,Tomcat日志),因此第二个模式将跳过记录器/类字段并解析出时间戳,级别,pid,线程和日志消息。  使用date插件解析并设置事件日期:  match=>["timestamp","yyyy-MM-ddHH:mm:ss.SSS"]→timestamp字段(早先grokked)包含指定格式的时间戳

  Output部分  Output部分包含将事件数据发送到特定目标的输出插件。产出是事件管道的最后阶段。我们将把日志事件发送到stdout(控制台输出,用于调试)和Elasticsearch。  与Filter分相比,Output部分非常简单:

  filter{  #Ifloglinecontainstabcharacterfollowedby'at'thenwewilltagthatentryasstacktrace  if[message]=~"\tat"{  grok{  match=>["message","^(\tat)"]  add_tag=>["stacktrace"]  }  }  #GrokkingSpringBoot'sdefaultlogformat  grok{  match=>["message",  "(?%{YEAR}-%{MONTHNUM}-%{MONTHDAY}%{TIME})%{LOGLEVEL:level}%{NUMBER:pid}---\[(?[A-Za-z0-9-]+)\][A-Za-z0-9.]*\.(?[A-Za-z0-9#_]+)\s*:\s+(?.*)",  "message",  "(?%{YEAR}-%{MONTHNUM}-%{MONTHDAY}%{TIME})%{LOGLEVEL:level}%{NUMBER:pid}---.+?:\s+(?.*)"

  ]

  }

  #Parsingouttimestampswhichareintimestampfieldthankstopreviousgroksection

  date{

  match=>["timestamp","yyyy-MM-ddHH:mm:ss.SSS"]

  }

  }

  说明:

  我们正在使用多个输出:stdout和elasticsearch。

  stdout{...}→stdout插件将日志事件打印到标准输出(控制台)。

  codec=>rubydebug→使用类似JSON格式的漂亮打印事件。

  elasticsearch{...}→elasticsearch插件将日志事件发送到Elasticsearch服务器。

  host=>"127.0.0.1"→Elasticsearch所在的主机名在我们的例子中是localhost。

  Update5/9/2016:在编写此更新时,Logstash的elasticsearch输出插件的最新版本使用hosts配置参数,而不是host上面的示例中所示。新参数将一组主机(例如elasticsearchcluster)作为值。换句话说,如果您正在使用最新的Logstash版本,请按如下所示配置elasticsearch输出插件:

  elasticsearch{

  hosts=>["127.0.0.1"]

  }

  把各个部分放在一起

  最后,三个部分——input,filter和output需要复制粘贴到一起并保存在Logstash.conf配置文件中。一旦配置文件就位,并且Elasticsearch运行,我们可以运行Logstash:

  elasticsearch{

  hosts=>["127.0.0.1"]

  }

  如果一切顺利,Logstash正在传递日志时间到Elasticsearch。

  步骤六配置Kibana

  现在是我们再次访问KibanawebUI的时候了,我们已经在第二部中启动了,它应该在http://localhost:5601上运行。

  首先,您需要将Kibana指向您选择的elasticsearch索引。Logstash创建索引的名称模式是:logstash-YYYY.MM.DD。在Kibana设置——索引中配置索引。

  索引包含基于时间的事件(选择此项)

  使用事件时间创建索引名称(选择此项)

  索引模式间隔:日

  索引名称或模式:[logstash-]YYYY.MM.DD

  点击“创建索引”

  现在,点击“Discover”标签。在我看来,“Discover”选项卡在Kibana中的确命名不正确-它应该被标记为“Search”而不是“Discover”,因为它允许您执行新的搜索并保存/管理它们。日志事件现在应该显示在主窗口中。如果不是,则再次检查屏幕右上角的时间段过滤器。默认表格默认有2列:Time和_source。为了使列表更有用,我们可以配置显示的列。从左侧的选择菜单中选择级别,类别和日志消息。

  好的!您现在已准备好使用ELK堆栈来控制日志,并开始自定义和调整日志管理配置。

  您可以从这里下载这篇文章时使用的示例应用程序:https://github.com/knes1/todo。它已被配置为将日志写入文件,并具有上述的Logstash配置(尽管需要调整绝对路径logstash.conf)。

推荐阅读更多精彩内容