github.com/waldiirawan/apm-agent-go/v2@v2.2.2/fmt.go (about)

     1  // Licensed to Elasticsearch B.V. under one or more contributor
     2  // license agreements. See the NOTICE file distributed with
     3  // this work for additional information regarding copyright
     4  // ownership. Elasticsearch B.V. licenses this file to you under
     5  // the Apache License, Version 2.0 (the "License"); you may
     6  // not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing,
    12  // software distributed under the License is distributed on an
    13  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    14  // KIND, either express or implied.  See the License for the
    15  // specific language governing permissions and limitations
    16  // under the License.
    17  
    18  package apm // import "github.com/waldiirawan/apm-agent-go/v2"
    19  
    20  import (
    21  	"context"
    22  	"fmt"
    23  	"io"
    24  )
    25  
    26  // TraceFormatter returns a fmt.Formatter that can be used to
    27  // format the identifiers of the transaction and span in ctx.
    28  //
    29  // The returned Formatter understands the following verbs:
    30  //
    31  //	%v: trace ID, transaction ID, and span ID (if existing), space-separated
    32  //	    the plus flag (%+v) adds field names, e.g. "trace.id=... transaction.id=..."
    33  //	%t: trace ID (hex-encoded, or empty string if non-existent)
    34  //	    the plus flag (%+T) adds the field name, e.g. "trace.id=..."
    35  //	%x: transaction ID (hex-encoded, or empty string if non-existent)
    36  //	    the plus flag (%+t) adds the field name, e.g. "transaction.id=..."
    37  //	%s: span ID (hex-encoded, or empty string if non-existent)
    38  //	    the plus flag (%+s) adds the field name, e.g. "span.id=..."
    39  func TraceFormatter(ctx context.Context) fmt.Formatter {
    40  	f := traceFormatter{tx: TransactionFromContext(ctx)}
    41  	if f.tx != nil {
    42  		f.span = SpanFromContext(ctx)
    43  	}
    44  	return f
    45  }
    46  
    47  type traceFormatter struct {
    48  	tx   *Transaction
    49  	span *Span
    50  }
    51  
    52  func (t traceFormatter) Format(f fmt.State, c rune) {
    53  	switch c {
    54  	case 'v':
    55  		if t.tx != nil {
    56  			t.writeField(f, "trace.id", t.tx.TraceContext().Trace.String())
    57  			f.Write([]byte{' '})
    58  			t.writeField(f, "transaction.id", t.tx.TraceContext().Span.String())
    59  			if t.span != nil {
    60  				f.Write([]byte{' '})
    61  				t.writeField(f, "span.id", t.span.TraceContext().Span.String())
    62  			}
    63  		}
    64  	case 't':
    65  		if t.tx != nil {
    66  			t.writeField(f, "trace.id", t.tx.TraceContext().Trace.String())
    67  		}
    68  	case 'x':
    69  		if t.tx != nil {
    70  			t.writeField(f, "transaction.id", t.tx.TraceContext().Span.String())
    71  		}
    72  	case 's':
    73  		if t.span != nil {
    74  			t.writeField(f, "span.id", t.span.TraceContext().Span.String())
    75  		}
    76  	}
    77  }
    78  
    79  func (t traceFormatter) writeField(f fmt.State, name, value string) {
    80  	if f.Flag('+') {
    81  		io.WriteString(f, name)
    82  		f.Write([]byte{'='})
    83  	}
    84  	io.WriteString(f, value)
    85  }