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  )