Loki 单机 Linux Docker 搭建指南1. 适用场景本文档适用于以下部署条件Spring Boot 2.x 项目Java 后端项目单机 Linux 服务器使用 Docker / Docker Compose 部署业务日志目录为/home/admin/app/logs/visa需要快速检索日志、查看异常堆栈、按时间范围筛选日志当前项目的日志格式参考src/main/resources/logback.xml核心格式如下pattern%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} %L %msg%n/pattern当前日志滚动策略为按天切分单文件超过20MB自动继续拆分错误日志单独输出到error子目录以上策略可以正常接入Loki Promtail Grafana。2. 方案说明本方案采用以下组件Loki日志存储与查询服务Promtail读取日志文件并推送到 LokiGrafana图形化查看日志整体流程如下Spring Boot 按现有logback配置继续写本地日志文件Promtail 持续采集/home/admin/app/logs/visa目录下的日志Promtail 将日志推送到 LokiGrafana 连接 Loki 后提供检索界面3. 目录规划建议在 Linux 服务器创建统一的观测目录mkdir-p/opt/visa-observe/loki/datamkdir-p/opt/visa-observe/promtail/positionsmkdir-p/opt/visa-observe/grafana-data建议最终目录结构如下/opt/visa-observe/ ├── docker-compose.yml ├── grafana-data/ ├── loki/ │ ├── data/ │ └── loki-config.yaml └── promtail/ ├── positions/ └── promtail-config.yaml4. 前置准备4.1 检查 Docker执行以下命令确认 Docker 已安装docker-vdockercompose version如果服务器没有安装 Docker 和 Docker Compose需要先安装。4.2 确认日志目录确认业务日志目录已经存在并且日志文件会持续写入ls-lh/home/admin/app/logs/visa如果存在error子目录也建议一并确认ls-lh/home/admin/app/logs/visa/error5. 创建 docker-compose.yml在/opt/visa-observe目录下创建docker-compose.ymlversion:3.8services:loki:image:grafana/loki:2.9.8container_name:lokirestart:unless-stoppedports:-3100:3100volumes:-/opt/visa-observe/loki/loki-config.yaml:/etc/loki/local-config.yaml-/opt/visa-observe/loki/data:/lokicommand:-config.file/etc/loki/local-config.yamlpromtail:image:grafana/promtail:2.9.8container_name:promtailrestart:unless-stoppedvolumes:-/opt/visa-observe/promtail/promtail-config.yaml:/etc/promtail/config.yml-/home/admin/app/logs/visa:/home/admin/app/logs/visa:ro-/opt/visa-observe/promtail/positions:/tmpcommand:-config.file/etc/promtail/config.ymldepends_on:-lokigrafana:image:grafana/grafana:10.4.3container_name:grafanarestart:unless-stoppedports:-3000:3000volumes:-/opt/visa-observe/grafana-data:/var/lib/grafanaenvironment:-GF_SECURITY_ADMIN_USERadmin-GF_SECURITY_ADMIN_PASSWORDadmin123-GF_SERVER_ROOT_URLhttp://localhost:3000depends_on:-loki6. 创建 Loki 配置在/opt/visa-observe/loki目录下创建loki-config.yamlauth_enabled:falseserver:http_listen_port:3100common:path_prefix:/lokireplication_factor:1ring:kvstore:store:inmemoryschema_config:configs:-from:2024-01-01store:tsdbobject_store:filesystemschema:v13index:prefix:loki_index_period:24hstorage_config:filesystem:directory:/loki/chunkscompactor:working_directory:/loki/compactorlimits_config:reject_old_samples:truereject_old_samples_max_age:168hallow_structured_metadata:false7. 创建 Promtail 配置在/opt/visa-observe/promtail目录下创建promtail-config.yamlserver:http_listen_port:9080grpc_listen_port:0positions:filename:/tmp/positions.yamlclients:-url:http://loki:3100/loki/api/v1/pushscrape_configs:-job_name:visa-logstatic_configs:-targets:-localhostlabels:job:visa-logapp:visa__path__:/home/admin/app/logs/visa/**/*.logpipeline_stages:-multiline:firstline:^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}-regex:expression:^(?Ptime\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}) \[(?Pthread[^\]])\] (?Plevel[A-Z])\s(?Plogger\S) (?Pline\d) (?Pmessage[\s\S]*)$-timestamp:source:timeformat:2006-01-02 15:04:05.000-labels:level:-output:source:message8. 为什么这个配置适合当前项目8.1 支持 20MB 自动拆分后的日志采集你当前日志采用SizeAndTimeBasedRollingPolicy超过20MB后会继续生成新文件例如/home/admin/app/logs/visa/2026-06-26.0.log /home/admin/app/logs/visa/2026-06-26.1.log /home/admin/app/logs/visa/2026-06-26.2.logPromtail 配置中的__path__:/home/admin/app/logs/visa/**/*.log可以匹配当前目录下的普通日志error子目录中的错误日志后续因为滚动产生的新日志文件因此超过20MB自动拆分后仍然可以继续监控。8.2 支持 Java 异常堆栈Java 异常通常是多行输出如果不做合并Grafana 中会看到很多碎片化日志。这里使用了multiline配置-multiline:firstline:^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}它会把不是以时间开头的后续行自动合并到上一条日志中适合 Java 堆栈输出。8.3 控制标签数量避免查询变慢当前配置只把level提升为标签没有把thread和logger提升为标签。这样做的原因是thread变化太多容易造成高基数logger也可能很多标签过多会影响 Loki 查询性能当前最适合先保留jobapplevel9. 启动服务进入目录后启动cd/opt/visa-observedockercompose up-d查看容器状态dockerps查看 Loki 日志dockerlogs-floki查看 Promtail 日志dockerlogs-fpromtail查看 Grafana 日志dockerlogs-fgrafana10. 基础验证10.1 检查 Loki 是否可用curlhttp://127.0.0.1:3100/ready返回ready说明正常。10.2 检查 Promtail 是否成功采集执行dockerlogs promtail|tail-n50重点关注是否存在以下问题无法读取日志目录配置文件语法错误无法连接loki:310010.3 检查 Grafana 是否可访问浏览器访问http://服务器IP:3000默认账号密码用户名admin密码admin12311. 配置 Grafana 数据源登录 Grafana 后按以下步骤操作进入Connections选择Data sourcesURL 填写http://loki:3100点击Save test如果显示成功说明 Grafana 已经可以访问 Loki。12. 常用查询语句进入 Grafana 的Explore页面后可以使用以下查询。12.1 查询全部业务日志{jobvisa-log}12.2 只看错误日志{jobvisa-log, levelERROR}12.3 搜索异常关键字{jobvisa-log} | Exception12.4 搜索某个业务关键字{jobvisa-log} | 申请单12.5 搜索某个类打印的日志因为logger当前没有作为标签所以建议直接全文搜索例如{jobvisa-log} | com.cxwl13. 推荐的执行顺序建议严格按以下顺序执行安装并确认 Docker 环境创建/opt/visa-observe目录结构创建docker-compose.yml创建loki-config.yaml创建promtail-config.yaml启动docker compose up -d登录 Grafana 配置 Loki 数据源进入 Explore 页面验证是否已经有日志14. 与当前 logback 配置相关的建议14.1 建议把 Linux 日志目录改成绝对路径你当前logback.xml中配置的是propertynameLOG_HOMEvalue../logs/这个写法在 Linux Docker 场景下不够稳定建议改成绝对路径例如propertynameLOG_HOMEvalue/home/admin/app/logs/这样最终输出目录会更明确/home/admin/app/logs/visa14.2 生产环境建议关闭 Logback 调试你当前配置中configurationdebugtruescantrue建议生产环境改为configurationdebugfalsescantrue原因debugtrue会输出 Logback 自身内部调试信息生产环境通常没有必要开启14.3 不建议立即改成应用直推 Loki当前场景下更推荐保持以下模式Java 应用继续按本地文件方式写日志Promtail 负责统一采集这样做的优点是改动小风险低出问题时仍可直接登录 Linux 服务器查看本地日志15. 常见问题15.1 为什么 Grafana 查不到日志优先排查以下问题/home/admin/app/logs/visa是否真的有日志文件Promtail 是否挂载到了正确目录Promtail 配置文件是否写错Promtail 是否成功连接到 LokiGrafana 数据源 URL 是否写成了http://loki:310015.2 日志滚动后是否会丢失正常不会。原因Promtail 会记录读取位置新生成的.log文件仍会被__path__匹配但仍建议不要频繁删除正在写入的日志文件。15.3 历史压缩日志会不会实时采集不建议依赖.gz压缩文件做实时采集。建议原则如下正在写入或刚滚动出的日志保持.log需要长期归档时再压缩15.4 如果 Java 项目也运行在 Docker 中怎么办需要确保应用容器已经把日志目录挂载到宿主机例如volumes:-/home/admin/app/logs:/home/admin/app/logsPromtail 采集的是宿主机目录不是应用容器内部的临时文件系统。16. 实际调试问题与解决方案以下内容基于本次实际部署过程中遇到的问题整理建议在首次搭建时重点关注。16.1 Loki 启动时报配置文件无权限问题现象failed parsing config: open /etc/loki/local-config.yaml: permission denied原因分析宿主机挂载到容器内的loki-config.yaml权限不足宿主机上级目录权限不足导致容器用户无法读取配置文件某些 Linux 发行版开启了SELinux卷挂载可能还需要额外处理解决方案先修正目录和文件权限chmod755/optchmod755/opt/visa-observechmod755/opt/visa-observe/lokichmod644/opt/visa-observe/loki/loki-config.yamlchmod755/opt/visa-observe/loki/datachown-R10001:10001 /opt/visa-observe/loki/data如果系统启用了SELinux先检查getenforce如果返回Enforcing建议在卷挂载时增加:Z例如volumes:-/opt/visa-observe/loki/loki-config.yaml:/etc/loki/local-config.yaml:ro,Z-/opt/visa-observe/loki/data:/loki:Z验证方式dockercompose downdockercompose up-ddockerlogs--tail100lokicurlhttp://127.0.0.1:3100/ready16.2 Loki 返回 Ingester not ready问题现象Ingester not ready: waiting for 15s after being ready原因分析这是Loki启动后的短暂预热状态并不代表配置错误或服务异常解决方案等待15~30秒后重新检查验证方式curlhttp://127.0.0.1:3100/ready当返回以下内容时说明服务正常ready16.3 Grafana 启动失败并反复重启问题现象GF_PATHS_DATA/var/lib/grafana is not writable. mkdir: cant create directory /var/lib/grafana/plugins: Permission denied同时docker ps中可能看到grafana Restarting (1)原因分析宿主机挂载目录/opt/visa-observe/grafana-data对容器内 Grafana 用户不可写Grafana 无法创建插件目录和内部数据文件因此启动失败解决方案先创建并修正目录权限mkdir-p/opt/visa-observe/grafana-datachown-R472:472 /opt/visa-observe/grafana-datachmod-R755/opt/visa-observe/grafana-data然后重启容器cd/opt/visa-observedockercompose downdockercompose up-d如果系统启用了SELinux建议把卷挂载改为volumes:-/opt/visa-observe/grafana-data:/var/lib/grafana:Z验证方式dockerpsdockerlogs--tail100grafanacurl-Ihttp://127.0.0.1:3000正常状态下应满足docker ps中grafana为Up可以看到0.0.0.0:3000-3000/tcpcurl返回302 Found并跳转到/login16.4 UFW 已放行但浏览器仍无法访问 Grafana问题现象ufw status已显示3000/tcp ALLOW服务器本机访问http://127.0.0.1:3000正常外部浏览器访问http://公网IP:3000仍然失败原因分析这通常不是 Linux 本机防火墙问题更常见原因是云服务器安全组未放行3000/tcp解决方案先确认本机防火墙已放行ufw allow3000/tcp ufw reload ufw status再确认服务本机访问正常curl-Ihttp://127.0.0.1:3000如果本机正常但外部仍无法访问需要到云平台控制台放行安全组协议TCP端口3000来源0.0.0.0/0或指定办公公网 IP验证方式服务器本机执行curl-Ihttp://127.0.0.1:3000浏览器访问http://公网IP:300016.5 Promtail 首次启动 CPU 偏高问题现象promtail初次启动后 CPU 使用率明显升高宿主机top中看到promtail持续占用较高 CPU原因分析首次启动时Promtail 会扫描现有日志目录并补采历史日志当前配置使用了递归路径/home/admin/app/logs/visa/**/*.log同时还启用了multiline和regex解析首次扫描成本会更高解决方案如果只是启动初期短时间 CPU 升高可以先观察几分钟如果历史日志很多建议收窄采集范围可以将普通日志和错误日志分开配置避免全量递归扫描示例scrape_configs:-job_name:visa-logstatic_configs:-targets:-localhostlabels:job:visa-logapp:visa__path__:/home/admin/app/logs/visa/*.log-job_name:visa-error-logstatic_configs:-targets:-localhostlabels:job:visa-error-logapp:visa__path__:/home/admin/app/logs/visa/error/*.log验证方式dockerlogs--tail100promtailtop观察一段时间后如果 CPU 明显下降通常说明补采已完成。17. 建议的上线后检查项上线完成后建议至少检查以下内容Grafana 可以打开Loki 数据源测试通过Explore 页面能查到最近 15 分钟日志ERROR级别日志可以独立筛选人为制造一条异常日志后能在 Grafana 中看到完整堆栈日志超过20MB滚动后新文件仍能继续被采集18. 一次性执行命令汇总如果你想按步骤手工执行可以参考以下命令顺序。17.1 创建目录mkdir-p/opt/visa-observe/loki/datamkdir-p/opt/visa-observe/promtail/positionsmkdir-p/opt/visa-observe/grafana-data17.2 进入工作目录cd/opt/visa-observe17.3 创建配置文件手工创建以下文件docker-compose.ymlloki/loki-config.yamlpromtail/promtail-config.yaml17.4 启动dockercompose up-d17.5 查看状态dockerpscurlhttp://127.0.0.1:3100/readydockerlogs promtail|tail-n5019. 后续可选优化当前方案适合快速落地。后续如果日志量继续增长可以考虑给 Grafana 配置登录安全策略给 Loki 配置更长的数据保留周期单独给错误日志配置不同的抓取任务增加告警能力例如发现ERROR或Exception自动通知20. 结论对于当前项目最稳妥、改动最小的方式是Spring Boot 保持本地文件输出使用 Promtail 采集/home/admin/app/logs/visa/**/*.log使用 Loki 做日志存储使用 Grafana 做查询和检索该方案已经兼容你当前的单机 LinuxDocker 部署Spring Boot 2.x20MB自动拆分日志Java 异常堆栈查看需求
Loki 单机 Linux Docker 搭建指南
发布时间:2026/6/27 7:01:02
Loki 单机 Linux Docker 搭建指南1. 适用场景本文档适用于以下部署条件Spring Boot 2.x 项目Java 后端项目单机 Linux 服务器使用 Docker / Docker Compose 部署业务日志目录为/home/admin/app/logs/visa需要快速检索日志、查看异常堆栈、按时间范围筛选日志当前项目的日志格式参考src/main/resources/logback.xml核心格式如下pattern%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} %L %msg%n/pattern当前日志滚动策略为按天切分单文件超过20MB自动继续拆分错误日志单独输出到error子目录以上策略可以正常接入Loki Promtail Grafana。2. 方案说明本方案采用以下组件Loki日志存储与查询服务Promtail读取日志文件并推送到 LokiGrafana图形化查看日志整体流程如下Spring Boot 按现有logback配置继续写本地日志文件Promtail 持续采集/home/admin/app/logs/visa目录下的日志Promtail 将日志推送到 LokiGrafana 连接 Loki 后提供检索界面3. 目录规划建议在 Linux 服务器创建统一的观测目录mkdir-p/opt/visa-observe/loki/datamkdir-p/opt/visa-observe/promtail/positionsmkdir-p/opt/visa-observe/grafana-data建议最终目录结构如下/opt/visa-observe/ ├── docker-compose.yml ├── grafana-data/ ├── loki/ │ ├── data/ │ └── loki-config.yaml └── promtail/ ├── positions/ └── promtail-config.yaml4. 前置准备4.1 检查 Docker执行以下命令确认 Docker 已安装docker-vdockercompose version如果服务器没有安装 Docker 和 Docker Compose需要先安装。4.2 确认日志目录确认业务日志目录已经存在并且日志文件会持续写入ls-lh/home/admin/app/logs/visa如果存在error子目录也建议一并确认ls-lh/home/admin/app/logs/visa/error5. 创建 docker-compose.yml在/opt/visa-observe目录下创建docker-compose.ymlversion:3.8services:loki:image:grafana/loki:2.9.8container_name:lokirestart:unless-stoppedports:-3100:3100volumes:-/opt/visa-observe/loki/loki-config.yaml:/etc/loki/local-config.yaml-/opt/visa-observe/loki/data:/lokicommand:-config.file/etc/loki/local-config.yamlpromtail:image:grafana/promtail:2.9.8container_name:promtailrestart:unless-stoppedvolumes:-/opt/visa-observe/promtail/promtail-config.yaml:/etc/promtail/config.yml-/home/admin/app/logs/visa:/home/admin/app/logs/visa:ro-/opt/visa-observe/promtail/positions:/tmpcommand:-config.file/etc/promtail/config.ymldepends_on:-lokigrafana:image:grafana/grafana:10.4.3container_name:grafanarestart:unless-stoppedports:-3000:3000volumes:-/opt/visa-observe/grafana-data:/var/lib/grafanaenvironment:-GF_SECURITY_ADMIN_USERadmin-GF_SECURITY_ADMIN_PASSWORDadmin123-GF_SERVER_ROOT_URLhttp://localhost:3000depends_on:-loki6. 创建 Loki 配置在/opt/visa-observe/loki目录下创建loki-config.yamlauth_enabled:falseserver:http_listen_port:3100common:path_prefix:/lokireplication_factor:1ring:kvstore:store:inmemoryschema_config:configs:-from:2024-01-01store:tsdbobject_store:filesystemschema:v13index:prefix:loki_index_period:24hstorage_config:filesystem:directory:/loki/chunkscompactor:working_directory:/loki/compactorlimits_config:reject_old_samples:truereject_old_samples_max_age:168hallow_structured_metadata:false7. 创建 Promtail 配置在/opt/visa-observe/promtail目录下创建promtail-config.yamlserver:http_listen_port:9080grpc_listen_port:0positions:filename:/tmp/positions.yamlclients:-url:http://loki:3100/loki/api/v1/pushscrape_configs:-job_name:visa-logstatic_configs:-targets:-localhostlabels:job:visa-logapp:visa__path__:/home/admin/app/logs/visa/**/*.logpipeline_stages:-multiline:firstline:^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}-regex:expression:^(?Ptime\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}) \[(?Pthread[^\]])\] (?Plevel[A-Z])\s(?Plogger\S) (?Pline\d) (?Pmessage[\s\S]*)$-timestamp:source:timeformat:2006-01-02 15:04:05.000-labels:level:-output:source:message8. 为什么这个配置适合当前项目8.1 支持 20MB 自动拆分后的日志采集你当前日志采用SizeAndTimeBasedRollingPolicy超过20MB后会继续生成新文件例如/home/admin/app/logs/visa/2026-06-26.0.log /home/admin/app/logs/visa/2026-06-26.1.log /home/admin/app/logs/visa/2026-06-26.2.logPromtail 配置中的__path__:/home/admin/app/logs/visa/**/*.log可以匹配当前目录下的普通日志error子目录中的错误日志后续因为滚动产生的新日志文件因此超过20MB自动拆分后仍然可以继续监控。8.2 支持 Java 异常堆栈Java 异常通常是多行输出如果不做合并Grafana 中会看到很多碎片化日志。这里使用了multiline配置-multiline:firstline:^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}它会把不是以时间开头的后续行自动合并到上一条日志中适合 Java 堆栈输出。8.3 控制标签数量避免查询变慢当前配置只把level提升为标签没有把thread和logger提升为标签。这样做的原因是thread变化太多容易造成高基数logger也可能很多标签过多会影响 Loki 查询性能当前最适合先保留jobapplevel9. 启动服务进入目录后启动cd/opt/visa-observedockercompose up-d查看容器状态dockerps查看 Loki 日志dockerlogs-floki查看 Promtail 日志dockerlogs-fpromtail查看 Grafana 日志dockerlogs-fgrafana10. 基础验证10.1 检查 Loki 是否可用curlhttp://127.0.0.1:3100/ready返回ready说明正常。10.2 检查 Promtail 是否成功采集执行dockerlogs promtail|tail-n50重点关注是否存在以下问题无法读取日志目录配置文件语法错误无法连接loki:310010.3 检查 Grafana 是否可访问浏览器访问http://服务器IP:3000默认账号密码用户名admin密码admin12311. 配置 Grafana 数据源登录 Grafana 后按以下步骤操作进入Connections选择Data sourcesURL 填写http://loki:3100点击Save test如果显示成功说明 Grafana 已经可以访问 Loki。12. 常用查询语句进入 Grafana 的Explore页面后可以使用以下查询。12.1 查询全部业务日志{jobvisa-log}12.2 只看错误日志{jobvisa-log, levelERROR}12.3 搜索异常关键字{jobvisa-log} | Exception12.4 搜索某个业务关键字{jobvisa-log} | 申请单12.5 搜索某个类打印的日志因为logger当前没有作为标签所以建议直接全文搜索例如{jobvisa-log} | com.cxwl13. 推荐的执行顺序建议严格按以下顺序执行安装并确认 Docker 环境创建/opt/visa-observe目录结构创建docker-compose.yml创建loki-config.yaml创建promtail-config.yaml启动docker compose up -d登录 Grafana 配置 Loki 数据源进入 Explore 页面验证是否已经有日志14. 与当前 logback 配置相关的建议14.1 建议把 Linux 日志目录改成绝对路径你当前logback.xml中配置的是propertynameLOG_HOMEvalue../logs/这个写法在 Linux Docker 场景下不够稳定建议改成绝对路径例如propertynameLOG_HOMEvalue/home/admin/app/logs/这样最终输出目录会更明确/home/admin/app/logs/visa14.2 生产环境建议关闭 Logback 调试你当前配置中configurationdebugtruescantrue建议生产环境改为configurationdebugfalsescantrue原因debugtrue会输出 Logback 自身内部调试信息生产环境通常没有必要开启14.3 不建议立即改成应用直推 Loki当前场景下更推荐保持以下模式Java 应用继续按本地文件方式写日志Promtail 负责统一采集这样做的优点是改动小风险低出问题时仍可直接登录 Linux 服务器查看本地日志15. 常见问题15.1 为什么 Grafana 查不到日志优先排查以下问题/home/admin/app/logs/visa是否真的有日志文件Promtail 是否挂载到了正确目录Promtail 配置文件是否写错Promtail 是否成功连接到 LokiGrafana 数据源 URL 是否写成了http://loki:310015.2 日志滚动后是否会丢失正常不会。原因Promtail 会记录读取位置新生成的.log文件仍会被__path__匹配但仍建议不要频繁删除正在写入的日志文件。15.3 历史压缩日志会不会实时采集不建议依赖.gz压缩文件做实时采集。建议原则如下正在写入或刚滚动出的日志保持.log需要长期归档时再压缩15.4 如果 Java 项目也运行在 Docker 中怎么办需要确保应用容器已经把日志目录挂载到宿主机例如volumes:-/home/admin/app/logs:/home/admin/app/logsPromtail 采集的是宿主机目录不是应用容器内部的临时文件系统。16. 实际调试问题与解决方案以下内容基于本次实际部署过程中遇到的问题整理建议在首次搭建时重点关注。16.1 Loki 启动时报配置文件无权限问题现象failed parsing config: open /etc/loki/local-config.yaml: permission denied原因分析宿主机挂载到容器内的loki-config.yaml权限不足宿主机上级目录权限不足导致容器用户无法读取配置文件某些 Linux 发行版开启了SELinux卷挂载可能还需要额外处理解决方案先修正目录和文件权限chmod755/optchmod755/opt/visa-observechmod755/opt/visa-observe/lokichmod644/opt/visa-observe/loki/loki-config.yamlchmod755/opt/visa-observe/loki/datachown-R10001:10001 /opt/visa-observe/loki/data如果系统启用了SELinux先检查getenforce如果返回Enforcing建议在卷挂载时增加:Z例如volumes:-/opt/visa-observe/loki/loki-config.yaml:/etc/loki/local-config.yaml:ro,Z-/opt/visa-observe/loki/data:/loki:Z验证方式dockercompose downdockercompose up-ddockerlogs--tail100lokicurlhttp://127.0.0.1:3100/ready16.2 Loki 返回 Ingester not ready问题现象Ingester not ready: waiting for 15s after being ready原因分析这是Loki启动后的短暂预热状态并不代表配置错误或服务异常解决方案等待15~30秒后重新检查验证方式curlhttp://127.0.0.1:3100/ready当返回以下内容时说明服务正常ready16.3 Grafana 启动失败并反复重启问题现象GF_PATHS_DATA/var/lib/grafana is not writable. mkdir: cant create directory /var/lib/grafana/plugins: Permission denied同时docker ps中可能看到grafana Restarting (1)原因分析宿主机挂载目录/opt/visa-observe/grafana-data对容器内 Grafana 用户不可写Grafana 无法创建插件目录和内部数据文件因此启动失败解决方案先创建并修正目录权限mkdir-p/opt/visa-observe/grafana-datachown-R472:472 /opt/visa-observe/grafana-datachmod-R755/opt/visa-observe/grafana-data然后重启容器cd/opt/visa-observedockercompose downdockercompose up-d如果系统启用了SELinux建议把卷挂载改为volumes:-/opt/visa-observe/grafana-data:/var/lib/grafana:Z验证方式dockerpsdockerlogs--tail100grafanacurl-Ihttp://127.0.0.1:3000正常状态下应满足docker ps中grafana为Up可以看到0.0.0.0:3000-3000/tcpcurl返回302 Found并跳转到/login16.4 UFW 已放行但浏览器仍无法访问 Grafana问题现象ufw status已显示3000/tcp ALLOW服务器本机访问http://127.0.0.1:3000正常外部浏览器访问http://公网IP:3000仍然失败原因分析这通常不是 Linux 本机防火墙问题更常见原因是云服务器安全组未放行3000/tcp解决方案先确认本机防火墙已放行ufw allow3000/tcp ufw reload ufw status再确认服务本机访问正常curl-Ihttp://127.0.0.1:3000如果本机正常但外部仍无法访问需要到云平台控制台放行安全组协议TCP端口3000来源0.0.0.0/0或指定办公公网 IP验证方式服务器本机执行curl-Ihttp://127.0.0.1:3000浏览器访问http://公网IP:300016.5 Promtail 首次启动 CPU 偏高问题现象promtail初次启动后 CPU 使用率明显升高宿主机top中看到promtail持续占用较高 CPU原因分析首次启动时Promtail 会扫描现有日志目录并补采历史日志当前配置使用了递归路径/home/admin/app/logs/visa/**/*.log同时还启用了multiline和regex解析首次扫描成本会更高解决方案如果只是启动初期短时间 CPU 升高可以先观察几分钟如果历史日志很多建议收窄采集范围可以将普通日志和错误日志分开配置避免全量递归扫描示例scrape_configs:-job_name:visa-logstatic_configs:-targets:-localhostlabels:job:visa-logapp:visa__path__:/home/admin/app/logs/visa/*.log-job_name:visa-error-logstatic_configs:-targets:-localhostlabels:job:visa-error-logapp:visa__path__:/home/admin/app/logs/visa/error/*.log验证方式dockerlogs--tail100promtailtop观察一段时间后如果 CPU 明显下降通常说明补采已完成。17. 建议的上线后检查项上线完成后建议至少检查以下内容Grafana 可以打开Loki 数据源测试通过Explore 页面能查到最近 15 分钟日志ERROR级别日志可以独立筛选人为制造一条异常日志后能在 Grafana 中看到完整堆栈日志超过20MB滚动后新文件仍能继续被采集18. 一次性执行命令汇总如果你想按步骤手工执行可以参考以下命令顺序。17.1 创建目录mkdir-p/opt/visa-observe/loki/datamkdir-p/opt/visa-observe/promtail/positionsmkdir-p/opt/visa-observe/grafana-data17.2 进入工作目录cd/opt/visa-observe17.3 创建配置文件手工创建以下文件docker-compose.ymlloki/loki-config.yamlpromtail/promtail-config.yaml17.4 启动dockercompose up-d17.5 查看状态dockerpscurlhttp://127.0.0.1:3100/readydockerlogs promtail|tail-n5019. 后续可选优化当前方案适合快速落地。后续如果日志量继续增长可以考虑给 Grafana 配置登录安全策略给 Loki 配置更长的数据保留周期单独给错误日志配置不同的抓取任务增加告警能力例如发现ERROR或Exception自动通知20. 结论对于当前项目最稳妥、改动最小的方式是Spring Boot 保持本地文件输出使用 Promtail 采集/home/admin/app/logs/visa/**/*.log使用 Loki 做日志存储使用 Grafana 做查询和检索该方案已经兼容你当前的单机 LinuxDocker 部署Spring Boot 2.x20MB自动拆分日志Java 异常堆栈查看需求