Loki 中小项目日志系统的不二之选
Loki 学习总结(1)—— Loki 中小项目日志系统的不二之选
前言
项目做正规了,日志系统是少不了的,目前大部分日志平台推荐基于 ELK 构建,不过 ELK 算是比较重了,架构太大,中小项目不太好 Hold 住,希望找一款简单一些的,如果实在找不到再上 ELK,这个时候一款名叫 Loki 的日志系统横空出世。Loki 是 Grafana Labs 团队最新的开源项目,是一个水平可扩展,高可用性,多租户的日志聚合系统。它的设计非常经济高效且易于操作,因为它不会为日志内容编制索引,而是为每个日志流编制一组标签。项目受 Prometheus 启发,官方的介绍就是:Like Prometheus, but for logs,类似于 Prometheus 的日志系统。
一、Loki 快速上手
Loki 作为日志系统的后起之秀,设计上可以说非常优秀,设计的理念就是为了让日志聚合更简单,它被设计为非常经济高效且易于操作。它不索引日志的内容,而是为每个日志流设置一组标签。它主要由三部分组成:
Promtail 是日志收集器,负责收集应用的日志并发送给 Loki。
Loki 用于日志的存储和解析,并提供查询 API 给下游展示。
Grafana 负责将 Loki 的日志可视化。
与其他日志聚合系统相比,Loki具有下面的一些特性:
- 不对日志进行全文索引。通过存储压缩非结构化日志和仅索引元数据,Loki 操作起来会更简单,更省成本。
- 通过使用与 Prometheus 相同的标签记录流对日志进行索引和分组,这使得日志的扩展和操作效率更高。
- 特别适合储存 Kubernetes Pod 日志; 诸如 Pod 标签之类的元数据会被自动删除和编入索引。
简单上手
Loki 安装
首先是安装,现在跑 demo 我优先选择快捷方便的 Docker。下面是我修改过的 Docker Compose 脚本,根据自己的需要改改就能一键启动 Loki。
version: "3"
networks:
loki:
services:
loki:
image: grafana/loki:2.2.1
container_name: loki-service
volumes:
# 将loki的配置文件挂载到本地 c:/docker/loki 目录
- c:/docker/loki:/etc/loki/
ports:
- "3100:3100"
command: -config.file=/etc/loki/loki.yml
networks:
- loki
promtail:
image: grafana/promtail:2.2.1
container_name: promtail-service
volumes:
# 为了读取本地的日志目录,这个是个默认配置目的就是为跑起来,生产肯定不是这样的。
- c:/docker/log:/var/log/
# promtail 的配置文件也挂载到本地 c:/docker/promtail目录
- c:/docker/promtail:/etc/promtail/
command: -config.file=/etc/promtail/promtail.yml
networks:
- loki
grafana:
image: grafana/grafana:latest
container_name: grafana-service
ports:
- "3000:3000"
networks:
- loki
上面的挂载目录 c:/docker/loki
和 c:/docker/promtail 可以
根据自己的情况修改。
Loki 配置
上面文件中的 -config.file=/etc/loki/loki.yml
是 Loki 的配置文件,我们需要将配置文件 loki.yml
提前放在 c:/docker/loki
下,我使用默认配置:
auth_enabled: false
server:
http_listen_port: 3100
ingester:
lifecycler:
address: 127.0.0.1
ring:
kvstore:
store: inmemory
replication_factor: 1
final_sleep: 0s
chunk_idle_period: 1h # Any chunk not receiving new logs in this time will be flushed
max_chunk_age: 1h # All chunks will be flushed when they hit this age, default is 1h
chunk_target_size: 1048576 # Loki will attempt to build chunks up to 1.5MB, flushing first if chunk_idle_period or max_chunk_age is reached first
chunk_retain_period: 30s # Must be greater than index read cache TTL if using an index cache (Default index read cache TTL is 5m)
max_transfer_retries: 0 # Chunk transfers disabled
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
storage_config:
boltdb_shipper:
active_index_directory: /loki/boltdb-shipper-active
cache_location: /loki/boltdb-shipper-cache
cache_ttl: 24h # Can be increased for faster performance over longer query periods, uses more disk space
shared_store: filesystem
filesystem:
directory: /loki/chunks
compactor:
working_directory: /loki/boltdb-shipper-compactor
shared_store: filesystem
limits_config:
reject_old_samples: true
reject_old_samples_max_age: 168h
chunk_store_config:
max_look_back_period: 0s
table_manager:
retention_deletes_enabled: false
retention_period: 0s
ruler:
storage:
type: local
local:
directory: /loki/rules
rule_path: /loki/rules-temp
alertmanager_url: http://localhost:9093
ring:
kvstore:
store: inmemory
enable_api: true
Promtail 的配置
和 Loki 类似,Promtail 也要在本地挂载的 c:/docker/promtail
目录下配置 promtail.yml
,这里也使用默认配置:
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: varlogs
# 这个跟挂载的位置有点关系,你可以猜猜
__path__: /var/log/*log
我猜测 /var/log/*log
就是读取日志的位置,所以我把它挂载到本地 c:/docker/log
,等下弄点日志到本地这个目录下,看看能读取出来不。
启动 Loki
配置完毕后执行 docker-compose -f <docker-compose.yml 路径> up
命令,会先下载镜像然后启动三个 Docker 容器。成功后打开 http://localhost:3000/
登录 Grafana,默认账号密码是 admin/admin
。然后在侧边栏添加数据源为 Loki。
然后点击 Log labels 就可以把当前系统采集的日志标签给显示出来,可以根据这些标签进行日志的过滤查询
然后配置 Loki 的 URL 为 http://loki:3100
,然后点确定和测试,有绿色提示就表示成功了。
Promtail 日志代理
目前 Promtail 可以从两个来源跟踪日志:本地日志文件和 systemd 日志,我们上面演示的就是本地日志文件的加载,这种方式是目前我唯一能够使用的途径,另一种途径是通过 K8S 的服务发现能力。
如果在多个应用服务器上部署对应的多个 Promtail 守护程序就能监视多个应用的静态日志文件,并通过 Loki API 将日志推送到 Loki 中进行聚合式的管理。
Promtail动态配置
我们只需要为 Loki 应用部署相关的 Promtail 守护程序即可。这里我仍然使用 Docker 对 Promtail 进行部署,不过我不能再使用默认配置了,这时的 config.yml 应该是:
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /var/log/positions.yaml
client:
url: http://${LOKI_HOST}:${LOKI_PORT}/loki/api/v1/push
scrape_configs:
- job_name: system
pipeline_stages:
static_configs:
- labels:
app: ${APP_NAME}
job: varlogs
host: ${LOG_HOST}
__path__: /var/log/*log
为了构建一个通用的配置,我将一些参数进行了动态化。这是 Loki2.1+ 版本提供的特性,可以使用 ${} 来引用环境变量,甚至你可以为其指定默认值 ${VAR:default_value}。但是你必须得知道为了开启这一特性需要在 Promtail 启动命令中添加选项 -config.expand-env。
Promtail Docker 镜像改造
根据这个我对 Promtail 的 Docker 镜像进行了改造,具体的 Dockerfile 为:
FROM grafana/promtail:2.2.1
LABEL AUTHOR = felord.cn
VOLUME ["/var/log/"]
EXPOSE 9080
ENV LOKI_HOST="localhost"
ENV LOKI_PORT=3100
ENV APP_NAME="APP"
ENV LOG_HOST="localhost"
COPY config.yml /etc/promtail/
CMD ["-config.file=/etc/promtail/config.yml", "-config.expand-env"]
你可以通过 docker build -t loki-promtail:1.0 .命令构建这个自定义 Promtail 镜像。基本的启动命令:
docker run -d --name promtail-service --network loki -v c:/docker/log:/var/log/ -e LOKI_HOST=loki -e APP_NAME=SpringBoot loki-promtail:1.0
其中挂载的目录 c:/docker/log 依然是应用的日志目录,LOKI_HOST 要保证能够同 Loki 服务器通信,无论你通过直连还是 Docker 网络(这里用了 Docker 网桥)。你可以可以使用 Docker Compose 将应用和 Promtail 进行捆绑,所有的 Promtail 将把对应的日志发往 Loki 进行集中式的管理。另外通过自定义的 Label 我们可以通过应用名称来搜索日志了。
二、Loki 语法
选择器
对于查询表达式的标签部分,将其包装在花括号中 {},然后使用键值对的语法来选择标签,多个标签表达式用逗号分隔,比如:
|=:日志行包含字符串
!=:日志行不包含字符串
|~:日志行匹配正则表达式
!~:日志行与正则表达式不匹配
1 # 精确匹配:|="2020-11-16 " 2 {app_kubernetes_io_instance="admin-service-test2-container-provider"}|="2020-11-16 " 1 # 模糊匹配:|~"2020-11-16 " 2 {app_kubernetes_io_instance="admin-service-test2-container-provider"}|~"2020-11-16 " 1 # 排除过滤:!=/!~ "数据中心" 2 {app_kubernetes_io_instance="admin-service-master-container-provider"}!="数据中心" 3 {app_kubernetes_io_instance="admin-service-master-container-provider"}!~"数据中心" 1 # 正则匹配: |~ "()" 2 {app_kubernetes_io_instance="admin-service-master-container-provider"}!~"(admin|web)" 3 {app_kubernetes_io_instance="admin-service-master-container-provider"}|~"ERROR|error"
其他:
https://huaweicloud.csdn.net/63311dccd3efff3090b52b5e.html?spm=1001.2101.3001.6650.19&utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~activity-19-125220408-blog-125771943.235^v35^pc_relevant_increate_t0_download_v2_base&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~activity-19-125220408-blog-125771943.235^v35^pc_relevant_increate_t0_download_v2_base&utm_relevant_index=26