2020-10-21 15:19:27 +03:00
|
|
|
package rediscensus
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2023-01-26 09:23:14 +03:00
|
|
|
"net"
|
2020-10-21 15:19:27 +03:00
|
|
|
|
2021-09-08 16:00:52 +03:00
|
|
|
"go.opencensus.io/trace"
|
|
|
|
|
2023-01-23 09:48:54 +03:00
|
|
|
"github.com/redis/go-redis/extra/rediscmd/v9"
|
|
|
|
"github.com/redis/go-redis/v9"
|
2020-10-21 15:19:27 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
type TracingHook struct{}
|
|
|
|
|
2021-04-16 15:00:10 +03:00
|
|
|
var _ redis.Hook = (*TracingHook)(nil)
|
|
|
|
|
|
|
|
func NewTracingHook() *TracingHook {
|
|
|
|
return new(TracingHook)
|
|
|
|
}
|
2020-10-21 15:19:27 +03:00
|
|
|
|
2023-01-26 09:23:14 +03:00
|
|
|
func (TracingHook) DialHook(next redis.DialHook) redis.DialHook {
|
|
|
|
return func(ctx context.Context, network, addr string) (net.Conn, error) {
|
|
|
|
ctx, span := trace.StartSpan(ctx, "dial")
|
|
|
|
defer span.End()
|
2020-10-21 15:19:27 +03:00
|
|
|
|
2023-01-26 09:23:14 +03:00
|
|
|
span.AddAttributes(
|
|
|
|
trace.StringAttribute("db.system", "redis"),
|
|
|
|
trace.StringAttribute("network", network),
|
|
|
|
trace.StringAttribute("addr", addr),
|
|
|
|
)
|
|
|
|
|
|
|
|
conn, err := next(ctx, network, addr)
|
|
|
|
if err != nil {
|
|
|
|
recordErrorOnOCSpan(ctx, span, err)
|
2020-10-21 15:19:27 +03:00
|
|
|
|
2023-01-26 09:23:14 +03:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return conn, nil
|
2020-10-21 15:19:27 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-26 09:23:14 +03:00
|
|
|
func (TracingHook) ProcessHook(next redis.ProcessHook) redis.ProcessHook {
|
|
|
|
return func(ctx context.Context, cmd redis.Cmder) error {
|
|
|
|
ctx, span := trace.StartSpan(ctx, cmd.FullName())
|
|
|
|
defer span.End()
|
|
|
|
|
|
|
|
span.AddAttributes(
|
|
|
|
trace.StringAttribute("db.system", "redis"),
|
|
|
|
trace.StringAttribute("redis.cmd", rediscmd.CmdString(cmd)),
|
|
|
|
)
|
|
|
|
|
|
|
|
err := next(ctx, cmd)
|
|
|
|
if err != nil {
|
|
|
|
recordErrorOnOCSpan(ctx, span, err)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = cmd.Err(); err != nil {
|
|
|
|
recordErrorOnOCSpan(ctx, span, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2020-10-21 15:19:27 +03:00
|
|
|
}
|
|
|
|
|
2023-01-26 09:23:14 +03:00
|
|
|
func (TracingHook) ProcessPipelineHook(next redis.ProcessPipelineHook) redis.ProcessPipelineHook {
|
|
|
|
return next
|
2020-10-21 15:19:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func recordErrorOnOCSpan(ctx context.Context, span *trace.Span, err error) {
|
|
|
|
if err != redis.Nil {
|
|
|
|
span.AddAttributes(trace.BoolAttribute("error", true))
|
|
|
|
span.Annotate([]trace.Attribute{trace.StringAttribute("Error", "redis error")}, err.Error())
|
|
|
|
}
|
|
|
|
}
|