mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-24 13:16:28 +00:00
add metric
This commit is contained in:
Generated
+1
-1
@@ -7347,7 +7347,6 @@ dependencies = [
|
|||||||
"axum",
|
"axum",
|
||||||
"config",
|
"config",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"http",
|
|
||||||
"rdkafka",
|
"rdkafka",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rumqttc",
|
"rumqttc",
|
||||||
@@ -7391,6 +7390,7 @@ dependencies = [
|
|||||||
"async-trait",
|
"async-trait",
|
||||||
"chrono",
|
"chrono",
|
||||||
"config",
|
"config",
|
||||||
|
"lazy_static",
|
||||||
"local-ip-address",
|
"local-ip-address",
|
||||||
"nvml-wrapper",
|
"nvml-wrapper",
|
||||||
"opentelemetry",
|
"opentelemetry",
|
||||||
|
|||||||
@@ -113,5 +113,3 @@ export RUSTFS_OBS_CONFIG="./deploy/config/obs.toml"
|
|||||||
| use_stdout | 是否输出到控制台 | true/false |
|
| use_stdout | 是否输出到控制台 | true/false |
|
||||||
| logger_level | 日志级别 | info |
|
| logger_level | 日志级别 | info |
|
||||||
| local_logging_enable | 控制台是否答应日志 | true/false |
|
| local_logging_enable | 控制台是否答应日志 | true/false |
|
||||||
|
|
||||||
```
|
|
||||||
@@ -35,7 +35,6 @@ rdkafka = { workspace = true, features = ["tokio"], optional = true }
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio = { workspace = true, features = ["test-util"] }
|
tokio = { workspace = true, features = ["test-util"] }
|
||||||
tracing-subscriber = { workspace = true }
|
tracing-subscriber = { workspace = true }
|
||||||
http = { workspace = true }
|
|
||||||
axum = { workspace = true }
|
axum = { workspace = true }
|
||||||
dotenvy = "0.15.7"
|
dotenvy = "0.15.7"
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ rustfs-config = { workspace = true }
|
|||||||
async-trait = { workspace = true }
|
async-trait = { workspace = true }
|
||||||
chrono = { workspace = true }
|
chrono = { workspace = true }
|
||||||
config = { workspace = true }
|
config = { workspace = true }
|
||||||
|
lazy_static = { workspace = true }
|
||||||
local-ip-address = { workspace = true }
|
local-ip-address = { workspace = true }
|
||||||
nvml-wrapper = { workspace = true, optional = true }
|
nvml-wrapper = { workspace = true, optional = true }
|
||||||
opentelemetry = { workspace = true }
|
opentelemetry = { workspace = true }
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ mod config;
|
|||||||
mod entry;
|
mod entry;
|
||||||
mod global;
|
mod global;
|
||||||
mod logger;
|
mod logger;
|
||||||
|
mod metrics;
|
||||||
mod sinks;
|
mod sinks;
|
||||||
mod system;
|
mod system;
|
||||||
mod telemetry;
|
mod telemetry;
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
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,
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
use crate::metrics::{MetricName, MetricType};
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
/// MetricDescriptor - Indicates the metric descriptor
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct MetricDescriptor {
|
||||||
|
pub name: MetricName,
|
||||||
|
pub metric_type: MetricType,
|
||||||
|
pub help: String,
|
||||||
|
pub variable_labels: Vec<String>,
|
||||||
|
|
||||||
|
// 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 {
|
||||||
|
Self {
|
||||||
|
name,
|
||||||
|
metric_type,
|
||||||
|
help,
|
||||||
|
variable_labels,
|
||||||
|
label_set: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check whether the label is in the label set
|
||||||
|
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());
|
||||||
|
for label in &self.variable_labels {
|
||||||
|
set.insert(label.clone());
|
||||||
|
}
|
||||||
|
self.label_set = Some(set);
|
||||||
|
}
|
||||||
|
self.label_set.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,321 @@
|
|||||||
|
/// The metric name is the individual name of the metric
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub enum MetricName {
|
||||||
|
// 通用指标名称
|
||||||
|
AuthTotal,
|
||||||
|
CanceledTotal,
|
||||||
|
ErrorsTotal,
|
||||||
|
HeaderTotal,
|
||||||
|
HealTotal,
|
||||||
|
HitsTotal,
|
||||||
|
InflightTotal,
|
||||||
|
InvalidTotal,
|
||||||
|
LimitTotal,
|
||||||
|
MissedTotal,
|
||||||
|
WaitingTotal,
|
||||||
|
IncomingTotal,
|
||||||
|
ObjectTotal,
|
||||||
|
VersionTotal,
|
||||||
|
DeleteMarkerTotal,
|
||||||
|
OfflineTotal,
|
||||||
|
OnlineTotal,
|
||||||
|
OpenTotal,
|
||||||
|
ReadTotal,
|
||||||
|
TimestampTotal,
|
||||||
|
WriteTotal,
|
||||||
|
Total,
|
||||||
|
FreeInodes,
|
||||||
|
|
||||||
|
// 失败统计指标
|
||||||
|
LastMinFailedCount,
|
||||||
|
LastMinFailedBytes,
|
||||||
|
LastHourFailedCount,
|
||||||
|
LastHourFailedBytes,
|
||||||
|
TotalFailedCount,
|
||||||
|
TotalFailedBytes,
|
||||||
|
|
||||||
|
// 工作线程指标
|
||||||
|
CurrActiveWorkers,
|
||||||
|
AvgActiveWorkers,
|
||||||
|
MaxActiveWorkers,
|
||||||
|
RecentBacklogCount,
|
||||||
|
CurrInQueueCount,
|
||||||
|
CurrInQueueBytes,
|
||||||
|
ReceivedCount,
|
||||||
|
SentCount,
|
||||||
|
CurrTransferRate,
|
||||||
|
AvgTransferRate,
|
||||||
|
MaxTransferRate,
|
||||||
|
CredentialErrors,
|
||||||
|
|
||||||
|
// 链接延迟指标
|
||||||
|
CurrLinkLatency,
|
||||||
|
AvgLinkLatency,
|
||||||
|
MaxLinkLatency,
|
||||||
|
|
||||||
|
// 链接状态指标
|
||||||
|
LinkOnline,
|
||||||
|
LinkOfflineDuration,
|
||||||
|
LinkDowntimeTotalDuration,
|
||||||
|
|
||||||
|
// 队列指标
|
||||||
|
AvgInQueueCount,
|
||||||
|
AvgInQueueBytes,
|
||||||
|
MaxInQueueCount,
|
||||||
|
MaxInQueueBytes,
|
||||||
|
|
||||||
|
// 代理请求指标
|
||||||
|
ProxiedGetRequestsTotal,
|
||||||
|
ProxiedHeadRequestsTotal,
|
||||||
|
ProxiedPutTaggingRequestsTotal,
|
||||||
|
ProxiedGetTaggingRequestsTotal,
|
||||||
|
ProxiedDeleteTaggingRequestsTotal,
|
||||||
|
ProxiedGetRequestsFailures,
|
||||||
|
ProxiedHeadRequestsFailures,
|
||||||
|
ProxiedPutTaggingRequestFailures,
|
||||||
|
ProxiedGetTaggingRequestFailures,
|
||||||
|
ProxiedDeleteTaggingRequestFailures,
|
||||||
|
|
||||||
|
// 字节相关指标
|
||||||
|
FreeBytes,
|
||||||
|
ReadBytes,
|
||||||
|
RcharBytes,
|
||||||
|
ReceivedBytes,
|
||||||
|
LatencyMilliSec,
|
||||||
|
SentBytes,
|
||||||
|
TotalBytes,
|
||||||
|
UsedBytes,
|
||||||
|
WriteBytes,
|
||||||
|
WcharBytes,
|
||||||
|
|
||||||
|
// 延迟指标
|
||||||
|
LatencyMicroSec,
|
||||||
|
LatencyNanoSec,
|
||||||
|
|
||||||
|
// 信息指标
|
||||||
|
CommitInfo,
|
||||||
|
UsageInfo,
|
||||||
|
VersionInfo,
|
||||||
|
|
||||||
|
// 分布指标
|
||||||
|
SizeDistribution,
|
||||||
|
VersionDistribution,
|
||||||
|
TtfbDistribution,
|
||||||
|
TtlbDistribution,
|
||||||
|
|
||||||
|
// 时间指标
|
||||||
|
LastActivityTime,
|
||||||
|
StartTime,
|
||||||
|
UpTime,
|
||||||
|
Memory,
|
||||||
|
Vmemory,
|
||||||
|
Cpu,
|
||||||
|
|
||||||
|
// 过期和转换指标
|
||||||
|
ExpiryMissedTasks,
|
||||||
|
ExpiryMissedFreeVersions,
|
||||||
|
ExpiryMissedTierJournalTasks,
|
||||||
|
ExpiryNumWorkers,
|
||||||
|
TransitionMissedTasks,
|
||||||
|
TransitionedBytes,
|
||||||
|
TransitionedObjects,
|
||||||
|
TransitionedVersions,
|
||||||
|
|
||||||
|
// Tier 请求指标
|
||||||
|
TierRequestsSuccess,
|
||||||
|
TierRequestsFailure,
|
||||||
|
|
||||||
|
// KMS 指标
|
||||||
|
KmsOnline,
|
||||||
|
KmsRequestsSuccess,
|
||||||
|
KmsRequestsError,
|
||||||
|
KmsRequestsFail,
|
||||||
|
KmsUptime,
|
||||||
|
|
||||||
|
// Webhook 指标
|
||||||
|
WebhookOnline,
|
||||||
|
|
||||||
|
// API 拒绝指标
|
||||||
|
ApiRejectedAuthTotal,
|
||||||
|
ApiRejectedHeaderTotal,
|
||||||
|
ApiRejectedTimestampTotal,
|
||||||
|
ApiRejectedInvalidTotal,
|
||||||
|
|
||||||
|
// API 请求指标
|
||||||
|
ApiRequestsWaitingTotal,
|
||||||
|
ApiRequestsIncomingTotal,
|
||||||
|
ApiRequestsInFlightTotal,
|
||||||
|
ApiRequestsTotal,
|
||||||
|
ApiRequestsErrorsTotal,
|
||||||
|
ApiRequests5xxErrorsTotal,
|
||||||
|
ApiRequests4xxErrorsTotal,
|
||||||
|
ApiRequestsCanceledTotal,
|
||||||
|
|
||||||
|
// API 分布指标
|
||||||
|
ApiRequestsTTFBSecondsDistribution,
|
||||||
|
|
||||||
|
// API 流量指标
|
||||||
|
ApiTrafficSentBytes,
|
||||||
|
ApiTrafficRecvBytes,
|
||||||
|
|
||||||
|
// 自定义指标
|
||||||
|
Custom(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MetricName {
|
||||||
|
pub fn as_str(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Self::AuthTotal => "auth_total".to_string(),
|
||||||
|
Self::CanceledTotal => "canceled_total".to_string(),
|
||||||
|
Self::ErrorsTotal => "errors_total".to_string(),
|
||||||
|
Self::HeaderTotal => "header_total".to_string(),
|
||||||
|
Self::HealTotal => "heal_total".to_string(),
|
||||||
|
Self::HitsTotal => "hits_total".to_string(),
|
||||||
|
Self::InflightTotal => "inflight_total".to_string(),
|
||||||
|
Self::InvalidTotal => "invalid_total".to_string(),
|
||||||
|
Self::LimitTotal => "limit_total".to_string(),
|
||||||
|
Self::MissedTotal => "missed_total".to_string(),
|
||||||
|
Self::WaitingTotal => "waiting_total".to_string(),
|
||||||
|
Self::IncomingTotal => "incoming_total".to_string(),
|
||||||
|
Self::ObjectTotal => "object_total".to_string(),
|
||||||
|
Self::VersionTotal => "version_total".to_string(),
|
||||||
|
Self::DeleteMarkerTotal => "deletemarker_total".to_string(),
|
||||||
|
Self::OfflineTotal => "offline_total".to_string(),
|
||||||
|
Self::OnlineTotal => "online_total".to_string(),
|
||||||
|
Self::OpenTotal => "open_total".to_string(),
|
||||||
|
Self::ReadTotal => "read_total".to_string(),
|
||||||
|
Self::TimestampTotal => "timestamp_total".to_string(),
|
||||||
|
Self::WriteTotal => "write_total".to_string(),
|
||||||
|
Self::Total => "total".to_string(),
|
||||||
|
Self::FreeInodes => "free_inodes".to_string(),
|
||||||
|
|
||||||
|
Self::LastMinFailedCount => "last_minute_failed_count".to_string(),
|
||||||
|
Self::LastMinFailedBytes => "last_minute_failed_bytes".to_string(),
|
||||||
|
Self::LastHourFailedCount => "last_hour_failed_count".to_string(),
|
||||||
|
Self::LastHourFailedBytes => "last_hour_failed_bytes".to_string(),
|
||||||
|
Self::TotalFailedCount => "total_failed_count".to_string(),
|
||||||
|
Self::TotalFailedBytes => "total_failed_bytes".to_string(),
|
||||||
|
|
||||||
|
Self::CurrActiveWorkers => "current_active_workers".to_string(),
|
||||||
|
Self::AvgActiveWorkers => "average_active_workers".to_string(),
|
||||||
|
Self::MaxActiveWorkers => "max_active_workers".to_string(),
|
||||||
|
Self::RecentBacklogCount => "recent_backlog_count".to_string(),
|
||||||
|
Self::CurrInQueueCount => "last_minute_queued_count".to_string(),
|
||||||
|
Self::CurrInQueueBytes => "last_minute_queued_bytes".to_string(),
|
||||||
|
Self::ReceivedCount => "received_count".to_string(),
|
||||||
|
Self::SentCount => "sent_count".to_string(),
|
||||||
|
Self::CurrTransferRate => "current_transfer_rate".to_string(),
|
||||||
|
Self::AvgTransferRate => "average_transfer_rate".to_string(),
|
||||||
|
Self::MaxTransferRate => "max_transfer_rate".to_string(),
|
||||||
|
Self::CredentialErrors => "credential_errors".to_string(),
|
||||||
|
|
||||||
|
Self::CurrLinkLatency => "current_link_latency_ms".to_string(),
|
||||||
|
Self::AvgLinkLatency => "average_link_latency_ms".to_string(),
|
||||||
|
Self::MaxLinkLatency => "max_link_latency_ms".to_string(),
|
||||||
|
|
||||||
|
Self::LinkOnline => "link_online".to_string(),
|
||||||
|
Self::LinkOfflineDuration => "link_offline_duration_seconds".to_string(),
|
||||||
|
Self::LinkDowntimeTotalDuration => "link_downtime_duration_seconds".to_string(),
|
||||||
|
|
||||||
|
Self::AvgInQueueCount => "average_queued_count".to_string(),
|
||||||
|
Self::AvgInQueueBytes => "average_queued_bytes".to_string(),
|
||||||
|
Self::MaxInQueueCount => "max_queued_count".to_string(),
|
||||||
|
Self::MaxInQueueBytes => "max_queued_bytes".to_string(),
|
||||||
|
|
||||||
|
Self::ProxiedGetRequestsTotal => "proxied_get_requests_total".to_string(),
|
||||||
|
Self::ProxiedHeadRequestsTotal => "proxied_head_requests_total".to_string(),
|
||||||
|
Self::ProxiedPutTaggingRequestsTotal => "proxied_put_tagging_requests_total".to_string(),
|
||||||
|
Self::ProxiedGetTaggingRequestsTotal => "proxied_get_tagging_requests_total".to_string(),
|
||||||
|
Self::ProxiedDeleteTaggingRequestsTotal => "proxied_delete_tagging_requests_total".to_string(),
|
||||||
|
Self::ProxiedGetRequestsFailures => "proxied_get_requests_failures".to_string(),
|
||||||
|
Self::ProxiedHeadRequestsFailures => "proxied_head_requests_failures".to_string(),
|
||||||
|
Self::ProxiedPutTaggingRequestFailures => "proxied_put_tagging_requests_failures".to_string(),
|
||||||
|
Self::ProxiedGetTaggingRequestFailures => "proxied_get_tagging_requests_failures".to_string(),
|
||||||
|
Self::ProxiedDeleteTaggingRequestFailures => "proxied_delete_tagging_requests_failures".to_string(),
|
||||||
|
|
||||||
|
Self::FreeBytes => "free_bytes".to_string(),
|
||||||
|
Self::ReadBytes => "read_bytes".to_string(),
|
||||||
|
Self::RcharBytes => "rchar_bytes".to_string(),
|
||||||
|
Self::ReceivedBytes => "received_bytes".to_string(),
|
||||||
|
Self::LatencyMilliSec => "latency_ms".to_string(),
|
||||||
|
Self::SentBytes => "sent_bytes".to_string(),
|
||||||
|
Self::TotalBytes => "total_bytes".to_string(),
|
||||||
|
Self::UsedBytes => "used_bytes".to_string(),
|
||||||
|
Self::WriteBytes => "write_bytes".to_string(),
|
||||||
|
Self::WcharBytes => "wchar_bytes".to_string(),
|
||||||
|
|
||||||
|
Self::LatencyMicroSec => "latency_us".to_string(),
|
||||||
|
Self::LatencyNanoSec => "latency_ns".to_string(),
|
||||||
|
|
||||||
|
Self::CommitInfo => "commit_info".to_string(),
|
||||||
|
Self::UsageInfo => "usage_info".to_string(),
|
||||||
|
Self::VersionInfo => "version_info".to_string(),
|
||||||
|
|
||||||
|
Self::SizeDistribution => "size_distribution".to_string(),
|
||||||
|
Self::VersionDistribution => "version_distribution".to_string(),
|
||||||
|
Self::TtfbDistribution => "seconds_distribution".to_string(),
|
||||||
|
Self::TtlbDistribution => "ttlb_seconds_distribution".to_string(),
|
||||||
|
|
||||||
|
Self::LastActivityTime => "last_activity_nano_seconds".to_string(),
|
||||||
|
Self::StartTime => "starttime_seconds".to_string(),
|
||||||
|
Self::UpTime => "uptime_seconds".to_string(),
|
||||||
|
Self::Memory => "resident_memory_bytes".to_string(),
|
||||||
|
Self::Vmemory => "virtual_memory_bytes".to_string(),
|
||||||
|
Self::Cpu => "cpu_total_seconds".to_string(),
|
||||||
|
|
||||||
|
Self::ExpiryMissedTasks => "expiry_missed_tasks".to_string(),
|
||||||
|
Self::ExpiryMissedFreeVersions => "expiry_missed_freeversions".to_string(),
|
||||||
|
Self::ExpiryMissedTierJournalTasks => "expiry_missed_tierjournal_tasks".to_string(),
|
||||||
|
Self::ExpiryNumWorkers => "expiry_num_workers".to_string(),
|
||||||
|
Self::TransitionMissedTasks => "transition_missed_immediate_tasks".to_string(),
|
||||||
|
|
||||||
|
Self::TransitionedBytes => "transitioned_bytes".to_string(),
|
||||||
|
Self::TransitionedObjects => "transitioned_objects".to_string(),
|
||||||
|
Self::TransitionedVersions => "transitioned_versions".to_string(),
|
||||||
|
|
||||||
|
Self::TierRequestsSuccess => "requests_success".to_string(),
|
||||||
|
Self::TierRequestsFailure => "requests_failure".to_string(),
|
||||||
|
|
||||||
|
Self::KmsOnline => "online".to_string(),
|
||||||
|
Self::KmsRequestsSuccess => "request_success".to_string(),
|
||||||
|
Self::KmsRequestsError => "request_error".to_string(),
|
||||||
|
Self::KmsRequestsFail => "request_failure".to_string(),
|
||||||
|
Self::KmsUptime => "uptime".to_string(),
|
||||||
|
|
||||||
|
Self::WebhookOnline => "online".to_string(),
|
||||||
|
|
||||||
|
Self::ApiRejectedAuthTotal => "rejected_auth_total".to_string(),
|
||||||
|
Self::ApiRejectedHeaderTotal => "rejected_header_total".to_string(),
|
||||||
|
Self::ApiRejectedTimestampTotal => "rejected_timestamp_total".to_string(),
|
||||||
|
Self::ApiRejectedInvalidTotal => "rejected_invalid_total".to_string(),
|
||||||
|
|
||||||
|
Self::ApiRequestsWaitingTotal => "waiting_total".to_string(),
|
||||||
|
Self::ApiRequestsIncomingTotal => "incoming_total".to_string(),
|
||||||
|
Self::ApiRequestsInFlightTotal => "inflight_total".to_string(),
|
||||||
|
Self::ApiRequestsTotal => "total".to_string(),
|
||||||
|
Self::ApiRequestsErrorsTotal => "errors_total".to_string(),
|
||||||
|
Self::ApiRequests5xxErrorsTotal => "5xx_errors_total".to_string(),
|
||||||
|
Self::ApiRequests4xxErrorsTotal => "4xx_errors_total".to_string(),
|
||||||
|
Self::ApiRequestsCanceledTotal => "canceled_total".to_string(),
|
||||||
|
|
||||||
|
Self::ApiRequestsTTFBSecondsDistribution => "ttfb_seconds_distribution".to_string(),
|
||||||
|
|
||||||
|
Self::ApiTrafficSentBytes => "traffic_sent_bytes".to_string(),
|
||||||
|
Self::ApiTrafficRecvBytes => "traffic_received_bytes".to_string(),
|
||||||
|
|
||||||
|
Self::Custom(name) => name.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for MetricName {
|
||||||
|
fn from(s: String) -> Self {
|
||||||
|
Self::Custom(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for MetricName {
|
||||||
|
fn from(s: &str) -> Self {
|
||||||
|
Self::Custom(s.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/// MetricType - Indicates the type of indicator
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum MetricType {
|
||||||
|
Counter,
|
||||||
|
Gauge,
|
||||||
|
Histogram,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MetricType {
|
||||||
|
/// convert the metric type to a string representation
|
||||||
|
pub fn as_str(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::Counter => "counter",
|
||||||
|
Self::Gauge => "gauge",
|
||||||
|
Self::Histogram => "histogram",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert the metric type to the Prometheus value type
|
||||||
|
/// 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 值
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
use crate::metrics::{MetricDescriptor, MetricName, MetricType};
|
||||||
|
|
||||||
|
pub(crate) mod description;
|
||||||
|
pub(crate) mod descriptor;
|
||||||
|
pub(crate) mod metric_name;
|
||||||
|
pub(crate) mod metric_type;
|
||||||
|
pub(crate) mod namespace;
|
||||||
|
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 {
|
||||||
|
MetricDescriptor::new(
|
||||||
|
name.into(),
|
||||||
|
MetricType::Counter,
|
||||||
|
help.into(),
|
||||||
|
labels.iter().map(|&s| s.to_string()).collect(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new gauge metric descriptor
|
||||||
|
pub fn new_gauge_md(name: impl Into<MetricName>, help: impl Into<String>, labels: &[&str]) -> MetricDescriptor {
|
||||||
|
MetricDescriptor::new(
|
||||||
|
name.into(),
|
||||||
|
MetricType::Gauge,
|
||||||
|
help.into(),
|
||||||
|
labels.iter().map(|&s| s.to_string()).collect(),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/// The metric namespace is the top-level grouping created by the metric name
|
||||||
|
#[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,79 @@
|
|||||||
|
/// The metrics subsystem is a subgroup of metrics within a namespace
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
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,
|
||||||
|
Ilm,
|
||||||
|
Tier,
|
||||||
|
Scanner,
|
||||||
|
Iam,
|
||||||
|
Kms,
|
||||||
|
Notify,
|
||||||
|
Lambda,
|
||||||
|
Audit,
|
||||||
|
Webhook,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MetricSubsystem {
|
||||||
|
pub fn as_str(&self) -> &'static 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",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
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::MetricSubsystem;
|
||||||
|
pub use entry::{new_counter_md, new_gauge_md};
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
use crate::metrics::{new_counter_md, new_gauge_md, MetricDescriptor, MetricName};
|
||||||
|
|
||||||
|
/// Predefined API metric descriptors
|
||||||
|
lazy_static::lazy_static! {
|
||||||
|
pub static ref API_REJECTED_AUTH_TOTAL_MD: MetricDescriptor =
|
||||||
|
new_counter_md(
|
||||||
|
MetricName::ApiRejectedAuthTotal.as_str(),
|
||||||
|
"Total number of requests rejected for auth failure",
|
||||||
|
&["type"]
|
||||||
|
);
|
||||||
|
|
||||||
|
pub static ref API_REJECTED_HEADER_TOTAL_MD: MetricDescriptor =
|
||||||
|
new_counter_md(
|
||||||
|
MetricName::ApiRejectedHeaderTotal.as_str(),
|
||||||
|
"Total number of requests rejected for invalid header",
|
||||||
|
&["type"]
|
||||||
|
);
|
||||||
|
|
||||||
|
pub static ref API_REJECTED_TIMESTAMP_TOTAL_MD: MetricDescriptor =
|
||||||
|
new_counter_md(
|
||||||
|
MetricName::ApiRejectedTimestampTotal.as_str(),
|
||||||
|
"Total number of requests rejected for invalid timestamp",
|
||||||
|
&["type"]
|
||||||
|
);
|
||||||
|
|
||||||
|
pub static ref API_REJECTED_INVALID_TOTAL_MD: MetricDescriptor =
|
||||||
|
new_counter_md(
|
||||||
|
MetricName::ApiRejectedInvalidTotal.as_str(),
|
||||||
|
"Total number of invalid requests",
|
||||||
|
&["type"]
|
||||||
|
);
|
||||||
|
|
||||||
|
pub static ref API_REQUESTS_WAITING_TOTAL_MD: MetricDescriptor =
|
||||||
|
new_gauge_md(
|
||||||
|
MetricName::ApiRequestsWaitingTotal.as_str(),
|
||||||
|
"Total number of requests in the waiting queue",
|
||||||
|
&["type"]
|
||||||
|
);
|
||||||
|
|
||||||
|
pub static ref API_REQUESTS_INCOMING_TOTAL_MD: MetricDescriptor =
|
||||||
|
new_gauge_md(
|
||||||
|
MetricName::ApiRequestsIncomingTotal.as_str(),
|
||||||
|
"Total number of incoming requests",
|
||||||
|
&["type"]
|
||||||
|
);
|
||||||
|
|
||||||
|
pub static ref API_REQUESTS_IN_FLIGHT_TOTAL_MD: MetricDescriptor =
|
||||||
|
new_gauge_md(
|
||||||
|
MetricName::ApiRequestsInFlightTotal.as_str(),
|
||||||
|
"Total number of requests currently in flight",
|
||||||
|
&["name", "type"]
|
||||||
|
);
|
||||||
|
|
||||||
|
pub static ref API_REQUESTS_TOTAL_MD: MetricDescriptor =
|
||||||
|
new_counter_md(
|
||||||
|
MetricName::ApiRequestsTotal.as_str(),
|
||||||
|
"Total number of requests",
|
||||||
|
&["name", "type"]
|
||||||
|
);
|
||||||
|
|
||||||
|
pub static ref API_REQUESTS_ERRORS_TOTAL_MD: MetricDescriptor =
|
||||||
|
new_counter_md(
|
||||||
|
MetricName::ApiRequestsErrorsTotal.as_str(),
|
||||||
|
"Total number of requests with (4xx and 5xx) errors",
|
||||||
|
&["name", "type"]
|
||||||
|
);
|
||||||
|
|
||||||
|
pub static ref API_REQUESTS_5XX_ERRORS_TOTAL_MD: MetricDescriptor =
|
||||||
|
new_counter_md(
|
||||||
|
MetricName::ApiRequests5xxErrorsTotal.as_str(),
|
||||||
|
"Total number of requests with 5xx errors",
|
||||||
|
&["name", "type"]
|
||||||
|
);
|
||||||
|
|
||||||
|
pub static ref API_REQUESTS_4XX_ERRORS_TOTAL_MD: MetricDescriptor =
|
||||||
|
new_counter_md(
|
||||||
|
MetricName::ApiRequests4xxErrorsTotal.as_str(),
|
||||||
|
"Total number of requests with 4xx errors",
|
||||||
|
&["name", "type"]
|
||||||
|
);
|
||||||
|
|
||||||
|
pub static ref API_REQUESTS_CANCELED_TOTAL_MD: MetricDescriptor =
|
||||||
|
new_counter_md(
|
||||||
|
MetricName::ApiRequestsCanceledTotal.as_str(),
|
||||||
|
"Total number of requests canceled by the client",
|
||||||
|
&["name", "type"]
|
||||||
|
);
|
||||||
|
|
||||||
|
pub static ref API_REQUESTS_TTFB_SECONDS_DISTRIBUTION_MD: MetricDescriptor =
|
||||||
|
new_counter_md(
|
||||||
|
MetricName::ApiRequestsTTFBSecondsDistribution.as_str(),
|
||||||
|
"Distribution of time to first byte across API calls",
|
||||||
|
&["name", "type", "le"]
|
||||||
|
);
|
||||||
|
|
||||||
|
pub static ref API_TRAFFIC_SENT_BYTES_MD: MetricDescriptor =
|
||||||
|
new_counter_md(
|
||||||
|
MetricName::ApiTrafficSentBytes.as_str(),
|
||||||
|
"Total number of bytes sent",
|
||||||
|
&["type"]
|
||||||
|
);
|
||||||
|
|
||||||
|
pub static ref API_TRAFFIC_RECV_BYTES_MD: MetricDescriptor =
|
||||||
|
new_counter_md(
|
||||||
|
MetricName::ApiTrafficRecvBytes.as_str(),
|
||||||
|
"Total number of bytes received",
|
||||||
|
&["type"]
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ use handlers::{
|
|||||||
|
|
||||||
use hyper::Method;
|
use hyper::Method;
|
||||||
use router::{AdminOperation, S3Router};
|
use router::{AdminOperation, S3Router};
|
||||||
use rpc::regist_rpc_route;
|
use rpc::register_rpc_route;
|
||||||
use s3s::route::S3Route;
|
use s3s::route::S3Route;
|
||||||
|
|
||||||
const ADMIN_PREFIX: &str = "/rustfs/admin";
|
const ADMIN_PREFIX: &str = "/rustfs/admin";
|
||||||
@@ -24,7 +24,7 @@ pub fn make_admin_route() -> Result<impl S3Route> {
|
|||||||
// 1
|
// 1
|
||||||
r.insert(Method::POST, "/", AdminOperation(&sts::AssumeRoleHandle {}))?;
|
r.insert(Method::POST, "/", AdminOperation(&sts::AssumeRoleHandle {}))?;
|
||||||
|
|
||||||
regist_rpc_route(&mut r)?;
|
register_rpc_route(&mut r)?;
|
||||||
register_user_route(&mut r)?;
|
register_user_route(&mut r)?;
|
||||||
|
|
||||||
r.insert(
|
r.insert(
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ use tokio_util::io::StreamReader;
|
|||||||
|
|
||||||
pub const RPC_PREFIX: &str = "/rustfs/rpc";
|
pub const RPC_PREFIX: &str = "/rustfs/rpc";
|
||||||
|
|
||||||
pub fn regist_rpc_route(r: &mut S3Router<AdminOperation>) -> Result<()> {
|
pub fn register_rpc_route(r: &mut S3Router<AdminOperation>) -> Result<()> {
|
||||||
r.insert(
|
r.insert(
|
||||||
Method::GET,
|
Method::GET,
|
||||||
format!("{}{}", RPC_PREFIX, "/read_file_stream").as_str(),
|
format!("{}{}", RPC_PREFIX, "/read_file_stream").as_str(),
|
||||||
|
|||||||
Reference in New Issue
Block a user