本文最后更新于 2024-06-07,

若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益, 请联系我 删除。

本站只有Telegram群组为唯一交流群组, 点击加入

文章内容有误?申请成为本站文章修订者或作者? 向站长提出申请

1717701084874.webp

前言

在对公司容器云的日志方案进行设计的时候,发现主流的 ELK(Elasticsearch,Logstash,Kibana)或者 EFK(Elasticsearch,Filebeat or Fluentd,Kibana)比较重,再加上现阶段对于 ES 复杂的搜索功能很多都用不上,最终选择了 Grafana 开源的 Loki 日志系统。

下面我们来介绍下 Loki 的一些基本概念和架构,当然 EFK 作为业界成熟的日志聚合解决方案也是大家应该需要熟悉和掌握的。

简介

Loki 是 Grafana Labs 团队最新的开源项目,是一个水平可扩展,高可用性,多租户的日志聚合系统。

它的设计非常经济高效且易于操作,因为它不会为日志内容编制索引,而是为每个日志流编制一组标签,专门为 Prometheus 和 Kubernetes 用户做了相关优化。

该项目受 Prometheus 启发,官方的介绍就是:Like Prometheus,But For Logs。类似于 Prometheus 的日志系统。

项目地址:https://github.com/grafana/loki/

与其他日志聚合系统相比,Loki 具有下面的一些特性:

  • 不对日志进行全文索引。通过存储压缩非结构化日志和仅索引元数据,Loki 操作起来会更简单,更省成本。
  • 通过使用与 Prometheus 相同的标签记录流对日志进行索引和分组,这使得日志的扩展和操作效率更高,能对接 alertmanager。
  • 特别适合储存 Kubernetes Pod 日志;诸如 Pod 标签之类的元数据会被自动删除和编入索引。
  • 受 Grafana 原生支持,避免 kibana 和 grafana 来回切换。

架构说明

1717701222609.webp

组件说明

说明如下:

  • Promtail 作为采集器,类比 filebeat
  • Loki 相当于服务端,类比 es

Loki 进程包含四种角色:

  • querier 查询器
  • inester 日志存储器
  • query-frontend 前置查询器
  • distributor 写入分发器

可以通过 Loki 二进制的 -target 参数指定运行角色。

read path

如下:

  • 查询器接受 HTTP/1 数据请求
  • 查询器将查询传递给所有 ingesters 请求内存中的数据
  • 接收器接受读取的请求,并返回与查询匹配的数据(如果有)
  • 如果没有接受者返回数据,则查询器会从后备存储中延迟加载数据并对其执行查询
  • 查询器将迭代所有接收到的数据并进行重复数据删除,从而通过 HTTP/1 连接返回最终数据集
write path

1717701254946.webp

如上图:

  • 分发服务器收到一个 HTTP/1 请求,以存储流数据
  • 每个流都使用散列环散列
  • 分发程序将每个流发送到适当的 inester 和其副本(基于配置的复制因子)
  • 每个实例将为流的数据创建一个块或将其追加到现有块中,, 每个租户和每个标签集的块都是唯一的
  • 分发服务器通过 HTTP/1 链接以成功代码作为响应

部署

本地化模式安装

下载 Promtail 和 Loki:

wget  https://github.com/grafana/loki/releases/download/v2.9.8/loki-linux-amd64.zip 
wget https://github.com/grafana/loki/releases/download/v2.9.8/promtail-linux-amd64.zip

安装 Promtail

创建文件夹
mkdir /opt/app/{promtail,loki} -pv
promtail配置文件
cat <<EOF> /opt/app/promtail/promtail.yaml
server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /var/log/positions.yaml # This location needs to be writeable by promtail.

client:
  url: http://localhost:3100/loki/api/v1/push

scrape_configs:
 - job_name: system
   pipeline_stages:
   static_configs:
   - targets:
      - localhost
     labels:
      job: varlogs
      host: yourhost
      __path__: /var/log/*.log
EOF
解压安装包
unzip promtail-linux-amd64.zip
mv promtail-linux-amd64 /opt/app/promtail/promtail
service配置文件
cat <<EOF >/etc/systemd/system/promtail.service
[Unit]
Description=promtail server
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/opt/app/promtail/promtail -config.file=/opt/app/promtail/promtail.yaml
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=promtail
[Install]
WantedBy=default.target
EOF
重启服务
systemctl daemon-reload
systemctl restart promtail
systemctl status promtail
安装 Loki
promtail配置文件
cat <<EOF> /opt/app/loki/loki.yaml
auth_enabled: false

server:
  http_listen_port: 3100
  grpc_listen_port: 9096

ingester:
  wal:
    enabled: true
    dir: /opt/app/loki/wal
  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: /opt/app/loki/boltdb-shipper-active
    cache_location: /opt/app/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: /opt/app/loki/chunks

compactor:
  working_directory: /opt/app/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: /opt/app/loki/rules
  rule_path: /opt/app/loki/rules-temp
  alertmanager_url: http://localhost:9093
  ring:
    kvstore:
      store: inmemory
  enable_api: true
EOF
解压安装包
unzip loki-linux-amd64.zip 
mv loki-linux-amd64 /opt/app/loki/loki
service配置文件
cat <<EOF >/etc/systemd/system/loki.service
[Unit]
Description=loki server
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/opt/app/loki/loki -config.file=/opt/app/loki/loki.yaml
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=loki
[Install]
WantedBy=default.target
EOF
重启服务
systemctl daemon-reload
systemctl restart loki
systemctl status loki

安装Grafana

Ubuntu22
更新系统包
sudo apt update
sudo apt upgrade -y
安装所需的依赖
sudo apt install -y apt-transport-https software-properties-common wget
添加Grafana的APT存储库
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
sudo add-apt-repository "deb https://packages.grafana.com/oss/deb stable main"
更新APT包列表并安装Grafana
sudo apt update
sudo apt install -y grafana
启动并启用Grafana服务
sudo systemctl start grafana-server
sudo systemctl enable grafana-server
访问Grafana
http://your_server_ip:3000

默认的登录用户名和密码都是 admin。第一次登录时,系统会提示你修改密码。

配置防火墙(可选)

如果你的系统启用了防火墙(例如 ufw),你需要允许3000端口的访问:

sudo ufw allow 3000/tcp
Centos7
添加Grafana的YUM存储库
sudo tee /etc/yum.repos.d/grafana.repo <<-'EOF'
[grafana]
name=Grafana Repository - rpm
baseurl=https://packages.grafana.com/oss/rpm
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://packages.grafana.com/gpg.key
EOF
更新YUM缓存并安装Grafana
sudo yum update -y
sudo yum install -y grafana
启动并启用Grafana服务
sudo systemctl start grafana-server
sudo systemctl enable grafana-server
配置防火墙

如果你启用了防火墙,需要允许3000端口的访问(Grafana默认运行在3000端口):

sudo firewall-cmd --zone=public --add-port=3000/tcp --permanent
sudo firewall-cmd --reload
访问Grafana

打开浏览器,访问以下URL:

http://<your_server_ip>:3000
使用阿里源加速

如果你在中国大陆,可以使用阿里源来加速安装包的下载。你可以修改Grafana的YUM存储库为阿里云镜像:

sudo tee /etc/yum.repos.d/grafana.repo <<-'EOF'
[grafana]
name=Grafana Repository - rpm
baseurl=https://mirrors.aliyun.com/grafana/yum/rpm
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/grafana/yum/rpm/gpg.key
EOF

Grafana配置为中文

vim /etc/grafana/grafana.ini

将default_language = en-US改为 zh-Hans即可,存在部分翻译不完全

#default_language = en-US
default_language = zh-Hans

重启服务

sudo systemctl restart grafana-server

使用

grafana 上配置 loki 数据源

1717702384141.webp在数据源列表中选择 Loki,配置 Loki 源地址:

1717702462056.webp

源地址配置 http://loki:3100 即可,保存。

保存完成后,切换到 grafana 左侧区域的 Explore,即可进入到 Loki 的页面。

然后我们点击 Log labels 就可以把当前系统采集的日志标签给显示出来,可以根据这些标签进行日志的过滤查询:

1717702523914.webp

比如我们这里选择 varlogs,就会把该文件下面的日志过滤展示出来,不过由于时区的问题,可能还需要设置下时间才可以看到数据:

1717702602135.webp

在 grafana explore 上配置查看日志
查看日志 rate({job="message"} |="kubelet"

算 qps rate({job=”message”} |=”kubelet” [1m])

只索引标签

之前多次提到 loki 和 es 最大的不同是 loki 只对标签进行索引而不对内容索引。下面我们举例来看下。

静态标签匹配模式

以简单的 promtail 配置举例:

scrape_configs:
 - job_name: system
   pipeline_stages:
   static_configs:
   - targets:
      - localhost
     labels:
      job: message
      __path__: /var/log/messages

配置解读:

  • 上面这段配置代表启动一个日志采集任务
  • 这个任务有 1 个固定标签 job=”syslog”
  • 采集日志路径为 /var/log/messages,会以一个名为 filename 的固定标签
  • 在 promtail 的 web 页面上可以看到类似 prometheus 的 target 信息页面

可以和使用 Prometheus 一样的标签匹配语句进行查询。

{job="syslog"}:

scrape_configs:
 - job_name: system
   pipeline_stages:
   static_configs:
   - targets:
      - localhost
     labels:
      job: syslog
      __path__: /var/log/syslog
 - job_name: system
   pipeline_stages:
   static_configs:
   - targets:
      - localhost
     labels:
      job: apache
      __path__: /var/log/apache.log

如果我们配置了两个 job,则可以使用job=~”apachesyslog”进行多 job 匹配;同时也支持正则和正则非匹配。

标签匹配模式的特点
原理如下:
  • 和 prometheus 一致,相同标签对应的是一个流 prometheus 处理 series 的模式
  • prometheus 中标签一致对应的同一个 hash 值和 refid(正整数递增的 id),也就是同一个 series
  • 时序数据不断的 append 追加到这个 memseries 中
  • 当有任意标签发生变化时会产生新的 hash 值和 refid,对应新的 series

loki 处理日志的模式和 prometheus 一致,loki 一组标签值会生成一个 stream。日志随着时间的递增会追加到这个 stream 中,最后压缩为 chunk。当有任意标签发生变化时会产生新的 hash 值,对应新的 stream。

查询过程
  • 所以 loki 先根据标签算出 hash 值在倒排索引中找到对应的 chunk?
  • 然后再根据查询语句中的关键词等进行过滤,这样能大大的提速
  • 因为这种根据标签算哈希在倒排中查找 id,对应找到存储的块在 prometheus 中已经被验证过了
  • 属于开销低
  • 速度快
动态标签和高基数

所以有了上述知识,那么就得谈谈动态标签的问题了。

两个概念:

  • 何为动态标签:说白了就是标签的 value 不固定
  • 何为高基数标签:说白了就是标签的 value 可能性太多了,达到 10 万,100 万甚至更多

比如 apache 的 access 日志:

11.11.11.11 - frank [25/Jan/2000:14:00:01 -0500] "GET /1986.js HTTP/1.1" 200 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6"

在 Promtail 中使用 regex 想要匹配 action 和 status_code 两个标签:

scrape_configs:
 - job_name: system
   pipeline_stages:
   static_configs:
   - targets:
      - localhost
     labels:
      job: syslog
      __path__: /var/log/syslog
 - job_name: system
   pipeline_stages:
   static_configs:
   - targets:
      - localhost
     labels:
      job: apache
      __path__: /var/log/apache.log

  - job_name: system
    pipeline_stages:
       - regex:
         expression: "^(?P<ip>\\S+) (?P<identd>\\S+) (?P<user>\\S+) \\[(?P<timestamp>[\\w:/]+\\s[+\\-]\\d{4})\\] \"(?P<action>\\S+)\\s?(?P<path>\\S+)?\\s?(?P<protocol>\\S+)?\" (?P<status_code>\\d{3}|-) (?P<size>\\d+|-)\\s?\"?(?P<referer>[^\"]*)\"?\\s?\"?(?P<useragent>[^\"]*)?\"?$"
     - labels:
         action:
         status_code:
    static_configs:
    - targets:
       - localhost
      labels:
       job: apache
       env: dev
       __path__: /var/log/apache.log

那么对应 action=get/post 和 status_code=200/400 则对应 4 个流:

11.11.11.11 - frank [25/Jan/2000:14:00:01 -0500] "GET /1986.js HTTP/1.1" 200 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6"
11.11.11.12 - frank [25/Jan/2000:14:00:02 -0500] "POST /1986.js HTTP/1.1" 200 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6"
11.11.11.13 - frank [25/Jan/2000:14:00:03 -0500] "GET /1986.js HTTP/1.1" 400 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6"
11.11.11.14 - frank [25/Jan/2000:14:00:04 -0500] "POST /1986.js HTTP/1.1" 400 932 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6"

那四个日志行将变成四个单独的流,并开始填充四个单独的块。

如果出现另一个独特的标签组合(例如 status_code =“500”),则会创建另一个新流。

高基数问题

就像上面,如果给 ip 设置一个标签,现在想象一下,如果您为设置了标签 ip,来自用户的每个不同的 ip 请求不仅成为唯一的流。可以快速生成成千上万的流,这是高基数,这可以杀死 Loki。

如果字段没有被当做标签被索引,会不会查询很慢,Loki 的超级能力是将查询分解为小块并并行分发,以便您可以在短时间内查询大量日志数据。

全文索引问题

大索引既复杂又昂贵。通常,日志数据的全文索引的大小等于或大于日志数据本身的大小。

要查询日志数据,需要加载此索引,并且为了提高性能,它可能应该在内存中。这很难扩展,并且随着您摄入更多日志,索引会迅速变大。

Loki 的索引通常比摄取的日志量小一个数量级,索引的增长非常缓慢。

加速查询没标签字段:以上边提到的 ip 字段为例 - 使用过滤器表达式查询。
{job="apache"} |= "11.11.11.11"
loki 查询时的分片(按时间范围分段 grep):
  • Loki 将把查询分解成较小的分片,并为与标签匹配的流打开每个区块,并开始寻找该 IP 地址。
  • 这些分片的大小和并行化的数量是可配置的,并取决于您提供的资源
  • 如果需要,您可以将分片间隔配置为 5m,部署 20 个查询器,并在几秒钟内处理千兆字节的日志
  • 或者,您可以发疯并设置 200 个查询器并处理 TB 的日志!
两种索引模式对比:
  • es 的大索引,不管你查不查询,他都必须时刻存在。比如长时间占用过多的内存
  • loki 的逻辑是查询时再启动多个分段并行查询
日志量少时少加标签:
  • 因为每多加载一个 chunk 就有额外的开销
  • 举例,如果该查询是 {app=”loki”,level!=”debug”}
  • 在没加 level 标签的情况下只需加载一个 chunk 即 app=“loki” 的标签
  • 如果加了 level 的情况,则需要把 level=info,warn,error,critical 5 个 chunk 都加载再查询
需要标签时再去添加:
  • 当 chunk_target_size=1MB 时代表 以 1MB 的压缩大小来切割块
  • 对应的原始日志大小在 5MB-10MB,如果日志在 max_chunk_age 时间内能达到 10MB,考虑添加标签
日志应当按时间递增:
  • 这个问题和 tsdb 中处理旧数据是一样的道理
  • 目前 loki 为了性能考虑直接拒绝掉旧数据

独立日志采集

要使用 Grafana Loki 来收集和监控其他服务器上的特定日志文件(例如 /log/log/Log.log),你可以按照以下步骤进行配置。这里我们将使用 Promtail 作为日志收集器。

假设你已经在你的主服务器上安装了 Loki 并运行。

在被监控服务器上安装 Promtail

在每个被监控的服务器上安装 Promtail:

  • 下载 Promtail
# 假设你使用的是Linux x86_64架构
wget https://github.com/grafana/loki/releases/download/v2.9.8/promtail-linux-amd64.zip
unzip promtail-linux-amd64.zip
chmod a+x promtail-linux-amd64
sudo mv promtail-linux-amd64 /usr/local/bin/promtail
  • 配置 Promtail

创建一个 Promtail 配置文件 promtail-config.yaml。以下是一个示例配置文件,专门用于采集 /root/log/Log.log 文件:

server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /你的文件位置/positions.yaml

clients:
  - url: http://<loki-server-ip>:3100/loki/api/v1/push

scrape_configs:
  - job_name: logproxy
    static_configs:
      - targets:
          - localhost
        labels:
          job: logproxy
          __path__: /root/log/Log.log

请根据实际情况修改 <loki-server-ip> 为你的 Loki 服务器的 IP 地址。

  • 运行 Promtail

使用以下命令启动 Promtail:

promtail -config.file=promtail-config.yaml

为了确保 Promtail 在系统重启后自动启动,可以创建一个 systemd 服务:

sudo tee /etc/systemd/system/promtail.service <<EOF
[Unit]
Description=Promtail service
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/promtail -config.file=/path/to/promtail-config.yaml
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable promtail
sudo systemctl start promtail

在 Grafana 中配置 Loki 数据源
  • 添加 Loki 数据源

打开 Grafana Web 界面,登录后进入设置(齿轮图标),选择 “Data Sources”(数据源),然后点击 “Add data source”(添加数据源)。

  • 选择 Loki

在数据源列表中选择 “Loki”。

  • 配置 Loki 数据源

在 URL 字段中输入你的 Loki 服务器地址,例如 http://<loki-server-ip>:3100。完成后点击 “Save & Test”(保存并测试)。

创建仪表板
  • 创建新的仪表板

在 Grafana 中点击 “+” 图标,然后选择 “Dashboard” 来创建一个新的仪表板。

  • 添加查询面板

在新仪表板中,添加一个新的面板。选择 Loki 作为数据源,然后输入查询语句,例如:

{job="logproxy"}

根据需要配置面板的显示样式、时间范围等,完成后保存仪表板。

定时采集日志

Promtail 和 Loki 的设计目的是用于实时收集和监控日志。如果你希望每天定时获取一次日志,可能需要采取不同的方法,比如使用定时任务(cron job)来实现这一功能。以下是如何在 CentOS 7 上使用 cron job 定时获取日志并将其推送到 Loki 的步骤。

创建日志收集脚本

首先,创建一个脚本,该脚本会在指定时间收集日志并推送到 Loki。

sudo nano /usr/local/bin/push_logs.sh

在脚本中添加以下内容:

#!/bin/bash

# 配置变量
LOKI_URL="http://<loki-server-ip>:3100/loki/api/v1/push"
LOG_FILE="/root/log/Log.log"
HOSTNAME=$(hostname)

# 读取日志文件
LOG_CONTENT=$(cat $LOG_FILE)

# 构建JSON负载
json_payload=$(cat <<EOF
{
  "streams": [
    {
      "stream": {
        "job": "logproxy",
        "host": "$HOSTNAME"
      },
      "values": [
        [ "$(date +%s%N)", "$LOG_CONTENT" ]
      ]
    }
  ]
}
EOF
)

# 推送日志到Loki
curl -X POST -H "Content-Type: application/json" -d "$json_payload" $LOKI_URL

请确保将 <loki-server-ip> 替换为你的 Loki 服务器的实际 IP 地址。

保存并关闭文件,然后为脚本赋予执行权限:

sudo chmod +x /usr/local/bin/push_logs.sh
创建 Cron Job

编辑 cron 配置文件来创建一个定时任务,每天12点执行日志收集脚本。

sudo crontab -e

添加以下行:

0 12 * * * /usr/local/bin/push_logs.sh

这行命令会每天中午12点执行一次 push_logs.sh 脚本。

如果你计划每天定时推送一次日志,而不是实时监控,那么应该删除掉 Promtail 的 systemd 服务,因为 Promtail 的设计是用于实时日志收集和监控。

删除 Promtail 的 systemd 服务
  • 停止 Promtail 服务
sudo systemctl stop promtail
  • 禁用 Promtail 服务
sudo systemctl disable promtail
  • 删除 Promtail 服务文件
sudo rm /etc/systemd/system/promtail.service
sudo systemctl daemon-reload

在当前的脚本中,推送到 Loki 的日志是追加的,而不是覆盖的。每次运行脚本时,它会将当前日志文件的全部内容发送到 Loki,这意味着每天定时任务会将当时的整个日志文件内容推送一次。

如果你的日志文件是按天滚动的(例如,每天生成一个新的日志文件),那么上述方法没有问题。如果日志文件没有按天滚动,日志内容会每天增长,推送的内容会越来越多。为了避免这种情况,你可以仅推送新增加的日志内容。

修改脚本以仅推送新增日志

可以通过记录上次读取的位置来实现增量推送日志。以下是修改后的脚本,使用一个位置文件来记录上次读取的位置:

  • 创建增量推送日志脚本

编辑或创建 /usr/local/bin/push_incremental_logs.sh

sudo nano /usr/local/bin/push_incremental_logs.sh

添加以下内容并保存:

#!/bin/bash

# 配置变量
LOKI_URL="http://<loki-server-ip>:3100/loki/api/v1/push"
LOG_FILE="/root/log/Log.log"
POSITION_FILE="/tmp/log_position"
HOSTNAME=$(hostname)

# 获取上次读取的位置
if [ -f $POSITION_FILE ]; then
  LAST_POSITION=$(cat $POSITION_FILE)
else
  LAST_POSITION=0
fi

# 获取文件大小
FILE_SIZE=$(stat -c%s "$LOG_FILE")

# 如果文件被轮转(文件大小小于上次记录位置),重新开始读取
if [ $FILE_SIZE -lt $LAST_POSITION ]; then
  LAST_POSITION=0
fi

# 读取新增的日志内容
LOG_CONTENT=$(tail -c +$((LAST_POSITION + 1)) "$LOG_FILE")

# 更新位置文件
echo $FILE_SIZE > $POSITION_FILE

# 构建JSON负载
json_payload=$(cat <<EOF
{
  "streams": [
    {
      "stream": {
        "job": "logproxy",
        "host": "$HOSTNAME"
      },
      "values": [
        [ "$(date +%s%N)", "$LOG_CONTENT" ]
      ]
    }
  ]
}
EOF
)

# 推送日志到Loki
curl -X POST -H "Content-Type: application/json" -d "$json_payload" $LOKI_URL

确保将 <loki-server-ip> 替换为你的 Loki 服务器的实际 IP 地址,并为脚本赋予执行权限:

sudo chmod +x /usr/local/bin/push_incremental_logs.sh
  • 更新 Cron Job

编辑 Cron 配置文件来创建一个定时任务,每天12点执行日志收集脚本:

sudo crontab -e

添加以下行:

0 12 * * * /usr/local/bin/push_incremental_logs.sh

通过这种方式,脚本将每天只推送新增的日志内容,而不是整个日志文件的内容。这将减少推送的数据量,并确保日志数据在 Loki 中的连续性。如果发送日志的机器默认只保留7天的日志,Loki 将能够正确地保留并展示这些日志

处理日志文件轮转

Promtail会自动检测到日志文件的轮转,并处理新的日志文件。这意味着当你的程序将日志打包存放到别的地方并创建一个新的日志文件时,Promtail会继续从新的日志文件中读取内容并推送到Loki。

配置Promtail以处理文件轮转

创建或编辑Promtail的配置文件 promtail-config.yaml,使其能够处理日志文件轮转:

server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /你的文件位置/positions.yaml

clients:
  - url: http://<loki-server-ip>:3100/loki/api/v1/push

scrape_configs:
  - job_name: logproxy
    static_configs:
      - targets:
          - localhost
        labels:
          job: logproxy
          __path__: /root/log/Log.log

请确保将 <loki-server-ip> 替换为你的 Loki 服务器的实际 IP 地址。

创建启动 Promtail 的脚本

创建一个脚本来启动 Promtail:

sudo nano /usr/local/bin/start_promtail.sh

添加以下内容并保存:

#!/bin/bash

# 启动 Promtail 并指定配置文件
/usr/local/bin/promtail -config.file=/path/to/promtail-config.yaml

确保为脚本赋予执行权限:

sudo chmod +x /usr/local/bin/start_promtail.sh
使用 Cron Job 定时启动 Promtail

编辑 Cron 配置文件来创建一个定时任务,每天启动 Promtail:

sudo crontab -e

添加以下行:

0 12 * * * /usr/local/bin/start_promtail.sh

这行命令会每天中午12点执行一次 start_promtail.sh 脚本。

通过这些步骤,你可以确保在日志文件轮转后,Promtail仍然能够连续收集并推送新的日志内容到 Loki。Promtail的文件轮转处理功能可以确保日志数据的连续性,即使在日志文件被重命名或移动的情况下。

日志存放

在Loki中,日志数据存储的位置和删除方式取决于你如何配置了Loki的存储后端。Loki支持多种存储后端,如本地文件系统、对象存储(如S3、GCS)等

  • 本地文件系统

如果你配置Loki使用本地文件系统存储日志数据,通常配置文件中会指定一个目录。例如:

storage_config:
  boltdb:
    directory: /data/loki/index

  filesystem:
    directory: /data/loki/chunks

在这种情况下,日志数据存储在 /data/loki/index/data/loki/chunks 目录下。

  • 对象存储

如果你使用对象存储(如AWS S3或GCS),日志数据将存储在指定的桶中。配置示例如下:

storage_config:
  aws:
    s3: s3://bucket-name

手动删除日志数据

手动删除某个节点的日志文件涉及删除存储后端的相关数据。以下是如何操作的说明:

本地文件系统

  • 停止Loki服务

为了安全删除文件,首先停止Loki服务:

sudo systemctl stop loki
  • 找到并删除相关文件

查找并删除相关的日志文件。例如,删除特定时间段或节点的日志文件:

rm -rf /data/loki/index/<specific-index-files>
rm -rf /data/loki/chunks/<specific-chunk-files>
  • 重启Loki服务

删除文件后,重新启动Loki服务:

sudo systemctl start loki

对象存储

  • 使用对象存储的管理工具

使用对象存储服务提供的管理工具或API来删除特定日志文件。例如,使用AWS CLI删除S3桶中的对象:

aws s3 rm s3://bucket-name/path/to/log-file
注意
  • 数据一致性:手动删除日志文件可能会导致数据不一致。如果需要定期删除日志数据,建议使用Loki的Retention机制。
  • 保留策略:配置Loki的保留策略,以自动管理日志数据的生命周期。例如,配置一个7天的保留策略:
table_manager:
  retention_deletes_enabled: true
  retention_period: 168h  # 7 days

如果你要查找loki的日志文件存放路径,请按以下操作

查找Loki的配置文件

Loki的配置文件通常位于以下路径之一:

  • /etc/loki/loki-local-config.yaml
  • /etc/loki/loki.yaml
  • 你在启动Loki时指定的任何其他路径
查看配置文件中的存储设置

打开Loki的配置文件并查看 storage_config部分。

识别存储路径

在配置文件的 storage_config部分,你可以看到日志文件的存储位置:

  • boltdb.directory: 用于存储索引数据。
  • filesystem.directory: 用于存储日志块数据。

反向代理

参考教程:安装及使用

⚠️Nginx Proxy Manager(以下简称NPM)会用到80、443端口,所以本机不能占用(比如原来就有Nginx)

互联网使用请确保完成了域名解析