はじめに
2025年9月に出荷開始されたCICS Transaction Server for z/OS V6.3では新機能としてOpenTelemetryのサポートが追加されています。当記事ではこのOpenTelemetryサポートでどのようにCICSの処理が観測できるかを検証します。
OpenTelemetry
OpenTelemetryはアプリケーションやシステムのパフォーマンスを監視・観測する分散トレーシングのためのベンダー非依存のオープンソースのオブザーバビリティ―・フレームワークです。ログ、メトリクス、トレースなどのテレメトリー・データを生成・伝播・収集するための仕組みを定義し、様々なプラットフォームやソフトウェア、アプリケーション言語でAPIやSDKを提供し、システムを統合的に観測することを実現します。観測された情報は、JaegerやPrometeusなどのオープンソース・ツールや商用ツールなど90以上のオブザーバビリティ―製品で可視化可能です。
以下はOpenTelemetryによる情報収集の概要図です。
各システムの個々の処理の詳細情報はOTelスパンとして生成され、後続のコンポーネントにOTelスパンのコンテキストを伝播していきます。各コンポーネントのOTelスパンはOpenTelemetryコレクターに送られ、バックエンドUIで結合し可視化されます。
これにより、以下のようにどのコンポーネントでどれくらい処理時間が要しているのか把握することができ、分散システム上の問題発生や遅延を早期に検知し、迅速な問題判別・問題解決を実現します。
詳細は以下のサイトをご参照下さい。
https://opentelemetry.io
z/OSでのOpenTelemetryサポート
z/OSでのOpenTelemetryサポートはz/OS V3.1,V3.2のAPAR OA66345(2025年9月出荷)により提供されます。z/OS Data Gathererでz/OS OpenTelemetry Emitterというコンポーネントが提供されており、CICS/MQ/Db2/IMSなどz/OSミドルウェアで生成されるOTelスパンをIn-memory SMF経由で収集し、OpenTelemetry対応のコレクターやツールに送信します。
以下は各ミドルウェアのOpenTelemetryサポート・レベルです。
| MW | サポートレベル |
|---|---|
| CICS TS for z/OS | V6.3 |
| MQ for z/OS | V9.4.3 |
| IMS | V15.5/V15.6 + APAR PH65117/PH62728 |
| Db2 for z/OS | V13.1 + APAR PH67971/PH68073 |
| CICS TG for z/OS | V10.1 + APAR PH66340 |
| z/OS Connect | V3.0.96 (OpenAPI3ランタイムのみ) |
z/OSミドルウェアはOpenTelemetry出力用にそれぞれSMFタイプ番号がアサインされています。よって各SMFタイプについてIn-memory SMFのリソースを定義/準備しておく必要があります。
| MW | SMFタイプ |
|---|---|
| CICS | 1159 |
| MQ | 1158 |
| IMS | 1160 |
| Db2 | 1161 |
なお、CTGとz/OS ConnectおよびCICS LibertyはJavaベースのランタイムとしてSMF経由ではなく直接OpenTelemetryのコレクターにOTelスパンを送信します。
参考:
https://www.ibm.com/support/pages/apar/OA66345
https://community.ibm.com/community/user/blogs/sneha-kanaujia1/2025/09/30/zos-32-ga-with-zos-dg-otel-emitter
z/OS OpenTelemetry Emitterのセットアップ
z/OS OpenTelemetry Emitterのセットアップは、In-memory SMFの設定、RACF定義、および、z/OS OpenTelemetry Emitterアドレス空間の作成の3つになります。
1. In-memory SMFの設定
In-memory SMFはSMFログストリーム・レコーディングを使用するため、SMFPRMxxでRECORDING(LOGSTREAM)の設定が必要となります。DSNAMEで指定するMAN1/MAN2/MAN3などのSMFデータセットを同時に使用することはできませんので注意が必要です。In-memoryリソースはINMEMパラメーターで指定します。以下はCICSのSMF Type 1159のIn-memoryリソースを設定しているSMFPRMxxの例です。
RECORDING(LOGSTREAM)
LSNAME(IFASMF.&SYSNAME..PERF.DATA,TYPE(16,50,70:79,99,113))
LSNAME(IFASMF.&SYSNAME..CICS.DATA,TYPE(110))
DEFAULTLSNAME(IFASMF.&SYSNAME..DFLT.DATA)
INMEM(IFASMF.OTEL.T1159,RESSIZMAX(2G),TYPE(1159))
CICSのSMF Type 110をログストリーム"IFASMF.sysname.CICS.DATA"に、OpenTelemetryのSMF Type 1159を"IFASMF.OTEL.T1159"というIn-memoryリソースとして定義している例です。
In-memory SMFは基本的にメモリー上で保持されるリアルタイムアクセスが可能なリソースです。メモリー上の保持となりますので、揮発性です。もしディスクなどにもデータ保管したい場合は、該当のSMFタイプ番号についてログストリームとIn-memoryリソースの両方を定義してください。
2. RACF定義
ここではSMF In-memoryリソースをアクセスするためのRACFのFACILITYクラスで設定を行います。In-memoryリソースが"IFASMF.OTEL.xxxx"の場合、プロファイル名は"IFA.IFASMF.OTEL.xxxx"のように"IFA."で始まる必要があります。(下記"userID"はz/OS OpenTelemetry Emitterのアドレス空間のユーザーIDです)
RDEFINE FACILITY IFA.IFASMF.OTEL.* UACC(NONE)
ADDGROUP groupID
PERMIT IFA.IFASMF.OTEL.* CLASS(FACILITY) ID(groupID) ACCESS(READ)
ADDUSER userID DFLTGRP(groupID) NOPASSWORD
SETROPTS RACLIST(FACILITY) REFRESH
3. z/OS OpenTelemetry Emitterアドレス空間のセットアップ
z/OS OpenTelemetry Emitterアドレス空間のセットアップ情報は/usr/lpp/grb/opentelemetry_emitter/dt/READMEのファイルに記載されています。
起動JCLのサンプルが同じディレクトリー内の/usr/lpp/grb/opentelemetry_emitter/dt/GRBZOESSというファイルで提供されていますので、これを環境に応じてカスタマイズします。
以下はJCLサンプルです。(提供サンプルにある詳細な説明コメント行は削除してあります)
//GRBZOESS JOB (OTEL),MSGLEVEL=(1,1),NOTIFY=&SYSUID
// EXPORT SYMLIST=*
//* JZOS Load Module version
// SET VERSION='21'
//* Java path (without "/bin" at end)
// SET JAVADIR='/usr/lpp/java/J21.0_64'
//* ZOES Java Application JAR path (without "/" at end)
// SET APPHOME='/usr/lpp/grb/opentelemetry_emitter/dt'
//* Application .jar file name
// SET JARFILE='zos-otel-emitter-dt.jar'
//* In-mem SMF resource names list separated by comma
// SET $INMRESL='IFASMF.OTEL.T1159'
//* In-mem SMF records read flag
// SET $SMFRDFL='0'
//* Open Telemetry OTLP endpoint
// SET $OTLENDP='http://xxxx.xxxx.xxxx.xxxx:4317'
//* Open Telemetry OTLP protocol
// SET $OTLPRT='grpc'
//* Region Size for Started task
// SET REGSIZE='0M'
//*
//* Optional parameter symbols
//*
//* Open Telemetry export config
// SET $OTLEXPC='true'
//*
//* TLS Configuration symbols
// SET $TLSENBL='false'
// SET $MTLS='false'
// SET $TLSCERT=''
// SET $TLSCLKY=''
// SET $TLSCLCR=''
//*
// SET $SMFRDBS=''
//*
//* SET $SMFDUMP='false'
// SET $SMFDUMP='true'
//*
// SET $SHEAPSZ='1024M'
// SET $MHEAPSZ='1024M'
//JAVAJVM EXEC PGM=JVMLDM&VERSION,REGION=®SIZE,
// PARM='+D'
//* STEPLIB DD DSN=&DSNNAME,DISP=SHR
//SYSPRINT DD SYSOUT=* '< System stdout
//SYSOUT DD SYSOUT=* '< System stderr
//STDOUT DD SYSOUT=* '< Java System.out
//STDERR DD SYSOUT=* '< Java System.err
//CEEDUMP DD SYSOUT=*
//ABNLIGNR DD DUMMY
//MAINARGS DD *,SYMBOLS=JCLONLY
-jar &APPHOME/&JARFILE
/*
//STDENV DD *,SYMBOLS=JCLONLY,LRECL=150
. /etc/profile
export JAVA_HOME=&JAVADIR
export APP_HOME=&APPHOME
export PATH=/bin:"${JAVA_HOME}"/bin
LIBPATH=/lib:/usr/lib:"${JAVA_HOME}"/bin
LIBPATH="$LIBPATH":"${JAVA_HOME}"/lib
LIBPATH="$LIBPATH":"${JAVA_HOME}"/lib/j9vm
export LIBPATH="$LIBPATH":
# Customize your CLASSPATH here
CLASSPATH=$APP_HOME:"${JAVA_HOME}"/lib
# Add Application required jars to end of CLASSPATH
for i in "${APP_HOME}"/*.jar; do
CLASSPATH="$CLASSPATH":"$i"
done
export CLASSPATH="$CLASSPATH":
# Configure JVM options
IJO=""
IJO="$IJO"
IJO="$IJO -verbose:gc"
IJO="$IJO -Xms&$SHEAPSZ -Xmx&$MHEAPSZ"
IJO="$IJO -Dgrb.otel.dt.read.flag=&$SMFRDFL"
IJO="$IJO -Dgrb.otel.dt.endpoint=&$OTLENDP"
IJO="$IJO -Dgrb.otel.dt.protocol=&$OTLPRT"
# In-memory smf resource names list separated by comma
IJO="$IJO -Dgrb.otel.dt.resource.names=&$INMRESL"
# TLS support options
IJO="$IJO -Dgrb.otel.dt.tls.enabled=&$TLSENBL"
IJO="$IJO -Dgrb.otel.dt.mtls.enabled=&$MTLS"
#IJO="$IJO -Dgrb.otel.dt.tls.trusted.certs=&$TLSCERT"
#IJO="$IJO -Dgrb.otel.dt.tls.client.key=&$TLSCLKY"
#IJO="$IJO -Dgrb.otel.dt.tls.client.cert=&$TLSCLCR"
# Optional parameter options
IJO="$IJO -Dgrb.otel.dt.exporter=&$OTLEXPC"
IJO="$IJO -Dgrb.otel.dt.resource.buffer.size=&$SMFRDBS"
# Uncomment the following when required to dump SMF record to console
IJO="$IJO -Dgrb.otel.dt.data.dump=&$SMFDUMP"
# Uncomment the following line when running with Java 21
IJO="$IJO -Dfile.encoding=IBM-1047"
export IBM_JAVA_OPTIONS="$IJO "
/*
GRBZOESSのJCLをサブミットします。起動するとジョブログに以下のようなメッセージが出力されます。(SMFのIn-memoryリソースに接続できないと起動に失敗します)
0JVMJZBL1012I Java Virtual Machine created. Version information follows:
java version "21.0.6"
IBM Semeru Runtime Certified Edition for z/OS (build 21.0.6+7)
IBM J9 VM (build z/OS-Release-21.0.6.0-b01, JRE 21 z/OS s390x-64-Bit Compressed References 20250130_22 (JIT enabled, AOT enabled)
OpenJ9 - 518e03ffb72
OMR - 004424d5d94
IBM - 4e0e2df
JCL - deb8eabc068 based on jdk-21.0.6+7)
JVMJZBL1027I Using output encoding: IBM-1047
JVMJZBL1016I MVS commands are ENABLED
JVMJZBL1023N Invoking org.springframework.boot.loader.launch.JarLauncher.main()...
JVMJZBL1024N org.springframework.boot.loader.launch.JarLauncher.main() completed.
JVMJZBL1014I Waiting for non-daemon Java threads to finish before exiting...
2025-10-30 20:44:15.102/GMT+10:00 | otel-tracer | [INFO ] | [main] service-launcher - 'Starting OtelLauncher'
2025-10-30 20:44:15.105/GMT+10:00 | otel-tracer | [INFO ] | [main] service-launcher - 'Module version '1.4.0''
2025-10-30 20:44:15.105/GMT+10:00 | otel-tracer | [INFO ] | [main] service-launcher - 'Build from '2025-08-26T09:17:50Z''
2025-10-30 20:44:15.109/GMT+10:00 | otel-tracer | [INFO ] | [main] bridge-connector - 'OTelBridgeImpl instance created'
2025-10-30 20:44:15.124/GMT+10:00 | otel-tracer | [WARN ] | [main] config-validation - 'TLS is disabled, emitter will publish on un
secure connection!'
2025-10-30 20:44:15.124/GMT+10:00 | otel-tracer | [WARN ] | [main] config-validation - 'Mutual TLS is disabled!'
2025-10-30 20:44:15.131/GMT+10:00 | otel-tracer | [WARN ] | [main] system-info-collector - 'Property grb.otel.dt.spans.host.id not
set. Will not be filled in produced spans'
2025-10-30 20:44:15.131/GMT+10:00 | otel-tracer | [WARN ] | [main] system-info-collector - 'Property grb.otel.dt.spans.zos.sysplex
not set. Will not be filled in produced spans'
2025-10-30 20:44:15.131/GMT+10:00 | otel-tracer | [WARN ] | [main] system-info-collector - 'Property grb.otel.dt.spans.zos.smf.id n
ot set. Will not be filled in produced spans'
2025-10-30 20:44:15.131/GMT+10:00 | otel-tracer | [WARN ] | [main] system-info-collector - 'Property grb.otel.dt.spans.mainframe.lp
ar.name not set. Will not be filled in produced spans'
2025-10-30 20:44:15.131/GMT+10:00 | otel-tracer | [INFO ] | [main] service-launcher - 'The following attributes will be added to al
l spans:'
2025-10-30 20:44:15.132/GMT+10:00 | otel-tracer | [INFO ] | [main] service-launcher - ' 'host.name': 'aaaa.bbbb.cccc.dddd''
2025-10-30 20:44:15.132/GMT+10:00 | otel-tracer | [INFO ] | [main] service-launcher - ' 'host.arch': 's390x''
2025-10-30 20:44:15.132/GMT+10:00 | otel-tracer | [INFO ] | [main] service-launcher - ' 'os.type': 'z_os''
2025-10-30 20:44:15.132/GMT+10:00 | otel-tracer | [INFO ] | [main] service-launcher - ' 'os.name': 'z/OS''
2025-10-30 20:44:15.132/GMT+10:00 | otel-tracer | [INFO ] | [main] service-launcher - ' 'os.description': 'IBM z/OS 3.1''
2025-10-30 20:44:15.132/GMT+10:00 | otel-tracer | [INFO ] | [main] service-launcher - ' 'os.version': '03.01.00''
2025-10-30 20:44:15.132/GMT+10:00 | otel-tracer | [INFO ] | [main] service-launcher - 'z/OS OTel Emitter Service successfully conne
cted to inMemory resource IFASMF.OTEL.T1159'
CICSでのOpenTelemetryサポート
以下はCICSでのOpenTelemetryサポートの概要図です。
CICSのOpenTelemetryサポートではCICSのトランザクションがOpenTelemetryを使用した分散トレーシングへの参画を可能とします。CICSにOTelのコンテキストが付加されたリクエストが到達した場合に、そこから起動されるトランザクションでOTelスパンの引き継ぎおよび伝播が可能です。CICSでOTelスパンの伝播をサポートするプロトコルは以下のようになっています。
CICSでOpenTelemtryサポートを有効にするにはV6.3で追加された新しいSITパラメーターOTELTRACEを指定します。デフォルトはNOです。
OTELTRACE=YES
CICSのトランザクション定義では新たにOTELPROPとOTELEMITというパラメーターが追加されており、どのようにOTelを有効化するかこの2つのパラメーターの組み合わせで指定します。
| パラメーター | 説明 |
|---|---|
| OTELPROP | OTelスパンの後続に伝播するか - NOPROP: OTelスパンを伝播しない - PROPONLY: (デフォルト) OTelスパンを伝播する |
| OTELEMIT | OTelスパンをSMFに出力するか - NOEMIT: SMFに出力しない - TASKEND: (デフォルト) タスク終了時にSMFに出力する |
これらのパラメーターの組み合わせでOTelスパンの扱いは以下のようになります。
| OTELPROP | OTELEMIT | OTelトレースの伝播 | OTelスパンのSMF出力 |
|---|---|---|---|
| NOPROP | NOEMIT | 伝播しない | 出力しない |
| NOPROP | TASKEND | 伝播しない | 出力しない |
| PROPONLY | NOEMIT | 伝播する | 出力しない |
| PROPONLY | TASKEND | 伝播する | 出力する |
デフォルトはOTELPROP(PROPONLY)/OTELEMIT(TASKEND)なので、SITパラメーターでOTELTRACE=YESが指定されていてリクエストにOTelコンテキストがあればそれを自動的に伝播・SMF出力するということになります。リクエストにOTelのコンテキストがなければOpenTelemetry関連の処理は行われませんので、CICSにリクエストを投入してくるクライアント側でOpenTelemetryが有効にしているかどうかが重要です。
OpenTelemetryでのCICSのトレーシング例
以下の構成にてOpenTelemetryのトレースを確認します。
フロントエンドのSpring Bootアプリケーション側は自動計装(automatic instrumentation)による実装でアプリケーションにコードを追加することなくOpenTelemetryの環境変数とライブラリーの組み込みだけでトレーシングできるようになります。Spring BootアプリケーションからはAPI呼び出しでz/OS Connectを経由してCICSのアプリケーションを呼び出します。CICSはフロントのAOR(Application Owning Region)からFunction ShippingでバックのFOR(File Owning Region)にあるVSAMファイルをアクセスしています。
Spring Bootアプリケーション側の設定
自動計装で実施するため、以下の環境変数を設定します。
JAVA_TOOL_OPTIONS="-javaagent:C:\Test\OTel\opentelemetry-javaagent.jar"
OTEL_EXPORTER_OTLP_ENDPOINT=http://xxxx.xxxx.xxxx.xxxx:4317
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
OTEL_LOGS_EXPORTER=otlp
OTEL_METRICS_EXPORTER=otlp
OTEL_METRIC_EXPORT_INTERVAL=15000
OTEL_TRACES_EXPORTER=otlp
あとはアプリケーションを実行するだけです。
z/OS Connectでの設定
z/OS ConnectもV3.0.96からOpenAPI3のランタイムでOpenTelemetryをサポートしています。z/OS ConnectでのOpenTelemetryのセットアップは以下の通りです。
まずserver.xmlにOpenTelemtryのフィーチャーを追加します。
<featureManager>
<feature>zosconnect:zosConnect-3.0</feature>
<feature>mpTelemetry-2.0</feature>
</featureManager>
次にbootstrap.propertiesにOpenTelemetry関連のプロパティーを設定します。これはJavaオプションや環境変数として設定することも可能です。
# OpenTelemetry settings
otel.sdk.disabled=false
otel.service.name=zc33ci01
otel.traces.exporter=otlp
otel.exporter.otlp.endpoint=http://xxxx.xxxx.xxxx.xxxx:4317
otel.logs.exporter=none
otel.metrics.exporter=none
# OpenTelemetry recommended settings
otel.java.disabled.resource.providers=io.opentelemetry.instrumentation.resources.ProcessResourceProvider
otel.bsp.max.queue.size=10000
otel.bsp.max.export.batch.size=2048
API単位でOpenTemetryの有無を設定した場合、サーバー全体でのotel.sdk.disabledは設定せず、server.xmlでWebアプリケーションごとにで設定します。
<webApplication id="CICS Catalog Manager" location="${server.config.dir}/apps/api.war" name="sampleCicsApi">
<appProperties>
<property name="otel.sdk.disabled" value="false" />
</appProperties>
</webApplication>
あとはz/OS Connectを再起動します。(環境変数やbootstrap.propertiesの変更の反映は再起動が必要です。)
参考:https://www.ibm.com/docs/en/zos-connect/3.0.0?topic=30-configuring-opentelemetry
CICSでの設定
SITパラメーターでOTELTRACE=YESを設定します。
z/OS ConnectからはIPIC(IP interconnectivity)接続でCICS(AOR)が呼ばれ、デフォルトではCSMIトランザクションが起動されます。CSMIトランザクションのトランザクション定義はデフォルトでOTELPROP(PROPONLY)とOTELEMIT(TASKEND)が設定されているので、他の設定は不要です。AORからFORへのFunction ShippingはMRO接続経由で行われ、FOR内でもCSMIトランザクションのもとでVSAMファイルアクセスが実行されます。
アプリケーション実行時のトレース
今回はOpenTelemetryコレクターとバックエンドUIとしてJaegerを使っています。
参考:https://www.jaegertracing.io/
ブラウザーからHTTPリクエストを1回実行すると一連のフローが流れ、Jaeger UIにはエントリーが表示されます。(画面上のjava-simple-apiの部分)

該当エントリーではOTelスパンが8つ、Spring Boot、z/OS Connect、CICS-AOR、CICS-FORのそれぞれのコンポーネントが存在していることがわかります。全体の応答時間も2.38秒と表示されています。
該当エントリーを選ぶと詳細が表示されます。
こちらの画面でどのコンポーネントの処理がどの程度の時間を要しているかわかります。
全体的には一番最初のjava-simple-api GET /apicall (ブラウザーからのリクエスト到達)から次のjava-simple-api GET (z/OS ConnectへのAPI呼び出し)まで1秒以上かかっています。これはSpring Bootアプリケーションの初回実行なので各種クラスのロードなどで時間を要しているものと推測できます。
z/OS Connect(zc33ci01)内はスパンが4つに分かれており、GET /items、Request mapping、invoke CICS、Response mappingがあり、z/OS Connect内の各処理で要している時間がわかるようになっています。(リクエストのJSONをバイナリー形式に変換するRequest mappingがレスポンスを変換するReponse mappingのあとに表示されていたり配置がFOR処理の最中に位置づけられていますが、Jaeger UI上でスパンが並ぶ順番や配置は、サーバー間のクロックのズレや調整処理(clock-skew-adjustment)などがあると必ずしも正しい位置では表示されないようなので注意が必要です。当環境ではSpring Bootのサーバーとz/OSのクロックが十数秒の違いがあったためclock-skew-adjustmentによる調整を有効にしています。)
CICSの処理はAOR内のCT63S1A1 CICS transaction CSMIとFOR内のCT63S1A2 CICS transaction CSMIが表示されています。どちらもCSMIというトランザクションが動いていることを示しています。
各行はクリックするとスパンの詳細情報が表示されます。
さらにTagsやProcessを展開してスパンの属性の全体を確認することができます。以下はz/OS ConnectとCICSのOTelスパンに含まれている属性です。
・z/OS ConnectのOTelスパン詳細 (Invoke CICSの処理の場合)

CICSの場合、トランザクションがアベンドした場合はさらにアベンド・コードも含まれてきます。
参考までに、以下のエントリーは2回目の実行時のトレースです。初回とは異なり、全体の応答時間は120msです。最初のjava-simple-api GET /apicallの処理時間が大きく短縮されていることがわかります。z/OS ConnectやCICSの処理時間も軒並み短くなっています。z/OS ConnectもJavaベースの処理なので初回ロードなどの影響、CICS内処理は初回はVSAMファイルのOpen処理が入るため、2回目は短縮したものと考えられます。
まとめ
当記事はCICSの最新リリース(V6.3)で追加されたOpenTelemetryのサポートで、最新のz/OS OpenTelemetry EmitterをセットアップしてJaeger UIで表示する手順をご紹介しました。オンプレやクラウドを含めたハイブリッドなシステムが増えていく中で、可観測性(Observability)のエリアで事実上の業界標準であるOpenTelemetryを使い、CICSのみならずIMS/MQ/Db2などz/OS上の処理も観測できることはメインフレーム運用のハードルをまた1つ下げるのに役立つと期待できます。








