async-graphql/src/extensions/logger.rs

95 lines
3.2 KiB
Rust
Raw Normal View History

2020-05-22 03:58:49 +00:00
use crate::extensions::{Extension, ResolveInfo};
use crate::Error;
use async_graphql_parser::query::{Definition, Document, OperationDefinition, Selection};
2020-05-22 03:58:49 +00:00
use itertools::Itertools;
use std::sync::atomic::{AtomicBool, Ordering};
2020-05-22 03:58:49 +00:00
use uuid::Uuid;
/// Logger extension
pub struct Logger {
id: Uuid,
enabled: AtomicBool,
}
2020-05-22 03:58:49 +00:00
impl Default for Logger {
fn default() -> Self {
Self {
id: Uuid::new_v4(),
enabled: AtomicBool::new(true),
}
2020-05-22 03:58:49 +00:00
}
}
impl Extension for Logger {
fn parse_end(&self, query_source: &str, document: &Document) {
let mut is_schema = false;
for definition in document.definitions() {
if let Definition::Operation(operation) = &definition.node {
let selection_set = match &operation.node {
OperationDefinition::Query(query) => &query.selection_set,
OperationDefinition::SelectionSet(selection_set) => &selection_set.node,
_ => continue,
};
is_schema = selection_set.items.iter().any(|selection| {
if let Selection::Field(field) = &selection.node {
if field.name.as_str() == "__schema" {
return true;
}
}
false
});
if is_schema {
break;
}
}
}
if is_schema {
self.enabled.store(false, Ordering::Relaxed);
return;
}
info!(target: "async-graphql", "query, id: {}, source: \"{}\"", self.id, query_source);
2020-05-22 03:58:49 +00:00
}
fn resolve_start(&self, info: &ResolveInfo<'_>) {
if !self.enabled.load(Ordering::Relaxed) {
return;
}
trace!(target: "async-graphql", "resolve start, id: {}, path: \"{}\"", self.id, info.path_node);
2020-05-22 03:58:49 +00:00
}
fn resolve_end(&self, info: &ResolveInfo<'_>) {
if !self.enabled.load(Ordering::Relaxed) {
return;
}
trace!(target: "async-graphql", "resolve end, id: {}, path: \"{}\"", self.id, info.path_node);
2020-05-22 03:58:49 +00:00
}
fn error(&self, err: &Error) {
match err {
Error::Parse(err) => {
error!(target: "async-graphql", "parse error, id: {}, [{}:{}] {}", self.id, err.pos.line, err.pos.column, err)
2020-05-22 03:58:49 +00:00
}
Error::Query { pos, path, err } => {
if let Some(path) = path {
error!(target: "async-graphql", "query error, id: {}, path: \"{}\", [{}:{}] {}", self.id, path, pos.line, pos.column, err)
2020-05-22 03:58:49 +00:00
} else {
error!(target: "async-graphql", "query error, id: {}, [{}:{}] {}", self.id, pos.line, pos.column, err)
2020-05-22 03:58:49 +00:00
}
}
Error::Rule { errors } => {
for error in errors {
let locations = error
.locations
.iter()
.map(|pos| format!("{}:{}", pos.line, pos.column))
.join(", ");
error!(target: "async-graphql", "validation error, id: {}, [{}] {}", self.id, locations, error.message)
2020-05-22 03:58:49 +00:00
}
}
}
}
}