应用日志杂谈

日志分类

  1. 登录日志:登录轨迹,检测账号安全性,统计用户活跃度,刻画用户画像,流动情况。
  2. 退出日志:系统使用时长,留存期。
  3. 操作日志:用户旅途
  4. 接口日志:接口交互频率,接口性能,三方系统联调的重要定位手段
  5. 程序日志:重要业务,比如订单创建、MQ消费生产
  6. 埋点日志:用户特定行为,产品运营数据分析

日志框架

  1. logback
  2. log4j
    Java市面上主流的就是这两种日志框架,引入依赖后就能结合Spring一起使用。
    要使用日志门面模式的接口,而不是耦合具体的框架,Java日志的门面叫做SLF4J(Simple logging Facade for Java )。他是一个标准接口。也符合架构设计中的依赖抽象,而不是具体。
    目前大部分都使用logback,log4j前段时间频频报出漏洞影响了好多关联框架~当然logback也有。

tip: 使用lombok 在类上加@Slf4j注解即可直接用log对象来打印日志

日志等级

  • fatal 致命、极其严重的错误,可能会导致程序终止或崩溃
  • error 错误级别最高,用于运行时异常或者自定义的业务严重异常
  • warn 有点问题,但是不会影响大局
  • info 业务型日志,一般用于rest请求参数和返回值、重要业务流程节点
  • debug 调试过程,用于更多程序相关开发者关注的日志
  • trace 很少见,用于跟踪链路
    他们的级别也按照顺序排列。等级越低的日志越没那么重要。

日志归档、留存期、分文件

<?xml version="1.0" encoding="UTF-8"?>

<!-- 配置文件修改时重新加载,默认true -->
<configuration scan="true">
    
    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
    <property name="CATALINA_BASE" value="**/logs"></property>
    
    <!-- 控制台输出 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder charset="UTF-8">
            <!-- 输出日志记录格式 -->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
 
    <!-- 第一个文件输出,每天产生一个文件 -->
    <appender name="FILE1" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 输出文件路径+文件名 -->
            <fileNamePattern>${CATALINA_BASE}/aa.%d{yyyyMMdd}.log</fileNamePattern>
            <!-- 保存30天的日志 -->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <!-- 输出日志记录格式 -->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    
    <appender name="CUSTOM" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${CATALINA_BASE}/custom.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- daily rollover -->
            <fileNamePattern>${CATALINA_BASE}/custom.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- keep 30 days' worth of history -->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    
    <!-- 设置日志输出级别 -->
    <root level="ERROR">
        <appender-ref ref="CONSOLE" />
    </root>
    <logger name="file1" level="DEBUG">
        <appender-ref ref="FILE1" />
    </logger>
    <logger name="file1" level="INFO">
        <appender-ref ref="FILE2" />
    </logger>
    <!-- 自定义logger -->
    <logger name="custom" level="INFO">
        <appender-ref ref="CUSTOM" />
    </logger>
</configuration>

每个xml节点的类都是可以自定义的,比如归档后的日志文件权限只能是440以下,log4j就又一个filePermissions的配置,而logback不支持这个属性,只能继承ch.qos.logback.core.rolling.TimeBasedRollingPolicy类,重写内部的文件权限设置方法。

日志安全性

隐私数据脱敏

隐私数据包含了密码、token、秘钥、电话号码、手机号、邮箱等等,这些都是业务数据,IT运维时需要脱敏。一般会在这几种场景下打印
1、打印了接口的所有入参,若修改密码 这种场景很容易出现
2、远程调用三方接口打印入参
3、查询数据库是打印返回值
4、数据处理时有意打印

那怎么解决呢?

  1. 不打印敏感字段,若实体类用的lombok,刚好又用toString来打印这个对象,就可以在字段上加@ToString.Exclude,避免打印
  2. 脱敏,继承日志消息转换器MessageConverter 重写convert方法,将要打印的字符串通过正则匹配敏感信息,再替换成如 138***1111的字符串。
  3. 声明变量名为transient,让其在序列化时忽略,但是要注意使用场景。

日志注入

用户输入的参数未做任何验证直接写入日志文件,导致攻击者可以通过特殊字符(\r \n)在日志中注入新的日志条目,破坏系统日志的完整性。

审计日志

管理界面对数据的增、改、查都非常重视,因为一个小改动都有可能对系统造成深远影响,所以需要审计日志,并且根据重要程度还需要落库。一个合格的审计日志应该有以下信息

  1. 来源ip
  2. 操作资源
  3. 操作类型(增?改?查)
  4. 涉及修改和删除,要打印部分之前重要数据,用于回滚
  5. 时间
  6. 操作人,这抓到就是一顿批

一般可以用AOP来实现对应方法的日志记录,在方法上加自定义的@AuditLog注解。

日志存储

分布式日志

常见的有ELK,EFK等技术。ELK是ElasticSearch+Logstash+Kibana,而EFK是将Logstash换成了FlieBeat。更加的轻量。
分布式集群部署的场景下,日志分散在各个微服务docker中

存储性能

写日志是一个写磁盘的操作,作为日志记录应该要和业务进行解耦,这里建议使用异步的方式(线程池、内存队列、MQ)记录日志。

存储介质

一般是直接写磁盘里,但是为了数据分析,也用到了数据库,如

  1. MongoDB 存储报文,不规则数据
  2. MySQL 日志流水、订单交易需要查询排序的数据
  3. ES 适用所有日志

应用组件日志

mysql

数据库的日志作用就更强大了,可以用来做数据回滚,数据备份,数据同步等等操作。

  • redolog 记录数据的物理变化 InnoDB引擎独有的能力
  • undolog 回滚(binlog相反的SQL)和多版本控制(MVCC)
  • binlog 用于复制和恢复数据,记录所有用户的增删改操作,主从同步也是依赖该日志
  • 慢日志

Nginx & tomcat

  • access.log 访问日志,主要用于看用户接口层面的浏览轨迹,以及响应码是否符合预期,报表统计接口、QPS、各个状态码的分布。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容