update the as per the comment

This commit is contained in:
Manendra Pal Singh
2025-12-18 12:30:28 +05:30
parent 17d9ca865d
commit 176b8f3043
14 changed files with 60 additions and 40 deletions

View File

@@ -296,10 +296,10 @@ Each metric includes consistent labels such as `module`, `role`, `action`, `stat
**Note**: Metric definitions are now located in their respective modules: **Note**: Metric definitions are now located in their respective modules:
- OTel setup: `pkg/plugin/implementation/otelsetup` - OTel setup: `pkg/plugin/implementation/otelsetup`
- Step metrics: `pkg/telemetry/step_metrics.go` - Step metrics: `core/module/handler/step_metrics.go`
- Handler metrics: `core/module/handler/metrics.go` - Handler metrics: `core/module/handler/handlerMetrics.go`
- Cache metrics: `pkg/plugin/implementation/cache/metrics.go` - Cache metrics: `pkg/plugin/implementation/cache/cache_metrics.go`
- Plugin metrics: `pkg/telemetry/metrics.go` - Plugin metrics: `pkg/telemetry/pluginMetrics.go`
--- ---

View File

@@ -17,6 +17,7 @@ import (
"github.com/beckn-one/beckn-onix/core/module/handler" "github.com/beckn-one/beckn-onix/core/module/handler"
"github.com/beckn-one/beckn-onix/pkg/log" "github.com/beckn-one/beckn-onix/pkg/log"
"github.com/beckn-one/beckn-onix/pkg/plugin" "github.com/beckn-one/beckn-onix/pkg/plugin"
"github.com/beckn-one/beckn-onix/pkg/telemetry"
) )
// ApplicationPlugins holds application-level plugin configurations. // ApplicationPlugins holds application-level plugin configurations.
@@ -97,18 +98,31 @@ func validateConfig(cfg *Config) error {
return nil return nil
} }
// initPlugins initializes application-level plugins including telemetry. // loadAppPlugin is a generic function to load and validate application-level plugins.
func initPlugins(ctx context.Context, mgr *plugin.Manager, otelSetupCfg *plugin.Config) error { func loadAppPlugin[T any](ctx context.Context, name string, cfg *plugin.Config, mgrFunc func(context.Context, *plugin.Config) (T, error)) error {
if otelSetupCfg == nil { if cfg == nil {
log.Info(ctx, "Telemetry config not provided; skipping OpenTelemetry setup") log.Debugf(ctx, "Skipping %s plugin: not configured", name)
return nil return nil
} }
log.Infof(ctx, "Initializing telemetry via plugin id=%s", otelSetupCfg.ID) _, err := mgrFunc(ctx, cfg)
_, err := mgr.OtelSetup(ctx, otelSetupCfg)
if err != nil { if err != nil {
return fmt.Errorf("failed to initialize telemetry plugin: %w", err) return fmt.Errorf("failed to load %s plugin (%s): %w", name, cfg.ID, err)
} }
log.Debugf(ctx, "Loaded %s plugin: %s", name, cfg.ID)
return nil
}
// initAppPlugins initializes application-level plugins including telemetry.
// This function is designed to be extensible for future plugin types.
func initAppPlugins(ctx context.Context, mgr *plugin.Manager, cfg ApplicationPlugins) error {
if err := loadAppPlugin(ctx, "OtelSetup", cfg.OtelSetup, func(ctx context.Context, cfg *plugin.Config) (*telemetry.Provider, error) {
return mgr.OtelSetup(ctx, cfg)
}); err != nil {
return fmt.Errorf("failed to initialize application plugins: %w", err)
}
return nil return nil
} }
@@ -148,7 +162,7 @@ func run(ctx context.Context, configPath string) error {
log.Debug(ctx, "Plugin manager loaded.") log.Debug(ctx, "Plugin manager loaded.")
// Initialize plugins including telemetry. // Initialize plugins including telemetry.
if err := initPlugins(ctx, mgr, cfg.Plugins.OtelSetup); err != nil { if err := initAppPlugins(ctx, mgr, cfg.Plugins); err != nil {
return fmt.Errorf("failed to initialize plugins: %w", err) return fmt.Errorf("failed to initialize plugins: %w", err)
} }

View File

@@ -13,7 +13,6 @@ import (
"github.com/beckn-one/beckn-onix/pkg/plugin" "github.com/beckn-one/beckn-onix/pkg/plugin"
"github.com/beckn-one/beckn-onix/pkg/plugin/definition" "github.com/beckn-one/beckn-onix/pkg/plugin/definition"
"github.com/beckn-one/beckn-onix/pkg/response" "github.com/beckn-one/beckn-onix/pkg/response"
"github.com/beckn-one/beckn-onix/pkg/telemetry"
) )
// stdHandler orchestrates the execution of defined processing steps. // stdHandler orchestrates the execution of defined processing steps.
@@ -311,7 +310,7 @@ func (h *stdHandler) initSteps(ctx context.Context, mgr PluginManager, cfg *Conf
if err != nil { if err != nil {
return err return err
} }
instrumentedStep, wrapErr := telemetry.NewInstrumentedStep(s, step, h.moduleName) instrumentedStep, wrapErr := NewInstrumentedStep(s, step, h.moduleName)
if wrapErr != nil { if wrapErr != nil {
log.Warnf(ctx, "Failed to instrument step %s: %v", step, wrapErr) log.Warnf(ctx, "Failed to instrument step %s: %v", step, wrapErr)
h.steps = append(h.steps, s) h.steps = append(h.steps, s)

View File

@@ -1,4 +1,4 @@
package telemetry package handler
import ( import (
"context" "context"
@@ -11,6 +11,7 @@ import (
"github.com/beckn-one/beckn-onix/pkg/log" "github.com/beckn-one/beckn-onix/pkg/log"
"github.com/beckn-one/beckn-onix/pkg/model" "github.com/beckn-one/beckn-onix/pkg/model"
"github.com/beckn-one/beckn-onix/pkg/telemetry"
) )
// StepRunner represents the minimal contract required for step instrumentation. // StepRunner represents the minimal contract required for step instrumentation.
@@ -56,9 +57,9 @@ func (is *InstrumentedStep) Run(ctx *model.StepContext) error {
duration := time.Since(start).Seconds() duration := time.Since(start).Seconds()
attrs := []attribute.KeyValue{ attrs := []attribute.KeyValue{
AttrModule.String(is.moduleName), telemetry.AttrModule.String(is.moduleName),
AttrStep.String(is.stepName), telemetry.AttrStep.String(is.stepName),
AttrRole.String(string(ctx.Role)), telemetry.AttrRole.String(string(ctx.Role)),
} }
is.metrics.StepExecutionTotal.Add(ctx.Context, 1, metric.WithAttributes(attrs...)) is.metrics.StepExecutionTotal.Add(ctx.Context, 1, metric.WithAttributes(attrs...))
@@ -73,10 +74,11 @@ func (is *InstrumentedStep) Run(ctx *model.StepContext) error {
} }
} }
errorAttrs := append(attrs, AttrErrorType.String(errorType)) errorAttrs := append(attrs, telemetry.AttrErrorType.String(errorType))
is.metrics.StepErrorsTotal.Add(ctx.Context, 1, metric.WithAttributes(errorAttrs...)) is.metrics.StepErrorsTotal.Add(ctx.Context, 1, metric.WithAttributes(errorAttrs...))
log.Errorf(ctx.Context, err, "Step %s failed", is.stepName) log.Errorf(ctx.Context, err, "Step %s failed", is.stepName)
} }
return err return err
} }

View File

@@ -1,4 +1,4 @@
package telemetry package handler
import ( import (
"context" "context"
@@ -6,6 +6,7 @@ import (
"testing" "testing"
"github.com/beckn-one/beckn-onix/pkg/model" "github.com/beckn-one/beckn-onix/pkg/model"
"github.com/beckn-one/beckn-onix/pkg/telemetry"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@@ -19,7 +20,7 @@ func (s stubStep) Run(ctx *model.StepContext) error {
func TestInstrumentedStepSuccess(t *testing.T) { func TestInstrumentedStepSuccess(t *testing.T) {
ctx := context.Background() ctx := context.Background()
provider, err := NewTestProvider(ctx) provider, err := telemetry.NewTestProvider(ctx)
require.NoError(t, err) require.NoError(t, err)
defer provider.Shutdown(context.Background()) defer provider.Shutdown(context.Background())
@@ -35,7 +36,7 @@ func TestInstrumentedStepSuccess(t *testing.T) {
func TestInstrumentedStepError(t *testing.T) { func TestInstrumentedStepError(t *testing.T) {
ctx := context.Background() ctx := context.Background()
provider, err := NewTestProvider(ctx) provider, err := telemetry.NewTestProvider(ctx)
require.NoError(t, err) require.NoError(t, err)
defer provider.Shutdown(context.Background()) defer provider.Shutdown(context.Background())
@@ -48,3 +49,4 @@ func TestInstrumentedStepError(t *testing.T) {
} }
require.Error(t, step.Run(stepCtx)) require.Error(t, step.Run(stepCtx))
} }

View File

@@ -1,4 +1,4 @@
package telemetry package handler
import ( import (
"context" "context"

View File

@@ -1,4 +1,4 @@
package telemetry package handler
import ( import (
"context" "context"
@@ -7,6 +7,7 @@ import (
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
"github.com/beckn-one/beckn-onix/pkg/telemetry"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@@ -15,7 +16,7 @@ func TestGetStepMetrics_Success(t *testing.T) {
ctx := context.Background() ctx := context.Background()
// Initialize telemetry provider first // Initialize telemetry provider first
provider, err := NewTestProvider(ctx) provider, err := telemetry.NewTestProvider(ctx)
require.NoError(t, err) require.NoError(t, err)
defer provider.Shutdown(context.Background()) defer provider.Shutdown(context.Background())
@@ -34,7 +35,7 @@ func TestGetStepMetrics_ConcurrentAccess(t *testing.T) {
ctx := context.Background() ctx := context.Background()
// Initialize telemetry provider first // Initialize telemetry provider first
provider, err := NewTestProvider(ctx) provider, err := telemetry.NewTestProvider(ctx)
require.NoError(t, err) require.NoError(t, err)
defer provider.Shutdown(context.Background()) defer provider.Shutdown(context.Background())
@@ -71,7 +72,7 @@ func TestStepMetrics_Instruments(t *testing.T) {
ctx := context.Background() ctx := context.Background()
// Initialize telemetry provider // Initialize telemetry provider
provider, err := NewTestProvider(ctx) provider, err := telemetry.NewTestProvider(ctx)
require.NoError(t, err) require.NoError(t, err)
defer provider.Shutdown(context.Background()) defer provider.Shutdown(context.Background())
@@ -87,19 +88,19 @@ func TestStepMetrics_Instruments(t *testing.T) {
// Test StepExecutionDuration // Test StepExecutionDuration
require.NotPanics(t, func() { require.NotPanics(t, func() {
metrics.StepExecutionDuration.Record(ctx, 0.5, metrics.StepExecutionDuration.Record(ctx, 0.5,
metric.WithAttributes(AttrStep.String("test-step"), AttrModule.String("test-module"))) metric.WithAttributes(telemetry.AttrStep.String("test-step"), telemetry.AttrModule.String("test-module")))
}, "StepExecutionDuration.Record should not panic") }, "StepExecutionDuration.Record should not panic")
// Test StepExecutionTotal // Test StepExecutionTotal
require.NotPanics(t, func() { require.NotPanics(t, func() {
metrics.StepExecutionTotal.Add(ctx, 1, metrics.StepExecutionTotal.Add(ctx, 1,
metric.WithAttributes(AttrStep.String("test-step"), AttrModule.String("test-module"))) metric.WithAttributes(telemetry.AttrStep.String("test-step"), telemetry.AttrModule.String("test-module")))
}, "StepExecutionTotal.Add should not panic") }, "StepExecutionTotal.Add should not panic")
// Test StepErrorsTotal // Test StepErrorsTotal
require.NotPanics(t, func() { require.NotPanics(t, func() {
metrics.StepErrorsTotal.Add(ctx, 1, metrics.StepErrorsTotal.Add(ctx, 1,
metric.WithAttributes(AttrStep.String("test-step"), AttrModule.String("test-module"))) metric.WithAttributes(telemetry.AttrStep.String("test-step"), telemetry.AttrModule.String("test-module")))
}, "StepErrorsTotal.Add should not panic") }, "StepErrorsTotal.Add should not panic")
// Verify metrics are exposed via HTTP handler // Verify metrics are exposed via HTTP handler
@@ -113,7 +114,7 @@ func TestStepMetrics_MultipleCalls(t *testing.T) {
ctx := context.Background() ctx := context.Background()
// Initialize telemetry provider // Initialize telemetry provider
provider, err := NewTestProvider(ctx) provider, err := telemetry.NewTestProvider(ctx)
require.NoError(t, err) require.NoError(t, err)
defer provider.Shutdown(context.Background()) defer provider.Shutdown(context.Background())
@@ -127,3 +128,4 @@ func TestStepMetrics_MultipleCalls(t *testing.T) {
assert.NotNil(t, metrics.StepErrorsTotal, "StepErrorsTotal should be initialized") assert.NotNil(t, metrics.StepErrorsTotal, "StepErrorsTotal should be initialized")
} }
} }

View File

@@ -6,10 +6,10 @@ import (
"github.com/beckn-one/beckn-onix/pkg/telemetry" "github.com/beckn-one/beckn-onix/pkg/telemetry"
) )
// MetricsProvider encapsulates initialization of OpenTelemetry metrics // OtelSetupMetricsProvider encapsulates initialization of OpenTelemetry metrics
// providers. Implementations wire exporters and return a Provider that the core // providers. Implementations wire exporters and return a Provider that the core
// application can manage. // application can manage.
type MetricsProvider interface { type OtelSetupMetricsProvider interface {
// New initializes a new telemetry provider instance with the given configuration. // New initializes a new telemetry provider instance with the given configuration.
New(ctx context.Context, config map[string]string) (*telemetry.Provider, func() error, error) New(ctx context.Context, config map[string]string) (*telemetry.Provider, func() error, error)
} }

View File

@@ -11,7 +11,7 @@ import (
"github.com/beckn-one/beckn-onix/pkg/telemetry" "github.com/beckn-one/beckn-onix/pkg/telemetry"
) )
// metricsProvider implements the MetricsProvider interface for the otelsetup plugin. // metricsProvider implements the OtelSetupMetricsProvider interface for the otelsetup plugin.
type metricsProvider struct { type metricsProvider struct {
impl otelsetup.Setup impl otelsetup.Setup
} }

View File

@@ -23,7 +23,7 @@ import (
) )
// Setup wires the telemetry provider. This is the concrete implementation // Setup wires the telemetry provider. This is the concrete implementation
// behind the MetricsProvider interface. // behind the OtelSetupMetricsProvider interface.
type Setup struct{} type Setup struct{}
// Config represents OpenTelemetry related configuration. // Config represents OpenTelemetry related configuration.
@@ -151,7 +151,8 @@ func (Setup) New(ctx context.Context, cfg *Config) (*telemetry.Provider, error)
}() }()
return &telemetry.Provider{ return &telemetry.Provider{
MeterProvider: meterProvider, MeterProvider: meterProvider,
MetricsHandler: metricsHandler,
Shutdown: func(shutdownCtx context.Context) error { Shutdown: func(shutdownCtx context.Context) error {
log.Infof(ctx, "Shutting down metrics server...") log.Infof(ctx, "Shutting down metrics server...")
// Shutdown the metrics server // Shutdown the metrics server

View File

@@ -206,7 +206,7 @@ func (m *Manager) OtelSetup(ctx context.Context, cfg *Config) (*telemetry.Provid
return nil, nil return nil, nil
} }
otp, err := provider[definition.MetricsProvider](m.plugins, cfg.ID) otp, err := provider[definition.OtelSetupMetricsProvider](m.plugins, cfg.ID)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to load provider for %s: %w", cfg.ID, err) return nil, fmt.Errorf("failed to load provider for %s: %w", cfg.ID, err)
} }

View File

@@ -14,9 +14,9 @@ import (
// Note: Most metrics have been moved to their respective modules. Only plugin-level // Note: Most metrics have been moved to their respective modules. Only plugin-level
// metrics remain here. See: // metrics remain here. See:
// - OTel setup: pkg/plugin/implementation/otelsetup // - OTel setup: pkg/plugin/implementation/otelsetup
// - Step metrics: pkg/telemetry/step_metrics.go // - Step metrics: core/module/handler/step_metrics.go
// - Cache metrics: pkg/plugin/implementation/cache/metrics.go // - Cache metrics: pkg/plugin/implementation/cache/cache_metrics.go
// - Handler metrics: core/module/handler/metrics.go // - Handler metrics: core/module/handler/handlerMetrics.go
type Metrics struct { type Metrics struct {
PluginExecutionDuration metric.Float64Histogram PluginExecutionDuration metric.Float64Histogram
PluginErrorsTotal metric.Int64Counter PluginErrorsTotal metric.Int64Counter