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
7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ required-features = ["schemars", "serde_yaml"]

[dependencies]
async-trait = { version = "^0.1.51" }
famedly_rust_utils = { version = "1.0.0", features = ["level_filter"] }
famedly_rust_utils = { version = "1.0.2", features = [
"level_filter",
"schemars",
] }
http = { version = "1.2.0" }
once_cell = { version = "1.20.2" }
opentelemetry = { version = "0.30.0" }
Expand All @@ -33,7 +36,7 @@ tracing-subscriber = { version = "0.3.19", features = ["env-filter", "json"] }
tracing = "0.1.40"
serde = { version = "1.0.210", features = ["derive"] }
url = { version = "2.5.2", features = ["serde"] }
schemars = { version = "0.8.22", optional = true }
schemars = { version = "1.0.4", optional = true, features = ["url2"] }
serde_yaml = { version = "0.9.34", optional = true }

# tracing-error
Expand Down
62 changes: 38 additions & 24 deletions config-schema.yaml
Original file line number Diff line number Diff line change
@@ -1,50 +1,52 @@
# SPDX-FileCopyrightText: 2025 Famedly GmbH (info@famedly.com)
#
# SPDX-License-Identifier: Apache-2.0
$schema: http://json-schema.org/draft-07/schema#
$schema: https://json-schema.org/draft/2020-12/schema
title: OtelConfig
description: OpenTelemetry configuration
type: object
properties:
exporter:
description: Configurations for exporting traces, metrics and logs
anyOf:
- $ref: '#/definitions/ExporterConfig'
- $ref: '#/$defs/ExporterConfig'
- type: 'null'
stdout:
description: Enables logs on stdout
anyOf:
- $ref: '#/definitions/StdoutLogsConfig'
- $ref: '#/$defs/StdoutLogsConfig'
- type: 'null'
definitions:
$defs:
ExporterConfig:
description: Configuration for exporting OpenTelemetry data
type: object
properties:
endpoint:
description: gRPC endpoint for exporting using OTELP
type: string
format: uri
$ref: '#/$defs/OtelUrl'
logs:
description: Logs exporting config
anyOf:
- $ref: '#/definitions/ProviderConfig'
- $ref: '#/$defs/ProviderConfig'
- type: 'null'
metrics:
description: Metrics exporting config
anyOf:
- $ref: '#/definitions/ProviderConfig'
- $ref: '#/$defs/ProviderConfig'
- type: 'null'
resource_metadata:
description: Key value mapping of the OTEL resource. See [Resource semantic conventions](https://opentelemetry.io/docs/specs/semconv/resource/) for what can be set here. Only string values are supported now. This crate sets `service.name` and `service.version` by default.
default: {}
description: |-
Key value mapping of the OTEL resource. See [Resource semantic conventions](https://opentelemetry.io/docs/specs/semconv/resource/) for what can be set here.
Only string values are supported now.
This crate sets `service.name` and `service.version` by default.
type: object
additionalProperties:
type: string
default: {}
traces:
description: Traces exporting config
anyOf:
- $ref: '#/definitions/ProviderConfig'
- $ref: '#/$defs/ProviderConfig'
- type: 'null'
LevelFilter:
type: string
Expand All @@ -55,43 +57,55 @@ definitions:
- info
- debug
- trace
OtelUrl:
description: Wrapper over [`Url`] with [`Default`] implementation `http://localhost:4317`
type: string
format: uri
ProviderConfig:
description: Provider configuration for OpenTelemetry export
type: object
properties:
dependencies_levels:
description: Levels for the dependencies
type: object
additionalProperties:
$ref: '#/$defs/LevelFilter'
default: {}
enabled:
description: Enables provider
default: false
type: boolean
default: false
general_level:
description: Level for the dependencies
description: General level
$ref: '#/$defs/LevelFilter'
default: info
allOf:
- $ref: '#/definitions/LevelFilter'
level:
description: Level for the crate
$ref: '#/$defs/LevelFilter'
default: info
allOf:
- $ref: '#/definitions/LevelFilter'
StdoutLogsConfig:
description: Stdout logs configuration
type: object
properties:
dependencies_levels:
description: Level for the dependencies
type: object
additionalProperties:
$ref: '#/$defs/LevelFilter'
default: {}
enabled:
description: Enables the stdout logs
default: true
type: boolean
default: true
general_level:
description: Level for the dependencies
description: General level
$ref: '#/$defs/LevelFilter'
default: info
allOf:
- $ref: '#/definitions/LevelFilter'
json_output:
description: Output structured JSON logs
default: false
type: boolean
default: false
level:
description: Level for the crate
$ref: '#/$defs/LevelFilter'
default: info
allOf:
- $ref: '#/definitions/LevelFilter'
20 changes: 20 additions & 0 deletions config.sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ stdout:
# <off|error|warn|info|debug|trace> optional, default: info
general_level: info

# Level for the dependencies
# <off|error|warn|info|debug|trace> optional, default: empty
dependencies_levels:
"famedly-rust-utils": debug

# Output structured JSON logs
# optional, default: false
json_output: false
Expand Down Expand Up @@ -47,6 +52,11 @@ exporter:
# <off|error|warn|info|debug|trace> optional, default: info
general_level: LevelFilter,

# Level for the dependencies
# <off|error|warn|info|debug|trace> optional, default: empty
dependencies_levels:
"famedly-rust-utils": debug

# Traces exporting config
# optional
traces:
Expand All @@ -61,6 +71,11 @@ exporter:
# <off|error|warn|info|debug|trace> optional, default: info
general_level: LevelFilter,

# Level for the dependencies
# <off|error|warn|info|debug|trace> optional, default: empty
dependencies_levels:
"famedly-rust-utils": debug

# Metrics exporting config
# optional
metrics:
Expand All @@ -74,3 +89,8 @@ exporter:
# Level for the dependencies
# <off|error|warn|info|debug|trace> optional, default: info
general_level: LevelFilter,

# Level for the dependencies
# <off|error|warn|info|debug|trace> optional, default: empty
dependencies_levels:
"famedly-rust-utils": debug
42 changes: 37 additions & 5 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//!
//! Module containing the configuration struct for the OpenTelemetry

use std::collections::BTreeMap as Map;
use std::collections::{BTreeMap as Map, HashMap};

use famedly_rust_utils::LevelFilter;
use serde::Deserialize;
Expand Down Expand Up @@ -57,6 +57,7 @@ impl OtelConfig {
enabled: true,
level: tracing_subscriber::filter::LevelFilter::TRACE.into(),
general_level: tracing_subscriber::filter::LevelFilter::INFO.into(),
dependencies_levels: HashMap::new(),
json_output: false,
}),
exporter: None,
Expand Down Expand Up @@ -94,9 +95,12 @@ pub struct StdoutLogsConfig {
/// Level for the crate
#[serde(default = "default_level_filter")]
pub level: LevelFilter,
/// Level for the dependencies
/// General level
#[serde(default = "default_level_filter")]
pub general_level: LevelFilter,
/// Level for the dependencies
#[serde(default)]
pub dependencies_levels: HashMap<String, LevelFilter>,
/// Output structured JSON logs
#[serde(default)]
pub json_output: bool,
Expand All @@ -112,22 +116,37 @@ pub struct ProviderConfig {
/// Level for the crate
#[serde(default = "default_level_filter")]
pub level: LevelFilter,
/// Level for the dependencies
/// General level
#[serde(default = "default_level_filter")]
pub general_level: LevelFilter,
/// Levels for the dependencies
#[serde(default)]
pub dependencies_levels: HashMap<String, LevelFilter>,
}

impl ProviderConfig {
/// Builds a trace filter
pub(crate) fn get_filter(&self, crate_name: &'static str) -> String {
format!("{},{}={}", self.general_level, crate_name, self.level)
format!(
"{},{}{}={}",
self.general_level,
build_dependencies_level_string(&self.dependencies_levels),
crate_name,
self.level
)
}
}

impl StdoutLogsConfig {
/// Builds a trace filter
pub(crate) fn get_filter(&self, crate_name: &'static str) -> String {
format!("{},{}={}", self.general_level, crate_name, self.level)
format!(
"{},{}{}={}",
self.general_level,
build_dependencies_level_string(&self.dependencies_levels),
crate_name,
self.level
)
}
}

Expand All @@ -137,6 +156,7 @@ impl Default for StdoutLogsConfig {
enabled: true,
level: default_level_filter(),
general_level: default_level_filter(),
dependencies_levels: HashMap::new(),
json_output: false,
}
}
Expand All @@ -148,6 +168,7 @@ impl Default for ProviderConfig {
enabled: false,
level: default_level_filter(),
general_level: default_level_filter(),
dependencies_levels: HashMap::new(),
}
}
}
Expand All @@ -161,3 +182,14 @@ const fn default_level_filter() -> LevelFilter {
const fn true_() -> bool {
true
}

/// Builds a string that configures the filter level of each dependency on the
/// map
fn build_dependencies_level_string(dependencies_levels: &HashMap<String, LevelFilter>) -> String {
let mut dependencies_levels =
dependencies_levels.iter().map(|(k, v)| format!("{k}={v}")).collect::<Vec<_>>().join(",");
if !dependencies_levels.is_empty() {
dependencies_levels.push(',');
}
dependencies_levels
}
Loading