This is an automated email from the ASF dual-hosted git repository.

xuanwo pushed a commit to branch xuanwo/layers-metrics-split
in repository https://gitbox.apache.org/repos/asf/opendal.git

commit 0fbb3e404c989f92b4f2ea27f309d77250dc2a05
Author: Xuanwo <[email protected]>
AuthorDate: Mon Dec 8 20:58:45 2025 +0800

    refactor: split metrics related crates to new crates
    
    Signed-off-by: Xuanwo <[email protected]>
---
 core/Cargo.lock                                    | 64 ++++++++++++++-
 core/Cargo.toml                                    | 19 +++--
 core/core/Cargo.toml                               | 18 -----
 core/core/src/layers/mod.rs                        | 33 --------
 core/core/src/layers/observe/mod.rs                | 93 ----------------------
 core/core/src/raw/http_util/body.rs                |  4 +-
 core/core/src/raw/http_util/client.rs              |  2 +-
 core/layers/fastmetrics/Cargo.toml                 | 36 +++++++++
 .../fastmetrics/src/lib.rs}                        | 16 ++--
 core/layers/metrics/Cargo.toml                     | 36 +++++++++
 .../metrics.rs => layers/metrics/src/lib.rs}       |  8 +-
 core/layers/observe-metrics-common/Cargo.toml      | 36 +++++++++
 .../observe-metrics-common/src/lib.rs}             | 62 ++++++++++++++-
 core/layers/otelmetrics/Cargo.toml                 | 36 +++++++++
 .../otelmetrics/src/lib.rs}                        | 12 +--
 core/layers/prometheus-client/Cargo.toml           | 36 +++++++++
 .../prometheus-client/src/lib.rs}                  | 12 +--
 core/layers/prometheus/Cargo.toml                  | 36 +++++++++
 .../prometheus.rs => layers/prometheus/src/lib.rs} | 20 ++---
 core/src/lib.rs                                    | 10 +++
 20 files changed, 393 insertions(+), 196 deletions(-)

diff --git a/core/Cargo.lock b/core/Cargo.lock
index baa1b2579..0170d4537 100644
--- a/core/Cargo.lock
+++ b/core/Cargo.lock
@@ -5478,6 +5478,12 @@ dependencies = [
  "opendal-layer-async-backtrace",
  "opendal-layer-await-tree",
  "opendal-layer-capability-check",
+ "opendal-layer-fastmetrics",
+ "opendal-layer-metrics",
+ "opendal-layer-observe-metrics-common",
+ "opendal-layer-otelmetrics",
+ "opendal-layer-prometheus",
+ "opendal-layer-prometheus-client",
  "opendal-service-aliyun-drive",
  "opendal-service-azblob",
  "opendal-service-azdls",
@@ -5541,7 +5547,6 @@ dependencies = [
  "divan",
  "dotenvy",
  "etcd-client",
- "fastmetrics",
  "fastpool",
  "fastrace",
  "fastrace-jaeger",
@@ -5562,7 +5567,6 @@ dependencies = [
  "log",
  "md-5",
  "mea",
- "metrics",
  "mime_guess",
  "mini-moka",
  "moka",
@@ -5579,8 +5583,6 @@ dependencies = [
  "persy",
  "pretty_assertions",
  "probe",
- "prometheus 0.14.0",
- "prometheus-client",
  "prost 0.13.5",
  "quick-xml",
  "rand 0.8.5",
@@ -5676,6 +5678,60 @@ dependencies = [
  "tokio",
 ]
 
+[[package]]
+name = "opendal-layer-fastmetrics"
+version = "0.55.0"
+dependencies = [
+ "fastmetrics",
+ "opendal-core",
+ "opendal-layer-observe-metrics-common",
+]
+
+[[package]]
+name = "opendal-layer-metrics"
+version = "0.55.0"
+dependencies = [
+ "metrics",
+ "opendal-core",
+ "opendal-layer-observe-metrics-common",
+]
+
+[[package]]
+name = "opendal-layer-observe-metrics-common"
+version = "0.55.0"
+dependencies = [
+ "futures",
+ "http 1.4.0",
+ "opendal-core",
+]
+
+[[package]]
+name = "opendal-layer-otelmetrics"
+version = "0.55.0"
+dependencies = [
+ "opendal-core",
+ "opendal-layer-observe-metrics-common",
+ "opentelemetry",
+]
+
+[[package]]
+name = "opendal-layer-prometheus"
+version = "0.55.0"
+dependencies = [
+ "opendal-core",
+ "opendal-layer-observe-metrics-common",
+ "prometheus 0.14.0",
+]
+
+[[package]]
+name = "opendal-layer-prometheus-client"
+version = "0.55.0"
+dependencies = [
+ "opendal-core",
+ "opendal-layer-observe-metrics-common",
+ "prometheus-client",
+]
+
 [[package]]
 name = "opendal-service-aliyun-drive"
 version = "0.55.0"
diff --git a/core/Cargo.toml b/core/Cargo.toml
index d087b0414..28b1c63db 100644
--- a/core/Cargo.toml
+++ b/core/Cargo.toml
@@ -27,8 +27,6 @@ members = [
   "services/aliyun-drive",
   "services/*",
   "layers/*",
-  "layers/await-tree",
-  "layers/capability-check",
 ]
 
 [workspace.package]
@@ -84,7 +82,6 @@ default = [
   "reqwest-rustls-tls",
   "executors-tokio",
   "services-memory",
-  "layers-capability-check",
 ]
 executors-tokio = ["opendal-core/executors-tokio"]
 internal-path-cache = ["opendal-core/internal-path-cache"]
@@ -94,14 +91,14 @@ layers-await-tree = ["dep:opendal-layer-await-tree"]
 layers-capability-check = ["dep:opendal-layer-capability-check"]
 layers-chaos = ["opendal-core/layers-chaos"]
 layers-dtrace = ["opendal-core/layers-dtrace"]
-layers-fastmetrics = ["opendal-core/layers-fastmetrics"]
+layers-fastmetrics = ["dep:opendal-layer-fastmetrics"]
 layers-fastrace = ["opendal-core/layers-fastrace"]
-layers-metrics = ["opendal-core/layers-metrics"]
+layers-metrics = ["dep:opendal-layer-metrics"]
 layers-mime-guess = ["opendal-core/layers-mime-guess"]
-layers-otel-metrics = ["opendal-core/layers-otel-metrics"]
+layers-otel-metrics = ["dep:opendal-layer-otelmetrics"]
 layers-otel-trace = ["opendal-core/layers-otel-trace"]
-layers-prometheus = ["opendal-core/layers-prometheus"]
-layers-prometheus-client = ["opendal-core/layers-prometheus-client"]
+layers-prometheus = ["dep:opendal-layer-prometheus"]
+layers-prometheus-client = ["dep:opendal-layer-prometheus-client"]
 layers-throttle = ["opendal-core/layers-throttle"]
 layers-tracing = ["opendal-core/layers-tracing"]
 reqwest-rustls-tls = ["opendal-core/reqwest-rustls-tls"]
@@ -193,6 +190,12 @@ opendal-core = { path = "core", version = "0.55.0", 
default-features = false }
 opendal-layer-async-backtrace = { path = "layers/async-backtrace", version = 
"0.55.0", optional = true, default-features = false }
 opendal-layer-await-tree = { path = "layers/await-tree", version = "0.55.0", 
optional = true, default-features = false }
 opendal-layer-capability-check = { path = "layers/capability-check", version = 
"0.55.0", optional = true, default-features = false }
+opendal-layer-observe-metrics-common = { path = 
"layers/observe-metrics-common", version = "0.55.0", optional = true, 
default-features = false }
+opendal-layer-metrics = { path = "layers/metrics", version = "0.55.0", 
optional = true, default-features = false }
+opendal-layer-otelmetrics = { path = "layers/otelmetrics", version = "0.55.0", 
optional = true, default-features = false }
+opendal-layer-prometheus = { path = "layers/prometheus", version = "0.55.0", 
optional = true, default-features = false }
+opendal-layer-prometheus-client = { path = "layers/prometheus-client", version 
= "0.55.0", optional = true, default-features = false }
+opendal-layer-fastmetrics = { path = "layers/fastmetrics", version = "0.55.0", 
optional = true, default-features = false }
 opendal-service-aliyun-drive = { path = "services/aliyun-drive", version = 
"0.55.0", optional = true, default-features = false }
 opendal-service-azblob = { path = "services/azblob", version = "0.55.0", 
optional = true, default-features = false }
 opendal-service-azdls = { path = "services/azdls", version = "0.55.0", 
optional = true, default-features = false }
diff --git a/core/core/Cargo.toml b/core/core/Cargo.toml
index a268c0478..375ecde7c 100644
--- a/core/core/Cargo.toml
+++ b/core/core/Cargo.toml
@@ -72,22 +72,12 @@ executors-tokio = ["tokio/rt"]
 
 # Enable layers chaos support
 layers-chaos = ["dep:rand"]
-# Enable layers metrics support
-layers-metrics = ["dep:metrics"]
 # Enable layers mime_guess support
 layers-mime-guess = ["dep:mime_guess"]
-# Enable layers prometheus support, with tikv/prometheus-rs crate
-layers-prometheus = ["dep:prometheus"]
-# Enable layers prometheus support, with prometheus-client crate
-layers-prometheus-client = ["dep:prometheus-client"]
-# Enable layers fastmetrics support.
-layers-fastmetrics = ["dep:fastmetrics"]
 # Enable layers fastrace support.
 layers-fastrace = ["dep:fastrace"]
 # Enable layers tracing support.
 layers-tracing = ["dep:tracing"]
-# Enable layers otelmetrics support.
-layers-otel-metrics = ["dep:opentelemetry", "opentelemetry/metrics"]
 # Enable layers oteltrace support.
 layers-otel-trace = ["dep:opentelemetry", "opentelemetry/trace"]
 # Enable layers throttle support.
@@ -325,20 +315,12 @@ web-sys = { version = "0.3.77", optional = true, features 
= [
 # Layers
 # for layers-throttle
 governor = { version = "0.10.1", optional = true, features = ["std"] }
-# for layers-metrics
-metrics = { version = "0.24", optional = true }
 # for layers-mime-guess
 mime_guess = { version = "2.0.5", optional = true }
 # for layers-fastrace
 fastrace = { version = "0.7.14", optional = true }
 # for layers-opentelemetry
 opentelemetry = { version = "0.31.0", optional = true }
-# for layers-prometheus
-prometheus = { version = "0.14", features = ["process"], optional = true }
-# for layers-prometheus-client
-prometheus-client = { version = "0.24", optional = true }
-# for fastmetrics
-fastmetrics = { version = "0.4.1", optional = true }
 # for layers-tracing
 tracing = { version = "0.1", optional = true }
 # for layers-dtrace
diff --git a/core/core/src/layers/mod.rs b/core/core/src/layers/mod.rs
index 85cccd55b..4b1012ff6 100644
--- a/core/core/src/layers/mod.rs
+++ b/core/core/src/layers/mod.rs
@@ -47,37 +47,11 @@ mod chaos;
 #[cfg(feature = "layers-chaos")]
 pub use chaos::ChaosLayer;
 
-#[cfg(feature = "layers-metrics")]
-mod metrics;
-#[cfg(feature = "layers-metrics")]
-pub use self::metrics::MetricsLayer;
-
 #[cfg(feature = "layers-mime-guess")]
 mod mime_guess;
 #[cfg(feature = "layers-mime-guess")]
 pub use self::mime_guess::MimeGuessLayer;
 
-#[cfg(feature = "layers-prometheus")]
-mod prometheus;
-#[cfg(feature = "layers-prometheus")]
-pub use self::prometheus::PrometheusLayer;
-#[cfg(feature = "layers-prometheus")]
-pub use self::prometheus::PrometheusLayerBuilder;
-
-#[cfg(feature = "layers-prometheus-client")]
-mod prometheus_client;
-#[cfg(feature = "layers-prometheus-client")]
-pub use self::prometheus_client::PrometheusClientLayer;
-#[cfg(feature = "layers-prometheus-client")]
-pub use self::prometheus_client::PrometheusClientLayerBuilder;
-
-#[cfg(feature = "layers-fastmetrics")]
-mod fastmetrics;
-#[cfg(feature = "layers-fastmetrics")]
-pub use self::fastmetrics::FastmetricsLayer;
-#[cfg(feature = "layers-fastmetrics")]
-pub use self::fastmetrics::FastmetricsLayerBuilder;
-
 mod retry;
 pub use self::retry::RetryInterceptor;
 pub use self::retry::RetryLayer;
@@ -96,11 +70,6 @@ mod fastrace;
 #[cfg(feature = "layers-fastrace")]
 pub use self::fastrace::FastraceLayer;
 
-#[cfg(feature = "layers-otel-metrics")]
-mod otelmetrics;
-#[cfg(feature = "layers-otel-metrics")]
-pub use self::otelmetrics::OtelMetricsLayer;
-
 #[cfg(feature = "layers-otel-trace")]
 mod oteltrace;
 #[cfg(feature = "layers-otel-trace")]
@@ -116,8 +85,6 @@ mod dtrace;
 #[cfg(all(target_os = "linux", feature = "layers-dtrace"))]
 pub use self::dtrace::DtraceLayer;
 
-pub mod observe;
-
 mod correctness_check;
 pub(crate) use correctness_check::CorrectnessCheckLayer;
 
diff --git a/core/core/src/layers/observe/mod.rs 
b/core/core/src/layers/observe/mod.rs
deleted file mode 100644
index 7837e1e33..000000000
--- a/core/core/src/layers/observe/mod.rs
+++ /dev/null
@@ -1,93 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-//! OpenDAL Observability
-//!
-//! This module offers essential components to facilitate the implementation 
of observability in OpenDAL.
-//!
-//! # OpenDAL Metrics Reference
-//!
-//! This document describes all metrics exposed by OpenDAL.
-//!
-//! ## Operation Metrics
-//!
-//! These metrics track operations at the storage abstraction level.
-//!
-//! | Metric Name                      | Type      | Description               
                                                                 | Labels       
                                   |
-//! 
|----------------------------------|-----------|--------------------------------------------------------------------------------------------|-------------------------------------------------|
-//! | operation_bytes                  | Histogram | Current operation size in 
bytes, represents the size of data being processed               | scheme, 
namespace, root, operation, path        |
-//! | operation_bytes_rate             | Histogram | Histogram of data 
processing rates in bytes per second within individual operations        | 
scheme, namespace, root, operation, path        |
-//! | operation_entries                | Histogram | Current operation size in 
entries, represents the entries being processed                  | scheme, 
namespace, root, operation, path        |
-//! | operation_entries_rate           | Histogram | Histogram of entries 
processing rates in entries per second within individual operations   | scheme, 
namespace, root, operation, path        |
-//! | operation_duration_seconds       | Histogram | Duration of operations in 
seconds, measured from start to completion                       | scheme, 
namespace, root, operation, path        |
-//! | operation_errors_total           | Counter   | Total number of failed 
operations                                                         | scheme, 
namespace, root, operation, path, error |
-//! | operation_executing              | Gauge     | Number of operations 
currently being executed                                             | scheme, 
namespace, root, operation              |
-//! | operation_ttfb_seconds           | Histogram | Time to first byte in 
seconds for operations                                              | scheme, 
namespace, root, operation, path        |
-//!
-//! ## HTTP Metrics
-//!
-//! These metrics track the underlying HTTP requests made by OpenDAL services 
that use HTTP.
-//!
-//! | Metric Name                      | Type      | Description               
                                                                 | Labels       
                                   |
-//! 
|----------------------------------|-----------|--------------------------------------------------------------------------------------------|-------------------------------------------------|
-//! | http_connection_errors_total     | Counter   | Total number of HTTP 
requests that failed before receiving a response                      | scheme, 
namespace, root, operation, error       |
-//! | http_status_errors_total         | Counter   | Total number of HTTP 
requests that received error status codes (non-2xx responses)         | scheme, 
namespace, root, operation, status      |
-//! | http_executing                   | Gauge     | Number of HTTP requests 
currently in flight from this client                              | scheme, 
namespace, root                         |
-//! | http_request_bytes               | Histogram | Histogram of HTTP request 
body sizes in bytes                                             | scheme, 
namespace, root, operation              |
-//! | http_request_bytes_rate          | Histogram | Histogram of HTTP request 
bytes per second rates                                          | scheme, 
namespace, root, operation              |
-//! | http_request_duration_seconds    | Histogram | Histogram of time spent 
sending HTTP requests, from first byte sent to first byte received | scheme, 
namespace, root, operation              |
-//! | http_response_bytes              | Histogram | Histogram of HTTP 
response body sizes in bytes                                            | 
scheme, namespace, root, operation              |
-//! | http_response_bytes_rate         | Histogram | Histogram of HTTP 
response bytes per second rates                                         | 
scheme, namespace, root, operation              |
-//! | http_response_duration_seconds   | Histogram | Histogram of time spent 
receiving HTTP responses, from first byte to last byte received   | scheme, 
namespace, root, operation              |
-//!
-//! ## Label Descriptions
-//!
-//! | Label     | Description                                                  
 | Example Values                         |
-//! 
|-----------|---------------------------------------------------------------|----------------------------------------|
-//! | scheme    | The storage service scheme                                   
 | s3, gcs, azblob, fs, memory            |
-//! | namespace | The storage service namespace (bucket, container, etc.)      
 | my-bucket, my-container                |
-//! | root      | The root path within the namespace                           
 | /data, /backup                         |
-//! | operation | The operation being performed                                
 | read, write, stat, list, delete        |
-//! | path      | The path of the object being operated on                     
 | /path/to/file.txt                      |
-//! | error     | The error type or message for error metrics                  
 | not_found, permission_denied           |
-//! | status    | The HTTP status code for HTTP error metrics                  
 | 404, 403, 500                          |
-//!
-//! ## Metric Types
-//!
-//! * **Histogram**: Distribution of values with configurable buckets, 
includes count, sum and quantiles
-//! * **Counter**: Cumulative metric that only increases over time (resets on 
restart)
-//! * **Gauge**: Point-in-time metric that can increase and decrease
-
-mod metrics;
-
-pub use metrics::DEFAULT_BYTES_BUCKETS;
-pub use metrics::DEFAULT_BYTES_RATE_BUCKETS;
-pub use metrics::DEFAULT_DURATION_SECONDS_BUCKETS;
-pub use metrics::DEFAULT_ENTRIES_BUCKETS;
-pub use metrics::DEFAULT_ENTRIES_RATE_BUCKETS;
-pub use metrics::DEFAULT_TTFB_BUCKETS;
-pub use metrics::LABEL_ERROR;
-pub use metrics::LABEL_NAMESPACE;
-pub use metrics::LABEL_OPERATION;
-pub use metrics::LABEL_ROOT;
-pub use metrics::LABEL_SCHEME;
-pub use metrics::LABEL_STATUS_CODE;
-pub use metrics::MetricLabels;
-pub use metrics::MetricValue;
-pub use metrics::MetricsAccessor;
-pub use metrics::MetricsIntercept;
-pub use metrics::MetricsLayer;
diff --git a/core/core/src/raw/http_util/body.rs 
b/core/core/src/raw/http_util/body.rs
index 34b1a22e5..f694633db 100644
--- a/core/core/src/raw/http_util/body.rs
+++ b/core/core/src/raw/http_util/body.rs
@@ -76,7 +76,7 @@ impl HttpBody {
 
     /// Map the inner stream.
     #[cfg(not(target_arch = "wasm32"))]
-    pub(crate) fn map_inner(
+    pub fn map_inner(
         mut self,
         f: impl FnOnce(
             Box<dyn Stream<Item = Result<Buffer>> + Send + Sync + Unpin + 
'static>,
@@ -89,7 +89,7 @@ impl HttpBody {
 
     /// Map the inner stream.
     #[cfg(target_arch = "wasm32")]
-    pub(crate) fn map_inner(
+    pub fn map_inner(
         mut self,
         f: impl FnOnce(
             Box<dyn Stream<Item = Result<Buffer>> + Unpin + 'static>,
diff --git a/core/core/src/raw/http_util/client.rs 
b/core/core/src/raw/http_util/client.rs
index f00c47443..abab39396 100644
--- a/core/core/src/raw/http_util/client.rs
+++ b/core/core/src/raw/http_util/client.rs
@@ -91,7 +91,7 @@ impl HttpClient {
     }
 
     /// Get the inner http client.
-    pub(crate) fn into_inner(self) -> HttpFetcher {
+    pub fn into_inner(self) -> HttpFetcher {
         self.fetcher
     }
 
diff --git a/core/layers/fastmetrics/Cargo.toml 
b/core/layers/fastmetrics/Cargo.toml
new file mode 100644
index 000000000..c60193292
--- /dev/null
+++ b/core/layers/fastmetrics/Cargo.toml
@@ -0,0 +1,36 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+[package]
+description = "Apache OpenDAL metrics layer using fastmetrics"
+name = "opendal-layer-fastmetrics"
+
+authors = { workspace = true }
+edition = { workspace = true }
+homepage = { workspace = true }
+license = { workspace = true }
+repository = { workspace = true }
+rust-version = { workspace = true }
+version = { workspace = true }
+
+[package.metadata.docs.rs]
+all-features = true
+
+[dependencies]
+fastmetrics = { version = "0.4.1" }
+opendal-core = { path = "../../core", version = "0.55.0", default-features = 
false }
+opendal-layer-observe-metrics-common = { path = "../observe-metrics-common", 
version = "0.55.0", default-features = false }
diff --git a/core/core/src/layers/fastmetrics.rs 
b/core/layers/fastmetrics/src/lib.rs
similarity index 98%
rename from core/core/src/layers/fastmetrics.rs
rename to core/layers/fastmetrics/src/lib.rs
index f3a9f00a7..d6b03f774 100644
--- a/core/core/src/layers/fastmetrics.rs
+++ b/core/layers/fastmetrics/src/lib.rs
@@ -28,10 +28,9 @@ use fastmetrics::registry::Register;
 use fastmetrics::registry::Registry;
 use fastmetrics::registry::RegistryError;
 use fastmetrics::registry::with_global_registry_mut;
-
-use crate::layers::observe;
-use crate::raw::*;
-use crate::*;
+use opendal_core::raw::*;
+use opendal_core::*;
+use opendal_layer_observe_metrics_common as observe;
 
 /// Add [fastmetrics](https://docs.rs/fastmetrics/) for every operation.
 ///
@@ -42,7 +41,7 @@ use crate::*;
 /// ```no_run
 /// # use fastmetrics::format::text;
 /// # use log::info;
-/// # use opendal_core::layers::FastmetricsLayer;
+/// # use opendal_layer_fastmetrics::FastmetricsLayer;
 /// # use opendal_core::services;
 /// # use opendal_core::Operator;
 /// # use opendal_core::Result;
@@ -87,7 +86,7 @@ use crate::*;
 /// # use fastmetrics::format::text;
 /// # use fastmetrics::registry::with_global_registry;
 /// # use log::info;
-/// # use opendal_core::layers::FastmetricsLayer;
+/// # use opendal_layer_fastmetrics::FastmetricsLayer;
 /// # use opendal_core::services;
 /// # use opendal_core::Operator;
 /// # use opendal_core::Result;
@@ -230,7 +229,7 @@ impl FastmetricsLayerBuilder {
     /// # Example
     ///
     /// ```no_run
-    /// # use opendal_core::layers::FastmetricsLayer;
+    /// # use opendal_layer_fastmetrics::FastmetricsLayer;
     /// # use opendal_core::services;
     /// # use opendal_core::Operator;
     /// # use opendal_core::Result;
@@ -325,7 +324,7 @@ impl FastmetricsLayerBuilder {
     /// # Example
     ///
     /// ```no_run
-    /// # use opendal_core::layers::FastmetricsLayer;
+    /// # use opendal_layer_fastmetrics::FastmetricsLayer;
     /// # use opendal_core::services;
     /// # use opendal_core::Operator;
     /// # use opendal_core::Result;
@@ -495,6 +494,7 @@ impl observe::MetricsIntercept for FastmetricsInterceptor {
                 self.http_status_errors_total
                     .with_or_new(&labels, |counter| counter.inc());
             }
+            _ => {}
         };
     }
 }
diff --git a/core/layers/metrics/Cargo.toml b/core/layers/metrics/Cargo.toml
new file mode 100644
index 000000000..8461ebff6
--- /dev/null
+++ b/core/layers/metrics/Cargo.toml
@@ -0,0 +1,36 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+[package]
+description = "Apache OpenDAL metrics layer built on metrics crate"
+name = "opendal-layer-metrics"
+
+authors = { workspace = true }
+edition = { workspace = true }
+homepage = { workspace = true }
+license = { workspace = true }
+repository = { workspace = true }
+rust-version = { workspace = true }
+version = { workspace = true }
+
+[package.metadata.docs.rs]
+all-features = true
+
+[dependencies]
+metrics = "0.24"
+opendal-core = { path = "../../core", version = "0.55.0", default-features = 
false }
+opendal-layer-observe-metrics-common = { path = "../observe-metrics-common", 
version = "0.55.0", default-features = false }
diff --git a/core/core/src/layers/metrics.rs b/core/layers/metrics/src/lib.rs
similarity index 97%
rename from core/core/src/layers/metrics.rs
rename to core/layers/metrics/src/lib.rs
index 6de9bc347..2d098d5f5 100644
--- a/core/core/src/layers/metrics.rs
+++ b/core/layers/metrics/src/lib.rs
@@ -19,9 +19,8 @@ use metrics::Label;
 use metrics::counter;
 use metrics::gauge;
 use metrics::histogram;
-
-use crate::layers::observe;
-use crate::raw::*;
+use opendal_core::raw::*;
+use opendal_layer_observe_metrics_common as observe;
 
 /// Add [metrics](https://docs.rs/metrics/) for every operation.
 ///
@@ -38,7 +37,7 @@ use crate::raw::*;
 /// # Examples
 ///
 /// ```no_run
-/// # use opendal_core::layers::MetricsLayer;
+/// # use opendal_layer_metrics::MetricsLayer;
 /// # use opendal_core::services;
 /// # use opendal_core::Operator;
 /// # use opendal_core::Result;
@@ -148,6 +147,7 @@ impl observe::MetricsIntercept for MetricsInterceptor {
             observe::MetricValue::HttpStatusErrorsTotal => {
                 counter!(value.name(), labels).increment(1)
             }
+            _ => {}
         }
     }
 }
diff --git a/core/layers/observe-metrics-common/Cargo.toml 
b/core/layers/observe-metrics-common/Cargo.toml
new file mode 100644
index 000000000..5206cd453
--- /dev/null
+++ b/core/layers/observe-metrics-common/Cargo.toml
@@ -0,0 +1,36 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+[package]
+description = "Apache OpenDAL observe metrics common components"
+name = "opendal-layer-observe-metrics-common"
+
+authors = { workspace = true }
+edition = { workspace = true }
+homepage = { workspace = true }
+license = { workspace = true }
+repository = { workspace = true }
+rust-version = { workspace = true }
+version = { workspace = true }
+
+[package.metadata.docs.rs]
+all-features = true
+
+[dependencies]
+futures = { version = "0.3", default-features = false, features = ["std", 
"async-await"] }
+http = { workspace = true }
+opendal-core = { path = "../../core", version = "0.55.0", default-features = 
false }
diff --git a/core/core/src/layers/observe/metrics.rs 
b/core/layers/observe-metrics-common/src/lib.rs
similarity index 85%
rename from core/core/src/layers/observe/metrics.rs
rename to core/layers/observe-metrics-common/src/lib.rs
index 82f390453..d03480204 100644
--- a/core/core/src/layers/observe/metrics.rs
+++ b/core/layers/observe-metrics-common/src/lib.rs
@@ -15,6 +15,63 @@
 // specific language governing permissions and limitations
 // under the License.
 
+//! OpenDAL Observability
+//!
+//! This module offers essential components to facilitate the implementation 
of observability in OpenDAL.
+//!
+//! # OpenDAL Metrics Reference
+//!
+//! This document describes all metrics exposed by OpenDAL.
+//!
+//! ## Operation Metrics
+//!
+//! These metrics track operations at the storage abstraction level.
+//!
+//! | Metric Name                      | Type      | Description               
                                                                 | Labels       
                                   |
+//! 
|----------------------------------|-----------|--------------------------------------------------------------------------------------------|-------------------------------------------------|
+//! | operation_bytes                  | Histogram | Current operation size in 
bytes, represents the size of data being processed               | scheme, 
namespace, root, operation, path        |
+//! | operation_bytes_rate             | Histogram | Histogram of data 
processing rates in bytes per second within individual operations        | 
scheme, namespace, root, operation, path        |
+//! | operation_entries                | Histogram | Current operation size in 
entries, represents the entries being processed                  | scheme, 
namespace, root, operation, path        |
+//! | operation_entries_rate           | Histogram | Histogram of entries 
processing rates in entries per second within individual operations   | scheme, 
namespace, root, operation, path        |
+//! | operation_duration_seconds       | Histogram | Duration of operations in 
seconds, measured from start to completion                       | scheme, 
namespace, root, operation, path        |
+//! | operation_errors_total           | Counter   | Total number of failed 
operations                                                         | scheme, 
namespace, root, operation, path, error |
+//! | operation_executing              | Gauge     | Number of operations 
currently being executed                                             | scheme, 
namespace, root, operation              |
+//! | operation_ttfb_seconds           | Histogram | Time to first byte in 
seconds for operations                                              | scheme, 
namespace, root, operation, path        |
+//!
+//! ## HTTP Metrics
+//!
+//! These metrics track the underlying HTTP requests made by OpenDAL services 
that use HTTP.
+//!
+//! | Metric Name                      | Type      | Description               
                                                                 | Labels       
                                   |
+//! 
|----------------------------------|-----------|--------------------------------------------------------------------------------------------|-------------------------------------------------|
+//! | http_connection_errors_total     | Counter   | Total number of HTTP 
requests that failed before receiving a response                      | scheme, 
namespace, root, operation, error       |
+//! | http_status_errors_total         | Counter   | Total number of HTTP 
requests that received error status codes (non-2xx responses)         | scheme, 
namespace, root, operation, status      |
+//! | http_executing                   | Gauge     | Number of HTTP requests 
currently in flight from this client                              | scheme, 
namespace, root                         |
+//! | http_request_bytes               | Histogram | Histogram of HTTP request 
body sizes in bytes                                             | scheme, 
namespace, root, operation              |
+//! | http_request_bytes_rate          | Histogram | Histogram of HTTP request 
bytes per second rates                                          | scheme, 
namespace, root, operation              |
+//! | http_request_duration_seconds    | Histogram | Histogram of time spent 
sending HTTP requests, from first byte sent to first byte received | scheme, 
namespace, root, operation              |
+//! | http_response_bytes              | Histogram | Histogram of HTTP 
response body sizes in bytes                                            | 
scheme, namespace, root, operation              |
+//! | http_response_bytes_rate         | Histogram | Histogram of HTTP 
response bytes per second rates                                         | 
scheme, namespace, root, operation              |
+//! | http_response_duration_seconds   | Histogram | Histogram of time spent 
receiving HTTP responses, from first byte to last byte received   | scheme, 
namespace, root, operation              |
+//!
+//! ## Label Descriptions
+//!
+//! | Label     | Description                                                  
 | Example Values                         |
+//! 
|-----------|---------------------------------------------------------------|----------------------------------------|
+//! | scheme    | The storage service scheme                                   
 | s3, gcs, azblob, fs, memory            |
+//! | namespace | The storage service namespace (bucket, container, etc.)      
 | my-bucket, my-container                |
+//! | root      | The root path within the namespace                           
 | /data, /backup                         |
+//! | operation | The operation being performed                                
 | read, write, stat, list, delete        |
+//! | path      | The path of the object being operated on                     
 | /path/to/file.txt                      |
+//! | error     | The error type or message for error metrics                  
 | not_found, permission_denied           |
+//! | status    | The HTTP status code for HTTP error metrics                  
 | 404, 403, 500                          |
+//!
+//! ## Metric Types
+//!
+//! * **Histogram**: Distribution of values with configurable buckets, 
includes count, sum and quantiles
+//! * **Counter**: Cumulative metric that only increases over time (resets on 
restart)
+//! * **Gauge**: Point-in-time metric that can increase and decrease
+
 use std::fmt::Debug;
 use std::fmt::Formatter;
 use std::pin::Pin;
@@ -26,9 +83,8 @@ use std::task::ready;
 use futures::Stream;
 use futures::StreamExt;
 use http::StatusCode;
-
-use crate::raw::*;
-use crate::*;
+use opendal_core::raw::*;
+use opendal_core::*;
 
 const KIB: f64 = 1024.0;
 const MIB: f64 = 1024.0 * KIB;
diff --git a/core/layers/otelmetrics/Cargo.toml 
b/core/layers/otelmetrics/Cargo.toml
new file mode 100644
index 000000000..3441b07a1
--- /dev/null
+++ b/core/layers/otelmetrics/Cargo.toml
@@ -0,0 +1,36 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+[package]
+description = "Apache OpenDAL OpenTelemetry metrics layer"
+name = "opendal-layer-otelmetrics"
+
+authors = { workspace = true }
+edition = { workspace = true }
+homepage = { workspace = true }
+license = { workspace = true }
+repository = { workspace = true }
+rust-version = { workspace = true }
+version = { workspace = true }
+
+[package.metadata.docs.rs]
+all-features = true
+
+[dependencies]
+opendal-core = { path = "../../core", version = "0.55.0", default-features = 
false }
+opendal-layer-observe-metrics-common = { path = "../observe-metrics-common", 
version = "0.55.0", default-features = false }
+opentelemetry = { version = "0.31.0", default-features = false, features = 
["metrics"] }
diff --git a/core/core/src/layers/otelmetrics.rs 
b/core/layers/otelmetrics/src/lib.rs
similarity index 98%
rename from core/core/src/layers/otelmetrics.rs
rename to core/layers/otelmetrics/src/lib.rs
index cd4962abb..5b084a59c 100644
--- a/core/core/src/layers/otelmetrics.rs
+++ b/core/layers/otelmetrics/src/lib.rs
@@ -15,21 +15,20 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use opendal_core::raw::*;
+use opendal_layer_observe_metrics_common as observe;
 use opentelemetry::KeyValue;
 use opentelemetry::metrics::Counter;
 use opentelemetry::metrics::Histogram;
 use opentelemetry::metrics::Meter;
 use opentelemetry::metrics::UpDownCounter;
 
-use crate::layers::observe;
-use crate::raw::*;
-
 /// Add 
[opentelemetry::metrics](https://docs.rs/opentelemetry/latest/opentelemetry/metrics/index.html)
 for every operation.
 ///
 /// # Examples
 ///
 /// ```no_run
-/// # use opendal_core::layers::OtelMetricsLayer;
+/// # use opendal_layer_otelmetrics::OtelMetricsLayer;
 /// # use opendal_core::services;
 /// # use opendal_core::Operator;
 /// # use opendal_core::Result;
@@ -53,7 +52,7 @@ impl OtelMetricsLayer {
     /// # Examples
     ///
     /// ```no_run
-    /// # use opendal_core::layers::OtelMetricsLayer;
+    /// # use opendal_layer_otelmetrics::OtelMetricsLayer;
     /// # use opendal_core::services;
     /// # use opendal_core::Operator;
     /// # use opendal_core::Result;
@@ -150,7 +149,7 @@ impl OtelMetricsLayerBuilder {
     /// # Examples
     ///
     /// ```no_run
-    /// # use opendal_core::layers::OtelMetricsLayer;
+    /// # use opendal_layer_otelmetrics::OtelMetricsLayer;
     /// # use opendal_core::services;
     /// # use opendal_core::Operator;
     /// # use opendal_core::Result;
@@ -421,6 +420,7 @@ impl observe::MetricsIntercept for OtelMetricsInterceptor {
             observe::MetricValue::HttpStatusErrorsTotal => {
                 self.http_status_errors_total.add(1, &attributes)
             }
+            _ => {}
         }
     }
 }
diff --git a/core/layers/prometheus-client/Cargo.toml 
b/core/layers/prometheus-client/Cargo.toml
new file mode 100644
index 000000000..2fe48a82a
--- /dev/null
+++ b/core/layers/prometheus-client/Cargo.toml
@@ -0,0 +1,36 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+[package]
+description = "Apache OpenDAL metrics layer using prometheus-client"
+name = "opendal-layer-prometheus-client"
+
+authors = { workspace = true }
+edition = { workspace = true }
+homepage = { workspace = true }
+license = { workspace = true }
+repository = { workspace = true }
+rust-version = { workspace = true }
+version = { workspace = true }
+
+[package.metadata.docs.rs]
+all-features = true
+
+[dependencies]
+opendal-core = { path = "../../core", version = "0.55.0", default-features = 
false }
+opendal-layer-observe-metrics-common = { path = "../observe-metrics-common", 
version = "0.55.0", default-features = false }
+prometheus-client = { version = "0.24" }
diff --git a/core/core/src/layers/prometheus_client.rs 
b/core/layers/prometheus-client/src/lib.rs
similarity index 98%
rename from core/core/src/layers/prometheus_client.rs
rename to core/layers/prometheus-client/src/lib.rs
index 1198cd582..85f31848b 100644
--- a/core/core/src/layers/prometheus_client.rs
+++ b/core/layers/prometheus-client/src/lib.rs
@@ -17,6 +17,9 @@
 
 use std::fmt;
 
+use opendal_core::raw::*;
+use opendal_core::*;
+use opendal_layer_observe_metrics_common as observe;
 use prometheus_client::encoding::EncodeLabel;
 use prometheus_client::encoding::EncodeLabelSet;
 use prometheus_client::encoding::LabelSetEncoder;
@@ -29,10 +32,6 @@ use prometheus_client::registry::Metric;
 use prometheus_client::registry::Registry;
 use prometheus_client::registry::Unit;
 
-use crate::layers::observe;
-use crate::raw::*;
-use crate::*;
-
 /// Add [prometheus-client](https://docs.rs/prometheus-client) for every 
operation.
 ///
 /// # Prometheus Metrics
@@ -44,7 +43,7 @@ use crate::*;
 ///
 /// ```no_run
 /// # use log::info;
-/// # use opendal_core::layers::PrometheusClientLayer;
+/// # use opendal_layer_prometheus_client::PrometheusClientLayer;
 /// # use opendal_core::services;
 /// # use opendal_core::Operator;
 /// # use opendal_core::Result;
@@ -181,7 +180,7 @@ impl PrometheusClientLayerBuilder {
     /// # Example
     ///
     /// ```no_run
-    /// # use opendal_core::layers::PrometheusClientLayer;
+    /// # use opendal_layer_prometheus_client::PrometheusClientLayer;
     /// # use opendal_core::services;
     /// # use opendal_core::Operator;
     /// # use opendal_core::Result;
@@ -477,6 +476,7 @@ impl observe::MetricsIntercept for 
PrometheusClientInterceptor {
             observe::MetricValue::HttpStatusErrorsTotal => {
                 self.http_status_errors_total.get_or_create(&labels).inc();
             }
+            _ => {}
         };
     }
 }
diff --git a/core/layers/prometheus/Cargo.toml 
b/core/layers/prometheus/Cargo.toml
new file mode 100644
index 000000000..45f588a22
--- /dev/null
+++ b/core/layers/prometheus/Cargo.toml
@@ -0,0 +1,36 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+[package]
+description = "Apache OpenDAL Prometheus metrics layer"
+name = "opendal-layer-prometheus"
+
+authors = { workspace = true }
+edition = { workspace = true }
+homepage = { workspace = true }
+license = { workspace = true }
+repository = { workspace = true }
+rust-version = { workspace = true }
+version = { workspace = true }
+
+[package.metadata.docs.rs]
+all-features = true
+
+[dependencies]
+opendal-core = { path = "../../core", version = "0.55.0", default-features = 
false }
+opendal-layer-observe-metrics-common = { path = "../observe-metrics-common", 
version = "0.55.0", default-features = false }
+prometheus = { version = "0.14", features = ["process"] }
diff --git a/core/core/src/layers/prometheus.rs 
b/core/layers/prometheus/src/lib.rs
similarity index 98%
rename from core/core/src/layers/prometheus.rs
rename to core/layers/prometheus/src/lib.rs
index eb6dfae4a..003e3d5ed 100644
--- a/core/core/src/layers/prometheus.rs
+++ b/core/layers/prometheus/src/lib.rs
@@ -15,6 +15,10 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use opendal_core::raw::Access;
+use opendal_core::raw::*;
+use opendal_core::*;
+use opendal_layer_observe_metrics_common as observe;
 use prometheus::HistogramVec;
 use prometheus::Registry;
 use prometheus::core::AtomicI64;
@@ -25,11 +29,6 @@ use prometheus::register_histogram_vec_with_registry;
 use prometheus::register_int_counter_vec_with_registry;
 use prometheus::register_int_gauge_vec_with_registry;
 
-use crate::layers::observe;
-use crate::raw::Access;
-use crate::raw::*;
-use crate::*;
-
 /// Add [prometheus](https://docs.rs/prometheus) for every operation.
 ///
 /// # Prometheus Metrics
@@ -43,7 +42,7 @@ use crate::*;
 ///
 /// ```no_run
 /// # use log::info;
-/// # use opendal_core::layers::PrometheusLayer;
+/// # use opendal_layer_prometheus::PrometheusLayer;
 /// # use opendal_core::services;
 /// # use opendal_core::Operator;
 /// # use opendal_core::Result;
@@ -94,7 +93,7 @@ use crate::*;
 /// ```no_run
 /// # use std::sync::OnceLock;
 /// # use log::info;
-/// # use opendal_core::layers::PrometheusLayer;
+/// # use opendal_layer_prometheus::PrometheusLayer;
 /// # use opendal_core::services;
 /// # use opendal_core::Operator;
 /// # use opendal_core::Result;
@@ -146,7 +145,7 @@ impl PrometheusLayer {
     /// # Example
     ///
     /// ```no_run
-    /// # use opendal_core::layers::PrometheusLayer;
+    /// # use opendal_layer_prometheus::PrometheusLayer;
     /// # use opendal_core::services;
     /// # use opendal_core::Operator;
     /// # use opendal_core::Result;
@@ -261,7 +260,7 @@ impl PrometheusLayerBuilder {
     /// # Example
     ///
     /// ```no_run
-    /// # use opendal_core::layers::PrometheusLayer;
+    /// # use opendal_layer_prometheus::PrometheusLayer;
     /// # use opendal_core::services;
     /// # use opendal_core::Operator;
     /// # use opendal_core::Result;
@@ -499,7 +498,7 @@ impl PrometheusLayerBuilder {
     /// # Example
     ///
     /// ```no_run
-    /// # use opendal_core::layers::PrometheusLayer;
+    /// # use opendal_layer_prometheus::PrometheusLayer;
     /// # use opendal_core::services;
     /// # use opendal_core::Operator;
     /// # use opendal_core::Result;
@@ -624,6 +623,7 @@ impl observe::MetricsIntercept for PrometheusInterceptor {
                 .http_status_errors_total
                 .with_label_values(&labels.values())
                 .inc(),
+            _ => {}
         }
     }
 }
diff --git a/core/src/lib.rs b/core/src/lib.rs
index c6872d9c7..f4604e167 100644
--- a/core/src/lib.rs
+++ b/core/src/lib.rs
@@ -52,4 +52,14 @@ pub mod layers {
     pub use opendal_layer_await_tree::*;
     #[cfg(feature = "layers-capability-check")]
     pub use opendal_layer_capability_check::*;
+    #[cfg(feature = "layers-fastmetrics")]
+    pub use opendal_layer_fastmetrics::*;
+    #[cfg(feature = "layers-metrics")]
+    pub use opendal_layer_metrics::*;
+    #[cfg(feature = "layers-otel-metrics")]
+    pub use opendal_layer_otelmetrics::*;
+    #[cfg(feature = "layers-prometheus")]
+    pub use opendal_layer_prometheus::*;
+    #[cfg(feature = "layers-prometheus-client")]
+    pub use opendal_layer_prometheus_client::*;
 }


Reply via email to