# README
logtracing
This package is a toolkit for log-based tracing. It provides several APIs for adding traces for the application and logging them in a standard format.
Usage
Import the package
import 'github.com/theplant/appkit/logtracing'
Inside a function, you can use these three APIs to track it:
StartSpan(context.Context, string)
to start a spanEndSpan(context.Context, error)
to end the span, also log it in an agreed formatRecordPanic(context.Context)
to record the panic into the span
func DoWork(ctx context.Context) err error {
ctx, _ := logtracing.StartSpan(ctx, "<span.context>")
defer func() { logtracing.EndSpan(ctx, err) }()
defer RecordPanic(ctx)
}
It will create a new span, record the error, and log the span with the logger in context.
You can append key-values to an active span with AppendSpanKvs
:
func DoWork(ctx context.Context) err error {
ctx, _ := logtracing.StartSpan(ctx, "<span.context>")
defer func() { logtracing.EndSpan(ctx, err) }()
defer RecordPanic(ctx)
logtracing.AppendSpanKVs(ctx,
"service", "greeter",
)
}
If you want to append key-values to all spans, you can append the key-values to the context with ContextWithKVs
:
func DoWork(ctx context.Context) err error {
// all the spans within this context will contain `"key": "value"`
ctx = logtracing.ContextWithKVs(ctx, "key", "value")
ctx, _ = logtracing.StartSpan(ctx, "test")
defer func() { logtracing.EndSpan(ctx, err) }()
defer RecordPanic(ctx)
}
For flexibility, the package provides the following APIs to manipulate the span directly:
(*span).AppendKVs(...interface{})
(*span).RecordError(err error)
(*span).RecordPanic(panic interface{}})
(*span).End()
LogSpan(ctx context, s *span)
Key-values
Common
With logtracing.StartSpan
and logtracing.EndSpan
, these are automatically added to the span:
ts
msg
trace.id
span.id
span.context
span.dur_ms
span.parent_id
If the span records an error, these key-values will be added:
span.err
span.err_type
span.with_err
Reference
span.type
: This usually describes "how" the span is sent/received, what kind of underlying API or network transport is used, eghttp
,sql
,grpc
,dns
,aws.<service>
span.role
: This describes what role this span plays in an interaction with another service, eg for HTTP aclient
makes a request to aserver
. Or in aqueue
, aproducer
adds work to the queue, that is consumed by aconsumer
.
Data that is for specific types should use the type as a prefix when adding supplementary keys-values, For example:
-
With
span.type=http
, the HTTP method would be logged ashttp.method
, the response status would be logged ashttp.status=200
. -
AWS S3 API calls (
span.type=aws.s3
), uses3
oraws.s3
as a prefix, an object used in the API call could be logged ass3.object=<object key>
(oraws.s3.object=<object key>
)
XMLRPC
span.type
:xmlrpc
span.role
:client
xmlrpc.method
: the service methodhttp.method
:post
http.url
: the server URLxmlrpc.fault_string
: only exists when getting a fault error
GRPC
span.type
:grpc
span.role
:client
orserver
grpc.service
: gRPC service namegrpc.method
: gRPC method namegrpc.code
: gRPC response status code
The package provides server and client interceptors to log these key-values automatically.
HTTP
For the client requests:
span.type
:http
span.role
:client
http.url
: the request full URLhttp.method
: the request methodhttp.status
: the response status, only exists when getting the response successfully
For the server requests:
span.type
:http
span.role
:server
http.path
: the request pathhttp.method
: the request methodhttp.user_agent
: the request user agenthttp.client_ip
: the request client IPhttp.status
: the response status
Queue
span.type
:queue
span.role
:consumer
orproducer
Function
For internal functions:
span.role
:internal
Export span data
You can export span data to an expected destination such as Honeycomb by registering an exporter.
- Implement the
Exporter
interface:type Exporter interface { ExportSpan(s *SpanData) }
- Initialize and register your exporter:
exporter := <your exporter> logtracing.RegisterExporter(exporter)
When you register exporters, logtracing
will pass sampled spans to the exporters after logging.
Honeycomb exporter
You can use this exporter to send spans to Honeycomb. The sent events are in the same format as the logged events.
- Import the package:
import github.com/theplant/appkit/logtracing/exporters/honeycomb
- Initialize the exporter:
exporter, err := honeycomb.NewExporter(libhoney.Config{ WriteKey: "mock", Dataset: "mock", Transmission: mockSender, }) ```
- Register the exporter:
logtracing.RegisterExporter(expoter)
How to migrate from util/trace.go
- Use
logtracing.TraceFunc
to replaceutil.Lt
- Use
logtracing.AppendSpanKVs
to replaceutil.AppendKVs
- Use
logtracing.TraceHTTPRequest
to replaceutil.LtRequest
- Use
logtracing.HTTPTransport
to replaceutil.LtTransport
- Use
logtracing.XMLRPCClientKVs
to replaceutil.XMLRpcKVs