add metric info

This commit is contained in:
houseme
2025-05-14 19:00:15 +08:00
parent cdd285dec8
commit 9e9f721c08
15 changed files with 720 additions and 147 deletions
+30
View File
@@ -0,0 +1,30 @@
use crate::metrics::{new_counter_md, new_gauge_md, subsystems, MetricDescriptor, MetricName};
const TARGET_ID: &str = "target_id";
/// audit related metric descriptors
lazy_static::lazy_static! {
pub static ref AUDIT_FAILED_MESSAGES_MD: MetricDescriptor =
new_counter_md(
MetricName::AuditFailedMessages,
"Total number of messages that failed to send since start",
&[TARGET_ID],
subsystems::AUDIT
);
pub static ref AUDIT_TARGET_QUEUE_LENGTH_MD: MetricDescriptor =
new_gauge_md(
MetricName::AuditTargetQueueLength,
"Number of unsent messages in queue for target",
&[TARGET_ID],
subsystems::AUDIT
);
pub static ref AUDIT_TOTAL_MESSAGES_MD: MetricDescriptor =
new_counter_md(
MetricName::AuditTotalMessages,
"Total number of messages sent since start",
&[TARGET_ID],
subsystems::AUDIT
);
}
+68
View File
@@ -0,0 +1,68 @@
use crate::metrics::{new_counter_md, new_gauge_md, new_histogram_md, subsystems, MetricDescriptor, MetricName};
/// Bucket 级别 S3 指标描述符
lazy_static::lazy_static! {
pub static ref BUCKET_API_TRAFFIC_SENT_BYTES_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiTrafficSentBytes,
"Total number of bytes received for a bucket",
&["bucket", "type"],
subsystems::BUCKET_API
);
pub static ref BUCKET_API_TRAFFIC_RECV_BYTES_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiTrafficRecvBytes,
"Total number of bytes sent for a bucket",
&["bucket", "type"],
subsystems::BUCKET_API
);
pub static ref BUCKET_API_REQUESTS_IN_FLIGHT_MD: MetricDescriptor =
new_gauge_md(
MetricName::ApiRequestsInFlightTotal,
"Total number of requests currently in flight for a bucket",
&["bucket", "name", "type"],
subsystems::BUCKET_API
);
pub static ref BUCKET_API_REQUESTS_TOTAL_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiRequestsTotal,
"Total number of requests for a bucket",
&["bucket", "name", "type"],
subsystems::BUCKET_API
);
pub static ref BUCKET_API_REQUESTS_CANCELED_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiRequestsCanceledTotal,
"Total number of requests canceled by the client for a bucket",
&["bucket", "name", "type"],
subsystems::BUCKET_API
);
pub static ref BUCKET_API_REQUESTS_4XX_ERRORS_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiRequests4xxErrorsTotal,
"Total number of requests with 4xx errors for a bucket",
&["bucket", "name", "type"],
subsystems::BUCKET_API
);
pub static ref BUCKET_API_REQUESTS_5XX_ERRORS_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiRequests5xxErrorsTotal,
"Total number of requests with 5xx errors for a bucket",
&["bucket", "name", "type"],
subsystems::BUCKET_API
);
pub static ref BUCKET_API_REQUESTS_TTFB_SECONDS_DISTRIBUTION_MD: MetricDescriptor =
new_histogram_md(
MetricName::ApiRequestsTTFBSecondsDistribution,
"Distribution of time to first byte across API calls for a bucket",
&["bucket", "name", "le", "type"],
subsystems::BUCKET_API
);
}
@@ -0,0 +1,165 @@
use crate::metrics::{new_counter_md, new_gauge_md, subsystems, MetricDescriptor, MetricName};
// Label constants
pub const BUCKET_L: &str = "bucket";
pub const OPERATION_L: &str = "operation";
pub const TARGET_ARN_L: &str = "targetArn";
pub const RANGE_L: &str = "range";
/// Bucket copy metric descriptor
lazy_static::lazy_static! {
pub static ref BUCKET_REPL_LAST_HR_FAILED_BYTES_MD: MetricDescriptor =
new_gauge_md(
MetricName::LastHourFailedBytes,
"Total number of bytes failed at least once to replicate in the last hour on a bucket",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
pub static ref BUCKET_REPL_LAST_HR_FAILED_COUNT_MD: MetricDescriptor =
new_gauge_md(
MetricName::LastHourFailedCount,
"Total number of objects which failed replication in the last hour on a bucket",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
pub static ref BUCKET_REPL_LAST_MIN_FAILED_BYTES_MD: MetricDescriptor =
new_gauge_md(
MetricName::LastMinFailedBytes,
"Total number of bytes failed at least once to replicate in the last full minute on a bucket",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
pub static ref BUCKET_REPL_LAST_MIN_FAILED_COUNT_MD: MetricDescriptor =
new_gauge_md(
MetricName::LastMinFailedCount,
"Total number of objects which failed replication in the last full minute on a bucket",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
pub static ref BUCKET_REPL_LATENCY_MS_MD: MetricDescriptor =
new_gauge_md(
MetricName::LatencyMilliSec,
"Replication latency on a bucket in milliseconds",
&[BUCKET_L, OPERATION_L, RANGE_L, TARGET_ARN_L],
subsystems::BUCKET_REPLICATION
);
pub static ref BUCKET_REPL_PROXIED_DELETE_TAGGING_REQUESTS_TOTAL_MD: MetricDescriptor =
new_counter_md(
MetricName::ProxiedDeleteTaggingRequestsTotal,
"Number of DELETE tagging requests proxied to replication target",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
pub static ref BUCKET_REPL_PROXIED_GET_REQUESTS_FAILURES_MD: MetricDescriptor =
new_counter_md(
MetricName::ProxiedGetRequestsFailures,
"Number of failures in GET requests proxied to replication target",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
pub static ref BUCKET_REPL_PROXIED_GET_REQUESTS_TOTAL_MD: MetricDescriptor =
new_counter_md(
MetricName::ProxiedGetRequestsTotal,
"Number of GET requests proxied to replication target",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
// TODO - add a metric for the number of PUT requests proxied to replication target
pub static ref BUCKET_REPL_PROXIED_GET_TAGGING_REQUESTS_FAILURES_MD: MetricDescriptor =
new_counter_md(
MetricName::ProxiedGetTaggingRequestFailures,
"Number of failures in GET tagging requests proxied to replication target",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
pub static ref BUCKET_REPL_PROXIED_GET_TAGGING_REQUESTS_TOTAL_MD: MetricDescriptor =
new_counter_md(
MetricName::ProxiedGetTaggingRequestsTotal,
"Number of GET tagging requests proxied to replication target",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
pub static ref BUCKET_REPL_PROXIED_HEAD_REQUESTS_FAILURES_MD: MetricDescriptor =
new_counter_md(
MetricName::ProxiedHeadRequestsFailures,
"Number of failures in HEAD requests proxied to replication target",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
pub static ref BUCKET_REPL_PROXIED_HEAD_REQUESTS_TOTAL_MD: MetricDescriptor =
new_counter_md(
MetricName::ProxiedHeadRequestsTotal,
"Number of HEAD requests proxied to replication target",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
// TODO - add a metric for the number of PUT requests proxied to replication target
pub static ref BUCKET_REPL_PROXIED_PUT_TAGGING_REQUESTS_FAILURES_MD: MetricDescriptor =
new_counter_md(
MetricName::ProxiedPutTaggingRequestFailures,
"Number of failures in PUT tagging requests proxied to replication target",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
pub static ref BUCKET_REPL_PROXIED_PUT_TAGGING_REQUESTS_TOTAL_MD: MetricDescriptor =
new_counter_md(
MetricName::ProxiedPutTaggingRequestsTotal,
"Number of PUT tagging requests proxied to replication target",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
pub static ref BUCKET_REPL_SENT_BYTES_MD: MetricDescriptor =
new_counter_md(
MetricName::SentBytes,
"Total number of bytes replicated to the target",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
pub static ref BUCKET_REPL_SENT_COUNT_MD: MetricDescriptor =
new_counter_md(
MetricName::SentCount,
"Total number of objects replicated to the target",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
pub static ref BUCKET_REPL_TOTAL_FAILED_BYTES_MD: MetricDescriptor =
new_counter_md(
MetricName::TotalFailedBytes,
"Total number of bytes failed at least once to replicate since server start",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
pub static ref BUCKET_REPL_TOTAL_FAILED_COUNT_MD: MetricDescriptor =
new_counter_md(
MetricName::TotalFailedCount,
"Total number of objects which failed replication since server start",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
// TODO - add a metric for the number of DELETE requests proxied to replication target
pub static ref BUCKET_REPL_PROXIED_DELETE_TAGGING_REQUESTS_FAILURES_MD: MetricDescriptor =
new_counter_md(
MetricName::ProxiedDeleteTaggingRequestFailures,
"Number of failures in DELETE tagging requests proxied to replication target",
&[BUCKET_L],
subsystems::BUCKET_REPLICATION
);
}
+20
View File
@@ -0,0 +1,20 @@
use crate::metrics::{new_gauge_md, subsystems, MetricDescriptor, MetricName};
/// 集群配置相关指标描述符
lazy_static::lazy_static! {
pub static ref CONFIG_RRS_PARITY_MD: MetricDescriptor =
new_gauge_md(
MetricName::ConfigRRSParity,
"Reduced redundancy storage class parity",
&[], // 无标签
subsystems::CLUSTER_CONFIG
);
pub static ref CONFIG_STANDARD_PARITY_MD: MetricDescriptor =
new_gauge_md(
MetricName::ConfigStandardParity,
"Standard storage class parity",
&[], // 无标签
subsystems::CLUSTER_CONFIG
);
}
@@ -1,12 +0,0 @@
use crate::metrics::{MetricName, MetricNamespace, MetricSubsystem, MetricType};
/// The metric description describes the metric
/// It contains the namespace, subsystem, name, help text, and type of the metric
#[derive(Debug, Clone)]
pub struct MetricDescription {
pub namespace: MetricNamespace,
pub subsystem: MetricSubsystem,
pub name: MetricName,
pub help: String,
pub metric_type: MetricType,
}
+29 -7
View File
@@ -1,36 +1,58 @@
use crate::metrics::{MetricName, MetricType};
use crate::metrics::{MetricName, MetricNamespace, MetricSubsystem, MetricType};
use std::collections::HashSet;
/// MetricDescriptor - Indicates the metric descriptor
/// MetricDescriptor - 指标描述符
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct MetricDescriptor {
pub name: MetricName,
pub metric_type: MetricType,
pub help: String,
pub variable_labels: Vec<String>,
pub namespace: MetricNamespace,
pub subsystem: MetricSubsystem, // 从 String 修改为 MetricSubsystem
// internal values for management
// 内部管理值
label_set: Option<HashSet<String>>,
}
impl MetricDescriptor {
/// Create a new metric descriptor
pub fn new(name: MetricName, metric_type: MetricType, help: String, variable_labels: Vec<String>) -> Self {
/// 创建新的指标描述符
pub fn new(
name: MetricName,
metric_type: MetricType,
help: String,
variable_labels: Vec<String>,
namespace: MetricNamespace,
subsystem: impl Into<MetricSubsystem>, // 修改参数类型
) -> Self {
Self {
name,
metric_type,
help,
variable_labels,
namespace,
subsystem: subsystem.into(),
label_set: None,
}
}
/// Check whether the label is in the label set
/// 获取完整的指标名称,包含前缀和格式化路径
pub fn get_full_metric_name(&self) -> String {
let prefix = self.metric_type.to_prom();
let namespace = self.namespace.as_str();
let formatted_subsystem = self.subsystem.as_str();
format!("{}{}_{}_{}", prefix, namespace, formatted_subsystem, self.name.as_str())
}
/// 检查标签是否在标签集中
#[allow(dead_code)]
pub fn has_label(&mut self, label: &str) -> bool {
self.get_label_set().contains(label)
}
/// Gets a collection of tags, and creates if it doesn't exist
/// 获取标签集合,如果不存在则创建
pub fn get_label_set(&mut self) -> &HashSet<String> {
if self.label_set.is_none() {
let mut set = HashSet::with_capacity(self.variable_labels.len());
@@ -1,4 +1,5 @@
/// The metric name is the individual name of the metric
#[allow(dead_code)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MetricName {
// 通用指标名称
@@ -158,6 +159,15 @@ pub enum MetricName {
ApiTrafficSentBytes,
ApiTrafficRecvBytes,
// 审计指标
AuditFailedMessages,
AuditTargetQueueLength,
AuditTotalMessages,
// 集群配置相关指标
ConfigRRSParity,
ConfigStandardParity,
// 自定义指标
Custom(String),
}
@@ -303,6 +313,14 @@ impl MetricName {
Self::ApiTrafficSentBytes => "traffic_sent_bytes".to_string(),
Self::ApiTrafficRecvBytes => "traffic_received_bytes".to_string(),
Self::AuditFailedMessages => "failed_messages".to_string(),
Self::AuditTargetQueueLength => "target_queue_length".to_string(),
Self::AuditTotalMessages => "total_messages".to_string(),
/// metrics related to cluster configurations
Self::ConfigRRSParity => "rrs_parity".to_string(),
Self::ConfigStandardParity => "standard_parity".to_string(),
Self::Custom(name) => name.clone(),
}
}
+5 -3
View File
@@ -1,4 +1,5 @@
/// MetricType - Indicates the type of indicator
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MetricType {
Counter,
@@ -8,6 +9,7 @@ pub enum MetricType {
impl MetricType {
/// convert the metric type to a string representation
#[allow(dead_code)]
pub fn as_str(&self) -> &'static str {
match self {
Self::Counter => "counter",
@@ -20,9 +22,9 @@ impl MetricType {
/// In a Rust implementation, this might return the corresponding Prometheus Rust client type
pub fn to_prom(&self) -> &'static str {
match self {
Self::Counter => "counter_value",
Self::Gauge => "gauge_value",
Self::Histogram => "counter_value", // 直方图在 Prometheus 中仍使用 counter 值
Self::Counter => "counter.",
Self::Gauge => "gauge.",
Self::Histogram => "histogram.", // Histograms still use the counter value in Prometheus
}
}
}
+92 -9
View File
@@ -1,32 +1,115 @@
use crate::metrics::{MetricDescriptor, MetricName, MetricType};
use crate::metrics::{MetricDescriptor, MetricName, MetricNamespace, MetricSubsystem, MetricType};
pub(crate) mod description;
pub(crate) mod descriptor;
pub(crate) mod metric_name;
pub(crate) mod metric_type;
pub(crate) mod namespace;
mod path_utils;
pub(crate) mod subsystem;
/// Represents a range label constant
pub const RANGE_LABEL: &str = "range";
pub const SERVER_NAME: &str = "server";
/// Create a new counter metric descriptor
pub fn new_counter_md(name: impl Into<MetricName>, help: impl Into<String>, labels: &[&str]) -> MetricDescriptor {
pub fn new_counter_md(
name: impl Into<MetricName>,
help: impl Into<String>,
labels: &[&str],
subsystem: impl Into<MetricSubsystem>,
) -> MetricDescriptor {
MetricDescriptor::new(
name.into(),
MetricType::Counter,
help.into(),
labels.iter().map(|&s| s.to_string()).collect(),
MetricNamespace::RustFS,
subsystem,
)
}
/// Create a new gauge metric descriptor
pub fn new_gauge_md(name: impl Into<MetricName>, help: impl Into<String>, labels: &[&str]) -> MetricDescriptor {
/// create a new dashboard metric descriptor
pub fn new_gauge_md(
name: impl Into<MetricName>,
help: impl Into<String>,
labels: &[&str],
subsystem: impl Into<MetricSubsystem>,
) -> MetricDescriptor {
MetricDescriptor::new(
name.into(),
MetricType::Gauge,
help.into(),
labels.iter().map(|&s| s.to_string()).collect(),
MetricNamespace::RustFS,
subsystem,
)
}
/// create a new histogram indicator descriptor
#[allow(dead_code)]
pub fn new_histogram_md(
name: impl Into<MetricName>,
help: impl Into<String>,
labels: &[&str],
subsystem: impl Into<MetricSubsystem>,
) -> MetricDescriptor {
MetricDescriptor::new(
name.into(),
MetricType::Histogram,
help.into(),
labels.iter().map(|&s| s.to_string()).collect(),
MetricNamespace::RustFS,
subsystem,
)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::metrics::subsystems;
#[test]
fn test_new_histogram_md() {
// create a histogram indicator descriptor
let histogram_md = new_histogram_md(
MetricName::TtfbDistribution,
"test the response time distribution",
&["api", "method", "le"],
subsystems::API_REQUESTS,
);
// verify that the metric type is correct
assert_eq!(histogram_md.metric_type, MetricType::Histogram);
// verify that the metric name is correct
assert_eq!(histogram_md.name.as_str(), "seconds_distribution");
// verify that the help information is correct
assert_eq!(histogram_md.help, "test the response time distribution");
// Verify that the label is correct
assert_eq!(histogram_md.variable_labels.len(), 3);
assert!(histogram_md.variable_labels.contains(&"api".to_string()));
assert!(histogram_md.variable_labels.contains(&"method".to_string()));
assert!(histogram_md.variable_labels.contains(&"le".to_string()));
// Verify that the namespace is correct
assert_eq!(histogram_md.namespace, MetricNamespace::RustFS);
// Verify that the subsystem is correct
assert_eq!(histogram_md.subsystem, MetricSubsystem::ApiRequests);
// Verify that the full metric name generated is formatted correctly
assert_eq!(histogram_md.get_full_metric_name(), "histogram.rustfs_api_requests_seconds_distribution");
// Tests use custom subsystems
let custom_histogram_md = new_histogram_md(
"custom_latency_distribution",
"custom latency distribution",
&["endpoint", "le"],
MetricSubsystem::new("/custom/path-metrics"),
);
// Verify the custom name and subsystem
assert_eq!(
custom_histogram_md.get_full_metric_name(),
"histogram.rustfs_custom_path_metrics_custom_latency_distribution"
);
}
}
+1 -13
View File
@@ -1,25 +1,13 @@
/// The metric namespace is the top-level grouping created by the metric name
/// The metric namespace, which represents the top-level grouping of the metric
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MetricNamespace {
Bucket,
Cluster,
Heal,
InterNode,
Node,
RustFS,
S3,
}
impl MetricNamespace {
pub fn as_str(&self) -> &'static str {
match self {
Self::Bucket => "rustfs_bucket",
Self::Cluster => "rustfs_cluster",
Self::Heal => "rustfs_heal",
Self::InterNode => "rustfs_inter_node",
Self::Node => "rustfs_node",
Self::RustFS => "rustfs",
Self::S3 => "rustfs_s3",
}
}
}
@@ -0,0 +1,18 @@
/// Format the path to the metric name format
/// Replace '/' and '-' with '_'
pub fn format_path_to_metric_name(path: &str) -> String {
path.trim_start_matches('/').replace('/', "_").replace('-', "_")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_format_path_to_metric_name() {
assert_eq!(format_path_to_metric_name("/api/requests"), "api_requests");
assert_eq!(format_path_to_metric_name("/system/network/internode"), "system_network_internode");
assert_eq!(format_path_to_metric_name("/bucket-api"), "bucket_api");
assert_eq!(format_path_to_metric_name("cluster/health"), "cluster_health");
}
}
+219 -68
View File
@@ -1,79 +1,230 @@
use crate::metrics::entry::path_utils::format_path_to_metric_name;
/// The metrics subsystem is a subgroup of metrics within a namespace
#[derive(Debug, Clone, PartialEq, Eq)]
/// 指标子系统,表示命名空间内指标的子分组
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum MetricSubsystem {
Cache,
CapacityRaw,
CapacityUsable,
Drive,
Interface,
Memory,
CpuAvg,
StorageClass,
FileDescriptor,
GoRoutine,
Io,
Nodes,
Objects,
Bucket,
Process,
Replication,
Requests,
RequestsRejected,
Time,
Ttfb,
Traffic,
Software,
Syscall,
Usage,
Quota,
// API 相关子系统
ApiRequests,
// 桶相关子系统
BucketApi,
BucketReplication,
// 系统相关子系统
SystemNetworkInternode,
SystemDrive,
SystemMemory,
SystemCpu,
SystemProcess,
// 调试相关子系统
DebugGo,
// 集群相关子系统
ClusterHealth,
ClusterUsageObjects,
ClusterUsageBuckets,
ClusterErasureSet,
ClusterIam,
ClusterConfig,
// 其他服务相关子系统
Ilm,
Tier,
Scanner,
Iam,
Kms,
Notify,
Lambda,
Audit,
Webhook,
LoggerWebhook,
Replication,
Notification,
Scanner,
// 自定义路径
Custom(String),
}
impl MetricSubsystem {
pub fn as_str(&self) -> &'static str {
/// 获取原始路径字符串
pub fn path(&self) -> &str {
match self {
Self::Cache => "cache",
Self::CapacityRaw => "capacity_raw",
Self::CapacityUsable => "capacity_usable",
Self::Drive => "drive",
Self::Interface => "if",
Self::Memory => "mem",
Self::CpuAvg => "cpu_avg",
Self::StorageClass => "storage_class",
Self::FileDescriptor => "file_descriptor",
Self::GoRoutine => "go_routine",
Self::Io => "io",
Self::Nodes => "nodes",
Self::Objects => "objects",
Self::Bucket => "bucket",
Self::Process => "process",
Self::Replication => "replication",
Self::Requests => "requests",
Self::RequestsRejected => "requests_rejected",
Self::Time => "time",
Self::Ttfb => "requests_ttfb",
Self::Traffic => "traffic",
Self::Software => "software",
Self::Syscall => "syscall",
Self::Usage => "usage",
Self::Quota => "quota",
Self::Ilm => "ilm",
Self::Tier => "tier",
Self::Scanner => "scanner",
Self::Iam => "iam",
Self::Kms => "kms",
Self::Notify => "notify",
Self::Lambda => "lambda",
Self::Audit => "audit",
Self::Webhook => "webhook",
// API 相关子系统
Self::ApiRequests => "/api/requests",
// 桶相关子系统
Self::BucketApi => "/bucket/api",
Self::BucketReplication => "/bucket/replication",
// 系统相关子系统
Self::SystemNetworkInternode => "/system/network/internode",
Self::SystemDrive => "/system/drive",
Self::SystemMemory => "/system/memory",
Self::SystemCpu => "/system/cpu",
Self::SystemProcess => "/system/process",
// 调试相关子系统
Self::DebugGo => "/debug/go",
// 集群相关子系统
Self::ClusterHealth => "/cluster/health",
Self::ClusterUsageObjects => "/cluster/usage/objects",
Self::ClusterUsageBuckets => "/cluster/usage/buckets",
Self::ClusterErasureSet => "/cluster/erasure-set",
Self::ClusterIam => "/cluster/iam",
Self::ClusterConfig => "/cluster/config",
// 其他服务相关子系统
Self::Ilm => "/ilm",
Self::Audit => "/audit",
Self::LoggerWebhook => "/logger/webhook",
Self::Replication => "/replication",
Self::Notification => "/notification",
Self::Scanner => "/scanner",
// 自定义路径
Self::Custom(path) => path,
}
}
/// 获取格式化后的指标名称格式字符串
pub fn as_str(&self) -> String {
format_path_to_metric_name(self.path())
}
/// 从路径字符串创建子系统枚举
pub fn from_path(path: &str) -> Self {
match path {
// API 相关子系统
"/api/requests" => Self::ApiRequests,
// 桶相关子系统
"/bucket/api" => Self::BucketApi,
"/bucket/replication" => Self::BucketReplication,
// 系统相关子系统
"/system/network/internode" => Self::SystemNetworkInternode,
"/system/drive" => Self::SystemDrive,
"/system/memory" => Self::SystemMemory,
"/system/cpu" => Self::SystemCpu,
"/system/process" => Self::SystemProcess,
// 调试相关子系统
"/debug/go" => Self::DebugGo,
// 集群相关子系统
"/cluster/health" => Self::ClusterHealth,
"/cluster/usage/objects" => Self::ClusterUsageObjects,
"/cluster/usage/buckets" => Self::ClusterUsageBuckets,
"/cluster/erasure-set" => Self::ClusterErasureSet,
"/cluster/iam" => Self::ClusterIam,
"/cluster/config" => Self::ClusterConfig,
// 其他服务相关子系统
"/ilm" => Self::Ilm,
"/audit" => Self::Audit,
"/logger/webhook" => Self::LoggerWebhook,
"/replication" => Self::Replication,
"/notification" => Self::Notification,
"/scanner" => Self::Scanner,
// 其他路径作为自定义处理
_ => Self::Custom(path.to_string()),
}
}
// 便利方法,直接创建自定义子系统
pub fn new(path: impl Into<String>) -> Self {
Self::Custom(path.into())
}
}
// 便于与字符串相互转换的实现
impl From<&str> for MetricSubsystem {
fn from(s: &str) -> Self {
Self::from_path(s)
}
}
impl From<String> for MetricSubsystem {
fn from(s: String) -> Self {
Self::from_path(&s)
}
}
impl std::fmt::Display for MetricSubsystem {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.path())
}
}
#[allow(dead_code)]
pub mod subsystems {
use super::MetricSubsystem;
// 集群基本路径常量
pub const CLUSTER_BASE_PATH: &str = "/cluster";
// 快捷访问各子系统的常量
pub const API_REQUESTS: MetricSubsystem = MetricSubsystem::ApiRequests;
pub const BUCKET_API: MetricSubsystem = MetricSubsystem::BucketApi;
pub const BUCKET_REPLICATION: MetricSubsystem = MetricSubsystem::BucketReplication;
pub const SYSTEM_NETWORK_INTERNODE: MetricSubsystem = MetricSubsystem::SystemNetworkInternode;
pub const SYSTEM_DRIVE: MetricSubsystem = MetricSubsystem::SystemDrive;
pub const SYSTEM_MEMORY: MetricSubsystem = MetricSubsystem::SystemMemory;
pub const SYSTEM_CPU: MetricSubsystem = MetricSubsystem::SystemCpu;
pub const SYSTEM_PROCESS: MetricSubsystem = MetricSubsystem::SystemProcess;
pub const DEBUG_GO: MetricSubsystem = MetricSubsystem::DebugGo;
pub const CLUSTER_HEALTH: MetricSubsystem = MetricSubsystem::ClusterHealth;
pub const CLUSTER_USAGE_OBJECTS: MetricSubsystem = MetricSubsystem::ClusterUsageObjects;
pub const CLUSTER_USAGE_BUCKETS: MetricSubsystem = MetricSubsystem::ClusterUsageBuckets;
pub const CLUSTER_ERASURE_SET: MetricSubsystem = MetricSubsystem::ClusterErasureSet;
pub const CLUSTER_IAM: MetricSubsystem = MetricSubsystem::ClusterIam;
pub const CLUSTER_CONFIG: MetricSubsystem = MetricSubsystem::ClusterConfig;
pub const ILM: MetricSubsystem = MetricSubsystem::Ilm;
pub const AUDIT: MetricSubsystem = MetricSubsystem::Audit;
pub const LOGGER_WEBHOOK: MetricSubsystem = MetricSubsystem::LoggerWebhook;
pub const REPLICATION: MetricSubsystem = MetricSubsystem::Replication;
pub const NOTIFICATION: MetricSubsystem = MetricSubsystem::Notification;
pub const SCANNER: MetricSubsystem = MetricSubsystem::Scanner;
}
#[cfg(test)]
mod tests {
use super::*;
use crate::metrics::MetricType;
use crate::metrics::{MetricDescriptor, MetricName, MetricNamespace};
#[test]
fn test_metric_subsystem_formatting() {
assert_eq!(MetricSubsystem::ApiRequests.as_str(), "api_requests");
assert_eq!(MetricSubsystem::SystemNetworkInternode.as_str(), "system_network_internode");
assert_eq!(MetricSubsystem::BucketApi.as_str(), "bucket_api");
assert_eq!(MetricSubsystem::ClusterHealth.as_str(), "cluster_health");
// 测试自定义路径
let custom = MetricSubsystem::new("/custom/path-test");
assert_eq!(custom.as_str(), "custom_path_test");
}
#[test]
fn test_metric_descriptor_name_generation() {
let md = MetricDescriptor::new(
MetricName::ApiRequestsTotal,
MetricType::Counter,
"Test help".to_string(),
vec!["label1".to_string(), "label2".to_string()],
MetricNamespace::RustFS,
MetricSubsystem::ApiRequests,
);
assert_eq!(md.get_full_metric_name(), "counter.rustfs_api_requests_total");
let custom_md = MetricDescriptor::new(
MetricName::Custom("test_metric".to_string()),
MetricType::Gauge,
"Test help".to_string(),
vec!["label1".to_string()],
MetricNamespace::RustFS,
MetricSubsystem::new("/custom/path-with-dash"),
);
assert_eq!(custom_md.get_full_metric_name(), "gauge.rustfs_custom_path_with_dash_test_metric");
}
}
+5 -2
View File
@@ -1,10 +1,13 @@
mod audit;
mod bucket;
mod bucket_replication;
mod entry;
mod request;
pub use entry::description::MetricDescription;
pub use entry::descriptor::MetricDescriptor;
pub use entry::metric_name::MetricName;
pub use entry::metric_type::MetricType;
pub use entry::namespace::MetricNamespace;
pub use entry::subsystem::subsystems;
pub use entry::subsystem::MetricSubsystem;
pub use entry::{new_counter_md, new_gauge_md};
pub use entry::{new_counter_md, new_gauge_md, new_histogram_md};
+46 -32
View File
@@ -1,109 +1,123 @@
use crate::metrics::{new_counter_md, new_gauge_md, MetricDescriptor, MetricName};
use crate::metrics::{new_counter_md, new_gauge_md, subsystems, MetricDescriptor, MetricName, MetricSubsystem};
/// Predefined API metric descriptors
lazy_static::lazy_static! {
pub static ref API_REJECTED_AUTH_TOTAL_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiRejectedAuthTotal.as_str(),
MetricName::ApiRejectedAuthTotal,
"Total number of requests rejected for auth failure",
&["type"]
&["type"],
subsystems::API_REQUESTS
);
pub static ref API_REJECTED_HEADER_TOTAL_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiRejectedHeaderTotal.as_str(),
MetricName::ApiRejectedHeaderTotal,
"Total number of requests rejected for invalid header",
&["type"]
&["type"],
MetricSubsystem::ApiRequests
);
pub static ref API_REJECTED_TIMESTAMP_TOTAL_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiRejectedTimestampTotal.as_str(),
MetricName::ApiRejectedTimestampTotal,
"Total number of requests rejected for invalid timestamp",
&["type"]
&["type"],
MetricSubsystem::ApiRequests
);
pub static ref API_REJECTED_INVALID_TOTAL_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiRejectedInvalidTotal.as_str(),
MetricName::ApiRejectedInvalidTotal,
"Total number of invalid requests",
&["type"]
&["type"],
MetricSubsystem::ApiRequests
);
pub static ref API_REQUESTS_WAITING_TOTAL_MD: MetricDescriptor =
new_gauge_md(
MetricName::ApiRequestsWaitingTotal.as_str(),
MetricName::ApiRequestsWaitingTotal,
"Total number of requests in the waiting queue",
&["type"]
&["type"],
MetricSubsystem::ApiRequests
);
pub static ref API_REQUESTS_INCOMING_TOTAL_MD: MetricDescriptor =
new_gauge_md(
MetricName::ApiRequestsIncomingTotal.as_str(),
MetricName::ApiRequestsIncomingTotal,
"Total number of incoming requests",
&["type"]
&["type"],
MetricSubsystem::ApiRequests
);
pub static ref API_REQUESTS_IN_FLIGHT_TOTAL_MD: MetricDescriptor =
new_gauge_md(
MetricName::ApiRequestsInFlightTotal.as_str(),
MetricName::ApiRequestsInFlightTotal,
"Total number of requests currently in flight",
&["name", "type"]
&["name", "type"],
MetricSubsystem::ApiRequests
);
pub static ref API_REQUESTS_TOTAL_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiRequestsTotal.as_str(),
MetricName::ApiRequestsTotal,
"Total number of requests",
&["name", "type"]
&["name", "type"],
MetricSubsystem::ApiRequests
);
pub static ref API_REQUESTS_ERRORS_TOTAL_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiRequestsErrorsTotal.as_str(),
MetricName::ApiRequestsErrorsTotal,
"Total number of requests with (4xx and 5xx) errors",
&["name", "type"]
&["name", "type"],
MetricSubsystem::ApiRequests
);
pub static ref API_REQUESTS_5XX_ERRORS_TOTAL_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiRequests5xxErrorsTotal.as_str(),
MetricName::ApiRequests5xxErrorsTotal,
"Total number of requests with 5xx errors",
&["name", "type"]
&["name", "type"],
MetricSubsystem::ApiRequests
);
pub static ref API_REQUESTS_4XX_ERRORS_TOTAL_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiRequests4xxErrorsTotal.as_str(),
MetricName::ApiRequests4xxErrorsTotal,
"Total number of requests with 4xx errors",
&["name", "type"]
&["name", "type"],
MetricSubsystem::ApiRequests
);
pub static ref API_REQUESTS_CANCELED_TOTAL_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiRequestsCanceledTotal.as_str(),
MetricName::ApiRequestsCanceledTotal,
"Total number of requests canceled by the client",
&["name", "type"]
&["name", "type"],
MetricSubsystem::ApiRequests
);
pub static ref API_REQUESTS_TTFB_SECONDS_DISTRIBUTION_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiRequestsTTFBSecondsDistribution.as_str(),
MetricName::ApiRequestsTTFBSecondsDistribution,
"Distribution of time to first byte across API calls",
&["name", "type", "le"]
&["name", "type", "le"],
MetricSubsystem::ApiRequests
);
pub static ref API_TRAFFIC_SENT_BYTES_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiTrafficSentBytes.as_str(),
MetricName::ApiTrafficSentBytes,
"Total number of bytes sent",
&["type"]
&["type"],
MetricSubsystem::ApiRequests
);
pub static ref API_TRAFFIC_RECV_BYTES_MD: MetricDescriptor =
new_counter_md(
MetricName::ApiTrafficRecvBytes.as_str(),
MetricName::ApiTrafficRecvBytes,
"Total number of bytes received",
&["type"]
&["type"],
MetricSubsystem::ApiRequests
);
}
+4 -1
View File
@@ -1,8 +1,11 @@
#[cfg(feature = "tls")]
mod certs;
#[cfg(feature = "ip")]
mod ip;
#[cfg(feature = "net")]
mod net;
#[cfg(feature = "ip")]
#[cfg(feature = "tls")]
pub use certs::*;
#[cfg(feature = "ip")]
pub use ip::*;