diff --git a/ibm-mq-metrics/config.yml b/ibm-mq-metrics/config.yml index 69e99e6cf..6f2b50e46 100644 --- a/ibm-mq-metrics/config.yml +++ b/ibm-mq-metrics/config.yml @@ -186,6 +186,8 @@ metrics: enabled: true "ibm.mq.heartbeat": # Queue manager heartbeat enabled: true + "ibm.mq.queue_manager.uptime": # Queue manager uptime + enabled: true "ibm.mq.archive.log.size": # Queue manager archive log size enabled: true "ibm.mq.manager.max.active.channels": # Queue manager max active channels diff --git a/ibm-mq-metrics/model/metrics.yaml b/ibm-mq-metrics/model/metrics.yaml index cfdfca3f2..e9cdeaa9c 100644 --- a/ibm-mq-metrics/model/metrics.yaml +++ b/ibm-mq-metrics/model/metrics.yaml @@ -533,6 +533,16 @@ groups: attributes: - ref: ibm.mq.queue.manager requirement_level: required + - id: ibm.mq.queue_manager.uptime + type: metric + metric_name: ibm.mq.queue_manager.uptime + stability: development + brief: "Queue manager uptime" + instrument: counter + unit: "s" + attributes: + - ref: ibm.mq.queue.manager + requirement_level: required - id: ibm.mq.archive.log.size type: metric metric_name: ibm.mq.archive.log.size diff --git a/ibm-mq-metrics/src/main/java/io/opentelemetry/ibm/mq/metrics/Metrics.java b/ibm-mq-metrics/src/main/java/io/opentelemetry/ibm/mq/metrics/Metrics.java index b5c5f3c87..adfe58153 100644 --- a/ibm-mq-metrics/src/main/java/io/opentelemetry/ibm/mq/metrics/Metrics.java +++ b/ibm-mq-metrics/src/main/java/io/opentelemetry/ibm/mq/metrics/Metrics.java @@ -360,6 +360,14 @@ public static LongGauge createIbmMqHeartbeat(Meter meter) { .build(); } + public static LongCounter createIbmMqQueueManagerUptime(Meter meter) { + return meter + .counterBuilder("ibm.mq.queue_manager.uptime") + .setUnit("s") + .setDescription("Queue manager uptime") + .build(); + } + public static LongGauge createIbmMqArchiveLogSize(Meter meter) { return meter .gaugeBuilder("ibm.mq.archive.log.size") diff --git a/ibm-mq-metrics/src/main/java/io/opentelemetry/ibm/mq/metrics/MetricsConfig.java b/ibm-mq-metrics/src/main/java/io/opentelemetry/ibm/mq/metrics/MetricsConfig.java index 2b4c09958..f2bc14c85 100644 --- a/ibm-mq-metrics/src/main/java/io/opentelemetry/ibm/mq/metrics/MetricsConfig.java +++ b/ibm-mq-metrics/src/main/java/io/opentelemetry/ibm/mq/metrics/MetricsConfig.java @@ -171,6 +171,10 @@ public boolean isIbmMqHeartbeatEnabled() { return isEnabled("ibm.mq.heartbeat"); } + public boolean isIbmMqQueueManagerUptimeEnabled() { + return isEnabled("ibm.mq.queue_manager.uptime"); + } + public boolean isIbmMqArchiveLogSizeEnabled() { return isEnabled("ibm.mq.archive.log.size"); } diff --git a/ibm-mq-metrics/src/main/java/io/opentelemetry/ibm/mq/metricscollector/MessageBuddy.java b/ibm-mq-metrics/src/main/java/io/opentelemetry/ibm/mq/metricscollector/MessageBuddy.java index 688f9541d..248190965 100644 --- a/ibm-mq-metrics/src/main/java/io/opentelemetry/ibm/mq/metricscollector/MessageBuddy.java +++ b/ibm-mq-metrics/src/main/java/io/opentelemetry/ibm/mq/metricscollector/MessageBuddy.java @@ -11,6 +11,8 @@ import com.ibm.mq.headers.pcf.PCFException; import com.ibm.mq.headers.pcf.PCFMessage; import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; public final class MessageBuddy { @@ -72,4 +74,29 @@ public static long channelStartTime(PCFMessage message) throws PCFException { public static String jobName(PCFMessage message) throws PCFException { return message.getStringParameterValue(CMQCFC.MQCACH_MCA_JOB_NAME).trim(); } + + /** + * Calculate the queue manager uptime in seconds. + * + *
Fetches the queue manager start date and time from the PCF response, parses them, and
+ * calculates the difference from the current system time.
+ *
+ * @param message the PCF response message containing queue manager information
+ * @return uptime in seconds since the queue manager started
+ * @throws PCFException if the required attributes cannot be retrieved from the PCF message
+ */
+ public static long queueManagerUptime(PCFMessage message) throws PCFException {
+ String date = message.getStringParameterValue(CMQCFC.MQCACF_Q_MGR_START_DATE).trim();
+ String time = message.getStringParameterValue(CMQCFC.MQCACF_Q_MGR_START_TIME).trim();
+
+ // Parse the date (format: yyyy-MM-dd) and time (format: HH.mm.ss)
+ // The queue manager start timestamp does not include timezone information in this PCF response,
+ // so we normalize to UTC for a stable and predictable baseline across regions.
+ LocalDateTime qmgrStartLocal = LocalDateTime.parse(date + "T" + time.replaceAll("\\.", ":"));
+ Instant qmgrStartInstant = qmgrStartLocal.toInstant(ZoneOffset.UTC);
+ Instant now = Instant.now();
+
+ // Calculate uptime in seconds
+ return now.getEpochSecond() - qmgrStartInstant.getEpochSecond();
+ }
}
diff --git a/ibm-mq-metrics/src/main/java/io/opentelemetry/ibm/mq/metricscollector/QueueManagerMetricsCollector.java b/ibm-mq-metrics/src/main/java/io/opentelemetry/ibm/mq/metricscollector/QueueManagerMetricsCollector.java
index 2b3d57086..e79f6e14f 100644
--- a/ibm-mq-metrics/src/main/java/io/opentelemetry/ibm/mq/metricscollector/QueueManagerMetricsCollector.java
+++ b/ibm-mq-metrics/src/main/java/io/opentelemetry/ibm/mq/metricscollector/QueueManagerMetricsCollector.java
@@ -11,6 +11,7 @@
import com.ibm.mq.constants.CMQCFC;
import com.ibm.mq.headers.pcf.PCFMessage;
import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.LongGauge;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.ibm.mq.metrics.Metrics;
@@ -30,6 +31,7 @@ public final class QueueManagerMetricsCollector implements Consumer