Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
armstrmi committed Jan 11, 2022
1 parent a4a1c11 commit 8a97c48
Show file tree
Hide file tree
Showing 8 changed files with 374 additions and 4 deletions.
54 changes: 54 additions & 0 deletions jmx-metrics/docs/target-systems/activemq.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# ActiveMQ Metrics

The JMX Metric Gatherer provides built in Tomcat metric gathering capabilities.
These metrics are sourced from: https://activemq.apache.org/jmx

### Metrics

* Name: `activemq.consumer.count`
* Description: The number of consumers currently reading from the broker.
* Unit: `{consumers}`
* Labels: `destination`
* Instrument Type: LongUpDownCounterCallback


* Name: `activemq.producer.count`
* Description: The number of producers currently attached to the broker.
* Unit: `{producers}`
* Labels: `destination`
* Instrument Type: LongUpDownCounterCallback


* Name: `activemq.memory.usage`
* Description: The percentage of configured memory used.
* Unit: `%`
* Labels: `destination`
* Instrument Type: DoubleValueCallback


* Name: `tomcat.traffic`
* Description: The number of bytes transmitted and received.
* Unit: `by`
* Labels: `proto_handler`, `direction`
* Instrument Type: LongCounterCallback


* Name: `tomcat.threads`
* Description: The number of threads.
* Unit: `threads`
* Labels: `proto_handler`, `state`
* Instrument Type: LongValueCallback


* Name: `tomcat.max_time`
* Description: Maximum time to process a request.
* Unit: `ms`
* Labels: `proto_handler`
* Instrument Type: LongCounterCallback


* Name: `tomcat.request_count`
* Description: The total requests.
* Unit: `requests`
* Labels: `proto_handler`
* Instrument Type: LongCounterCallback
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ void beforeEach() {
@SafeVarargs
protected final void waitAndAssertMetrics(Consumer<Metric>... assertions) {
await()
.atMost(Duration.ofSeconds(30))
.atMost(Duration.ofMinutes(2))
.untilAsserted(
() -> {
List<Metric> metrics =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.contrib.jmxmetrics.target_systems;

import static org.assertj.core.api.Assertions.entry;

import io.opentelemetry.contrib.jmxmetrics.AbstractIntegrationTest;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.Network;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.images.builder.ImageFromDockerfile;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.utility.MountableFile;

class ActivemqIntegrationTest extends AbstractIntegrationTest {

ActivemqIntegrationTest() {
super(/* configFromStdin= */ false, "target-systems/activemq.properties");
}

@Container
GenericContainer<?> activemq =
new GenericContainer<>(
new ImageFromDockerfile()
.withDockerfileFromBuilder(
builder ->
builder
.from("rmohr/activemq:5.15.9-alpine")
.expose(10991)
.env(
"ACTIVEMQ_JMX_OPTS",
"-Djava.rmi.server.hostname=localhost -Dcom.sun.management.jmxremote.port=10991 -Dcom.sun.management.jmxremote.rmi.port=10991 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false")
.env("ACTIVEMQ_JMX", "10991")
// .env("ACTIVEMQ_OPTS","$ACTIVEMQ_JMX_OPTS
// -Dhawtio.authenticationEnabled=false -Dhawtio.realm=activemq
// -Dhawtio.role=admins
// -Dhawtio.rolePrincipalClasses=org.apache.activemq.jaas.GroupPrincipal")
//
// .env("ACTIVEMQ_SUNJMX_START","-Dcom.sun.management.jmxremote")
.build()))
.withCopyFileToContainer(
MountableFile.forClasspathResource("activemq/env", 0400), "/opt/activemq/bin/env")
.withNetwork(Network.SHARED)
.withEnv("LOCAL_JMX", "no")
.withNetworkAliases("activemq")
.withExposedPorts(10991)
.withStartupTimeout(Duration.ofMinutes(2))
.waitingFor(Wait.forListeningPort());

@Test
void endToEnd() {
waitAndAssertMetrics(
metric ->
assertGaugeWithAttributes(
metric,
"activemq.memory.usage",
"The percentage of configured memory used.",
"%",
attrs -> attrs.containsOnly(entry("destination", "client_test"))));
}
}
117 changes: 117 additions & 0 deletions jmx-metrics/src/integrationTest/resources/activemq/env
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/bin/sh
# ------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ------------------------------------------------------------------------
#
# Configuration file for running Apache Active MQ as standalone provider.
#
# This file overwrites the predefined settings of the sysv init-script.
# You can also use alternate location for default settings -
# invoke the init-script without a argument an review help section "Configuration of this script"
# /etc/default/activemq <activemq user home>/.activemqrc <activemq installation dir>/bin/env

# Active MQ installation dirs
# ACTIVEMQ_HOME="<Installationdir>/"
# ACTIVEMQ_BASE="$ACTIVEMQ_HOME"
# ACTIVEMQ_CONF="$ACTIVEMQ_BASE/conf"
# ACTIVEMQ_DATA="$ACTIVEMQ_BASE/data"
# ACTIVEMQ_TMP="$ACTIVEMQ_BASE/tmp"

# Set jvm memory configuration (minimal/maximum amount of memory)
ACTIVEMQ_OPTS_MEMORY="-Xms64M -Xmx256M"

if [ -z "$ACTIVEMQ_OPTS" ] ; then
ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS_MEMORY -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=$ACTIVEMQ_CONF/login.config"
fi

if [ -z "$ACTIVEMQ_OUT" ]; then
ACTIVEMQ_OUT="/dev/null"
fi

# Uncomment to enable audit logging
#ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS -Dorg.apache.activemq.audit=true"

# Set jvm jmx configuration
# This enables jmx access over a configured jmx-tcp-port.
# You have to configure the first four settings if you run a ibm jvm, caused by the
# fact that IBM's jvm does not support VirtualMachine.attach(PID).
# JMX access is needed for quering a running activemq instance to gain data or to
# trigger management operations.
#
# Example for ${ACTIVEMQ_CONF}/jmx.access:
# ---
# # The "monitorRole" role has readonly access.
# # The "controlRole" role has readwrite access.
# monitorRole readonly
# controlRole readwrite
# ---
#
# Example for ${ACTIVEMQ_CONF}/jmx.password:
# ---
# # The "monitorRole" role has password "abc123".
# # # The "controlRole" role has password "abcd1234".
# monitorRole abc123
# controlRole abcd1234
# ---
#
# ACTIVEMQ_SUNJMX_START="$ACTIVEMQ_SUNJMX_START -Dcom.sun.management.jmxremote.port=11099 "
# ACTIVEMQ_SUNJMX_START="$ACTIVEMQ_SUNJMX_START -Dcom.sun.management.jmxremote.password.file=${ACTIVEMQ_CONF}/jmx.password"
# ACTIVEMQ_SUNJMX_START="$ACTIVEMQ_SUNJMX_START -Dcom.sun.management.jmxremote.access.file=${ACTIVEMQ_CONF}/jmx.access"
# ACTIVEMQ_SUNJMX_START="$ACTIVEMQ_SUNJMX_START -Dcom.sun.management.jmxremote.ssl=false"
# ACTIVEMQ_SUNJMX_START="$ACTIVEMQ_SUNJMX_START -Dcom.sun.management.jmxremote"
ACTIVEMQ_SUNJMX_START="$ACTIVEMQ_SUNJMX_START -Dcom.sun.management.jmxremote"

# Set jvm jmx configuration for controlling the broker process
# You only have to configure the first four settings if you run a ibm jvm, caused by the
# fact that IBM's jvm does not support VirtualMachine.attach(PID)
# (see also com.sun.management.jmxremote.port, .jmx.password.file and .jmx.access.file )
#ACTIVEMQ_SUNJMX_CONTROL="--jmxurl service:jmx:rmi:///jndi/rmi://127.0.0.1:1099/jmxrmi --jmxuser controlRole --jmxpassword abcd1234"
ACTIVEMQ_SUNJMX_CONTROL=""

# Specify the queue manager URL for using "browse" option of sysv initscript
if [ -z "$ACTIVEMQ_QUEUEMANAGERURL" ]; then
ACTIVEMQ_QUEUEMANAGERURL="--amqurl tcp://localhost:61616"
fi

# Set additional JSE arguments
if [ -z "$ACTIVEMQ_SSL_OPTS" ] ; then
#ACTIVEMQ_SSL_OPTS="-Djava.security.properties=$ACTIVEMQ_CONF/java.security"
ACTIVEMQ_SSL_OPTS=""
fi

# Uncomment to enable remote debugging
#ACTIVEMQ_DEBUG_OPTS="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005"

# ActiveMQ tries to shutdown the broker by jmx,
# after a specified number of seconds send SIGKILL
if [ -z "$ACTIVEMQ_KILL_MAXSECONDS" ]; then
ACTIVEMQ_KILL_MAXSECONDS=30
fi

# Configure a user with non root privileges, if no user is specified do not change user
# (the entire activemq installation should be owned by this user)
ACTIVEMQ_USER=""

# location of the pidfile
# ACTIVEMQ_PIDFILE="$ACTIVEMQ_DATA/activemq.pid"

# Location of the java installation
# Specify the location of your java installation using JAVA_HOME, or specify the
# path to the "java" binary using JAVACMD
# (set JAVACMD to "auto" for automatic detection)
#JAVA_HOME=""
JAVACMD="auto"
ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS $ACTIVEMQ_JMX_OPTS -Dhawtio.authenticationEnabled=false -Dhawtio.realm=activemq -Dhawtio.role=admins -Dhawtio.rolePrincipalClasses=org.apache.activemq.jaas.GroupPrincipal"
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
otel.jmx.interval.milliseconds = 3000
otel.metrics.exporter = otlp
otel.jmx.service.url = service:jmx:rmi:///jndi/rmi://activemq:10991/jmxrmi
otel.jmx.target.system = activemq

# these will be overridden by cmd line
otel.exporter.otlp.endpoint = http://host.testcontainers.internal
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ class JmxConfig {
static final String JMX_REALM = PREFIX + "jmx.realm";

static final List<String> AVAILABLE_TARGET_SYSTEMS =
Arrays.asList("cassandra", "jvm", "kafka", "kafka-consumer", "kafka-producer", "tomcat");
Arrays.asList(
"cassandra", "jvm", "kafka", "kafka-consumer", "kafka-producer", "tomcat", "activemq");

final String serviceUrl;
final String groovyScript;
Expand Down
124 changes: 124 additions & 0 deletions jmx-metrics/src/main/resources/target-systems/activemq.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


def activemqMetrics = otel.mbeans(
[
"org.apache.activemq:type=Broker,brokerName=*,destinationType=Queue,destinationName=*",
"org.apache.activemq:type=Broker,brokerName=*,destinationType=Topic,destinationName=*"
]
)


otel.instrument(activemqMetrics,
"activemq.producer.count",
"The number of producers currently attached to the broker.",
"{producers}",
["destination" : { mbean -> mbean.name().getKeyProperty("destinationName") }],
"ProducerCount",
otel.&longUpDownCounterCallback)
//
//otel.instrument(activemqMetrics,
// "activemq.consumer.count",
// "The number of consumers currently reading from the broker.",
// "{consumers}",
// ["destination" : { mbean -> mbean.name().getKeyProperty("destinationName") }],
// "ConsumerCount",
// otel.&longUpDownCounterCallback)
//
//otel.instrument(activemqMetrics,
// "activemq.memory.usage",
// "The percentage of configured memory used.",
// "%",
// ["destination" : { mbean -> mbean.name().getKeyProperty("destinationName") }],
// "MemoryPercentUsage",
// otel.&doubleValueCallback)
//
//otel.instrument(activemqMetrics,
// "activemq.memory.usage",
// "The percentage of configured memory used.",
// "%",
// ["destination" : { mbean -> mbean.name().getKeyProperty("destinationName") }],
// "MemoryPercentUsage",
// otel.&doubleValueCallback)
//
//otel.instrument(activemqMetrics,
// "activemq.message.current",
// "The current number of messages waiting to be consumed.",
// "{messages}",
// ["destination" : { mbean -> mbean.name().getKeyProperty("destinationName") }],
// "QueueSize",
// otel.&longUpDownCounterCallback)
//
//otel.instrument(activemqMetrics,
// "activemq.message.expired",
// "The total number of messages not delivered because they expired.",
// "{messages}",
// ["destination" : { mbean -> mbean.name().getKeyProperty("destinationName") }],
// "ExpiredCount",
// otel.&longCounterCallback)
//
//otel.instrument(activemqMetrics,
// "activemq.message.enqueued",
// "The total number of messages received by the broker.",
// "{messages}",
// ["destination" : { mbean -> mbean.name().getKeyProperty("destinationName") }],
// "EnqueueCount",
// otel.&longCounterCallback)
//
//otel.instrument(activemqMetrics,
// "activemq.message.dequeued",
// "The total number of messages delivered to consumers.",
// "{messages}",
// ["destination" : { mbean -> mbean.name().getKeyProperty("destinationName") }],
// "DequeueCount",
// otel.&longCounterCallback)
//
//otel.instrument(activemqMetrics,
// "activemq.message.wait_time.avg",
// "The average time a message was held on a destination.",
// "ms",
// ["destination" : { mbean -> mbean.name().getKeyProperty("destinationName") }],
// "AverageEnqueueTime",
// otel.&doubleValueCallback)
//
//
//
//
//def activemqMetricsNoDestination = otel.mbean(
// "org.apache.activemq:type=Broker,brokerName=*"
//)
//
//otel.instrument(activemqMetricsNoDestination,
// "activemq.connection.count",
// "The total number of current connections.",
// "{connections}",
// "CurrentConnectionsCount",
// otel.&longUpDownCounterCallback)
//
//otel.instrument(activemqMetricsNoDestination,
// "activemq.disk.store_usage",
// "The percentage of configured disk used for persistent messages.",
// "%",
// "StorePercentUsage",
// otel.&doubleValueCallback)
//
//otel.instrument(activemqMetricsNoDestination,
// "activemq.disk.temp_usage",
// "The percentage of configured disk used for non-persistent messages.",
// "%",
// "TempPercentUsage",
// otel.&doubleValueCallback)
Loading

0 comments on commit 8a97c48

Please sign in to comment.