@@ -4,11 +4,12 @@ use hyper::{body::Incoming, server::conn::http1, service::service_fn};
44
55use hyper_util:: rt:: tokio:: TokioIo ;
66use lambda_runtime_api_client:: Client ;
7- use serde:: Deserialize ;
7+ use serde:: { de :: DeserializeOwned , Deserialize } ;
88use std:: {
99 convert:: Infallible ,
1010 fmt,
1111 future:: { ready, Future } ,
12+ marker:: PhantomData ,
1213 net:: SocketAddr ,
1314 path:: PathBuf ,
1415 pin:: Pin ,
@@ -29,7 +30,7 @@ const DEFAULT_LOG_PORT_NUMBER: u16 = 9002;
2930const DEFAULT_TELEMETRY_PORT_NUMBER : u16 = 9003 ;
3031
3132/// An Extension that runs event, log and telemetry processors
32- pub struct Extension < ' a , E , L , T > {
33+ pub struct Extension < ' a , E , L , T , TL = String > {
3334 extension_name : Option < & ' a str > ,
3435 events : Option < & ' a [ & ' a str ] > ,
3536 events_processor : E ,
@@ -41,6 +42,7 @@ pub struct Extension<'a, E, L, T> {
4142 telemetry_processor : Option < T > ,
4243 telemetry_buffering : Option < LogBuffering > ,
4344 telemetry_port_number : u16 ,
45+ _telemetry_record_type : PhantomData < fn ( TL ) > ,
4446}
4547
4648impl Extension < ' _ , Identity < LambdaEvent > , MakeIdentity < Vec < LambdaLog > > , MakeIdentity < Vec < LambdaTelemetry > > > {
@@ -58,6 +60,7 @@ impl Extension<'_, Identity<LambdaEvent>, MakeIdentity<Vec<LambdaLog>>, MakeIden
5860 telemetry_buffering : None ,
5961 telemetry_processor : None ,
6062 telemetry_port_number : DEFAULT_TELEMETRY_PORT_NUMBER ,
63+ _telemetry_record_type : PhantomData ,
6164 }
6265 }
6366}
@@ -70,7 +73,7 @@ impl Default
7073 }
7174}
7275
73- impl < ' a , E , L , T > Extension < ' a , E , L , T >
76+ impl < ' a , E , L , T , TL > Extension < ' a , E , L , T , TL >
7477where
7578 E : Service < LambdaEvent > ,
7679 E :: Future : Future < Output = Result < ( ) , E :: Error > > ,
@@ -85,12 +88,13 @@ where
8588 L :: Future : Send ,
8689
8790 // Fixme: 'static bound might be too restrictive
88- T : MakeService < ( ) , Vec < LambdaTelemetry > , Response = ( ) > + Send + Sync + ' static ,
89- T :: Service : Service < Vec < LambdaTelemetry > , Response = ( ) > + Send + Sync ,
90- <T :: Service as Service < Vec < LambdaTelemetry > > >:: Future : Send + ' a ,
91+ T : MakeService < ( ) , Vec < LambdaTelemetry < TL > > , Response = ( ) > + Send + Sync + ' static ,
92+ T :: Service : Service < Vec < LambdaTelemetry < TL > > , Response = ( ) > + Send + Sync ,
93+ <T :: Service as Service < Vec < LambdaTelemetry < TL > > > >:: Future : Send + ' a ,
9194 T :: Error : Into < Error > + fmt:: Debug ,
9295 T :: MakeError : Into < Error > + fmt:: Debug ,
9396 T :: Future : Send ,
97+ TL : DeserializeOwned + Send + ' static ,
9498{
9599 /// Create a new [`Extension`] with a given extension name
96100 pub fn with_extension_name ( self , extension_name : & ' a str ) -> Self {
@@ -110,7 +114,7 @@ where
110114 }
111115
112116 /// Create a new [`Extension`] with a service that receives Lambda events.
113- pub fn with_events_processor < N > ( self , ep : N ) -> Extension < ' a , N , L , T >
117+ pub fn with_events_processor < N > ( self , ep : N ) -> Extension < ' a , N , L , T , TL >
114118 where
115119 N : Service < LambdaEvent > ,
116120 N :: Future : Future < Output = Result < ( ) , N :: Error > > ,
@@ -128,11 +132,12 @@ where
128132 telemetry_buffering : self . telemetry_buffering ,
129133 telemetry_processor : self . telemetry_processor ,
130134 telemetry_port_number : self . telemetry_port_number ,
135+ _telemetry_record_type : self . _telemetry_record_type ,
131136 }
132137 }
133138
134139 /// Create a new [`Extension`] with a service that receives Lambda logs.
135- pub fn with_logs_processor < N , NS > ( self , lp : N ) -> Extension < ' a , E , N , T >
140+ pub fn with_logs_processor < N , NS > ( self , lp : N ) -> Extension < ' a , E , N , T , TL >
136141 where
137142 N : Service < ( ) > ,
138143 N :: Future : Future < Output = Result < NS , N :: Error > > ,
@@ -150,6 +155,7 @@ where
150155 telemetry_buffering : self . telemetry_buffering ,
151156 telemetry_processor : self . telemetry_processor ,
152157 telemetry_port_number : self . telemetry_port_number ,
158+ _telemetry_record_type : self . _telemetry_record_type ,
153159 }
154160 }
155161
@@ -179,7 +185,11 @@ where
179185 }
180186
181187 /// Create a new [`Extension`] with a service that receives Lambda telemetry data.
182- pub fn with_telemetry_processor < N , NS > ( self , lp : N ) -> Extension < ' a , E , L , N >
188+ ///
189+ /// By default, telemetry log records are deserialized as `String`, but
190+ /// it's possible to configure Lambda functions to emit logs in JSON format.
191+ /// For more information, refer to [`Self::with_telemetry_record_type`].
192+ pub fn with_telemetry_processor < N , NS > ( self , lp : N ) -> Extension < ' a , E , L , N , TL >
183193 where
184194 N : Service < ( ) > ,
185195 N :: Future : Future < Output = Result < NS , N :: Error > > ,
@@ -197,6 +207,7 @@ where
197207 telemetry_types : self . telemetry_types ,
198208 telemetry_buffering : self . telemetry_buffering ,
199209 telemetry_port_number : self . telemetry_port_number ,
210+ _telemetry_record_type : self . _telemetry_record_type ,
200211 }
201212 }
202213
@@ -345,6 +356,48 @@ where
345356 }
346357}
347358
359+ impl < ' a , E , L > Extension < ' a , E , L , MakeIdentity < Vec < LambdaTelemetry > > > {
360+ /// Set the deserialization type for telemetry log records.
361+ ///
362+ /// By default, telemetry log records are deserialized as `String`, but
363+ /// it's possible to configure Lambda functions to emit logs in JSON format.
364+ /// Use this method to deserialize into a different type, such as
365+ /// `serde_json::Value`.
366+ ///
367+ /// Must be called before [`Self::with_telemetry_processor`].
368+ ///
369+ /// ```
370+ /// use lambda_extension::{Extension, LambdaTelemetry, SharedService, service_fn};
371+ ///
372+ /// async fn handler(events: Vec<LambdaTelemetry<serde_json::Value>>) -> Result<(), lambda_extension::Error> {
373+ /// for event in &events {
374+ /// println!("{event:?}");
375+ /// }
376+ /// Ok(())
377+ /// }
378+ ///
379+ /// let _ext = Extension::new()
380+ /// .with_telemetry_record_type::<serde_json::Value>()
381+ /// .with_telemetry_processor(SharedService::new(service_fn(handler)));
382+ /// ```
383+ pub fn with_telemetry_record_type < N > ( self ) -> Extension < ' a , E , L , MakeIdentity < Vec < LambdaTelemetry < N > > > , N > {
384+ Extension {
385+ _telemetry_record_type : PhantomData ,
386+ telemetry_processor : None ,
387+ events_processor : self . events_processor ,
388+ extension_name : self . extension_name ,
389+ events : self . events ,
390+ log_types : self . log_types ,
391+ log_buffering : self . log_buffering ,
392+ logs_processor : self . logs_processor ,
393+ log_port_number : self . log_port_number ,
394+ telemetry_types : self . telemetry_types ,
395+ telemetry_buffering : self . telemetry_buffering ,
396+ telemetry_port_number : self . telemetry_port_number ,
397+ }
398+ }
399+ }
400+
348401/// An extension registered by calling [`Extension::register`].
349402pub struct RegisteredExtension < E > {
350403 /// The ID of the registered extension. This ID is unique per extension and remains constant
0 commit comments