针对日志产生上报到es的实践

背景

日志检索是在服务治理中用来快速定位错误的一个主要方式,在没有日志检索服务之前,都是需要通过获取相应的日志来进行排查定位。这是一个传统的方式。

为了更快地提升排查效率,现在市场上出现了很多关于日志检索的框架,比较常见的是ELK的搭建方式。

在这里面logStash是相对比较重的软件,目前针对日志,采用filebeat来替换采集。

遇到问题

因为elasticsearch是使用json格式来持久化文档,为了更好地控制日志检索的效果,我们需要特别的处理日志上报的json内容,同时也可以减少在filebeat的处理。

解决步骤

logback的配置

利用logback里面的日志格式转换,来对输入的日志做json转换处理。logback-spring.xml的相关配置。

<!-- Appender to log to file in a JSON format -->

<appender name="logstash"

class="ch.qos.logback.core.rolling.RollingFileAppender">

<filter class="ch.qos.logback.classic.filter.ThresholdFilter">

<level>INFO</level>

</filter>

<file>${LOG_HOME}/logstash.json</file>

<rollingPolicy

class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

<fileNamePattern>logstash.json.%d{yyyy-MM-dd}.gz</fileNamePattern>

<maxHistory>7</maxHistory>

<totalSizeCap>1GB</totalSizeCap>

</rollingPolicy>

<encoder

class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">

<providers>

<timestamp>

<timeZone>UTC+8</timeZone>

</timestamp>

<pattern>

<pattern>

{

"date":"%d{yyyy-MM-dd HH:mm:ss.SSS}",

"level": "%level",

"service": "${springAppName:-}",

"trace": "%X{traceid:-}",

"pid": "${PID:-}",

"thread": "%thread",

"class": "%logger",

"msg": "%message",

"stack_trace": "%exception{20}"

}

</pattern>

</pattern>

</providers>

</encoder>

</appender>

特别注意

因为logback会把所有的info以上的级别都输入到es当中,这里面可能会包含类似,spring tomcat等一些框架或者组件输出的日志,但是这些日志并不是我们需要关注的,为了节省ES的存储空间,需要针对这些框架进行排除

traceId 是分布式跟踪ID 这个根据代码实现

因此,针对logback需要加上以下配置【根据实际情况调配】,事实上这个在实际的工作当中,也是需要配置的,不是说写到es的时候才需要调整

<logger name="org.apache" level="WARN">

<appender-ref ref="WARN" />

<appender-ref ref="ERROR" />

</logger>

<logger name="org.mybatis" level="ERROR">

<appender-ref ref="ERROR" />

</logger>

<logger name="org.hibernate" level="ERROR">

<appender-ref ref="ERROR" />

</logger>

<logger name="org.springframework" level="WARN">

<appender-ref ref="WARN" />

<appender-ref ref="ERROR" />

</logger>

<logger name="com.netflix" level="WARN">

<appender-ref ref="WARN" />

<appender-ref ref="ERROR" />

</logger>

针对日志的记录,在代码直接使用slf4j的log直接输出就好。

filebeat配置

filebeat.inputs:

- type: log

enabled: true

paths:

- F:\data\logs\java\spring-cloud-eureka-client\*.json

fields:

ipaddr: ${serverIP}

fields_under_root: true

processors:

- decode_json_fields:

fields: ['message']

target: ''

overwrite_keys: true

- drop_fields:

fields: ["message", "ecs", "agent", "log","input"]

setup.template.enabled: false

setup.ilm.enabled: false

output.elasticsearch:

hosts: ["192.168.70.130:9200"]

index: "client-index-%{+YYYY-MM}"

bulk_max_size: 1000

启动filebeat,需要制定启动加载的文件

生成的ES日志

{

"_index" : "client-index-2021-09",

"_type" : "_doc",

"_id" : "s53vKnwB7cmcpxLLkw5s",

"_score" : null,

"_source" : {

"@timestamp" : "2021-09-28T05:45:06.614Z",

"ipaddr" : "192.168.70.1",

"trace" : "a6582d76a4bf4c4e88f446ce338dfc44",

"pid" : "19888",

"stack_trace" : """java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: eureka-user-service

at org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:90)

at org.springframework.cloud.sleuth.instrument.web.client.feign.TraceLoadBalancerFeignClient.execute(TraceLoadBalancerFeignClient.java:78)

at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:119)

at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:89)

at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:100)

at com.sun.proxy.$Proxy149.hello(Unknown Source)

at com.zhxw.eureka.client.api.UserClient.callHello(UserClient.java:31)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:498)

at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)

at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)

at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)

at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)

at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)

at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)

at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)

at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)

at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)

Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: eureka-user-service

at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.java:483)

at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:184)

at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180)

at rx.Observable.unsafeSubscribe(Observable.java:10327)

at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:94)

at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:42)

at rx.Observable.unsafeSubscribe(Observable.java:10327)

at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber$1.call(OperatorRetryWithPredicate.java:127)

at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.enqueue(TrampolineScheduler.java:73)

at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.schedule(TrampolineScheduler.java:52)

at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:79)

at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:45)

at rx.internal.util.ScalarSynchronousObservable$WeakSingleProducer.request(ScalarSynchronousObservable.java:276)

at rx.Subscriber.setProducer(Subscriber.java:209)

at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:138)

at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:129)

at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)

at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)

at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)

at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)

""",

"date" : "2021-09-28 13:45:06.614",

"service" : "eureka-user-client",

"thread" : "http-nio-8091-exec-10",

"class" : "com.zhxw.common.handler.controller.GlobalExceptionHandler",

"host" : {

"name" : "zhxw-pc"

},

"msg" : "异常本身",

"level" : "ERROR"

},

"sort" : [

1632807906614

]

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值