Skip to content

Commit

Permalink
add embedded tomcat jmx instrumentation
Browse files Browse the repository at this point in the history
update copyright

different name for datasource mbean

reorganize tomcat jmx

fix tomcat utils
  • Loading branch information
tbradellis committed Oct 18, 2022
1 parent 9e78796 commit 6215956
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,29 @@

package com.nr.agent.instrumentation.tomcat;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;

import com.newrelic.agent.bridge.AgentBridge;
import com.newrelic.api.agent.NewRelic;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;

public class TomcatUtils {

private static final String JMX_PREFIX = "Catalina";
private static final String JMX_EMBEDDED_PREFIX = "Tomcat";
private static final String JMX_EMBEDDED_DATASOURCE_PREFIX = "org.apache.tomcat.jdbc.pool.jmx";

private static final AtomicBoolean addedJmx = new AtomicBoolean(false);

public static void addJmx() {
if (System.getProperty("com.sun.aas.installRoot") == null) {
if (!addedJmx.getAndSet(true)) {
//We need to add all three possible types because embedded tomcat breaks out
//the types (which we named PREFIX) differently than standalone tomcat, yet the same Server/HostConfig_Instrumentation is used.
AgentBridge.jmxApi.addJmxMBeanGroup(JMX_PREFIX);
AgentBridge.jmxApi.addJmxMBeanGroup(JMX_EMBEDDED_PREFIX);
AgentBridge.jmxApi.addJmxMBeanGroup(JMX_EMBEDDED_DATASOURCE_PREFIX);

NewRelic.getAgent().getLogger().log(Level.FINER, "Added JMX for Tomcat");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import com.newrelic.agent.Agent;
import com.newrelic.agent.bridge.JmxApi;
import com.newrelic.agent.jmx.metrics.JmxFrameworkValues;
import com.newrelic.agent.jmx.values.EmbeddedTomcatDataSourceJmxValues;
import com.newrelic.agent.jmx.values.EmbeddedTomcatJmxValues;
import com.newrelic.agent.jmx.values.GlassfishJmxValues;
import com.newrelic.agent.jmx.values.Jboss7UpJmxValues;
import com.newrelic.agent.jmx.values.JettyJmxMetrics;
Expand Down Expand Up @@ -69,8 +71,12 @@ private JmxFrameworkValues getJmxFrameworkValues(String prefixName) {
return new Solr7JmxValues();
case WebsphereLibertyJmxValues.PREFIX:
return new WebsphereLibertyJmxValues();
case EmbeddedTomcatDataSourceJmxValues.PREFIX:
return new EmbeddedTomcatDataSourceJmxValues();
case TomcatJmxValues.PREFIX:
return new TomcatJmxValues();
case EmbeddedTomcatJmxValues.PREFIX:
return new EmbeddedTomcatJmxValues();
case JettyJmxMetrics.PREFIX:
return new JettyJmxMetrics();
case Jboss7UpJmxValues.PREFIX:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
*
* * Copyright 2022 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/

package com.newrelic.agent.jmx.values;

import com.newrelic.agent.MetricNames;
import com.newrelic.agent.jmx.metrics.BaseJmxValue;
import com.newrelic.agent.jmx.metrics.DataSourceJmxMetricGenerator;
import com.newrelic.agent.jmx.metrics.JmxFrameworkValues;
import com.newrelic.agent.jmx.metrics.JmxMetric;

import java.util.ArrayList;
import java.util.List;

public class EmbeddedTomcatDataSourceJmxValues extends JmxFrameworkValues {

/**
* The Mbean group namespaces are different between standalone Tomcat and Embedded Tomcat
* Standalone uses the prefix (aka type) Catalina for queries whereas embedded Tomcat uses the prefix (aka type) Tomcat.
* Our TomcatJmxValues instrumentation only queries MBeans with the Catalina prefix thus queries initiated by embedded Tomcat
* do not provide metrics. Additionally, datasource metrics
* were broken out into type: org.apache.tomcat.pool.jmx for embedded tomcat. See (@EmbeddedTomcatJmxValues)
*/

public static final String PREFIX = "org.apache.tomcat.jdbc.pool.jmx";

private static final int METRIC_COUNT = 1;

private static final JmxMetric CONNECTIONS_ACTIVE = DataSourceJmxMetricGenerator.CONNECTIONS_ACTIVE.createMetric("NumActive");
private static final JmxMetric CONNECTIONS_IDLE = DataSourceJmxMetricGenerator.CONNECTIONS_IDLE.createMetric("NumIdle");
private static final JmxMetric CONNECTIONS_MAX = DataSourceJmxMetricGenerator.CONNECTIONS_MAX.createMetric("MaxActive");
private static final JmxMetric CONNECTIONS_CREATED = DataSourceJmxMetricGenerator.CONNECTIONS_CREATED.createMetric("CreatedCount");

private final List<BaseJmxValue> metrics = new ArrayList<>(METRIC_COUNT);

public EmbeddedTomcatDataSourceJmxValues() {
createMetrics("*");
}

public EmbeddedTomcatDataSourceJmxValues(String name) {
createMetrics(name);

}

private void createMetrics(String name) {

metrics.add(new BaseJmxValue("org.apache.tomcat.jdbc.pool.jmx:name=*,type=ConnectionPool", MetricNames.JMX_DATASOURCES + "{name}/",
new JmxMetric[] { CONNECTIONS_ACTIVE, CONNECTIONS_IDLE, CONNECTIONS_MAX, CONNECTIONS_CREATED }));
}

@Override
public List<BaseJmxValue> getFrameworkMetrics() {
return metrics;
}

@Override
public String getPrefix() {
return PREFIX;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
*
* * Copyright 2022 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/

package com.newrelic.agent.jmx.values;

import com.newrelic.agent.MetricNames;
import com.newrelic.agent.jmx.JmxType;
import com.newrelic.agent.jmx.metrics.BaseJmxValue;
import com.newrelic.agent.jmx.metrics.JmxAction;
import com.newrelic.agent.jmx.metrics.JmxFrameworkValues;
import com.newrelic.agent.jmx.metrics.JmxMetric;
import com.newrelic.agent.jmx.metrics.ServerJmxMetricGenerator;

import java.util.ArrayList;
import java.util.List;

public class EmbeddedTomcatJmxValues extends JmxFrameworkValues {

/**
* The Mbean group namespaces are different between standalone Tomcat and Embedded Tomcat
* Standalone uses the prefix (aka type) Catalina for queries whereas embedded Tomcat uses the prefix (aka type) Tomcat.
* Our TomcatJmxValues instrumentation only queries MBeans with the Catalina prefix thus queries initiated by embedded Tomcat
* do not provide metrics. Additionally, datasource metrics
* were broken out into type: org.apache.tomcat.pool.jmx for embedded tomcat. See (@EmbeddedTomcatDataSourceJmxValues)
*/

public static final String PREFIX = "Tomcat";

private static final int METRIC_COUNT = 2;

// SESSION METRICS (Manager)
private static final JmxMetric ACTIVE_SESSIONS = ServerJmxMetricGenerator.SESSION_ACTIVE_COUNT.createMetric("activeSessions");
private static final JmxMetric EXPIRED_SESSIONS = ServerJmxMetricGenerator.SESSION_EXPIRED_COUNT.createMetric("expiredSessions");
private static final JmxMetric REJECTED_SESSIONS = ServerJmxMetricGenerator.SESSION_REJECTED_COUNT.createMetric("rejectedSessions");
private static final JmxMetric SESSION_ALIVE_TIME = ServerJmxMetricGenerator.SESSION_AVG_ALIVE_TIME.createMetric("sessionAverageAliveTime");

// THREAD POOL METRICS
private static final JmxMetric CURRENT_MAX_COUNT = ServerJmxMetricGenerator.MAX_THREAD_POOL_COUNT.createMetric("maxThreads");
private static final JmxMetric CURRENT_ACTIVE_COUNT = ServerJmxMetricGenerator.ACTIVE_THREAD_POOL_COUNT.createMetric("currentThreadsBusy");
private static final JmxMetric CURRENT_IDLE_COUNT = JmxMetric.create(new String[] { "currentThreadCount",
"currentThreadsBusy" }, MetricNames.JMX_THREAD_POOL_IDLE, JmxAction.SUBTRACT_ALL_FROM_FIRST, JmxType.SIMPLE);

private final List<BaseJmxValue> metrics = new ArrayList<>(METRIC_COUNT);

public EmbeddedTomcatJmxValues() {
createMetrics("*");
}

public EmbeddedTomcatJmxValues(String name) {
createMetrics(name);

}

private void createMetrics(String name) {
/*
* Only used by 7.0+. The manager bean provides information about sessions. sessionCounter is the total number of
* sessions created by this manager. ActiveSessions is the number of active sessions at this moment.
* expiredSesions is the number of sessions that have expired. RejectedSessions is the number of sessions
* rejected due to maxActive being reached. SessionAverageAliveTime is the average time an expired session had
* been alive.
*/
metrics.add(new BaseJmxValue(name + ":type=Manager,context=*,host=*,*", MetricNames.JMX_SESSION + "{context}/",
new JmxMetric[] { ACTIVE_SESSIONS, EXPIRED_SESSIONS, REJECTED_SESSIONS, SESSION_ALIVE_TIME }));

metrics.add(new BaseJmxValue(name + ":type=ThreadPool,name=*", MetricNames.JMX_THREAD_POOL + "{name}/",
new JmxMetric[] { CURRENT_ACTIVE_COUNT, CURRENT_IDLE_COUNT, CURRENT_MAX_COUNT }));

}

@Override
public List<BaseJmxValue> getFrameworkMetrics() {
return metrics;
}

@Override
public String getPrefix() {
return PREFIX;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class TomcatJmxValues extends JmxFrameworkValues {
*/
public static final String PREFIX = "Catalina";

private static final int METRIC_COUNT = 3;
private static final int METRIC_COUNT = 5;

// SESSION METRICS
private static final JmxMetric ACTIVE_SESSIONS = ServerJmxMetricGenerator.SESSION_ACTIVE_COUNT.createMetric("activeSessions");
Expand Down

0 comments on commit 6215956

Please sign in to comment.