Skip to content

Commit

Permalink
Otel config future
Browse files Browse the repository at this point in the history
  • Loading branch information
bryn committed Oct 20, 2023
1 parent ea78a92 commit 431e38e
Show file tree
Hide file tree
Showing 9 changed files with 789 additions and 0 deletions.
10 changes: 10 additions & 0 deletions apollo-router/src/plugins/telemetry/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,22 @@ pub(crate) struct Conf {
/// Logging configuration
#[serde(rename = "experimental_logging", default)]
pub(crate) logging: Logging,

#[allow(dead_code)]
#[serde(rename = "logging", default)]
pub(crate) new_logging: config_new::logging::Logging,
/// Metrics configuration
pub(crate) metrics: Metrics,
/// Tracing configuration
pub(crate) tracing: Tracing,
/// Apollo reporting configuration
pub(crate) apollo: apollo::Config,
/// Event configuration
pub(crate) events: config_new::events::Events,
/// Span configuration
pub(crate) spans: config_new::spans::Spans,
/// Instrument configuration
pub(crate) instruments: config_new::instruments::Instruments,
}

/// Metrics configuration
Expand Down
256 changes: 256 additions & 0 deletions apollo-router/src/plugins/telemetry/config_new/attributes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
use crate::plugins::telemetry::config::AttributeValue;
use schemars::gen::SchemaGenerator;
use schemars::schema::Schema;
use schemars::JsonSchema;
use serde::Deserialize;
use std::collections::HashMap;

/// This struct can be used as an attributes container, it has a custom JsonSchema implementation that will merge the schemas of the attributes and custom fields.
#[allow(dead_code)]
#[derive(Clone, Deserialize, Debug)]
#[serde(default)]
pub(crate) struct ExtendableAttributes<A, E>
where
A: Default,
{
#[serde(flatten)]
attributes: A,

#[serde(flatten)]
custom: HashMap<String, E>,
}

impl ExtendableAttributes<(), ()> {
pub(crate) fn empty<A, E>() -> ExtendableAttributes<A, E>
where
A: Default,
{
Default::default()
}
}

impl<A, E> JsonSchema for ExtendableAttributes<A, E>
where
A: Default + JsonSchema,
E: JsonSchema,
{
fn schema_name() -> String {
"extendable_attribute".to_string()
}

fn json_schema(gen: &mut SchemaGenerator) -> Schema {
let mut attributes = gen.subschema_for::<A>();
let custom = gen.subschema_for::<HashMap<String, E>>();
if let Schema::Object(schema) = &mut attributes {
if let Some(object) = &mut schema.object {
object.additional_properties =
custom.into_object().object().additional_properties.clone();
}
}

attributes
}
}

impl<A, E> Default for ExtendableAttributes<A, E>
where
A: Default,
{
fn default() -> Self {
Self {
attributes: Default::default(),
custom: HashMap::new(),
}
}
}

#[allow(dead_code)]
#[derive(Deserialize, JsonSchema, Clone, Debug, Default)]
#[serde(deny_unknown_fields, rename_all = "snake_case")]
pub(crate) enum DefaultAttributeRequirementLevel {
/// Attributes that are marked as required in otel semantic conventions and apollo documentation will be included (default)
#[default]
Required,
/// Attributes that are marked as required or recommended in otel semantic conventions and apollo documentation will be included
Recommended,
/// Attributes that are marked as required, recommended or opt-in in otel semantic conventions and apollo documentation will be included
OptIn,
}

#[allow(dead_code)]
#[derive(Deserialize, JsonSchema, Clone, Debug)]
#[serde(deny_unknown_fields, rename_all = "snake_case")]
pub(crate) enum TraceIdFormat {
OpenTelemetry,
Datadog,
}

#[allow(dead_code)]
#[derive(Deserialize, JsonSchema, Clone, Debug)]
#[serde(deny_unknown_fields, untagged)]
pub(crate) enum RouterCustomAttribute {
RequestHeader {
request_header: String,
redact: Option<String>,
default: Option<String>,
},
ResponseHeader {
response_header: String,
redact: Option<String>,
default: Option<String>,
},
TraceId {
trace_id: TraceIdFormat,
},
ResponseContext {
response_context: String,
redact: Option<String>,
default: Option<AttributeValue>,
},
Env {
env: String,
redact: Option<String>,
default: Option<String>,
},
}
#[allow(dead_code)]
#[derive(Deserialize, JsonSchema, Clone, Debug)]
#[serde(deny_unknown_fields, rename_all = "snake_case")]
pub(crate) enum OperationName {
String,
Hash,
}

#[allow(dead_code)]
#[derive(Deserialize, JsonSchema, Clone, Debug)]
#[serde(deny_unknown_fields, untagged)]
pub(crate) enum SupergraphCustomAttribute {
OperationName {
operation_name: OperationName,
redact: Option<String>,
default: Option<String>,
},
OperationKind {
operation_kind: OperationName,
redact: Option<String>,
default: Option<String>,
},
QueryVariable {
query_variable: String,
redact: Option<String>,
default: Option<String>,
},
ResponseBody {
// Json Path into the response body
response_body: String,
redact: Option<String>,
default: Option<String>,
},
RequestHeader {
request_header: String,
redact: Option<String>,
default: Option<String>,
},
ResponseHeader {
response_header: String,
redact: Option<String>,
default: Option<String>,
},
RequestContext {
request_context: String,
redact: Option<String>,
default: Option<AttributeValue>,
},
ResponseContext {
response_context: String,
redact: Option<String>,
default: Option<AttributeValue>,
},
Env {
env: String,
redact: Option<String>,
default: Option<String>,
},
}

#[allow(dead_code)]
#[derive(Deserialize, JsonSchema, Clone, Debug)]
#[serde(deny_unknown_fields, rename_all = "snake_case", untagged)]
pub(crate) enum SubgraphCustomAttribute {
SubgraphOperationName {
subgraph_operation_name: OperationName,
redact: Option<String>,
default: Option<String>,
},
SubgraphOperationKind {
subgraph_operation_kind: OperationName,
redact: Option<String>,
default: Option<String>,
},
SubgraphQueryVariable {
subgraph_query_variable: String,
redact: Option<String>,
default: Option<String>,
},
SubgraphResponseBody {
subgraph_response_body: String,
redact: Option<String>,
default: Option<String>,
},
SubgraphRequestHeader {
subgraph_request_header: String,
redact: Option<String>,
default: Option<String>,
},
SubgraphResponseHeader {
subgraph_response_header: String,
redact: Option<String>,
default: Option<String>,
},

SupergraphOperationName {
supergraph_operation_name: OperationName,
redact: Option<String>,
default: Option<String>,
},
SupergraphOperationKind {
supergraph_operation_kind: OperationName,
redact: Option<String>,
default: Option<String>,
},
SupergraphQueryVariable {
supergraph_query_variable: String,
redact: Option<String>,
default: Option<String>,
},
SupergraphResponseBody {
supergraph_response_body: String,
redact: Option<String>,
default: Option<String>,
},
SupergraphRequestHeader {
supergraph_request_header: String,
redact: Option<String>,
default: Option<String>,
},
SupergraphResponseHeader {
supergraph_response_header: String,
redact: Option<String>,
default: Option<String>,
},
RequestContext {
request_context: String,
redact: Option<String>,
default: Option<AttributeValue>,
},
ResponseContext {
response_context: String,
redact: Option<String>,
default: Option<AttributeValue>,
},
Env {
env: String,
redact: Option<String>,
default: Option<String>,
},
}
70 changes: 70 additions & 0 deletions apollo-router/src/plugins/telemetry/config_new/events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use crate::plugins::telemetry::config_new::attributes::{
RouterCustomAttribute, SubgraphCustomAttribute, SupergraphCustomAttribute,
};
use schemars::JsonSchema;
use serde::Deserialize;
use std::collections::HashMap;

#[allow(dead_code)]
#[derive(Deserialize, JsonSchema, Clone, Default, Debug)]
#[serde(deny_unknown_fields, default)]
pub(crate) struct Events {
router: RouterEvents,
supergraph: SupergraphEvents,
subgraph: SubgraphEvents,
}

#[allow(dead_code)]
#[derive(Deserialize, JsonSchema, Clone, Debug, Default)]
#[serde(rename_all = "snake_case")]
enum EventLevel {
Info,
Warn,
Error,
#[default]
Off,
}
#[allow(dead_code)]
#[derive(Deserialize, JsonSchema, Clone, Default, Debug)]
#[serde(deny_unknown_fields, default)]
struct RouterEvents {
on_error: Event<RouterCustomAttribute>,
on_request: Event<RouterCustomAttribute>,
on_response: Event<RouterCustomAttribute>,
}

#[allow(dead_code)]
#[derive(Deserialize, JsonSchema, Clone, Default, Debug)]
#[serde(deny_unknown_fields, default)]
struct SupergraphEvents {
on_error: Event<SupergraphCustomAttribute>,
on_request: Event<RouterCustomAttribute>,
on_response: Event<RouterCustomAttribute>,
}

#[allow(dead_code)]
#[derive(Deserialize, JsonSchema, Clone, Default, Debug)]
#[serde(deny_unknown_fields, default)]
struct SubgraphEvents {
on_error: Event<SubgraphCustomAttribute>,
on_request: Event<RouterCustomAttribute>,
on_response: Event<RouterCustomAttribute>,
}

#[allow(dead_code)]
#[derive(Deserialize, JsonSchema, Clone, Debug)]
#[serde(default)]
struct Event<T> {
level: EventLevel,

attributes: HashMap<String, T>,
}

impl<T> Default for Event<T> {
fn default() -> Self {
Event {
level: EventLevel::Off,
attributes: HashMap::new(),
}
}
}
Loading

0 comments on commit 431e38e

Please sign in to comment.