Wiring Distributed Tracing from Microservices to Mainframe COBOL Batch Jobs
Distributed tracing across the microservices-to-mainframe boundary requires bridging two fundamentally different execution models: synchronous HTTP request-response cycles and asynchronous batch job processing with no inherent caller-callee relationship. This article maps an executable path using OpenTelemetry as the unifying telemetry layer, with version-anchored configuration for each integration point.
The Core Problem: Two Worlds, One Trace ID
A microservice emits a W3C traceparent header in the format version-trace-id-parent-id-trace-flags. The vendor documentation states this is a fixed-format string every W3C-compliant system reads identically. The challenge is preserving that trace context through to COBOL batch jobs submitted via JCL, where no HTTP headers exist and no request-response boundary defines the span hierarchy.
The impedance mismatch manifests in three dimensions:
| Dimension | Microservices Side | Mainframe Side |
|---|---|---|
| Trigger | HTTP request or message | JCL job submission, CICS transaction start |
| Span timing | Synchronous, millisecond-scale | Asynchronous, potentially hour-scale |
| Context carrier | HTTP headers, message metadata | Job cards, temporary files, CICS containers |
Without explicit propagation, a trace fragments at the mainframe boundary. The microservice shows an outbound call; the mainframe shows an orphaned batch job with no parent.
OpenTelemetry Collector Configuration: The Central Hub
The OpenTelemetry Collector serves as the vendor-agnostic receive-process-export layer. The search material references Collector Contrib version 0.162.0 and semantic conventions v1.44.0 as current documentation anchors.
Back up first: Before modifying any collector configuration, snapshot your existing otel-collector-config.yaml and any associated TLS certificates. Collector configuration changes can drop telemetry silently if receivers and exporters mismatch.
A propagation-aware collector configuration requires these components:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 1s
send_batch_size: 1024
resource:
attributes:
– key: environment
value: production
action: upsert
exporters:
otlp/mainframe-bridge:
endpoint: mainframe-sidecar.internal:4317
tls:
insecure: false
ca_file: /etc/otel/certs/ca.crt
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch, resource]
exporters: [otlp/mainframe-bridge]
This configuration follows the documented pattern for Collector 0.154.0 and later. The otlp/mainframe-bridge exporter pushes trace data to a sidecar or gateway process running on or near the mainframe. The vendor documentation notes that component availability varies by distribution; verify your chosen distribution’s manifest.yaml for included exporters.
Who this collector pattern is wrong for: Teams running CICS TS versions without native OpenTelemetry support, or sites where firewall rules block the gRPC/HTTP ports required for OTLP. These environments need queue-based telemetry egress instead.
Microservice-Side W3C Traceparent Handling
Spring Boot’s auto-configuration adds filters that extract and inject the traceparent context for each HTTP request, per the community implementation notes. For explicit control, manual propagation follows this pattern:
// OpenTelemetry API usage, SDK 1.45.0 per documented versions
TextMapPropagator propagator = W3CTraceContextPropagator.getInstance();
propagator.inject(context, carrier, setter);
The carrier becomes an HTTP header map for outbound calls, or message metadata for asynchronous handoffs. The critical requirement: the traceparent value must survive serialization to whatever format the mainframe integration uses—flat file, MQ message, or CICS COMMAREA.
For batch job initiation, the microservice typically writes the traceparent to a staging location rather than holding a synchronous connection open. The span representing “batch job submitted” should use SpanKind.PRODUCER and set its status to OK once the submission is confirmed, not when the batch completes.
CICS-Side Trace Context Propagation: Configuration Without Code Changes
IBM CICS Transaction Server for z/OS documentation states that OpenTelemetry tracing can be enabled without changing application code. Configuration involves one system-level parameter and two transaction-level attributes.
The system-level enablement:
| Parameter | Purpose | Scope |
|---|---|---|
| OTEL_ENABLED=YES | Activates OTel tracing region-wide | CICS region |
| OTEL_EXPORTER_OTLP_ENDPOINT | Target collector endpoint | CICS region |
| OTEL_RESOURCE_ATTRIBUTES | Static resource labels | CICS region |
Transaction-level attributes then control whether individual transactions participate in trace propagation and emit span data. This permits gradual rollout—critical for production mainframe environments where blanket enablement risks performance impact.
For CICS transactions invoked through CICS Transaction Gateway, the vendor documentation describes a mechanism by which monitoring products can trace requests using traceparent. The CICS TG propagates the traceparent into the CICS region, where the native OTel integration picks it up.
Flagging doc-vs-reality drift: The vendor documentation presents CICS OTel as configuration-only, but community implementations frequently require DFHWS-TRACING or similar pipeline adjustments for web service transactions. Verify traceparent arrival in your specific CICS TS version before assuming zero-code deployment.
COBOL Batch Job Tracing: JCL Injection and Direct Instrumentation
Batch jobs lack the request-response boundary that carries traceparent automatically. Two patterns bridge this gap:
Pattern A: Traceparent via JCL Job Card
The submitting microservice or scheduler writes the traceparent into a job card comment or an initial dataset:
//JOBNAME JOB (ACCT),’BATCH TRACE’,CLASS=A
//* TRACEPARENT=00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
//STEP1 EXEC PGM=MYCOBOL
The COBOL program reads this via JCL symbolic parameter parsing or dataset access, then constructs an OpenTelemetry span with the extracted trace ID as parent. This requires COBOL code changes—a CALL to an OTel SDK or sidecar API—to create the span and set the parent context.
Pattern B: Sidecar Interception
A sidecar process running on z/Linux or a connected system intercepts the job submission, creates the initial span, and exposes an API for the COBOL program to report child spans. The COBOL program uses standard HTTP client calls or MQ messages to emit span data, avoiding direct OTel SDK dependency in the legacy code.
The sidecar pattern is wrong for: Sites with strict LPAR isolation where no adjacent system can run the sidecar, or where COBOL programs cannot make outbound network calls due to security policy.
Handling the Synchronous-Asynchronous Impedance Mismatch
The core architectural tension: HTTP spans have explicit start and end timestamps with parent-child relationships defined by call nesting. Batch job spans have start times potentially hours before completion, with no active parent waiting.
The resolution is semantic, not technical. The microservice span representing job submission should:
- Use
SpanKind.PRODUCER - Set attributes indicating the target system (
mainframe.subsystem=zOS,job.name=JOBNAME) - End immediately after submission confirmation
The batch job span then:
- Uses the same trace ID with the submission span as parent
- Sets
SpanKind.CONSUMERon the initial batch step - Carries
traceparentin its propagated context field
For multi-step jobs, each step becomes a child span of the job span. The JCL step boundaries provide natural span demarcation points.
Collector-to-Mainframe Transport Options
| Transport | When Applicable | Limitation |
|---|---|---|
| OTLP/gRPC direct | CICS TS with native OTel, network path available | Requires TLS certificate management |
| OTLP/HTTP | Firewall-friendly, simpler load balancing | Larger per-span overhead |
| File-based (retry) | Air-gapped LPARs, strict batch windows | Delayed visibility, manual recovery |
| MQ bridge | Existing MQ infrastructure | Requires custom exporter or adapter |
The vendor documentation emphasizes that OpenTelemetry is vendor-agnostic, but the practical reality is that mainframe-side OTLP reception requires either IBM’s native integration (CICS TS with OTel support) or a bridge component. Community implementations using generic OTLP collectors on z/Linux are documented but not vendor-supported.
Tool Selection Boundaries
OpenTelemetry Collector: Wrong for teams needing turnkey mainframe observability without integration engineering. The collector is a framework requiring configuration, not a product with guaranteed mainframe interoperability.
IBM CICS native OTel: Wrong for CICS TS versions prior to OTel support introduction, and for pure batch (non-CICS) COBOL workloads. The vendor documentation frames this as CICS-specific.
Jaeger or Zipkin direct: Both tools now sit downstream of OpenTelemetry per third-party reviews. Direct instrumentation bypassing OTel is deprecated; these are backends, not propagation layers.
Sentry: Listed in vendor reference context but not addressed in the search material for mainframe tracing scenarios. No sourced figures available for Sentry’s mainframe capabilities.
Visit Sentry’s official documentation
Verification Checklist
Before declaring the integration operational:
- [ ] Collector 0.154.0+ configured with working OTLP exporter
- [ ] Microservice emits valid W3C traceparent (verify with
traceparentheader inspection) - [ ] CICS region shows OTel spans in collector logs, or batch job traceparent reads correctly from JCL
- [ ] Trace ID persists across the microservice-to-mainframe boundary in your backend
- [ ] Span timestamps reflect actual wall-clock time (mainframe and microservice clocks synchronized)

Version Anchors and Documentation Drift
All configuration in this article follows:
- OpenTelemetry semantic conventions v1.44.0
- OpenTelemetry Collector and Collector Contrib v0.162.0
- OpenTelemetry Python SDK 1.45.0 (for microservice reference)
- IBM CICS Transaction Server documentation as of search date
Where vendor documentation presents configuration-only CICS OTel enablement, community implementations indicate potential need for web service pipeline adjustments. The executable path assumes documented behavior but flags this divergence for verification.

