Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
0d2cf40
feat(tracing): migrate from OpenTracing/Jaeger to OpenTelemetry
martinconic May 11, 2026
c99fd5e
fix: linter issues
martinconic May 11, 2026
d7f3a13
test: testing with beekeeper changes
martinconic May 11, 2026
fe49f93
fix(tracing): address PR review — protocol flag, sampling 0, nested c…
martinconic May 12, 2026
1be8864
fix: go mod
martinconic May 12, 2026
b981f5e
fix(tracing): require endpoint, secure-by-default TLS, CA bundle flag
martinconic May 13, 2026
6701b50
test(p2p/libp2p): set dead endpoint for tracer in TestTracing
martinconic May 13, 2026
560a77c
refactor(tracing): unexport package-internal constants
martinconic May 15, 2026
376e4a8
chore: revert beekeeper to master branch
martinconic May 18, 2026
9f5c4b9
Merge remote-tracking branch 'origin/master' into feat/opentelemetry-…
martinconic May 21, 2026
fe4a927
refactor(tracing): address review feedback on tracing wrapper
martinconic May 29, 2026
6c851ca
test(tracing): cover OTLP CA bundle loading
martinconic May 29, 2026
265c2cf
feat(tracing): accept deprecated pre-OTel tracing keys as no-ops
martinconic Jun 3, 2026
2b4d8cf
Merge remote-tracking branch 'origin/master' into feat/opentelemetry-…
martinconic Jun 5, 2026
09b7db2
fix(tracing): version p2p span-context header and relocate TLS warning
martinconic Jun 5, 2026
e61483a
Merge remote-tracking branch 'origin/master' into feat/opentelemetry-…
martinconic Jun 8, 2026
2c8cefc
feat(tracing): enrich OTel resource, compress OTLP, annotate spans (#…
martinconic Jun 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/beekeeper.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ on:
paths-ignore:
- packaging/**
- openapi/**
- '**/*.md'
- '.github/ISSUE_TEMPLATE/**'
- "**/*.md"
- ".github/ISSUE_TEMPLATE/**"
branches:
- "**"

Expand Down
98 changes: 91 additions & 7 deletions cmd/bee/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ const (
optionCORSAllowedOrigins = "cors-allowed-origins"
optionNameTracingEnabled = "tracing-enable"
optionNameTracingEndpoint = "tracing-endpoint"
optionNameTracingHost = "tracing-host"
optionNameTracingPort = "tracing-port"
optionNameTracingInsecure = "tracing-insecure"
optionNameTracingCAFile = "tracing-ca-file"
optionNameTracingProtocol = "tracing-protocol"
optionNameTracingSamplingRatio = "tracing-sampling-ratio"
optionNameTracingServiceName = "tracing-service-name"
Comment thread
martinconic marked this conversation as resolved.
optionNameVerbosity = "verbosity"
optionNamePaymentThreshold = "payment-threshold"
Expand Down Expand Up @@ -103,6 +105,15 @@ const (
configKeyBlockchainRpcTLSTimeout = "blockchain-rpc.tls-timeout"
configKeyBlockchainRpcIdleTimeout = "blockchain-rpc.idle-timeout"
configKeyBlockchainRpcKeepalive = "blockchain-rpc.keepalive"

// tracing
configKeyTracingEnabled = "tracing.enable"
configKeyTracingEndpoint = "tracing.endpoint"
configKeyTracingInsecure = "tracing.insecure"
configKeyTracingCAFile = "tracing.ca-file"
configKeyTracingProtocol = "tracing.protocol"
configKeyTracingSamplingRatio = "tracing.sampling-ratio"
configKeyTracingServiceName = "tracing.service-name"
)

var blockchainRpcConfigPairs = []struct{ flat, dotted string }{
Expand All @@ -113,11 +124,44 @@ var blockchainRpcConfigPairs = []struct{ flat, dotted string }{
{optionNameBlockchainRpcKeepalive, configKeyBlockchainRpcKeepalive},
}

var tracingConfigPairs = []struct{ flat, dotted string }{
{optionNameTracingEnabled, configKeyTracingEnabled},
{optionNameTracingEndpoint, configKeyTracingEndpoint},
{optionNameTracingInsecure, configKeyTracingInsecure},
{optionNameTracingCAFile, configKeyTracingCAFile},
{optionNameTracingProtocol, configKeyTracingProtocol},
{optionNameTracingSamplingRatio, configKeyTracingSamplingRatio},
{optionNameTracingServiceName, configKeyTracingServiceName},
}

// Deprecated tracing options, removed in the OpenTelemetry migration. They are
// kept only as hidden no-op flags so that existing configs do not break node
// startup; their values are ignored (see deprecatedTracingKeys).
//
// Note: tracing-endpoint is intentionally NOT here — it is reused as the active
// OTLP endpoint flag (see optionNameTracingEndpoint). Its meaning changed from a
// Jaeger agent address to an OTLP collector endpoint.
const (
optionNameTracingHost = "tracing-host"
optionNameTracingPort = "tracing-port"
)

// deprecatedTracingKeys are the pre-OpenTelemetry tracing options. They are
// registered as hidden no-op flags so stale configs still start the node, but
// their values are ignored; operators should migrate to the tracing-* keys.
var deprecatedTracingKeys = []string{
optionNameTracingHost,
optionNameTracingPort,
}

var knownNestedKeys = func() map[string]bool {
m := make(map[string]bool, len(blockchainRpcConfigPairs))
m := make(map[string]bool, len(blockchainRpcConfigPairs)+len(tracingConfigPairs))
for _, p := range blockchainRpcConfigPairs {
m[p.dotted] = true
}
for _, p := range tracingConfigPairs {
m[p.dotted] = true
}
return m
}()

Expand Down Expand Up @@ -284,10 +328,18 @@ func (c *command) setAllFlags(cmd *cobra.Command) {
cmd.Flags().Uint64(optionNameNetworkID, chaincfg.Mainnet.NetworkID, "ID of the Swarm network")
cmd.Flags().StringSlice(optionCORSAllowedOrigins, []string{}, "origins with CORS headers enabled")
cmd.Flags().Bool(optionNameTracingEnabled, false, "enable tracing")
cmd.Flags().String(optionNameTracingEndpoint, "127.0.0.1:6831", "endpoint to send tracing data")
cmd.Flags().String(optionNameTracingHost, "", "host to send tracing data")
cmd.Flags().String(optionNameTracingPort, "", "port to send tracing data")
cmd.Flags().String(optionNameTracingEndpoint, "127.0.0.1:4318", "OTLP collector endpoint to send tracing data (host:port); default port is 4318 for http, 4317 for grpc")
cmd.Flags().Bool(optionNameTracingInsecure, false, "disable TLS for the OTLP exporter (useful for a local collector); when false, set --tracing-ca-file to verify the collector certificate against a private CA")
cmd.Flags().String(optionNameTracingCAFile, "", "path to a PEM-encoded CA bundle used to verify the OTLP collector certificate; ignored when --tracing-insecure=true")
cmd.Flags().String(optionNameTracingProtocol, "http", "OTLP exporter transport: http or grpc")
cmd.Flags().Float64(optionNameTracingSamplingRatio, 1.0, "head-based sampling ratio in [0,1]; 0 samples nothing, 1 samples everything")
cmd.Flags().String(optionNameTracingServiceName, "bee", "service name identifier for tracing")
// Deprecated, no-op tracing flags kept for backward compatibility so that
// existing configs do not break node startup. Their values are ignored.
for _, name := range deprecatedTracingKeys {
cmd.Flags().String(name, "", "deprecated and ignored; use the tracing-* options")
_ = cmd.Flags().MarkDeprecated(name, "no longer used after the OpenTelemetry migration; use the tracing-* options")
}
cmd.Flags().String(optionNameVerbosity, "info", "log verbosity level 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=trace")
cmd.Flags().String(optionWelcomeMessage, "", "send a welcome message string during handshakes")
cmd.Flags().String(optionNamePaymentThreshold, "13500000", "threshold in BZZ where you expect to get paid from your peers")
Expand Down Expand Up @@ -370,7 +422,39 @@ func (c *command) initLogger(cmd *cobra.Command) error {
// bindBlockchainRpcConfig supports both flat (blockchain-rpc-endpoint) and
// nested (blockchain-rpc.endpoint) YAML forms, with nested taking precedence.
func (c *command) bindBlockchainRpcConfig(cmd *cobra.Command) {
for _, p := range blockchainRpcConfigPairs {
c.bindNestedConfig(cmd, blockchainRpcConfigPairs)
}

// bindTracingConfig supports both flat (tracing-endpoint) and nested
// (tracing.endpoint) YAML forms, with nested taking precedence.
func (c *command) bindTracingConfig(cmd *cobra.Command) {
c.bindNestedConfig(cmd, tracingConfigPairs)
}

// warnDeprecatedTracingKeys logs a warning for each pre-OpenTelemetry tracing
// key found in the config file. The keys are accepted to keep stale configs
// bootable, but their values are ignored. Keys passed on the command line are
// already handled by cobra's deprecation notice.
func (c *command) warnDeprecatedTracingKeys() {
for _, key := range deprecatedTracingKeys {
if c.config.InConfig(key) {
c.logger.Warning("deprecated tracing config key is ignored; use the tracing-* options", "key", key)
}
}
}

// warnTracingTLSWithoutCA warns when tracing runs over TLS without an explicit
// CA bundle, in which case the OTLP exporter falls back to the system root CAs.
func (c *command) warnTracingTLSWithoutCA() {
if c.config.GetBool(configKeyTracingEnabled) &&
!c.config.GetBool(configKeyTracingInsecure) &&
c.config.GetString(configKeyTracingCAFile) == "" {
c.logger.Warning("tracing: TLS is enabled but no CA bundle is configured; the OTLP exporter will rely on the system root CAs. Provide --tracing-ca-file, set --tracing-insecure=true for a plaintext local collector, or disable tracing.")
}
}

func (c *command) bindNestedConfig(cmd *cobra.Command, pairs []struct{ flat, dotted string }) {
for _, p := range pairs {
// Check before registering the alias; afterwards the flat value is unreachable.
if c.config.InConfig(p.flat) && c.config.InConfig(p.dotted) {
c.logger.Warning("config key conflict: nested form takes precedence", "ignored", p.flat, "used", p.dotted)
Expand Down
68 changes: 68 additions & 0 deletions cmd/bee/cmd/deprecated_tracing_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2026 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package cmd_test

import (
"os"
"path/filepath"
"strings"
"testing"
)

// TestDeprecatedTracingKeysAccepted verifies that the pre-OpenTelemetry tracing
// keys are tolerated in a config file (so stale configs still boot) while a
// genuinely unknown key is still rejected.
func TestDeprecatedTracingKeysAccepted(t *testing.T) {
t.Parallel()

for _, tc := range []struct {
name string
config string
wantError string
}{
{
name: "deprecated tracing keys accepted",
config: "tracing-enable: false\n" +
"tracing-endpoint: my-jaeger:6831\n" +
"tracing-host: \"\"\n" +
"tracing-port: \"\"\n",
},
{
name: "unknown key rejected",
config: "totally-made-up-key: 1\n",
wantError: "totally-made-up-key",
},
} {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

cfgFile := filepath.Join(t.TempDir(), "config.yaml")
if err := os.WriteFile(cfgFile, []byte(tc.config), 0o644); err != nil {
t.Fatal(err)
}

c := newCommand(t)
c.SetCfgFileForTest(cfgFile)
startCmd := c.SubCommandForTest("start")
if startCmd == nil {
t.Fatal("start subcommand not found")
}

err := c.CheckUnknownParamsForTest(startCmd)
if tc.wantError == "" {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
return
}
if err == nil {
t.Fatalf("expected error containing %q, got nil", tc.wantError)
}
if !strings.Contains(err.Error(), tc.wantError) {
t.Fatalf("expected error containing %q, got %v", tc.wantError, err)
}
})
}
}
28 changes: 27 additions & 1 deletion cmd/bee/cmd/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,33 @@

package cmd

import "io"
import (
"io"

"github.com/spf13/cobra"
)

type (
Command = command
Option = option
PasswordReader = passwordReader
)

// SubCommandForTest returns the registered subcommand with the given name.
func (c *Command) SubCommandForTest(name string) *cobra.Command {
for _, sc := range c.root.Commands() {
if sc.Name() == name {
return sc
}
}
return nil
}

// CheckUnknownParamsForTest exposes the unknown-parameter validation.
func (c *Command) CheckUnknownParamsForTest(cmd *cobra.Command) error {
return c.CheckUnknownParams(cmd, nil)
}

var (
NewCommand = newCommand

Expand Down Expand Up @@ -63,3 +82,10 @@ func WithPasswordReader(r PasswordReader) func(c *Command) {
c.passwordReader = r
}
}

// SetCfgFileForTest sets the config file path after command construction. It
// must be used instead of WithCfgFile because the global "config" flag's
// StringVar default resets c.cfgFile during flag registration.
func (c *Command) SetCfgFileForTest(f string) {
c.cfgFile = f
}
20 changes: 10 additions & 10 deletions cmd/bee/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"os/signal"
"path/filepath"
"runtime"
"strings"
"sync/atomic"
"syscall"
"time"
Expand Down Expand Up @@ -163,6 +162,9 @@ func (c *command) initStartCmd() (err error) {
return err
}
c.bindBlockchainRpcConfig(cmd)
c.bindTracingConfig(cmd)
c.warnDeprecatedTracingKeys()
c.warnTracingTLSWithoutCA()
return nil
},
}
Expand Down Expand Up @@ -245,12 +247,6 @@ func buildBeeNode(ctx context.Context, c *command, cmd *cobra.Command, logger lo
networkConfig.blockTime = time.Duration(blockTime) * time.Second
}

tracingEndpoint := c.config.GetString(optionNameTracingEndpoint)

if c.config.IsSet(optionNameTracingHost) && c.config.IsSet(optionNameTracingPort) {
tracingEndpoint = strings.Join([]string{c.config.GetString(optionNameTracingHost), c.config.GetString(optionNameTracingPort)}, ":")
}

staticNodesOpt := c.config.GetStringSlice(optionNameStaticNodes)
staticNodes := make([]swarm.Address, 0, len(staticNodesOpt))
for _, p := range staticNodesOpt {
Expand Down Expand Up @@ -346,9 +342,13 @@ func buildBeeNode(ctx context.Context, c *command, cmd *cobra.Command, logger lo
SwapFactoryAddress: c.config.GetString(optionNameSwapFactoryAddress),
SwapInitialDeposit: c.config.GetString(optionNameSwapInitialDeposit),
TargetNeighborhood: c.config.GetString(optionNameTargetNeighborhood),
TracingEnabled: c.config.GetBool(optionNameTracingEnabled),
TracingEndpoint: tracingEndpoint,
TracingServiceName: c.config.GetString(optionNameTracingServiceName),
TracingEnabled: c.config.GetBool(configKeyTracingEnabled),
TracingEndpoint: c.config.GetString(configKeyTracingEndpoint),
TracingInsecure: c.config.GetBool(configKeyTracingInsecure),
TracingCAFile: c.config.GetString(configKeyTracingCAFile),
TracingProtocol: c.config.GetString(configKeyTracingProtocol),
TracingSamplingRatio: c.config.GetFloat64(configKeyTracingSamplingRatio),
TracingServiceName: c.config.GetString(configKeyTracingServiceName),
TrxDebugMode: c.config.GetBool(optionNameTransactionDebugMode),
WarmupTime: c.config.GetDuration(optionWarmUpTime),
WelcomeMessage: c.config.GetString(optionWelcomeMessage),
Expand Down
Loading
Loading