业务日志报警

除了Loggie本身的报警,业务日志本身的监控报警也是一个常用的功能,比如在日志中包含了ERROR日志,可以发送报警,这种报警会更贴近业务本身,是基于metrics报警的一种很好的补充。

使用方式

有以下两种方式可以选择:

  • 采集链路检测报警:Loggie可以在Agent采集日志的时候,或者在中转机转发的时候,检测到匹配的异常日志,然后发送报警
  • 独立链路检测报警:单独部署Loggie,使用Elasticsearch source或者其他的source查询日志,然后匹配检测发送报警

采集链路检测

原理

采集链路不需要独立部署Loggie,但是由于在采集的数据链路上进行匹配,理论上会对传输性能造成一定影响,但胜在方便简单。

logAlert interceptor用于在日志传输的时候检测异常日志,异常日志会被封装成报警的事件发送至monitor eventbus的logAlert topic,由logAlert listener来消费。logAlert listener支持发送至任意http后端(可以多个)。
发送体根据自定义模板进行渲染,若模板未定义,则会发送原始数据。在配置模板前,可以先观察原始数据(设置debug模式启动),再进行模板配置,原始数据可能会根据pipeline配置被其他interceptor改动而与示例不同。

配置示例

1. 新增logAlert listener

配置新增logAlert listener发送告警配置。用于在检测到匹配的日志后,将日志报警发送至诸如alertManager等后端,详细配置可参考logAlert listener

全局Config文件

  1. loggie:
  2. monitor:
  3. logger:
  4. period: 30s
  5. enabled: true
  6. listeners:
  7. logAlert:
  8. addr: ["http://127.0.0.1:8080/loggie"]
  9. bufferSize: 100
  10. batchTimeout: 10s
  11. batchSize: 10
  12. linelimit: 10
  13. template: |
  14. {
  15. "alerts":
  16. [
  17. {{$first := true}}
  18. {{range .Alerts}}
  19. {{if $first}}{{$first = false}}{{else}},{{end}}
  20. {
  21. "labels": {
  22. "topic": "{{.fields.topic}}"
  23. },
  24. "annotations": {
  25. "message": "\nNew alert: \nbody:\n{{range .body}}{{.}}\n{{end}}\ncontainerid: {{._meta.pipelineName}}\nsource: {{._meta.sourceName}}\ncontainername: {{.fields.containername}}\nlogconfig: {{.fields.logconfig}}\nname: {{.fields.name}}\nnamespace: {{.fields.namespace}}\nnodename: {{.fields.nodename}}\npodname: {{.fields.podname}}\nfilename: {{.state.filename}}\n",
  26. "reason": "{{.reason}}"
  27. },
  28. "startsAt": "{{._meta.timestamp}}",
  29. "endsAt": "{{._meta.timestamp}}"
  30. }
  31. {{end}}
  32. ],
  33. {{$first := true}}
  34. {{range .Alerts}}
  35. {{if $first}}{{$first = false}}{{else}}
  36. "commonLabels": {
  37. "module": "{{._additions.module}}",
  38. "alertname": "{{._additions.alertname}}",
  39. "cluster": "{{._additions.cluster}}"
  40. }
  41. {{end}}
  42. {{end}}
  43. }
  44. filesource: ~
  45. filewatcher: ~
  46. reload: ~
  47. queue: ~
  48. sink: ~
  49. http:
  50. enabled: true
  51. port: 9196

上面的template模版表示发送的告警内容格式,使用go template格式。可参考GO Template,或者请自行搜索go template使用教程。

其中可使用类似{{._meta.timestamp}}等形式动态渲染原始alert数据中的字段。

alert字段解释

字段是否内置含义
_metaalert元数据
_meta.pipelineName表示pipeline名称
_meta.sourceName表示source名称
_meta.timestamp表示日志时间戳
bodylogBody
reason匹配成功原因
fieldsfield字段,由其余配置添加
state采集信息,需要在file source配置addonMeta: true
_additions由配置指定

原始alert数据为一个json,其中Alerts为固定的key。

原始alert数据示例

  1. {
  2. "Alerts": [
  3. {
  4. "_meta": {
  5. "pipelineName": "default/spring",
  6. "sourceName": "loggie-source-756fd6bb94-4skqv/loggie-alert/common",
  7. "timestamp": "2022-10-28T13:12:30.528824+08:00"
  8. },
  9. "body": [
  10. "2022-10-28 01:48:07.093 ERROR 1 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/]. [dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ArithmeticException: / by zero] with root cause",
  11. "",
  12. "java.lang.ArithmeticException: / by zero"
  13. ],
  14. "fields": {
  15. "containerid": "0dc5f07983bfdf7709ee4fce752679983c4184e94c70dab5fe6df5843d5cbb68",
  16. "containername": "loggie-alert",
  17. "logconfig": "spring",
  18. "name": "loggie-source",
  19. "namespace": "default",
  20. "nodename": "docker-desktop",
  21. "podname": "loggie-source-756fd6bb94-4skqv",
  22. "topic": "loggie"
  23. },
  24. "reason": "matches some rules",
  25. "state": {
  26. "bytes": 6913,
  27. "filename": "/var/log/pods/ default_loggie-source-756fd6bb94-4skqv_9da3e440-e749-4930-8e4d-41e0d5b66417/ loggie-alert/1.log",
  28. "hostname": "docker-desktop",
  29. "offset": 3836,
  30. "pipeline": "default/spring",
  31. "source": "loggie-source-756fd6bb94-4skqv/loggie-alert/common",
  32. "timestamp": "2022-10-28T13:12:30.527Z"
  33. },
  34. "_additions": {
  35. "namespace": "default",
  36. "cluster": "local",
  37. "alertname": "loggie-test",
  38. "module": "loggie"
  39. }
  40. }
  41. ]
  42. }

2. 增加logAlert interceptor

Pipeline中增加logAlert interceptor用于在采集的时候检测日志并匹配日志报警规则,可在ClusterLogConfig/LogConfig中引用。其中additions为给alert额外添加的字段,会放入alert原始数据的_addtions字段中,可用做模板渲染。

建议先使用debug模式(-log.level=debug)观察原始alert数据格式,再配置模板进行渲染,原始数据会受到其他配置的影响,这里仅展示一个示例。

详细配置可参考logAlert interceptor

Config

  1. apiVersion: loggie.io/v1beta1
  2. kind: Interceptor
  3. metadata:
  4. name: logalert
  5. spec:
  6. interceptors: |
  7. - type: logAlert
  8. matcher:
  9. contains: ["ERROR"]
  10. additions:
  11. module: "loggie"
  12. alertname: "loggie-test"
  13. cluster: "local"

匹配到日志告警规则之后,告警后端可接收到类似的数据如下所示:

Example

  1. {
  2. "alerts": [
  3. {
  4. "labels": {
  5. "topic": "loggie"
  6. },
  7. "annotations": {
  8. "message": "\nNew alert: \nbody:\n2022-10-28 01:48:07.093 ERROR 1 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ArithmeticException: / by zero] with root cause\n\njava.lang.ArithmeticException: / by zero\ncontainerid: 0dc5f07983bfdf7709ee4fce752679983c4184e94c70dab5fe6df5843d5cbb68\nsource: loggie-source-756fd6bb94-4skqv/loggie-alert/common\ncontainername: loggie-alert\nlogconfig: spring\nname: loggie-source\nnamespace: default\nnodename: docker-desktop\npodname: loggie-source-756fd6bb94-4skqv\nfilename: /var/log/pods/default_loggie-source-756fd6bb94-4skqv_9da3e440-e749-4930-8e4d-41e0d5b66417/loggie-alert/1.log\n",
  9. "reason": "matches some rules"
  10. },
  11. "startsAt": "2022-10-28T13:12:30.527Z",
  12. "endsAt": "2022-10-28T13:12:30.527Z"
  13. }
  14. ],
  15. "commonLabels": {
  16. "module": "loggie",
  17. "alertname": "loggie-test",
  18. "cluster": "local"
  19. }
  20. }

独立链路检测

原理

Loggie配置source采集日志,经过logAlert interceptor匹配时,可配置sendOnlyMatched仅将匹配成功的日志发送至alertWebhook sink,匹配失败的日志看作正常日志被忽略。建议在使用alertWebhook sink时,同时开启logAlert interceptor, 设置sendOnlyMatchedtrue搭配使用。

配置示例

配置新增alertWebhook sink。详细配置可参考alertWebhook Sink

Config

  1. sink:
  2. type: alertWebhook
  3. addr: http://localhost:8080/loggie
  4. linelimit: 10
  5. template: |
  6. {
  7. "alerts":
  8. [
  9. {{$first := true}}
  10. {{range .Alerts}}
  11. {{if $first}}{{$first = false}}{{else}},{{end}}
  12. {
  13. "labels": {
  14. "topic": "{{.fields.topic}}"
  15. },
  16. "annotations": {
  17. "message": "\nNew alert: \nbody:\n{{range .body}}{{.}}\n {{end}}\ncontainerid: {{._meta.pipelineName}}\nsource: {{. _meta.sourceName}}\ncontainername: {{.fields. containername}}\nlogconfig: {{.fields.logconfig}}\nname: {{.fields.name}}\nnamespace: {{.fields.namespace}} \nnodename: {{.fields.nodename}}\npodname: {{.fields. podname}}\nfilename: {{.state.filename}}\n",
  18. "reason": "{{.reason}}"
  19. },
  20. "startsAt": "{{._meta.timestamp}}",
  21. "endsAt": "{{._meta.timestamp}}"
  22. }
  23. {{end}}
  24. ],
  25. {{$first := true}}
  26. {{range .Alerts}}
  27. {{if $first}}{{$first = false}}{{else}}
  28. "commonLabels": {
  29. "namespace": "{{._additions.namespace}}",
  30. "module": "{{._additions.module}}",
  31. "alertname": "{{._additions.alertname}}",
  32. "cluster": "{{._additions.cluster}}"
  33. }
  34. {{end}}
  35. {{end}}
  36. }

logAlert Interceptor配置和接收方收到的报警与采集链路检测报警类似。