SpringBoot 輕量級一站式日志可視化與JVM監控

一、項目初衷

Java 應用開發的同學都知道,項目上線后,日志的可視化查詢與 JVM 的可視化監控是一件非常重要的事。
市面上成熟方案一般是采用 ELK/EFK 實現日志可視化,采用 Actuator?+?Prometheus?+?Grafana 實現 JVM 監控。
這兩套都是非常優秀的解決方案,不過對于很多開發者來說,這中間存在大量的繁瑣的配置過程。
而對于大多數中小型企業來說,很多都是一個簡單的單體項目,并不想要多余的運維和部署成本!
為此我們希望通過一些低門檻的方式,實現日志的自動采集與日志可視化查詢。

二、軟件介紹

我們的目標:zero-observer + zero-log = actuator + prometheus + granfana + elk / efk

1. 主要功能

  • 應用日志查詢:

    ?提供控制臺面板與列表兩種方式查詢應用日志;

  • 慢接口監控:

    ?監控 Java 服務中請求超過閾值的接口,支持通用配置與自定義配置;

  • JVM 監控:

    ?監控 JVM 進程中的各種指標,包括堆內存、非堆內存、Eden、Survivor、OldGen、Metaspace、線程、GC、物理內存、CPU 等。

2. 系統架構

圖片

本項目主要分為客戶端和服務端兩個部分。

3. Java 日志采集客戶端【zero-log】

采集客戶端旨在提供低門檻、少配置、輕量級、無侵入的方式實現日志、JVM 指標的自動采集與發送。

zero-log 基于 logback 實現將代碼中通過 log.error、log.warn、log.info、log.trace?等方式輸出的日志與 JVM 運行時的各項指標自動采集并發送到遠程服務器上
原系統代碼無需任何改動,只需要引入 zero-log 的依賴,同時在 logback-spring.xml 中添加 HttpBatchAppender,配置采集數據接收的接口即可實現自動采集與傳輸。

4. 服務端【zero-observer】

收集客戶端采集插件采集的客戶端數據,包括應用日志、JVM 指標等,并提供開箱即用的可視化檢索功能,極大降低了 Java 應用日志與 JVM 指標監控可視化檢索的門檻。

5. 功能介紹

儀表盤

圖片

應用日志

圖片

控制臺日志

圖片

慢接口日志

圖片

日志查詢

圖片

日志詳情

圖片

JVM 監控

圖片

圖片

圖片

三、服務端安裝

zero-observer 數據存儲使用的是 mysql 與 elasticsearch,mysql 存儲的是系統數據,elasticsearch 存儲的是日志數據。 所以需要自行安裝 mysql 與 elasticsearch。

1. Mysql 初始化腳本

創建數據庫:zero_observer

CREATE TABLE `app_log_growth_trend` (`id` bigint(20) NOT NULL,`create_time` datetime NOT NULL,`app` varchar(255) NOT NULL,`env` varchar(50) NOT NULL,`level` varchar(10) NOT NULL,`statistic_time` datetime NOT NULL,`log_count` int(11) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;CREATE TABLE `app_log_total_growth_trend` (`id` bigint(20) NOT NULL,`create_time` datetime NOT NULL,`statistic_time` datetime NOT NULL,`log_count` bigint(20) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;CREATE TABLE `app_log_level_statistic` (`id` bigint(20) NOT NULL,`create_time` datetime NOT NULL,`app` varchar(255) NOT NULL,`env` varchar(50) NOT NULL,`level` varchar(10) NOT NULL,`statistic_time` datetime NOT NULL,`log_count` int(11) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;CREATE TABLE `app_env_instance` (`id` bigint(20) NOT NULL,`create_time` datetime NOT NULL,`app` varchar(255) NOT NULL,`env` varchar(50) NOT NULL,`ip` varchar(50) NOT NULL,`port` varchar(5) NOT NULL,`hostname` varchar(255) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;CREATE TABLE `app_log_statistic` (`id` bigint(20) NOT NULL,`create_time` datetime NOT NULL,`app_log_statistic_counter_id` bigint(20) NOT NULL,`app` varchar(255) NOT NULL,`env` varchar(50) NOT NULL,`statistic_time` datetime NOT NULL,`log_count` bigint(20) NOT NULL DEFAULT '0',`slow_request_count` bigint(20) NOT NULL DEFAULT '0',`error_count` bigint(20) NOT NULL DEFAULT '0',`warn_count` bigint(20) NOT NULL DEFAULT '0',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;CREATE TABLE `app_log_statistic_counter` (`id` bigint(20) NOT NULL,`create_time` datetime NOT NULL,`statistic_time` datetime NOT NULL,`statistic_status` int(11) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;CREATE TABLE `system_config` (`id` bigint(20) NOT NULL COMMENT '主鍵',`create_time` datetime NOT NULL COMMENT '創建時間',`key_code` varchar(50) NOT NULL COMMENT 'key編碼',`key_name` varchar(50) DEFAULT NULL COMMENT 'key 名稱',`key_value` varchar(255) NOT NULL COMMENT 'key值',`enabled` int(11) NOT NULL DEFAULT '1' COMMENT '是否啟用',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;INSERT INTO `system_config` (`id`, `create_time`, `key_code`, `key_name`, `key_value`, `enabled`)
VALUES (1, '2025-07-19 23:56:06', 'app_log_storage_days', '應用日志存儲天數', '3', 1);CREATE TABLE `users` (`id` bigint(20) NOT NULL,`create_time` datetime NOT NULL,`account` varchar(100) NOT NULL,`pwd` varchar(255) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;CREATE TABLE `token_info` (`id` bigint(20) NOT NULL,`create_time` datetime NOT NULL,`subject` varchar(100) NOT NULL,`token` varchar(255) NOT NULL,`expire_time` datetime NOT NULL,`expire_timestamp` bigint(20) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;CREATE TABLE `license` (`id` bigint(20) NOT NULL,`create_time` datetime NOT NULL,`content` text NOT NULL,`remark` text DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

2. Docker 部署

# 拉取鏡像
docker pull registry.cn-hangzhou.aliyuncs.com/kuafucv/zero-observer:1.1.0
# 啟動容器
docker run -itd -p 8080:8080 --name zero-observer \-e TZ=Asia/Shanghai-e ES_IP=127.0.0.1 \-e ES_PORT=9200 \-e ES_USERNAME=es \-e ES_PASSWORD=es \-e MYSQL_IP=127.0.0.1 \-e MYSQL_PORT=3306 \-e MYSQL_USERNAME=root \-e MYSQL_PASSWORD=123456 \registry.cn-hangzhou.aliyuncs.com/kuafucv/zero-observer:1.1.0

參數解析:

  • TZ:時區,默認 Asia/Shanghai

  • ES_IP:elasticsearch 的 ip

  • ES_PORT:elasticsearch restapi 的端口

  • ES_USERNAME:elasticsearch 用戶名,無則不填即可

  • ES_PASSWORD:elasticsearch 密碼,無則不填即可

  • MYSQL_IP:mysql 的ip

  • MYSQL_PORT:mysql 端口

  • MYSQL_USERNAME 用戶名

  • MYSQL_PASSWORD 密碼

啟動成功后,瀏覽器訪問:http://127.0.0.1:8080/zero-observer/
默認用戶密碼:admin/123456

四、Java 應用日志快速接入

1. 引入 maven 依賴


<dependency><groupId>io.github.kuafucv</groupId><artifactId>zero-log-spring-boot-starter</artifactId><version>1.1.0</version>
</dependency>

2. 配置 logback-spring.xml

<configuration debug="false"><springProperty name="app_name" source="spring.application.name"/><springProperty name="env" source="spring.profiles.active"/><springProperty name="port" source="server.port"/><conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" /><conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" /><conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" /><property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN:-[%X{TRACE_ID}] %d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%15.15t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/><property name="FILE_LOG_CHARSET" value="${FILE_LOG_CHARSET:-${file.encoding:-UTF-8}}"/><appender name="BATCH_HTTP" class="io.github.kuafucv.zero.log.core.HttpBatchAppender"><!-- 必需:參照 logback 的 encoder 配置 --><encoder><pattern>${FILE_LOG_PATTERN}</pattern><charset>${FILE_LOG_CHARSET}</charset></encoder><!--請求的地址--><!-- 廢棄:日志接收接口URL,該配置已過時,后續版本將刪除該配置,建議使用 serverUrl 進行配置 --><endpointUrl>http://ip:port/zero-observer/appLog/report</endpointUrl><!-- 必需:日志接收接口URL --><serverUrl>http://ip:port/zero-observer/</serverUrl><!-- 必填:應用名稱 --><appName>${app_name}</appName><!-- 可選:環境,默認值:env --><env>${env}</env><!-- 可選:服務端口,默認值:0 --><appServerPort>${port}</appServerPort><!-- 可選:是否包含MDC上下文 --><includeMDC>true</includeMDC><!-- 可選:日志傳輸頻率,單位秒,默認值:3 秒 --><flushIntervalInSeconds>3</flushIntervalInSeconds><!-- 可選:請求超時時間,默認值:1000 毫秒 --><httpReadTimeoutInMillis>1000</httpReadTimeoutInMillis><!-- 可選:請求超時時間,默認值:1000 毫秒 --><httpConnectionTimeoutInMillis>1000</httpConnectionTimeoutInMillis><!-- 可選:日志存儲滾筒最大數量,默認值:8 --><maxNumberOfBuckets>8</maxNumberOfBuckets><!-- 可選:每個日志存儲滾筒大小(KB),默認值:1024 --><maxBucketSizeInKilobytes>1024</maxBucketSizeInKilobytes></appender><!-- 日志輸出級別 --><root level="INFO"><appender-ref ref="BATCH_HTTP" /></root>
</configuration>

注意:

  • 這里僅僅展示 springboot 下的 logback-spring-xml 的配置,非 springboot 項目自行配置。

  • 主要是新增 io.github.kuafucv.zero.log.core.HttpBatchAppender 日志 Appender,該 Appender 中的 encoder 建議與原項目中輸出到日志文件的 encoder 一致。

  • endpointUrl(過時) 為日志接收的遠程日志中心接口,zero-log 會自動調用該接口,并發送日志數據

  • 推薦使用 serverUrl,該屬性值為 http://ip:port/zero-observer/

3. 全量配置列表

圖片

4. 日志觀測

啟動 Java 服務,等待日志自動上報至 zero-observer 即可。

五、Java 慢接口監控

1. 快速接入

SpringBoot 工程

springboot 工程引入zero-log-spring-boot-starter包,則自動開啟慢接口監控。可以通過配置zero.log.slow-request.enabled=false進行關閉。

zero:log:slow-request:# 是否開啟慢接口健康enabled: true# 默認時間閾值(毫秒)default-time-threshold: 1000
非 SpringBoot 工程

非 springboot 工程引入的是zero-log-core包,無法使用 starter 的自動裝配,所以需要手

@Bean
public FilterRegistrationBean<SlowRequestFilter> slowRequestFilterFilterRegistrationBean() {FilterRegistrationBean<SlowRequestFilter> bean = new FilterRegistrationBean<>();bean.setFilter(new SlowRequestFilter());bean.setOrder(Integer.MIN_VALUE);bean.setUrlPatterns(Collections.singletonList("/*"));return bean;
}

其他更古老的項目,如使用 servlet 的 web.xml 配置的方式,請自行配置。

2. 高階配置

同一系統不同的接口,慢的時間閾值可能存在一定差別,zero-log 支持高階的自定義配置,實現不同接口的不同閾值配置能力。

@Component
public class SlowRequestThresholdFactoryImpl implements SlowRequestThresholdFactory {@Overridepublic List<SlowRequestThreshold> build() {List<SlowRequestThreshold> list = new ArrayList<>();SlowRequestThreshold s0 = new SlowRequestThreshold();s0.setUrlPattern("/**/user/**");s0.setTimeThreshold(500);list.add(s1);SlowRequestThreshold s1 = new SlowRequestThreshold();s1.setUrlPattern("/**");s1.setTimeThreshold(2000);list.add(s1);return list;}
}

不論是否是 springboot 工程,本質都是通過實現 SlowRequestThresholdFactory 接口的 build 方法,返回 List 集合,實現自定義不同接口的不同閾值能力。

注意事項:

接口匹配是通過 spring 的 AntPathMatcher 實現的,所以 SlowRequestThreshold.urlPattern 的值配置規則參考 spring AntPathMatcher 匹配規則。接口匹配根據放回的 List 從上到下逐個匹配,匹配到了則不再繼續匹配,所以 urlPattern 范圍更大的配置需要發放在 List 集合的的后面。如果匹配不到,則使用默認閾值。默認閾值與 SlowRequestThreshold 里設置的閾值,如果 小于等于 0,則默認該接口不做慢接口監控,不會進行日志輸出。

開源地址:

https://gitee.com/kuafucv/zero-observer

架構設計之道在于在不同的場景采用合適的架構設計,架構設計沒有完美,只有合適。

在代碼的路上,我們一起砥礪前行。用代碼改變世界!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/96748.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/96748.shtml
英文地址,請注明出處:http://en.pswp.cn/web/96748.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Leetcode hot 100】101.對稱二叉樹

問題鏈接 101.對稱二叉樹 問題描述 給你一個二叉樹的根節點 root &#xff0c; 檢查它是否軸對稱。 示例 1&#xff1a; 輸入&#xff1a;root [1,2,2,3,4,4,3] 輸出&#xff1a;true 示例 2&#xff1a; 輸入&#xff1a;root [1,2,2,null,3,null,3] 輸出&#xff1a;…

Zynq開發實踐(FPGA之選擇開發板)

【 聲明&#xff1a;版權所有&#xff0c;歡迎轉載&#xff0c;請勿用于商業用途。 聯系信箱&#xff1a;feixiaoxing 163.com】我們之所以選用zynq開發板&#xff0c;就在于它支持arm軟件開發&#xff0c;也支持fpga開發&#xff0c;甚至可以運行linux&#xff0c;這是之前沒有…

Flutter Riverpod 3.0 發布,大規模重構下的全新狀態管理框架

在之前的 《注解模式下的 Riverpod 有什么特別之處》我們聊過 Riverpod 2.x 的設計和使用原理&#xff0c;同時當時我們就聊到作者已經在開始探索 3.0 的重構方式&#xff0c;而現在隨著 Riverpod 3.0 的發布&#xff0c;riverpod 帶來了許多細節性的變化。 當然&#xff0c;這…

Xcode 上傳 ipa 全流程詳解 App Store 上架流程、uni-app 生成 ipa 文件上傳與審核指南

對于 iOS 開發者而言&#xff0c;應用開發完成后最重要的一步就是將應用打包為 ipa 文件&#xff0c;并上傳至 App Store Connect 進行分發或上架。 其中&#xff0c;Xcode 上傳 ipa 是最常見的方法&#xff0c;但很多開發者在實際操作中常常遇到卡住、上傳失敗或簽名錯誤等問題…

快速選中對象

圖片要求 圖片背景單純&#xff0c;對象邊緣比較清晰 對象選擇工具 選擇對象選擇工具后&#xff0c;畫出大致區域&#xff0c;系統將自動分析圖片內容&#xff0c;從而實現快速選擇圖片中的一個惑多個對象他有兩種模式&#xff0c;分別是舉行與套索模式。使用時可以先選中對象的…

點到點鏈路上的OSPF動態路由(2025年9月10日)

一、前言前面我們已經分享過了靜態路由、缺省路由、浮動靜態路由這些靜態路由的配置。接下來將會 陸陸續續開始分享動態路由以及其他路由配置。博主這里是一個新人&#xff0c;了解這些路由配置不是自上而下的&#xff0c;而是自下而上的&#xff0c;也就是說通過實驗去理解原理…

技術視界 | 末端執行器:機器人的“手”,如何賦予機器以生命?

在現代自動化系統中&#xff0c;末端執行器&#xff08;End Effector&#xff09;作為機器人與物理世界交互的“手”&#xff0c;發揮著至關重要的作用。它直接安裝在機械臂末端&#xff0c;不僅是機器人實現“抓取、感知和操作”三大核心功能的關鍵部件&#xff0c;更是整個自…

滑動窗口概述

滑動窗口算法簡介滑動窗口是一種用于處理數組或字符串子區間問題的高效算法。它通過維護一個動態窗口&#xff08;通常由兩個指針表示&#xff09;來避免重復計算&#xff0c;將時間復雜度從O(n)優化到O(n)。基本實現步驟初始化窗口指針&#xff1a;通常使用left和right指針表示…

AI 創建學生管理系統

使用騰訊元寶創建&#xff0c;整體效果不錯。修正2個bug跑起來&#xff0c;達到了需要的功能先上效果圖&#xff1a;按鈕分類別配色&#xff0c;界面清爽。喜歡這布局創建過程&#xff1a;prompt: 使用最新穩定vue版&#xff0c;使用pinia存儲&#xff0c;基于typescript, 樣式…

ASP.NET Core 中的簡單授權

ASP.NET Core 中的授權通過 [Authorize] 屬性及其各種參數控制。 在其最基本的形式中&#xff0c;通過向控制器、操作或 [Authorize] Page 應用 Razor 屬性&#xff0c;可限制為僅允許經過身份驗證的用戶訪問該組件。 使用 [Authorize] 屬性 以下代碼限制為僅允許經過身份驗證…

leetcode 493 翻轉對

一、題目描述 二、解題思路 本題的思路與逆序數的思路相似&#xff0c;采用歸并排序的思路來實現。leetcode LCR 170.交易逆序對的總數-CSDN博客 注意&#xff1a;但是逆序數的ret更新在左、右區間合并時更新&#xff0c;但本題ret更新在左、右區間合并前更新。 三、代碼實現…

初識微服務-nacos配置中心

配置中心 概述 配置中心是微服務中不可或缺的組件&#xff0c;因為如果沒有配置中心&#xff0c;那么各個微服務的的配置信息無法得到統一和管理&#xff0c;會變得冗余。 :::color4 配置中心是用于管理應用程序配置信息的工具 集中管理配置&#xff1a;解決微服務架構下配置分…

Android webview更新記錄-aosp

一、下載 webview下載地址&#xff0c;感謝火哥分享&#xff0c;版本很全。 https://www.firepx.com/app/android-system-webview/ 二、更新 external/chromium-webview/prebuilt 具體更新那個目錄&#xff0c;需要查看編譯架構 這個看你的lunch就行&#xff0c;這里我的是a…

無感FOC(無傳感器磁場定向控制)

我們來詳細解析無感FOC&#xff08;無傳感器磁場定向控制&#xff09;中的高頻方波注入&#xff08;High-Frequency Square-Wave Injection, HFSWI&#xff09;?? 的原理。這是一個用于零低速或極低速范圍內估算轉子位置的核心技術。核心思想與要解決的問題在電機靜止或轉速極…

MATLAB基于博弈論組合賦權-云模型的煤與瓦斯突出危險性評價

MATLAB基于博弈論組合賦權-云模型的煤與瓦斯突出危險性評價 1. 問題背景與核心目標 背景&#xff1a;煤與瓦斯突出是煤礦生產中的一種極其復雜的動力災害&#xff0c;其發生機理復雜&#xff0c;影響因素眾多&#xff08;如地應力、瓦斯壓力、煤體物理屬性等&#xff09;。對其…

JavaWeb-Servlet總結及JSP

目錄 一、文件下載 二、ServletConfig對象 三、Web.xml文件使用總結 四、server.xml文件 五、JSP動態網頁技術 1.概念&#xff1a; 2.動態網頁&#xff1a; 3.特點&#xff1a; 4.JSP的訪問原理&#xff1a; 5.JSP的文檔說明&#xff1a; 6.jsp實際運行文件&#xff…

DDIM和DDPM之 間的區別與聯系

核心關系概述 首先&#xff0c;要理解DDIM并不是一個全新的模型&#xff0c;而是DDPM的一個精巧的重新參數化和擴展。它們使用完全相同的訓練目標和方法&#xff0c;因此你可以用一個訓練好的DDPM模型直接來運行DDIM的采樣算法&#xff0c;而無需重新訓練。 DDIM的核心貢獻是&a…

c++---map和set

這里再提二叉樹&#xff08;二叉搜索樹&#xff09;&#xff0c;是為了后面講解map和set做準備。 一、二叉搜索樹 二叉搜索樹又稱二叉排序樹&#xff0c;它或者是一棵空樹&#xff0c;或者是具有以下性質的二叉樹。 若它的左子樹不為空&#xff0c;則左子樹上所有節點的值都…

windows下,podman遷移鏡像文件位置

docker-desktop有自帶的鏡像文件位置遷移功能&#xff0c;但podman-desktop還沒有&#xff0c;所以只能自己操作wsl導入導出來實現# 1.一定要先停止當前machine podman machine stop# 2. 導出當前 machine&#xff08;會生成 tar 鏡像&#xff09; wsl --export podman-machine…

Champ-基于3D的人物圖像到動畫視頻生成框架

本文轉載自&#xff1a;https://www.hello123.com/champ ** 一、&#x1f916; Champ 是什么&#xff1f; 阿里 南大 復旦聯手打造的虛擬人動作黑科技&#xff01;Champ 可不是普通動畫工具&#xff0c;它能把你隨手拍的小視頻變成專業級 3D 動畫 —— 無論跳舞、打拳還是走…