github.com/instana/go-sensor@v1.62.2-0.20240520081010-4919868049e1/delayed_spans.go (about)

     1  // (c) Copyright IBM Corp. 2022
     2  
     3  package instana
     4  
     5  import (
     6  	"net/url"
     7  )
     8  
     9  const maxDelayedSpans = 500
    10  
    11  var delayed = &delayedSpans{
    12  	spans: make(chan *spanS, maxDelayedSpans),
    13  }
    14  
    15  type delayedSpans struct {
    16  	spans chan *spanS
    17  }
    18  
    19  // append add a span to the buffer if buffer is not full yet
    20  func (ds *delayedSpans) append(span *spanS) bool {
    21  	select {
    22  	case ds.spans <- span:
    23  		return true
    24  	default:
    25  		return false
    26  	}
    27  }
    28  
    29  // flush processes buffered spans and move them from the delayed buffer to the recorder if agent is ready
    30  func (ds *delayedSpans) flush() {
    31  	for {
    32  		select {
    33  		case s := <-ds.spans:
    34  			t, ok := s.Tracer().(Tracer)
    35  			if !ok {
    36  				sensor.logger.Debug("span tracer has unexpected type")
    37  				continue
    38  			}
    39  
    40  			if err := ds.processSpan(s, t.Options()); err != nil {
    41  				sensor.logger.Debug("error while processing spans:", err.Error())
    42  				continue
    43  			}
    44  
    45  			if sensor.Agent().Ready() {
    46  				s.tracer.recorder.RecordSpan(s)
    47  			} else {
    48  				ds.append(s)
    49  				return
    50  			}
    51  		default:
    52  			return
    53  		}
    54  	}
    55  }
    56  
    57  // processSpan applies secret filtering to the buffered http span http.params tag
    58  func (ds *delayedSpans) processSpan(s *spanS, opts TracerOptions) error {
    59  	newParams := url.Values{}
    60  	if paramsTag, ok := s.Tags["http.params"]; ok {
    61  		if httpParams, ok := paramsTag.(string); ok {
    62  			p, err := url.ParseQuery(httpParams)
    63  			if err != nil {
    64  				return err
    65  			}
    66  
    67  			for key, value := range p {
    68  				if opts.Secrets.Match(key) {
    69  					newParams[key] = []string{"<redacted>"}
    70  				} else {
    71  					newParams[key] = value
    72  				}
    73  			}
    74  		}
    75  	}
    76  
    77  	if len(newParams) > 0 {
    78  		s.SetTag("http.params", newParams.Encode())
    79  	}
    80  
    81  	return nil
    82  }