Loki配置采集haproxy日志

  • 前言
  • 正文
  • haproxy格式化日志
  • Loki配置日志采集
  • 结语

前言

haproxy作为一个负载均衡器,能够有效的分摊应用的访问负载,一定程度上帮助应用避免单点风险,有时候,会有从haproxy日志中分析数据的需求。
当前的一个环境中,通过haproxy作为后端查询接口的负载均衡器,在haproxy日志中捕捉了http请求中的关键信息,结合Loki进行日志采集,提供了一种可视化分析的方式。

正文

haproxy格式化日志

默认的情况下,haproxy的日志记录的非常简单,只会记录请求从哪发送过来,类似下面这样:

haproxy 查看状态 haproxy查看日志_数据


这样的日志可以说是毫无作用的,所以要做亿点点修改才可以( • ̀ω•́ )✧

# 在对应的listen中加入一下配置项
        log global
        option http-buffer-request
        declare capture request len 40000
        http-request capture req.body id 0
        capture request header Host len 6400
        capture request header User-Agent len 5120
        capture request header X-Forwarded-For len 1000
        capture request header Referer len 2000
        capture response header Server len 400
        capture response header Server-ID len 400
        # log format这部分就是实际格式化的日志输出部分
        log-format "frontend:%f client:%ci:%cp method:%HM code:%ST url:%HP body:%[capture.req.hdr(0)] destination:%si:%sp"

至于怎么开启haproxy的日志记录,百度上都有一大把方法,实在不行就google一下,这里不赘述了;
配置完后,重启下haproxy,当然如果是1.7版本以上,官方说是支持热更新配置的,日志打印的格式会类似这样:

Jan 13 14:03:47 10.10.10.10 haproxy[40946]: frontend:druid-pools client:10.10.10.12:12345 method:POST code:200 url:/api/v1/query body:{"queryType":"sql","query":"SELECT * FROM TABELNAME","resultFormat":"array","header":true} destination:10.10.10.11:1234

Loki配置日志采集

针对上面的日志格式,我们要配置Loki对它进行采集,因为日志量不是很大,所以不需要去采用微服务的方式部署Loki,一体化的部署就可以了,同时还要部署promtail采集器去采集日志,官方文档中说明支持了很多采集器,promtail是配套的,除此之外使用logstash也是可以的,具体的参考官方文档。

loki的配置可以使用以下的:

auth_enabled: false

server:
  http_listen_port: 3100
  grpc_listen_port: 9096

common:
  # 数据目录的路径
  path_prefix: /data2/loki
  storage:
    filesystem:
      # 一般这部分直接使用${path_prefix}/chuncks
      chunks_directory: /data2/loki/chuncks
      # 一般这部分直接使用${path_prefix}/rules
      rules_directory: /data2/loki/rules
  # 副本数量,测试的情况下或者日志本身并不具备高数据安全要求的情况下就设置为1就好
  replication_factor: 1
  ring:
    instance_addr: 127.0.0.1
    kvstore:
      store: inmemory
schema_config:
  # 保留默认配置即可
  configs:
    - from: 2022-01-01
      store: boltdb-shipper
      object_store: filesystem
      schema: v11
      index:
        prefix: index_
        period: 24h
limits_config:
  # 这部分配置是为了增加日志采集的限制,默认的限制是很小的,很容易触发报错
  # 需要注意的是,报错本身只是会丢日志,不会导致采集器或者loki宕机
  enforce_metric_name: false
  reject_old_samples: true
  reject_old_samples_max_age: 168h
  ingestion_rate_mb: 40
  ingestion_burst_size_mb: 20
ruler:
  alertmanager_url: http://localhost:9093

接下来是promtail组件,用来监听haproxy.log的情况:

server:
  http_listen_port: 9080
  grpc_listen_port: 0
positions:
  # 这个文件是promtail记录日志偏移量的文件,每次采集这个文件都会更新
  # 就算服务宕机,下次重启的话也会从这个文件中记录的日志偏移量开始
  filename: /tmp/positions.yaml
clients: # 注意,此处将日志发送给Loki
  - url: http://localhost:3100/loki/api/v1/push
scrape_configs:
# 下面的配置部分就和Prometheus很相似了
  - job_name: system
    static_configs:
    - targets:
        - XXXXXX
      labels:
        # 静态标签,代表这个job下的所有日志都至少包含这两个标签
        job: haproxy
        # level,由于haproxy日志本身不包好log level,所以loki解析不出来
        # 正常的日志如果包含标准日志登记的标记则不需要设置这个标签
        level: info
        __path__: /var/log/haproxy/*.log
    pipeline_stages:
    - match:
        # 这部分对日志做处理,selector选择器用来筛选满足条件的日志流
        selector: '{job="haproxy"}'
        stages:
        - regex:
            # RE2格式的正则表达式,?P<XXX>代表把匹配的部分设置为变量
            expression: '(?P<time>[^ ]* +[^ ]* +[^ ]*) (?P<syslog_host>[\w-\.]+) (?P<ps>\w+)\[(?P<pid>\d+)\]:(?P<output>.*)'
        # 这一步我是为了把本身日志的时间记录和其他我不要的筛选掉,以output变量输出
        - output:
            source: output
    - match:
        # 虽然这里我依旧使用相同条件的选择器,但是此时的日志流已经被上面处理了一次了
        # 所以不要的信息已经不存在了
        selector: '{job="haproxy"}'
        stages:
        - regex:
            expression: 'frontend:(?P<frontend>\S+) haproxy:(?P<haproxy>\S+) client:(?P<client>\S+) method:(?P<method>\S+) code:(?P<code>\S+) url:(?P<url>\S+) destination:(?P<destination>\S+)}?$'
        - labels:
            # 动态标签生成
            frontend:
            method:
            code:
            destination:

随后我们依次启动promtail和loki即可,注意,第一次启动,会扫描匹配的所有完整日志,因为没有记录的日志偏移量,这样的造成的影响是,会发现出现大量429报错,server returned HTTP status 429 Too Many Requests (429),我的处理方法是第一次采集完成后,等待promtail扫描到不报错为止,然后停止loki服务,将loki的数据清空,重新再启动服务,这样做的目的是让promtail获取最新的日志偏移量,loki也能重置记录时间。

如果有大佬能有更好的方式请留言给我

现在日志已经采集到了,我们可以等待一会,然后在Grafana中进行配置,通过explore进行查询:

haproxy 查看状态 haproxy查看日志_haproxy 查看状态_02


目标达成,至于想要发掘什么样子的数据价值,就看使用的人了(o゜▽゜)o☆[BINGO!]

结语

Loki作为一个新生的日志采集工具,可能还不能完全代替ELK,但是从使用体验来看是非常友好的,而且我本身也不喜欢太重的系统,ELK就是典型的重型系统,无论是学习成本还是部署成本都不低,所以非常期待Loki以后的发展。