/
tracing.go
130 lines (113 loc) · 3.36 KB
/
tracing.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package tracing
import (
"fmt"
"net/url"
"strings"
rtrace "github.com/cs3org/reva/v2/pkg/trace"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"go.opentelemetry.io/otel/exporters/jaeger"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
)
// Propagator ensures the importer module uses the same trace propagation strategy.
var Propagator = propagation.NewCompositeTextMapPropagator(
propagation.Baggage{},
propagation.TraceContext{},
)
// GetTraceProvider returns a configured open-telemetry trace provider.
func GetTraceProvider(agentEndpoint, collectorEndpoint, serviceName, traceType string) (*sdktrace.TracerProvider, error) {
switch t := traceType; t {
case "", "jaeger":
var (
exp *jaeger.Exporter
err error
)
if agentEndpoint != "" {
var agentHost string
var agentPort string
agentHost, agentPort, err = parseAgentConfig(agentEndpoint)
if err != nil {
return nil, err
}
exp, err = jaeger.New(
jaeger.WithAgentEndpoint(
jaeger.WithAgentHost(agentHost),
jaeger.WithAgentPort(agentPort),
),
)
} else if collectorEndpoint != "" {
exp, err = jaeger.New(
jaeger.WithCollectorEndpoint(
jaeger.WithEndpoint(collectorEndpoint),
),
)
}
if err != nil {
return nil, err
}
rtrace.InitDefaultTracerProvider(collectorEndpoint, agentEndpoint)
return sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exp),
sdktrace.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String(serviceName)),
),
), nil
case "agent":
fallthrough
case "zipkin":
fallthrough
default:
return nil, fmt.Errorf("unknown trace type %s", traceType)
}
}
func parseAgentConfig(ae string) (string, string, error) {
u, err := url.Parse(ae)
// as per url.go:
// [...] Trying to parse a hostname and path
// without a scheme is invalid but may not necessarily return an
// error, due to parsing ambiguities.
if err == nil && u.Hostname() != "" && u.Port() != "" {
return u.Hostname(), u.Port(), nil
}
p := strings.Split(ae, ":")
if len(p) != 2 {
return "", "", fmt.Errorf(fmt.Sprintf("invalid agent endpoint `%s`. expected format: `hostname:port`", ae))
}
switch {
case p[0] == "" && p[1] == "": // case ae = ":"
return "", "", fmt.Errorf(fmt.Sprintf("invalid agent endpoint `%s`. expected format: `hostname:port`", ae))
case p[0] == "":
return "", "", fmt.Errorf(fmt.Sprintf("invalid agent endpoint `%s`. expected format: `hostname:port`", ae))
}
return p[0], p[1], nil
}
// Configure for Reva serves only as informational / instructive log messages. Tracing config will be delegated directly
// to Reva services.
func Configure(enabled bool, tracingType string, logger log.Logger) {
if enabled {
switch tracingType {
case "agent":
logger.Error().
Str("type", tracingType).
Msg("Reva only supports the jaeger tracing backend")
case "jaeger":
logger.Info().
Str("type", tracingType).
Msg("configuring storage to use the jaeger tracing backend")
case "zipkin":
logger.Error().
Str("type", tracingType).
Msg("Reva only supports the jaeger tracing backend")
default:
logger.Warn().
Str("type", tracingType).
Msg("Unknown tracing backend")
}
} else {
logger.Debug().
Msg("Tracing is not enabled")
}
}