-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathtrace.go
123 lines (112 loc) · 3.32 KB
/
trace.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
package logx
import (
"encoding/json"
"io"
"os"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/jaeger"
"go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
"go.opentelemetry.io/otel/sdk/resource"
"go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
)
type Trace struct{}
// NewJaegerProvider
func (tx Trace) NewJaegerProvider(conf Config,
attributes ...Field,
) (*trace.TracerProvider, error) {
exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(conf.JaegerServer),
jaeger.WithUsername(conf.JaegerUsername),
jaeger.WithPassword(conf.JaegerPassword)))
if err != nil {
return nil, err
}
if conf.TraceSampleRatio > 1 {
conf.TraceSampleRatio = 1
}
if conf.TraceSampleRatio < 0 {
conf.TraceSampleRatio = 0
}
tp := trace.NewTracerProvider(
// Always be sure to batch in production.
trace.WithBatcher(exp),
// Record information about this application in an Resource.
trace.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
FieldsToKeyValues(attributes...)...,
)),
trace.WithSampler(trace.TraceIDRatioBased(conf.TraceSampleRatio)),
)
otel.SetTracerProvider(tp)
return tp, nil
}
// NewFileProvider
func (tx Trace) NewFileProvider(conf Config, attributes ...Field) (*trace.TracerProvider, error) {
f, _ := os.Create("trace.txt")
exp, _ := newExporter(f)
tp := trace.NewTracerProvider(
// Always be sure to batch in production.
trace.WithBatcher(exp),
// Record information about this application in an Resource.
trace.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
FieldsToKeyValues(attributes...)...,
)),
trace.WithSampler(trace.AlwaysSample()),
)
otel.SetTracerProvider(tp)
return tp, nil
}
func newExporter(w io.Writer) (trace.SpanExporter, error) {
return stdouttrace.New(
stdouttrace.WithWriter(w),
// Use human-readable output.
stdouttrace.WithPrettyPrint(),
// Do not print timestamps for the demo.
stdouttrace.WithoutTimestamps(),
)
}
// FieldsToKeyValue
func FieldsToKeyValues(fields ...Field) []attribute.KeyValue {
kvs := []attribute.KeyValue{}
for _, f := range fields {
switch f.Type {
case boolType:
kvs = append(kvs, attribute.Bool(f.Key, f.Bool))
case boolSliceType:
kvs = append(kvs, attribute.BoolSlice(f.Key, f.Bools))
case intType:
kvs = append(kvs, attribute.Int(f.Key, f.Integer))
case intSliceType:
kvs = append(kvs, attribute.IntSlice(f.Key, f.Integers))
case int64Type:
kvs = append(kvs, attribute.Int64(f.Key, f.Integer64))
case int64SliceType:
kvs = append(kvs, attribute.Int64Slice(f.Key, f.Integer64s))
case float64Type:
kvs = append(kvs, attribute.Float64(f.Key, f.Float64))
case float64SliceType:
kvs = append(kvs, attribute.Float64Slice(f.Key, f.Float64s))
case stringType:
kvs = append(kvs, attribute.String(f.Key, f.String))
case stringSliceType:
kvs = append(kvs, attribute.StringSlice(f.Key, f.Strings))
case stringerType:
stringer := stringer{str: f.String}
kvs = append(kvs, attribute.Stringer(f.Key, stringer))
case anyType:
if str, err := json.Marshal(f.Any); err == nil {
kvs = append(kvs, attribute.String(f.Key, string(str)))
}
}
}
return kvs
}
// stringer fmt.Stringer
type stringer struct {
str string
}
func (s stringer) String() string {
return s.str
}