77mod built_info;
88/// GraphQL resolvers
99mod graphql;
10+ /// An [`axum::handler::Handler`] for GraphQL
11+ mod route_handlers;
1012
11- use async_graphql:: { extensions:: Tracing , http:: GraphiQLSource , SDLExportOptions } ;
12- use async_graphql_axum:: { GraphQL , GraphQLSubscription } ;
13+ use async_graphql:: { http:: GraphiQLSource , SDLExportOptions } ;
1314use aws_credential_types:: { provider:: SharedCredentialsProvider , Credentials } ;
1415use aws_sdk_s3:: { config:: Region , Client } ;
1516use axum:: { response:: Html , routing:: get, Router } ;
17+ use axum_tracing_opentelemetry:: middleware:: { OtelAxumLayer , OtelInResponseLayer } ;
1618use clap:: { ArgAction :: SetTrue , Parser } ;
1719use derive_more:: { Deref , FromStr , Into } ;
1820use graphql:: { root_schema_builder, RootSchema } ;
@@ -26,10 +28,12 @@ use std::{
2628 time:: Duration ,
2729} ;
2830use tokio:: net:: TcpListener ;
29- use tracing:: instrument;
31+ use tracing:: { info , instrument} ;
3032use tracing_subscriber:: { layer:: SubscriberExt , util:: SubscriberInitExt } ;
3133use url:: Url ;
3234
35+ use crate :: route_handlers:: GraphQLHandler ;
36+
3337/// A service providing Beamline ISPyB data collected during sessions
3438#[ derive( Debug , Parser ) ]
3539#[ command( author, version, about, long_about=None ) ]
@@ -127,41 +131,40 @@ struct SchemaArgs {
127131/// Creates a connection pool to access the database
128132#[ instrument( skip( database_url) ) ]
129133async fn setup_database ( database_url : Url ) -> Result < DatabaseConnection , TransactionError < DbErr > > {
130- let connection_options = ConnectOptions :: new ( database_url. to_string ( ) ) ;
134+ info ! ( "Connecting to database at {database_url}" ) ;
135+ let connection_options = ConnectOptions :: new ( database_url. to_string ( ) )
136+ . sqlx_logging_level ( tracing:: log:: LevelFilter :: Debug )
137+ . to_owned ( ) ;
131138 let connection = Database :: connect ( connection_options) . await ?;
139+ info ! ( "Database connection established: {connection:?}" ) ;
132140 Ok ( connection)
133141}
134142
135143/// Creates an [`axum::Router`] serving GraphiQL, synchronous GraphQL and GraphQL subscriptions
136144fn setup_router ( schema : RootSchema ) -> Router {
137145 #[ allow( clippy:: missing_docs_in_private_items) ]
138146 const GRAPHQL_ENDPOINT : & str = "/" ;
139- #[ allow( clippy:: missing_docs_in_private_items) ]
140- const SUBSCRIPTION_ENDPOINT : & str = "/ws" ;
141147
142148 Router :: new ( )
143149 . route (
144150 GRAPHQL_ENDPOINT ,
145151 get ( Html (
146- GraphiQLSource :: build ( )
147- . endpoint ( GRAPHQL_ENDPOINT )
148- . subscription_endpoint ( SUBSCRIPTION_ENDPOINT )
149- . finish ( ) ,
152+ GraphiQLSource :: build ( ) . endpoint ( GRAPHQL_ENDPOINT ) . finish ( ) ,
150153 ) )
151- . post_service ( GraphQL :: new ( schema. clone ( ) ) ) ,
154+ . post ( GraphQLHandler :: new ( schema) ) ,
152155 )
153- . route_service ( SUBSCRIPTION_ENDPOINT , GraphQLSubscription :: new ( schema) )
156+ . layer ( OtelInResponseLayer )
157+ . layer ( OtelAxumLayer :: default ( ) )
154158}
155159
156160/// Serves the endpoints on the specified port forever
157161async fn serve ( router : Router , port : u16 ) -> Result < ( ) , std:: io:: Error > {
158162 let socket_addr = SocketAddr :: V4 ( SocketAddrV4 :: new ( Ipv4Addr :: UNSPECIFIED , port) ) ;
159163 let listener = TcpListener :: bind ( socket_addr) . await ?;
160- println ! ( "GraphiQL IDE: {}" , socket_addr) ;
164+ println ! ( "Serving API & GraphQL UI at {}" , socket_addr) ;
161165 axum:: serve ( listener, router. into_make_service ( ) ) . await ?;
162166 Ok ( ( ) )
163167}
164-
165168/// Sets up Logging & Tracing using opentelemetry if available
166169fn setup_telemetry (
167170 log_level : tracing:: Level ,
@@ -180,6 +183,9 @@ fn setup_telemetry(
180183 ) ,
181184 ] ) ;
182185 let ( metrics_layer, tracing_layer) = if let Some ( otel_collector_url) = otel_collector_url {
186+ opentelemetry:: global:: set_text_map_propagator (
187+ opentelemetry_sdk:: propagation:: TraceContextPropagator :: default ( ) ,
188+ ) ;
183189 (
184190 Some ( tracing_opentelemetry:: MetricsLayer :: new (
185191 opentelemetry_otlp:: new_pipeline ( )
@@ -232,13 +238,7 @@ async fn main() {
232238 Cli :: Serve ( args) => {
233239 setup_telemetry ( args. log_level , args. otel_collector_url ) . unwrap ( ) ;
234240 let database = setup_database ( args. database_url ) . await . unwrap ( ) ;
235- let s3_client = aws_sdk_s3:: Client :: from_s3_client_args ( args. s3_client ) ;
236- let schema = root_schema_builder ( )
237- . extension ( Tracing )
238- . data ( database)
239- . data ( s3_client)
240- . data ( args. s3_bucket )
241- . finish ( ) ;
241+ let schema = root_schema_builder ( ) . data ( database) . finish ( ) ;
242242 let router = setup_router ( schema) ;
243243 serve ( router, args. port ) . await . unwrap ( ) ;
244244 }
0 commit comments