跨平台应用进程cpu与内存监控的搭建说明

1. 前言:

随着科技的进步,互联网发展,能网上办理的就网上办理,按装一个app客户端,连接后台服务,只要是有网络就OK.便捷,快速,省事.但随之而来的是pc端上安装的应用越来越多,系统资源越来越不够用.这也一定程度上对应用程序有一定的要求,除了实现其功能外,性能也是需要关注的.

2. 目的

有了前言背景,那也不难理解,本文编写的目的即如何关注监测应用进程的性能.一般来说这也是跟业务脱不开关系.指标其实很简单与服务器性能指标相同还会更简单一些,比如cpu,内存使用率等.场景也就是核心的业务场景.比如一个应用具有杀毒,基线扫描与修复功能等,那就需要关注在杀毒或是基线扫描与修复时其进程使用cpu与内存使用情况,还有一个就是稳定性,在没有进行业务逻辑操作时,长时间的挂着应用会对系统有何影响等.

3. 实现方式

目标明确了,那就是如何实现,本文会使用比较流行常用的监控工具,有完整的操作手册,还支持跨平台操作.那就是当仁不让的工具"prometheus+grafana",工具是现成的,就是数据采集跟服务器端还是有一定的差别的.这里实现的是在pc端采集数据主动推送到prometheus进而再在grafana里展现出来.

最终展示出来的结果如下:
请添加图片描述

3.1. 环境准备

python环境,prometheus+grafana服务器

3.2. 具体操作

首先是使用python调用prometheus_client客户端函数,使用数据推送到prometheus pushgateway里,下面为python实现获取本地应用进程使用cpu,内存数据,然后推送到prometheus pushgateway.

3.2.1. python脚本

# -*- coding: utf-8 -*-
# @Time    : 2024-3-30
# @Author  : zhh
# @Version :
# @File    : app_perf.py
# @Software: PyCharm# pip install psutil matplotlib prometheus_client
import time
import threading
import psutil
# import matplotlib.pyplot as plt
from prometheus_client import CollectorRegistry, Counter, Gauge, push_to_gateway
import os
from datetime import datetime
import platform
import socket# 获取当前系统基本信息
def get_local_ip():try:# 获取当前系统类型system_typesystem_type = platform.system()# 创建一个Socket对象s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)# 获取当前系统名fqdn = socket.getfqdn()# 连接到远程主机,这里选择Google的DNS服务器s.connect(("8.8.8.8", 80))# 获取本地IP地址local_ip = s.getsockname()[0]# 关闭Socket连接s.close()return fqdn, system_type, local_ip,except Exception as e:print("获取系统信息出错:", e)return None
def pushgetway(cpu,mem,process):fqdn,system_type,local_ip=get_local_ip()registry = CollectorRegistry()if system_type=="Linux":process = process+"Linux"# 定义获取cpuc = Gauge('cpu_usage', 'get cpu usage', ['processName','platform','instance','hostname','hostIP'], registry=registry)c.labels(processName=process,platform=system_type,instance="",hostname=fqdn,hostIP=local_ip).set(cpu)  # +1# 定义获取memroym = Gauge('memory_usage', 'get mem usage', ['processName','platform','instance','hostname','hostIP'], registry=registry)m.labels(processName=process,platform=system_type,instance="",hostname=fqdn,hostIP=local_ip).set(mem)  # -10push_to_gateway('10.90.21.12:9091', job=process, registry=registry)
def get_process_info(process_name):pid = Nonenum_cores = psutil.cpu_count(logical=True)for proc in psutil.process_iter(['pid', 'name']):if proc.info['name'] == process_name:pid = proc.info['pid']breakif pid is not None:process = psutil.Process(pid)cpu_percent = process.cpu_percent(interval=1)# total_cpu_percent = cpu_percent / num_cores# memory_percent = process.memory_percent()# return cpu_percent, memory_percent# 获取内存信息(返回字节数)memory_info = process.memory_info()# 获取进程的rss即物理内存,将字节数转换为MBmemory_in_mb = memory_info.rss / (1024 * 1024)# print(f"当前进程使用的内存: {memory_in_mb:.2f} MB")return cpu_percent, memory_in_mbelse:return None, None
# 写入时间def write_file(process,cpu,mem):
#     # print(process,cpu,mem)
#     # 获取当前执行工作的绝对路径
#     current_path = os.path.abspath(os.getcwd())
#     file_path = os.path.join("", current_path, process+"_perf.txt")
#     # print('Current Working Directory:', file_path)
#     # 获取当前日期和时间
#     current_datetime = datetime.now()
#     # 格式化时间为指定格式
#     formatted_time = current_datetime.strftime("%Y-%m-%dT%H:%M:%S")
#     # print('Current Date and Time:', formatted_time)
#
#     # 打开一个txt文件,如果文件不存在会自动创建并追加数据
#     with open(file_path, 'a') as file:
#         content = formatted_time + " " + str(cpu) + " " + str(mem) + "\n"
#         # 追加数据到文件
#         file.write(content)
#     # print('Additional data has been saved to example.txt')、cpu、memory到执行目录的app_perf.txt文件中# 定义一个函数,作为线程要执行的任务
def task(process):cpu_percent, memory_in_mb = get_process_info(process)print("*****",process,cpu_percent,memory_in_mb)if cpu_percent is not None:# print("***task****",process, cpu_percent, memory_in_mb)pushgetway(cpu_percent, memory_in_mb, process)# write_file(process,cpu_percent, memory_in_mb)# Press the green button in the gutter to run the script.
if __name__ == '__main__':fqdn, system_type, local_ip = get_local_ip()if system_type=="Darwin":process_name = ["CAZeroTrust", "com.chiansecurity.caztpmac.helper", "CASAviraService","FileService","NetAccess","CASBaseEndpointSecurity"]  # macOS替换成你要监控的进程名elif system_type=="Windows":process_name = ["caztpaui.exe", "caztpasvc.exe", "caztpawh.exe", "caztpAV.exe","caztpasw.exe"]elif system_type == "Linux":process_name = ["caztp", "CAZeroTrust", "catray"]while True:# 创建多个线程并启动threads = []for i in range(len(process_name)):t = threading.Thread(target=task, args=(process_name[i],))threads.append(t)t.start()# 等待所有线程执行完毕for t in threads:t.join()# print("All threads have finished.")# break

3.2.2. prometheus+grafana服务器搭建

在此使用的是macOS系统,当时下载了个docker桌面应用,启动后自动的就有docker-compose组件.只需做好配置文件,直接启动docker-compose即可.

需要注意的也就是两个配置文件:docker-compose.yml, prometheus.yml

version: "3"
services:prometheus:image: prom/prometheus:v2.36.2container_name: prometheusvolumes:- ./prometheus.yml:/etc/prometheus/prometheus.yml- ./data/prometheus_data:/prometheusports:- "9090:9090"grafana:image: grafana/grafana:9.0.1container_name: grafanavolumes:- ./data/grafana_data:/var/lib/grafana#- ./grafana/provisioning:/etc/grafana/provisioningenvironment:- GF_SECURITY_ADMIN_USER=admin- GF_SECURITY_ADMIN_PASSWORD=hogwarts- GF_USERS_ALLOW_SIGN_UP=falseports:- "3000:3000"influxdb:image: influxdb:1.8.10container_name: influxdbports:- "8086:8086"volumes:- ./data/influxdb_data:/var/lib/influxdb

Prometheus.yml文件内容如下:

# my global config
global:scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.# scrape_timeout is set to the global default (10s).# Alertmanager configuration
alerting:alertmanagers:- static_configs:- targets:# - alertmanager:9093# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:# - "first_rules.yml"# - "second_rules.yml"# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.- job_name: "prometheus"# metrics_path defaults to '/metrics'# scheme defaults to 'http'.static_configs:- targets: ["localhost:9090"]- job_name: redis_exporterstatic_configs:- targets:- 10.1.1.11:9121- job_name: node_exporterstatic_configs:- targets:- 10.1.1.11:9100- job_name: pushgatewaystatic_configs:- targets:- pushgateway:9091

启动docker-compose

创建文件夹,把上面的文件放入到文件夹中,再创建一个空的data数据存储文件夹.如"/docker/monitoring"
请添加图片描述

cd /docker/monitoring #进入到此文件夹下
docker-compose up -d #执行一键启动docker-compose ,数据文件夹data,配置文件docker-compose.yml与prometheus.yml配置正确

请添加图片描述
启动成功后在浏览器中输入"http://10.90.21.12:9090/targets?search="
请添加图片描述
在浏览器输入"http://10.90.21.12:9091/"即可看到各客户端推送的数据
请添加图片描述
请添加图片描述
请添加图片描述

3.2.3. 数据源与面板展示配置

浏览器输入"http://10.90.21.12:3000/"打开grafana,进行数据源与展示的数据面板配置
请添加图片描述
面板是自定义的面板:
请添加图片描述
请添加图片描述
请添加图片描述

4. 其他

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

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

相关文章

python如何输入矩阵

使用numpy创建矩阵有2种方法&#xff0c;一种是使用numpy库的matrix直接创建&#xff0c;另一种则是使用array来创建。 首先导入numpy&#xff1a; &#xff08;1&#xff09;import numpy &#xff08;2&#xff09;from numpy import * &#xff08;3&#xff09;import …

【JVM】JVM调优练习-随笔

JVM实战笔记-随笔 前言字节码如何查看字节码文件jclasslibJavapArthasArthurs监控面板Arthus查看字节码信息 内存调优内存溢出的常见场景解决内存溢出发现问题Top命令VisualVMArthas使用案例 Prometheus Grafana案例 堆内存情况对比内存泄漏的原因:代码中的内存泄漏并发请求问…

MenuToolButton自绘控件,带下拉框的QToolButton,附源码

MenuToolButton自绘控件&#xff0c;带下拉框的QToolButton 效果 下拉样式可自定义 跟随QToolButton的Qt::ToolButtonStyle属性改变图标文字样式 使用示例 正常UI文件创建QToolButton然后提升&#xff0c;或者直接代码创建都可以。 // 创建一个 QList 对象来存储 QPixm…

关于MySQL的一些相关规定

1.为什么阿里巴巴规定不能超过三张表join 之所以不建议使用join查询&#xff0c;最主要的原因就是join的效率比较低。 MySQL是使用了嵌套循环&#xff08;Nested-Loop Join&#xff09;的方式来实现关联查询的&#xff0c;简单点说就是要通过两层循环&#xff0c;用第一张表做…

TDC 5.0:多集群统一纳管,构建一体化大数据云平台

近期&#xff0c;星环科技数据云平台Transwarp Data Cloud&#xff08;简称TDC&#xff09;5.0版本正式发布&#xff0c;TDC5.0架构屏蔽底层多个TDH集群的差异&#xff0c;采用统一操作模式&#xff0c;新增一个多集群抽象与管理层&#xff0c;能够实现多集群网络互通、跨集群资…

使用 RocketMQ 实现消息的顺序消费

在分布式系统中&#xff0c;保持消息的顺序性是一个常见且重要的问题。RocketMQ 提供了一种有效的方式来确保消息的顺序消费。本文将通过代码示例&#xff0c;介绍如何使用 RocketMQ 实现消息的顺序生产和消费。 环境准备 在开始之前&#xff0c;请确保您已经配置好 RocketMQ…

QT纯代码实现滑动开关控件

开关按钮大家应该很熟悉&#xff0c;在设置里面经常遇到&#xff0c;切换时候的滑动效果比较帅气。通常说的开关按钮&#xff0c;有两个状态&#xff1a;on、off。大部分的开关按钮控件&#xff0c;基本上有两大类&#xff0c;第一类是纯代码绘制&#xff0c;这种对代码的掌控度…

dhtmlx-gantt甘特图数据展示

官网文档&#xff1a;甘特图文档 实现效果&#xff1a; 首先需要下载 dhtmlx-gantt组件 npm i dhtmlx-gantt //我项目中使用的是"dhtmlx-gantt": "^8.0.6" 这个版本&#xff0c;不同的版本api或是文档中存在的方法稍有差异 界面引用 <template>&l…

目标检测算法与应用算法 DS集成 接口相关_v0.1

目录 文章目录 目录0. 目标GPS信息、速度、加速度、航向角信息的输出1. 目标检测算法接口1.1 模型相关1.2 检测结果相关 2. 应用算法接口2.1 bool cross_line; //跨线&#xff08;变道压线检测&#xff09;2.2 bool break_in; //闯入&#xff08;目标闯入&#xff09;2.3 bool …

Linux HOOK机制与Netfilter HOOK

一. 什么是HOOK&#xff08;钩子&#xff09; 在计算机中&#xff0c;基本所有的软件程序都可以通过hook方式进行行为拦截&#xff0c;hook方式就是改变原始的执行流。 二. Linux常见的HOOK方式 1、修改函数指针。 2、用户态动态库拦截。 ①利用环境变量LD_PRELOAD和预装载机…

【Python】python中list的迭代

什么是迭代&#xff1a; 迭代其实就是遍历整个数据结构 nums [3,4,5] for n in nums:print(n)上述代码中&#xff0c;我们定义了一个nums列表&#xff0c;并且使用for循环对其进行遍历。其实整个过程就是迭代&#xff0c;所谓迭代&#xff0c;就是对数据集中每一个元素对其进…

STM32自己从零开始实操:PCB全过程

一、PCB总体分布 以下只能让大家看到各个模块大致分布在板子的哪一块&#xff0c;只能说每个人画都有自己的理由&#xff1a; 电源&#xff1a;从外部接入电源&#xff0c;5V接到中间&#xff0c;向上变成4V供给无线&#xff0c;向下变成3V供给下面的接口&#xff08;也刻意放…

无极与有极电容的区别

无极性电容与有极性电容&#xff1a;差异与应用探索 在电子元件的广阔世界里&#xff0c;电容器无疑是不可或缺的一部分。它们以储存电荷和调节电路中的电压与电流而闻名。然而&#xff0c;电容器并非一概而论&#xff0c;其中最为显著的区别之一就是无极性电容与有极性电容。…

Springboot中常见的注解及其底层实现?

Spring Boot 是一个用于简化 Spring 应用初始搭建以及开发过程的框架&#xff0c;它大量使用了注解来简化配置和提高开发效率。以下是一些常见的 Spring Boot 注解及其底层实现&#xff1a; ### 1. SpringBootApplication 这是一个复合注解&#xff0c;包含了 Configuration、…

DP讨论——访问者模式

学而时习之&#xff0c;温故而知新。 访问者模式 角色 3个角色&#xff0c;访问者类&#xff0c;被访问者类&#xff0c;管理被访问者类的类。 特色 所谓访问者模式&#xff0c;我感觉就是被访问的类的方法形参是别的对象引用&#xff0c;然后临时过来进入一下&#xff0c…

每日一练 - BGP 路由表中的团体属性

01 真题题目 下面一台路由器的输出信息&#xff0c;关于这段信息描述正确的是? A.目的网段 1.1.1.0/24 所携带的团体属性值是 NO-EXPORT&#xff0c; 表明该路由条目不能通告给任何 BGP 邻居 B.目的网段 1.1.1.0/24 所携带的图体属性值是 NO-EXPORT&#xff0c; 表明试路由…

Python面试整理-Python中的变量和赋值:理解变量的命名规则、赋值方式以及变量类型

在Python中,变量用于存储数据。以下是关于变量的命名规则、赋值方式和变量类型的详细说明: 变量的命名规则 1. 字母、数字和下划线: ● 变量名必须以字母(a-z,A-Z)或下划线(_)开头,后续字符可以是字母、数字(0-9)或下划线。 ● 例如:my_var, _var2, var3 2.

Three.JS 使用RGBELoader和CubeTextureLoader 添加环境贴图

导入RGBELoader模块&#xff1a; import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js"; 使用 addRGBEMappingk(environment, background,url) {rgbeLoader new RGBELoader();rgbeLoader.loadAsync(url).then((texture) > {//贴图模式 经纬…

三个国产数据库调研(达梦,PolarDB,TDSQL

三个国产数据库调研&#xff1a;达梦&#xff0c;PolarDB&#xff0c;TDSQL 1. 整体描述2. 达梦数据库2.1 相关网站2.2 接入工作2.3 工具使用2.4 总结 3. PolarDB数据库3.1 相关网站3.2 产品对比3.3 接入工作 4. TDSQL数据库4.1 相关网站4.2 产品对比4.3 接入工作 5. 对比总结5…

git使用-命令行+VS Code结合使用

一、Git常用命令 // 显示当分支的状态。它会列出已修改、已暂存和未跟踪的文件 git status// 列出本地仓库中所有的分支&#xff0c;其中会特殊显示当前所在分支 git branch// 在当前分支的基础上创建一个新的分支&#xff0c;并切换到这个新的分支上 git checkout -b 新分支…