Skip to content

Commit 6deb55c

Browse files
feat: Add NRDOT IBM MQ install recipe (#1386)
Co-authored-by: pranav-new-relic <pnandula@newrelic.com>
1 parent 51095dc commit 6deb55c

8 files changed

Lines changed: 913 additions & 0 deletions

File tree

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
# Visit our schema definition for additional information on this file format.
2+
# https://github.com/newrelic/open-install-library/blob/main/docs/recipe-spec/recipe-spec.md#schema-definition
3+
4+
name: nrdot-collector-ibm-mq
5+
displayName: NRDOT Collector - IBM MQ
6+
description: New Relic install recipe for IBM MQ monitoring via NRDOT Collector on Debian/Ubuntu.
7+
repository: https://github.com/newrelic/nrdot-collector-releases
8+
9+
installTargets:
10+
- type: host
11+
os: linux
12+
platformFamily: debian
13+
- type: host
14+
os: linux
15+
platform: ubuntu
16+
17+
keywords:
18+
- IBM MQ
19+
- IBMMQ
20+
- NRDOT
21+
- OpenTelemetry
22+
- OTel
23+
- Messaging
24+
- Queue
25+
- Linux
26+
- Debian
27+
- Ubuntu
28+
29+
processMatch: []
30+
31+
preInstall:
32+
discoveryMode:
33+
- targeted
34+
35+
inputVars:
36+
- name: NR_CLI_IBMMQ_EXPORTER_ENDPOINT
37+
prompt: "IBM MQ Prometheus exporter address (mq-metric-samples, e.g. localhost:9157): "
38+
default: "localhost:9157"
39+
- name: NR_CLI_IBMMQ_CLUSTER_NAME
40+
prompt: "IBM MQ cluster name (optional, press Enter to skip): "
41+
default: ""
42+
43+
validationNrql: "SELECT count(*) FROM Metric WHERE metricName LIKE 'ibmmq_%' AND instrumentation.provider = 'opentelemetry' SINCE 10 minutes ago"
44+
45+
install:
46+
version: "3"
47+
silent: true
48+
49+
vars:
50+
IS_SYSTEMCTL:
51+
sh: command -v systemctl | wc -l
52+
NRDOT_ARCH:
53+
sh: if [ "$(uname -m)" = "aarch64" ]; then echo "arm64"; else echo "amd64"; fi
54+
COLLECTOR_DISTRO: "nrdot-collector"
55+
CONFIG_DIR: "/etc/nrdot-collector"
56+
57+
tasks:
58+
default:
59+
cmds:
60+
- task: write_recipe_metadata
61+
- task: assert_pre_req
62+
- task: install_nrdot
63+
- task: create_collector_config
64+
- task: configure_service
65+
- task: restart_nrdot
66+
- task: assert_nrdot_status_ok
67+
68+
write_recipe_metadata:
69+
cmds:
70+
- |
71+
echo '{"Metadata":{"CapturedCliOutput":"true"}}' | tee {{.NR_CLI_OUTPUT}} > /dev/null
72+
73+
assert_pre_req:
74+
cmds:
75+
- |
76+
if [ "$(id -u)" != "0" ]; then
77+
echo "This newrelic install must be run under sudo or root" >&2
78+
exit 3
79+
fi
80+
- |
81+
if ! command -v curl > /dev/null 2>&1; then
82+
echo "curl is required to run the newrelic install. Please install curl and re-run the installation." >&2
83+
exit 16
84+
fi
85+
- |
86+
if [ "{{.IS_SYSTEMCTL}}" -eq 0 ]; then
87+
echo "systemd is required for the nrdot-collector service configuration." >&2
88+
exit 131
89+
fi
90+
- |
91+
# Config-only recipe: verify the existing mq_prometheus exporter is serving ibmmq_*.
92+
ENDPOINT="{{.NR_CLI_IBMMQ_EXPORTER_ENDPOINT}}"
93+
if ! curl -sf "http://${ENDPOINT}/metrics" 2>/dev/null | grep -q "^ibmmq_"; then
94+
echo "" >&2
95+
echo "Could not read IBM MQ metrics from the exporter at http://${ENDPOINT}/metrics" >&2
96+
echo "Make sure the mq-metric-samples (mq_prometheus) exporter is running and serving" >&2
97+
echo "ibmmq_* metrics, then re-run. Setup: https://github.com/ibm-messaging/mq-metric-samples" >&2
98+
exit 132
99+
fi
100+
101+
install_nrdot:
102+
cmds:
103+
- |
104+
# Resolve the latest release into a variable and fail fast if it is empty.
105+
# (A pipeline's trailing `|| fallback` only guards the last command, so an
106+
# empty API response would otherwise yield an empty version and a broken
107+
# download URL that fails much later at dpkg with a misleading error.)
108+
NRDOT_VERSION=$(curl -sf "https://api.github.com/repos/newrelic/nrdot-collector-releases/releases/latest" | grep '"tag_name"' | head -1 | cut -d '"' -f 4 | sed 's/^v//')
109+
if [ -z "$NRDOT_VERSION" ]; then
110+
echo "Could not determine the latest nrdot-collector release from GitHub (network issue or API rate limit). Please re-run the installation." >&2
111+
exit 1
112+
fi
113+
# Idempotent: skip the download if this version is already installed.
114+
if dpkg -l | grep -q "^ii.*{{.COLLECTOR_DISTRO}} "; then
115+
INSTALLED_VERSION=$(dpkg -l {{.COLLECTOR_DISTRO}} | awk '/^ii/{print $3}' | sed 's/^[0-9]*://')
116+
if [ "$INSTALLED_VERSION" = "$NRDOT_VERSION" ]; then
117+
echo "{{.COLLECTOR_DISTRO}} $NRDOT_VERSION is already installed. Skipping download."
118+
exit 0
119+
fi
120+
fi
121+
echo "Installing NRDOT Collector v$NRDOT_VERSION..."
122+
NRDOT_DEB="/tmp/{{.COLLECTOR_DISTRO}}_${NRDOT_VERSION}_linux_{{.NRDOT_ARCH}}.deb"
123+
curl -fL --output "$NRDOT_DEB" \
124+
"https://github.com/newrelic/nrdot-collector-releases/releases/download/${NRDOT_VERSION}/{{.COLLECTOR_DISTRO}}_${NRDOT_VERSION}_linux_{{.NRDOT_ARCH}}.deb"
125+
if [ $? -ne 0 ]; then
126+
echo "Failed to download the NRDOT Collector package (version ${NRDOT_VERSION}, arch {{.NRDOT_ARCH}})." >&2
127+
exit 1
128+
fi
129+
DEBIAN_FRONTEND=noninteractive dpkg -i "$NRDOT_DEB" > /dev/null
130+
if [ $? -ne 0 ]; then
131+
apt-get -o DPkg::Lock::Timeout=60 install -f -y > /dev/null
132+
if [ $? -ne 0 ]; then
133+
echo "Failed to install NRDOT Collector package." >&2
134+
exit 1
135+
fi
136+
fi
137+
rm -f "$NRDOT_DEB"
138+
139+
create_collector_config:
140+
cmds:
141+
- |
142+
COLLECTOR_CONFIG="{{.CONFIG_DIR}}/ibmmq-collector-config.yaml"
143+
ENV_FILE="{{.CONFIG_DIR}}/ibmmq-env.conf"
144+
mkdir -p "{{.CONFIG_DIR}}"
145+
146+
# Config uses ${env:...} expansion; values come from the env file below
147+
# (no in-place edits). target.name is derived from the detected host.id.
148+
cat > "$COLLECTOR_CONFIG" << 'EOF'
149+
extensions:
150+
health_check:
151+
endpoint: 0.0.0.0:13133
152+
receivers:
153+
prometheus/ibmmq:
154+
config:
155+
scrape_configs:
156+
- job_name: 'ibmmq'
157+
scrape_interval: 60s
158+
scrape_timeout: 15s
159+
static_configs:
160+
- targets: ['${env:IBMMQ_EXPORTER_ENDPOINT}']
161+
processors:
162+
resourcedetection:
163+
detectors: [env, ec2, gcp, azure, system]
164+
system:
165+
resource_attributes:
166+
host.id:
167+
enabled: true
168+
host.name:
169+
enabled: true
170+
filter/ibmmq-overhead:
171+
metrics:
172+
exclude:
173+
match_type: regexp
174+
metric_names:
175+
- "^go_.*"
176+
- "^process_.*"
177+
- "^promhttp_.*"
178+
- "^scrape_.*"
179+
filter/ibmmq-queues:
180+
metrics:
181+
datapoint:
182+
- 'attributes["queue"] != nil and IsMatch(attributes["queue"], "^SYSTEM[.](ADMIN[.]|MQSC[.]|DEFAULT[.]|AUTH[.]|CHANNEL[.]|CHLAUTH[.]|CICS[.]|SYNCPOINT[.]|INTERNAL[.]|PENDING[.]|PROTECTION[.]|BROKER[.]|AMQP[.]|DOTNET[.]|REST[.]|RETAINED[.]|SELECTION[.]|DURABLE[.]|HIERARCHY[.]|DDELAY[.])")'
183+
- 'attributes["queue"] != nil and IsMatch(attributes["queue"], "^SYSTEM[.]CLUSTER[.](COMMAND|HISTORY)[.]QUEUE$")'
184+
- 'attributes["queue"] != nil and IsMatch(attributes["queue"], "^AMQ[.]")'
185+
transform/ibmmq-cleanup:
186+
metric_statements:
187+
- context: resource
188+
statements:
189+
- set(attributes["target.name"], attributes["host.id"]) where attributes["host.id"] != nil
190+
- set(attributes["cluster.name"], "${env:IBMMQ_CLUSTER_NAME}") where "${env:IBMMQ_CLUSTER_NAME}" != ""
191+
- delete_key(attributes, "service.name")
192+
- delete_key(attributes, "url.scheme")
193+
- context: datapoint
194+
statements:
195+
- delete_key(attributes, "instance")
196+
- delete_key(attributes, "job")
197+
memory_limiter/ibmmq:
198+
check_interval: 1s
199+
limit_mib: 512
200+
spike_limit_mib: 256
201+
cumulativetodelta/ibmmq: {}
202+
batch/ibmmq:
203+
send_batch_size: 1000
204+
timeout: 200ms
205+
exporters:
206+
otlp/ibmmq:
207+
endpoint: ${env:NEW_RELIC_OTLP_ENDPOINT}
208+
headers:
209+
api-key: ${env:NEW_RELIC_LICENSE_KEY}
210+
compression: gzip
211+
service:
212+
extensions: [health_check]
213+
pipelines:
214+
metrics/ibmmq:
215+
receivers: [prometheus/ibmmq]
216+
processors: [memory_limiter/ibmmq, resourcedetection, filter/ibmmq-overhead, filter/ibmmq-queues, transform/ibmmq-cleanup, cumulativetodelta/ibmmq, batch/ibmmq]
217+
exporters: [otlp/ibmmq]
218+
EOF
219+
220+
if [ "{{.NEW_RELIC_REGION}}" = "EU" ]; then
221+
OTLP_ENDPOINT="https://otlp.eu01.nr-data.net:4317"
222+
elif [ "{{.NEW_RELIC_REGION}}" = "staging" ]; then
223+
OTLP_ENDPOINT="https://staging-otlp.nr-data.net:4317"
224+
elif [ "{{.NEW_RELIC_REGION}}" = "JP" ]; then
225+
OTLP_ENDPOINT="https://otlp.jp.nr-data.net:4317"
226+
else
227+
OTLP_ENDPOINT="https://otlp.nr-data.net:4317"
228+
fi
229+
230+
printf "IBMMQ_EXPORTER_ENDPOINT=%s\n" "{{.NR_CLI_IBMMQ_EXPORTER_ENDPOINT}}" > "$ENV_FILE"
231+
printf "IBMMQ_CLUSTER_NAME=%s\n" "{{.NR_CLI_IBMMQ_CLUSTER_NAME}}" >> "$ENV_FILE"
232+
printf "NEW_RELIC_OTLP_ENDPOINT=%s\n" "$OTLP_ENDPOINT" >> "$ENV_FILE"
233+
printf "NEW_RELIC_LICENSE_KEY=%s\n" "{{.NEW_RELIC_LICENSE_KEY}}" >> "$ENV_FILE"
234+
chmod 600 "$ENV_FILE"
235+
echo "Collector config written to $COLLECTOR_CONFIG"
236+
237+
configure_service:
238+
cmds:
239+
- |
240+
DROPIN_DIR="/etc/systemd/system/{{.COLLECTOR_DISTRO}}.service.d"
241+
mkdir -p "$DROPIN_DIR"
242+
NRDOT_BIN=$(command -v {{.COLLECTOR_DISTRO}} 2>/dev/null || echo "/usr/bin/{{.COLLECTOR_DISTRO}}")
243+
{
244+
printf '[Service]\n'
245+
printf 'EnvironmentFile={{.CONFIG_DIR}}/ibmmq-env.conf\n'
246+
printf 'ExecStart=\n'
247+
printf 'ExecStart=%s --config {{.CONFIG_DIR}}/ibmmq-collector-config.yaml\n' "$NRDOT_BIN"
248+
} > "$DROPIN_DIR/ibmmq-config.conf"
249+
echo "Systemd drop-in configured."
250+
251+
restart_nrdot:
252+
cmds:
253+
- |
254+
systemctl daemon-reload
255+
systemctl enable {{.COLLECTOR_DISTRO}}.service
256+
systemctl restart {{.COLLECTOR_DISTRO}}.service
257+
258+
assert_nrdot_status_ok:
259+
cmds:
260+
- |
261+
MAX_RETRIES=30
262+
TRIES=0
263+
echo "Waiting for NRDOT Collector to start..."
264+
while [ $TRIES -lt $MAX_RETRIES ]; do
265+
TRIES=$((TRIES + 1))
266+
if systemctl is-active --quiet {{.COLLECTOR_DISTRO}}.service && curl -sf http://localhost:13133 > /dev/null 2>&1; then
267+
echo "NRDOT Collector is running and healthy."
268+
exit 0
269+
fi
270+
sleep 2
271+
done
272+
echo "NRDOT Collector did not start in time." >&2
273+
journalctl -u {{.COLLECTOR_DISTRO}}.service --no-pager -n 50 >&2
274+
exit 31
275+
276+
postInstall:
277+
info: |2
278+
IBM MQ OTel Collector config: /etc/nrdot-collector/ibmmq-collector-config.yaml
279+
Environment file: /etc/nrdot-collector/ibmmq-env.conf
280+
Service status: systemctl status nrdot-collector
281+
View logs: journalctl -u nrdot-collector -f

0 commit comments

Comments
 (0)