Loki
简介
Loki是 Grafana Labs 团队最新的开源项目,是一个水平可扩展,高可用性,多租户的日志聚合系统。它的设计非常经济高效且易于操作,因为它不会为日志内容编制索引,而是为每个日志流编制一组标签,为 Prometheus和 Kubernetes用户做了相关优化。项目受 Prometheus 启发,类似于 Prometheus 的日志系统。
整体架构
不难看出,Loki的架构非常简单,使用了和prometheus一样的标签来作为索引,也就是说,你通过这些标签既可以查询日志的内容也可以查询到监控的数据,不但减少了两种查询之间的切换成本,也极大地降低了日志索引的存储。
Loki将使用与prometheus相同的服务发现和标签重新标记库,编写了pormtail, 在k8s中promtail以daemonset方式运行在每个节点中,通过kubernetes api等到日志的正确元数据,并将它们发送到Loki。
日志存储架构
读写
日志数据的写主要依托的是Distributor和Ingester两个组件, 整体的流程如下:
Distributor
一旦promtail收集日志并将其发送给loki,Distributor就是第一个接收日志的组件。由于日志的写入量可能很大,所以不能在它们传入时将它们写入数据库。这会毁掉数据库。我们需要批处理和压缩数据。
Loki通过构建压缩数据块来实现这一点,方法是在日志进入时对其进行gzip操作,组件ingester是一个有状态的组件,负责构建和刷新chunck,当chunk达到一定的数量或者时间后,刷新到存储中去。每个流的日志对应一个ingester,当日志到达Distributor后,根据元数据和hash算法计算出应该到哪个ingester上面。
此外,为了冗余和弹性,我们将其复制n(默认情况下为3)次。
Ingester
ingester接收到日志并开始构建chunk:
基本上就是将日志进行压缩并附加到chunk上面。一旦chunk“填满”(数据达到一定数量或者过了一定期限),ingester将其刷新到数据库。我们对块和索引使用单独的数据库,因为它们存储的数据类型不同。
刷新一个chunk之后,ingester然后创建一个新的空chunk并将新条目添加到该chunk中。
Querier
读取就非常简单了,由Querier负责给定一个时间范围和标签选择器,Querier查看索引以确定哪些块匹配,并通过greps将结果显示出来。它还从Ingester获取尚未刷新的最新数据。
对于每个查询,一个查询器将为您显示所有相关日志。实现了查询并行化,提供分布式grep,使即使是大型查询也是足够的。
特点
与其他日志聚合系统相比, Loki具有下面的一些特性:
- 不对日志进行全文索引。通过存储压缩非结构化日志和仅索引元数据,Loki 操作起来会更简单,更省成本。
- 通过使用与 Prometheus 相同的标签记录流对日志进行索引和分组,这使得日志的扩展和操作效率更高。
- 特别适合储存 Kubernetes Pod 日志; 诸如 Pod 标签之类的元数据会被自动删除和编入索引。
- 受 Grafana 原生支持。
组成
- loki是主服务器,负责存储日志和处理查询。
- promtail是代理,负责收集日志并将其发送给 loki。
- Grafana 用于 UI 展示。
环境搭建
loki 下载
1
2
3
4
5
|
wget https://github.com/grafana/loki/releases/download/v1.3.0/loki-linux-amd64.zip
mkdir /usr/local/loki
unzip loki-linux-amd64.zip
mv loki-linux-amd64 loki
mv loki /usr/local/loki
|
loki 启动
- loki-local-config.yaml
官方地址:https://github.com/grafana/loki/blob/master/docs/configuration/examples.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
cd /usr/local/loki
vim loki-local-config.yaml
# 写入以下内容
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: 5m
chunk_retain_period: 30s
max_transfer_retries: 1
schema_config:
configs:
- from: 2018-04-15
store: boltdb
object_store: filesystem
schema: v9
index:
prefix: index_
period: 168h
storage_config:
boltdb:
directory: /tmp/loki/index
filesystem:
directory: /tmp/loki/chunks
limits_config:
enforce_metric_name: false
reject_old_samples: true
reject_old_samples_max_age: 168h
chunk_store_config:
max_look_back_period: 0
table_manager:
chunk_tables_provisioning:
inactive_read_throughput: 0
inactive_write_throughput: 0
provisioned_read_throughput: 0
provisioned_write_throughput: 0
index_tables_provisioning:
inactive_read_throughput: 0
inactive_write_throughput: 0
provisioned_read_throughput: 0
provisioned_write_throughput: 0
retention_deletes_enabled: false
retention_period: 0
|
1
2
|
cd /usr/local/loki
./loki -config.file=loki-local-config.yaml
|
配置系统服务
1
2
3
4
5
6
7
8
9
10
11
12
13
|
vim /etc/systemd/system/loki.service
# 写入以下内容
[Unit]
Description=loki
Wants=network-online.target
After=network-online.target
[Service]
Restart=on-failure
ExecStart=/usr/local/loki/loki --config.file=/usr/local/loki/loki-local-config.yaml
[Install]
WantedBy=multi-user.target
|
配置好均需要执行以下命令
1
|
systemctl daemon-reload
|
1
2
3
4
|
systemctl start loki.service
systemctl status loki.service
systemctl stop loki.service
systemctl restart loki.service
|
promtail 下载
1
2
3
4
5
|
wget https://github.com/grafana/loki/releases/download/v1.3.0/promtail-linux-amd64.zip
unzip promtail-linux-amd64.zip
mkdir /usr/local/promtail
mv promtail-linux-amd64 promtail
mv promtail /usr/local/promtail
|
promtail 启动
- promtail-local-config.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
cd /usr/local/promtail
vim promtail-local-config.yaml
# 写入以下内容
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://localhost:3100/loki/api/v1/push
scrape_configs:
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: varlogs
__path__: /var/log/*
|
1
2
|
cd /usr/local/promtail
./promtail -config.file=promtail-local-config.yaml
|
配置系统服务
1
2
3
4
5
6
7
8
9
10
11
12
13
|
vim /etc/systemd/system/promtail.service
#写入以下内容
[Unit]
Description=promtail
Wants=network-online.target
After=network-online.target
[Service]
Restart=on-failure
ExecStart=/usr/local/promtail/promtail --config.file=/usr/local/promtail/promtail-local-config.yaml
[Install]
WantedBy=multi-user.target
|
配置好执行以下命令
1
|
systemctl daemon-reload
|
1
2
3
4
|
systemctl start promtail.service
systemctl status promtail.service
systemctl restart promtail.service
systemctl stop promtail.service
|
grafana loki 接入
添加Data Source
Grafana Explore
选择Loki
LogQL 语法
选择器
对于查询表达式的标签部分,将放在{}中,多个标签表达式用逗号分隔:
1
|
{app="mysql",name="mysql-backup"}
|
支持的符号有:
- = 完全相同。
- != 不平等。
- =~ 正则表达式匹配。
- !~ 不要正则表达式匹配。
过滤表达式
编写日志流选择器后,您可以通过编写搜索表达式进一步过滤结果。搜索表达式可以文本或正则表达式。
如:
-
{job=“mysql”} |= “error”
-
{name=“kafka”} |~ “tsdb-ops.*io:2003”
-
{instance=~“kafka-[23]”,name=“kafka”} != kafka.server:type=ReplicaManager
支持多个过滤
-
{job=“mysql”} |= “error” != “timeout”
目前支持的操作符:
-
|= line包含字符串。
-
!= line不包含字符串。
-
|~ line匹配正则表达式。
-
!~ line与正则表达式不匹配。
查看更多
在查询出来的结果行后面有一个show context (查看上下文),点击这个按钮,默认展示结果行前10行和后10行。
Author
dylan
LastMod
2020-03-21
License
如需转载请注明文章作者和出处。谢谢!