@@ -28,6 +28,7 @@ pub struct TelemetryConfigResponse {
2828 datadog : Option < TelemetrySinkStatus > ,
2929 grafana_cloud : Option < TelemetrySinkStatus > ,
3030 logfire : Option < TelemetrySinkStatus > ,
31+ generic : Option < TelemetrySinkStatus > ,
3132}
3233
3334impl From < Vec < TelemetrySinkConfig > > for TelemetryConfigResponse {
@@ -48,6 +49,9 @@ impl From<Vec<TelemetrySinkConfig>> for TelemetryConfigResponse {
4849 TelemetrySinkConfig :: Logfire ( _) => {
4950 instance. logfire = Some ( TelemetrySinkStatus { enabled : true } )
5051 }
52+ TelemetrySinkConfig :: GenericOtel ( _) => {
53+ instance. generic = Some ( TelemetrySinkStatus { enabled : true } )
54+ }
5155 TelemetrySinkConfig :: Debug ( _) => { }
5256 }
5357 }
@@ -95,6 +99,9 @@ pub enum TelemetrySinkConfig {
9599 /// [Logfire](https://logfire.pydantic.dev/docs/how-to-guides/alternative-clients/)
96100 Logfire ( LogfireConfig ) ,
97101
102+ /// Generic config for Otel sinks that only need a host and Bearer token
103+ GenericOtel ( GenericOtelConfig ) ,
104+
98105 /// Internal Debugging
99106 #[ doc( hidden) ]
100107 #[ typeshare( skip) ]
@@ -204,6 +211,33 @@ impl Default for LogfireConfig {
204211 }
205212}
206213
214+ #[ derive( Eq , Clone , PartialEq , Serialize , Deserialize ) ]
215+ #[ cfg_attr( feature = "integration-tests" , derive( Debug ) ) ]
216+ #[ cfg_attr( feature = "utoipa" , derive( utoipa:: ToSchema ) ) ]
217+ #[ typeshare:: typeshare]
218+ pub struct GenericOtelConfig {
219+ pub endpoint : String ,
220+ pub bearer_token : String ,
221+ pub grpc : bool ,
222+ pub logs : bool ,
223+ pub traces : bool ,
224+ pub metrics : bool ,
225+ }
226+
227+ #[ cfg( any( test, feature = "integration-tests" ) ) ]
228+ impl Default for GenericOtelConfig {
229+ fn default ( ) -> Self {
230+ Self {
231+ endpoint : "https://host.host/" . into ( ) ,
232+ bearer_token : "bearer" . into ( ) ,
233+ grpc : true ,
234+ logs : true ,
235+ traces : true ,
236+ metrics : true ,
237+ }
238+ }
239+ }
240+
207241#[ cfg( feature = "integration-tests" ) ]
208242impl From < BetterstackConfig > for TelemetrySinkConfig {
209243 fn from ( value : BetterstackConfig ) -> Self {
@@ -232,6 +266,13 @@ impl From<LogfireConfig> for TelemetrySinkConfig {
232266 }
233267}
234268
269+ #[ cfg( feature = "integration-tests" ) ]
270+ impl From < GenericOtelConfig > for TelemetrySinkConfig {
271+ fn from ( value : GenericOtelConfig ) -> Self {
272+ TelemetrySinkConfig :: GenericOtel ( value)
273+ }
274+ }
275+
235276#[ cfg( feature = "integration-tests" ) ]
236277impl std:: str:: FromStr for TelemetrySinkConfig {
237278 type Err = serde_json:: Error ;
@@ -273,6 +314,15 @@ impl std::str::FromStr for TelemetrySinkConfig {
273314 "cannot deserialize config as valid Logfire configuration" ,
274315 )
275316 } ) )
317+ . or ( serde_json:: from_str :: < GenericOtelConfig > ( config)
318+ . map ( Self :: from)
319+ . inspect_err ( |error| {
320+ tracing:: debug!(
321+ %config,
322+ %error,
323+ "cannot deserialize config as valid Generic configuration" ,
324+ )
325+ } ) )
276326 . map_err ( |_| {
277327 <serde_json:: Error as serde:: de:: Error >:: custom ( format ! (
278328 "configuration does not match any known external telemetry sink: {}" ,
@@ -309,6 +359,13 @@ mod tests {
309359 assert_eq ! ( "logfire" , sink. as_ref( ) ) ;
310360 assert_eq ! ( "project::telemetry::logfire::config" , sink. as_db_type( ) ) ;
311361 }
362+ sink @ TelemetrySinkConfig :: GenericOtel ( _) => {
363+ assert_eq ! ( "generic_otel" , sink. as_ref( ) ) ;
364+ assert_eq ! (
365+ "project::telemetry::generic_otel::config" ,
366+ sink. as_db_type( )
367+ ) ;
368+ }
312369 sink @ TelemetrySinkConfig :: Debug ( _) => {
313370 assert_eq ! ( "debug" , sink. as_ref( ) ) ;
314371 assert_eq ! ( "project::telemetry::debug::config" , sink. as_db_type( ) ) ;
@@ -346,6 +403,13 @@ mod tests {
346403 serde_json:: to_string( & discriminant) . unwrap( )
347404 ) ;
348405 }
406+ discriminant @ TelemetrySinkConfigDiscriminants :: GenericOtel => {
407+ assert_eq ! ( "generic_otel" , discriminant. as_ref( ) ) ;
408+ assert_eq ! (
409+ r#""generic_otel""# ,
410+ serde_json:: to_string( & discriminant) . unwrap( )
411+ ) ;
412+ }
349413 discriminant @ TelemetrySinkConfigDiscriminants :: Debug => {
350414 assert_eq ! ( "debug" , discriminant. as_ref( ) ) ;
351415 assert_eq ! ( r#""debug""# , serde_json:: to_string( & discriminant) . unwrap( ) ) ;
0 commit comments