Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions apps/docs/content/docs/reference/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -886,9 +886,9 @@ The `experimentalObservability` configuration requires `futureFlags.experimental
},
"timeoutMs": 10000,
"intervalMs": 15000,
"resource": [
{ "key": "service.name", "value": "turborepo" }
],
"resource": {
"service.name": "turborepo"
},
"metrics": {
"runSummary": true,
"taskDetails": false,
Expand Down Expand Up @@ -970,17 +970,17 @@ Interval in milliseconds between periodic exports to the collector. This control

#### `experimentalObservability.otel.resource`

Optional resource attributes to attach to all exported metrics. Each entry is an object with `key` and `value` fields. These help identify the source of metrics in your observability platform.
Optional resource attributes to attach to all exported metrics. These help identify the source of metrics in your observability platform.

```jsonc title="./turbo.json"
{
"experimentalObservability": {
"otel": {
"resource": [
{ "key": "service.name", "value": "turborepo" },
{ "key": "service.namespace", "value": "ci" },
{ "key": "deployment.environment", "value": "production" }
]
"resource": {
"service.name": "turborepo",
"service.namespace": "ci",
"deployment.environment": "production"
}
}
}
}
Expand Down
36 changes: 13 additions & 23 deletions crates/turborepo-config/src/turbo_json.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::{collections::BTreeMap, str::FromStr};
use std::str::FromStr;

use camino::Utf8PathBuf;
use turbopath::{AbsoluteSystemPath, RelativeUnixPath};
use turborepo_turbo_json::{
RawExperimentalObservability, RawKeyValue, RawObservabilityOtel, RawRemoteCacheOptions,
RawRootTurboJson, RawTurboJson,
RawExperimentalObservability, RawObservabilityOtel, RawRemoteCacheOptions, RawRootTurboJson,
RawTurboJson,
};

use crate::{
Expand Down Expand Up @@ -160,29 +160,19 @@ fn convert_raw_observability_otel(
}),
});

let headers = raw.headers.map(convert_key_values);

let resource = raw.resource.map(convert_key_values);

Ok(ExperimentalOtelOptions {
enabled: raw.enabled.map(|flag| *flag.as_inner()),
protocol,
endpoint: raw.endpoint.map(|endpoint| endpoint.into_inner().into()),
headers,
headers: raw.headers,
timeout_ms: raw.timeout_ms.map(|timeout| *timeout.as_inner()),
interval_ms: raw.interval_ms.map(|interval| *interval.as_inner()),
resource,
resource: raw.resource,
metrics,
use_remote_cache_token: raw.use_remote_cache_token.map(|flag| *flag.as_inner()),
})
}

fn convert_key_values(raw: Vec<RawKeyValue>) -> BTreeMap<String, String> {
raw.into_iter()
.map(|kv| (kv.key.into_inner().into(), kv.value.into_inner().into()))
.collect()
}

#[cfg(test)]
mod test {
use serde_json::json;
Expand Down Expand Up @@ -429,14 +419,14 @@ mod test {
"otel": {
"enabled": true,
"endpoint": "https://example.com/otel",
"headers": [
{ "key": "Authorization", "value": "Bearer token123" },
{ "key": "X-Custom-Header", "value": "custom-value" }
],
"resource": [
{ "key": "service.name", "value": "turborepo" },
{ "key": "service.version", "value": "1.0.0" }
]
"headers": {
"Authorization": "Bearer token123",
"X-Custom-Header": "custom-value"
},
"resource": {
"service.name": "turborepo",
"service.version": "1.0.0"
}
}
}
}))
Expand Down
6 changes: 3 additions & 3 deletions crates/turborepo-turbo-json/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ pub use processed::{
ProcessedPassThroughEnv, ProcessedTaskDefinition, ProcessedWith,
};
pub use raw::{
HasConfigBeyondExtends, Pipeline, RawExperimentalObservability, RawKeyValue,
RawObservabilityOtel, RawObservabilityOtelMetrics, RawPackageTurboJson, RawRemoteCacheOptions,
RawRootTurboJson, RawTaskDefinition, RawTurboJson, SpacesJson,
HasConfigBeyondExtends, Pipeline, RawExperimentalObservability, RawObservabilityOtel,
RawObservabilityOtelMetrics, RawPackageTurboJson, RawRemoteCacheOptions, RawRootTurboJson,
RawTaskDefinition, RawTurboJson, SpacesJson,
};
pub use validator::{TOPOLOGICAL_PIPELINE_DELIMITER, Validator};

Expand Down
20 changes: 2 additions & 18 deletions crates/turborepo-turbo-json/src/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,10 @@ pub struct RawObservabilityOtel {
pub enabled: Option<Spanned<bool>>,
pub protocol: Option<Spanned<UnescapedString>>,
pub endpoint: Option<Spanned<UnescapedString>>,
pub headers: Option<Vec<RawKeyValue>>,
pub headers: Option<BTreeMap<String, String>>,
pub timeout_ms: Option<Spanned<u64>>,
pub interval_ms: Option<Spanned<u64>>,
pub resource: Option<Vec<RawKeyValue>>,
pub resource: Option<BTreeMap<String, String>>,
pub metrics: Option<RawObservabilityOtelMetrics>,
pub use_remote_cache_token: Option<Spanned<bool>>,
}
Expand All @@ -225,13 +225,6 @@ pub struct RawExperimentalObservability {
pub otel: Option<RawObservabilityOtel>,
}

/// A key-value pair for OTel configuration
#[derive(Serialize, Debug, Clone, Iterable, Deserializable)]
pub struct RawKeyValue {
pub key: Spanned<UnescapedString>,
pub value: Spanned<UnescapedString>,
}

/// OTel metrics configuration
#[derive(Serialize, Default, Debug, Clone, Iterable, Deserializable)]
#[serde(rename_all = "camelCase")]
Expand All @@ -249,15 +242,6 @@ pub struct RawObservabilityOtelTaskAttributes {
pub hashes: Option<Spanned<bool>>,
}

impl Default for RawKeyValue {
fn default() -> Self {
Self {
key: Spanned::new(UnescapedString::from(String::new())),
value: Spanned::new(UnescapedString::from(String::new())),
}
}
}

// Root turbo.json
#[derive(Default, Debug, Clone, Iterable, Deserializable)]
pub struct RawRootTurboJson {
Expand Down
Loading