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 }