Skip to content

Commit 434e0e9

Browse files
authored
Merge pull request #605 from Beckn-One/feat/issues_585
Feat: Network Observability - OTelSetup plugin, Instrumentation in Core.
2 parents 9d60045 + 59aa058 commit 434e0e9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+2893
-344
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Logs
22
.DS_Store
33
logs
4+
.idea
45
*.log
56
npm-debug.log*
67
yarn-debug.log*

CONFIG.md

Lines changed: 86 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,7 @@ log:
199199
#### `plugins.otelsetup`
200200
**Type**: `object`
201201
**Required**: No
202-
**Description**: OpenTelemetry configuration controlling whether the Prometheus exporter is enabled.
203-
204-
**Important**: This block is optional—omit it to run without telemetry. When present, the `/metrics` endpoint is exposed on a separate port (configurable via `metricsPort`) only if `enableMetrics: true`.
202+
**Description**: OpenTelemetry (OTLP) configuration for metrics, traces, and logs. When configured, telemetry is exported to an OTLP collector endpoint. Omit this block to run without telemetry.
205203

206204
##### Parameters:
207205

@@ -215,11 +213,10 @@ log:
215213
**Required**: Yes
216214
**Description**: Plugin configuration parameters.
217215

218-
###### `config.enableMetrics`
219-
**Type**: `string` (boolean)
220-
**Required**: No
221-
**Default**: `"true"`
222-
**Description**: Enables metrics collection and the `/metrics` endpoint. Must be `"true"` or `"false"` as a string.
216+
###### `config.otlpEndpoint`
217+
**Type**: `string`
218+
**Required**: Yes (when OtelSetup is used)
219+
**Description**: OTLP gRPC endpoint (host:port) for exporting metrics, traces, and logs. Example: `"localhost:4317"`, `"otel-collector-bap:4317"`.
223220

224221
###### `config.serviceName`
225222
**Type**: `string`
@@ -238,47 +235,114 @@ log:
238235
**Default**: `"development"`
239236
**Description**: Sets the `deployment.environment` attribute (e.g., `development`, `staging`, `production`).
240237

241-
###### `config.metricsPort`
238+
###### `config.domain`
242239
**Type**: `string`
243240
**Required**: No
244241
**Default**: `"9090"`
245242
**Description**: Port on which the metrics HTTP server will listen. The metrics endpoint is hosted on a separate server from the main application.
246243

247-
**Example - Enable Metrics** (matches `config/local-simple.yaml`):
244+
###### `config.enableMetrics`
245+
**Type**: `string` (boolean)
246+
**Required**: No
247+
**Default**: `"false"`
248+
**Description**: Enables metrics collection and OTLP metric export. Use `"true"` or `"false"` as a string.
249+
250+
###### `config.enableTracing`
251+
**Type**: `string` (boolean)
252+
**Required**: No
253+
**Default**: `"false"`
254+
**Description**: Enables trace export via OTLP. Use `"true"` or `"false"` as a string.
255+
256+
###### `config.enableLogs`
257+
**Type**: `string` (boolean)
258+
**Required**: No
259+
**Default**: `"false"`
260+
**Description**: Enables log export via OTLP (e.g. audit logs). Use `"true"` or `"false"` as a string.
261+
262+
###### `config.timeInterval`
263+
**Type**: `string` (integer)
264+
**Required**: No
265+
**Default**: `"5"`
266+
**Description**: Time interval in seconds used for periodic metric export or batching.
267+
268+
###### `config.auditFieldsConfig`
269+
**Type**: `string`
270+
**Required**: No
271+
**Description**: Path to a YAML file that defines which request/response fields are included in audit logs, per action. See [Audit fields configuration](#audit-fields-configuration). Example: `"/app/config/audit-fields.yaml"`.
272+
273+
274+
**Example - OTLP export with audit logs** (e.g. `config/local-beckn-one-bap.yaml`):
248275
```yaml
249276
plugins:
250277
otelsetup:
251278
id: otelsetup
252279
config:
253-
serviceName: "beckn-onix"
280+
serviceName: "beckn-one-bap"
254281
serviceVersion: "1.0.0"
255-
enableMetrics: "true"
256282
environment: "development"
257-
metricsPort: "9090"
283+
domain: "ev_charging"
284+
otlpEndpoint: "otel-collector-bap:4317"
285+
enableMetrics: "true"
286+
enableTracing: "true"
287+
enableLogs: "true"
288+
timeInterval: "5"
289+
networkMetricsGranularity: "2min"
290+
networkMetricsFrequency: "4min"
291+
auditFieldsConfig: "/app/config/audit-fields.yaml"
258292
```
259293

260-
### Accessing Metrics
261294

262-
When `plugins.otelsetup.config.enableMetrics: "true"`, the metrics endpoint is hosted on a separate HTTP server. Scrape metrics at:
263295

296+
### Audit fields configuration
297+
298+
When `config.auditFieldsConfig` points to a YAML file, audit logs (emitted via OTLP when `enableLogs: "true"`) include only the fields you list per action. The file format:
299+
300+
```yaml
301+
auditRules:
302+
default: # Optional: fallback for actions without a specific list
303+
- context.transaction_id
304+
- context.message_id
305+
- context.action
306+
- context.domain
307+
- context.bap_id
308+
- context.bpp_id
309+
discover:
310+
- context.transaction_id
311+
- context.message_id
312+
- context.action
313+
- context.timestamp
314+
- message.filters
315+
- message.spatial
316+
select:
317+
- context.transaction_id
318+
- context.message_id
319+
- context.action
320+
- message.order.beckn:buyer.beckn:id
321+
# ... more dot-path fields
264322
```
265-
http://your-server:9090/metrics
266-
```
267323

268-
**Note**: The metrics server runs on the port specified by `config.metricsPort` (default: `9090`), which is separate from the main application port configured in `http.port`.
324+
- **Top-level key**: `auditRules`.
325+
- **Action keys**: Use Beckn action names (e.g. `discover`, `select`, `init`, `confirm`, `update`, `track`, `cancel`, `rating`, `support`). Use `default` for actions that do not have a specific list.
326+
- **Values**: List of dot-path strings into the request/response JSON (e.g. `context.transaction_id`, `message.order.beckn:id`). Namespaced keys use colons (e.g. `beckn:id`).
327+
328+
See `config/audit-fields.yaml` for a full example.
269329

270330
### Metrics Collected
271331

332+
When OtelSetup is configured with `otlpEndpoint`, metrics and traces are exported via OTLP (no separate metrics HTTP server). Scrape metrics from your OTLP collector
333+
272334
Metrics are organized by module for better maintainability and encapsulation:
273335

274336
#### OTel Setup (from `otelsetup` plugin)
275-
- Prometheus exporter & `/metrics` endpoint on separate HTTP server
276-
- Go runtime instrumentation (`go_*`), resource attributes, and meter provider wiring
337+
- OTLP export for metrics, traces, and logs (gRPC endpoint).
338+
- Go runtime instrumentation (`go_*`), resource attributes, and meter/tracer provider wiring.
339+
- When `enableLogs: "true"` and `auditFieldsConfig` is set, audit logs are emitted via OTLP with fields defined in the audit-fields YAML.
277340

278341
#### Step Execution Metrics (from `telemetry` package)
279342
- `onix_step_executions_total`, `onix_step_execution_duration_seconds`, `onix_step_errors_total`
280343

281344
#### Handler Metrics (from `handler` module)
345+
- `onix_http_request_count` – HTTP requests by status class, route, method, role, sender, recipient (and optional network metric attributes).
282346
- `beckn_signature_validations_total` - Signature validation attempts
283347
- `beckn_schema_validations_total` - Schema validation attempts
284348
- `onix_routing_decisions_total` - Routing decisions taken by handler
@@ -752,12 +816,12 @@ publisher:
752816
middleware:
753817
- id: reqpreprocessor
754818
config:
755-
uuidKeys: transaction_id,message_id
756819
role: bap
820+
contextKeys: transaction_id,message_id,subscriber_id,module_id
757821
```
758822

759823
**Parameters**:
760-
- `uuidKeys`: Comma-separated list of fields to auto-generate UUIDs for if missing
824+
- `contextKeys`: Comma-separated list of fields to auto-generate UUIDs for if missing
761825
- `role`: BAP or BPP role for request processing
762826

763827
---

README.md

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ The **Beckn Protocol** is an open protocol that enables location-aware, local co
132132
- **Decrypter**: AES decryption for encrypted data processing
133133
- **ReqPreprocessor**: Request preprocessing (UUID generation, headers)
134134
- **ReqMapper**: Middleware to transform payload either between Beckn versions or against other platforms.
135-
- **OtelSetup**: Observability Setup to make metrics, traces and logs available
135+
- **OtelSetup**: Observability setup for metrics, traces, and logs (OTLP). Supports optional audit log configuration via `auditFieldsConfig` (YAML mapping actions to fields) . See [CONFIG.md](CONFIG.md) for details.
136136

137137

138138
## Quick Start
@@ -330,10 +330,11 @@ modules:
330330
### Deployment Modes
331331
332332
1. **Combined Mode**: Single instance handling both BAP and BPP (`config/onix/`) - Uses `secretskeymanager` (HashiCorp Vault) for production key management
333-
2. **BAP-Only Mode**: Dedicated buyer-side deployment (`config/onix-bap/`)
334-
3. **BPP-Only Mode**: Dedicated seller-side deployment (`config/onix-bpp/`)
335-
4. **Local Development Combined Mode**: Simplified configuration (`config/local-simple.yaml`) - Uses `simplekeymanager` with embedded Ed25519 keys, no vault setup needed.
336-
5. **Local Development Combined Mode (Alternative)**: Development configuration (`config/local-dev.yaml`) - Uses `keymanager` vault setup needed
333+
2. **BAP-Only Mode**: Dedicated buyer-side deployment (`config/onix-bap/`)
334+
3. **BPP-Only Mode**: Dedicated seller-side deployment (`config/onix-bpp/`)
335+
4. **Local Development Combined Mode**: Simplified configuration (`config/local-simple.yaml`) - Uses `simplekeymanager` with embedded Ed25519 keys, no vault setup needed
336+
5. **Local Development Combined Mode (Alternative)**: Development configuration (`config/local-dev.yaml`) - Uses `keymanager`, vault setup needed
337+
6. **Local with Observability (BAP/BPP)**: Configs `config/local-beckn-one-bap.yaml` and `config/local-beckn-one-bpp.yaml` include OtelSetup (metrics, traces, audit logs) for use with an OTLP collector. Audit fields are configured via `config/audit-fields.yaml`. For a full stack (collectors, Grafana, Loki), see `install/network-observability/`
337338

338339
## API Endpoints
339340

@@ -359,14 +360,6 @@ modules:
359360
| POST | `/bpp/receiver/*` | Receives all BAP requests |
360361
| POST | `/bpp/caller/on_*` | Sends responses back to BAP |
361362

362-
### Observability Endpoints
363-
364-
| Method | Endpoint | Description |
365-
|--------|----------|-------------|
366-
| GET | `/health` | Health check endpoint |
367-
| GET | `/metrics` | Prometheus metrics endpoint (when telemetry is enabled) |
368-
369-
**Note**: The `/metrics` endpoint is available when `telemetry.enableMetrics: true` in the configuration file. It returns metrics in Prometheus format.
370363

371364
## Documentation
372365

cmd/adapter/main.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"sync"
1212
"time"
1313

14+
"github.com/beckn-one/beckn-onix/pkg/model"
1415
"gopkg.in/yaml.v2"
1516

1617
"github.com/beckn-one/beckn-onix/core/module"
@@ -153,6 +154,9 @@ func run(ctx context.Context, configPath string) error {
153154
return fmt.Errorf("failed to initialize logger: %w", err)
154155
}
155156

157+
//to add the parent_id in the context value so it get passed to the logs
158+
ctx = addParentIdCtx(ctx, cfg)
159+
156160
// Initialize plugin manager.
157161
log.Infof(ctx, "Initializing plugin manager")
158162
mgr, closer, err := newManagerFunc(ctx, cfg.PluginManager)
@@ -220,3 +224,40 @@ func shutdown(ctx context.Context, httpServer *http.Server, wg *sync.WaitGroup,
220224
}
221225
}()
222226
}
227+
228+
func addParentIdCtx(ctx context.Context, config *Config) context.Context {
229+
var parentID string
230+
var podName string
231+
232+
if p := os.Getenv("POD_NAME"); p != "" {
233+
log.Infof(ctx, "Adding POD name: %s", p)
234+
podName = p
235+
} else {
236+
log.Info(ctx, "POD_NAME environment variable not set, falling back to hostname")
237+
if hostname, err := os.Hostname(); err == nil {
238+
log.Infof(ctx, "Setting POD name as hostname: %s", hostname)
239+
podName = hostname
240+
} else {
241+
log.Info(ctx, "failed to get POD name")
242+
}
243+
}
244+
245+
for _, m := range config.Modules {
246+
if m.Handler.Role == "" || m.Handler.SubscriberID == "" {
247+
continue
248+
}
249+
candidate := string(m.Handler.Role) + ":" + m.Handler.SubscriberID + ":" + podName
250+
if parentID == "" {
251+
parentID = candidate
252+
} else if candidate != parentID {
253+
log.Warnf(ctx, "Multiple distinct role:subscriberID pairs found in modules (using %q, also saw %q); consider explicit parent_id config", parentID, candidate)
254+
}
255+
}
256+
257+
if parentID != "" {
258+
ctx = context.WithValue(ctx, model.ContextKeyParentID, parentID)
259+
} else {
260+
log.Warnf(ctx, "Failed to find parent ID in config; add role and subscriber_id to the handler config")
261+
}
262+
return ctx
263+
}

config/audit-fields.yaml

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
auditRules:
2+
default:
3+
- context.transaction_id
4+
- context.message_id
5+
- context.action
6+
- context.domain
7+
- context.bap_id
8+
- context.bpp_id
9+
10+
discover:
11+
- context.transaction_id
12+
- context.message_id
13+
- context.action
14+
- context.timestamp
15+
- message.filters
16+
- message.spatial
17+
18+
select:
19+
- context.transaction_id
20+
- context.message_id
21+
- context.action
22+
- context.timestamp
23+
- message.order.beckn:buyer.beckn:id
24+
- message.order.beckn:seller
25+
- message.order.beckn:orderItems.beckn:acceptedOffer.beckn:id
26+
- message.order.beckn:orderAttributes
27+
28+
init:
29+
- context.transaction_id
30+
- context.message_id
31+
- context.action
32+
- context.timestamp
33+
- message.order.beckn:id
34+
- message.order.beckn:buyer.beckn:id
35+
- message.order.beckn:orderValue.value
36+
- message.order.beckn:payment.beckn:paymentStatus
37+
38+
confirm:
39+
- context.transaction_id
40+
- context.message_id
41+
- context.action
42+
- context.timestamp
43+
- message.order.beckn:id
44+
- message.order.beckn:orderStatus
45+
- message.order.beckn:buyer.beckn:id
46+
- message.order.beckn:payment.beckn:txnRef
47+
- message.order.beckn:payment.beckn:paymentStatus
48+
49+
update:
50+
- context.transaction_id
51+
- context.message_id
52+
- context.action
53+
- context.timestamp
54+
- message.order.beckn:id
55+
- message.order.beckn:orderStatus
56+
- message.order.beckn:fulfillment.beckn:deliveryAttributes.sessionStatus
57+
58+
track:
59+
- context.transaction_id
60+
- context.message_id
61+
- context.action
62+
- context.timestamp
63+
- message.order.beckn:id
64+
65+
cancel:
66+
- context.transaction_id
67+
- context.message_id
68+
- context.action
69+
- context.timestamp
70+
- message.order.beckn:id
71+
- message.order.beckn:orderStatus
72+
- message.order.beckn:buyer.beckn:id
73+
74+
rating:
75+
- context.transaction_id
76+
- context.message_id
77+
- context.action
78+
- context.timestamp
79+
- message.id
80+
- message.value
81+
- message.category
82+
83+
support:
84+
- context.transaction_id
85+
- context.message_id
86+
- context.action
87+
- context.timestamp
88+
- message.ref_id
89+
- message.ref_type

config/local-beckn-one-bap.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,25 @@ http:
1616
idle: 30
1717
pluginManager:
1818
root: ./plugins
19+
20+
# OpenTelemetry (OTLP) - metrics and traces sent to OTEL collector
21+
plugins:
22+
otelsetup:
23+
id: otelsetup
24+
config:
25+
serviceName: "beckn-one-bap"
26+
serviceVersion: "1.0.0"
27+
environment: "development"
28+
domain: "ev_charging"
29+
otlpEndpoint: "otel-collector-bap:4317"
30+
enableMetrics: "true"
31+
networkMetricsGranularity: "2min"
32+
networkMetricsFrequency: "4min"
33+
enableTracing: "true"
34+
enableLogs: "true"
35+
timeInterval: "5"
36+
auditFieldsConfig: "/app/config/audit-fields.yaml"
37+
1938
modules:
2039
- name: bapTxnReceiver
2140
path: /bap/receiver/

0 commit comments

Comments
 (0)