86 lines
2.7 KiB
Rust
86 lines
2.7 KiB
Rust
use std::fmt::Write;
|
|
use std::sync::Arc;
|
|
|
|
use crate::extensions::{
|
|
Extension, ExtensionContext, ExtensionFactory, NextExecute, NextParseQuery,
|
|
};
|
|
use crate::parser::types::{ExecutableDocument, OperationType, Selection};
|
|
use crate::{PathSegment, Response, ServerResult, Variables};
|
|
|
|
/// Logger extension
|
|
#[cfg_attr(docsrs, doc(cfg(feature = "log")))]
|
|
pub struct Logger;
|
|
|
|
impl ExtensionFactory for Logger {
|
|
fn create(&self) -> Arc<dyn Extension> {
|
|
Arc::new(LoggerExtension)
|
|
}
|
|
}
|
|
|
|
struct LoggerExtension;
|
|
|
|
#[async_trait::async_trait]
|
|
impl Extension for LoggerExtension {
|
|
async fn parse_query(
|
|
&self,
|
|
ctx: &ExtensionContext<'_>,
|
|
query: &str,
|
|
variables: &Variables,
|
|
next: NextParseQuery<'_>,
|
|
) -> ServerResult<ExecutableDocument> {
|
|
let document = next.run(ctx, query, variables).await?;
|
|
let is_schema = document
|
|
.operations
|
|
.iter()
|
|
.filter(|(_, operation)| operation.node.ty == OperationType::Query)
|
|
.any(|(_, operation)| operation.node.selection_set.node.items.iter().any(|selection| matches!(&selection.node, Selection::Field(field) if field.node.name.node == "__schema")));
|
|
if !is_schema {
|
|
log::info!(
|
|
target: "async-graphql",
|
|
"[Execute] {}", ctx.stringify_execute_doc(&document, variables)
|
|
);
|
|
}
|
|
Ok(document)
|
|
}
|
|
|
|
async fn execute(
|
|
&self,
|
|
ctx: &ExtensionContext<'_>,
|
|
operation_name: Option<&str>,
|
|
next: NextExecute<'_>,
|
|
) -> Response {
|
|
let resp = next.run(ctx, operation_name).await;
|
|
if resp.is_err() {
|
|
for err in &resp.errors {
|
|
if !err.path.is_empty() {
|
|
let mut path = String::new();
|
|
for (idx, s) in err.path.iter().enumerate() {
|
|
if idx > 0 {
|
|
path.push('.');
|
|
}
|
|
match s {
|
|
PathSegment::Index(idx) => {
|
|
let _ = write!(&mut path, "{}", idx);
|
|
}
|
|
PathSegment::Field(name) => {
|
|
let _ = write!(&mut path, "{}", name);
|
|
}
|
|
}
|
|
}
|
|
|
|
log::info!(
|
|
target: "async-graphql",
|
|
"[Error] path={} message={}", path, err.message,
|
|
);
|
|
} else {
|
|
log::info!(
|
|
target: "async-graphql",
|
|
"[Error] message={}", err.message,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
resp
|
|
}
|
|
}
|