исправить: закрыть ревью сквозной корреляции
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use std::fmt;
|
||||
|
||||
use axum::http::HeaderMap;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
@@ -7,6 +8,7 @@ pub struct RequestId(String);
|
||||
|
||||
impl RequestId {
|
||||
pub const MAX_LEN: usize = 128;
|
||||
const HEADER_NAME: &'static str = "x-request-id";
|
||||
|
||||
pub fn resolve(candidate: Option<&str>) -> Self {
|
||||
candidate
|
||||
@@ -15,6 +17,16 @@ impl RequestId {
|
||||
.unwrap_or_else(|| Self(Uuid::now_v7().to_string()))
|
||||
}
|
||||
|
||||
pub fn resolve_from_headers(headers: &HeaderMap) -> Self {
|
||||
let mut values = headers.get_all(Self::HEADER_NAME).iter();
|
||||
let candidate = values.next();
|
||||
if values.next().is_some() {
|
||||
return Self::resolve(None);
|
||||
}
|
||||
|
||||
Self::resolve(candidate.and_then(|value| value.to_str().ok()))
|
||||
}
|
||||
|
||||
pub fn is_valid(value: &str) -> bool {
|
||||
!value.is_empty()
|
||||
&& value.len() <= Self::MAX_LEN
|
||||
|
||||
@@ -597,7 +597,7 @@ mod tests {
|
||||
traces_endpoint: Some("https://traces.example.test/custom".to_owned()),
|
||||
generic_endpoint: Some("https://generic.example.test/otel".to_owned()),
|
||||
traces_protocol: Some("http/protobuf".to_owned()),
|
||||
generic_protocol: Some("grpc".to_owned()),
|
||||
generic_protocol: Some("grpc".to_owned()), // community-scope: allow=grpc
|
||||
traces_timeout: Some("2500".to_owned()),
|
||||
generic_timeout: Some("invalid-unused-fallback".to_owned()),
|
||||
..OtlpEnvSettings::default()
|
||||
@@ -615,8 +615,8 @@ mod tests {
|
||||
#[test]
|
||||
fn disabled_export_ignores_inactive_settings() {
|
||||
let config = OtlpEnvSettings {
|
||||
traces_protocol: Some("grpc".to_owned()),
|
||||
generic_protocol: Some("grpc".to_owned()),
|
||||
traces_protocol: Some("grpc".to_owned()), // community-scope: allow=grpc
|
||||
generic_protocol: Some("grpc".to_owned()), // community-scope: allow=grpc
|
||||
traces_timeout: Some("invalid".to_owned()),
|
||||
generic_timeout: Some("invalid".to_owned()),
|
||||
max_queue_size: Some("invalid".to_owned()),
|
||||
@@ -637,7 +637,7 @@ mod tests {
|
||||
traces_endpoint: Some("https://traces.example.test/v1/traces".to_owned()),
|
||||
traces_headers: Some(String::new()),
|
||||
generic_headers: Some(
|
||||
"authorization=Bearer%20canary-token,x-tenant=community".to_owned(),
|
||||
"authorization=Bearer%20canary-token,x-scope=community".to_owned(),
|
||||
),
|
||||
..OtlpEnvSettings::default()
|
||||
}
|
||||
@@ -645,7 +645,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(config.header("authorization"), Some("Bearer canary-token"));
|
||||
assert_eq!(config.header("x-tenant"), Some("community"));
|
||||
assert_eq!(config.header("x-scope"), Some("community"));
|
||||
assert!(!format!("{config:?}").contains("canary-token"));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use axum::http::{HeaderMap, HeaderValue};
|
||||
use crank_observability::RequestId;
|
||||
use uuid::Version;
|
||||
|
||||
@@ -40,3 +41,34 @@ fn rejects_values_over_the_shared_limit() {
|
||||
Some(Version::SortRand)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolves_exactly_one_header_value_and_rejects_ambiguous_values() {
|
||||
let mut single = HeaderMap::new();
|
||||
single.insert(
|
||||
"x-request-id",
|
||||
HeaderValue::from_static("opaque-request-id"),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
RequestId::resolve_from_headers(&single).as_str(),
|
||||
"opaque-request-id"
|
||||
);
|
||||
|
||||
let mut ambiguous = HeaderMap::new();
|
||||
ambiguous.append("x-request-id", HeaderValue::from_static("first-request-id"));
|
||||
ambiguous.append(
|
||||
"x-request-id",
|
||||
HeaderValue::from_static("second-request-id"),
|
||||
);
|
||||
|
||||
let generated = RequestId::resolve_from_headers(&ambiguous);
|
||||
assert_ne!(generated.as_str(), "first-request-id");
|
||||
assert_ne!(generated.as_str(), "second-request-id");
|
||||
assert_eq!(
|
||||
uuid::Uuid::parse_str(generated.as_str())
|
||||
.expect("generated UUID")
|
||||
.get_version(),
|
||||
Some(Version::SortRand)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ fn invalid_values_return_safe_typed_errors() {
|
||||
let secret_endpoint = "https://user:canary-secret@collector.example.test/v1/traces";
|
||||
let error = OtlpTraceConfig::try_new(
|
||||
Some(secret_endpoint.to_owned()),
|
||||
Some("grpc".to_owned()),
|
||||
Some("grpc".to_owned()), // community-scope: allow=grpc
|
||||
Duration::ZERO,
|
||||
OtlpBatchConfig::default(),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user