您的位置:首页 > 其它

window10下ELK环境搭建与实战

2018-03-15 13:04 495 查看

需求

    多环境多服务日志无法统一查看,需要连接到不同的机器不同的目录通过GREP命令查看日志,过滤日志,定位问题非常麻烦。所以需要一种工具能把分布在不同机器目录的日志集中到一起,方便查询排错等。    针对上述需求在各种社区搜索以后,发现开源实时日志分析ELK平台能够完美的解决,ELK由ElasticSearch、Logstash和Kiabana三个开源工具组成。官方网站:https://www.elastic.co/products

Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。

Logstash是一个日志收集过滤工具,通过配置input、output、filter等实现日志的导入过滤和导出,支持不同数据源的导入导出。
Kibana 是一个开源的分析和可视化平台,旨在与 Elasticsearch 合作。Kibana 提供搜索、查看和与存储在 Elasticsearch 索引中的数据进行交互的功能。开发者或运维人员可以轻松地执行高级数据分析,并在各种图表、表格和地图中可视化数据。

ELK下载安装

    下载地址:https://www.elastic.co/products
    文件:logstash-6.2.2.zip  
              elasticsearch-6.2.2.zip
              kibana-6.2.2-windows-x86_64.zip

      安装环境:window 10
logstash安装
    解压logstash-6.2.2.zip到指定目录,把logstash-6.2.2/bin加入环境变量,创建helloworld.conf,输入以下内容input{
    stdin{}
}
output{
    stdout{
        codec=>rubydebug
    }
}    执行命令:logstash -f  helloworld.conf 启动完毕后输入helloworld等到如下结果,证明启动成功:



elasticsearch安装

    解压 elasticsearch-6.2.2.zip到指定目录(注意不要解压到带有空格名称的目录,启动可能会报错),把elasticsearch-6.2.2/bin加入环境变量,打开powershell直接输入elasticsearch用默认配置启动(默认传输端口为9300,接受HTTP请求的端口为9200),打开http://localhost:9200/



Kibana 安装

       解压 kibana-6.2.2-windows-x86_64.zip到指定目录,把kibana-6.2.2-windows-x86_64/bin加入环境变量,在powershell中执行Kibana直接启动,打开http://localhost:5601/访问即可。可通过修改kibana-6.2.2-windows-x86_64\config\kibana.yml配置指定elasticsearch地址等。

实战

    通过logstash的input=>file读取指定日志文件,通过output=>elasticsearch写入的elasticsearch中,进入kibana查看日志情况。
    日志是通过logback写入log的,logback的pattern为 %d [%t - %X{traceNo}] %-5level %c{1} - %m%n2018-03-14 11:03:43,078 [Thread-5 - YOdmYjIfXUeZ] INFO c.n.f.c.s.i.AppTradeQueryServiceImpl - fsProductQueryService findProductDetail res:ApiResultResponse[apiResult=<null>,retState=SUCCESS,retCode=000000,retMsg=查询成功,extAttrs=<null>]
2018-03-14 11:03:43,078 [Thread-5 - YOdmYjIfXUeZ] ERROR c.n.f.c.s.i.AppTradeQueryServiceImpl - fsProductQueryService findProductDetail res is null
2018-03-14 11:03:43,079 [Thread-5 - YOdmYjIfXUeZ] ERROR c.n.f.w.r.LogExceptionOnlyResolver - 产品服务异常
[YOdmYjIfXUeZ] com.nicaifu.fundSaleApp.core.exception.RemoteInvokeException: 产品服务异常
[YOdmYjIfXUeZ] at com.nicaifu.fundSaleApp.core.service.impl.AppTradeQueryServiceImpl.saleTargetQuery(AppTradeQueryServiceImpl.java:78)
[YOdmYjIfXUeZ] at com.nicaifu.fundSaleApp.web.expose.AppTradeQueryServiceExpose.saleTargetQuery(AppTradeQueryServiceExpose.java:32)
[YOdmYjIfXUeZ] at com.nicaifu.fundSaleApp.web.expose.AppTradeQueryServiceExpose$$FastClassBySpringCGLIB$$f949f9cf.invoke(<generated>)
[YOdmYjIfXUeZ] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
[YOdmYjIfXUeZ] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
[YOdmYjIfXUeZ] at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
[YOdmYjIfXUeZ] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
[YOdmYjIfXUeZ] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
[YOdmYjIfXUeZ] at com.nicaifu.fundSaleApp.web.expose.AppTradeQueryServiceExpose$$EnhancerBySpringCGLIB$$1a578b7a.saleTargetQuery(<generated>)
[YOdmYjIfXUeZ] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[YOdmYjIfXUeZ] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[YOdmYjIfXUeZ] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[YOdmYjIfXUeZ] at java.lang.reflect.Method.invoke(Method.java:497)
[YOdmYjIfXUeZ] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
[YOdmYjIfXUeZ] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
[YOdmYjIfXUeZ] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116)
[YOdmYjIfXUeZ] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
[YOdmYjIfXUeZ] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
[YOdmYjIfXUeZ] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
[YOdmYjIfXUeZ] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
[YOdmYjIfXUeZ] at org.springframework.web.servlet.DispatcherServlet.do
aedc
Service(DispatcherServlet.java:897)
[YOdmYjIfXUeZ] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
[YOdmYjIfXUeZ] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
[YOdmYjIfXUeZ] at org.springframework.boot.web.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:90)
[YOdmYjIfXUeZ] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
[YOdmYjIfXUeZ] at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:108)
[YOdmYjIfXUeZ] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
[YOdmYjIfXUeZ] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
[YOdmYjIfXUeZ] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
[YOdmYjIfXUeZ] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
[YOdmYjIfXUeZ] at java.lang.Thread.run(Thread.java:745)
2018-03-14 11:03:43,081 [Thread-5 - YOdmYjIfXUeZ] INFO c.n.c.a.ExceptionFilterUtils - check /data/appdatas/cat/exceptionAppender.properties
    编写logstash的配置文件test.conf用户解析以上配置input {
file {
path => "D:/info.log"
start_position => "beginning" #从文件开始处读写
codec => multiline{
    pattern => "^\s*%{TIMESTAMP_ISO8601}" #正则表达式,用来做规则匹配
                    negate => true #negate是对pattern的结果做判断是否匹配,默认值是false代表匹配,而true代表不匹配,这里并没有反,因为negate本身是否定的意思,在这里就是不以大括号开头的内容才算符合条件,后续才会进行合并操作
    what => previous #next或者previous二选一,previous代表codec将把匹配内容与之前的内容合并,next代表之后的内容
}
}
# stdin {} #可以从标准输入读数据
}

filter {

#定义数据的格式
grok {
match => { "message" => "\s*%{TIMESTAMP_ISO8601:time}\s*\[%{DATA:thread}\ -%{DATA:traceNo}\]\s*%{LOGLEVEL:level}\s*%{DATA:class}\ -\s*(?<info>([\s\S]*))"}
}

#定义时间戳的格式
date {
match => ["time", "yyyy-MM-dd HH:mm:ss,SSS"]
    target => "@timestamp"
locale => "cn"
}

mutate {
gsub => [ "info", "\r", "" ]
}

mutate {
gsub => [ "message", "\r", "" ]
}

mutate {
gsub => [ "traceNo", " ", "" ]
}

}

output {
elasticsearch {
hosts => "127.0.0.1"
}

#输出到stdout
#stdout { codec => rubydebug }
}    input标签:定义的文件的输入源,file=>path指定文件的路径,codec => multiline主要用于解决打印异常时的换行情况,通过正则匹配后把下一行拼接到上一行后面(多线程环境下好像有问题)。
    filter标签:对数据进行匹配过滤,常用的匹配插件为grop,定义匹配规则。mutate插件可以对匹配到的结果进行一些操作,date指定日期格式通过target把time内容放到@timestamp中去
    output标签:通过elasticsearch=>hosts(不是host)指定elasticsearch 的地址。

    先按照上文操作步骤启动elasticsearch,然后执行logstash -f  test.conf后启动日志分析,最后启动kibana查询日志导入结果,如下图。
先创建需要查看的index,可用正在匹配



 创建成功后,得到下图(左侧为解析文件时定义的字段名,右侧根据左侧字段名选择显示的列)



接下来的工作

通过应用的logback直接输入日志到redis,logstash直接用input接受redis中的日志信息
多文件解析,不同的文件定义不同的index,导入到elasticsearch 
kibana中图表的应用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息