Skip to content

Commit

Permalink
Add Jetty Integration (#320)
Browse files Browse the repository at this point in the history
* Add jetty integration

* Update Readmes

* Add Default app to generate session metrics

* Spotless

* Fix doc description
  • Loading branch information
Miguel Rodriguez committed May 11, 2022
1 parent 8e0c440 commit ee223df
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 1 deletion.
1 change: 1 addition & 0 deletions jmx-metrics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ mutually exclusive with `otel.jmx.groovy.script`. The currently supported target
| [`cassandra`](./docs/target-systems/cassandra.md) |
| [`hbase`](./docs/target-systems/hbase.md) |
| [`hadoop`](./docs/target-systems/hadoop.md) |
| [`jetty`](./docs/target-systems/jetty.md) |
| [`kafka`](./docs/target-systems/kafka.md) |
| [`kafka-consumer`](./docs/target-systems/kafka-consumer.md) |
| [`kafka-producer`](./docs/target-systems/kafka-producer.md) |
Expand Down
41 changes: 41 additions & 0 deletions jmx-metrics/docs/target-systems/jetty.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Jetty Metrics

The JMX Metric Gatherer provides built in Jetty metric gathering capabilities.
Details about using JMX with WildFly can be found here: https://www.eclipse.org/jetty/documentation/jetty-11/operations-guide/index.html#og-jmx

### Metrics
* Name: `jetty.select.count`
* Description: The number of select calls.
* Unit: `{operations}`
* Instrument Type: longCounterCallback


* Name: `jetty.session.count`
* Description: The number of sessions created.
* Unit: `{sessions}`
* Instrument Type: LongCounterCallback


* Name: `jetty.session.time.total`
* Description: The total time sessions have been active.
* Unit: `s`
* Instrument Type: longUpDownCounterCallback


* Name: `jetty.session.time.max`
* Description: The maximum amount of time a session has been active.
* Unit: `s`
* Instrument Type: longValueCallback


* Name: `jetty.thread.count`
* Description: The current number of threads.
* Unit: `{threads}`
* Labels: `state`
* Instrument Type: longValueCallback


* Name: `jetty.thread.queue.count`
* Description: The current number of threads in the queue.
* Unit: `{threads}`
* Instrument Type: longValueCallback
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* 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;

class JettyIntegrationTest extends AbstractIntegrationTest {

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

@Container
GenericContainer<?> jetty =
new GenericContainer<>(
new ImageFromDockerfile()
.withDockerfileFromBuilder(
builder ->
builder
.from("jetty")
.run(
"java",
"-jar",
"/usr/local/jetty/start.jar",
"--add-to-startd=jmx,stats,http")
.run("mkdir -p /var/lib/jetty/webapps/ROOT/")
.run("touch /var/lib/jetty/webapps/ROOT/index.html")
.env(
"JAVA_OPTIONS",
"-Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.rmi.port=1099")
.build()))
.withNetwork(Network.SHARED)
.withEnv("LOCAL_JMX", "no")
.withNetworkAliases("jetty")
.withExposedPorts(1099, 8080)
.withStartupTimeout(Duration.ofMinutes(2))
.waitingFor(Wait.forLogMessage(".*Started Server.*", 1));

@Test
void endToEnd() throws InterruptedException {
waitAndAssertMetrics(
metric ->
assertSumWithAttributes(
metric,
"jetty.session.count",
"The number of sessions established in total.",
"{sessions}",
attrs -> attrs.containsKey("resource")),
metric ->
assertSumWithAttributes(
metric,
"jetty.session.time.total",
"The total time sessions have been active.",
"s",
attrs -> attrs.containsKey("resource")),
metric ->
assertGaugeWithAttributes(
metric,
"jetty.session.time.max",
"The maximum amount of time a session has been active.",
"s",
attrs -> attrs.containsKey("resource")),
metric ->
assertSum(metric, "jetty.select.count", "The number of select calls.", "{operations}"),
metric ->
assertGaugeWithAttributes(
metric,
"jetty.thread.count",
"The current number of threads.",
"{threads}",
attrs -> attrs.contains(entry("state", "busy")),
attrs -> attrs.contains(entry("state", "idle"))),
metric ->
assertGauge(
metric,
"jetty.thread.queue.count",
"The current number of threads in the queue.",
"{threads}"));
}
}
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://jetty:1099/jmxrmi
otel.jmx.target.system = jetty

# 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 @@ -49,6 +49,7 @@ class JmxConfig {
"cassandra",
"hbase",
"hadoop",
"jetty",
"jvm",
"kafka",
"kafka-consumer",
Expand Down
37 changes: 37 additions & 0 deletions jmx-metrics/src/main/resources/target-systems/jetty.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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 beanSelector = otel.mbean("org.eclipse.jetty.io:context=*,type=managedselector,id=*")
otel.instrument(beanSelector, "jetty.select.count", "The number of select calls.", "{operations}","selectCount", otel.&longCounterCallback)

def beanSessions = otel.mbean("org.eclipse.jetty.server.session:context=*,type=sessionhandler,id=*")
otel.instrument(beanSessions, "jetty.session.count", "The number of sessions established in total.", "{sessions}",
["resource" : { mbean -> mbean.name().getKeyProperty("context") }],
"sessionsCreated", otel.&longCounterCallback)
otel.instrument(beanSessions, "jetty.session.time.total", "The total time sessions have been active.", "s",
["resource" : { mbean -> mbean.name().getKeyProperty("context") }],
"sessionTimeTotal", otel.&longUpDownCounterCallback)
otel.instrument(beanSessions, "jetty.session.time.max", "The maximum amount of time a session has been active.", "s",
["resource" : { mbean -> mbean.name().getKeyProperty("context") }],
"sessionTimeMax", otel.&longValueCallback)

def beanThreads = otel.mbean("org.eclipse.jetty.util.thread:type=queuedthreadpool,id=*")
otel.instrument(beanThreads, "jetty.thread.count", "The current number of threads.", "{threads}",
[
"busyThreads":["state" : {"busy"}],
"idleThreads": ["state" : {"idle"}]
], otel.&longValueCallback)
otel.instrument(beanThreads, "jetty.thread.queue.count", "The current number of threads in the queue.", "{threads}","queueSize", otel.&longValueCallback)
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ void staticValues() {
"cassandra",
"hbase",
"hadoop",
"jetty",
"jvm",
"kafka",
"kafka-consumer",
Expand Down Expand Up @@ -191,7 +192,7 @@ void invalidTargetSystem() {
assertThatThrownBy(config::validate)
.isInstanceOf(ConfigurationException.class)
.hasMessage(
"[jvm, unavailabletargetsystem] must specify targets from [activemq, cassandra, hbase, hadoop, jvm, "
"[jvm, unavailabletargetsystem] must specify targets from [activemq, cassandra, hbase, hadoop, jetty, jvm, "
+ "kafka, kafka-consumer, kafka-producer, solr, tomcat, wildfly]");
}

Expand Down

0 comments on commit ee223df

Please sign in to comment.