收集日志模式
阿里云中自带的日志收集插件是logtail,但和fluentd的安装配置上都类似的,具体的差异,可点击此处参考别人的文章。
Logtail的部署方式有DaemonSet方式和Sidecar方式,由于sidecar耗费系统资源,实际日志量没有达到一定层级,此处采用DaemonSet的方式部署。
日志配置
需要收集的是Java spring boot日志,应用场景是有多个项目,每个项目有dev、sit、prod三个环境都需要收集日志。每个项目的每个环境放到k8s中一个单独的namespace下。Java微服务日志配置文件在src/main/resources/logback.xml
里面,配置案例如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志文件保存历史数量 -->
<property name="log.minIndex" value="1" />
<property name="log.maxIndex" value="10" />
<!-- 日志文件大小 -->
<property name="log.maxFileSize" value="100MB" />
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%line:行号,%msg:日志消息,%n是换行符-->
<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} Line:%line - %msg%n" />
<!-- 项目名 -->
<property name="app.name" value="fr-care-auth"/>
<!-- 日志级别 -->
<property name="log.level" value="info"/>
<!--日志文件存储地址 勿使用相对路径 -->
<property name="log.path" value="/opt/logs/care/"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/${app.name}/syslog.log</file>
<!-- 循环方案:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/${app.name}/syslog_%i.log</fileNamePattern>
<minIndex>${log.minIndex}</minIndex>
<maxIndex>${log.maxIndex}</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>${log.maxFileSize}</maxFileSize>
</triggeringPolicy>
<bufferSize>81920</bufferSize>
<!-- 追加方式记录日志 -->
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${log.pattern}</pattern>
<charset class="java.nio.charset.Charset">UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/${app.name}/errorlog.log</file>
<!-- 循环方案:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/${app.name}/errorlog_%i.log</fileNamePattern>
<minIndex>${log.minIndex}</minIndex>
<maxIndex>${log.maxIndex}</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>${log.maxFileSize}</maxFileSize>
</triggeringPolicy>
<bufferSize>81920</bufferSize>
<!-- 追加方式记录日志 -->
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %class [%thread] %-5level %logger{50} Line:%line - %msg%n</pattern>
<charset class="java.nio.charset.Charset">UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<root level="info">
<appender-ref ref="console" />
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info" />
<appender-ref ref="file_error" />
</root>
</configuration>
日志存储在对应k8s pod的/opt/logs/${app.name}/
中,其中${app.name}指代每一个微服务,日志分为errorlog.log 和 info.log。
Logtail创建及配置
首先创建project,此处收集的是 dev和sit环境的容器日志,可以手动创建相关project,另外,创建logtail的步骤中,可以指定sls project或者创建一个,单击创建新Project,自动创建一个新的Project来管理采集的日志,Project会自动命名为k8s-log-{ClusterID},ClusterID是您新建的Kubernetes集群的唯一标识。安装完成后,在该Project下自动创建名为k8s-group-${your_k8s_cluster_id}的机器组和名为config-operation-log的Logstore。
如,下图所示
日志库logstore规划
由上述Java日志配置文件的配置可知,每个微服务会自动在对应pod下面生成日志文件,如:/opt/logs/care/fr-care-auth/
,每个文件路径下都包含syslog.log 和 errorlog.log,由于error日志和info日志的匹配模式不同,所以需要分成不同的日志库logstore。
-
每个项目(包含dev和sit环境或者prod)包含error和info的两个logstore,如下图所示:
这样配置会使得同一个项目里面dev和sit环境的所有微服务会打到通过一个logstore中,可以根据自动生成的一些tag来做过滤搜索。当然也可以将同一个项目dev、sit的日志分别建单独的logstore,这里要结合日志量以及长远规划来做差异处理。
-
所有的日志都是在容器的``/opt/logs/care/`目录下,但在此目录下的子文件夹名都是以每个服务的服务类型做命名,比如有fr-care-auth和fr-care-gateway等。有关logtail配置项的日志路径,需要用正则匹配,匹配到该项目下所有的info或者error log日志,配置案例如下所示:
Logtail匹配模式介绍
logtail中数据接入部分的logtail配置,可以通过DaemonSet-CRD,即手动写logtail 正则匹配文件,但经过实践证明,手动配置yaml,匹配模式不太友好,遇到过同一条errorlog日志被匹配成多个日志记录的问题,可能是匹配模式有问题,向阿里开了工单,也没找到原因,后来推荐DaemonSet-控制台方式直接匹配极简模式-多行或者极简模式-单行,输入日志后,会自动生成正则匹配,都能正确收集errorl log,当然infor级别log直接使用极简模式-单行即可,配置案例如下所示:
另外,遇到过log的debug日志收集不到,而info日志可以,debug日志是可以打到容器控制台的,后面排查发现,debug日志,后端开发没有配置写入到文件,只打到控制台,而上述配置的logtail都是从容器指定文件中获取日志,所以获取不到debug日志。可以参考通过DaemonSet-控制台方式采集容器标准输出,来获取debug日志,或者将debug日志也打入到文件都可以解决。