Skip to content

Commit

Permalink
chore(telemetry): move configuration to node config (gnolang#2021)
Browse files Browse the repository at this point in the history
This PR moves Telemetry configuration to the centralised node config.
h/t to @albttx for identifying this.
  • Loading branch information
thehowl committed May 2, 2024
1 parent 3a4b742 commit 6482c18
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 96 deletions.
26 changes: 3 additions & 23 deletions gno.land/cmd/gnoland/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"errors"
"flag"
"fmt"
"os"
"path/filepath"
"strings"
"time"
Expand Down Expand Up @@ -219,12 +218,6 @@ func execStart(c *startCfg, io commands.IO) error {
loadCfgErr error
)

// Attempt to initialize telemetry. If the environment variables required to initialize
// telemetry are not set, then the initialization will do nothing.
if err := initTelemetry(); err != nil {
return fmt.Errorf("error initializing telemetry: %w", err)
}

// Set the node configuration
if c.nodeConfigPath != "" {
// Load the node configuration
Expand Down Expand Up @@ -254,6 +247,9 @@ func execStart(c *startCfg, io commands.IO) error {
// Wrap the zap logger
logger := log.ZapLoggerToSlog(zapLogger)

// Initialize telemetry
telemetry.Init(*cfg.Telemetry)

// Write genesis file if missing.
// NOTE: this will be dropped in a PR that resolves issue #1886:
// https://github.com/gnolang/gno/issues/1886
Expand Down Expand Up @@ -399,19 +395,3 @@ func getTxEventStoreConfig(c *startCfg) (*eventstorecfg.Config, error) {

return cfg, nil
}

func initTelemetry() error {
var options []telemetry.Option

if os.Getenv("TELEM_METRICS_ENABLED") == "true" {
options = append(options, telemetry.WithOptionMetricsEnabled())
}

// The string options can be added by default. Their absence would yield the same result
// as if the option were excluded altogether.
options = append(options, telemetry.WithOptionMeterName(os.Getenv("TELEM_METER_NAME")))
options = append(options, telemetry.WithOptionExporterEndpoint(os.Getenv("TELEM_EXPORTER_ENDPOINT")))
options = append(options, telemetry.WithOptionServiceName(os.Getenv("TELEM_SERVICE_NAME")))

return telemetry.Init(options...)
}
4 changes: 4 additions & 0 deletions tm2/pkg/bft/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/gnolang/gno/tm2/pkg/errors"
osm "github.com/gnolang/gno/tm2/pkg/os"
p2p "github.com/gnolang/gno/tm2/pkg/p2p/config"
telemetry "github.com/gnolang/gno/tm2/pkg/telemetry/config"
)

var (
Expand Down Expand Up @@ -51,6 +52,7 @@ type Config struct {
Mempool *mem.MempoolConfig `toml:"mempool" comment:"##### mempool configuration options #####"`
Consensus *cns.ConsensusConfig `toml:"consensus" comment:"##### consensus configuration options #####"`
TxEventStore *eventstore.Config `toml:"tx_event_store" comment:"##### event store #####"`
Telemetry *telemetry.Config `toml:"telemetry" comment:"##### node telemetry #####"`
}

// DefaultConfig returns a default configuration for a Tendermint node
Expand All @@ -62,6 +64,7 @@ func DefaultConfig() *Config {
Mempool: mem.DefaultMempoolConfig(),
Consensus: cns.DefaultConsensusConfig(),
TxEventStore: eventstore.DefaultEventStoreConfig(),
Telemetry: telemetry.DefaultTelemetryConfig(),
}
}

Expand Down Expand Up @@ -138,6 +141,7 @@ func TestConfig() *Config {
Mempool: mem.TestMempoolConfig(),
Consensus: cns.TestConsensusConfig(),
TxEventStore: eventstore.DefaultEventStoreConfig(),
Telemetry: telemetry.TestTelemetryConfig(),
}
}

Expand Down
14 changes: 6 additions & 8 deletions tm2/pkg/telemetry/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
# Telemetry

The purpose of this package is to provide a way to easily integrate OpenTelemetry Protocol (OTLP) metrics collection into our codebase.
The purpose of this package is to provide a way to easily integrate OpenTelemetry Protocol (OTLP) metrics collection into a Tendermint 2 node.

## Configure environment variables
Metrics can be enabled using environment variables. The following variables are supported:
- `TELEM_METRICS_ENABLED`: setting to `true` will enable metrics collection
- `TELEM_METER_NAME`: optionally set the meter name; the default is `gno.land`
- `TELEM_SERVICE_NAME`: optionally set the service name; the default is `gno.land`
- `TELEM_EXPORTER_ENDPOINT`: required; this is the endpoint to export metrics to, like a local OTEL collector
## Configure Telemetry

Telemetry can be regularly configured within the TM2 node through the
`[telemetry]` section. It is disabled by default.

## OTEL configuration
There are many ways configure the OTEL pipeline for exporting metrics. Here is an example of how a local OTEL collector can be configured to send metrics to Grafana Cloud. This is an optional step and can be highly customized.
Expand Down Expand Up @@ -40,4 +38,4 @@ Collector exporter environment variables, including those for authentication, ca
## Resources
- https://opentelemetry.io/docs/collector/
- https://grafana.com/docs/grafana-cloud/monitor-applications/application-observability/setup/collector/
- https://grafana.com/docs/grafana-cloud/monitor-applications/application-observability/setup/collector/
27 changes: 27 additions & 0 deletions tm2/pkg/telemetry/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Package config contains the configuration types and helpers for the telemetry
// package.
package config

// Config is the configuration struct for the tm2 telemetry package.
type Config struct {
MetricsEnabled bool `toml:"enabled"`
MeterName string `toml:"meter_name"`
ServiceName string `toml:"service_name"`
ExporterEndpoint string `toml:"exporter_endpoint" comment:"the endpoint to export metrics to, like a local OpenTelemetry collector"`
}

// DefaultTelemetryConfig is the default configuration used for the node.
func DefaultTelemetryConfig() *Config {
return &Config{
MetricsEnabled: false,
MeterName: "gno.land",
ServiceName: "gno.land",
ExporterEndpoint: "",
}
}

// TestTelemetryConfig is the test configuration. Currently it is an alias for
// [DefaultTelemetryConfig].
func TestTelemetryConfig() *Config {
return DefaultTelemetryConfig()
}
36 changes: 16 additions & 20 deletions tm2/pkg/telemetry/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,33 @@ package telemetry
// https://github.com/open-telemetry/opentelemetry-go/blob/main/example/prometheus/main.go

import (
"sync/atomic"

"github.com/gnolang/gno/tm2/pkg/telemetry/config"
"github.com/gnolang/gno/tm2/pkg/telemetry/metrics"
"github.com/gnolang/gno/tm2/pkg/telemetry/options"
)

const (
defaultMeterName = "gno.land"
defaultServiceName = "gno.land"
var (
globalConfig config.Config
globalConfigSet atomic.Bool
)

var config options.Config

// MetricsEnabled returns true if metrics have been initialized.
func MetricsEnabled() bool {
return config.MetricsEnabled
return globalConfig.MetricsEnabled
}

// Init will initialize metrics with the options provided. This function may also initialize tracing when
// this is something that we want to support.
func Init(options ...Option) error {
config.MeterName = defaultMeterName
config.ServiceName = defaultServiceName
for _, opt := range options {
opt(&config)
// Init sets the configuration for telemetry to c, and if telemetry is enabled,
// starts tracking.
// Init may only be called once. Multiple calls to Init will panic.
func Init(c config.Config) error {
if !globalConfigSet.CompareAndSwap(false, true) {
panic("telemetry configuration has already been set and initialised")
}

globalConfig = c
// Initialize metrics to be collected.
if config.MetricsEnabled {
if err := metrics.Init(config); err != nil {
return err
}
if c.MetricsEnabled {
return metrics.Init(c)
}

return nil
}
4 changes: 2 additions & 2 deletions tm2/pkg/telemetry/metrics/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package metrics
import (
"context"

"github.com/gnolang/gno/tm2/pkg/telemetry/config"
"github.com/gnolang/gno/tm2/pkg/telemetry/exporter"
"github.com/gnolang/gno/tm2/pkg/telemetry/options"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
"go.opentelemetry.io/otel/metric"
Expand All @@ -19,7 +19,7 @@ var (
BuildBlockTimer metric.Int64Histogram
)

func Init(config options.Config) error {
func Init(config config.Config) error {
if config.ExporterEndpoint == "" {
return exporter.ErrEndpointNotSet
}
Expand Down
35 changes: 0 additions & 35 deletions tm2/pkg/telemetry/options.go

This file was deleted.

8 changes: 0 additions & 8 deletions tm2/pkg/telemetry/options/config.go

This file was deleted.

0 comments on commit 6482c18

Please sign in to comment.