1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
// 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 Layer
//!
//! This module offers essential components to facilitate the implementation of observability in OpenDAL.
//!
//! # Prometheus Metrics
//!
//! These metrics are essential for understanding the behavior and performance of our applications.
//!
//! | Metric Name | Type | Description | Labels |
//! |------------------------------|-----------|--------------------------------------------------------------|-------------------------------------------------|
//! | operation_duration_seconds | Histogram | Histogram of time spent during opendal operations | scheme, namespace, root, operation, path |
//! | operation_bytes. | Histogram | Histogram of the bytes transferred during opendal operations | scheme, operation, root, operation, path |
//! | operation_errors_total | Counter | Error counter during opendal operations | scheme, operation, root, operation, path, error |
mod metrics;
pub use metrics::MetricMetadata;
pub use metrics::MetricsAccessor;
pub use metrics::MetricsIntercept;
pub use metrics::MetricsLayer;
pub use metrics::LABEL_ERROR;
pub use metrics::LABEL_NAMESPACE;
pub use metrics::LABEL_OPERATION;
pub use metrics::LABEL_PATH;
pub use metrics::LABEL_ROOT;
pub use metrics::LABEL_SCHEME;
pub use metrics::METRIC_OPERATION_BYTES;
pub use metrics::METRIC_OPERATION_DURATION_SECONDS;
pub use metrics::METRIC_OPERATION_ERRORS_TOTAL;
/// Return the path label value according to the given `path` and `level`.
///
/// - level = 0: return `None`, which means we ignore the path label.
/// - level > 0: the path label will be the path split by "/" and get the last n level,
/// if n=1 and input path is "abc/def/ghi", and then we'll use "abc/" as the path label.
pub fn path_label_value(path: &str, level: usize) -> Option<&str> {
if level > 0 {
if path.is_empty() {
return Some("");
}
let label_value = path
.char_indices()
.filter(|&(_, c)| c == '/')
.nth(level - 1)
.map_or(path, |(i, _)| &path[..i]);
Some(label_value)
} else {
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_path_label_value() {
let path = "abc/def/ghi";
assert_eq!(path_label_value(path, 0), None);
assert_eq!(path_label_value(path, 1), Some("abc"));
assert_eq!(path_label_value(path, 2), Some("abc/def"));
assert_eq!(path_label_value(path, 3), Some("abc/def/ghi"));
assert_eq!(path_label_value(path, usize::MAX), Some("abc/def/ghi"));
assert_eq!(path_label_value("", 0), None);
assert_eq!(path_label_value("", 1), Some(""));
}
}