JAVA 服务可观测性最佳实践

news2025/1/15 18:29:33

前言

本次实践主要是介绍 Java 服务通过无侵入的方式接入观测云进行全面的可观测。

环境信息

  • 系统环境:Ubuntu(主机环境)
  • 开发语言:JDK 11.0.18
  • Web 框架:SpringBoot
  • 日志框架:Logback
  • APM 探针:DDTrace

实现目标

  • 应用链路接入
  • 应用日志接入
  • JVM 指标接入
  • Profiling 接入

对 JDK 有版本要求,具体参考文档: Java - 观测云文档

接入方案

准备工作

安装 DataKit
# 需要把token 改成观测云空间的实际token值(可在「观测云控制台」-「集成」-「Datakit」 上面获取)
DK_DATAWAY="https://openway.guance.com?token=tkn_xxxxxx" bash -c "$(curl -L https://static.guance.com/datakit/install.sh)" 
重启 DataKit

以下接入配置后都需重启 DataKit ,使配置生效,命令如下:

datakit service -R

通过 datakit monitor 命令可以观察到采集器是否启动成功。

红色为采集器,下面各种接入都会开启采集器,每个采集器都需要重启 DataKit 。

日志接入

  • Logback 日志格式调整

主要是调整 pattern ,新增三个参数 %X{dd.service} %X{dd.trace_id} %X{dd.span_id} ,部分配置如下:

<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] %X{dd.service} %X{dd.trace_id} %X{dd.span_id} - %msg%n" />
<!--    <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] [traceId=%X{trace_id} spanId=%X{span_id}] - %msg%n" />-->
    <springProperty scope="context" name="logName" source="spring.application.name" defaultValue="Springboot"/>
    <!-- %m输出的信息,%p日志级别,%t线程名,%d日期,%c类的全名,,,, -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.pattern}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/${logName}/${logName}.log</file>    <!-- 使用方法 -->
        <append>true</append>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>logs/${logName}/${logName}-%d{yyyy-MM-dd}.log.%i</fileNamePattern>
            <maxFileSize>64MB</maxFileSize>
            <maxHistory>30</maxHistory>
            <totalSizeCap>1GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

Log 采集器主要用于采集日志信息,可以通过 Socket 或者 File 方式进行日志采集。进入到 DataKit 安装目录下,执行 conf.d/log/ ,复制 logging.conf.sample 并重命名为 logging.conf 。

  • 配置应用日志目录
  logfiles = [
    "/home/liurui/code/observable-demo/logs/server/server.log"
  ]
  # 服务名称,非必填
  service = "server"
  ## Grok pipeline script name.
  pipeline = "server.p"
  • 配置 pipeline

日志 pipeline 用于解析日志格式

解析脚本

grok(_, "%{TIMESTAMP_ISO8601:time} %{NOTSPACE:thread_name} %{LOGLEVEL:status}%{SPACE}%{NOTSPACE:class_name} - \\[%{NOTSPACE:method_name},%{NUMBER:line}\\] %{DATA:service_name} %{DATA:trace_id} %{DATA:span_id} - %{GREEDYDATA:msg}")

default_time(time,"Asia/Shanghai")

可以按照实际日志格式进行调整,以上 pipeline 只适应 %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] %X{dd.service} %X{dd.trace_id} %X{dd.span_id} - %msg%n 的日志格式。

链路接入

  • 开启 DDTrace 采集器

DDTrace 采集器用于采集链路信息,进入到 DataKit 安装目录下,执行 conf.d/ddtrace/ ,复制 ddtrace.conf.sample 并重命名为 ddtrace.conf 即可 。

  • 应用启动参数
java \
-javaagent:/home/liurui/agent/dd-java-agent-1.21.1-guance.jar \
-Ddd.service.name=server \
-Ddd.env=dev \
-Ddd.version=1.2.3
-jar springboot-server.jar

JVM 指标接入

  • 开启 StatsD 采集器

StatsD 采集器用于采集指标信息,进入到 DataKit 安装目录下,执行 conf.d/statsd/ ,复制 statsd.conf.sample 并重命名为 statsd.conf 即可,默认端口为 8125 。

按照链路的启动方式启动应用即可。

Profiling 接入

  • 开启 Profile 采集器

Profiling 采集器主要用于采集应用性能数据,如 java 的 jfr。进入到 DataKit 安装目录下,执行 conf.d/profile/ ,复制 profile.conf.sample 并重命名为 profile.conf 。

  • 应用启动参数

主要是调整参数,添加以下参数。

-Ddd.profiling.enabled=true  \
-Ddd.profiling.ddprof.enabled=true \
-Ddd.profiling.ddprof.cpu.enabled=true \
-Ddd.profiling.ddprof.wall.enabled=true \
-Ddd.profiling.ddprof.alloc.enabled=true \
-Ddd.profiling.ddprof.liveheap.enabled=true \

完整启动命令

在启动命令加上 DDTrace 相关参数。

java \
-javaagent:/home/liurui/agent/dd-java-agent-1.21.1-guance.jar \
-Ddd.service.name=server \
-Ddd.env=dev \
-Ddd.version=1.2.3  \
-Ddd.profiling.enabled=true  \
-Ddd.profiling.ddprof.enabled=true \
-Ddd.profiling.ddprof.cpu.enabled=true \
-Ddd.profiling.ddprof.wall.enabled=true \
-Ddd.profiling.ddprof.alloc.enabled=true \
-Ddd.profiling.ddprof.liveheap.enabled=true \
-jar springboot-server.jar

实践效果

  • 日志视图

应用日志基本上都采集上来了,而且日志里面还包含了 trace_id 这些信息。

  • 日志详情

  • 链路视图

  • 链路详情

通过链路可以关联到日志信息,反之亦然,实现了日志与链路的联动效果。

  • Profiling

通过 Profiling 能更详细的追溯堆栈问题,从而更好的优化代码、提升性能。

  • JVM 监控视图

可以分析 java 在内存、cpu 等分配使用情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1519393.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言-存储期

C语言中&#xff0c;变量都是有一定的生存周期的&#xff0c;所谓生存周期指的是从分配到释放的时间间隔。为变量分配内存相当于变量的诞生&#xff0c;释放其内存相当于变量的死亡。从诞生到死亡就是一个变量的生命周期。 根据定义方式的不同&#xff0c;变量的生命周期有三种…

C#,子集和问题(Subset Sum Problem)的算法与源代码

1 子集和问题(Subset Sum Problem) 给定一组非负整数和一个值和,确定给定集合中是否存在和等于给定和的子集。 示例: 输入:set[]={3,34,4,12,5,2},sum=9 输出:真 有一个子集(4,5)和9。 输入:设置[]={3,34,4,12,5,2},和=30 输出:False 没有加起来…

【研发日记】Matlab/Simulink技能解锁(一)——在Simulink编辑窗口Debug

文章目录 前言 时间阈值断点 信号阈值断点 周期步进 Signal Value Lable Data Inspector 分析和应用 总结 前言 近期在一些研发项目中使用Matlab/Simulink时&#xff0c;遇到了挺多费时费力的事情。所以利用晚上和周末时间&#xff0c;在这些方面深入研究了一下&#x…

C++ 作业 24/3/14

1、成员函数版本实现算术运算符的重载&#xff1b;全局函数版本实现算术运算符的重载 #include <iostream>using namespace std;class Test {friend const Test operator-(const Test &L,const Test &R); private:int c;int n; public:Test(){}Test(int c,int n…

蓝桥杯单片机快速开发笔记——PCF8591电压信号探测器(可调电阻Rb2电压)

一、原理图 此处考点分析&#xff1a;可能会在引用iic文件时需要自己在头文件定义SCL/SDA sbit sda P2^1; sbit scl P2^0; 二、思维导图 三、代码示例 #include "iic.h" #include "smg.h"unsigned int adc_value 0; //AIN3的采样数据 float adc_…

医院为什么需要信息集成平台?有什么数据集成平台推荐?

在现代医疗行业中&#xff0c;信息技术的应用已经成为提高医疗服务质量、提升医院管理效率的关键。信息集成平台作为医院信息化建设的重要组成部分&#xff0c;扮演着连接各类医疗信息系统、整合医疗数据的重要角色。本文将详细探讨医院信息集成平台的必要性&#xff0c;以及集…

【JS逆向学习】猿人学第六题 js混淆 回溯

逆向目标 网址&#xff1a;https://match.yuanrenxue.cn/match/6接口&#xff1a;https://match.yuanrenxue.cn/api/match/6参数&#xff1a;payload(m、q) 逆向过程 老规矩&#xff0c;先来分析网络请求&#xff0c;加密的地方一目了然&#xff0c;没什么可多说的&#xff…

【Python】清理conda缓存的常用命令

最近发现磁盘空间不足&#xff0c;很大一部分都被anaconda占据了&#xff0c;下面是一些清除conda缓存的命令 清理所有环境的Anaconda包缓存 删除所有未使用的包以及缓存的索引和临时文件 conda clean --all清理某一特定环境的Anaconda包缓存 conda clean --all -n 环境名清…

【优选算法】专题1 -- 双指针 -- 移动零

前言: &#x1f4da;为了提高算法思维&#xff0c;我会时常更新这个优选算法的系列&#xff0c;这个专题是关于双指针的练习 &#x1f3af;个人主页&#xff1a;Dream_Chaser&#xff5e;-CSDN博客 一.移动零&#xff08;easy&#xff09; 描述&#xff1a; 「数组分两块」是⾮…

面向对象编程第二式:继承 (Java篇)

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

vue2之过滤器

过滤器 过滤器的实现类似Django的过滤器。 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>过…

c++入门你需要知道的知识点(上)

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 今日主菜&#xff1a;c入门 主厨&#xff1a;邪王真眼 所属专栏&#xff1a;c专栏 主厨的主页&#xff1a;Chef‘s blog 前言&#xff1a; 咱也是好久没有更…

reids设计与实现(一)——数据结构

文章目录 1. 前言2. redis 动态字符串2.1. 字符串的数据结构&#xff1a;2.2. 剖析&#xff0c;length&#xff1b;2.3. 剖析&#xff0c;free&#xff1b;2.3. 使用c字符串函数&#xff1b; 3. redis 链表4. 字典5. 跳跃表6. 整数set&#xff08;intset&#xff09;6.1. 升级&…

【C++ 】list 类

1. 标准库中的list类 list 类 的介绍&#xff1a; 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代 2. list与forward_list非常相似&#xff1a;最主要的不同在于forward_list是单链表 3. 与其他的序列式容器相比(a…

汇编语言(Assemble Language)学习笔记(更新中)

零.学习介绍和使用工具 【1】我们使用的教材是机械工业出版社的《32位汇编语言程序设计第二版》。 指导老师是福州大学的倪一涛老师。 这门课程教授的是Intel 80*86系列处理器的32位汇编。我们现在的处理器都兼容这个处理器。 这篇博客只是大二下汇编语言学习的总结&#xff…

城乡居民基本医疗信息管理系统|基于Springboot的城乡居民基本医疗信息管理系统设计与实现(源码+数据库+文档)

城乡居民基本医疗信息管理系统目录 目录 基于Springboot的城乡居民基本医疗信息管理系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1、病例管理 2、医院资讯信息管理 3、医院资讯类型管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选…

第十四次CCF-CSP(第二题 买菜、第四题 再卖菜)

第十四次CCF-CSP 第二题 买菜 原题链接&#xff1a;3263. 买菜 - AcWing题库 思路分析 简单来说&#xff0c;就是给出两组区间的集合A,B 求出两集合中相交区间的部分的长度&#xff0c;注意若区间 [s,t] 是相交的&#xff0c;则长度为 t-s 。 思路一 因为数据量比较小&am…

传输层的UDP协议

1. UDP协议报文格式 1.1 16位端口号 UDP协议报文中&#xff0c;端口号占2个字节&#xff0c;包括 源端口号 和 目的端口号。 1.2 16位UDP长度 UDP报文长度为2个字节 &#xff0c;即UDP数据报长度为0~65535&#xff0c;也就是64kb。 1.3 16位UDP检验和 数据在网络传输的…

Opencv4.5读取视频文件失败的原因

0. 写在前面 这篇短文是对上期编译的一个补充&#xff1a;Windows11OpenCV4.5Qt5.9.1安装教程_opencv4.5.4 windows11安装-CSDN博客 1. 问题现象 上篇博文是读取图片数据成功&#xff0c;结果今天做项目&#xff0c;测试视频文件和录像时&#xff0c;发现capture.isOpened()返…

ROS2组件component自定义实现

ROS2系列文章目录 ROS2中nav_msgs/msg/Path 数据含义及使用 ROS2中std_msgs/msg/Header 数据含义及使用 ROS中TF变换详解 ROS2中launch编写及参数含义&#xff08;launch.xml、python&#xff09; 提示&#xff1a;阅读并实践本文档后&#xff0c;将掌握并理解ros1中nodele…