• Sentry、Loki 轻量级日志系统部署及应用


    image-20220929181948016

    Author:rab



    一、Sentry

    1.1 什么是 Sentry ?

    sentry 是一个实时的集中式日志管理系统其专注于错误监控以及提取一切事后处理所需信息而不依赖于麻烦的用户反馈。它分为客户端和服务端,客户端(目前客户端有 Javascript、Python、PHP、Go 等多种语言)就嵌入在你的应用程序中间。其采用的是 C/S 架构,客户端通过 SDK 的方式集成到应用程序中,并自动将错误发送到 Sentry 的服务端。

    image-20220920132625128

    它具备以下优点:

    • 多项目,多用户;
    • 界面友好;
    • 可以配置异常触发规则,例如监控到程序出现异常后发送邮件;
    • 支持主流语言接口(具体可查阅语言接口文档)。

    官方文档

    Github 地址

    1.2 规划及部署

    1.2.1 规划

    1、主机规划

    Hostserver说明
    CentOS7.9(192.168.56.132)Docker、Sentry轻量级日志系统

    2、版本规划

    • Docker:18.06.3
    • Sentry:
    1.2.2 部署
    1.2.2.1 Docker

    此处略… 需要部署脚本得私我。

    1.2.2.2 Sentry

    1、部署 redis

    • 创建持久化目录

      mkdir -p /data/sentry/redis/data/
      
    • 运行容器

      docker run -d --privileged=true --restart=always -v /data/sentry/redis/data:/data --name sentry-redis redis:6.0.9
      

    2、部署 Postgres

    • 创建持久化目录

      mkdir -p /data/sentry/postgres/data/
      
    • 运行容器

      docker run -d --privileged=true --restart=always  -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=sentry -v /data/sentry/postgres/data:/var/lib/postgresql/data --name sentry-postgres postgres:13.3
      

    3、部署 Sentry

    • 生成密钥

      docker run --rm sentry:9.1.2 config generate-secret-key
      
      # w+@-ofmi8zp8d4f=)scbfoeen-jj)tx%15h+e*wyc18spdy*mz
      
    • 初始化数据结构

      # 初始化数据结构,在升级过程中,系统将提示您创建将充当超级用户的初始用户(如果没有看FAQ部分)
      docker run -it --rm \
        -e SENTRY_SECRET_KEY='w+@-ofmi8zp8d4f=)scbfoeen-jj)tx%15h+e*wyc18spdy*mz' \
        --link sentry-postgres:postgres \
        --link sentry-redis:redis sentry:9.1.2 upgrade
      

      image-20220920111452601

    • 启动 Sentry(web 端)

      docker run -d \
        --name=sentry \
        --privileged=true \
        --restart=always \
        -p 9000:9000 \
        -e SENTRY_SECRET_KEY='w+@-ofmi8zp8d4f=)scbfoeen-jj)tx%15h+e*wyc18spdy*mz' \
        --link sentry-redis:redis \
        --link sentry-postgres:postgres sentry:9.1.2
      
    • 启动 Sentry(定时任务,活性检测等)

      docker run -d \
        --name=sentry-celery
        --privileged=true \
        --restart=always \
        -e SENTRY_SECRET_KEY='w+@-ofmi8zp8d4f=)scbfoeen-jj)tx%15h+e*wyc18spdy*mz' \
        --link sentry-postgres:postgres \
        --link sentry-redis:redis sentry:9.1.2 run cron
      
    • 启动 Sentry(业务处理,数据持久化,报警等)

      docker run -d \
        --name=sentry-worker-1 \
        --privileged=true \
        --restart=always \
        -e SENTRY_SECRET_KEY='w+@-ofmi8zp8d4f=)scbfoeen-jj)tx%15h+e*wyc18spdy*mz' \
        --link sentry-postgres:postgres \
        --link sentry-redis:redis sentry:9.1.2 run worker
      

    4、验证

    浏览器输入:http://192.168.56.180:9000/

    image-20220920114313058

    1.3 案例

    1、创建一个 Java 工程

    image-20220922142123198

    image-20220922142222501

    2、获取 DSN

    image-20220922141952897

    3、将 DSN 集成到 Java 代码中

    因为 Sentry 是一个 C/S 架构,我们需要在应用中集成 Sentry 的 SDK 才能在应用发生错误是将错误信息发送给 Sentry 服务端。根据语言和框架的不同,可以选择自动或自定义设置特殊的错误类型报告给 Sentry 服务端。

    image-20220926182941182

    1.4 FAQ

    1.4.1 数据初始化

    初始化数据结构未提示添加用户,解决方案:https://github.com/getsentry/sentry/issues/8862

    1、报错类型

    image-20220920114342934

    2、解决方案

    在 2.2.2 小节初始化数据结构时,并没有提示添加用户,因此需要我们进入 sentry 容器进行手动创建,具体步骤如下:

    • 进入 sentry 容器并执行以下语句

      docker exec -it sentry bash
      
      SENTRY_CONF=/etc/sentry /usr/local/bin/sentry shell
      from sentry.models import Project
      from sentry.receivers.core import create_default_projects
      create_default_projects([Project])
      
      # 完成后exit()退出sentry的shell终端
      

      image-20220920114126543

    • 继续在 sentry 容器创建用户

      SENTRY_CONF=/etc/sentry /usr/local/bin/sentry createuser
      

      image-20220920132001347

    • 再次验证一下

      浏览器输入:http://192.168.56.180:9000/

      输入刚刚设置的用户名/密码

      image-20220920114313058

      image-20220920121925896

    二、Loki

    主流的 ELK 或者 EFK 比较重,再加上现阶段对于 ES 复杂的搜索功能很多都用不上,Loki 是 Grafana 开源的日志系统。现有的很多日志采集的方案都是采用全文检索对日志进行索引(如ELK方案),优点是功能丰富,允许复杂的操作。但是,ELK 成本相对较高(服务器费用、维护等),因此我们可以采用轻量级的 Loki 系统。

    2.1 什么是 Loki ?

    Grafana Loki 是一组组件,可以组成一个功能齐全的日志堆栈。与其他日志系统不同,Loki 是围绕仅索引有关日志的元数据的想法构建的:标签(就像 Prometheus 标签一样)。然后,日志数据本身会被压缩并以块的形式存储在对象存储(例如 S3 或 GCS)中,甚至本地存储在文件系统中。小索引和高度压缩的块简化了操作并显着降低了 Loki 的成本。

    代理(也称为客户端)获取日志,将日志转换为流,并通过 HTTP API 将流推送到 Loki。Promtail 代理专为 Loki 安装而设计,但许多其他代理与 Loki 无缝集成。

    image-20220922164058713

    功能/特点

    • 用于索引日志的高效内存使用

      通过在一组标签上建立索引,索引可以显着小于其他日志聚合产品。内存越少,操作成本就越低。

    • 多用户

      Loki 允许多个用户使用单个 Loki 实例。不同用户的数据与其他用户完全隔离。通过在代理中分配租户 ID 来配置多租户。

    • LogQL 语言查询

      Prometheus 查询语言 PromQL 的用户会发现 LogQL 熟悉且灵活,可针对日志生成查询。该语言还有助于从日志数据生成指标,这是一个远远超出日志聚合的强大功能。

    • 可扩展性

      Loki 可以作为单个二进制文件运行;所有组件在一个进程中运行。

      Loki 专为可扩展性而设计,因为 Loki 的每个组件都可以作为微服务运行。配置允许单独扩展微服务,允许灵活的大规模安装。

    • 灵活性

      许多代理(客户端)都有插件支持。这允许当前的可观察性结构添加 Loki 作为其日志聚合工具,而无需切换可观察性堆栈的现有部分。

    • Grafana 集成

      Loki 与 Grafana 无缝集成,提供完整的可观察性堆栈。

    Loki 官方文档

    2.2 部署/日志采集

    2.2.1 Docker
    2.2.1.1 Loki

    1、创建相关文件

    mkdir -p /home/data/loki/{conf,chunks,rules}
    

    2、下载配置文件

    cd /home/data/loki/conf
    wget --no-check-certificate https://raw.githubusercontent.com/grafana/loki/v2.6.1/cmd/loki/loki-local-config.yaml -O loki-config.yaml
    
    cat loki-config.yaml
    
    auth_enabled: false
    
    server:
      http_listen_port: 3100
      grpc_listen_port: 9096
    
    common:
      path_prefix: /tmp/loki
      storage:
        filesystem:
          chunks_directory: /tmp/loki/chunks
          rules_directory: /tmp/loki/rules
      replication_factor: 1
      ring:
        instance_addr: 127.0.0.1
        kvstore:
          store: inmemory
    
    schema_config:
      configs:
        - from: 2020-10-24
          store: boltdb-shipper
          object_store: filesystem
          schema: v11
          index:
            prefix: index_
            period: 24h
    
    ruler:
      alertmanager_url: http://localhost:9093
    

    3、目录权限

    chmod -R 777 /home/data/loki/*
    

    4、运行容器

    docker run -d -u root \
      --name=loki \
      --privileged=true \
      --restart=always \
      -v /etc/localtime:/etc/localtime \
      -v /home/data/loki/conf:/mnt/config \
      -v /home/data/loki/chunks:/tmp/loki/chunks \
      -v /home/data/loki/rules:/tmp/loki/rules \
      -p 3100:3100 \
      -p 9096:9096 \
      grafana/loki:2.6.1 -config.file=/mnt/config/loki-config.yaml
      
    # 指定root用户启动,否则无法容器无法创建chunks目录
    
    2.2.1.2 Promtail

    作为 Agent 部署于被采集目标服务器上

    1、创建相关文件

    mkdir -p /home/data/promtail/conf
    

    2、下载配置文件

    cd /home/data/promtail/conf
    wget --no-check-certificate https://raw.githubusercontent.com/grafana/loki/v2.6.1/clients/cmd/promtail/promtail-docker-config.yaml -O promtail-config.yaml
    
    cat promtail-config.yaml
    
    server:
      http_listen_port: 9080
      grpc_listen_port: 0
    
    positions:
      filename: /tmp/positions.yaml
    
    clients:
      - url: http://192.168.56.132:3100/loki/api/v1/push
    
    scrape_configs:
    - job_name: system
      static_configs:
      - targets:
          - localhost
        labels:
          job: varlogs
          # class: A   # 支持自定义多个标签
          __path__: /var/log/*.log
    

    如果还需要采集其他日志,继续往下添加 - job_name 即可。

    3、目录权限

    chmod -R 777 /home/data/promtail/*
    

    4、运行容器

    docker run -d -u root \
      --name=promtail \
      --privileged=true \
      --restart=always \
      -v /home/data/promtail/conf:/mnt/config \
      -v /var/log:/var/log \
      grafana/promtail:2.6.1 -config.file=/mnt/config/promtail-config.yaml
      
    
    
    docker run -d -u root \
      --name=promtail \
      --privileged=true \
      --restart=always \
      -v /home/data/promtail/conf:/mnt/config \
      -v /opt/ddz-srv/platform_log/http_srv:/opt/ddz-srv/platform_log/http_srv \
      grafana/promtail:2.6.1 -config.file=/mnt/config/promtail-config.yaml
    
    2.2.1.3 Grafana

    1、pull 镜像

    docker pull grafana/grafana:9.0.3
    

    2、创建监控用户

    groupadd -g 2000 monitor
    useradd -u 2000 -g monitor monitor
    

    3、创建相关目录

    mkdir -p /home/data/grafana/{data,logs}
    

    4、启动临时容器(copy相关配置文件)

    docker run -d -p 3000:3000 --name=tmp grafana/grafana:9.0.3
    
    # 复制配置文件
    docker cp tmp:/etc/grafana/ /home/data/grafana/
    # 退出临时容器
    exit
    # 修改文件名
    mv /home/data/grafana/grafana /home/data/grafana/etc
    # 删除临时容器
    docker stop tmp
    docker rm tmp
    

    5、目录授权

    chown -R monitor. /home/data/grafana
    chmod 777 -R /home/data/grafana
    

    6、启动容器

    docker run -d --user root \
        --name=grafana \
        --privileged=true \
        --restart=always \
        -p 3000:3000 \
        -v /home/data/grafana/etc:/etc/grafana \
        -v /home/data/grafana/data:/var/lib/grafana \
        -v /home/data/grafana/logs:/var/log/grafana \
        -v /etc/localtime:/etc/localtime \
        grafana/grafana:8.4.3
        
    # 注:我的版本改为与公司版本一致8.4.3
    

    7、登录验证

    默认用户:admin

    默认密码:admin

    输入完成之后,会提示你再次输入新的登录密码(zhurs@123)。

    image-20220718134653471

    功能界面

    image-20220718134806098

    2.2.2 Docker-compose

    三个组件:Loki、promtail、grafana

    这种部署方式用于快速临时测试。

    1、编写 docker-compose.yaml 文件

    version: "3"
    networks:
      loki:
    services:
      loki:
        container_name: loki
        image: grafana/loki:2.6.1
        ports:
          - "3100:3100"
        command: -config.file=/etc/loki/local-config.yaml
        networks:
          - loki
      promtail:
        container_name: promtail
        image: grafana/promtail:2.6.1
        volumes:
          - /var/log:/var/log
          - /home/data/loki/conf/promtail.yaml:/etc/promtail/docker-config.yaml
        command: -config.file=/etc/promtail/docker-config.yaml
        networks:
          - loki
      grafana:
        container_name: grafana
        image: grafana/grafana:latest
        ports:
          - "3000:3000"
        networks:
          - loki
    

    2、创建相关文件

    mkdir -p /home/data/loki/conf
    

    编写 promtail.yaml 文件,该配置文件用于配置被采集端的信息。

    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
              # class: A   # 支持自定义多个标签
              __path__: /var/log/*log
    

    3、启动容器

    docker-compose -f docker-compose.yaml up -d
    

    2.3 Docker swarm 日志采集

    2.3.1 全局配置

    这种配置方式会在你运行容器时输出相关的日志内容,类似于 nohup 日志文件输出。

    1、安装 loki 的 docker plugin 插件

    docker plugin install grafana/loki-docker-driver:main --alias loki --grant-all-permissions
    

    image-20220926143659008

    2、Docker 配置

    {
      "registry-mirrors": ["https://q1rw9tzz.mirror.aliyuncs.com"],
      "insecure-registries":["http://192.168.56.180"],
      "log-driver": "loki",
      "log-opts": {
        "loki-url": "http://192.168.56.132:3100/loki/api/v1/push",
        "max-size": "50m",
        "max-file": "10"
      }
    }
    

    3、重启docker

    systemctl daemon-reload
    systemctl restart docker.service
    
    # 重启后,之后每运行的每个容器的日志都会被打入grafana
    

    4、运行一个容器进行测试

    docker run -d --name=tmp redis:6.0.9
    
    # 此时docker logs -f .. 的日志就会被打入grafana
    

    image-20220926144424481

    如何查询 docker 持久化数据?

    很简单,将数据持久化文件挂载到 Promtail 容器即可,这样的话既可以在运行 docker 容器是实时查看输出的日志,也可以

    2.3.2 特定配置

    全局配置是对于整个 Docker daemon 来说,每个容器的日志都会输出到 Loki,而特定配置则是根据当前需求间接性性接入 Loki,具体配置如下。

    docker run --rm --name=<Container name> \
      --log-driver=loki \
      --log-opt loki-url="http://YOUR_IP:3100/loki/api/v1/push" \
      --log-opt max-size=50m \
      --log-opt max-file=10 <images>
    
    # 参数说明:
    # --log-driver:指定日志驱动器为loki
    # --log-opt loki-url:指定loki的url
    # --log-opt max-size:日志最大大小
    # --log-opt max-file:日志文件最大数量
    

    根据实际条件进行选择配置即可。

    2.4 Grafana Web 展示

    2.4.1 添加数据源(Loki)

    1、选择 Data sources

    image-20220926103420064

    2、添加 Loki 为数据源

    image-20220926103608535

    2.4.2 日志查询

    Loki 日志查询语言官方文档:https://www.bookstack.cn/read/loki/logql.md

    2.4.2.1 基础查询

    image-20220926104125454

    2.4.2.2 精准查询

    1、选择要搜索的标签(container_name、filename、host、job、source)

    2、选择要查询的标签已存在的内容

    image-20220926164953594

    2.4.2.3 升/降序查询

    根据日志输出时间升序或降序查询

    image-20220926141246495

    JSON 格式展示(默认是行显示日志)

    image-20220926141355573

    2.5 数据指标查询

    Loki 本身会暴露自己的指标数据,供 Prometheus 进行监控,我们可以在 Prometheus 中进行配置来监控 Loki 健康状态。

    image-20220926150748230

    查看 Loki 运行状态

    image-20220926152426312

    三、Loki、Sentry、ELK 比较

    平台架构存储/索引查询维护资源占用
    Loki分布式纯文本存储/非结构化/仅元数据索引Grafana 原生支持简单、轻量级CPU/内存占用适中
    Sentry集中式集中化数据存储/查询原生 Web 端查询简单、轻量级CPU/内存占用适中
    ELK分布式非结构化JSON对象存储/键值均索引Kibana 可视化查询困难、重量级、组件多CPU/内存占用较高

    整体资源占用:Loki < Sentry < ELK

    1、对于大规模的日志量场景,可以选择 EL(F)K 来实现数据存储、索引、查询;

    2、对于小规模的日志量场景,可以采用 Loki 来实现数据存储、索引、查询,且其 Grafana 原生支持;

    3、对于小规模的日志量场景且有日志监控的需求,可采用 Sentry 来实现(针对性较强),而日志查询则没有 ELK、Loki 灵活。

    因此:对于目前公司的服务器与日志体量,如果更偏向于日志诊断则采用 Sentry;如果更偏向于灵活的日志审计,则采用 Loki。

    <点击跳转至开头>

  • 相关阅读:
    码蹄集 - MT2094 - 回文之时:第4组数据错误
    LeetCode 0146. LRU 缓存:双向链表 + 哈希
    Python Requests 丨爬虫基础入门
    C++实现演讲比赛流程管理系统
    Matlab 中值滤波原理分析
    基于Linux的无界面网盘 项目
    鸿蒙HarmonyOS实战-Stage模型(进程模型)
    Kubeapps 安装测试
    串口 COM口,并口 LPT口,RS232、RS485、CAN
    正则表达式使用总结
  • 原文地址:https://blog.csdn.net/IT_ZRS/article/details/127111765