SkyWalking OAP 日志分析实战:log-analyzer 配置与 LAL 日志分析语言完全指南

📅 发布时间:2026/9/21 0:20:26
SkyWalking OAP 日志分析实战:log-analyzer 配置与 LAL 日志分析语言完全指南
可观测性后端微服务云原生【免费下载链接】skywalkingAPM, Application Performance Monitoring System项目地址https://gitcode.com/gh_mirrors/sky/skywalking点击查看免费下载日志分析是 APM 系统补齐可观测性最后一环的关键能力。SkyWalking OAP Server 内置的log-analyzer 模块可以直接接收并处理原生日志数据native log data并通过专为日志分析设计的Log Analysis LanguageLAL完成日志的结构化解析、字段提取与落库保存同时借助Meter Analysis LanguageMAL引擎将日志中蕴含的指标如各日志级别的计数、响应时间分布进一步计算成可查询的业务指标。读完本文你将掌握 log-analyzer 的完整配置方法、LAL 的 parser / extractor / sink 三大组件语法并能独立编写从原始日志到结构化日志 指标 慢 SQL的完整分析规则。一、认识 OAP 的 log-analyzer 模块log-analyzer 是 OAP Server 中负责日志分析的核心模块代码位于 oap-server/analyzer/log-analyzer。它通过LogAnalysisListener监听各接收器receiver上报的原始日志再交由 LAL 脚本完成解析、提取与保存。其模块配置定义在 LogAnalyzerModuleConfig.java配置项默认值说明selectordefault选择 log-analyzer 的实现提供者对应LogAnalyzerModuleProvidername 为defaultdefault.lalFilesdefault.yaml启用的 LAL 规则文件列表逗号分隔文件位于lal目录default.malFiles空启用的 MAL 指标规则文件列表逗号分隔文件位于log-mal-rules目录1. 配置文件与目录约定在 OAP 的application.yml中log-analyzer 的标准配置如下出自 docs/en/setup/backend/log-analyzer.mdlog-analyzer: selector: ${SW_LOG_ANALYZER:default} default: lalFiles: ${SW_LOG_LAL_FILES:default} malFiles: ${SW_LOG_MAL_FILES:}三个配置项全部支持通过环境变量覆盖便于在容器化部署中按需调整SW_LOG_ANALYZER选择模块实现一般保持defaultSW_LOG_LAL_FILES激活哪些 LAL 文件相对于lal目录SW_LOG_MAL_FILES激活哪些 MAL 指标文件相对于log-mal-rules目录。从源码看lalFiles通过Splitter.on(,)按逗号切分omitEmptyStrings忽略空段malFiles则由Rules.loadRules(getMalPath(), files)加载为 MAL 规则对象。这意味着多个文件用逗号分隔即可一次启用例如lalFiles: a,b,c。OAP 发行版自带的默认配置oap-server/server-starter/src/main/resources/application.yml是这样的log-analyzer: selector: ${SW_LOG_ANALYZER:default} default: lalFiles: ${SW_LOG_LAL_FILES:envoy-als,mesh-dp,mysql-slowsql,pgsql-slowsql,redis-slowsql,k8s-service,nginx,default} malFiles: ${SW_LOG_MAL_FILES:nginx}可见官方默认就内置了 Envoy ALS、服务网格数据面、MySQL/PostgreSQL/Redis 慢 SQL、K8s 服务日志、Nginx 日志等多套开箱即用的 LAL 规则以及一套nginx的 MAL 指标规则。2. 模块装配与加载流程LogAnalyzerModuleProvider.java 展示了模块的装配方式prepare()阶段创建LogAnalyzerServiceImpl并注册ILogAnalyzerService服务start()阶段注册LogFilterListener.Factory——它是 LAL 脚本的驱动入口。模块依赖CoreModule与ConfigurationModule。LAL 脚本本身基于 Groovy 实现加载逻辑集中在 DSL.java。值得关注的安全设计DSL 编译时通过SecureASTCustomizer禁用了while/do-while/for循环语句并将允许的接收者类型限制为Object、Map、List、Array、String及ProcessRegistry同时把脚本基类设置为LALDelegatingScript从而在提供强大表达能力的同时避免脚本造成安全风险。二、LAL 语言核心从一条日志到结构化数据LALLog Analysis Language是 SkyWalking 为日志分析专门设计的领域特定语言DSL完整语言参考见 docs/en/concepts-and-designs/lal.md。它的整体思路是每一条日志都会顺序经过 LAL 规则中声明的一个或多个filter每个 filter 内部由 parser解析、extractor提取、sink落库按声明顺序依次执行。LAL 文件为 YAML 格式放在lal目录下结构如下参考发行版示例 dist-material/config-examples/lal.yamlrules: - name: example dsl: | filter { ... }每个规则由name和dsl组成dsl就是一段 Groovy 风格的 LAL 脚本。1. Layer日志的分析范围layer在 LAL 脚本中声明表示日志所属的分析分层如GENERAL、MYSQL等对应 Layer.java 定义的分层枚举。它既可以在extractor中通过layer GENERAL这种形式从脚本直接设置也可以通过layer parsed.layer as String从解析结果中提取。2. Filter 与全局函数filter是 parser、extractor、sink 的容器。每条日志会被发送到 LAL 规则中的所有 filter在脚本内当前日志以log属性访问如log.service取服务名。除组件自身的语法外LAL 还提供两个全局函数可在任意组件中使用abort提前终止过滤器链。默认情况下无论dropped、saved等标志如何所有已声明组件都会执行abort则从声明位置起跳过剩余所有组件实现快速失败。典型用法是在 filter 入口过滤掉无价值的日志来源filter { if (log.service TestingService) { // 不为测试服务浪费资源 abort {} // 后续所有组件都不会执行 } // ... parsers, extractors, sinks }注意在if条件中使用regexp时必须写成regexp(表达式)的括号形式不能省略括号。tag读取日志标签。日志数据中携带的 tagskey/value 对可通过tag(KEY)便捷取值常用于条件判断filter { if (tag(TEST_KEY) TEST_VALUE) { ... } }三、Parser把原始日志变成结构化字段parser 负责把原始日志解析为结构化数据。解析完成后LAL 会注入属性parsed——一个 Map包含解析出的所有字段json/yamlparser 的parsed是 JSON/YAML 的全部键值textparser配合正则的parsed则是所有捕获组及其值。所有 parser 共享一个选项abortOnFailureboolean默认true解析/匹配失败时是否中止整个过滤器链。parser适用场景示例jsonJSON 结构化日志json { abortOnFailure true }yamlYAML 结构化日志yaml { abortOnFailure true }textregexp非结构化文本日志见下文正则示例json/yaml的用法非常直接filter { json { abortOnFailure true // 可选这是默认行为 } }对非结构化日志使用textparser 中的regexp它基于正则的捕获组提取字段返回boolean表示是否匹配filter { text { abortOnFailure true // 可选这是默认行为 // 演示用模式 regexp (?timestamp\\d{8}) (?thread\\w) (?level\\w) (?traceId\\w) (?msg.) } extractor { tag level: parsed.level // 增加一个名为 level 的标签值来自上面正则捕获的 parsed.level traceId parsed.traceId // 提取 trace id用于将日志与链路关联 } // ... }LAL 文档中也预告了grokparserTODO 状态官方正在评估 grok Java 库的性能问题尚未正式支持社区欢迎相关贡献。四、Extractor提取元数据与生成指标extractor 的目标是从parsed中提取元数据并写入LogData——包括服务名、实例名、端点名、trace ID 等从而与已有的链路trace和指标metrics建立关联。LAL 支持的 extractor 如下1. 基础关联提取器提取器作用service从parsed提取服务名写入LogData用于关联 trace/metricsinstance提取服务实例名endpoint提取端点名traceId提取 trace ID建立日志与链路的关联segmentId提取 segment IDspanId提取 span IDtimestamp提取时间戳毫秒或带格式的日期字符串见下文layer提取分层layer写入LogData并与服务关联tag从parsed提取标签写入LogData支持动态键值timestamp支持两种写法——毫秒时间戳extractor { timestamp parsed.time as String }或带格式的日期字符串extractor { timestamp parsed.time as String, yyyy-MM-dd HH:mm:ss }tag的写法是tag key1: value, key2: value2键和值都可以来自parsedextractor { tag level: parsed.level, (parsed.statusCode): parsed.statusMsg tag anotherKey: anotherConstantValue layer GENERAL }2. metrics从日志生成指标metricsextractor 从日志中提取/生成指标并发送到 meter 系统之后由 MAL 规则做进一步计算。这些专用的 MAL 配置文件放在log-mal-rules目录通过log-analyzer/default/malFiles或环境变量SW_LOG_MAL_FILES启用# application.yml log-analyzer: selector: ${SW_LOG_ANALYZER:default} default: lalFiles: ${SW_LOG_LAL_FILES:my-lal-config} # 文件位于 lal 目录 malFiles: ${SW_LOG_MAL_FILES:my-lal-mal-config, folder1/another-lal-mal-config, folder2/*} # 文件位于 log-mal-rules 目录注意malFiles支持目录通配folder2/*与lalFiles一样用逗号分隔多个条目。在 extractor 中声明指标例如生成日志计数和HTTP 响应时间两个指标extractor { service parsed.serviceName metrics { name log_count timestamp parsed.timestamp labels level: parsed.level, service: parsed.service, instance: parsed.instance value 1 } metrics { name http_response_time timestamp parsed.timestamp labels status_code: parsed.statusCode, service: parsed.service, instance: parsed.instance value parsed.duration } }随后即可在log-mal-rules下的 MAL 配置中按日志级别聚合计数# ... MAL 的其他配置 metrics: - name: log_count_debug exp: log_count.tagEqual(level, DEBUG).sum([service, instance]).increase(PT1M) - name: log_count_error exp: log_count.tagEqual(level, ERROR).sum([service, instance]).increase(PT1M)也可以对http_response_time生成百分位等更丰富的指标metrics: - name: response_time_percentile exp: http_response_time.sum([le, service, instance]).increase(PT5M).histogram().histogram_percentile([50,70,90,99])3. slowSql慢 SQL 识别slowSqlextractor 用于将LogData转换为DatabaseSlowStatement数据库慢语句记录与 TopN 数据库语句统计关联。它不会中止或修改日志本身可以继续用其他 LAL 做进一步处理同时它会复用 extractor 中的service、layer、timestamp因此必须在这三个字段设置之后使用。要让 OAP 从普通日志中识别慢 SQL日志必须携带标签LOG_KIND SLOW_SQL。一个上报到 OAP 的 JSON 示例[ { tags:{ data:[ { key:LOG_KIND, value:SLOW_SQL } ] }, layer:MYSQL, body:{ json:{ json:{\time\:\1663063011\,\id\:\cb92c1a5b-2691e-fb2f-457a-9c72a392d9ed\,\service\:\root[root][localhost]\,\statement\:\select sleep(2);\,\layer\:\MYSQL\,\query_time\:2000} } }, service:root[root][localhost] } ]配合slowSql的还有三个从parsed提取字段的 extractor均写入DatabaseSlowStatement提取器作用statement提取 SQL 语句latency提取耗时毫秒id提取语句 ID一个完整的慢 SQL 识别 LAL 示例filter { json{ } extractor{ layer parsed.layer as String service parsed.service as String timestamp parsed.time as String if (tag(LOG_KIND) SLOW_SQL) { slowSql { id parsed.id as String statement parsed.statement as String latency parsed.query_time as Long } } } }注意慢 SQL 采样只是把该 SQL 标记进候选列表。OAP 会按服务统计默认每 10 分钟由topNReportPeriod: ${SW_CORE_TOPN_REPORT_PERIOD:10}控制只持久化 Top 50 条。4. sampledTrace网络剖析采样链路sampledTraceextractor 将LogData转换为SampledTraceRecord采样链路记录用于网络剖析network profiling场景同样不会中止或修改日志。识别标识是日志标签LOG_KIND NET_PROFILING_SAMPLED_TRACE对应layer: MESH的日志[ { tags:{ data:[ { key:LOG_KIND, value:NET_PROFILING_SAMPLED_TRACE } ] }, layer:MESH, body:{ json:{ json:{\uri\:\/provider\,\reason\:\slow\,\latency\:2048,\client_process\:{\process_id\:\c1519f4555ec11eda8df0242ac1d0002\,\local\:false,\address\:\\},\server_process\:{\process_id\:\\,\local\:false,\address\:\172.31.0.3:443\},\detect_point\:\client\,\component\:\http\,\ssl\:true} } }, service:test-service, serviceInstance:test-service-instance, timestamp: 1666916962406, } ]对应的 LAL 示例含客户端/服务端进程 ID 的生成与组件 ID 映射filter { json { } if (tag(LOG_KIND) NET_PROFILING_SAMPLED_TRACE) { sampledTrace { latency parsed.latency as Long uri parsed.uri as String reason parsed.reason as String if (parsed.client_process.process_id as String ! ) { processId parsed.client_process.process_id as String } else if (parsed.client_process.local as Boolean) { processId ProcessRegistry.generateVirtualLocalProcess(parsed.service as String, parsed.serviceInstance as String) as String } else { processId ProcessRegistry.generateVirtualRemoteProcess(parsed.service as String, parsed.serviceInstance as String, parsed.client_process.address as String) as String } if (parsed.server_process.process_id as String ! ) { destProcessId parsed.server_process.process_id as String } else if (parsed.server_process.local as Boolean) { destProcessId ProcessRegistry.generateVirtualLocalProcess(parsed.service as String, parsed.serviceInstance as String) as String } else { destProcessId ProcessRegistry.generateVirtualRemoteProcess(parsed.service as String, parsed.serviceInstance as String, parsed.server_process.address as String) as String } detectPoint parsed.detect_point as String if (parsed.component as String http parsed.ssl as Boolean) { componentId 129 } else if (parsed.component as String http) { componentId 49 } else if (parsed.ssl as Boolean) { componentId 130 } else { componentId 110 } } } }其中ProcessRegistry由 DSL 编译期导入用于生成虚拟进程 ID本地/远程进程均支持componentId则按协议与是否 SSL 映射到 SkyWalking 组件编号。五、Sink采样、丢弃与强制保留sink 是 LAL 的持久化层。默认情况下每个 filter 的日志都会保存到存储但 LAL 提供多种机制支持选择性保存甚至全部丢弃。1. Sampler按策略采样sampler 支持两种采样策略rateLimit按分钟限流采样。rateLimit(SamplerID)需要一个采样器 ID——相同 ID 的 sampler 声明共享同一个采样器实例因此共享rpm计数与重置逻辑sink { sampler { if (parsed.service ImportantApp) { rateLimit(ImportantAppSampler) { rpm 1800 // 对服务 ImportantApp 每分钟最多采样 1800 条 } } else { rateLimit(OtherSampler) { rpm 180 // 其他服务每分钟最多采样 180 条 } } } }possibility按百分比概率采样概率由 Java 随机数生成器产生并与此前给定的percentage比较sink { sampler { if (parsed.service ImportantApp) { possibility(80) { // 对服务 ImportantApp 采样 80% 的日志 } } else { possibility(30) { // 其他服务采样 30% 的日志 } } } }若同时指定了多个 sampler最后一个生效。2. Dropper无条件丢弃dropper 是特殊的 sink——所有日志无条件丢弃适合过滤 DEBUG 等调试日志sink { if (parsed.level DEBUG) { dropper {} } else { sampler { // ... 采样配置 } } }当配置了多个 filter其中一些仅用于提取指标时可以让用于落库的 filter 之外的 filter 全部 dropper——因为日志已在前面保存过filter { // filter A负责持久化 // ... parser sink { sampler { // ... 采样配置 } } } filter { // filter B只负责生成指标 // ... extractors 生成大量指标 extractors { metrics { // ... 指标配置 } } sink { dropper {} // 日志已在 filter A 保存这里全部丢弃 } }3. Enforcer强制采样enforcer 是另一种特殊 sink强制采样。典型场景是已经配置了 sampler但仍希望某些日志如错误日志、特定测试用户日志即使被采样策略命中也要强制保存sink { sampler { // ... 采样配置 } if (parsed.level ERROR || parsed.userId TestingUserId) { // 即使配置了采样策略也强制保存错误日志或测试用户日志 enforcer { } } }六、完整实战一套可运行的日志分析规则下面把前文的知识点串成一个完整示例。它出自官方发行版示例 dist-material/config-examples/lal.yaml文件实际路径应位于config/lal/下展示了 text 正则解析 指标提取 限流采样的完整链路rules: - name: example dsl: | filter { if (log.service TestService) { abort {} } text { if (!regexp($/(?s)(?timestamp\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}) \[TID:(?tid.?)] \[(?thread.?)] (?level\w{4,}) (?logger.{1,36}) (?msg.)/$)) { abort {} } } extractor { metrics { timestamp log.timestamp labels level: parsed.level, service: log.service, instance: log.serviceInstance name log_count value 1 } } sink { sampler { if (log.service ImportantApp) { rateLimit(ImportantAppSampler) { rpm 18000 } } else { rateLimit(OtherSampler) { rpm 1800 } } } } }配套的 MAL 指标规则参考 dist-material/config-examples/log-mal.yaml实际路径位于config/log-mal-rules/下可按日志级别计算 INFO 日志计数expSuffix: instance([service], [instance]) metricPrefix: log metricsRules: - name: count_info exp: log_count.tagEqual(level, INFO).sum([service, instance])部署时只要把上述 LAL 文件放入config/lal/目录、MAL 文件放入config/log-mal-rules/目录并在application.yml或环境变量中启用对应文件名即可# 通过环境变量启用示例 SW_LOG_LAL_FILESexample SW_LOG_MAL_FILESlog-mal-example七、总结SkyWalking 的日志分析能力可以概括为一条流水线接收器上报原生日志 → log-analyzer 模块加载 LAL 规则 → parser 结构化解析 → extractor 提取服务/实例/端点/链路 ID 与指标 → sink 按采样/丢弃/强制策略落库 → MAL 引擎对生成的指标做二次计算。整套机制将日志、链路trace与指标metrics三类可观测性数据打通通过traceId/segmentId/spanId提取器实现日志与链路的关联通过metricsextractor MAL 规则实现日志驱动的指标体系通过slowSqlextractor 实现数据库慢语句的 TopN 统计。深入理解 LAL 的完整语法可继续阅读 docs/en/concepts-and-designs/lal.mdMAL 的表达式与聚合能力见 docs/en/concepts-and-designs/mal.md日志上报协议字段定义log属性可访问的全部字段可参考数据收集协议中 Logging 协议的定义模块配置与加载的源码实现可分别查看 LogAnalyzerModuleConfig.java 与 DSL.java。赞分享可观测性后端微服务云原生【免费下载链接】skywalkingAPM, Application Performance Monitoring System项目地址https://gitcode.com/gh_mirrors/sky/skywalking点击查看免费下载相关推荐Apache SkyWalking 日志分析语言LAL完全指南从 DSL 语法到日志、链路与指标联动Apache SkyWalking 日志分析语言LAL完全指南从 DSL 语法到日志、链路与指标联动 导读 Log Analysis LanguageL可观测性后端微服务云原生SkyWalking OAP LAL DSL 调试 API 实战指南基于 DSL Debug API 逐语句剖析日志分析规则SkyWalking OAP LAL DSL 调试 API 实战指南基于 DSL Debug API 逐语句剖析日志分析规则 导读 本文是 SkyWalkin可观测性APM链路追踪指标监控日志分析微服务Apache SkyWalking日志关键字提取基于LAL的异常检测Apache SkyWalking日志关键字提取基于LAL的异常检测 一、日志分析的痛点与解决方案 在分布式系统监控中日志数据犹如散落的拼图碎片传统人工筛可观测性后端微服务云原生创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考