@@ -17,6 +17,7 @@ limitations under the License.
1717package main
1818
1919import (
20+ "encoding/json"
2021 "fmt"
2122 "io"
2223 "log"
@@ -107,6 +108,28 @@ func errorHandler(path, defaultFormat string) func(http.ResponseWriter, *http.Re
107108 return func (w http.ResponseWriter , r * http.Request ) {
108109 start := time .Now ()
109110 ext := defaultExt
111+ var logJSON []byte // Declare logJSON variable for reuse throughout function
112+
113+ // Log request details in JSON format with debug level
114+ requestLog := map [string ]interface {}{
115+ "timestamp" : start .Format (time .RFC3339 ),
116+ "level" : "debug" , // Set log level to debug for Datadog categorization
117+ "method" : r .Method ,
118+ "path" : r .URL .Path ,
119+ "query" : r .URL .RawQuery ,
120+ "host" : r .Host ,
121+ "remote_addr" : r .RemoteAddr ,
122+ "user_agent" : r .Header .Get ("User-Agent" ),
123+ "original_uri" : r .Header .Get (OriginalURI ),
124+ "namespace" : r .Header .Get (Namespace ),
125+ "ingress_name" : r .Header .Get (IngressName ),
126+ "service_name" : r .Header .Get (ServiceName ),
127+ "service_port" : r .Header .Get (ServicePort ),
128+ "request_id" : r .Header .Get (RequestId ),
129+ "x_code" : r .Header .Get (CodeHeader ),
130+ "x_format" : r .Header .Get (FormatHeader ),
131+ "accept" : r .Header .Get ("Accept" ),
132+ }
110133
111134 if os .Getenv ("DEBUG" ) != "" {
112135 w .Header ().Set (FormatHeader , r .Header .Get (FormatHeader ))
@@ -123,25 +146,75 @@ func errorHandler(path, defaultFormat string) func(http.ResponseWriter, *http.Re
123146 format := r .Header .Get (FormatHeader )
124147 if format == "" {
125148 format = defaultFormat
126- log .Printf ("format not specified. Using %v" , format )
149+ if os .Getenv ("DEBUG" ) != "" {
150+ // Log debug message in JSON format for Datadog
151+ debugLog := map [string ]interface {}{
152+ "timestamp" : time .Now ().Format (time .RFC3339 ),
153+ "level" : "debug" ,
154+ "message" : fmt .Sprintf ("format not specified. Using %v" , format ),
155+ "context" : "format_selection" ,
156+ }
157+ logJSON , _ = json .Marshal (debugLog )
158+ log .Printf ("%s" , logJSON )
159+ }
127160 }
128161
129162 cext , err := mime .ExtensionsByType (format )
130163 if err != nil {
131- log .Printf ("unexpected error reading media type extension: %v. Using %v" , err , ext )
164+ // Log error message in JSON format for Datadog
165+ errorLog := map [string ]interface {}{
166+ "timestamp" : time .Now ().Format (time .RFC3339 ),
167+ "level" : "debug" ,
168+ "message" : fmt .Sprintf ("unexpected error reading media type extension: %v. Using %v" , err , ext ),
169+ "context" : "mime_type_parsing" ,
170+ "error" : err .Error (),
171+ }
172+ logJSON , _ = json .Marshal (errorLog )
173+ log .Printf ("%s" , logJSON )
132174 format = defaultFormat
133175 } else if len (cext ) == 0 {
134- log .Printf ("couldn't get media type extension. Using %v" , ext )
176+ // Log warning message in JSON format for Datadog
177+ warnLog := map [string ]interface {}{
178+ "timestamp" : time .Now ().Format (time .RFC3339 ),
179+ "level" : "debug" ,
180+ "message" : fmt .Sprintf ("couldn't get media type extension. Using %v" , ext ),
181+ "context" : "mime_extension_lookup" ,
182+ }
183+ logJSON , _ = json .Marshal (warnLog )
184+ log .Printf ("%s" , logJSON )
135185 } else {
136186 ext = cext [0 ]
137187 }
138188 w .Header ().Set (ContentType , format )
139189
140190 errCode := r .Header .Get (CodeHeader )
141- code , err := strconv .Atoi (errCode )
142- if err != nil {
143- code = 404
144- log .Printf ("unexpected error reading return code: %v. Using %v" , err , code )
191+ code := 404 // Default code
192+ if errCode != "" {
193+ parsedCode , err := strconv .Atoi (errCode )
194+ if err != nil {
195+ // Log error message in JSON format for Datadog
196+ errorLog := map [string ]interface {}{
197+ "timestamp" : time .Now ().Format (time .RFC3339 ),
198+ "level" : "debug" ,
199+ "message" : fmt .Sprintf ("invalid return code %q: %v. Using %v" , errCode , err , code ),
200+ "context" : "return_code_parsing" ,
201+ "error" : err .Error (),
202+ }
203+ logJSON , _ = json .Marshal (errorLog )
204+ log .Printf ("%s" , logJSON )
205+ } else {
206+ code = parsedCode
207+ }
208+ } else if os .Getenv ("DEBUG" ) != "" {
209+ // Log debug message in JSON format for Datadog
210+ debugLog := map [string ]interface {}{
211+ "timestamp" : time .Now ().Format (time .RFC3339 ),
212+ "level" : "debug" ,
213+ "message" : fmt .Sprintf ("return code not specified. Using %v" , code ),
214+ "context" : "return_code_default" ,
215+ }
216+ logJSON , _ = json .Marshal (debugLog )
217+ log .Printf ("%s" , logJSON )
145218 }
146219 w .WriteHeader (code )
147220
@@ -155,22 +228,47 @@ func errorHandler(path, defaultFormat string) func(http.ResponseWriter, *http.Re
155228 file := fmt .Sprintf ("%v/%v%v" , path , code , ext )
156229 f , err := os .Open (file )
157230 if err != nil {
158- log .Printf ("unexpected error opening file: %v" , err )
231+ // Log error message in JSON format for Datadog
232+ errorLog := map [string ]interface {}{
233+ "timestamp" : time .Now ().Format (time .RFC3339 ),
234+ "level" : "debug" ,
235+ "message" : fmt .Sprintf ("unexpected error opening file: %v" , err ),
236+ "context" : "file_opening" ,
237+ "error" : err .Error (),
238+ }
239+ logJSON , _ = json .Marshal (errorLog )
240+ log .Printf ("%s" , logJSON )
159241 scode := strconv .Itoa (code )
160242 file := fmt .Sprintf ("%v/%cxx%v" , path , scode [0 ], ext )
161243 f , err := os .Open (file )
162244 if err != nil {
163- log .Printf ("unexpected error opening file: %v" , err )
245+ // Log error message in JSON format for Datadog
246+ errorLog := map [string ]interface {}{
247+ "timestamp" : time .Now ().Format (time .RFC3339 ),
248+ "level" : "debug" ,
249+ "message" : fmt .Sprintf ("unexpected error opening file: %v" , err ),
250+ "context" : "file_opening" ,
251+ "error" : err .Error (),
252+ }
253+ logJSON , _ = json .Marshal (errorLog )
254+ log .Printf ("%s" , logJSON )
164255 http .NotFound (w , r )
165256 return
166257 }
167258 defer f .Close ()
168- log .Printf ("serving custom error response for code %v and format %v from file %v" , code , format , file )
259+ // Log info message in JSON format for Datadog
260+ infoLog := map [string ]interface {}{
261+ "timestamp" : time .Now ().Format (time .RFC3339 ),
262+ "level" : "debug" ,
263+ "message" : fmt .Sprintf ("serving custom error response for code %v and format %v from file %v" , code , format , file ),
264+ "context" : "custom_error_response" ,
265+ }
266+ logJSON , _ = json .Marshal (infoLog )
267+ log .Printf ("%s" , logJSON )
169268 io .Copy (w , f )
170269 return
171270 }
172271 defer f .Close ()
173- log .Printf ("serving custom error response for code %v and format %v from file %v" , code , format , file )
174272 io .Copy (w , f )
175273
176274 duration := time .Now ().Sub (start ).Seconds ()
@@ -180,5 +278,18 @@ func errorHandler(path, defaultFormat string) func(http.ResponseWriter, *http.Re
180278
181279 requestCount .WithLabelValues (proto ).Inc ()
182280 requestDuration .WithLabelValues (proto ).Observe (duration )
281+
282+ // Add response details to log
283+ requestLog ["status_code" ] = code
284+ requestLog ["content_type" ] = format
285+ requestLog ["response_file" ] = file
286+ requestLog ["duration_seconds" ] = duration
287+ requestLog ["protocol" ] = proto
288+ requestLog ["message" ] = fmt .Sprintf ("HTTP %s %s - %d" , r .Method , r .URL .Path , code )
289+ requestLog ["context" ] = "http_request"
290+
291+ // Output JSON log with debug level for Datadog
292+ logJSON , _ = json .Marshal (requestLog )
293+ log .Printf ("%s" , logJSON )
183294 }
184295}
0 commit comments