Skip to content

[ibm-mq-metrics] Connection errors counter #2122

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions ibm-mq-metrics/docs/metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -799,3 +799,19 @@
| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
|---|---|---|---|---|---|
| `ibm.mq.queue.manager` | string | The name of the IBM queue manager | `MQ1` | `Required` | ![Development](https://img.shields.io/badge/-development-blue) |



## Metric `ibm.mq.connection.errors`

| Name | Instrument Type | Unit (UCUM) | Description | Stability |
| -------- | --------------- | ----------- | -------------- | --------- |
| `ibm.mq.connection.errors` | Counter | `{errors}` | Number of connection errors | ![Development](https://img.shields.io/badge/-development-blue) |


### `ibm.mq.connection.errors` Attributes

| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
|---|---|---|---|---|---|
| `error.code` | string | The reason code associated with an error | `2038`; `2543`; `2009` | `Required` | ![Development](https://img.shields.io/badge/-development-blue) |
| `ibm.mq.queue.manager` | string | The name of the IBM queue manager | `MQ1` | `Required` | ![Development](https://img.shields.io/badge/-development-blue) |
6 changes: 6 additions & 0 deletions ibm-mq-metrics/model/attributes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,9 @@ groups:
note: This is duplicated from otel semantic-conventions.
stability: development
examples: [ "Wordle", "JMSService" ]
- id: error.code
type: string
brief: >
The reason code associated with an error
stability: development
examples: [ "2038", "2543", "2009" ]
12 changes: 12 additions & 0 deletions ibm-mq-metrics/model/metrics.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -609,3 +609,15 @@ groups:
attributes:
- ref: ibm.mq.queue.manager
requirement_level: required
- id: ibm.mq.connection.errors
type: metric
metric_name: ibm.mq.connection.errors
stability: development
brief: "Number of connection errors"
instrument: counter
unit: "{errors}"
attributes:
- ref: ibm.mq.queue.manager
requirement_level: required
- ref: error.code
requirement_level: required
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@
import com.ibm.mq.headers.pcf.PCFException;
import com.ibm.mq.headers.pcf.PCFMessage;
import com.ibm.mq.headers.pcf.PCFMessageAgent;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.ibm.mq.config.QueueManager;
import io.opentelemetry.ibm.mq.opentelemetry.ConfigWrapper;
import io.opentelemetry.ibm.mq.opentelemetry.Main;
import io.opentelemetry.ibm.mq.util.WmqUtil;
import io.opentelemetry.sdk.metrics.data.LongPointData;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.metrics.data.SumData;
import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension;
import java.io.File;
import java.net.URISyntaxException;
Expand Down Expand Up @@ -281,4 +284,34 @@ void test_otlphttp() throws Exception {
// reads a value from the heartbeat gauge
assertThat(metricNames).contains("ibm.mq.heartbeat");
}

@Test
void test_bad_connection() throws Exception {
logger.info("\n\n\n\n\n\nRunning test: test_bad_connection");
String configFile = getConfigFile("conf/test-bad-config.yml");

ConfigWrapper config = ConfigWrapper.parse(configFile);
Meter meter = otelTesting.getOpenTelemetry().getMeter("opentelemetry.io/mq");
TestWMQMonitor monitor = new TestWMQMonitor(config, meter, service);
monitor.runTest();

List<MetricData> data = otelTesting.getMetrics();

assertThat(data).isNotEmpty();
assertThat(data).hasSize(2);

SumData<LongPointData> connectionErrors = null;
for (MetricData metricData : data) {
if ("ibm.mq.connection.errors".equals(metricData.getName())) {
connectionErrors = (SumData<LongPointData>) metricData.getData();
}
}

assertThat(connectionErrors).isNotNull();

LongPointData metricPoint = connectionErrors.getPoints().iterator().next();
String value = metricPoint.getAttributes().get(AttributeKey.stringKey("error.code"));

assertThat(value).isEqualTo("2538");
Comment on lines +312 to +315
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to verify the value as well?

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,302 @@
queueManagers:
- name: "QM1"
host: "localhost"
port: 1417

#The transport type for the queue manager connection, the default is "Bindings" for a binding type connection
#For bindings type, connection WMQ extension (i.e machine agent) need to be on the same machine on which WebbsphereMQ server is running
#For client type, connection change it to "Client".
transportType: "Client"

#Channel name of the queue manager, channel should be server-conn type.
#This field is not required in case of transportType: Bindings
channelName: DEV.ADMIN.SVRCONN

#for user access level, please check "Access Permissions" section on the extensions page
#comment out the username and password in case of transportType: Bindings.
username: "admin"
password: "passw0rd"

queueFilters:
#Can provide complete queue name or generic names. A generic name is a character string followed by an asterisk (*),
#for example ABC*, and it selects all objects having names that start with the selected character string.
#An asterisk on its own matches all possible names.
include: ["*"]
exclude:
#type value: STARTSWITH, EQUALS, ENDSWITH, CONTAINS
- type: "STARTSWITH"
#The name of the queue or queue name pattern as per queue filter, comma separated values
values: ["SYSTEM","AMQ"]


channelFilters:
#Can provide complete channel name or generic names. A generic name is a character string followed by an asterisk (*),
#for example ABC*, and it selects all objects having names that start with the selected character string.
#An asterisk on its own matches all possible names.
include: ["*"]
exclude:
#type value: STARTSWITH, EQUALS, ENDSWITH, CONTAINS
- type: "STARTSWITH"
#The name of the queue or queue name pattern as per queue filter, comma separated values
values: ["SYSTEM"]

listenerFilters:
#Can provide complete channel name or generic names. A generic name is a character string followed by an asterisk (*),
#for example ABC*, and it selects all objects having names that start with the selected character string.
#An asterisk on its own matches all possible names.
include: ["*"]
exclude:
#type value: STARTSWITH, EQUALS, ENDSWITH, CONTAINS
- type: "STARTSWITH"
#The name of the queue or queue name pattern as per queue filter, comma separated values
values: ["SYSTEM"]

topicFilters:
# For topics, IBM MQ uses the topic wildcard characters ('#' and '+') and does not treat a trailing asterisk as a wildcard
# https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_7.5.0/com.ibm.mq.pla.doc/q005020_.htm
include: ["#"]
exclude:
#type value: STARTSWITH, EQUALS, ENDSWITH, CONTAINS
- type: "STARTSWITH"
#The name of the queue or queue name pattern as per queue filter, comma separated values
values: ["SYSTEM","$SYS"]

mqMetrics:
# This Object will extract queue manager metrics
- metricsType: "queueMgrMetrics"
metrics:
include:
- Status:
alias: "Status"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACF_Q_MGR_STATUS"
aggregationType: "OBSERVATION"
timeRollUpType: "AVERAGE"
clusterRollUpType: "INDIVIDUAL"
- ConnectionCount:
alias: "ConnectionCount"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACF_CONNECTION_COUNT"

- ReusableLogSize:
alias: "Reusable Log Size"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACF_REUSABLE_LOG_SIZE"
ibmCommand: "MQCMD_INQUIRE_Q_MGR_STATUS"

- RestartLogSize:
alias: "Restart Log Size"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACF_RESTART_LOG_SIZE"
ibmCommand: "MQCMD_INQUIRE_Q_MGR_STATUS"

- ArchiveLogSize:
alias: "Archive Log Size"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACF_ARCHIVE_LOG_SIZE"
ibmCommand: "MQCMD_INQUIRE_Q_MGR_STATUS"

- StatisticsInterval:
alias: "Statistics Interval"
ibmConstant: "com.ibm.mq.constants.CMQC.MQIA_STATISTICS_INTERVAL"
ibmCommand: "MQCMD_INQUIRE_Q_MGR"

# This Object will extract queue metrics
- metricsType: "queueMetrics"
metrics:
include:
- MaxQueueDepth:
alias: "Max Queue Depth"
ibmConstant: "com.ibm.mq.constants.CMQC.MQIA_MAX_Q_DEPTH"
ibmCommand: "MQCMD_INQUIRE_Q"

- CurrentQueueDepth:
alias: "Current Queue Depth"
ibmConstant: "com.ibm.mq.constants.CMQC.MQIA_CURRENT_Q_DEPTH"
ibmCommand: "MQCMD_INQUIRE_Q"

- CurrentQueueFileSize:
alias: "Current queue file size"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACF_CUR_Q_FILE_SIZE"
ibmCommand: "MQCMD_INQUIRE_Q_STATUS"

- MaxQueueFileSize:
alias: "Current maximum queue file size"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACF_CUR_MAX_FILE_SIZE"
ibmCommand: "MQCMD_INQUIRE_Q_STATUS"

- OpenInputCount:
alias: "Open Input Count"
ibmConstant: "com.ibm.mq.constants.CMQC.MQIA_OPEN_INPUT_COUNT"
ibmCommand: "MQCMD_INQUIRE_Q"

- OpenOutputCount:
alias: "Open Output Count"
ibmConstant: "com.ibm.mq.constants.CMQC.MQIA_OPEN_OUTPUT_COUNT"
ibmCommand: "MQCMD_INQUIRE_Q"

- OldestMsgAge:
alias: "OldestMsgAge"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACF_OLDEST_MSG_AGE"
ibmCommand: "MQCMD_INQUIRE_Q_STATUS"
aggregationType: "OBSERVATION"
timeRollUpType: "CURRENT"
clusterRollUpType: "INDIVIDUAL"

- UncommittedMsgs:
alias: "UncommittedMsgs"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACF_UNCOMMITTED_MSGS"
ibmCommand: "MQCMD_INQUIRE_Q_STATUS"

- OnQTime:
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACF_Q_TIME_INDICATOR"
ibmCommand: "MQCMD_INQUIRE_Q_STATUS"
aggregationType: "OBSERVATION"
timeRollUpType: "CURRENT"
clusterRollUpType: "INDIVIDUAL"

- HighQDepth:
alias: "HighQDepth"
ibmConstant: "com.ibm.mq.constants.CMQC.MQIA_HIGH_Q_DEPTH"
ibmCommand: "MQCMD_RESET_Q_STATS"

- MsgDeqCount:
alias: "MsgDeqCount"
ibmConstant: "com.ibm.mq.constants.CMQC.MQIA_MSG_DEQ_COUNT"
ibmCommand: "MQCMD_RESET_Q_STATS"

- MsgEnqCount:
alias: "MsgEnqCount"
ibmConstant: "com.ibm.mq.constants.CMQC.MQIA_MSG_ENQ_COUNT"
ibmCommand: "MQCMD_RESET_Q_STATS"

- UncommittedMsgs:
alias: "Uncommitted Messages"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACF_UNCOMMITTED_MSGS"
ibmCommand: "MQCMD_INQUIRE_Q_STATUS"

- ServiceInterval:
alias: "Service Interval"
ibmConstant: "com.ibm.mq.constants.CMQC.MQIA_Q_SERVICE_INTERVAL"
ibmCommand: "MQCMD_INQUIRE_Q"

- ServiceIntervalEvent:
alias: "Service Interval Event"
ibmConstant: "com.ibm.mq.constants.CMQC.MQIA_Q_SERVICE_INTERVAL_EVENT"
ibmCommand: "MQCMD_INQUIRE_Q"

# This Object will extract channel metrics
- metricsType: "channelMetrics"
metrics:
include:
- Messages:
alias: "Messages"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACH_MSGS"
ibmCommand: "MQCMD_INQUIRE_CHANNEL_STATUS"

- Status:
alias: "Status"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACH_CHANNEL_STATUS" #http://www.ibm.com/support/knowledgecenter/SSFKSJ_7.5.0/com.ibm.mq.ref.dev.doc/q090880_.htm
aggregationType: "OBSERVATION"
timeRollUpType: "AVERAGE"
clusterRollUpType: "INDIVIDUAL"
ibmCommand: "MQCMD_INQUIRE_CHANNEL_STATUS"

- ByteSent:
alias: "Byte Sent"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACH_BYTES_SENT"
ibmCommand: "MQCMD_INQUIRE_CHANNEL_STATUS"

- ByteReceived:
alias: "Byte Received"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACH_BYTES_RECEIVED"
ibmCommand: "MQCMD_INQUIRE_CHANNEL_STATUS"

- BuffersSent:
alias: "Buffers Sent"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACH_BUFFERS_SENT"
ibmCommand: "MQCMD_INQUIRE_CHANNEL_STATUS"

- BuffersReceived:
alias: "Buffers Received"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACH_BUFFERS_RECEIVED"
ibmCommand: "MQCMD_INQUIRE_CHANNEL_STATUS"

- CurrentSharingConversations:
alias: "Current Sharing Conversations"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACH_CURRENT_SHARING_CONVS"

- MaxSharingConversations:
alias: "Max Sharing Conversations"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACH_MAX_SHARING_CONVS"

- MaxInstances:
alias: "Max Instances"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACH_MAX_INSTANCES"
ibmCommand: "MQCMD_INQUIRE_CHANNEL"

- MaxInstancesPerClient:
alias: "Max Instances per Client"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACH_MAX_INSTS_PER_CLIENT"
ibmCommand: "MQCMD_INQUIRE_CHANNEL"

- MsgRetryCount:
alias: "Message Retry Count"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACH_MR_COUNT"
ibmCommand: "MQCMD_INQUIRE_CHANNEL"

- MsgsReceived:
alias: "Message Received Count"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACH_MSGS_RECEIVED"
ibmCommand: "MQCMD_INQUIRE_CHANNEL"

- MsgsSent:
alias: "Message Sent"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACH_MSGS_SENT"
ibmCommand: "MQCMD_INQUIRE_CHANNEL"

- metricsType: "listenerMetrics"
metrics:
include:
- Status:
alias: "Status"
ibmConstant: "com.ibm.mq.constants.CMQCFC.MQIACH_LISTENER_STATUS"
aggregationType: "OBSERVATION"
timeRollUpType: "AVERAGE"
clusterRollUpType: "INDIVIDUAL"

# This Object will extract topic metrics
- metricsType: "topicMetrics"
metrics:
include:
- PublishCount:
alias: "Publish Count"
ibmConstant: "com.ibm.mq.constants.CMQC.MQIA_PUB_COUNT"
ibmCommand: "MQCMD_INQUIRE_TOPIC_STATUS"
- SubscriptionCount:
alias: "Subscription Count"
ibmConstant: "com.ibm.mq.constants.CMQC.MQIA_SUB_COUNT"
ibmCommand: "MQCMD_INQUIRE_TOPIC_STATUS"

# Sets up reading configuration events from the configuration queue.
- metricsType: "configurationMetrics"
metrics:
include:
- MaxHandles:
alias: "Max Handles"
ibmConstant: "com.ibm.mq.constants.CMQC.MQIA_MAX_HANDLES"

#Run it as a scheduled task instead of running every minute.
#If you want to run this every minute, comment this out
#taskSchedule:
# numberOfThreads: 1
# taskDelaySeconds: 300


sslConnection:
trustStorePath: ""
trustStorePassword: ""
trustStoreEncryptedPassword: ""

keyStorePath: ""
keyStorePassword: ""
keyStoreEncryptedPassword: ""

# Configure the OTLP exporter using system properties keys following the specification https://opentelemetry.io/docs/languages/java/configuration/
otlpExporter:
otel.exporter.otlp.endpoint: http://0.0.0.0:4318
Loading
Loading