Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
13 changes: 12 additions & 1 deletion audit/audit.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/sirupsen/logrus"
"strings"
"sync"

"github.com/nuts-foundation/nuts-node/core"
"github.com/sirupsen/logrus"
)

const (
Expand Down Expand Up @@ -61,6 +63,15 @@ const auditLogLevel = "audit"
var auditLoggerInstance *logrus.Logger
var initAuditLoggerOnce = &sync.Once{}

func init() {
// Register callback so core.SetupTracing can add hooks to the audit logger.
// This is needed because the audit logger is a separate logrus instance,
// and we can't import audit from core due to circular dependencies.
core.RegisterAuditLogHook = func(hook logrus.Hook) {
auditLogger().AddHook(hook)
}
}

// auditLogger returns the initialized logger instance intended for audit logging.
func auditLogger() *logrus.Logger {
initAuditLoggerOnce.Do(func() {
Expand Down
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func startServer(ctx context.Context, system *core.System) error {
logrus.Info(fmt.Sprintf("Build info: \n%s", core.BuildInfo()))
logrus.Info(fmt.Sprintf("Config: \n%s", system.Config.PrintConfig()))

// check config on all engines
// check config on all engines (also initializes tracing)
if err := system.Configure(); err != nil {
return err
}
Expand Down
21 changes: 18 additions & 3 deletions core/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ package core
import (
"context"
"fmt"
"github.com/sirupsen/logrus"
"github.com/spf13/pflag"
"os"
"strings"

"github.com/sirupsen/logrus"
"github.com/spf13/pflag"
)

// Routable enables connecting a REST API to the echo server. The API wrappers should implement this interface
Expand Down Expand Up @@ -57,6 +58,8 @@ type System struct {
Context context.Context
// ContextCancel is a function to signal the system should shut down.
ContextCancel context.CancelFunc
// tracingShutdown is the shutdown function for OpenTelemetry tracing
tracingShutdown func(context.Context) error
}

var coreLogger = logrus.StandardLogger().WithField(LogFieldModule, "core")
Expand Down Expand Up @@ -111,13 +114,25 @@ func (system *System) Shutdown() error {
}
coreLogger.Infof("Stopped %s", name)
}
// Shutdown tracing last to ensure all logs are flushed
if system.tracingShutdown != nil {
if err := system.tracingShutdown(context.Background()); err != nil {
coreLogger.WithError(err).Error("Failed to shutdown tracing")
}
}
return nil
}

// Configure configures all engines in the system.
func (system *System) Configure() error {
// Set up tracing first, so all logs (including engine configuration) go to the configured destination
tracingShutdown, err := SetupTracing(system.Config.Tracing)
if err != nil {
return fmt.Errorf("failed to setup tracing: %w", err)
}
system.tracingShutdown = tracingShutdown

coreLogger.Debugf("Creating datadir: %s", system.Config.Datadir)
var err error
if err = os.MkdirAll(system.Config.Datadir, os.ModePerm); err != nil {
return fmt.Errorf("unable to create datadir (dir=%s): %w", system.Config.Datadir, err)
}
Expand Down
17 changes: 14 additions & 3 deletions core/http_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ package core
import (
"context"
"fmt"
"github.com/sirupsen/logrus"
"io"
"net/http"

"github.com/sirupsen/logrus"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)

// HttpResponseBodyLogClipAt is the maximum length of a response body to log.
Expand Down Expand Up @@ -98,8 +100,17 @@ func (w httpRequestDoerAdapter) Do(req *http.Request) (*http.Response, error) {
// If the given authorization token builder is non-nil, it calls it and passes the resulting token as bearer token with requests.
func CreateHTTPInternalClient(cfg ClientConfig, generator AuthorizationTokenGenerator) (HTTPRequestDoer, error) {
var result *httpRequestDoerAdapter
client := &http.Client{}
client.Timeout = cfg.Timeout
var transport http.RoundTripper = http.DefaultTransport
if TracingEnabled() {
transport = otelhttp.NewTransport(http.DefaultTransport,
otelhttp.WithSpanNameFormatter(func(_ string, r *http.Request) string {
return "internal-api: " + r.Method + " " + r.URL.Path
}))
}
client := &http.Client{
Transport: transport,
Timeout: cfg.Timeout,
}

result = &httpRequestDoerAdapter{
fn: client.Do,
Expand Down
14 changes: 13 additions & 1 deletion core/server_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ type ServerConfig struct {
LegacyTLS TLSConfig `koanf:"network"`
// HTTP exists to expose http.clientipheader to the nuts-network layer.
// This header should contaisn the client IP address for logging. Can be removed together with the nuts-network
HTTP HTTPConfig `koanf:"http"`
HTTP HTTPConfig `koanf:"http"`
Tracing TracingConfig `koanf:"tracing"`
configMap *koanf.Koanf
}

Expand All @@ -87,6 +88,15 @@ type HTTPClientConfig struct {
Timeout time.Duration `koanf:"timeout"`
}

// TracingConfig contains settings for OpenTelemetry tracing.
type TracingConfig struct {
// Endpoint is the OTLP collector endpoint (e.g., "localhost:4318" for HTTP).
// When empty, tracing is disabled. When set, logs are sent to both stdout and the OTLP endpoint.
Endpoint string `koanf:"endpoint"`
// Insecure disables TLS for the OTLP connection.
Insecure bool `koanf:"insecure"`
}

// TLSConfig specifies how TLS should be configured for connections.
type TLSConfig struct {
// Offload specifies the TLS offloading mode for incoming/outgoing traffic.
Expand Down Expand Up @@ -274,6 +284,8 @@ func FlagSet() *pflag.FlagSet {
flagSet.String("tls.offload", string(defaultCfg.TLS.Offload), fmt.Sprintf("Whether to enable TLS offloading for incoming gRPC connections. "+
"Enable by setting it to '%s'. If enabled 'tls.certheader' must be configured as well.", OffloadIncomingTLS))
flagSet.String("tls.certheader", defaultCfg.TLS.ClientCertHeaderName, "Name of the HTTP header that will contain the client certificate when TLS is offloaded for gRPC.")
flagSet.String("tracing.endpoint", defaultCfg.Tracing.Endpoint, "OTLP collector endpoint for OpenTelemetry tracing (e.g., 'localhost:4318'). When empty, tracing is disabled.")
flagSet.Bool("tracing.insecure", defaultCfg.Tracing.Insecure, "Disable TLS for the OTLP connection.")

return flagSet
}
Expand Down
Loading
Loading