前言

提及日志收集搜寻框架,最常看到的解决方案就是 ELK。尽管当初有 Docker、k8s 帮咱们简化了部署流程,但 ELK 对硬件的要求却很高。光是 Elasticsearch 官网就提及到须要 8 GB 内存以上的机器部署,可见占据的资源之多。为了能降本增效(穷~~~),在网上看到了 Grafana 团队的日志框架: Loki。为此进行了深刻的理解并利用在了一些我的项目上。

Loki 介绍

Loki 是 Grafana 团队开源的一款高可用、高拓展、多租户的日志聚合零碎,和 ELK 的组件性能一样,Loki 有负责日志存储查问的主服务,有在客户端负责收集日志并推送的代理服务,还有 Grafana 最拿手的可视化面板展现。

不同的是,Loki 不再依据日志内容去建设大量的索引,而是借鉴了 Prometheus 外围的思维,应用标签去对日志进行特色标记,而后归集统计。这样的话,能防止大量的内存资源占用,转向便宜的硬盘存储。当然 Loki 会对日志进行分块存储并压缩,保留大量的元数据索引,兼顾硬盘的查问效率。

除此之外,Loki 还有以下个性:

  • 一个 Loki 实例容许面向多个租户,不同租户的数据齐全与其余租户隔离。
  • LogQL:Loki 本人的日志查询语言,很容易上手应用的。
  • 高拓展性,Loki 的所有组件能够跑在同一个程序里,也能够按微服务的形式去部署它们。
  • 反对市面上许多风行的日志客户端插件,能较好的汇合在一起。

说白了,Loki 吸引人的中央就在于领有和 Prometheus 相似机制的时序数据库以及不便拓展的硬盘资源。

Loki 架构

上面,咱们来意识下 Loki 的总体架构。就像后面提及到的,Loki 次要分为了三局部:

  • agent client:日志代理客户端,负责收集日志发送到主服务 Loki,目前官网有本人的 client: Promtail,也反对支流的组件,如 Fluentd、Logstash、Fluent Bit 等。
  • loki:日志主服务,负责存储收集到的日志以及对日志查问解析。
  • grafana:日志数据展现面板。

能够看到,外围的组件其实是 Loki 这个主服务,对于它的外部组成,其实还能够细分为几局部:

  • Distributor:负责解决客户端发送过去的日志数据,测验正确性后将其分发给后续组件。
  • Ingester:负责将日志按块存储。
  • Query frontend:可选服务,对外提供查问 API,负责一些查问调整和整合。

Loki 的简略应用

Loki 的装置

对于 Loki 的装置十分的简略,大伙能够看官网的连贯:Install Grafana Loki with Docker or Docker Compose。自己实际了一下,应用了上面的 yaml 文件,以 docker-compose 形式进行了部署:

version: "3"services:    loki:        image: grafana/loki:2.4.0        ports:          - "3100:3100"        command: -config.file=/etc/loki/config.yaml        volumes:            - ./config/loki:/etc/loki            - loki-vm:/loki    grafana:        image: grafana/grafana:7.3.0        ports:          - "3000:3000"        volumes:            - grafana-vm:/var/lib/grafana        environment:            GF_SECURITY_ADMIN_PASSWORD: 123456            GF_SERVER_HTTP_PORT: 3000    promtail:        image: grafana/promtail:2.4.0        volumes:          - /var/log:/var/log        command: -config.file=/etc/config.yml        network_mode: "host"        volumes:            - "./config/promtail/etc:/etc"            - "./my-service/log:/var/log"            - "./my-service/log-position:/var/log-position"volumes:  grafana-vm:  loki-vm:

其中,对于 Loki 的配置文件,在本机的 ./config/loki 目录下须要有个 config.yaml,配置如下:

auth_enabled: falseserver:  http_listen_port: 3100  log_level: debugingester:  lifecycler:    address: 127.0.0.1    ring:      kvstore:        store: inmemory      replication_factor: 1    final_sleep: 0s  chunk_idle_period: 5m  chunk_retain_period: 30s  wal:    dir: /loki/walcompactor:  working_directory: /loki/persistent      # 压缩目录,个别也作为长久化目录  compaction_interval: 10m                 # 压缩距离  retention_enabled: true                  # 长久化开启  retention_delete_delay: 5m               # 过期后多久删除  retention_delete_worker_count: 150       # 过期删除协程数目schema_config:    configs:      - from: "2020-07-31"        index:            period: 24h            prefix: loki_index_        object_store: filesystem          # 长久化形式:本地文件        schema: v11        store: boltdb-shipperstorage_config:    boltdb_shipper:        active_index_directory: /loki/boltdb-index    # index 目录        cache_location: /loki/boltdb-cache            # cache 目录    filesystem:        directory: /loki/chunks                       # chunks 目录limits_config:  retention_period: 240h                              # 多久过期

对于 promtail 的配置文件,在本机的 ./config/promtail/etc 目录下须要有个 config.yaml,配置如下:

server:  http_listen_port: 9080  grpc_listen_port: 0positions:  filename: /var/log-position/positions.yaml # 日志上传地位client:  url: http://127.0.0.1:3100/loki/api/v1/pushscrape_configs:- job_name: my-service  static_configs:  - targets:      - localhost    labels:      job: my-service      __path__: /var/log/*.log

其中,在 promtail 的配置文件里有 __path__ 门路,这个就是咱们想要上传的日志文件门路了,它反对正则表达式。这样的话,只有咱们的服务有新的日志文件产生,那么它就会被推送到 Loki 了。

Grafana 的应用

下面将会把日志数据推送到 Loki ,接下来咱们就能够应用 Grafana 里的数据展现面板来查问咱们的日志了。在应用之前,咱们还得配置下 Grafana,在 http://服务器地址:3000 里输出配置的账号密码后,按以下步骤配置:

Data Sources 配置:

Manage 的配置:

最初一张图的输入框就是咱们想要查找日志关键字的中央了!

日志的标签

除了有 String Match 的输出外,咱们还看到了 App 的抉择。而这个 App 的抉择就是咱们提及 Loki 的重点:标签。此标签是咱们在 promtail 配置文件里 scrape_configs 下的 label 里的。只有咱们在这里配置一些标签,那么就能够对收集的日志进行标记而后在此过滤了,比方服务名、命名空间等。此外,它还反对 json 等格局的标签解析。

日志查询语言: LogQL

为了能满足各式各样的查问,比方蕴含、不蕴含、正则等查问,Loki 开发了属于本人的日志查询语言:LogQL。它就像 Prometheus 的 PromQL 一样,具备丰盛的查问语义,例如咱们能够点击如下的查问按钮:

就会跳转到如下界面:

如果咱们想要查找日志不蕴含某些关键字的,那么能够这么输出:

{job="my-service"} != "内容"

LogQL 的应用非常简单,这里列举一些罕用的语法:

|=: 蕴含!=: 不蕴含|~: 正则匹配!~: 不在正则匹配里的

总体上来讲,LogQL 的过滤分为了三种过滤,别离如下:

  • 标签匹配(Label matchers):例如 {job="my-service"},个别至多须要一个标签匹配,否则将检索所有数据了。
  • 行过滤器(Line filters):例如 != "内容",是对日志内容进行匹配过滤的。
  • 标签过滤器(Label filters):须要对标签进行转换计算,效率较低。

在 Loki 的官网里,有对于日志查问的一些最佳实际,上面总结列举一下,不便大家部署时留神:

  • 尽量应用动态标签,不应用动静标签,免得产生大量的小块文件
  • 在配置文件里尽量应用缓存,能放慢查问速度,配置反对 in-memory、memcached 和 redis。
  • Loki 的过滤成果是按标签匹配(Label matchers)、行过滤器(Line filters)、 标签过滤器(Label filters)逐级递加的,过滤条件越到前面匹配,将会越慢。尽量在后面就进行条件过滤。

遇到的问题

过期配置

在应用本地模式收集日志时,心愿日志的存储能在肯定工夫后革除,免得有限减少。过后看了官网的 Table Manager 和 Compactor。尝试了多种配置后,始终不失效,前面才发现,须要在 limits_config 里也配置。

查问超时

以后应用 Loki 的时候,发现查问日期较远,查问较简单时,会呈现 time out 状况,并且会莫名重启。前面发现原来是 2.4.0 的版本有 bug,会不定时的呈现 AllByUserID 的空指针拜访。前面更新到最新的 2.4.2 版本就能够了。

总结

Loki 在应用的过程中,的确比拟不便简略,特地是汇合了 Grafana 的查问面板以及它的类 Prometheus 的标签机制,让咱们的日志解决方案更加轻量。应用 Loki 期间也的确遇到了很多问题,大伙如果有趣味的话,能够尝试上手,后续一起交换探讨。


感兴趣的敌人能够搜一搜公众号「 阅新技术 」,关注更多的推送文章。
能够的话,就顺便点个赞、留个言、分享下,感激各位反对!
阅新技术,浏览更多的新常识。