使用场景
使用环境变量去配置 TKE Serverless 日志采集时,默认使用单行提取模式。但当客户程序的日志数据跨占多行时(例如 Java 程序日志),不能以换行符
\\n
作为日志的结束标识符。为了能让日志系统明确区分开每条日志,需要配置具有首行正则表达式的 configmap,当某行日志匹配了预先设置的正则表达式,则认为是一条日志的开头,而在下一个行首出现则作为该条日志的结束标识符。本文向您介绍使用环境变量的方式开启 TKE Serverless 日志采集时,如何实现多行日志合并。 操作步骤
原始日志示例
2020-09-24 16:09:07 ERROR System.out(4844) java.lang.NullPointerExceptionat com.temp.ttscancel.MainActivity.onCreate(MainActivity.java:43)at android.app.Activity.performCreate(Activity.java:5248)at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2162) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257)at android.app.ActivityThread.access$800(ActivityThread.java:139)at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
创建 Configmap
针对原始日志文件示例,parser.conf 配置文件内容为:
apiVersion: v1data:parser.conf: |-[PARSER]Name parser_nameFormat regexRegex ^(?<timestamp>[0-9]{2,4}\\-[0-9]{1,2}\\-[0-9]{1,2} [0-9]{1,2}\\:[0-9]{1,2}\\:[0-9]{1,2}) (?<message>.*)kind: ConfigMapmetadata:name: cmnamespace: default
其中
parser_name
需要在创建工作负载的时候设置在 annotation 中(spec.template.metadata.annotations),执行以下命令进行设置:eks.tke.cloud.tencent.com/parser-name: parser_name
创建 Pod 时挂载 Configmap
在创建 Pod 时需要做以下操作:
1. 以 Volume 形式挂载已创建的 Configmap。
2. 通过环境变量的方式开启日志采集,详情可参见 配置日志采集。
3. 指定两个 annotation。
eks.tke.cloud.tencent.com/parser-name: "parser_name"eks.tke.cloud.tencent.com/volume-name-for-parser: "volume-name"
eks.tke.cloud.tencent.com/parser-name
是指已创建的 Configmap 的 name。 eks.tke.cloud.tencent.com/volume-name-for-parser
是指 Pod 中挂载的 Volume 名称,可自定义。Pod yaml 模板
apiVersion: apps/v1kind: Deploymentmetadata:labels:k8s-app: multilineqcloud-app: multilinename: multilinenamespace: defaultspec:replicas: 1selector:matchLabels:k8s-app: multilineqcloud-app: multilinetemplate:metadata:annotations:eks.tke.cloud.tencent.com/parser-name: parser_nameeks.tke.cloud.tencent.com/volume-name-for-parser: volume-namelabels:k8s-app: multilineqcloud-app: multilinespec:containers:- env:- name: EKS_LOGS_OUTPUT_TYPEvalue: cls- name: EKS_LOGS_LOG_PATHSvalue: stdout- name: EKS_LOGS_TOPIC_IDvalue: topic-id- name: EKS_LOGS_LOGSET_NAMEvalue: eks- name: EKS_LOGS_SECRET_IDvalueFrom:secretKeyRef:key: SecretIdname: clsoptional: false- name: EKS_LOGS_SECRET_KEYvalueFrom:secretKeyRef:key: SecretKeyname: clsoptional: falseimage: nginximagePullPolicy: Alwaysname: ngresources:limits:cpu: 500mmemory: 1Girequests:cpu: 250mmemory: 256MivolumeMounts:- mountPath: /mntname: volume-nameimagePullSecrets:- name: qcloudregistrykeyrestartPolicy: Alwaysvolumes:- configMap:defaultMode: 420name: cmname: volume-name
结构化处理后日志示例
2020-09-24 16:09:07 ERROR System.out(4844) java.lang.NullPointerException \\at com.temp.ttscancel.MainActivity.onCreate(MainActivity.java:43) \\at android.app.Activity.performCreate(Activity.java:5248) \\at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110) \\at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2162) \\at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257) \\at android.app.ActivityThread.access$800(ActivityThread.java:139) \\at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)