需求: 将日志按照不同的模块和日志级别输入到不同的日志文件里.
    实现方式1:
        最初的想法是用 LoggerFactory.getLogger(logName),然后为不同的logName 定义不同的logger指向不同的FileAppender
        缺点:由于Logger 的名字改变,不再能根据每个类的名字动态调整日志级别,对错误排查影响较大
    
    
    实现方式2:
        利用Log4j2的Lookup功能动态构建文件名 参考https://logging.apache.org/log4j/2.x/manual/lookups.html
        缺点是这个只能在Logger 定义之前指定一个模块:如
        static {
            System.setProperty("module", "module1");
        }
        public static final Logger logger = LoggerFactory.getLogger(Module1.class);
        
        没办法在运行时动态切换日志文件
    
    实现方式3:
        按利用log4j2 的路由功能 (RoutingAppender)可以根据上下文变量将日志动态路由到的不同的文件
        具体配置如下:
        <RollingFile name="RollingFilePre" fileName="test-module1.log" filePattern="test-module1.%d{yyyy-MM-dd}.%i.log" append="true">
            <DynaJsonLayout compact="true" eventEol="true"/>    
            <Policies>
                <SizeBasedTriggeringPolicy size="1048576"/>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
            <DefaultRolloverStrategy max="200"/>
        </RollingFile>     
        <RollingFile name="RollingFileRule" fileName="test-module2.log" filePattern="test-module2.%d{yyyy-MM-dd}.%i.log" append="true">
            <DynaJsonLayout compact="true" eventEol="true"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="1048576"/>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
            <DefaultRolloverStrategy max="200"/>
        </RollingFile>     
        <Routing name="Routing" >
            <Routes pattern="${sys:module}">
                <Route key="val1" ref="RollingFilePre">
                </Route>
                <Route key="val2" ref="RollingFileRule">
                </Route>
            </Routes>
        </Routing>
        
        这样可以在程序中随时调用 System.setProperty() 来切换日志文件, 也可以通过其他选项比如ThreadContext property 来动态切换
    
        注意:如果需要程序中动态切换文件,route 和 异步日志 async 会有一定的冲突,切换时可能数据还在内存队列里,这样可能打不到正确的文件里
        
        按日志级别分文件则是另外一种思路,利用ThresholdFilter 将日志同时输出到A,B两个Appender, 再根据日志级别过滤. 比如A只接收Error 级别的日志
        B只接收Error以下级别的日志,奇怪的是Log4j2 没有把两者统一起来
        <root level="debug">  
            <appender-ref ref="Console"></appender-ref>
            <appender-ref ref="RoutingFileAsync"/>  
        </root>
        <Async name="RoutingFileAsync" bufferSize="300000">
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            <AppenderRef ref="Routing"/>
            <ArrayBlockingQueue/>
        </Async>
        <Console name="Console" target="SYSTEM_OUT">  
            <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="ACCEPT"/>
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>  
        </Console>      
    
LOGSTASH采集:
     利用Log4j2   JsonLayout,程序中会有一个工具类将错误日志格式变成JSON的,类似于 {"errorCode":xxx, "errorMessage":xxx}
     但是JsonLayout 会把日志报文统一放到message 属性中,这样在日志记录进入Elasticsearch 仍然无法直接被搜索,我们的期望是将
     JSON消息报文中的属性展开成多个顶级属性而不是嵌套在message中
     一种思路是在日志从KAFKA到Elasticsearch 的时候做一些转换,不确定Logstash 的mutate是否支持
     另一种思路是定制一个自己的JsonLayout 重载toSerializable方法来自定义输出的格式和内容, 具体实现步骤如下
     1.定义 DynaLogEvent 继承了log4j 原生的 LogEvent, 增加了一个Map 类型的 attributes 属性,如果原生Log4jEvent 中的Message是Json格式则就把解析出的键值对存到
     attributes 中  
    
     2. 定义了 DynaJsonLayout 通过 Plugin Annotation 注册到Log4j2 中,同时log4j2.xml 中需要声明 <configuration packages="org.apache.logging.log4j.core.layout">
     来指定扫描插件的路径 DynaJsonLayout 主要就是重载了 toSerializable 方法,将原生的 LogEvent 转化为 DynaLogEvent 并通过 json ObjectWriter 输出成json 格式
     ObjectWriter 使用了定制的 DynaLog4jJsonObjectMapper, 通过工厂类DynaJacksonFactory来构建,DynaJsonLayout 初始化时将 DynaLog4jJsonObjectMapper
     注入ObjectWriter 中
    
     3. 实践中发现attributes 并不能被Log4jJsonObjectMapper正确的序列化 (注:Log4j2的Log4jJsonObjectMapper使用了大量jackson的高级技巧来定制LogEvent的序列化,
     如Module, Mixin 等,大家有兴趣可以阅读下代码,这里不详细展开了), 所以为DynaLogEvent中的attributes属性添加了JsonIgnore Annotation 避免它被自动序列化,
     并定制了DynaLogEventSerializer 来自定义序列化 attributes, DynaLogEventSerializer通过 DynaLog4jJsonModule 注册到 DynaLog4jJsonObjectMapper 中
    
     源代码:https://github.com/wispershadow/myopensources/tree/master/jsonlogger

转载于:https://blog.51cto.com/shadowisper/1974934

监控日志采集的一些TIPS相关推荐

  1. Kubernetes入门——Kubernetes日志采集与监控告警

    作者简介: 郭川磊 百度基础架构部研发工程师 负责云原生产品的研发 本文基于百度云原生团队『云原生基础知识概述及实践』系列视频课程--『Kubernetes入门-Kubernetes实现应用高可用』梳 ...

  2. 资源放送丨《如何从零快速搭建一整套监控体系(日志采集+主机+数据库)》PPT视频...

    前段时间,墨天轮分享了直播<如何从零快速搭建一整套监控体系(日志采集+主机+数据库)>,在这里我们共享一下PPT和视频,供大家参考学习. 客户转型去O使用分布式架构的情况下,作为DBA需要 ...

  3. ELK日志分析平台(三)— kibana数据可视化、kibana监控、采集日志插件filebeat

    1.kibana数据可视化--日志分析 [root@foundation50 network-scripts]# cd /mnt/pub/docs/elk/7.6/ [root@foundation5 ...

  4. Skywalking调用链监控系统 及 日志采集

    Skywalking做为生产级的调用链监控工具,不仅提供了丰富的监控系统,而且通过字节码拦截形式集成系统,对系统没有任何侵入性:最近研究一下调用链项目,在此与大家共享: github 地址  http ...

  5. 采集虚拟机_系列文章:Kubernetes日志采集最佳实践

    前言 上一期主要介绍Kubernetes日志输出的一些注意事项,日志输出最终的目的还是做统一的采集和分析.在Kubernetes中,日志采集和普通虚拟机的方式有很大不同,相对实现难度和部署代价也略大, ...

  6. 日志采集框架Flume以及Flume的安装部署(一个分布式、可靠、和高可用的海量日志采集、聚合和传输的系统)...

    Flume支持众多的source和sink类型,详细手册可参考官方文档,更多source和sink组件 http://flume.apache.org/FlumeUserGuide.html Flum ...

  7. 直击痛点,详解 K8s 日志采集最佳实践

    作者 | 元乙 阿里云存储服务技术专家 导读:上一篇文章主要介绍 Kubernetes 日志输出的一些注意事项,日志输出最终的目的还是做统一的采集和分析.在 Kubernetes 中,日志采集和普通虚 ...

  8. 系列文章:Kubernetes日志采集最佳实践

    前言 上一期主要介绍Kubernetes日志输出的一些注意事项,日志输出最终的目的还是做统一的采集和分析.在Kubernetes中,日志采集和普通虚拟机的方式有很大不同,相对实现难度和部署代价也略大, ...

  9. LC3视角:Kubernetes下日志采集、存储与处理技术实践

    摘要: 在Kubernetes服务化.日志处理实时化以及日志集中式存储趋势下,Kubernetes日志处理上也遇到的新挑战,包括:容器动态采集.大流量性能瓶颈.日志路由管理等问题.本文介绍了" ...

最新文章

  1. php程序应用实例,PHP教程.应用实例1_php
  2. 从零点五开始用Unity做半个2D战棋小游戏(二)
  3. 切片slice(python)
  4. vue之filter用法
  5. 90 % Java 程序员被误导的一个性能优化策略
  6. python--类与GUI编程框架
  7. (pytorch-深度学习系列)深度卷积神经网络AlexNet
  8. 第三节:快速编译TypeScript,提高开发效率
  9. linux内核中读写文件
  10. Python 之父重回决策层,未来如何发展?
  11. 人群与网络:社会选择与社会影响
  12. CentOS7.2 在线安装MySQL8.0
  13. 我经历的学术与论文写作
  14. mysql双机热备份windows_window下使用mysql双机热备份
  15. 网址 URL 最后的斜杠 / 是作甚的?
  16. 计算机专业英语读书笔记,英语的读书笔记(精选10篇)
  17. MOT任务中JDE(Jointly learns the Detector and Embedding model)算法解读
  18. Ubuntu下WIFI不稳定问题
  19. Python生成自动化测试报告的两种方法
  20. 如何免费使用正版win10系统

热门文章

  1. [angularjs] angularjs系列笔记(四)控制器
  2. Spring AOP源码分析(八)SpringAOP要注意的地方
  3. [COCI 2013/2014 ROUND 3] parovi
  4. 从今天开始,我就要潜心研究软件开发技术了,不在被名利所困
  5. 告别2010,迎来2011
  6. Spring: 依赖注入的实现
  7. [20180627]测试bbed是否支持管道命令.txt
  8. docker一:mac入门安装
  9. Django 入门项目案例开发(下)——创建项目应用及模型类
  10. 第4章 管道与FIFO