Tracing
In microservices, link tracing is a very important capability, which plays an important role in quickly locating problems, analyzing business bottlenecks, and restoring the link status of a request. Hertz provides the capability of link tracking and also supports user-defined link tracking.
Hertz abstracts trace as the following interface:
// Tracer is executed at the start and finish of an HTTP.
type Tracer interface {
Start(ctx context.Context, c *app.RequestContext) context.Context
Finish(ctx context.Context, c *app.RequestContext)
}
Use the server.WithTracer()
configuration to add a tracer, you can add multiple tracers.
Hertz will execute the Start method of all tracers before the request starts (before reading the packet), and execute the Finish method of all tracers after the request ends (after writing back the data). Care should be taken when implementing this:
- When the Start method is executed, it just starts accepting packets, and at this time
requestContext
is an “empty”requestContext
, so we can’t get information about this request. If you want to get some information (such as the traceID in the header, etc.) after unpacking, you can use the middleware capability to inject the traceID into the span. - Changes to the context within the middleware are invalid.
There is traceInfo
in the requestContext
memory, which has the following information
type HTTPStats interface {
Record(event stats.Event, status stats.Status, info string) // Recording events
GetEvent(event stats.Event) Event // Get events
SendSize() int // Get SendSize
RecvSize() int // Get RecvSize
Error() error // Get Error
Panicked() (bool, interface{}) // Get Panic
Level() stats.Level // Get the current trace level
SetLevel(level stats.Level) // Set the trace level to not report when the event level is higher than the trace level
...
}
Events include:
HTTPStart = newEvent(httpStart, LevelBase) // Request start
HTTPFinish = newEvent(httpFinish, LevelBase) // Request end
ServerHandleStart = newEvent(serverHandleStart, LevelDetailed) // Business handler start
ServerHandleFinish = newEvent(serverHandleFinish, LevelDetailed) // Business handler end
ReadHeaderStart = newEvent(readHeaderStart, LevelDetailed) // Read header start
ReadHeaderFinish = newEvent(readHeaderFinish, LevelDetailed) // Read header end
ReadBodyStart = newEvent(readBodyStart, LevelDetailed) // Read body start
ReadBodyFinish = newEvent(readBodyFinish, LevelDetailed) // Read body end
WriteStart = newEvent(writeStart, LevelDetailed) // Write response start
WriteFinish = newEvent(writeFinish, LevelDetailed) // Write response end
The above information is available at Finish
At the same time, if you don’t want to log this information, you don’t have to register any tracer, and the framework stops logging this information.
An extension for opentracing is provided in hertz-contrib, and a demo for calling from http to rpc is also available in hertz-examples.
Related Repository: https://github.com/hertz-contrib/tracer