Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .changeset/sharp-carpets-run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": patch
---

#updated Wire up OTel logs streaming, integrate chainlink logger with otel
15 changes: 13 additions & 2 deletions core/cmd/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,17 +131,28 @@ func initGlobals(cfgProm config.Prometheus, cfgTracing config.Tracing, cfgTeleme
if err != nil {
return err
}

beholder.SetClient(beholderClient)
beholder.SetGlobalOtelProviders()

if clientCfg.LogStreamingEnabled {
// WithOtel mutates the logger
lggr, err = lggr.WithOtel(beholderClient.Logger)
if err != nil {
return fmt.Errorf("Failed to enable log streaming: %w", err)
}
lggr.Info("Log streaming enabled")
}

return nil
}()
})
return err
}

var (
// ErrorNoAPICredentialsAvailable is returned when not run from a terminal
// and no API credentials have been provided
// ErrorNoAPICredentialsAvailable is returned when not run from a terminal
// and no API credentials have been provided
ErrorNoAPICredentialsAvailable = errors.New("API credentials must be supplied")
)

Expand Down
11 changes: 9 additions & 2 deletions core/logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"path/filepath"

"github.com/fatih/color"
otellog "go.opentelemetry.io/otel/log"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
Expand All @@ -28,9 +29,11 @@ type stderrWriter struct{}
func (sw stderrWriter) Write(p []byte) (n int, err error) {
return os.Stderr.Write(p)
}

func (sw stderrWriter) Close() error {
return nil // never close stderr
}

func (sw stderrWriter) Sync() error {
return os.Stderr.Sync()
}
Expand Down Expand Up @@ -129,6 +132,9 @@ type Logger interface {
// Recover reports recovered panics; this is useful because it avoids
// double-reporting to sentry
Recover(panicErr interface{})

// WithOtel enables OpenTelemetry integration for this logger
WithOtel(otelLogger otellog.Logger) (Logger, error)
}

// newZapConfigProd returns a new production zap.Config.
Expand Down Expand Up @@ -265,10 +271,11 @@ func newLoggerForCore(zcfg zap.Config, core zapcore.Core) (*zapLogger, func(), e
if err != nil {
return nil, nil, err
}

opts := []zap.Option{zap.ErrorOutput(errSink), zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel)}
return &zapLogger{
level: zcfg.Level,
SugaredLogger: zap.New(core, zap.ErrorOutput(errSink), zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel)).Sugar(),
SugaredLogger: zap.New(core, opts...).Sugar(),
opts: opts,
}, closeFn, nil
}

Expand Down
29 changes: 28 additions & 1 deletion core/logger/logger_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions core/logger/null_logger.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package logger

import (
otellog "go.opentelemetry.io/otel/log"
"go.uber.org/zap/zapcore"
)

Expand Down Expand Up @@ -44,3 +45,8 @@ func (l *nullLogger) Helper(skip int) Logger { return l }
func (l *nullLogger) Name() string { return "nullLogger" }

func (l *nullLogger) Recover(panicErr interface{}) {}

func (l *nullLogger) WithOtel(otelLogger otellog.Logger) (Logger, error) {
// Null logger doesn't support OTel integration
return l, nil
}
15 changes: 14 additions & 1 deletion core/logger/prometheus.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,34 @@
package logger

import (
"errors"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
otellog "go.opentelemetry.io/otel/log"
"go.uber.org/zap/zapcore"
)

var warnCounter = promauto.NewCounter(prometheus.CounterOpts{
Name: "log_warn_count",
Help: "Number of warning messages in log",
})

var errorCounter = promauto.NewCounter(prometheus.CounterOpts{
Name: "log_error_count",
Help: "Number of error messages in log",
})

var criticalCounter = promauto.NewCounter(prometheus.CounterOpts{
Name: "log_critical_count",
Help: "Number of critical messages in log",
})

var panicCounter = promauto.NewCounter(prometheus.CounterOpts{
Name: "log_panic_count",
Help: "Number of panic messages in log",
})

var fatalCounter = promauto.NewCounter(prometheus.CounterOpts{
Name: "log_fatal_count",
Help: "Number of fatal messages in log",
Expand All @@ -42,7 +49,8 @@ func newPrometheusLoggerWithCounters(
errorCounter prometheus.Counter,
criticalCounter prometheus.Counter,
panicCounter prometheus.Counter,
fatalCounter prometheus.Counter) Logger {
fatalCounter prometheus.Counter,
) Logger {
return &prometheusLogger{
h: l.Helper(1),
warnCnt: warnCounter,
Expand Down Expand Up @@ -217,3 +225,8 @@ func (s *prometheusLogger) Recover(panicErr interface{}) {
s.panicCnt.Inc()
s.h.Recover(panicErr)
}

func (s *prometheusLogger) WithOtel(otelLogger otellog.Logger) (Logger, error) {
// OTel integration is not implemented for prometheus logger
return nil, errors.New("WithOtel not implemented for prometheus logger")
}
7 changes: 7 additions & 0 deletions core/logger/sentry.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package logger

import (
"errors"
"fmt"
"time"

"github.com/getsentry/sentry-go"
otellog "go.opentelemetry.io/otel/log"
"go.uber.org/zap/zapcore"
)

Expand Down Expand Up @@ -270,3 +272,8 @@ func (s *sentryLogger) Recover(panicErr interface{}) {

s.h.With("sentryEventID", eid).Recover(panicErr)
}

func (s *sentryLogger) WithOtel(otelLogger otellog.Logger) (Logger, error) {
// OTel integration is not implemented for sentry logger
return nil, errors.New("WithOtel not implemented for sentry logger")
}
27 changes: 27 additions & 0 deletions core/logger/zap.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import (
"os"

pkgerrors "github.com/pkg/errors"
otellog "go.opentelemetry.io/otel/log"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"

"github.com/smartcontractkit/chainlink-common/pkg/logger/otelzap"
)

var _ Logger = &zapLogger{}
Expand All @@ -15,6 +18,8 @@ type zapLogger struct {
level zap.AtomicLevel
fields []interface{}
callerSkip int
opts []zap.Option
otelLogger otellog.Logger
}

func makeEncoderConfig(unixTS bool) zapcore.EncoderConfig {
Expand Down Expand Up @@ -92,3 +97,25 @@ func (l *zapLogger) Sync() error {
func (l *zapLogger) Recover(panicErr interface{}) {
l.Criticalw("Recovered goroutine panic", "panic", panicErr)
}

func (l *zapLogger) WithOtel(otelLogger otellog.Logger) (Logger, error) {
if l.otelLogger != nil {
return l, nil
}
l.otelLogger = otelLogger

// Get the current core from the zap logger
primaryCore := l.SugaredLogger.Desugar().Core()

// Create OTel core with debug level to ensure all logs are captured
otelCore := otelzap.NewCore(otelLogger, otelzap.WithLevel(zapcore.DebugLevel))

// Create a new zap logger with both cores using Tee
combinedCore := zapcore.NewTee(primaryCore, otelCore)
newLogger := zap.New(combinedCore, l.opts...)

// Update the zapLogger with the new core
l.SugaredLogger = newLogger.Sugar()

return l, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ module github.com/smartcontractkit/chainlink/core/scripts/cre/environment/exampl
go 1.24.5

require (
github.com/smartcontractkit/cre-sdk-go v0.5.1-0.20250818141131-0b979c98bab0
github.com/smartcontractkit/cre-sdk-go/capabilities/scheduler/cron v0.5.1-0.20250818141131-0b979c98bab0
github.com/smartcontractkit/cre-sdk-go v0.8.0
github.com/smartcontractkit/cre-sdk-go/capabilities/scheduler/cron v0.8.0
gopkg.in/yaml.v3 v3.0.1
)

Expand All @@ -15,7 +15,7 @@ require (
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20250829155125-f4655b0b4605 // indirect
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20250911124514-5874cc6d62b2 // indirect
github.com/stretchr/testify v1.10.0 // indirect
google.golang.org/protobuf v1.36.7 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
Expand Down
12 changes: 6 additions & 6 deletions core/scripts/cre/environment/examples/workflows/v2/cron/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20250829155125-f4655b0b4605 h1:yVH5tLDzW2ZBUpmkHF5nci1SRSXTcU3A1VZ8iS5qudA=
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20250829155125-f4655b0b4605/go.mod h1:jUC52kZzEnWF9tddHh85zolKybmLpbQ1oNA4FjOHt1Q=
github.com/smartcontractkit/cre-sdk-go v0.5.1-0.20250818141131-0b979c98bab0 h1:cahx93+ayyS9j5kAjNG2bQq2hisQRHrDIkaKugmgRA4=
github.com/smartcontractkit/cre-sdk-go v0.5.1-0.20250818141131-0b979c98bab0/go.mod h1:C1KXVcxUy89lFVqJ335pEPeeC/wJy0jCF0ZztwWdCmU=
github.com/smartcontractkit/cre-sdk-go/capabilities/scheduler/cron v0.5.1-0.20250818141131-0b979c98bab0 h1:f3V1Nivq0sUScnp4IhtRGllEdX+Pkj6YZhBAIllPXlI=
github.com/smartcontractkit/cre-sdk-go/capabilities/scheduler/cron v0.5.1-0.20250818141131-0b979c98bab0/go.mod h1:TZT/U2g7nJ4SyMXWPkrBfMuHoA8Opu2GW99pbI1PhWA=
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20250911124514-5874cc6d62b2 h1:1/KdO5AbUr3CmpLjMPuJXPo2wHMbfB8mldKLsg7D4M8=
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20250911124514-5874cc6d62b2/go.mod h1:jUC52kZzEnWF9tddHh85zolKybmLpbQ1oNA4FjOHt1Q=
github.com/smartcontractkit/cre-sdk-go v0.8.0 h1:QHYnz6MgBGFRaTOrP9Nx4HSHUpxYWgRzXGdsAucKAiI=
github.com/smartcontractkit/cre-sdk-go v0.8.0/go.mod h1:CQY8hCISjctPmt8ViDVgFm4vMGLs5fYI198QhkBS++Y=
github.com/smartcontractkit/cre-sdk-go/capabilities/scheduler/cron v0.8.0 h1:aO++xdGcQ8TpxAfXrm7EHeIVLDitB8xg7J8/zSxbdBY=
github.com/smartcontractkit/cre-sdk-go/capabilities/scheduler/cron v0.8.0/go.mod h1:PWyrIw16It4TSyq6mDXqmSR0jF2evZRKuBxu7pK1yDw=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ toolchain go1.24.6

require (
github.com/ethereum/go-ethereum v1.16.2
github.com/smartcontractkit/chain-selectors v1.0.71
github.com/smartcontractkit/chainlink-common v0.9.0
github.com/smartcontractkit/chainlink-common/pkg/values v0.0.0-20250806152407-159881c7589c
github.com/smartcontractkit/chainlink-common/pkg/workflows/sdk/v2/pb v0.0.0-20250806155403-1d805e639a0f
github.com/smartcontractkit/cre-sdk-go v0.5.0
github.com/smartcontractkit/cre-sdk-go/capabilities/blockchain/evm v0.5.0
github.com/smartcontractkit/cre-sdk-go/capabilities/networking/http v0.5.0
github.com/smartcontractkit/cre-sdk-go/capabilities/scheduler/cron v0.5.0
github.com/smartcontractkit/chain-selectors v1.0.67
github.com/smartcontractkit/chainlink-common v0.9.6
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20250918131840-564fe2776a35
github.com/smartcontractkit/cre-sdk-go v0.8.0
github.com/smartcontractkit/cre-sdk-go/capabilities/blockchain/evm v0.8.0
github.com/smartcontractkit/cre-sdk-go/capabilities/networking/http v0.8.0
github.com/smartcontractkit/cre-sdk-go/capabilities/scheduler/cron v0.8.0
gopkg.in/yaml.v3 v3.0.1
)

Expand All @@ -34,15 +33,14 @@ require (
github.com/prometheus/client_golang v1.22.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.65.0 // indirect
github.com/prometheus/procfs v0.16.0 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/smartcontractkit/libocr v0.0.0-20250707144819-babe0ec4e358 // indirect
github.com/stretchr/testify v1.10.0 // indirect
github.com/stretchr/testify v1.11.1 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
golang.org/x/crypto v0.40.0 // indirect
golang.org/x/sys v0.34.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/protobuf v1.36.7 // indirect
)
Loading