日志服务
ADP底座对于客户的业务日志提供了日志采集、字段提取、监控分析、告警通知等能力。
功能概述
ADP底座的日志采集器有以下功能:
根据日志路径配置日志采集任务,定期汇集日志到Loki存储中,便于后续做日志查询和分析。
根据分隔符、json、表达式对日志文件进行字段提取,可以对提取的字段打标添加索引,客户可以根据打标的字段进行查询和聚合分析。
接入流程
ADP-Local提供的日志采集器需要先配置日志采集策略,然后加载线上日志,配置字段提取方式,并生成字段列,可以对字段列进行打标并生成Prometheus Metrics。接下来我们可以根据提取的字段进行查询和日志监控。
默认采集配置
ADP底座使用promtail作为日志采集工具,把日志采集上报至loki,由于日志的过滤查询、指标定义都依赖标签(label),在ADP的场景中会添加以下采集配置,在这个基础上,用户可以通过"component"标签对组件日志进行查询,若需要对promtail配置进行手动编辑,请不要删除这些配置项
scrape_configs:
- job_name: kubernetes-pods
relabel_configs:
- source_labels:
[
__meta_kubernetes_pod_label_app_kubernetes_io_component,
__meta_kubernetes_pod_label_component,
__meta_kubernetes_pod_label_adp_aliyuncs_com_component_name,
]
regex: ^;*([^;]+)(;.*)?$
target_label: component
action: replace
- job_name: kubernetes-pods-logdir-csi
relabel_configs:
- source_labels:
[
__meta_kubernetes_pod_label_app_kubernetes_io_component,
__meta_kubernetes_pod_label_component,
__meta_kubernetes_pod_label_adp_aliyuncs_com_component_name,
]
regex: ^;*([^;]+)(;.*)?$
target_label: component
action: replace
- job_name: kubernetes-pods-logdir
relabel_configs:
- source_labels:
[
__meta_kubernetes_pod_label_app_kubernetes_io_component,
__meta_kubernetes_pod_label_component,
__meta_kubernetes_pod_label_adp_aliyuncs_com_component_name,
]
regex: ^;*([^;]+)(;.*)?$
target_label: component
action: replace
在logQL中使用component标签进行日志查询
# 查询组件为mysql-mysql 且日志级别为error的日志
{component="mysql-mysql"} |="error"
默认采集说明
默认会对所有Pod的Stdout进行日志采集,存储至Loki,可通过ADP-Local或Grafana可视化查询,也可以通过调用loki API查询
日志采集器
由于对promtail的采集配置进行修改需要掌握一定量的背景知识,ADP提供了名为'LogCollector'的CR,帮助用户低成本地对日志采集进行配置
有日志采集需求的组件可提前配置好,放在组件helm chart内文件采集器示例及说明正则表达式编写
stdout日志采集器示例及说明
kind: LogCollector
apiVersion: logging.adp.aliyuncs.com/v1alpha1
metadata:
name: adp-local-stdout
namespace: acs-system
spec:
# 描述采集的内容
description: for analyse stdout log
# 采集哪个workload的日志,需要与采集位于同一namespace
workloadName: StatefulSet/adp-local
# 采集Pod Stdout 日志
logType: Stdout
# 若只对部分container进行分析采集,配置container属性
container:
- console
- system
# 当前支持Regexp、JSON两种提取模式
extractMode: Regexp
# 提取表达式(正则),JSON类型则不需要
extractExpression: ^time=(?P<time>.+) level=(?P<level>.+) msg="(?P<msg>.+)"
logColumns:
# name与正则匹配到的name一致或使用JSON的key
- name: level
description: 日志等级
# isLabel 为 true 时,作为label,可在logQL中的labelQuery被使用
isLabel: true
- name: msg
description: 描述信息
isLabel: false
文件采集器示例及说明
kind: LogCollector
apiVersion: logging.adp.aliyuncs.com/v1alpha1
metadata:
name: adp-local-access
namespace: acs-system
spec:
# 描述采集的内容
description: local-access-log
# 采集哪个workload的日志,需要与采集位于同一namespace
workloadName: StatefulSet/adp-local
# 采集Pod 内的文件日志
logType: File
# {volumeName}为卷名称,使用emptyDir的名称或CSI挂载卷的名称
paths:
- {volumeName}/*.access.log
# Regexp、JSON,不同提取方式需要配合不同的表达式
extractMode: Regexp
extractExpression: ^time=(?P<time>.+) level=(?P<level>.+) msg="(?P<msg>.+)"
# 日志切割,label做重复的校验提示
logColumns:
# name与正则匹配到的name一致或使用JSON的key
- name: level
description: 日志等级
# isLabel 为 true 时,作为label,可在logQL中的labelQuery被使用
isLabel: true
- name: msg
description: 描述信息
isLabel: false
正则表达式编写
日志样例
level=info ts=2022-05-10T08:16:57.403Z caller=custom_mysql_user_connections.go:82 scraper=custom.info_schema.processlist msg="custom user connections collect end."
对应的样例正则表达式
level=(?P<level>.+) ts=(?P<ts>.+) caller=(?P<caller>.+) scraper=(?P<scraper>.+) msg=(?P<msg>.+)
这里的正则表达式需要使用"(?'name'ABC) (?P<name>ABC) (?<name>ABC)"的格式标记"named capturing group"
正则表达式可以在站点https://regexr.com/进行调试,注意右上角Regex Engine选择'PCRE'
若调试成功,在Tools预览界面可以看到日志被分隔为多个键值对,键可作为logColumns中的name
JSON日志提取说明
extractMode为JSON时,可提取JSON格式日志
此时extractExpression留空,因为解析JSON格式不需要表达式
把JSON结构首层的key填入logColumns即可对特定key的打标
什么字段适合打标
仅建议把可枚举字段进行打标,如logLevel这样一般只有几种可枚举情况的
类似message、浮点数据这样每次内容都不一样的,不建议进行打标操作
由于Loki会将有同样标签的日志作为一个stream,使用不可枚举的标签会导致stream激增,达到上限(默认5000个stream),然后有新label的stream就无法写入了
Loki + Minio配置实践
说明:
此配置下loki可配置多副本,chunks数据写至minio
loki仍需配置数据盘,用于存放
ingester-WAL
rule-WAL
boltdb-shipper-cache
compactor working directory
性能瓶颈参数主要会受制于配置 server.grpc_server_max_recv_msg_size,默认 4194304bytes/sec(4MB/s),切换至minio后可提升数倍,具体视minio写入能力;
loki:
# 副本数在对接时minio后可配置为多个,提升采集性能
replicas: 3
# 依旧依赖PV存储,写入WAL、cache等数据,但容量要求不高,1Gi即可
persistence:
enabled: true
size: 1Gi
# 配置minio为s3存储,config下的其他配置如limits_config、ruler等维持原状
config:
server:
# 若速度受限可增大此参数配置
grpc_server_max_recv_msg_size: 4194304
common:
storage:
s3:
# minio服务地址
endpoint: http://minio-minio-svc.default:9000
# 存放日志的bucket
bucketnames: logs
# minio的AK/SK
access_key_id: foo
secret_access_key: bar
s3forcepathstyle: true
insecure: true
# 日志副本数
replication_factor: 3
compactor:
shared_store: s3
storage_config:
boltdb_shipper:
shared_store: s3
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: s3
schema: v11
index:
prefix: index_
period: 24h