Skip to content

Commit 8e7c11f

Browse files
committed
tracegen: add capability to marshal spans to file
Signed-off-by: Samriddha9619 <[email protected]>
1 parent b7f13fa commit 8e7c11f

File tree

3 files changed

+86
-62
lines changed

3 files changed

+86
-62
lines changed

cmd/tracegen/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ The binary is available from the Releases page, as well as a Docker image:
99
$ docker run jaegertracing/jaeger-tracegen -service abcd -traces 10
1010
```
1111

12-
The generator can be configured to export traces in different formats, via `-exporter` flag.
1312
By default, the exporters send data to `localhost`. If running in a container, this refers
1413
to the networking namespace of the container itself, so to export to another container,
1514
the exporters need to be provided with appropriate location.

cmd/tracegen/main.go

Lines changed: 85 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"errors"
99
"flag"
1010
"fmt"
11+
"os"
12+
"strings"
1113
"time"
1214

1315
"github.com/go-logr/zapr"
@@ -66,77 +68,100 @@ func main() {
6668
}
6769

6870
func createTracers(cfg *tracegen.Config, logger *zap.Logger) ([]trace.Tracer, func(context.Context) error) {
69-
if cfg.Services < 1 {
70-
cfg.Services = 1
71-
}
72-
var shutdown []func(context.Context) error
73-
var tracers []trace.Tracer
74-
for s := 0; s < cfg.Services; s++ {
75-
svc := cfg.Service
76-
if cfg.Services > 1 {
77-
svc = fmt.Sprintf("%s-%02d", svc, s)
78-
}
79-
80-
exp, err := createOtelExporter(cfg.TraceExporter)
81-
if err != nil {
82-
logger.Sugar().Fatalf("cannot create trace exporter %s: %s", cfg.TraceExporter, err)
83-
}
84-
logger.Sugar().Infof("using %s trace exporter for service %s", cfg.TraceExporter, svc)
85-
86-
res, err := resource.New(
87-
context.Background(),
88-
resource.WithSchemaURL(otelsemconv.SchemaURL),
89-
resource.WithAttributes(otelsemconv.ServiceNameAttribute(svc)),
90-
resource.WithTelemetrySDK(),
91-
resource.WithHost(),
92-
resource.WithOSType(),
93-
)
94-
if err != nil {
95-
logger.Sugar().Fatalf("resource creation failed: %s", err)
96-
}
97-
98-
opts := []sdktrace.TracerProviderOption{
99-
sdktrace.WithBatcher(exp, sdktrace.WithBlocking()),
100-
sdktrace.WithResource(res),
101-
}
102-
if flagAdaptiveSamplingEndpoint != "" {
103-
jaegerRemoteSampler := jaegerremote.New(
104-
svc,
105-
jaegerremote.WithSamplingServerURL(flagAdaptiveSamplingEndpoint),
106-
jaegerremote.WithSamplingRefreshInterval(5*time.Second),
107-
jaegerremote.WithInitialSampler(sdktrace.TraceIDRatioBased(0.5)),
71+
if cfg.Services < 1 {
72+
cfg.Services = 1
73+
}
74+
var shutdown []func(context.Context) error
75+
var tracers []trace.Tracer
76+
77+
var file *os.File
78+
exporterType := cfg.TraceExporter
79+
80+
if strings.HasPrefix(cfg.TraceExporter, "file:") {
81+
filename := strings.TrimPrefix(cfg.TraceExporter, "file:")
82+
var err error
83+
file, err = os.Create(filename)
84+
if err != nil {
85+
logger.Sugar().Fatalf("cannot create output file %s: %s", filename, err)
86+
}
87+
exporterType = "stdout"
88+
}
89+
90+
for s := 0; s < cfg.Services; s++ {
91+
svc := cfg.Service
92+
if cfg.Services > 1 {
93+
svc = fmt.Sprintf("%s-%02d", svc, s)
94+
}
95+
96+
exp, err := createOtelExporter(exporterType, file)
97+
if err != nil {
98+
logger.Sugar().Fatalf("cannot create trace exporter %s: %s", cfg.TraceExporter, err)
99+
}
100+
logger.Sugar().Infof("using %s trace exporter for service %s", cfg.TraceExporter, svc)
101+
102+
res, err := resource.New(
103+
context.Background(),
104+
resource.WithSchemaURL(otelsemconv.SchemaURL),
105+
resource.WithAttributes(otelsemconv.ServiceNameAttribute(svc)),
106+
resource.WithTelemetrySDK(),
107+
resource.WithHost(),
108+
resource.WithOSType(),
109+
)
110+
if err != nil {
111+
logger.Sugar().Fatalf("resource creation failed: %s", err)
112+
}
113+
114+
opts := []sdktrace.TracerProviderOption{
115+
sdktrace.WithBatcher(exp, sdktrace.WithBlocking()),
116+
sdktrace.WithResource(res),
117+
}
118+
if flagAdaptiveSamplingEndpoint != "" {
119+
jaegerRemoteSampler := jaegerremote.New(
120+
svc,
121+
jaegerremote.WithSamplingServerURL(flagAdaptiveSamplingEndpoint),
122+
jaegerremote.WithSamplingRefreshInterval(5*time.Second),
123+
jaegerremote.WithInitialSampler(sdktrace.TraceIDRatioBased(0.5)),
108124
)
109-
opts = append(opts, sdktrace.WithSampler(jaegerRemoteSampler))
110-
logger.Sugar().Infof("using adaptive sampling URL: %s", flagAdaptiveSamplingEndpoint)
111-
}
112-
tp := sdktrace.NewTracerProvider(opts...)
113-
tracers = append(tracers, tp.Tracer(cfg.Service))
114-
shutdown = append(shutdown, tp.Shutdown)
115-
}
116-
return tracers, func(ctx context.Context) error {
117-
var errs []error
118-
for _, f := range shutdown {
119-
errs = append(errs, f(ctx))
120-
}
121-
return errors.Join(errs...)
122-
}
125+
opts = append(opts, sdktrace.WithSampler(jaegerRemoteSampler))
126+
logger.Sugar().Infof("using adaptive sampling URL: %s", flagAdaptiveSamplingEndpoint)
127+
}
128+
tp := sdktrace.NewTracerProvider(opts...)
129+
tracers = append(tracers, tp.Tracer(cfg.Service))
130+
shutdown = append(shutdown, tp.Shutdown)
131+
}
132+
133+
if file != nil {
134+
shutdown = append(shutdown, func(_ context.Context) error {
135+
return file.Close()
136+
})
137+
}
138+
139+
return tracers, func(ctx context.Context) error {
140+
var errs []error
141+
for _, f := range shutdown {
142+
errs = append(errs, f(ctx))
143+
}
144+
return errors.Join(errs...)
145+
}
123146
}
124147

125-
func createOtelExporter(exporterType string) (sdktrace.SpanExporter, error) {
148+
func createOtelExporter(exporterType string, fileWriter *os.File) (sdktrace.SpanExporter, error) {
149+
if fileWriter != nil {
150+
return stdouttrace.New(
151+
stdouttrace.WithWriter(fileWriter),
152+
)
153+
}
154+
126155
var exporter sdktrace.SpanExporter
127156
var err error
128157
switch exporterType {
129158
case "jaeger":
130159
return nil, errors.New("jaeger exporter is no longer supported, please use otlp")
131160
case "otlp", "otlp-http":
132-
client := otlptracehttp.NewClient(
133-
otlptracehttp.WithInsecure(),
134-
)
161+
client := otlptracehttp.NewClient(otlptracehttp.WithInsecure())
135162
exporter, err = otlptrace.New(context.Background(), client)
136163
case "otlp-grpc":
137-
client := otlptracegrpc.NewClient(
138-
otlptracegrpc.WithInsecure(),
139-
)
164+
client := otlptracegrpc.NewClient(otlptracegrpc.WithInsecure())
140165
exporter, err = otlptrace.New(context.Background(), client)
141166
case "stdout":
142167
exporter, err = stdouttrace.New()

internal/tracegen/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func (c *Config) Flags(fs *flag.FlagSet) {
4646
fs.DurationVar(&c.Duration, "duration", 0, "For how long to run the test if greater than 0s (overrides -traces).")
4747
fs.StringVar(&c.Service, "service", "tracegen", "Service name prefix to use")
4848
fs.IntVar(&c.Services, "services", 1, "Number of unique suffixes to add to service name when generating traces, e.g. tracegen-01 (but only one service per trace)")
49-
fs.StringVar(&c.TraceExporter, "trace-exporter", "otlp-http", "Trace exporter (otlp/otlp-http|otlp-grpc|stdout). Exporters can be additionally configured via environment variables, see https://github.com/jaegertracing/jaeger/blob/main/cmd/tracegen/README.md")
49+
fs.StringVar(&c.TraceExporter, "trace-exporter", "otlp-http", "Trace exporter (otlp/otlp-http|otlp-grpc|stdout|file:{filename}). Exporters can be additionally configured via environment variables, see https://github.com/jaegertracing/jaeger/blob/main/cmd/tracegen/README.md")
5050
}
5151

5252
// Run executes the test scenario.

0 commit comments

Comments
 (0)