@@ -29,7 +29,7 @@ defmodule LoggerJSON.Formatters.DatadogLogger do
2929 @ behaviour LoggerJSON.Formatter
3030
3131 @ default_opts % { hostname: :system }
32- @ processed_metadata_keys ~w[ pid file line function module application span_id trace_id] a
32+ @ processed_metadata_keys ~w[ pid file line function module application span_id trace_id otel_span_id otel_trace_id ] a
3333
3434 @ impl true
3535 def init ( formatter_opts \\ % { } ) do
@@ -72,16 +72,46 @@ defmodule LoggerJSON.Formatters.DatadogLogger do
7272 # To connect logs and traces, span_id and trace_id keys are respectively dd.span_id and dd.trace_id
7373 # https://docs.datadoghq.com/tracing/faq/why-cant-i-see-my-correlated-logs-in-the-trace-id-panel/?tab=jsonlogs
7474 defp convert_tracing_keys ( output , md ) do
75- Enum . reduce ( [ :trace_id , :span_id ] , output , fn key , acc ->
75+ fields = % {
76+ span_id: [ "dd.span_id" , & & 1 ] ,
77+ trace_id: [ "dd.trace_id" , & & 1 ] ,
78+ otel_span_id: [ "dd.span_id" , & convert_otel_field / 1 ] ,
79+ otel_trace_id: [ "dd.trace_id" , & convert_otel_field / 1 ]
80+ }
81+
82+ Enum . reduce ( fields , output , fn { key , [ new_key , transformer ] } , acc ->
7683 if Keyword . has_key? ( md , key ) do
77- dd_key = "dd." <> Atom . to_string ( key )
78- Map . merge ( acc , % { dd_key => Keyword . get ( md , key ) } )
84+ new_value = apply ( transformer , [ Keyword . get ( md , key ) ] )
85+ Map . merge ( acc , % { new_key => new_value } )
7986 else
8087 acc
8188 end
8289 end )
8390 end
8491
92+ # This converts native OpenTelemetry fields to the native Datadog format.
93+ # This function is taken from the Datadog examples for converting. Mostly the Golang version
94+ # https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces/opentelemetry/?tab=go
95+ # Tests were stolen from https://github.com/open-telemetry/opentelemetry-specification/issues/525
96+ # and https://go.dev/play/p/pUBHcLdXJNy
97+ defp convert_otel_field ( << value :: binary - size ( 16 ) >> ) do
98+ { value , _ } = Integer . parse ( value , 16 )
99+ Integer . to_string ( value , 10 )
100+ rescue
101+ _ -> ""
102+ end
103+
104+ defp convert_otel_field ( value ) when byte_size ( value ) < 16 , do: ""
105+
106+ defp convert_otel_field ( value ) do
107+ value = to_string ( value )
108+ len = byte_size ( value ) - 16
109+ << _front :: binary - size ( len ) , value :: binary >> = value
110+ convert_otel_field ( value )
111+ rescue
112+ _ -> ""
113+ end
114+
85115 defp method_name ( metadata ) do
86116 function = Keyword . get ( metadata , :function )
87117 module = Keyword . get ( metadata , :module )
0 commit comments