Skip to content

Conversation

@Samriddha9619
Copy link

@Samriddha9619 Samriddha9619 commented Dec 4, 2025

Which problem is this PR solving?

Description of the changes

  • Added a new configuration flag -marshal-to-file to internal/tracegen/config.go.
  • Updated cmd/tracegen/main.go to intercept the exporter creation logic.
  • When the flag is set, the OTel stdout exporter is initialized with a custom os.File writer instead of the default os.Stdout.
  • This allows separating the JSON span data (written to file) from application logs (written to console), ensuring the output is valid JSON suitable for replay.
  • Implemented proper shutdown ordering: ensuring the TracerProvider flushes all spans to the exporter before the file handle is closed.

How was this change tested?

  • Manual Verification:
    • Ran command: ./tracegen -marshal-to-file=test.json -traces=1
    • Verified test.json contains valid, clean JSON span data with no log corruption.
    • Verified application logs (INFO level) still appear in the console.
  • Lint & Test:
    • Ran golangci-lint on modified packages (passed).
    • Ran go test ./internal/tracegen/... (passed).

Checklist

@Samriddha9619 Samriddha9619 requested a review from a team as a code owner December 4, 2025 19:59
@dosubot dosubot bot added the enhancement label Dec 4, 2025
@yurishkuro
Copy link
Member

Part 1 of Resolves #xxxx

When you have text Resolves #xxxx this PR will close the issue. If it's only a partial change then say Part of #xxxx

if fileWriter != nil {
return stdouttrace.New(
stdouttrace.WithWriter(fileWriter),
stdouttrace.WithPrettyPrint(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you need pretty-print for what is meant to be a machine-readable format?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry, I did it for debugging, but you're right, production doesn't need it

@Samriddha9619 Samriddha9619 force-pushed the feature/tracegen-file-export branch from 9dcee2c to bbb5126 Compare December 5, 2025 03:19
fs.StringVar(&c.Service, "service", "tracegen", "Service name prefix to use")
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)")
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")
fs.StringVar(&c.ExportToFile, "export-to-file", "", "Filename to write generated spans to (in JSON format) instead of sending to a collector")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just thinking - adding this new option creates an ambiguity, which one takes precedence, this one or trace-exporter. We can keep it to a single flag if we allow file:{filename} syntax.

Btw the README incorrectly says the option name is -exporter, can you fix it in the same PR?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

if err != nil {
logger.Sugar().Fatalf("cannot create output file %s: %s", filename, err)
}
exporterType = "stdout"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pass "file" and handle in the main switch, not based on file argument presence

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@codecov
Copy link

codecov bot commented Jan 7, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.51%. Comparing base (4c75af5) to head (f5ce25c).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7691      +/-   ##
==========================================
+ Coverage   95.49%   95.51%   +0.01%     
==========================================
  Files         307      307              
  Lines       15911    15911              
==========================================
+ Hits        15195    15197       +2     
+ Misses        562      561       -1     
+ Partials      154      153       -1     
Flag Coverage Δ
badger_v1 9.18% <ø> (ø)
badger_v2 1.93% <ø> (ø)
cassandra-4.x-v1-manual 13.58% <ø> (ø)
cassandra-4.x-v2-auto 1.92% <ø> (ø)
cassandra-4.x-v2-manual 1.92% <ø> (ø)
cassandra-5.x-v1-manual 13.58% <ø> (ø)
cassandra-5.x-v2-auto 1.92% <ø> (ø)
cassandra-5.x-v2-manual 1.92% <ø> (ø)
clickhouse 1.97% <ø> (ø)
elasticsearch-6.x-v1 17.54% <ø> (ø)
elasticsearch-7.x-v1 17.57% <ø> (ø)
elasticsearch-8.x-v1 17.73% <ø> (ø)
elasticsearch-8.x-v2 1.93% <ø> (ø)
elasticsearch-9.x-v2 1.93% <ø> (ø)
grpc_v1 8.84% <ø> (ø)
grpc_v2 1.93% <ø> (ø)
kafka-3.x-v2 1.93% <ø> (ø)
memory_v2 1.93% <ø> (ø)
opensearch-1.x-v1 17.62% <ø> (ø)
opensearch-2.x-v1 17.62% <ø> (ø)
opensearch-2.x-v2 1.93% <ø> (ø)
opensearch-3.x-v2 1.93% <ø> (ø)
query 1.93% <ø> (ø)
tailsampling-processor 0.55% <ø> (ø)
unittests 94.14% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link

github-actions bot commented Jan 7, 2026

Metrics Comparison Summary

Total changes across all snapshots: 0

Detailed changes per snapshot

summary_metrics_snapshot_cassandra

📊 Metrics Diff Summary

Total Changes: 0

  • 🆕 Added: 0 metrics
  • ❌ Removed: 0 metrics
  • 🔄 Modified: 0 metrics
  • 🚫 Excluded: 53 metrics

➡️ View full metrics file

@Samriddha9619 Samriddha9619 force-pushed the feature/tracegen-file-export branch from f5ce25c to d0661b2 Compare January 7, 2026 19:32
Comment on lines +133 to +137
if file != nil {
shutdown = append(shutdown, func(_ context.Context) error {
return file.Close()
})
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resource leak on early error: If an error occurs after the file is created (line 83) but before this shutdown function is registered, the file handle will never be closed. For example, if createOtelExporter fails at line 96-98, the code calls Fatalf which exits the program without properly closing the file.

Fix: Use defer immediately after file creation:

file, err = os.Create(filename)
if err != nil {
    logger.Sugar().Fatalf("cannot create output file %s: %s", filename, err)
}
defer file.Close()  // Add this

Alternatively, ensure the file close is registered in the shutdown list immediately after creation, before any operations that could fail.

Spotted by Graphite Agent

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed, this logic for adding file close to shutdown should be done right after you successfully opened the file

@@ -9,7 +9,6 @@ The binary is available from the Releases page, as well as a Docker image:
$ docker run jaegertracing/jaeger-tracegen -service abcd -traces 10
```

The generator can be configured to export traces in different formats, via `-exporter` flag.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why delete this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants