add metric

This commit is contained in:
houseme
2025-05-13 09:17:52 +08:00
parent 76e38526c6
commit cdd285dec8
16 changed files with 666 additions and 7 deletions
Generated
+1 -1
View File
@@ -7347,7 +7347,6 @@ dependencies = [
"axum",
"config",
"dotenvy",
"http",
"rdkafka",
"reqwest",
"rumqttc",
@@ -7391,6 +7390,7 @@ dependencies = [
"async-trait",
"chrono",
"config",
"lazy_static",
"local-ip-address",
"nvml-wrapper",
"opentelemetry",
-2
View File
@@ -113,5 +113,3 @@ export RUSTFS_OBS_CONFIG="./deploy/config/obs.toml"
| use_stdout | 是否输出到控制台 | true/false |
| logger_level | 日志级别 | info |
| local_logging_enable | 控制台是否答应日志 | true/false |
```
-1
View File
@@ -35,7 +35,6 @@ rdkafka = { workspace = true, features = ["tokio"], optional = true }
[dev-dependencies]
tokio = { workspace = true, features = ["test-util"] }
tracing-subscriber = { workspace = true }
http = { workspace = true }
axum = { workspace = true }
dotenvy = "0.15.7"
+1
View File
@@ -21,6 +21,7 @@ rustfs-config = { workspace = true }
async-trait = { workspace = true }
chrono = { workspace = true }
config = { workspace = true }
lazy_static = { workspace = true }
local-ip-address = { workspace = true }
nvml-wrapper = { workspace = true, optional = true }
opentelemetry = { workspace = true }
+1
View File
@@ -32,6 +32,7 @@ mod config;
mod entry;
mod global;
mod logger;
mod metrics;
mod sinks;
mod system;
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()
}
}
+321
View File
@@ -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 值
}
}
}
+32
View File
@@ -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(),
)
}
+25
View File
@@ -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",
}
}
}
+79
View File
@@ -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",
}
}
}
+10
View File
@@ -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};
+109
View File
@@ -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"]
);
}
+2 -2
View File
@@ -13,7 +13,7 @@ use handlers::{
use hyper::Method;
use router::{AdminOperation, S3Router};
use rpc::regist_rpc_route;
use rpc::register_rpc_route;
use s3s::route::S3Route;
const ADMIN_PREFIX: &str = "/rustfs/admin";
@@ -24,7 +24,7 @@ pub fn make_admin_route() -> Result<impl S3Route> {
// 1
r.insert(Method::POST, "/", AdminOperation(&sts::AssumeRoleHandle {}))?;
regist_rpc_route(&mut r)?;
register_rpc_route(&mut r)?;
register_user_route(&mut r)?;
r.insert(
+1 -1
View File
@@ -22,7 +22,7 @@ use tokio_util::io::StreamReader;
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(
Method::GET,
format!("{}{}", RPC_PREFIX, "/read_file_stream").as_str(),