当前位置: 首页 > news >正文

Ubuntu26.04下Loki与Spring Boot集成实战指南

本文基于实际踩坑经历,详细记录在Ubuntu系统上部署Loki+Grafana,并通过Spring Boot应用将日志直接推送至Loki的全过程。文中包含完整的配置示例、常见错误及解决方案,以及如何在Grafana中利用上下文功能快速定位问题。


1. 为什么选择Loki?

相比传统的ELK(Elasticsearch+Logstash+Kibana)栈,Loki采用标签索引而非全文索引,存储成本更低,查询速度更快,尤其适合Kubernetes环境和微服务架构。配合Grafana的可视化能力,可以轻松实现日志的聚合、检索和监控。

本文方案特点

  • 使用Loki4j作为Logback Appender,Spring Boot应用直接推送日志,无需额外部署Promtail。

  • 所有组件(Loki、Grafana)通过Docker Compose一键启动

  • 覆盖从部署到排错的全流程,尤其针对权限、配置文件等常见坑点给出明确解决办法。


2. 环境准备

  • 操作系统:Ubuntu 26.04(其他版本同理)

  • DockerDocker Compose(已安装)

  • Spring Boot项目(推荐3.x, 2/3/4均可)

  • JDK 8+

检查Docker版本:

docker --version docker compose version

若未安装,可参考官方文档安装Docker Engine和Compose。


3. 部署Loki和Grafana

3.1 创建项目目录

mkdir -p ~/loki-stack cd ~/loki-stack

3.2 编写docker-compose.yml

经过多次调整,最终使用不含配置文件挂载的简洁版本,避免因配置文件缺失或权限问题导致容器无法启动。关键点:数据目录权限必须正确。

创建docker-compose.yml

nanodocker-compose.yml

(ctrl+o save, press enter comfirm , ctrl+x exit)

networks: loki-network: services: loki: image: grafana/loki:latest container_name: loki ports: - "3100:3100" volumes: - ./loki/data:/loki # 数据持久化目录 networks: - loki-network # 不指定command,使用镜像默认配置 grafana: image: grafana/grafana:latest container_name: grafana ports: - "3000:3000" environment: - GF_SECURITY_ADMIN_PASSWORD=admin - GF_AUTH_ANONYMOUS_ENABLED=false volumes: - ./grafana/data:/var/lib/grafana networks: - loki-network depends_on: - loki

注意:此处去掉了version字段(避免警告),并未挂载loki/conf,让Loki使用内置默认配置。数据目录./loki/data./grafana/data需提前创建并赋予正确权限。

3.3 准备数据目录并解决权限问题

Loki和Grafana容器内均以非root用户运行(Loki用户uid约为10001,Grafana用户uid为472),需要宿主机目录具有写权限。

快速解决(测试环境)

# 创建目录 mkdir -p ./loki/data ./grafana/data # 赋予所有用户读写执行权限(777) chmod 777 ./loki/data ./grafana/data

更安全的做法(生产推荐)

# 为Loki目录设置uid 10001(可通过docker run --rm grafana/loki id -u确认) sudo chown -R 10001:10001 ./loki/data # 为Grafana目录设置uid 472 sudo chown -R 472:472 ./grafana/data

3.4 启动服务

docker compose up -d

检查容器状态:

docker ps

验证Loki是否就绪:

curl http://localhost:3100/ready

返回ready表示成功。也可查看日志:

docker logs loki docker logs grafana

若遇到权限错误(如mkdir /loki/rules: permission deniedGF_PATHS_DATA is not writable),请按上述权限调整步骤重新执行。

4. Spring Boot集成Loki4j

4.1 添加Maven依赖

pom.xml中加入:

<dependency> <groupId>com.github.loki4j</groupId> <artifactId>loki-logback-appender</artifactId> <version>1.4.1</version> </dependency>
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.5.0</version> <relativePath/> </parent> <groupId>com.example</groupId> <artifactId>springboot-loki</artifactId> <version>1.0.0</version> <name>Spring Boot Loki Integration</name> <description>Spring Boot 3.5 project with Loki4j integration</description> <properties> <java.version>17</java.version> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- Spring Boot Web Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Loki4j Logback Appender --> <dependency> <groupId>com.github.loki4j</groupId> <artifactId>loki-logback-appender</artifactId> <version>2.0.3</version> <scope>compile</scope> </dependency> <!-- Lombok (可选,简化代码) --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>

4.2 配置Logback

src/main/resources下创建或修改logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 控制台输出配置 --> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- Loki4j Appender 配置 --> <appender name="LOKI" class="com.github.loki4j.logback.Loki4jAppender"> <http> <url>http://localhost:3100/loki/api/v1/push</url> <connectionTimeoutMs>5000</connectionTimeoutMs> <requestTimeoutMs>10000</requestTimeoutMs> </http> <format> <label> <pattern>app=springboot-loki,env=local</pattern> <readMarkers>true</readMarkers> </label> <message> <pattern>${FILE_LOG_PATTERN:-%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n}</pattern> </message> <sortByTime>true</sortByTime> </format> <batch> <maxItems>1000</maxItems> <maxWaitMs>5000</maxWaitMs> <maxBytes>10485760</maxBytes> </batch> <send> <minLevel>INFO</minLevel> <retry> <maxRetries>3</maxRetries> <backoffMs>1000</backoffMs> </retry> </send> </appender> <!-- 异步Loki Appender --> <appender name="ASYNC_LOKI" class="ch.qos.logback.classic.AsyncAppender"> <appender-ref ref="LOKI"/> <queueSize>512</queueSize> <discardingThreshold>0</discardingThreshold> <neverBlock>true</neverBlock> </appender> <!-- 根日志配置 --> <root level="INFO"> <appender-ref ref="CONSOLE"/> <appender-ref ref="ASYNC_LOKI"/> </root> <!-- 应用特定日志配置 --> <logger name="com.example.springbootloki" level="DEBUG" additivity="false"> <appender-ref ref="CONSOLE"/> <appender-ref ref="ASYNC_LOKI"/> </logger> </configuration>

配置要点

  • <url>指向Loki的推送端点,若Loki不在本机,替换为实际IP。

  • 标签(applicationlevel)是查询的核心,建议包含应用名、环境等。

  • 消息体可包含自定义字段,便于后续解析。

application.properties中定义应用名:

spring: application: name: springboot-loki

4.3 编写测试接口

创建测试Controller,验证日志推送:

package com.example.springbootloki.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Map; @RestController @RequestMapping("/api/logs") public class LogTestController { //https://zhengkai.blog.csdn.net/ private static final Logger logger = LoggerFactory.getLogger(LogTestController.class); /** * 基本日志测试接口 */ @GetMapping("/test") public Map<String, String> testLogs() { logger.info("这是一条INFO级别日志 - 测试Loki集成"); logger.debug("这是一条DEBUG级别日志 - 调试信息"); logger.warn("这是一条WARN级别日志 - 警告信息"); logger.error("这是一条ERROR级别日志 - 错误信息"); return Map.of( "status", "success", "message", "日志已写入Loki", "timestamp", String.valueOf(System.currentTimeMillis()) ); } }

启动Spring Boot应用,访问/test,日志便会推送至Loki。

http://localhost:8080/api/logs/test


5. 在Grafana中配置Loki数据源

  1. 浏览器访问http://<你的Ubuntu IP>:3000,登录(admin/admin)。

  2. 点击左侧齿轮图标(Configuration)→Data SourcesAdd data source

  3. 选择Loki

  4. URL 填写http://loki:3100(因为Grafana与Loki在同一Docker网络,可使用服务名)。

  5. 点击Save & Test,显示成功即可。


6. 查询日志与查看上下文

6.1 基本查询

进入Explore页面,选择Loki数据源。使用标签过滤器,例如:

  • {app="default"}查看该应用所有日志。

  • 加上level="WARN"过滤警告级别。

  • 使用|= "警告信息"进行文本搜索。

6.2 查看某条日志的上下文(关键功能)

当你在日志列表中发现一条感兴趣的日志(如WARN),想查看它之前之后的日志以了解触发背景时,可以使用Grafana的上下文功能:

  1. 鼠标悬停在目标日志行上,右侧会出现操作图标。

  2. 点击显示上下文按钮(两条横线带箭头,英文版是Content)。

  3. 默认会展示该条日志前后各10行日志,你可以调整行数(例如20行),点击加载。

这样就能快速分析出WARN发生前的DEBUG或INFO日志,从而定位问题根源。

原理:上下文查询基于相同标签流时间顺序,因此务必确保标签组合能唯一标识一个日志流(例如包含applicationhostcontainer等)。


7. 常见问题与排错

7.1 Loki容器启动失败,日志显示config file not found

  • 原因:未正确挂载配置文件或镜像默认路径不存在。

  • 解决:移除volumes中挂载配置目录的行,让容器使用内置默认配置。

7.2 权限错误permission denied

  • 原因:宿主机数据目录权限不足。

  • 解决chmod 777chown为容器内用户uid(Loki uid≈10001,Grafana uid=472)。

7.3 Spring Boot日志未出现在Loki

  • 检查Loki URL是否正确,确保网络可达。

  • 查看Spring Boot日志中是否有连接异常。

  • 检查Loki容器是否正常运行(docker logs loki)。

7.4 Grafana无法连接Loki数据源

  • 确保Grafana和Loki在同一网络,URL使用服务名http://loki:3100

  • 检查Loki端口是否暴露,可用curl http://localhost:3100/ready测试。


8. 总结

通过本文的实战步骤,你已成功在Ubuntu上部署Loki+Grafana,并让Spring Boot应用通过Loki4j直接将结构化日志推送至Loki。整个过程解决了配置文件缺失、权限不足等典型问题,并掌握了利用Grafana上下文功能快速回溯日志的技巧。

这套轻量级日志方案适合开发和测试环境,也可平滑迁移至生产(配合Promtail收集文件日志、使用对象存储等)。希望本文能帮助你高效构建日志系统,提升问题排查效率。


附录:清理所有容器和数据

cd ~/loki-stack docker compose down #只是shutdown docker compose down -v # -v 会删除数据卷,谨慎使用

扩展阅读

  • Loki官方文档

  • Loki4j GitHub


​ # ----------------------------------------------------- # - 🚀 Powered by Moshow郑锴 # - 🌟 Might the holy code be with you! # ----------------------------------------------------- # 🔍 公众号 👉 软件开发大百科 # 💻 CSDN 👉 https://zhengkai.blog.csdn.net # 📂 Github 👉 https://github.com/moshowgame

本文基于Ubuntu 26.04实践,其他Linux发行版类似。如有问题,欢迎留言交流。

http://www.jsqmd.com/news/1071602/

相关文章:

  • 软件开发的伦理问题与社会责任思考
  • Java性能监控与诊断工具使用
  • 移动端混合开发实战
  • Android 开发者为什么必须掌握 AI 能力?端侧视角下的技术变革
  • SolidWorks 2026下载 三维CAD设计软件安装教程(2026最新版)
  • 合规能力从可选变为必选:声誉管理行业的准入门槛正在提高
  • 系统压测方案
  • 1.5 容器相关面试题
  • 吐血整理:开发者为什么都在用应用托管?看完这篇你就懂了
  • 谁是省时神器?8款AI写作辅助平台榜单,毕业季救星!
  • 服务网格:Istio 是什么?有什么用?
  • 手机投屏电视实用指南:4种通用方法+3款工具实测,网课追剧不再费眼
  • Java的java.lang.StackWalker日志优化
  • 个人技术成长路径规划与学习方法论探讨
  • Audacity:二十年老项目,开源音频编辑的标杆
  • 深度学习模型评估
  • 第4章 输入、输出和命令行交互
  • Cocos透明物体渲染层级错乱?深入剖析优先级与深度写入的相爱相杀
  • 【题解-Acwing】2048. 干草
  • 烤糊的饼干
  • 技术替换中的新旧交替与过渡方案
  • 基于 AI Loop Engine 与 Claude Code 自动生成 Doxygen 接口文档
  • 求学生平均成绩代码分享
  • 一线观察:佛山GEO优化公司的实际表现细节
  • 2026小团队远程办公方案实测:把“一群人共用设备”做成产品
  • 合规公关派和媒介关系派的核心分歧在哪里?
  • 【接口自动化测试】接口测试是什么
  • Python asyncio 调度性能分析
  • 【金属生长】基于元胞自动机模拟纯扩散镁合金模型附matlab代码
  • 【基础算法精讲 10】如何灵活运用递归?