相关文章推荐
谦虚好学的脸盆  ·  2021-06-28 ...·  11 月前    · 
好帅的匕首  ·  五日本女星性感亮相台湾衣着清凉(图)|AV女 ...·  1 年前    · 
买醉的香蕉  ·  Java初始化顺序的验证(Cannot ...·  1 年前    · 
冲动的西瓜  ·  python在服务器上运行慢_PyPI很慢。 ...·  1 年前    · 
聪明伶俐的沙发  ·  bootstrap5 - 夜雨初凉 - 博客园·  1 年前    · 
Code  ›  关于监控服务器指标、CPU、内存、警报的一些解决方案_isc.featuretracker.ssl
prometheus metrics https yx
https://blog.csdn.net/yaoxin521123/article/details/129119470
暗恋学妹的领带
1 年前
  • 关于监控服务器指标、CPU、内存、警报的一些解决方案
    • `Prometheus` + `Grafana` 配置 `IRIS` / `Caché` 监控服务器
      • `Prometheus`
        • 简介
        • 特点
        • 架构图
      • `Grafana`
        • 简介
        • 特点
      • 自定义`Prometheus`接口定义
      • 配置 `Exporter` 监控服务器系统资源
        • 简介
        • 配置流程
      • 使用 `Alertmanager`报警
        • 简介
        • 配置流程
      • 基于`M`实现监控服务器,并用邮件报警
        • 解析`Prometheus`数据接口信息
        • 使用嵌入式`Python`方式获取系统`CPU`、内存等
          • `python`模块之`psutil`详解
            • `CPU`相关
            • `Memory`内存相关
            • `Disk`相关
            • `Network`相关
            • `Process`相关
          • 通过嵌入式`Python`调用`psutil`库
        • 使用邮件发送报警信息
          • 使用`M`发送邮件发送消息
          • 通过配置文件`csv`文件,来获取维护指标,进行邮件报警。
        • 总结
        • 思考
        • 附

        关于监控服务器指标、CPU、内存、警报的一些解决方案

        本文章主要介绍以下几个章节内容:

        • Prometheus + Grafana 配置 IRIS / Caché 监控服务器
        • 自定义 Prometheus 接口定义 - 配置 Caché 监控服务
        • 配置 Exporter 监控服务器系统资源
        • 使用 Alertmanager 报警
        • 基于 M 实现监控服务器,并用邮件报警
          • 解析 Prometheus 数据接口信息
          • 使用嵌入式 Python 方式获取系统 CPU 、内存等
          • 使用邮件发送报警信息

        Prometheus + Grafana 配置 IRIS / Caché 监控服务器

        首先我们介绍一下如何用IRIS结合 Prometheus + Grafana 的使用,在介绍如何配置之前我们先了简单了解一下工具。

        Prometheus

        Prometheus 是一个最初在 SoundCloud 上构建的开源系统监视和警报工具包 。 自 2012 年成立以来,许多公司和组织都采用了 Prometheus ,该项目拥有一个非常活跃的开发人员和用户社区。它现在是一个独立的开源项目,可以独立于任何公司进行维护。为了强调这一点,并澄清项目的治理结构, Prometheus 于 2016 年加入 云计算本地计算基金会,作为继 Kubernetes 之后的第二个托管项目。

        • 具有由度量名称和键/值对标识的时间序列数据的多维数据模型。
        • 一个灵活的查询语言 来利用这一维度。
        • 不依赖分布式存储,单个服务器节点是自治的。
        • 时间序列收集通过 HTTP 上的拉模型发生。
        • 通过中间网关支持推送时间序列。
        • 通过服务发现或静态配置发现目标。
        • 多种图形和仪表板支持模式。

        Grafana

        Grafana 是一个跨平台的开源的度量分析和可视化工具,可以通过将采集的数据查询然后可视化的展示,并及时通知。

        • 展示方式:快速灵活的客户端图表,面板插件有许多不同方式的可视化指标和日志,官方库中具有丰富的仪表盘插件,比如热图、折线图、图表等多种展示方式。
        • 支持多种数据源: Graphite , InfluxDB , OpenTSDB , Prometheus , Elasticsearch , CloudWatch 和 KairosDB 等。
        • 通知提醒:以可视方式定义最重要指标的警报规则, Grafana 将不断计算并发送通知,在数据达到阈值时通过 Slack 、 PagerDuty 等获得通知。
        • 混合展示:在同一图表中混合使用不同的数据源,可以基于每个查询指定数据源,甚至自定义数据源。
        • 注释:使用来自不同数据源的丰富事件注释图表,将鼠标悬停在事件上会显示完整的事件元数据和标记。
        • 过滤器: Ad-hoc 过滤器允许动态创建新的键/值过滤器,这些过滤器会自动应用于使用该数据源的所有查询。
        1. 下载 Prometheus ,选择操作系统,下载对应安装包,以 windows 为例。
        • 下载地址:https://prometheus.io/download/
        1. 下载完成后,直接解压在所需目录即可。解压后进入目录直接运行 premetheus.exe , prometheus 默认端口为 9090 。
        1. 在浏览器输入地址、即可查看监控页面。
        • 地址 - http://localhost:9090/
        1. 配置监控服务器信息,编辑 prometheus-2.27.1.windows-amd64/prometheus.yml 文件。在 scrape_configs: 输入以下代码:
          • 这里以我的私有服务器地址为例:https://8.142.29.250:2443/api/monitor/metrics。

        输入以下代码:

          - job_name: "250-IRIS"
            metrics_path:  /api/monitor/metrics
            scheme: https
            tls_config:
              insecure_skip_verify: true
            static_configs:
            - targets: ['8.142.29.250:2443']
        
        • job_name - 服务器名称。
        • metrics_path - 监控服务器地址路径。
        • scheme - 网络协议。
        • tls_config - insecure_skip_verify - 过滤完成验证。
        • static_configs - targets - IP端口号。
        1. prometheus.yml文件修改完成后,重新启动prometheus.exe程序,进入到Status->Targets下,即可看到添加的监控服务器信息;
        1. 监控具体指标,点击Graph->勾选UseLocalime->输入监控指标iris_cpu_usage->点击Excute->选择监控时长范围30min。
        • iris_cpu_usage - 代表CPU使用率。

        说明:这里监控指标为服务器接口里的具体指标,输入接口地址具体查看。

        1. 由于Prometheus展示的信息相对简单,图表类型也比较少,下面介绍如何使用Grafana展示数据。输入Grafana地址,下载对应版本。
        • 下载地址:https://grafana.com/grafana/download?
        1. 下载后直接运行安装,安装完成后进入grafana/bin目录下,双击运行garafana-server.exe。
          • garafana默认端口为3030
          • 访问地址:http://localhost:3000/
          • 默认用户名密码admin/admin
        1. 在grafana里添加数据源Data Source。
        1. 选择Prometheus。
        1. 填写数据源信息,并保存。
        • Name - Prometheus
        • Url - http://localhost:9090
        • 点击Save&test显示测试成功。
        1. 创建模版,点击Dashboards->点击Browse->输入模版名称->New->NewDashboard。
        1. 点击Add a new panel。
        1. 选择数据源Data source,指标iris_cpu_usage -> Run query。
        • Title - 修改仪表盘名称。
        1. 输入仪表盘名称,点击保存即可。
        1. 最终效果,依次类推建立多个监控指标。
        • iris_csp_sessions - 会话使用数
        • iris_cpu_usage - cpu使用率
        • iris_system_alerts - 系统警报数
        • iris_process_count - 进程数量
        • iris_glo_ref_per_sec - Global每秒引用数量

        自定义Prometheus接口定义

        那么我们是否可以自定义Prometheus接口呢?

        答案肯定是可以的,整好 Caché 没有自带的监控服务,所以我们给Caché 自定义个一个监控服务接口。

        1. 首先我们需要创建一个Rest接口类M.Metrics。
        Class M.Metrics Extends %CSP.REST
        
        1. 在Portal中配置Rest接口,系统->安全管理->Web应用程序->编辑Web引用程序。
        • 名称 - /api/metrics
        • 命名空间 - 选择Rest接口类所在命名空间
        • 分派类 - M.Metrics
        1. 编写Rest接口逻辑,下面展示主要业务逻辑代码。
        • 基础仪表盘接口
        ClassMethod GetDashboardMetrics(ByRef array As %DynamicArray) As %Status
        	s dashboard = ##class(SYS.Stats.Dashboard).Sample()
        	s properties = ##class(%Dictionary.ClassDefinition).%OpenId(dashboard.%ClassName(1)).Properties
        	for i = 1 : 1 : properties.Count() {
        		s property = properties.GetAt(i)
        		s propertyName = property.Name
        		s propertyValue = $property(dashboard, propertyName)
        		if ((propertyValue '= "") && ('$match(propertyValue, ".*[-A-Za-z ]+.*")))
        
        
        
        
            
         {
        			s metricsName = ..CamelCase2Underscore(propertyName)
        			s metricsValue = propertyValue
        			s obj = {}
        			s obj.key = metricsName
        			s obj.val = metricsValue
        			d array.%Push(obj)
        	q $$$OK
        
        • 系统使用情况
        d ##class(SYS.Metrics).GetMainMetrics("", 0, .pValues, .pStatus, .pMsg)
        
        • 系统监视器统计
        d ##class(SYS.Metrics).GetGlobalStatistics("", 0, .pValues, .pStatus, .pMsg)
        
        • ECP 数据统计
        d ##class(SYS.Metrics).GetECPStatistics("", 0, .pValues, .pStatus, .pMsg)
        
        • 磁盘和缓冲区数据统计
        d ##class(SYS.Metrics).GetStatistics("",0,.pValues,.pStatus,.pMsg)
        
        • 许可数据统计
        ClassMethod GetLicenseStatistics(ByRef array As %DynamicArray)
            s licenseUsed = ##class(%SYSTEM.License).LUConsumed()
            s obj = {}
            s obj.key = ..#PREFIX _ "_license_used"
            s obj.val = licenseUsed
            d array.%Push(obj)
            s licenseAvailable=##class(%SYSTEM.License).LUAvailable()
            s obj = {}
            s obj.key = ..#PREFIX _ "_license_avail"
            s obj.val = licenseAvailable
            d array.%Push(obj)
            s licenseTotal=##class(%SYSTEM.License).GetUserLimit()
            s obj = {}
            s obj.key = ..#PREFIX _ "_license_total"
            s obj.val = licenseTotal
            d array.%Push(obj)
            s obj = {}
            s obj.key =..#PREFIX _ "_license_load"
            s obj.val = $fn((licenseUsed / (licenseAvailable + licenseUsed)), "N", "4")
            d array.%Push(obj)
        
        • 开放性事务数据统计
        ClassMethod GetOpenTransactionStatistics(ByRef array As %DynamicArray)
        	if ($zv [ "Cache") {
        		s index = "^CacheTemp.SysMetrics"
        	} else {
        		s index = "^IRIS.Temp.SysMetrics"
        	if (@index@("Transactions")) = "OK" {
        		s val = 1
        	} else {
        		s val = 0
            s obj = {}
            s obj.key = ..#PREFIX _ "_open_transaction"
            s obj.val = val
            d array.%Push(obj)
        
        • 数据库情况
        ClassMethod GetDatabaseStatistics(ByRef array As %DynamicArray)
        	s statement = ##class(%SQL.Statement).%New()
        	s sc = statement.%PrepareClassQuery("%SYS.DatabaseQuery", "FreeSpace")
        	s rs = statement.%Execute()
        	while (rs.%Next()) {
        	    s databaseName = rs.%Get("DatabaseName")
        	    s freeRate = rs.%GetData(7)
        	    s availableNum = rs.%Get("AvailableNum")
        	    s diskFreeSpaceNum = rs.%Get("DiskFreeSpaceNum")
         		s obj = {}
           	 	s obj.key =..#PREFIX _ "_database_free"
            	s obj.val = (100 - freeRate) / 100
            	s tag = {}
        		s tag.id = databaseName
        	    s obj.tag = tag
        	    d array.%Push(obj)
        
        • 把所有数据组装到一起。
        ClassMethod GetMetrics()
        	s array = []
        	#; 基础仪表盘
        	d ..GetDashboardMetrics(.array)
        	#; 系统使用情况
        	d ##class(SYS.Metrics).GetMainMetrics("", 0, .pValues, .pStatus, .pMsg)
        	d ..ParseJson(.pValues, .array)
        	#; 系统监视器统计
        	d ##class(SYS.Metrics).GetGlobalStatistics("", 0, .pValues, .pStatus, .pMsg)
        	d ..ParseJson(.pValues, .array)
        	#; ECP 数据统计
        	d ##class(SYS.Metrics).GetECPStatistics("", 0, .pValues, .
        
        
        
        
            
        pStatus, .pMsg)
        	d ..ParseJson(.pValues, .array)
        	#; 磁盘和缓冲区数据统计
        	d ##class(SYS.Metrics).GetStatistics("",0,.pValues,.pStatus,.pMsg)
        	d ..ParseJson(.pValues, .array)
        	#; 许可数据统计
        	d ..GetLicenseStatistics(.array)
        	#; 开放性事务数据统计
        	d ..GetOpenTransactionStatistics(.array)
        	#; 数据库情况
        	d ..GetDatabaseStatistics(.array)
        	q array
        
        • 将数据解析成Prometheus数据格式。

        prometheus将所有数据保存为timeseries data,用metric name和label区分,label是在metric name上的更细维度的划分,其中的每一个实例是由一个float64和timestamp组成,只不过timestamp是隐式加上去的,#HELP代表指标的注释信息,#TYPE用于定义样本的类型注释信息。如下示例:

        # HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
        # TYPE go_gc_duration_seconds summary
        go_gc_duration_seconds{quantile="0"} 0
        
        • metrics name - 为go_gc_duration_seconds
        • label - 为quantile="0"
        • float64 - 为0
        ClassMethod Metrics2Prometheus() As %Status
            s %response.ContentType = "text/plain;version=0.0.4;charset=utf-8"
            s array = ..GetMetrics()
            s iter = array.%GetIterator()
            while iter.%GetNext(.key, .json) { 
        		s str =  json.key
        		if (json.%IsDefined("tag")) {
        			s tag = json.tag
        			s tagIter = tag.%GetIterator()
        			s str = str _ "{" 
        			while tagIter.%GetNext(.tagKey, .tagVal) { 
        				s str = str _ tagKey _ "=" _ """" _ tagVal _ """"  _ ","
        			s str = $e(str, 1, * - 1) _ "}" 
        		w str _" "_ json.val  _ $c(10)
            q $$$OK
        
        XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
        <Routes>
        	<Route Url="/prometheus" Method="GET" Call="Metrics2Prometheus" />
        	<Route Url="/json" Method="GET" Call="Metrics2Json" />
        </Routes>
        
        1. 在界面输入自定义配置的Prometheus接口地址。
        • prometheus格式地址接口:http://localhost:57772/api/metrics/prometheus
        • Json格式地址接口:http://localhost:57772/api/metrics/json
        1. 在prometheus.yml配置文件中添加自定义的接口。代码如下:
          - job_name: "localhost-Cache"
            metrics_path:  /api/metrics/prometheus
            static_configs:
            - targets: ['localhost:57772']
        
        1. 重新启动prometheus,查看配置界面。这样我们就可以给Caché配置一个自定义的接口拉。

        配置 Exporter 监控服务器系统资源

        • 通过服务器配置Exporter监控服务器的系统信息,例如内存使用情况,CPU使用情况。

        为Prometheus提供监控数据源的应用都可以被成为Exporter,比如Node Exporter则用来提供节点相关的资源使用状况,而Prometheus从这些不同的Exporter中获取监控数据,然后可以在诸如Grafana这样的可视化工具中进行结果的显示。

        广义上讲所有可以向Prometheus提供监控样本数据的程序都可以被称为一个Exporter。而Exporter的一个实例称为target,如下所示,Prometheus通过轮询的方式定期从这些target中获取样本数据。

        1. 下载windows_exporter-0.21.0-amd64.msi文件后,直接双击运行;
        • 下载地址:https://github.com/prometheus-community/windows_exporter/releases
        1. windows_exporter默认端口号为9182,运行后浏览器访问地址, 出现以下信息,说明安装成功。
        • 地址:http://localhost:9182/metrics
        1. 将Exporter接口添加到Prometheus中。
          - job_name: "localhost-Exporter"
            metrics_path:  /metrics
            static_configs:
            - targets: ['localhost:9182']
        

        使用 Alertmanager报警

        Alertmanager是一个独立的告警模块,接收Prometheus等客户端发来的警报,之后通过分组、删除重复等处理,并将它们通过路由发送给正确的接收器。

        Prometheus 的报警分为两部分:

        • Prometheus 服务器中的警报规则向警报管理器(Alertmanager)发送警报。
        • 警报管理器负责管理这些警报,包括告警信息进行去重,降噪,分组等,并通过丰富的告警通知渠道,如电子邮件、微信、钉钉、Slack等常用沟通工具发出通知。
        1. 下载Prometheus,选择操作系统,下载对应安装包,下载完毕后并挤压,以windows为例。
        • 下载地址:https://github.com/prometheus/alertmanager/releases
        1. 双击alertmanager.exe,启动alertmanager服务,浏览器访问端口地址可以看到默认提供的 UI 页面。
        • 端口 - 9093
        • 地址 - http://localhost:9093/#/alerts
        1. AlertManager 默认配置文件为 alertmanager.yml,打开配置文件,配置使用 Email 方式通知报警信息,这里以 QQ 邮箱为例,配置信息如下:
        • global - 全局配置,包括报警解决后的超时时间、SMTP 相关配置、各种渠道通知的 API 地址等等。
        • route - 用来设置报警的分发策略,它是一个树状结构,按照深度优先从左向右的顺序进行匹配。
        • receivers - 配置告警消息接受者信息,例如常用的 email、wechat、slack、webhook 等消息通知方式。
        • inhibit_rules - 抑制规则配置,当存在与另一组匹配的警报时,抑制规则将禁用与一组匹配的警报(目标)。
        global:
          resolve_timeout: 5m
          smtp_from: 'xxxx@qq.com'
          smtp_smarthost: 'smtp.qq.com:465'
          smtp_auth_username: 'xxxx@qq.com'
          smtp_auth_password: 'xxxxxxxxxxxxxx'
          smtp_require_tls: false
          smtp_hello: 'qq.com'
        route:
          group_by: ['alertname']
          group_wait: 5s
          group_interval: 5s
          repeat_interval: 5m
          receiver: 'email'
        receivers:
        - name: 'email'
          email_configs:
          - to: 'xxxxx@mediway.cn'
            send_resolved: true
        inhibit_rules:
          - source_match:
              severity: 'critical'
            target_match:
              severity: 'warning'
            equal: ['alertname', 'dev', 'instance']
        
        1. 接下来,需要在 Prometheus 配置 AlertManager 服务地址以及告警规则,新建报警规则文件 alert_rules.yml,,放在prometheus.yml同级路径下,配置如下:
        • name - 规则名称,可自己定义。
        • alert - 报警名称,当触发报警时,会作为邮件标题显示。
        • expr - 报警规则,为 PromQL 表达式验证特定节点,如上述配置中up{job="250-IRIS"}为验证job="250-IRIS"是否还活着,如果等于0则启动报警。
        • for - 表示报警状态为 Pending 后等待 15s 变成 Firing 状态,一旦变成 Firing 状态则将报警发送到 AlertManager。
        • summary - 报警信息描述。
        groups:
            - name: "服务器报警"
              rules:
              - alert: yx服务器报警
                expr: up{job="250-IRIS"} == 0
                for: 15s
                labels:
                  status: warning
                annotations:
                  summary: "服务器{{ $labels.instance }} 挂了"
                  description: "姚鑫服务器挂了.请立即查看!"
              - alert: 本地Cache报警
                expr: up{job="localhost-Cache"}
        
        
        
        
            
         == 0
                for: 15s
                labels:
                  status: warning
                annotations:
                  summary: "服务器{{ $labels.instance }} 挂了"
                  description: "本地Cache服务器挂了.请立即查看!"
              - alert: 本地IRIS报警
                expr: up{job="localhost-IRIS"} == 0
                for: 15s
                labels:
                  status: warning
                annotations:
                  summary: "服务器{{ $labels.instance }} 挂了"
                  description: "本地IRIS服务器挂了.请立即查看!"
            - name: test-rules
              rules:
              - alert: "内存报警"
                expr: 100 - ((node_memory_MemAvailable_bytes * 100) / node_memory_MemTotal_bytes) > 3
                for: 15s
                labels:
                  status: warning
                annotations:
                  summary: "服务器:{{$labels.instance}}内存使用率超过3%了"
                  description: "内存使用率: {{ $value }}"
                  value: "{{ $value }}"
        
        1. 配置好报警规则文件后,需要修改 prometheus.yml 配置文件,添加 rules 规则文件:
        alerting:
          alertmanagers:
            - static_configs:
                - targets:
                    - 'localhost:9093'
                 # - alertmanager:9093
        # Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
        rule_files:
          - "alert_rules.yml"
          # - "second_rules.yml"
        
        1. 配置完毕后打,浏览器访问prometheus主页,进入Alerts和Rules界面,可查看报警规则信息:
        • 地址:http://localhost:9090/alerts?search=
        1. 测试报警功能,将本地Caché关闭,停库。
        1. 观察页面本地Cache警报状态。

        Prometheus Alert 告警状态有三种:Inactive、Pending、Firing。

        • Inactive - 非活动状态,表示正在监控,但是还未有任何警报触发。
        • Pending - 表示这个警报将被触发。由于警报可以被分组、压抑/抑制或静默/静音,所以等待验证,一旦所有的验证都通过,则将转到 Firing 状态。
        • Firing - 将警报发送到AlertManager,将按照配置将警报的发送给所有接收者。一旦警报解除,则将状态转到 Inactive,如此循环。

        首先发现警报变为Pending状态。

        过了15秒后变为Firing状态

        1. 触发报警,根据定义的报警规则,如果有触发告警的条件,自动向配置的接收邮箱中发送邮件,如下:

        基于M实现监控服务器,并用邮件报警

        解析Prometheus数据接口信息

        • 获取接口信息
        ClassMethod GetMetrics(url) As %Status
        	#; 初始化request对象
        	#dim request as %Net.HttpRequest= ##class(%Net.HttpRequest).%New()
        	#; 根据地址解析是否是https调用SSL配置
        	d ##class(%Net.URLParser).Parse(url, .components)
        	s scheme = components("scheme")
        	if (scheme = "https") {
        		s request.Https = 1
        		if ($zv [ "IRIS") {
        			s request.SSLConfiguration = "ISC.FeatureTracker.SSL.Config"
        		} else {
        			s request.SSLConfiguration = "WebTerminalSSL"
        		s request.SSLCheckServerIdentity = 0  
        	#; 请求地址并返回流数据
        	s sc = request.Get(url)
        	$$$ThrowOnError(sc)
        	s response = request.HttpResponse
        	s stream = response.Data
        	q stream
        
        • 将接口信息转为Json格式
        ClassMethod Metrics2Json(stream) As %Status
        	s array = []
        	while (stream.AtEnd = 0) {
        		#; 读取每行信息
        		s metrics = stream.ReadLine()
        		#; 过滤注释描述信息
        		continue:(metrics [ "# HELP")
        		continue:(metrics [ "# TYPE")
        		#; 指标字符串
        		s str = $p(metrics, " " ,1)
        		#; 指标值
        		s value = $p(metrics, " " ,2)
        		#; 指标字名称
        		s metricsName = $p(str, "{", 1)
        		#; 指标字label信息
        		s label = $e($p(str, "{", 2), 1, * - 1)
        		s obj = {}
        		s obj.key = metricsName
        		s obj.val = value
        		#; 如果label不为空将label信息转为JSON
        		if (label '= "") {
        			s tag = {}
        			s len = $l(label, ",")
        			for i = 1 : 1 : len{
        				s item = $p(label, """," ,i)
        				s key = $p(item, "=", 1) 
        				s val = $e($p(item, "=", 2), 2, *-1)
        				d tag.%Set(key, val)
        			s obj.tag = tag
        		d array.%Push(obj)
        	q array
        
        • 调用方法。
        /// w ##class(M.ParseMetrics).Main("https://localhost:2443/api/monitor/metrics").%ToJSON()
        /// w ##class(M.ParseMetrics).Main("http://localhost:9182/metrics").%ToJSON()
        /// w ##class(M.ParseMetrics).Main("http://localhost:57772/api/metrics/prometheus").%ToJSON()
        ClassMethod Main(url) As %Status
        	#; 获取指标接口信息
        	s stream = ..GetMetrics(url)
        	#; 将接口信息转为JSON格式
        	s json = ..Metrics2Json(stream)
        	q json
        
        • 调用自定义Caché接口
        IMP>w ##class(M.ParseMetrics).Main("http://localhost:57772/api/metrics/prometheus").%ToJSON()   
        [{"key":"yx_application_errors","val":"0"},{"key"
        
        
        
        
            
        :"yx_csp_sessions","val":"1"},{"key":"yx_cache_efficiency","val":"235.85"},{"key":"yx_disk_reads","val":"3316"},{"key":"yx_disk_writes","val":"1881"},{"key":"yx_ecp_app_srv_rate","val":"0"},{"key":"yx_ecp_data_srv_rate","val":"0"},{"key":"yx_glo_refs","val":"1225714"},{"key":"yx_glo_refs_per_sec","val":"439.00"},{"key":"yx_glo_sets","val":"108449"},{"key":"yx_journal_entries","val":"17178"},
        {"key":"yx_database_free","val":".8988","tag":{"id":"DHC-EPRMETADATA"}},{"key":"yx_database_free","val":".45","tag":{"id":"DHC-EPRQUALITYDATA"}},{"key":"yx_database_free","val":".71","tag":{"id":"DHC-EPRRBACINST"}},{"key":"yx_database_free","val":".74","tag":{"id":"DHC-EPRRBACMETA"}},{"key":"yx_database_free","val":".78","tag":{"id":"DHC-HEIS"}},{"key":"yx_database_free","val":".48","tag":{"id":"DHC-HL7"}},{"key":"yx_database_free","val":".9936","tag":{"id":"DHC-HR"}},{"key":"yx_database_free","val":".0345","tag":{"id":"DHC-LISDATA"}},{"key":"yx_database_free","val":".9328","tag":{"id":"DHC-LISSRC"}},{"key":"yx_database_free","val":".9884","tag":{"id":"DHC-LOGS"}},{"key":"yx_database_free","val":".9098","tag":{"id":"DHC-MEDSRC"}},{"key":"yx_database_free","val":".8996","tag":{"id":"DHC-MRQDATA"}},{"key":"yx_database_free","val":".9871","tag":{"id":"DHC-MRQSRC"}},{"key":"yx_database_free","val":".1","tag":{"id":"DHC-MSG"}},{"key":"yx_database_free","val":".0481","tag":{"id":"DHC-ORDDATA"}},{"key":"yx_database_free","val":".0417","tag":{"id":"DHC-ORDINDEX"}},{"key":"yx_database_free","val":".8782","tag":{"id":"PACS"}},{"key":"yx_database_free","val":".6","tag":{"id":"DHC-PISDATA"}},{"key":"yx_database_free","val":".831","tag":{"id":"DHC-PISSRC"}},{"key":"yx_database_free","val":".9548","tag":{"id":"DHC-RIS"}},{"key":"yx_database_free","val":".9615","tag":{"id":"DHC-SYS"}},{"key":"yx_database_free","val":".9218","tag":{"id":"DHC-TEMP"}},{"key":"yx_database_free","val":".8096","tag":{"id":"DHC-DWR"}},{"key":"yx_database_free","val":".039","tag":
        
        
        
        
            
        {"id":"DHC-WORKLOAD"}},{"key":"yx_database_free","val":".1797","tag":{"id":"IMP"}}]     
        
        • 调用自定义IRIS接口
        IMP>w ##class(M.ParseMetrics).Main("https://localhost:2443/api/monitor/metrics").%ToJSON()    
        [{"key":"iris_cpu_pct","val":"0","tag":{"id":"CSPSRV"}},{"key":"iris_cpu_pct","val":"0","tag":{"id":"ECPWorker"}},{"key":"iris_cpu_pct","val":"0","tag":{"id":"GARCOL"}},{"key":"iris_cpu_pct","val":"0","tag":{"id":"JRNDMN"}},
        {"key":"iris_wqm_max_work_queue_depth","val":"0","tag":{"id":"SYS"}},{"key":"iris_wqm_waiting_worker_jobs","val":"1","tag":{"id":"SYS"}}]    
        
        • 调用自定义Exporter接口
        IMP>w ##class(M.ParseMetrics).Main("http://localhost:9182/metrics").%ToJSON()
        [{"key":"go_gc_duration_seconds","val":"0","tag":{"quantile":"0"}},{"key":"go_gc_duration_seconds","val":"0","tag":{"quantile":"0.25"}},{"key":"go_gc_duration_seconds","val":"0","tag":{"quantile":"0.5"}},{"key":"go_gc_duration_seconds","val":"0","tag":{"quantile":"0.75"}},{"key":"go_gc_duration_seconds","val":"0.0023476","tag":{"quantile":"1"}},{"key":"go_gc_duration_seconds_sum","val":"0.0038789"},{"key":"go_gc_duration_seconds_count","val":"87"},{"key":"go_goroutines","val":"14"},{"key":"go_info","val":"1","tag":
        {"key":"go_threads","val":"19"},{"key":"process_cpu_seconds_total","val":"2.015625"},{"key":"process_max_fds","val":"1.6777216e+07"},{"key":"process_open_fds","val":"414"},{"key":"process_resident_memory_bytes","val":"3.5504128e+07"},{"key":"process_start_time_seconds","val":"1.67670656e+09"},{"key":"process_virtual_memory_bytes","val":"4.0259584e+07"},]
        

        使用嵌入式Python方式获取系统CPU、内存等

        python模块之psutil详解

        在讲嵌入式Python之前我们先了解一下psutil库

        psutil是一个开源切跨平台的库,其提供了便利的函数用来获取才做系统的信息,比如CPU,内存,磁盘,网络等。此外,psutil还可以用来进行进程管理,包括判断进程是否存在、获取进程列表、获取进程详细信息等。而且psutil还提供了许多命令行工具提供的功能,包括:ps,top,lsof,netstat,ifconfig, who,df,kill,free,nice,ionice,iostat,iotop,uptime,pidof,tty,taskset,pmap。

        psutil是一个跨平台的库,在官方网站上查到其支持如下操作系统。

        • Linux
        • Windows
        • OSX
        • FreeBSD
        • OpenBSD
        • NetBSD
        • Sun Solaris
        • AIX
        CPU相关
        函数描述
        psutil.cpu_count()cpu_count(,[logical]):默认返回逻辑CPU的个数,当设置logical的参数为False时,返回物理CPU的个数。
        psutil.cpu_percent()cpu_percent(,[percpu],[interval]):返回CPU的利用率,percpu为True时显示所有物理核心的利用率,interval不为0时,则阻塞时显示interval执行的时间内的平均利用率。
        psutil.cpu_times()cpu_times(,[percpu]):以命名元组(namedtuple)的形式返回cpu的时间花费,percpu=True表示获取每个CPU的时间花费。
        psutil.cpu_times_percent()cpu_times_percent(,[percpu]):功能和cpu_times大致相同,看字面意思就能知道,该函数返回的是耗时比例。
        psutil.cpu_stats()cpu_stats()以命名元组的形式返回CPU的统计信息,包括上下文切换,中断,软中断和系统调用次数。
        psutil.cpu_freq()cpu_freq([percpu]):返回cpu频率。
        Memory内存相关
        函数描述
        virtual_memory()以命名元组的形式返回内存使用情况,包括总内存,可用内存,内存利用率,buffer和cache等。单位为字节。
        swap_memory()以命名元组的形式返回swap/memory使用情况,包含swap中页的换入和换出。
        Disk相关
        函数描述
        psutil.disk_io_counters()disk_io_counters([perdisk]):以命名元组的形式返回磁盘io统计信息,包括读、写的次数,读、写的字节数等。 当perdisk的值为True,则分别列出单个磁盘的统计信息(字典:key为磁盘名称,value为统计的namedtuple)。
        psutil.disk_partitions()disk_partitions([all=False]):以命名元组的形式返回所有已挂载的磁盘,包含磁盘名称,挂载点,文件系统类型等信息。 当all等于True时,返回包含/proc等特殊文件系统的挂载信息。
        psutil.disk_usage()disk_usage(path):以命名元组的形式返回path所在磁盘的使用情况,包括磁盘的容量、已经使用的磁盘容量、磁盘的空间利用率等。
        Network相关
        函数详情
        psutil.net_io_counter([pernic])以命名元组的形式返回当前系统中每块网卡的网络io统计信息,包括收发字节数,收发包的数量、出错的情况和删包情况。当pernic为True时,则列出所有网卡的统计信息。
        psutil.net_connections([kind])以列表的形式返回每个网络连接的详细信息(namedtuple)。命名元组包含fd, family, type, laddr, raddr, status, pid等信息。kind表示过滤的连接类型,支持的值如下:(默认为inet)。
        psutil.net_if_addrs()以字典的形式返回网卡的配置信息,包括IP地址和mac地址、子网掩码和广播地址。
        psutil.net_if_stats()返回网卡的详细信息,包括是否启动、通信类型、传输速度与mtu。
        psutil.users()以命名元组的方式返回当前登陆用户的信息,包括用户名,登陆时间,终端,与主机信息。
        psutil.boot_time()以时间戳的形式返回系统的启动时间。
        Process相关
        函数详情
        psutil.pids()以列表的形式返回当前正在运行的进程。
        psutil.pid_exists(1)判断给点定的pid是否存在。
        psutil.process_iter()迭代当前正在运行的进程,返回的是每个进程的Process对象。
        psutil.Process()对进程进行封装,可以使用该类的方法获取进行的详细信息,或者给进程发送信号。
        通过嵌入式Python调用psutil库

        这里仅简单介绍个主要方法、其他获取系统资源方法由读者自行实现。

        • 在安装路径C:\InterSystems\IRISHealth\bin,输入cmd,进入命令行控制台输入命令。安装 psutil库。
        irispip install --target C:\InterSystems\IRISHealth\mgr\python psutil
        
        • 获取服务器CPU使用率
        ClassMethod GetSystemCpu() As %String [ Language = python ]
        	from psutil.__init__ import cpu_percent,virtual_memory
        	return cpu_percent(interval=2)
        
        USER> w ##class(M.SystemMetrics).GetSystemCpu()
        14.59999999999999964
        

        根据上图可以观察到获取的内容使用 1 - 是 IRIS监控接口、2 - 是M方法实现、 3 - 是任务管理器,三者监控的CPU使用率基本使用是一致的。(因为CPU使用率是瞬态的,所以可以认为是准确的)

        • 获取服务系内存使用状态
        ClassMethod GetSystemMemory() As %String [ Language = python ]
        	from psutil.__init__ import cpu_percent,virtual_memory
        	return virtual_memory()[2]
        
        USER>w ##class(M.SystemMetrics).GetSystemMemory()
        

        根据上图可以观察到获取的内容使用 1 - 是 360监控、2 - 是任务管理器、 3 - 是M方法实现,三者监控的内存使用是一致的。

        使用邮件发送报警信息

        这里考虑使用邮件来发送警报信息是因为:

        • 邮件相对其他方式来说比较方便,只管发送,不用管是否接收。
        • IRIS自带发送邮件接口,操作性大。
        • 相比其他方式,例如微信,公众号等,还需要做接口交互。使用邮件相对简单。

        那么下一个考虑的问题是通过什么方式来触发监控发邮件呢,笔者考虑以下两点可以触发:

        • 通过挂任务的方式定时轮询。
        • 通过SessionEvent事件来触发。

        这里仅提供代码示例,具体使用哪种方式由读者自行决定。

        使用M发送邮件发送消息
        • 这里以QQ邮箱例,配置信息与Alertmanager邮箱配置相同
        ClassMethod SetMailConfig() As %Net.SMTP
        	#; 配置smtp服务
        	s server = ##class(%Net.SMTP).%New()
        	s server.smtpserver = "smtp.qq.com"
        	s server.port = 465
        	if ($zv [ "IRIS") {
        		s server.SSLConfiguration = "ISC.FeatureTracker.SSL.Config"
        	} else {
        		s server.SSLConfiguration = "WebTerminalSSL"
        	#; 配置邮箱
        	s auth = ##class(%Net.Authenticator).%New()
        	s auth.UserName = "454115408@qq.com"
        	s auth.Password = "xxxxxxxxxxxxxxxx"
        	s server.authenticator = auth
        	s server.AuthFrom = auth.UserName
        	q server
        
        • 发送邮件具体方法
        ClassMethod SendMailMessage(title, content) As %List
        	#; 获取配置
        	s server  = ..SetMailConfig()
        	#; 初始化邮件对象
        	s msg = ##class(%Net.MailMessage).%New()
        	#; 添加from - 发送人,to - 接收人,Cc - 抄送人
        	s from = server.authenticator.UserName
        	s msg.From = from
        	d msg.To.Insert("yaoxin@mediway.cn")
        	d msg.Cc.Insert("965274651@qq.com")
        	#; 填写邮件具体内容
        	s msg.Subject = title
        	s msg.IsBinary = 0
        	s msg.IsHTML = 0
        	d msg.TextData.Write(content)
        	#; 执行发送
        	s sc = server.Send(msg)
        	$$$ThrowOnError(sc)
        	q server.FailedSend
        
        • 测试邮件方法,发送成功目标邮箱会接收到邮件。
        IMP>w ##class(M.Mail).SendMailMessage("yx发的邮件消息头","这是yx发的消息内容content")                                                                           10@%Collection.ListOfDT
        
        通过配置文件csv文件,来获取维护指标,进行邮件报警。
        • 使用csv文件通过手动的方式来维护需要监控的指标
          • key - 指标名称,这里要与IRIS接口信息的具体指标保持一致。
          • val - 报警的阈值。
          • oper - 操作符。指具体报警时操作符。是大于val时报警,还是小于val时报警,或其他。
          • desc - 指标描述信息。
        • 读取csv文件将数据转为Json。
        ClassMethod Csv2Json(filename)
        	q:('##class(%File).Exists(filename)) $$$NO
        	s stream = ##class(%Stream.FileCharacter).%New()
        	s stream.Filename = filename
        	s array = []
        	s keyStr = ""
        	while 'stream.AtEnd {
        		s str = stream.ReadLine()
        		if ($i(count) = 1) {
        			s keyStr = str
        		s obj = {}	
        		s len = $l(str, ",")
        		for i = 1
        
        
        
        
            
         : 1 : len {
        			s val = $p(str, ",", i)
        			s key = $p(keyStr, ",", i)
        			d obj.%Set(key, val)
        		d array.%Push(obj)
        	q array
        
        IMP>w ##class(M.Mail).LoadFile("E:\temp\metrics.csv").%ToJSON()
        [{"key":"iris_cpu_usage ","val":"10","oper":">"},{"key":"iris_license_available","val":"290","oper":">"},{"key":"iris_trans_open_count","val":"0","oper":">"},{"key":"memory","val":"40","oper":">"}]
        
        • 对比维护指标与接口指标,超过阈值发送邮件进行警报。

        注:这里双循环,时间复杂O2,数据量大,效率可能会比较低,需要注意下。

        ClassMethod Main(url As %String, filename As %String) As %Status
        	#; 获取接口指标Json
        	s irismetrics =  ##class(M.ParseMetrics).Main(url)
        	#; 获取Csv维护指标Json
        	s config = ##class(M.Mail).Csv2Json(filename)
        	#; 双向对比,维护指标超过阈值发送邮件警报
        	for i = 1 : 1 : irismetrics.%Size() - 1{
        		s metrics = irismetrics.%Get(i)
        		for j = 1 : 1 : config.%Size() - 1{
        			s obj = config.%Get(j)
        			if (obj.key = metrics.key) {
        				if @(metrics.val _ obj.oper _ obj.val) {
        					s content = obj.desc _ "警报,超过阈值:" _ obj.val
        					d ..SendMailMessage("来自系统的警报",content)
        					ret $$$NO
        	#; 监控内存使用率,接口中没有监视内存选项所以调用嵌入式接口
        	s memory = ..GetSystemMemory()
        	if (memory > 30) {
        		d ..SendMailMessage("来自系统的警报","内存使用率已经大于" _ 30 _ "")
        	ret $$$YES
        
        USER>w ##class(M.Mail).Main("https://localhost:2443/api/monitor/metrics", "E:\temp\metrics.csv")
        

        注:这里基本思路已经实现,可以通过挂任务或其他方式来定时轮询。

        以上是个人关于监控服务器指标、CPU、内存、警报的一些理解,由于个人能力有限,欢迎大家提出意见,共同交流。

        IRIS还提供了alert警报接口,该接口提供alert.log警报日志内容,基于以上方案,思考如何通过M程序进行监控

        • 接口地址:https://localhost:2443/api/monitor/alerts
        • 该接口有警报时会提示报警信息,调用一次后清空。
        • 如果有警报,警报信息如下:
        {"time":"02/19/23-15:49:22:650","severity":2,"message":"Previous system shutdown was abnormal, system forced down or crashed."}
        
        • /api/monitor/metrics指标含义列表:
        指标描述
        iris_cpu_pct {id="ProcessType"}IRIS 进程类型的 CPU 使用百分比。 ProcessType 可以是以下任何一项:ECPWorker、ECPCliR、ECPCliW、ECPSrvR、ECPSrvW、LICENSESRV、WDAUX、WRTDMN、JRNDMN、GARCOL、CSPDMN、CSPSRV、ODBCSRC、MirrorMaster、MirrorPri、MirrorBack、MirrorPre、MirrorSvrR、MirrorJrnR、MirrorSK、MirrorComm
        iris_cpu_usage操作系统上所有程序的 CPU 使用率百分比
        iris_csp_activity {id="IPaddress:port"}Web 网关服务器自启动以来处理的 Web 请求数
        iris_csp_actual_connections {id="IPAddress:port"}Web 网关服务器与该服务器的当前连接数
        iris_csp_gateway_latency {id="IPaddress:port"}获取 iris_csp_ 指标时从 Web 网关服务器获得响应的时间,以毫秒为单位
        iris_csp_in_use_connections {id="IPaddress:port"}正在处理 Web 请求的 Web 网关服务器与此服务器的当前连接数
        iris_csp_private_connections {id="IPaddress:port"}为状态感知应用程序保留的 Web 网关服务器与此服务器的当前连接数(保留模式 1)
        iris_csp_sessions此服务器上当前活动的 Web 会话 ID 数
        iris_cache_efficiency全局引用与物理读写的比率,以百分比表示
        iris_db_expansion_size_mb {id="database"}扩展数据库的数量,以兆字节为单位
        iris_db_free_space {id="database"}数据库中可用的可用空间,以兆字节为单位(此指标每天仅更新一次,可能不会反映最近的更改。)
        iris_db_latency {id="database"}完成从数据库随机读取的时间量,以毫秒为单位
        iris_db_max_size_mb {id="database"}`数据库可以增长到的最大大小,以兆字节为单位
        iris_db_size_mb {id="database",dir="path"}数据库大小,以兆字节为单位
        iris_directory_space {id="database",dir="path"}数据库目录存储卷上的可用空间,以兆字节为单位
        iris_disk_percent_full {id="database",dir="path"}数据库目录存储卷上的空间百分比
        iris_ecp_conn此 ECP 应用程序服务器上的活动客户端连接总数
        iris_ecp_conn_max来自此 ECP 应用程序服务器的最大活动客户端连接数
        iris_ecp_connections此 ECP 应用程序服务器与其配置的 ECP 数据服务器同步时同步的服务器数
        iris_ecp_latencyECP 应用服务器和 ECP 数据服务器之间的延迟,以毫秒为单位
        iris_ecps_conn每秒与此 ECP 数据服务器的活动客户端连接总数
        iris_ecps_conn_max与此 ECP 数据服务器的最大活动客户端连接数
        iris_glo_a_seize_per_sec每秒全局资源上的 Aseizes 数
        iris_glo_n_seize_per_sec每秒全局资源上的 Nseizes 数
        iris_glo_ref_per_sec每秒对位于本地数据库上的全局变量的引用数
        iris_glo_ref_rem_per_sec每秒对位于远程数据库上的全局变量的引用数
        iris_glo_seize_per_sec每秒占用全局资源的次数
        iris_glo_update_per_sec每秒对本地数据库上的全局变量进行更新(SET 和 KILL 命令)的次数
        iris_glo_update_rem_per_sec每秒对位于远程数据库上的全局变量的更新(SET 和 KILL 命令)数
        iris_jrn_block_per_sec每秒写入磁盘的日志块
        iris_jrn_free_space {id="JournalType",dir="path"}每个日志目录的存储卷上可用的可用空间,以兆字节为单位。 JournalType 可以是 WIJ、primary 或 secondary
        iris_jrn_size {id="JournalType"}每个日志文件的当前大小,以兆字节为单位。 JournalType 可以是 WIJ、primary 或 secondary
        iris_license_available当前未使用的许可证数量
        iris_license_consumed当前使用的许可证数量
        iris_license_percent_used当前使用的许可证的百分比
        iris_log_reads_per_sec每秒逻辑读取
        iris_obj_a_seize_per_sec每秒对象资源上的 Aseizes 数
        iris_obj_del_per_sec每秒删除的对象数
        iris_obj_hit_per_sec进程内存中每秒的对象引用数
        iris_obj_load_per_sec每秒从磁盘加载的对象数,不在共享内存中
        iris_obj_miss_per_sec每秒在内存中找不到的对象引用数
        iris_obj_new_per_sec每秒初始化的对象数
        iris_obj_seize_per_sec每秒占用对象资源的次数
        iris_page_space_percent_used已用最大分配页面文件空间的百分比
        iris_phys_mem_percent_used当前使用的物理内存 (RAM) 的百分比
        iris_phys_reads_per_sec每秒从磁盘读取的物理数据库块
        iris_phys_writes_per_sec每秒写入磁盘的物理数据库块
        iris_process_count活跃的 IRIS 进程总数
        iris_rtn_a_seize_per_sec每秒例程资源上的 Aseizes 数
        iris_rtn_call_local_per_sec每秒对位于远程数据库上的全局变量的本地例程调用数
        iris_rtn_call_miss_per_sec每秒在内存中找不到的例程调用数
        iris_rtn_call_remote_per_sec每秒远程例程调用次数
        iris_rtn_load_per_sec每秒从本地加载或保存到磁盘的例程数
        iris_rtn_load_rem_per_sec每秒从磁盘远程加载或保存到磁盘的例程数
        iris_rtn_seize_per_sec每秒占用例程资源的次数
        iris_sam_get_db_sensors_seconds收集 iris_db* 传感器所花费的时间,以秒为单位
        iris_sam_get_jrn_sensors_seconds收集 iris_jrn* 传感器所花费的时间,以秒为单位
        iris_sam_get_sql_sensors_seconds收集 iris_sql* 传感器所花费的时间,以秒为单位
        iris_sam_get_wqm_sensors_seconds收集 iris_wqm* 传感器所花费的时间,以秒为单位
        iris_smh_available {id="purpose"}按目的可用的共享内存,以千字节为单位
        iris_smh_percent_full {id="purpose"}按目的使用的已分配共享内存的百分比
        iris_smh_total为当前实例分配的共享内存,以千字节为单位
        iris_smh_total_percent_full当前实例使用的已分配共享内存的百分比
        iris_smh_used {id="purpose"}按目的使用的共享内存,以千字节为单位
        iris_sql_active_queries {id="namespace"}当前执行的 SQL语句数
        iris_sql_active_queries_95_percentile {id="namespace"}对于当前的活动 SQL 语句集,自语句开始执行以来经过的第 95 个百分位数的时间
        iris_sql_active_queries_99_percentile {id="namespace"}对于当前活动的 SQL 语句集,自语句开始执行以来经过的第 99 个百分位数的时间
        iris_sql_queries_avg_runtime {id="namespace"}平均 SQL 语句运行时间,以秒为单位
        iris_sql_queries_avg_runtime_std_dev {id="namespace"}平均 SQL 语句运行时间的标准偏差
        iris_sql_queries_per_second {id="namespace"}每秒平均 SQL 语句数
        iris_system_alerts自系统启动以来发布到消息日志的警报数
        iris_system_alerts_log当前位于警报日志中的警报数
        iris_system_alerts_new/api/monitor/alerts 端点上是否有新警报,作为布尔值
        iris_system_state表示系统监视器健康状态的数字
        iris_trans_open_count当前实例上打开的事务数
        iris_trans_open_secs当前实例上打开事务的平均持续时间,以秒为单位
        iris_trans_open_secs_max当前实例上当前打开的最长事务的
        iris_wd_buffer_redirty写入守护进程在最近一个周期中写入并且也在前一个周期中写入的数据库缓冲区数
        iris_wd_buffer_write写入守护进程在其最近周期写入的数据库缓冲区数
        iris_wd_cycle_time完成最近的写入守护进程周期所花费的时间量,以毫秒为单位
        iris_wd_proc_in_global在最近的写入守护进程周期开始时主动持有全局缓冲区的进程数
        iris_wd_size_write写入守护程序在其最近周期写入的数据库缓冲区的大小,以千字节为单位
        iris_wd_sleep写入守护进程在其最近的周期开始之前处于非活动状态的时间量,以毫秒为单位
        iris_wd_temp_queue写入守护进程在其最近周期开始时使用的内存缓冲区数
        iris_wd_temp_write写入守护进程在其最近周期中写入的内存缓冲区数
        iris_wdwij_time写入守护进程在其最近的周期内写入 WIJ 文件所花费的时间,以毫秒为单位
        iris_wd_write_time写守护进程在其最近的周期内将缓冲区写入数据库所花费的时间,以毫秒为单位
        iris_wij_writes_per_secWIJ 每秒物理块写入
        iris_wqm_active_worker_jobs {id="category"}未被阻塞的运行逻辑的平均工作者作业数
        iris_wqm_commands_per_sec {id="category"}平均每秒在此工作队列管理类别中执行的命令数
        iris_wqm_globals_per_sec {id="category"}平均每秒在此工作队列管理类别中运行的全局引用数
        iris_wqm_max_active_worker_jobs {id="category"}自上次记录日志条目以来的最大活动工作人员数
        iris_wqm_max_work_queue_depth {id="category"}自上次记录以来此工作队列管理类别队列中的最大条目数
        iris_wqm_waiting_worker_jobs {id="category"}等待一个组连接并为其工作的空闲工人作业的平均数量
        Prometheus是一个最初在SoundCloud上构建的开源系统监视和警报工具包。自2012年成立以来,许多公司和组织都采用了Prometheus,该项目拥有一个非常活跃的开发人员和用户社区。它现在是一个独立的开源项目,可以独立于任何公司进行维护。为了强调这一点,并澄清项目的治理结构,Prometheus于2016年加入 云计算本地计算基金会,作为继Kubernetes之后的第二个托管项目。Grafana是一个跨平台的开源的度量分析和可视化工具,可以通过将采集的数据查询然后可视化的展示,并及时通知。
 
推荐文章
谦虚好学的脸盆  ·  2021-06-28 解决iconfont在IE下不兼容问题_阿里 iconfont 浏览器兼容问题-CSDN博客
11 月前
好帅的匕首  ·  五日本女星性感亮相台湾衣着清凉(图)|AV女优|佐藤遥希|JULIA_新浪娱乐_新浪网
1 年前
买醉的香蕉  ·  Java初始化顺序的验证(Cannot reference XXX before supertype constructor has been called引发的思考)_Coder君的博客-CSDN博客
1 年前
冲动的西瓜  ·  python在服务器上运行慢_PyPI很慢。如何运行自己的服务器?_weixin_40000131的博客-CSDN博客
1 年前
聪明伶俐的沙发  ·  bootstrap5 - 夜雨初凉 - 博客园
1 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号