@@ -280,7 +280,10 @@ func (w *ResponseWriterWrapper) Finalize(c *gin.Context) error {
280280
281281 hasAPIError := len (slicesAPIResponseError ) > 0 || finalStatusCode >= http .StatusBadRequest
282282 forceLog := w .logOnErrorOnly && hasAPIError && ! w .logger .IsEnabled ()
283+ websocketTimelineSource := w .extractWebsocketTimelineSource (c )
284+ apiWebsocketTimelineSource := w .extractAPIWebsocketTimelineSource (c )
283285 if ! w .logger .IsEnabled () && ! forceLog {
286+ cleanupFileBodySources (websocketTimelineSource , apiWebsocketTimelineSource )
284287 return nil
285288 }
286289
@@ -307,6 +310,13 @@ func (w *ResponseWriterWrapper) Finalize(c *gin.Context) error {
307310 _ = w .streamWriter .WriteAPIResponse (apiResponse )
308311 }
309312 apiWebsocketTimeline := w .extractAPIWebsocketTimeline (c )
313+ var errMerge error
314+ apiWebsocketTimeline , errMerge = mergeFileBodySource (apiWebsocketTimeline , apiWebsocketTimelineSource )
315+ if errMerge != nil {
316+ cleanupFileBodySources (websocketTimelineSource )
317+ return errMerge
318+ }
319+ cleanupFileBodySources (websocketTimelineSource )
310320 if len (apiWebsocketTimeline ) > 0 {
311321 _ = w .streamWriter .WriteAPIWebsocketTimeline (apiWebsocketTimeline )
312322 }
@@ -318,7 +328,7 @@ func (w *ResponseWriterWrapper) Finalize(c *gin.Context) error {
318328 return nil
319329 }
320330
321- return w .logRequest (w .extractRequestBody (c ), finalStatusCode , w .cloneHeaders (), w .extractResponseBody (c ), w .extractWebsocketTimeline (c ), w .extractAPIRequest (c ), w .extractAPIResponse (c ), w .extractAPIWebsocketTimeline (c ), w .extractAPIResponseTimestamp (c ), slicesAPIResponseError , forceLog )
331+ return w .logRequest (w .extractRequestBody (c ), finalStatusCode , w .cloneHeaders (), w .extractResponseBody (c ), w .extractWebsocketTimeline (c ), websocketTimelineSource , w .extractAPIRequest (c ), w .extractAPIResponse (c ), w .extractAPIWebsocketTimeline (c ), apiWebsocketTimelineSource , w .extractAPIResponseTimestamp (c ), slicesAPIResponseError , forceLog )
322332}
323333
324334func (w * ResponseWriterWrapper ) cloneHeaders () map [string ][]string {
@@ -370,6 +380,10 @@ func (w *ResponseWriterWrapper) extractAPIWebsocketTimeline(c *gin.Context) []by
370380 return bytes .Clone (data )
371381}
372382
383+ func (w * ResponseWriterWrapper ) extractAPIWebsocketTimelineSource (c * gin.Context ) * logging.FileBodySource {
384+ return extractFileBodySource (c , logging .APIWebsocketTimelineSourceContextKey )
385+ }
386+
373387func (w * ResponseWriterWrapper ) extractAPIResponseTimestamp (c * gin.Context ) time.Time {
374388 ts , isExist := c .Get ("API_RESPONSE_TIMESTAMP" )
375389 if ! isExist {
@@ -405,6 +419,25 @@ func (w *ResponseWriterWrapper) extractWebsocketTimeline(c *gin.Context) []byte
405419 return extractBodyOverride (c , websocketTimelineOverrideContextKey )
406420}
407421
422+ func (w * ResponseWriterWrapper ) extractWebsocketTimelineSource (c * gin.Context ) * logging.FileBodySource {
423+ return extractFileBodySource (c , logging .WebsocketTimelineSourceContextKey )
424+ }
425+
426+ func extractFileBodySource (c * gin.Context , key string ) * logging.FileBodySource {
427+ if c == nil {
428+ return nil
429+ }
430+ value , exists := c .Get (key )
431+ if ! exists {
432+ return nil
433+ }
434+ source , ok := value .(* logging.FileBodySource )
435+ if ! ok || source == nil {
436+ return nil
437+ }
438+ return source
439+ }
440+
408441func extractBodyOverride (c * gin.Context , key string ) []byte {
409442 if c == nil {
410443 return nil
@@ -426,11 +459,48 @@ func extractBodyOverride(c *gin.Context, key string) []byte {
426459 return nil
427460}
428461
429- func (w * ResponseWriterWrapper ) logRequest (requestBody []byte , statusCode int , headers map [string ][]string , body , websocketTimeline , apiRequestBody , apiResponseBody , apiWebsocketTimeline []byte , apiResponseTimestamp time.Time , apiResponseErrors []* interfaces.ErrorMessage , forceLog bool ) error {
462+ func (w * ResponseWriterWrapper ) logRequest (requestBody []byte , statusCode int , headers map [string ][]string , body , websocketTimeline [] byte , websocketTimelineSource * logging. FileBodySource , apiRequestBody , apiResponseBody , apiWebsocketTimeline []byte , apiWebsocketTimelineSource * logging. FileBodySource , apiResponseTimestamp time.Time , apiResponseErrors []* interfaces.ErrorMessage , forceLog bool ) error {
430463 if w .requestInfo == nil {
464+ cleanupFileBodySources (websocketTimelineSource , apiWebsocketTimelineSource )
431465 return nil
432466 }
433467
468+ if loggerWithSources , ok := w .logger .(interface {
469+ LogRequestWithOptionsAndSources (string , string , map [string ][]string , []byte , int , map [string ][]string , []byte , []byte , * logging.FileBodySource , []byte , []byte , []byte , * logging.FileBodySource , []* interfaces.ErrorMessage , bool , string , time.Time , time.Time ) error
470+ }); ok {
471+ return loggerWithSources .LogRequestWithOptionsAndSources (
472+ w .requestInfo .URL ,
473+ w .requestInfo .Method ,
474+ w .requestInfo .Headers ,
475+ requestBody ,
476+ statusCode ,
477+ headers ,
478+ body ,
479+ websocketTimeline ,
480+ websocketTimelineSource ,
481+ apiRequestBody ,
482+ apiResponseBody ,
483+ apiWebsocketTimeline ,
484+ apiWebsocketTimelineSource ,
485+ apiResponseErrors ,
486+ forceLog ,
487+ w .requestInfo .RequestID ,
488+ w .requestInfo .Timestamp ,
489+ apiResponseTimestamp ,
490+ )
491+ }
492+
493+ var errMerge error
494+ websocketTimeline , errMerge = mergeFileBodySource (websocketTimeline , websocketTimelineSource )
495+ if errMerge != nil {
496+ cleanupFileBodySources (apiWebsocketTimelineSource )
497+ return errMerge
498+ }
499+ apiWebsocketTimeline , errMerge = mergeFileBodySource (apiWebsocketTimeline , apiWebsocketTimelineSource )
500+ if errMerge != nil {
501+ return errMerge
502+ }
503+
434504 if loggerWithOptions , ok := w .logger .(interface {
435505 LogRequestWithOptions (string , string , map [string ][]string , []byte , int , map [string ][]string , []byte , []byte , []byte , []byte , []byte , []* interfaces.ErrorMessage , bool , string , time.Time , time.Time ) error
436506 }); ok {
@@ -472,3 +542,34 @@ func (w *ResponseWriterWrapper) logRequest(requestBody []byte, statusCode int, h
472542 apiResponseTimestamp ,
473543 )
474544}
545+
546+ func mergeFileBodySource (payload []byte , source * logging.FileBodySource ) ([]byte , error ) {
547+ if source == nil {
548+ return payload , nil
549+ }
550+ defer cleanupFileBodySources (source )
551+ if ! source .HasPayload () {
552+ return payload , nil
553+ }
554+ var buf bytes.Buffer
555+ if len (payload ) > 0 {
556+ buf .Write (payload )
557+ if ! bytes .HasSuffix (payload , []byte ("\n " )) {
558+ buf .WriteByte ('\n' )
559+ }
560+ buf .WriteByte ('\n' )
561+ }
562+ if errWrite := source .WriteTo (& buf ); errWrite != nil {
563+ return nil , errWrite
564+ }
565+ return buf .Bytes (), nil
566+ }
567+
568+ func cleanupFileBodySources (sources ... * logging.FileBodySource ) {
569+ for _ , source := range sources {
570+ if source == nil {
571+ continue
572+ }
573+ _ = source .Cleanup ()
574+ }
575+ }
0 commit comments