Promtail + Loki + Grafana部署实践:从日志采集到LogQL查询

📅 2026/8/16 11:43:54
Promtail + Loki + Grafana部署实践:从日志采集到LogQL查询
前言一台服务器只有几个日志文件时直接使用tail、grep基本就能完成排查。但服务数量增加以后应用日志、系统日志和不同主机上的文件逐渐分散再依靠逐台SSH登录查日志很难快速还原同一时间段内发生了什么。Promtail、Loki和Grafana可以组成一条集中式日志处理链路。Promtail负责读取指定日志文件并附加标签Loki负责接收和保存日志数据Grafana则通过Loki数据源和LogQL提供查询与可视化入口。与对日志正文建立传统全文索引的方案不同Loki主要围绕标签组织日志流再结合LogQL对日志内容进行过滤和解析。这种设计更适合先根据服务、主机或环境缩小范围再继续检查具体日志内容的场景。本文将分别演示二进制方式和Docker Compose方式部署这套日志链路并通过普通文本日志、JSON结构化日志以及多个日志源验证Promtail到Loki的采集过程再使用Grafana Explore执行LogQL查询。最后还会通过cpolar为Grafana的3000端口创建公网入口让日志服务器保持在线时也可以从其他网络环境打开Grafana查看已经采集的日志。1.Promtail Loki Grafana可以做什么集中化日志收集Promtail作为日志采集代理可部署在每台服务器上实时监控指定路径的日志文件如/var/log/*.log、应用日志、容器日志等。支持自动发现、多行日志合并、标签注入便于后续分类查询。高效低成本的日志存储Loki是日志聚合系统不索引日志全文而是基于 标签labels 廻溯日志流类似 Prometheus 的时间序列模型。日志内容以压缩块形式存储可使用本地磁盘、对象存储如S3、MinIO等后端存储成本远低于 ELK。特别适合“先过滤再查内容”的使用模式对大多数运维和排错场景已足够高效。强大的日志查询与分析使用 LogQLLoki Query Language一种类似 PromQL 的查询语言支持过滤{job“app”} | “error”正则匹配{job“nginx”} |~ “404|500”统计rate({job“api”}[5m])提取结构化字段通过解析表达式可进行日志速率统计、错误趋势分析、关键词告警等。无缝集成Grafana实现统一可视化Grafana 原生支持 Loki 数据源无需插件。在同一个面板中可将日志Loki、指标Prometheus、链路Tempo联动展示构建完整的可观测性视图。支持实时日志流查看日志与 CPU/内存等指标关联分析创建日志告警规则通过 Grafana Alerting构建运维仪表盘如“近1小时错误日志 Top 10”典型应用场景微服务日志集中管理统一收集多个服务实例的日志按服务名、环境、版本等标签快速筛选。容器/ Kubernetes 日志通过 DaemonSet 部署 Promtail收集 Pod 日志并打上 namespace、pod 名等标签。系统运维排障快速定位某台服务器在特定时间段内的异常日志如 SSH 登录失败、服务崩溃。安全审计监控关键日志如 sudo 操作、防火墙拒绝记录并设置告警。轻量级替代 ELK在不需要全文搜索或复杂分析的场景下PLG 更节省资源、更易维护。优势总结特性PLG 栈ELK 栈资源占用低无全文索引高Elasticsearch 内存/CPU 密集部署复杂度简单3个组件配置直观复杂需调优 ES、Logstash、Kibana存储成本低压缩 仅索引标签高全文索引占用大量空间与指标系统集成原生支持 Prometheus Grafana需额外桥接2.环境准备操作系统CentOS Linux release 7.x建议最小安装用户权限root 或具有 sudo 权限的用户网络确保服务器可访问外网用于下载软件包建议关闭防火墙或开放相应端口3100、9080、3000systemctl stop firewalld systemctl disable firewalld# 或使用 iptables/firewalld 开放端口安装必要工具yum update-yyuminstall-ywgettarcurlvimnet-tools创建专用用户可选但推荐useradd-r-s/sbin/nologin loki3.下载并安装Loki下载Loki二进制文件以v3.0.0为例请根据 官方 GitHub 替换最新版cd/app/lokicurl-O-Lhttps://github.com/grafana/loki/releases/download/v1.5.0/loki-linux-amd64.zip解压该压缩文件unziploki-linux-amd64.zip在日志服务器 上创建目录用于文件存储和索引存储。mkdir/data/lokimkdir/data/loki/{chunks,index}配置文件config.yamlviconfig.yamlauth_enabled:falseserver: http_listen_port:8094ingester: lifecycler: address:192.168.42.140#日志服务器ip即本机地址ring: kvstore: store: inmemory replication_factor:1final_sleep: 0s chunk_idle_period: 5m chunk_retain_period: 30s schema_config: configs: - from:2024-04-01 store: boltdb object_store: filesystem schema: v11 index: prefix: index_ period: 168h#每张表的时间范围7天storage_config: boltdb: directory: /data/loki/index#索引文件存储地址filesystem: directory: /data/loki/chunks#块存储地址limits_config: enforce_metric_name:falsereject_old_samples:truereject_old_samples_max_age: 168h chunk_store_config: max_look_back_period: 168h table_manager: retention_deletes_enabled:trueretention_period: 168h#表的保留期7天创建启动脚本start.sh和关闭脚本shutdown.shvistart.sh#!/bin/bashnohup./loki-linux-amd64-config.file./config.yaml./server.log21echo$!pidvishutdown.sh#!/bin/bashkill-9catpidecho关闭成功!执行并查看日志shstart.shtail-200fserver.log4.下载并安装grafana首先关闭centos防火墙和selinuxsystemctl stop firewalld systemctl disable firewalld setenforce0sed-is/SELINUXenforcing/SELINUXdisabled/g/etc/selinux/config安装grafanaUbuntu and Debian(64 Bit):sudoapt-getinstall-yadduser libfontconfig1 muslwgethttps://dl.grafana.com/enterprise/release/grafana-enterprise_12.1.0_amd64.debsudodpkg-igrafana-enterprise_12.1.0_amd64.debStandalone Linux Binaries(64 Bit):wgethttps://dl.grafana.com/enterprise/release/grafana-enterprise-12.1.0.linux-amd64.tar.gztar-zxvfgrafana-enterprise-12.1.0.linux-amd64.tar.gzRed Hat, CentOS, RHEL, and Fedora(64 Bit):sudoyuminstall-yhttps://dl.grafana.com/enterprise/release/grafana-enterprise-12.1.0-1.x86_64.rpmOpenSUSE and SUSE(64 Bit):wgethttps://dl.grafana.com/enterprise/release/grafana-enterprise-12.1.0-1.x86_64.rpmsudorpm-Uvhgrafana-enterprise-12.1.0-1.x86_64.rpm我用的是CentOS在这里:sudoyuminstall-yhttps://dl.grafana.com/enterprise/release/grafana-enterprise-12.1.0-1.x86_64.rpm启动grafana并设置其开机自启:systemctl restart grafana-server systemctlenablegrafana-server查看已安装的grafana版本号grafana-cli-version浏览器打开服务器的3000端口如http://ip:3000/ip:3000第一次登录默认账号密码admin/admin认证后修改密码然后就登录成功啦5.下载并安装 promtail在服务器上创建目录 /app/promtail用于安装promtailcd/app/promtailcurl-O-Lhttps://github.com/grafana/loki/releases/download/v1.5.0/promtail-linux-amd64.zip解压该压缩文件unzippromtail-linux-amd64.zip配置文件promtail.yamlvipromtail.yamlserver: http_listen_port:9080grpc_listen_port:0positions: filename: ./positions.yaml clients: - url: http://192.168.42.140:8094/loki/api/v1/push#日志服务器loki地址和端口scrape_configs:#ucenter1- job_name: zcbackend-172.29.21.22-1 static_configs: - targets: -192.168.42.140 - labels: job: zcbachend-172.29.21.22-1 host:192.168.42.140 __path__: /jiuqi/zichan/zichanyitihuazhenghexiangmu-8084/backend/server.log#本机日志路径创建启动脚本start.sh和关闭脚本shutdown.shvistart.sh#!/bin/bashnohup./promtail-linux-amd64-config.file./promtail.yaml./server.log21echo$!pidvishutdown.sh执行并查看日志shstart.shtail-200fserver.log6.docker一键部署Lokigrafanapromtail本文也可以选择docker一键部署在开始部署之前确保你的系统已经安装了Docker。可以通过以下命令检查Docker是否已安装docker--version首先创建一下安装的目录并进入到该目录mkdir-p/docker/dochmod-R777/do执行前准备mkdir-p/docker/do/loki# 创建配置文件cat/docker/do/loki/config.ymlEOF auth_enabled:falseserver: http_listen_port:3100common: path_prefix: /tmp/loki storage: filesystem: directory: /tmp/loki/chunks replication_factor:1ring: kvstore: store: inmemory schema_config: configs: - from:2020-10-24 store: boltdb-shipper object_store: filesystem schema: v11 index: prefix: index_ period: 24h EOF# 创建目录mkdir-p/docker/do/promtail# 创建配置文件# 创建配置文件cat/docker/do/promtail/config.ymlEOF server: http_listen_port:9080grpc_listen_port:0positions: 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 - job_name:teststatic_configs: - targets: - localhost labels: job:test__path__: /var/log/test.log EOF创建并编辑docker-compose.yml文件vidocker-compose.ymlversion:3networks: loki: services: loki: image: grafana/loki:2.9.10 ports: -3100:3100volumes: - ./loki/config.yml:/etc/loki/config.yml# 挂载配置command:-config.file/etc/loki/config.yml# 路径匹配networks: - loki promtail: image: grafana/promtail:2.9.10 volumes: - /var/log:/var/log - ./promtail/config.yml:/etc/promtail/config.yml# 挂载配置command:-config.file/etc/promtail/config.yml# 路径匹配networks: - loki user:root# 关键避免权限问题grafana: environment: -GF_PATHS_PROVISIONING/etc/grafana/provisioning -GF_AUTH_ANONYMOUS_ENABLEDtrue -GF_AUTH_ANONYMOUS_ORG_ROLEAdmin entrypoint: -sh--euc-|mkdir-p/etc/grafana/provisioning/datasourcescatEOF/etc/grafana/provisioning/datasources/ds.yaml apiVersion:1datasources: - name: Loki type: loki access: proxy orgId:1url: http://loki:3100 basicAuth:falseisDefault:trueversion:1editable:falseEOF /run.sh image: grafana/grafana:latest ports: -3000:3000networks: - loki启动容器docker-composeup-d部署成功7.测试登录到grafana主页添加数据源搜索loki测试连接现在验证日志是否真的被采集确保测试日志有内容echoTest log entry at$(date)/var/log/test.log用正确语法查询curl-ghttp://localhost:3100/loki/api/v1/query?query{jobtest}limit5如果看到 values 数组中有内容说明 日志已成功从 Promtail → Loki打开浏览器访问http://你的服务器IP:3000进入Explore数据源选择 Loki在查询框输入{jobtest}点击 Run query你应该能看到日志8.模拟真实应用准备结构化日志# 模拟一个 Web 服务日志cat/var/log/app.jsonEOF {level:info,ts:2026-06-04T12:00:00Z,msg:User login,user_id:1001,ip:192.168.1.10,method:POST,path:/login,status:200} {level:error,ts:2026-06-04T12:01:05Z,msg:DB timeout,user_id:1002,ip:192.168.1.11,method:GET,path:/profile,status:500,error:context deadline exceeded} {level:warn,ts:2026-06-04T12:02:30Z,msg:Rate limit hit,user_id:1003,ip:192.168.1.12,method:POST,path:/api/v1/send,status:429} EOFLoki本身不解析JSON但可以通过Promtail的pipeline提取字段作为标签或结构化日志内容。升级Promtail配置支 JSON 解 标签提取编辑/docker/do/promtail/config.ymlserver: http_listen_port:9080grpc_listen_port:0positions: filename: /tmp/positions.yaml clients: - url: http://loki:3100/loki/api/v1/push scrape_configs: - job_name:teststatic_configs: - targets: - localhost labels: job:test__path__: /var/log/test.log - job_name: app-json pipeline_stages: - json: expressions: level: level msg: msg static_configs: - targets: - localhost labels: job: app __path__: /var/log/app.json这样level 和 status 会变成 可查询的标签原始 JSON 内容仍保留在日志行中然后重启 Promtaildocker-composerestart promtail高级 LogQL 查询测试使用解析表达式在 Grafana 中更强大虽然 API 不直接支持但在 Grafana Explore 中可以写{jobapp}|json|levelerror或{jobapp}|json|status500统计请求量LogQL 聚合在 Grafana 中运行sumby(path)(count_over_time({jobapp}[5m]))多日志源测试# 模拟 nginx 日志echo192.168.1.10 - - [04/Jun/2026:12:10:00 0000] GET /api/v1/data HTTP/1.1 200 1024/var/log/nginx-access.log# 模拟 auth 服务日志echo$(date-Iseconds)[AUTH] User 1001 logged in from 192.168.1.10/var/log/auth.log然后在 promtail/config.yml 中增加server: http_listen_port:9080grpc_listen_port:0positions: filename: /tmp/positions.yaml clients: - url: http://loki:3100/loki/api/v1/push scrape_configs: - job_name:teststatic_configs: - targets:[localhost]labels: job:test__path__: /var/log/test.log - job_name: app-json pipeline_stages: - json: expressions: level: level msg: msg static_configs:# ← 必须在这里- targets:[localhost]labels: job: app __path__: /var/log/app.json - job_name: nginx static_configs: - targets:[localhost]labels: job: nginx __path__: /var/log/nginx-access.log - job_name: auth static_configs: - targets:[localhost]labels: job: auth __path__: /var/log/auth.log重启后你可以在 Grafana 中切换不同 job跨服务关联查询如先查 auth 登录再查 nginx 访问Grafana本身提供强大的可视化与告警能力但默认仅限于内网访问。通过与cpolar结合可轻松实现Grafana服务的安全外网穿透cpolar基于TLS加密隧道无需公网IP或复杂网络配置只需一条命令即可将本地Grafana实例映射到全球可访问的HTTP地址支持自定义域名、身份验证和流量审计让运维人员随时随地通过浏览器安全查看监控面板极大提升了远程运维与应急响应的灵活性与效率。9.安装cpolar实现随时随地开发9.1 什么是cpolarcpolar是一款安全高效的内网穿透工具无需公网IP或复杂配置只需一条命令即可将本地服务器、Web服务或任意端口映射到公网让你随时随地远程访问内网应用特别适合开发调试、远程运维和应急部署等场景。9.2 部署cpolarcpolar 可以将你本地电脑中的服务如 SSH、Web、数据库映射到公网。即使你在家里或外出时也可以通过公网地址连接回本地运行的开发环境。❤️以下是安装cpolar步骤sudocurlhttps://get.cpolar.sh|sh安装完成后执行下方命令查看cpolar服务状态如图所示即为正常启动sudosystemctl status cpolarCpolar安装和成功启动服务后在浏览器上输入虚拟机主机IP加9200端口即:【http://192.168.42.101:9200】访问Cpolar管理界面使用Cpolar官网注册的账号登录,登录后即可看到cpolar web 配置界面,接下来在web 界面配置即可打开浏览器访问本地9200端口使用cpolar账户密码登录即可,登录后即可对隧道进行管理。10.配置公网地址登录cpolar web UI管理界面后,点击左侧仪表盘的隧道管理——创建隧道隧道名称可自定义本例使用了:grafana注意不要与已有的隧道名称重复协议http本地地址3000域名类型随机域名地区选择China Top创建成功后打开左侧在线隧道列表,可以看到刚刚通过创建隧道生成了公网地址接下来就可以在其他电脑或者移动端设备异地上使用地址访问。访问成功。11.保留固定公网地址使用cpolar为其配置二级子域名该地址为固定地址不会随机变化。点击左侧的预留选择保留二级子域名地区选择china top然后设置一个二级子域名名称我这里演示使用的是grafana3大家可以自定义。填写备注信息点击保留。登录cpolar web UI管理界面点击左侧仪表盘的隧道管理——隧道列表找到所要配置的隧道grafana点击右侧的编辑。修改隧道信息将保留成功的二级子域名配置到隧道中域名类型选择二级子域名Sub Domain填写保留成功的二级子域名地区: China Top点击更新更新完成后打开在线隧道列表此时可以看到随机的公网地址已经发生变化地址名称也变成了保留和固定的二级子域名名称。最后我们使用固定的公网地址在任意设备的浏览器中访问可以看到成功访问本地部署的grafana页面这样一个永久不会变化的二级子域名公网网址即设置好了。总结完成以上配置后一条基础的集中式日志链路已经建立起来。Promtail负责读取指定的系统日志和应用日志并将日志内容连同job等标签发送到LokiLoki负责保存这些日志流并提供LogQL查询接口Grafana则作为查询和展示入口用来选择Loki数据源并查看对应时间范围内的日志。本文先通过test.log验证了Promtail到Loki的基础采集过程又加入JSON格式的应用日志并使用| json、字段过滤和日志统计等LogQL写法进行了查询测试。随后继续增加nginx和auth等不同日志源通过不同job对日志进行区分验证同一个Loki实例可以集中接收多类服务日志。通过cpolar为Grafana的3000端口创建公网隧道后原本只能在服务器本地或局域网中打开的Grafana页面也可以从其他网络环境访问。公网使用前仍应保留Grafana自身的账号认证和权限控制不应把日志管理后台作为无认证页面公开。从日志文件采集、Loki存储到LogQL查询、Grafana展示以及远程访问本文完成了一套基础的集中式日志管理流程。