diff --git a/cmd/celestia/util.go b/cmd/celestia/util.go index a38860d1f7..0e78b1dca6 100644 --- a/cmd/celestia/util.go +++ b/cmd/celestia/util.go @@ -4,6 +4,7 @@ import ( "github.com/spf13/cobra" cmdnode "github.com/celestiaorg/celestia-node/cmd" + "github.com/celestiaorg/celestia-node/nodebuilder" "github.com/celestiaorg/celestia-node/nodebuilder/core" "github.com/celestiaorg/celestia-node/nodebuilder/gateway" "github.com/celestiaorg/celestia-node/nodebuilder/header" @@ -26,6 +27,13 @@ func persistentPreRunEnv(cmd *cobra.Command, nodeType node.Type, _ []string) err return err } ctx = cmdnode.WithNetwork(ctx, parsedNetwork) + ctx = cmdnode.WithNodeBuildInfo(ctx, &nodebuilder.BuildInfo{ + BuildTime: buildTime, + LastCommit: lastCommit, + SemanticVersion: semanticVersion, + SystemVersion: systemVersion, + GolangVersion: golangVersion, + }) // loads existing config into the environment ctx, err = cmdnode.ParseNodeFlags(ctx, cmd, cmdnode.Network(ctx)) diff --git a/cmd/celestia/version.go b/cmd/celestia/version.go index f6fba4a007..6befb127af 100644 --- a/cmd/celestia/version.go +++ b/cmd/celestia/version.go @@ -11,6 +11,9 @@ var ( buildTime string lastCommit string semanticVersion string + + systemVersion = fmt.Sprintf("%s/%s", runtime.GOARCH, runtime.GOOS) + golangVersion = runtime.Version() ) var versionCmd = &cobra.Command{ diff --git a/cmd/env.go b/cmd/env.go index f9860a2de8..bd1f4b3a21 100644 --- a/cmd/env.go +++ b/cmd/env.go @@ -38,6 +38,11 @@ func NodeConfig(ctx context.Context) nodebuilder.Config { return cfg } +// NodeInfo reads the node build inforamtion from the context. +func NodeInfo(ctx context.Context) nodebuilder.BuildInfo { + return ctx.Value(buildInfo{}).(nodebuilder.BuildInfo) +} + // WithNodeType sets the node type in the given context. func WithNodeType(ctx context.Context, tp node.Type) context.Context { return context.WithValue(ctx, nodeTypeKey{}, tp) @@ -73,10 +78,16 @@ func WithNodeConfig(ctx context.Context, config *nodebuilder.Config) context.Con return context.WithValue(ctx, configKey{}, *config) } +// WithNodeConfig sets the node config build information. +func WithNodeBuildInfo(ctx context.Context, info *nodebuilder.BuildInfo) context.Context { + return context.WithValue(ctx, buildInfo{}, *info) +} + type ( optionsKey struct{} configKey struct{} storePathKey struct{} nodeTypeKey struct{} networkKey struct{} + buildInfo struct{} ) diff --git a/cmd/flags_misc.go b/cmd/flags_misc.go index f671840eab..4483e17201 100644 --- a/cmd/flags_misc.go +++ b/cmd/flags_misc.go @@ -262,7 +262,7 @@ func ParseMiscFlags(ctx context.Context, cmd *cobra.Command) (context.Context, e opts = append(opts, otlpmetrichttp.WithInsecure()) } - ctx = WithNodeOptions(ctx, nodebuilder.WithMetrics(opts, NodeType(ctx))) + ctx = WithNodeOptions(ctx, nodebuilder.WithMetrics(opts, NodeType(ctx), NodeInfo(ctx))) } ok, err = cmd.Flags().GetBool(p2pMetrics) diff --git a/nodebuilder/config.go b/nodebuilder/config.go index d4df75d2f6..4d7937ac77 100644 --- a/nodebuilder/config.go +++ b/nodebuilder/config.go @@ -167,3 +167,12 @@ func (cfg *Config) Decode(r io.Reader) error { _, err := toml.NewDecoder(r).Decode(cfg) return err } + +// BuildInfo stores all necessary information for the current build. +type BuildInfo struct { + BuildTime string + LastCommit string + SemanticVersion string + SystemVersion string + GolangVersion string +} diff --git a/nodebuilder/node_test.go b/nodebuilder/node_test.go index aa22b0fcc7..9960ac7db0 100644 --- a/nodebuilder/node_test.go +++ b/nodebuilder/node_test.go @@ -80,6 +80,7 @@ func TestLifecycle_WithMetrics(t *testing.T) { otlpmetrichttp.WithInsecure(), }, tt.tp, + BuildInfo{}, ), ) require.NotNil(t, node) diff --git a/nodebuilder/settings.go b/nodebuilder/settings.go index 67a30793f8..f4b8094a95 100644 --- a/nodebuilder/settings.go +++ b/nodebuilder/settings.go @@ -7,6 +7,7 @@ import ( "github.com/libp2p/go-libp2p/core/peer" "github.com/pyroscope-io/client/pyroscope" + "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp" "go.opentelemetry.io/otel/metric/global" "go.opentelemetry.io/otel/sdk/metric" @@ -62,9 +63,10 @@ func WithPyroscope(endpoint string, nodeType node.Type) fx.Option { } // WithMetrics enables metrics exporting for the node. -func WithMetrics(metricOpts []otlpmetrichttp.Option, nodeType node.Type) fx.Option { +func WithMetrics(metricOpts []otlpmetrichttp.Option, nodeType node.Type, buildInfo BuildInfo) fx.Option { baseComponents := fx.Options( fx.Supply(metricOpts), + fx.Supply(buildInfo), fx.Invoke(initializeMetrics), fx.Invoke(state.WithMetrics), fx.Invoke(fraud.WithMetrics), @@ -109,6 +111,7 @@ func initializeMetrics( lc fx.Lifecycle, peerID peer.ID, nodeType node.Type, + buildInfo BuildInfo, opts []otlpmetrichttp.Option, ) error { exp, err := otlpmetrichttp.New(ctx, opts...) @@ -121,16 +124,19 @@ func initializeMetrics( metric.WithResource(resource.NewWithAttributes( semconv.SchemaURL, semconv.ServiceNameKey.String(fmt.Sprintf("Celestia-%s", nodeType.String())), - // TODO(@Wondertan): Versioning: semconv.ServiceVersionKey semconv.ServiceInstanceIDKey.String(peerID.String()), + // custom key-val pairs + attribute.String("service.buildTime", buildInfo.BuildTime), + attribute.String("service.lastCommit", buildInfo.LastCommit), + attribute.String("service.semanticVersion", buildInfo.SemanticVersion), + attribute.String("service.systemVersion", buildInfo.SystemVersion), + attribute.String("service.goVersion", buildInfo.GolangVersion), ))) - lc.Append(fx.Hook{ OnStop: func(ctx context.Context) error { return provider.Shutdown(ctx) }, }) global.SetMeterProvider(provider) - return nil }