-
Notifications
You must be signed in to change notification settings - Fork 277
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
bryn
committed
Oct 20, 2023
1 parent
ea78a92
commit 431e38e
Showing
9 changed files
with
789 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
256 changes: 256 additions & 0 deletions
256
apollo-router/src/plugins/telemetry/config_new/attributes.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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>, | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(), | ||
} | ||
} | ||
} |
Oops, something went wrong.