github.com/pinpoint-apm/pinpoint-go-agent@v1.4.1-0.20240110120318-a50c2eb18c8c/tracer.go (about) 1 // Package pinpoint provides the APIs to instrument Go applications for Pinpoint (https://github.com/pinpoint-apm/pinpoint). 2 // 3 // This package enables you to monitor Go applications using Pinpoint. 4 // Go applications must be instrumented manually at the source code level, 5 // because Go is a compiled language and does not have a virtual machine like Java. 6 // Developers can instrument Go applications using the APIs provided in this package. 7 // It has support for instrumenting Go’s built-in http package, database/sql drivers 8 // and plug-ins for popular frameworks and toolkits (like Gin and gRPC, ...). 9 // 10 // In Pinpoint, a transaction consists of a group of Spans. 11 // Each span represents a trace of a single logical node where the transaction has gone through. 12 // A span records important function invocations and their related data(arguments, return value, etc.) 13 // before encapsulating them as SpanEvents in a call stack like representation. 14 // The span itself and each of its SpanEvents represents a function invocation. 15 // Find out more about the concept of Pinpoint at the links below: 16 // - https://pinpoint-apm.gitbook.io/pinpoint/documents/plugin-dev-guide 17 // - https://pinpoint-apm.gitbook.io/pinpoint/want-a-quick-tour/techdetail 18 package pinpoint 19 20 import ( 21 "context" 22 "fmt" 23 "time" 24 ) 25 26 // Agent instruments an application and makes spans and manages it. 27 type Agent interface { 28 // NewSpanTracer returns a span Tracer indicating the start of a transaction. 29 // A span is generated according to a given sampling policy, and trace data is not collected if not sampled. 30 NewSpanTracer(operation string, rpcName string) Tracer 31 32 // NewSpanTracerWithReader returns a span Tracer that continues a transaction passed from the previous node. 33 // A span is generated according to a given sampling policy, and trace data is not collected if not sampled. 34 // Distributed tracing headers are extracted from the reader. If it is empty, new transaction is started. 35 NewSpanTracerWithReader(operation string, rpcName string, reader DistributedTracingContextReader) Tracer 36 37 // Enable returns whether the agent is in an operational state. 38 Enable() bool 39 40 // Config returns the configuration associated with the agent. 41 Config() *Config 42 43 // Shutdown stops all related goroutines managing this agent. 44 // After Shutdown is called, the agent will never collect tracing data again. 45 Shutdown() 46 } 47 48 // Tracer instruments a single call stack of application and makes the result a single span. 49 type Tracer interface { 50 // NewSpanEvent returns a span event. 51 NewSpanEvent(operationName string) Tracer 52 53 // NewAsyncSpan is deprecated. Use NewGoroutineTracer. 54 NewAsyncSpan() Tracer 55 56 // NewGoroutineTracer returns a tracer that tracks the call stack of a goroutine. 57 NewGoroutineTracer() Tracer 58 59 // WrapGoroutine generates a tracer that tracks a given goroutine and passes it in context. 60 WrapGoroutine(goroutineName string, goroutine func(context.Context), ctx context.Context) func() 61 62 // EndSpan completes the span and transmits it to the collector. 63 // Sending a span is handled by a separate goroutine. 64 EndSpan() 65 66 // EndSpanEvent completes the span event. 67 EndSpanEvent() 68 69 // Inject injects distributed tracing headers to the writer. 70 Inject(writer DistributedTracingContextWriter) 71 72 // Extract extracts distributed tracing headers from the reader. 73 Extract(reader DistributedTracingContextReader) 74 75 // TransactionId returns the ID of the transaction containing the span. 76 TransactionId() TransactionId 77 78 // SpanId returns the ID of the span. 79 SpanId() int64 80 81 Span() SpanRecorder 82 SpanEvent() SpanEventRecorder 83 84 // IsSampled returns whether the span has been sampled. 85 IsSampled() bool 86 87 // AddMetric adds a custom metric. 88 AddMetric(metric string, value interface{}) 89 90 JsonString() []byte 91 } 92 93 // SpanRecorder records the collected data in the fields of Span. 94 type SpanRecorder interface { 95 // SetServiceType sets the type of service. 96 SetServiceType(typ int32) 97 98 // SetError Record an error and indicate that operation has failed. 99 SetError(e error) 100 101 // SetFailure indicate that operation has failed. 102 SetFailure() 103 104 // SetRpcName sets the name of RPC. 105 // This value is displayed as the path of the span on the pinpoint web screen. 106 SetRpcName(rpc string) 107 108 // SetRemoteAddress sets the remote address. 109 SetRemoteAddress(remoteAddress string) 110 111 // SetEndPoint sets the end point of RPC. 112 SetEndPoint(endPoint string) 113 114 // SetAcceptorHost sets the host of acceptor. 115 SetAcceptorHost(host string) 116 117 // SetLogging sets whether the Span has been logged. 118 SetLogging(logInfo int32) 119 120 // Annotations returns annotations that the Span holds. 121 Annotations() Annotation 122 } 123 124 // SpanEventRecorder records the collected data in the fields of SpanEvent. 125 type SpanEventRecorder interface { 126 // SetServiceType sets the type of service. 127 SetServiceType(typ int32) 128 129 // SetDestination sets the destination of operation. 130 SetDestination(id string) 131 132 // SetEndPoint sets the end point of operation. 133 SetEndPoint(endPoint string) 134 135 // SetError Record an error and indicate that operation has failed. 136 SetError(e error, errorName ...string) 137 138 // SetSQL records the SQL string and bind variables. 139 SetSQL(sql string, args string) 140 141 // Annotations returns annotations that the SpanEvent holds. 142 Annotations() Annotation 143 144 // FixDuration fixes the elapsed time of operation. 145 FixDuration(start time.Time, end time.Time) 146 } 147 148 // Annotation is a key-value pair and used to annotate Span and SpanEvent with more information. 149 type Annotation interface { 150 // AppendInt records an integer value to annotation. 151 AppendInt(key int32, i int32) 152 153 // AppendLong records a long value to annotation. 154 AppendLong(key int32, l int64) 155 156 // AppendString records a string value to annotation. 157 AppendString(key int32, s string) 158 159 // AppendStringString records two string values to annotation. 160 AppendStringString(key int32, s1 string, s2 string) 161 162 // AppendIntStringString records an integer value and two string values to annotation. 163 AppendIntStringString(key int32, i int32, s1 string, s2 string) 164 165 // AppendBytesStringString records an array of byte and two string values to annotation. 166 AppendBytesStringString(key int32, b []byte, s1 string, s2 string) 167 168 // AppendLongIntIntByteByteString records a long integer value, two integer value, two byte value and a string value to annotation. 169 AppendLongIntIntByteByteString(key int32, l int64, i1 int32, i2 int32, b1 int32, b2 int32, s string) 170 } 171 172 // DistributedTracingContextReader reads distributed tracing headers from carrier. 173 type DistributedTracingContextReader interface { 174 // Get returns the value of a given key from carrier. 175 Get(key string) string 176 } 177 178 // DistributedTracingContextWriter writes distributed tracing headers to carrier. 179 type DistributedTracingContextWriter interface { 180 // Set sets a given key-value pair to carrier. 181 Set(key string, value string) 182 } 183 184 // keys of distributed tracing headers 185 const ( 186 HeaderTraceId = "Pinpoint-TraceID" 187 HeaderSpanId = "Pinpoint-SpanID" 188 HeaderParentSpanId = "Pinpoint-pSpanID" 189 HeaderSampled = "Pinpoint-Sampled" 190 HeaderFlags = "Pinpoint-Flags" 191 HeaderParentApplicationName = "Pinpoint-pAppName" 192 HeaderParentApplicationType = "Pinpoint-pAppType" 193 HeaderParentApplicationNamespace = "Pinpoint-pAppNamespace" 194 HeaderHost = "Pinpoint-Host" 195 ) 196 197 // TransactionId represents that different RPCs are associated with each other as a single transaction. 198 type TransactionId struct { 199 AgentId string 200 StartTime int64 201 Sequence int64 202 } 203 204 // String returns transaction id string. 205 func (tid TransactionId) String() string { 206 return fmt.Sprintf("%s^%d^%d", tid.AgentId, tid.StartTime, tid.Sequence) 207 } 208 209 type UrlStatEntry struct { 210 Url string 211 Method string 212 Status int 213 } 214 215 // service types pre-defined 216 const ( 217 ServiceTypeGoApp = 1800 218 ServiceTypeGoFunction = 1801 219 ServiceTypeGoHttpClient = 9401 220 ServiceTypeAsync = 100 221 ServiceTypeMysql = 2100 222 ServiceTypeMysqlExecuteQuery = 2101 223 ServiceTypeMssql = 2200 224 ServiceTypeMssqlExecuteQuery = 2201 225 ServiceTypeOracle = 2300 226 ServiceTypeOracleExecuteQuery = 2301 227 ServiceTypePgSql = 2500 228 ServiceTypePgSqlExecuteQuery = 2501 229 ServiceTypeCassandraExecuteQuery = 2601 230 ServiceTypeMongo = 2650 231 ServiceTypeMongoExecuteQuery = 2651 232 ServiceTypeGrpc = 9160 233 ServiceTypeGrpcServer = 1130 234 ServiceTypeMemcached = 8050 235 ServiceTypeRedis = 8203 236 ServiceTypeKafkaClient = 8660 237 ServiceTypeHbaseClient = 8800 238 ServiceTypeGoElastic = 9204 239 ) 240 241 // annotation keys pre-defined 242 const ( 243 AnnotationArgs0 = -1 244 AnnotationApi = 12 245 AnnotationSqlId = 20 246 AnnotationSqlUid = 25 247 AnnotationHttpUrl = 40 248 AnnotationHttpParam = 41 249 AnnotationHttpCookie = 45 250 AnnotationHttpStatusCode = 46 251 AnnotationHttpRequestHeader = 47 252 AnnotationHttpResponseHeader = 55 253 AnnotationHttpProxyHeader = 300 254 AnnotationKafkaTopic = 140 255 AnnotationKafkaPartition = 141 256 AnnotationKafkaOffset = 142 257 AnnotationMongoJasonData = 150 258 AnnotationMongoCollectionInfo = 151 259 AnnotationEsDsl = 173 260 AnnotationHbaseClientParams = 320 261 AnnotationExceptionChainId = -52 262 ) 263 264 const ( 265 LogTransactionIdKey = "PtxId" 266 LogSpanIdKey = "PspanId" 267 Logged = 1 268 NotLogged = 0 269 MetricURLStat = "URLStat" 270 )