当前位置: 首页 > news >正文

slf4j-logback 日志以json格式导入ELK

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

slf4j-logback 日志以json格式导入ELK

同事整理的,在此分享。logback,log4j2 等slf4j的日志实现都可以以json格式输出日志, 这里采用的是logback。当然也可以以文本行的格式输出,然后在logstash里通过grok解析,但是直接以json格式输出,在logstash处理时效率会高一点。

Logback 输出 Json格式日志文件

 为了让 logback 输出JSON 格式的日志文件,需要在pom.xml 加入如下依赖

<dependency>

   <groupId>net.logstash.logback</groupId>

   <artifactId>logstash-logback-encoder</artifactId>

   <version>4.8</version>

   <scope>runtime</scope>

</dependency>

logback日志配置示例

<appender name="errorFile" class="ch.qos.logback.core.rolling.RollingFileAppender">

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

      <level>ERROR</level>

      <onMatch>ACCEPT</onMatch>

      <onMismatch>DENY</onMismatch>

   </filter>

   <file>${log.dir}/elk/error.log</file> <!-- 当前的日志文件文件放在 elk文件下,该日志的内容会被filebeat传送到es --> 

   <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  <! -- 历史日志会放到 bak 文件下,最多保存7天的历史,最多占用 1G的空间 -->

      <fileNamePattern>${log.dir}/bak/error.%d{yyyy-MM-dd}.log</fileNamePattern>

      <maxHistory>7</maxHistory>

      <totalSizeCap>1GB</totalSizeCap>

   </rollingPolicy>

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

       

      <providers>

         <pattern>

            <pattern>

              {

              "tags": ["errorlog"],

              "project""myproject",

              "timestamp""%date{\"yyyy-MM-dd'T'HH:mm:ss,SSSZ\"}",

              "log_level""%level",

              "thread""%thread",

              "class_name""%class",

              "line_number""%line",

              "message""%message",

              "stack_trace""%exception{5}",

              "req_id""%X{reqId}",

              "elapsed_time""#asLong{%X{elapsedTime}}"

              }

            </pattern>

         </pattern>

      </providers>

   </encoder>

</appender>

 

 

Json 字段说明:

名称

说明

备注

 

 

 

 

 

tags用于说明这条日志是属于哪一类日志      
timestamp
日志记录时间      
project
系统名称,该日志来自于哪个系统      
log_level
输出日志级别      
thread
输出产生日志的线程名。      
class_name
输出执行记录请求的调用者的全限定名
 
     
line_number
输出执行日志请求的行号
 
     
message
输出应用程序提供的信息      
stack_trace
异常栈信息      
req_id
请求ID,用于追踪请求需要引入aop-logging     
elapsed_time
该方法执行时间,单位: 毫秒需要引入aop-logging     
%X{key}: 表示该项来自于SLF4j MDC,需要引入 aop-logging

<dependency>

        <groupId>com.cloud</groupId>

         <artifactId>xspring-aop-logging</artifactId>

        <version>0.7.1</version>

</dependency>

 

针对web应用,在 web.xml 中加入 ReqIdFilter,该过滤器会在MDC 加入 reqId

<filter>

    <filter-name>aopLogReqIdFilter</filter-name>

    <filter-class>com.github.nickvl.xspring.core.log.aop.ReqIdFilter</filter-class>

</filter>

 

<filter-mapping>

    <filter-name>aopLogReqIdFilter</filter-name>

    <url-pattern>/*</url-pattern>

</filter-mapping>

 

 

or register in springboot like this:

 

 

@Bean

public FilterRegistrationBean getDemoFilter(){

    ReqIdFilter reqIdFilter=new ReqIdFilter();

    FilterRegistrationBean registrationBean=new FilterRegistrationBean();

    registrationBean.setFilter(reqIdFilter);

    List<String> urlPatterns=new ArrayList<String>();

    urlPatterns.add("/*");

    registrationBean.setUrlPatterns(urlPatterns);

    registrationBean.setOrder(100);

    return registrationBean;

}

 

如果需要记录该方法执行时间: elapsed_time,如果在该类或者方法上加入如下注解:

 

import com.github.nickvl.xspring.core.log.aop.annotation.LogDebug;

import com.github.nickvl.xspring.core.log.aop.annotation.LogInfo;

 

@LogInfo  // 当logger 设为level=INFO 会输出

@LogException(value = {@Exc(value = Exception.class, stacktrace = false)}, warn = {@Exc({IllegalArgumentException.class})}) //

当logger 设为level=error 会输出

 

针对dubbo 消费者的日志记录,dubbo消费者是通过 javassist 生成的动态类型,如果要监控该dubbo接口的传入参数,返回值,和调用时间 需要引入aop-logging,

以及在 eye-rpc包中的接口上给对应的类或方法 加上上面的注解。

dubbo 消费者的日志会输出如下配置:

 

 <logger name="com.alibaba.dubbo.common.bytecode" level="INFO" additivity="false">

   <appender-ref ref="dubboApiFile"/>

</logger>

 

ElasticSearch 模板设置

curl -XPUT http://localhost:9200/_template/log -d '{

  "mappings": {

    "_default_": {

      "_all": {

        "enabled"false

      },

      "_meta": {

        "version""5.1.1"

      },

      "dynamic_templates": [

        {

          "strings_as_keyword": {

            "mapping": {

              "ignore_above"1024,

              "type""keyword"

            },

            "match_mapping_type""string"

          }

        }

      ],

      "properties": {

        "@timestamp": {

          "type""date"

        },

        "beat": {

          "properties": {

            "hostname": {

              "ignore_above"1024,

              "type""keyword"

            },

            "name": {

              "ignore_above"1024,

              "type""keyword"

            },

            "version": {

              "ignore_above"1024,

              "type""keyword"

            }

          }

        },

        "input_type": {

          "ignore_above"1024,

          "type""keyword"

        },

        "message": {

          "norms"false,

          "type""text"

        },

        "offset": {

          "type""long"

        },

        "source": {

          "ignore_above"1024,

          "type""keyword"

        },

        "tags": {

          "ignore_above"1024,

          "type""keyword"

        },

        "type": {

          "ignore_above"1024,

          "type""keyword"

        }

      }

    }

  },

  "order"0,

  "settings": {

    "index.refresh_interval""5s"

  },

  "template""log-*"

}'

 

curl -XPUT http://localhost:9200/_template/log-java -d '

 

{

  "mappings": {

    "_default_": {

      "properties": {

        "log_level": {

          "ignore_above"1024,

          "type""keyword"

        },

        "project": {

          "ignore_above"1024,

          "type""keyword"

        },

        "thread": {

          "ignore_above"1024,

          "type""keyword"

        },

        "req_id": {

          "ignore_above"1024,

          "type""keyword"

        },

        "class_name": {

          "ignore_above"1024,

          "type""keyword"

        },

        "line_number": {

          "type""long"

        },

        "exception_class":{

          "ignore_above"1024,

          "type""keyword"

        },

        "elapsed_time": {

          "type""long"

        },

        

        "stack_trace": {

          "type""keyword"

        }

      }

    }

  },

  "order"1,

  "settings": {

    "index.refresh_interval""5s"

  },

  "template""log-java-*"

}'

logstatsh 设置

logstash-java-log

if [fields][logType] == "java" {

    json {

        source => "message"

        remove_field => ["offset"]

    }

    date {

        match => ["timestamp","yyyy-MM-dd'T'HH:mm:ss,SSSZ"]

        remove_field => ["timestamp"]

    }

    if [stack_trace] {

         mutate {

            add_field => { "exception_class" => "%{stack_trace}" }

        }

    }

    if [exception_class] {

         mutate {

            gsub => [

                "exception_class""\n""",

                "exception_class"":.*"""

            ]

        }

    }

}

filebeat 设置

filebeat.yml

filebeat.prospectors:

- input_type: log

  paths:

    - /eyebiz/logs/eyebiz-service/elk/*.log   # eyebiz-service 日志

    - /eyebiz/logs/eyebiz-web/elk/*.log       # eyebiz-web 日志

  fields:

    logType: "java"

    docType: "log-java-dev"

转载于:https://my.oschina.net/u/199525/blog/1787344

相关文章:

  • jquery 笔记。。。——》摘自武方博
  • Linux导入导出Oracle数据库
  • 谈谈这些年来我为什么一直在坚持
  • 3171. [TJOI2013]循环格【费用流】
  • Android OTG之USB转串口模块通讯
  • 扑克千术
  • 删除数据库中所有表
  • 初来乍到
  • .NET成年了,然后呢?
  • android 线程消息深入
  • ios动态库和静态库
  • Chrome开发——第一个博客链接插件
  • RabbitMQ消息队列(九):Publisher的消息确认机制
  • 减治算法求n个数中的最小数的位置
  • spark2.1.0 自定义AccumulatorV2累加少值(线程不安全)?
  • ES10 特性的完整指南
  • Fundebug计费标准解释:事件数是如何定义的?
  • Tornado学习笔记(1)
  • 开源地图数据可视化库——mapnik
  • 让你的分享飞起来——极光推出社会化分享组件
  • 使用API自动生成工具优化前端工作流
  • Mac 上flink的安装与启动
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • ###项目技术发展史
  • #每天一道面试题# 什么是MySQL的回表查询
  • #数学建模# 线性规划问题的Matlab求解
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (C语言)二分查找 超详细
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (第一天)包装对象、作用域、创建对象
  • (多级缓存)缓存同步
  • (附源码)ssm航空客运订票系统 毕业设计 141612
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (排序详解之 堆排序)
  • (数据结构)顺序表的定义
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • (转载)OpenStack Hacker养成指南
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • *1 计算机基础和操作系统基础及几大协议
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全
  • .mysql secret在哪_MYSQL基本操作(上)
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .NET MVC第三章、三种传值方式
  • .NET 中创建支持集合初始化器的类型
  • .Net下C#针对Excel开发控件汇总(ClosedXML,EPPlus,NPOI)
  • [ C++ ] STL_stack(栈)queue(队列)使用及其重要接口模拟实现
  • [BZOJ4010]菜肴制作
  • [echarts] y轴不显示0
  • [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated c
  • [Gradle] 在 Eclipse 下利用 gradle 构建系统
  • [HeMIM]Cl,[AeMIM]Br,[CeEIM]Cl,([HO-PECH-MIM]Cl,[HOOC-PECH-MIM]Cl改性酚醛树脂
  • [HTML]Web前端开发技术30(HTML5、CSS3、JavaScript )JavaScript基础——喵喵画网页