Monitoring and Managing Tomcat with JMX
Starting with Java SE 5 there are features known as Monitoring and Management (M and M). The M and M platform and tools support enable applications to be monitored and managed in real-time, the technology that performs this is called Java Management Extension (JMX). JMX can monitor and managed multiple Tomcat instances remotely, Tomcat 6 is JMX-ready, it exposes a set of Java-based objects for external management. This set of objects provides runtime control for operating tuning/tweaking and runtime statistics for monitoring, they can be accessed locally or remotely using agents.
JMX Architecture
JMX is the subject matter of JSR-3, a specification developed over several years by an industry-wide network management experts group that is part of the Java Community Process (JCP). The group delivered the following specification
In the world today we have a standard that already can monitor hardware devices called simple network management protocol (SNMP), but it is very restrictive to modern day software services, also SNMP is very vendor specific. JMX was designed to be flexible and adaptive from the start, by not being very vendor specific and can coexist with SNMP.
The architecture of JMX is layered as well as modular, the layers are loosely coupled. Each layer within JMX is called a level and there are three levels, each level is defined in its own specification create by different group of experts.
Within the instrumentation level resources and objects that can be managed and monitored are enumerated, the act of defining what can be managed and monitored is called Instrumentation. For an example a WEb application may be candidate for JMX management which entails the creation of Managed Beans (MBeans).
MBeans are Java components that live within the instrumentation level, they present a well-defined Java interface for the resource (hardware, software, application, Tomcat, etc) being managed, below is the high-level anatomy of an MBean.
Conceptually, MBeans are similar to JavaBeans and expose attributes, operations and notification events that can be caught by other levels. MBeans are oblivious to the agent that may be managing them, enabling instrumented resources to managed by any JMX-compliant system.
At the agent level, the MBeans exposed by the instrumentation level are aggregated by the agent logic and presented as manageable entities to higher-level distributed services and management applications. The interfaces exposed by the MBean my be presented the same or different by the agent depending on what the management system wants. The components that reside at the agent level are
The MBean server is a component in the agent that aggregates the MBeans being exposed by the agent. A managed device or service needs to register the MBeans with the MBean server before it can be accessed, this happens at runtime.
The Mbean server component has no direct means of communicating with the external application, instead the MBean server relies on available connectors and protocol adapters to interface with external applications. Connectors can use many remote-access mechanisms (RMI, COBRA, Java Socket, etc).
JMX specifies a set of mandatory services that every compliant agent implementation must provide. These services including the following
Agents services allow developers to implement customized agent logic and management applications.
This level includes applications and services that access functionality provided by the agent. At this level the management applications interact with the agent level. This is still a work in progress and thus documentation is limited.
MBeans are software modules that expose the capabilities of a hardware device, a software service or a software component. The following is a list of MBean types
Standard MBean | The features (attributes, operations and notifications) that are exposed for management are fixed and cannot change (without a software or firmware change). These MBeans are the easiest to code. |
Dynamic MBean | The features (attributes, operations and notifications) that are exposed for management are determined at runtime. Therefore the exposed features can change over time. |
Model MBean | Dynamic MBeans are difficult to code, Model MBeans are a type of dynamic MBean to expedite the creation of their own dynamic MBeans. Tomcat make extensive use of the model MBean support provided by the Apache Jakarta Commons (modeler) project |
Open MBean | Open MBeans are a type of dynamic MBean. They can be managed by any compliant management software. The exposed features are guaranteed to be compliant with a universally manageable set of data types. This MBeans are a new feature of JMX 1.2 and are not required to be compliant with earlier versions of JMX. |
Almost all configurable elements of Tomcat will become JMX-manageable in the future, MBeans will be incorporated into all new attributes which then can be managed and monitored. Below is a small list of what MBeans are exposed in Tomcat
The MBeans are access by the using the following
Manageable Tomcat Architectural Components
Service Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerType | R/W |
java.lang.String |
managedResource | R/W |
java.lang.Object |
name | R/W |
java.lang.String |
connectorNames | RO |
javax.management.ObjectName[ ] |
containerName | RO |
java.lang.String |
container | RO |
javax.management.ObjectName |
Server Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerType | R/W |
java.lang.String |
managedResource | R/W |
java.lang.Object |
port | R/W |
int |
shutdown | R/W |
java.lang.String |
serviceNames | R/W |
javax.management.ObjectName[ ] |
Engine Manageable Objects |
||
Attribute Name | Read/Write |
Type |
baseDir | R/W |
java.lang.String |
defaultHost | R/W |
java.lang.String |
jvmRoute | R/W |
java.lang.String |
managedResource | R/W |
java.lang.Object |
modelerType | R/W |
java.lang.String |
name | R/W |
java.lang.String |
realm | R/W |
java.lang.String |
valveObjectNames | R/W |
javax.management.ObjectName[ ] |
Connector Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerType | R/W |
java.lang.String |
acceptCount | R/W |
int |
Address | R/W |
java.lang.String |
algorithm | R/W |
java.lang.String |
allowTrace | R/W |
boolean |
bufferSize | R/W |
int |
className | RO |
java.lang.String |
clientAuth | R/W |
boolean |
ciphers | R/W |
java.lang.String |
compression | R/W |
java.lang.String |
connectionLinger | R/W |
int |
connectionTimeout | R/W |
int |
connectionUploadTimeout | R/W |
int |
disableUploadTimeout | R/W |
boolean |
emptySessionPath | R/W |
java.lang.String |
enableLookups | R/W |
boolean |
keepAliveTimeout | R/W |
int |
keystoreFile | R/W |
java.lang.String |
keystorePass | R/W |
java.lang.String |
keystoreType | R/W |
java.lang.String |
keyAlias | R/W |
java.lang.String |
maxHttpeaderSize | R/W |
int |
maxKeepAliveRequests | R/W |
int |
maxPostSize | R/W |
int |
maxpareThreads | R/W |
int |
maxThreads | R/W |
int |
minSpareThreads | R/W |
int |
port | R/W |
int |
protocol | R/W |
java.lang.String |
protocolHandlerClassName | RO |
java.lang.String |
proxyName | R/W |
java.lang.String |
proxyPort | R/W |
int |
redirectPort | R/W |
int |
scheme | R/W |
java.lang.String |
secret | WO |
java.lang.String |
secure | R/W |
boolean |
sslProtocol | R/W |
java.lang.String |
sslProcotols | R/W |
java.lang.String |
strategy | R/W |
java.lang.String |
tcpNoDelay | R/W |
boolean |
threadPriority | R/W |
java.lang.String |
tomcatAuthentication | R/W |
boolean |
trustStoreFile | R/W |
java.lang.String |
trustStoreFile | R/W |
java.lang.String |
trustStorePass | R/W |
java.lang.String |
trustStoreType | R/W |
java.lang.String |
URIEncoding | R/W |
java.lang.String |
xpoweredBy | R/W |
boolean |
Host Manageable Objects |
||
Attribute Name | Read/Write | Type |
modelerType | R/W |
java.lang.String |
appBase | R/W |
java.lang.String |
autoDeploy | R/W |
boolean |
debug | R/W |
int |
deployOnStartup | R/W |
boolean |
deployXML | R/W |
boolean |
managedResource | R/W |
java.lang.Object |
name | R/W |
java.lang.String |
realm | R/W |
org.apache.catalina.Realm |
configClass | R/W |
java.lang.String |
unpackWARs | R/W |
boolean |
xmlNamespaceAware | R/W |
boolean |
xmlValidation | R/W |
boolean |
children | R/W |
javax.management.ObjectName[ ] |
aliases | R/W |
java.lang.String |
valveNames | R/W |
java.lang.String |
valveObjectNames | R/W |
javax.management.ObjectName[ ] |
Realm Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerType | R/W |
java.lang.String |
className | RO |
java.lang.String |
resourceName | R/W |
java.lang.String |
Valve Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerType | R/W |
java.lang.String |
className | RO |
java.lang.String |
Manager Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerType | R/W |
java.lang.String |
algorithm | R/W |
java.lang.String |
randomFile | R/W |
java.lang.String |
className | RO |
java.lang.String |
distributable | R/W |
boolean |
entropy | R/W |
java.lang.String |
managedResource | R/W |
java.lang.Object |
maxActiveSessions | R/W |
int |
maxInactiveInterval | R/W |
int |
sessionMaxKeepAliveTime | R/W |
Int |
sessionAverageAliveTime | R/W |
Int |
processExpiresFequency | R/W |
int |
name | RO |
java.lang.String |
pathname | R/W |
java.lang.String |
activeSessions | RO |
int |
sessionCounter | R/W |
int |
maxActive | R/W |
int |
rejectedSessions | R/W |
int |
expiredSessions | R/W |
int |
processingTime | R/W |
long |
duplicates | R/W |
int |
Manageable Runtime Data Objects
UserDatabase Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerType | R/W |
java.lang.String |
encoding | R/W |
java.lang.String |
groups | RO |
java.lang.String[ ] |
pathname | R/W |
java.lang.String |
roles | RO |
java.lang.String[ ] |
readonly | RO |
boolean |
writeable | RO |
boolean |
users | RO |
java.lang.String[ ] |
User Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerType | R/W |
java.lang.String |
fullName | R/W |
java.lang.String |
groups | R/W |
java.lang.String[ ] |
password | R/W |
java.lang.String |
roles | RO |
java.lang.String[ ] |
username | R/W |
java.lang.String |
Role Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerType | R/W |
java.lang.String |
description | R/W |
java.lang.String |
rolename | R/W |
java.lang.String |
NamingResources Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerType | R/W |
java.lang.String |
environments | RO |
java.lang.String[ ] |
resources | RO |
java.lang.String[ ] |
resourceLinks | RO |
java.lang.String[ ] |
Environment Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerType | R/W |
java.lang.String |
className | RO |
java.lang.String |
description | R/W |
java.lang.String |
name | R/W |
java.lang.String |
override | R/W |
boolean |
type | R/W |
java.lang.String |
value | R/W |
java.lang.String |
Resource Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerType | R/W |
java.lang.String |
auth | R/W |
java.lang.String |
description | R/W |
java.lang.String |
name | R/W |
java.lang.String |
scope | R/W |
java.lang.String |
type | R/W |
java.lang.String |
ResourceLink Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerType | R/W |
java.lang.String |
global | R/W |
java.lang.String |
name | R/W |
java.lang.String |
type | R/W |
java.lang.String |
Exposed Application-Related Objects
WebModule Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerType | R/W |
java.lang.String |
antiJARLocking | R/W |
boolean |
antiResourceLocking | R/W |
boolean |
allowLinking | R/W |
boolean |
annotationProcessor | R/W |
org.apache.AnnotationProcessor |
cacheMaxSize | R/W |
int |
cacheTTL | R/W |
int |
cachingAllowed | R/W |
boolean |
caseSensitive | R/W |
boolean |
children | R/W |
javax.management.ObjectName[ ] |
coookies | R/W |
boolean |
compilerClasspath | R/W |
java.lang.String |
configFile | R/W |
java.lang.String |
crossContext | R/W |
boolean |
defaultContextXml | R/W |
java.lang.String |
defaultWebXml | R/W |
java.lang.String |
delegate | R/W |
boolean |
deploymentDescriptor | R/W |
java.lang.String |
docBase | R/W |
java.lang.String |
engineName | R/W |
java.lang.String |
environments | R) |
java.lang.String[ ] |
eventProvider | R/W |
boolean |
javaVMs | R/W |
java.lang.String[ ] |
loader | R/W |
org.apache.catalina.Loader |
managedResource | R/W |
java.lang.Object |
manager | R/W |
org.apache.catalina/Manager |
managerChecksFrequency | R/W |
int |
mappingObject | R/W |
java.lang.bject |
namingContextListener | R/W |
org.apache.catalina.core.NamingContextListener |
objectName | R/W |
java.lang.String |
override | R/W |
boolean |
parentClassLoader | R/W |
java.lang.Classloader |
path | R/W |
java.lang.String |
privileged | R/W |
boolean |
processingTime | RO |
long |
realm | R/W |
org.apache.catalina.Realm |
reloadable | R/W |
boolean |
resourceNames | RO |
java.lang.String[ ] |
saveConfig | R/W |
boolean |
server | R/W |
java.lang.String |
servlets | RO |
java.lang.String[ ] |
startTime | R/W |
long |
startupTime | R/W |
long |
state | R/W |
int |
stateManageable | R/W |
boolean |
statisticsProvider | R/W |
boolean |
staticResources | RO |
javax.naming.directory.ObjectName[ ] |
swallowOutput | R/W |
boolean |
tldScanTime | R/W |
long |
unloadDelay | R/W |
long |
useNaming | R/W |
boolean |
valveObjectNames | RO |
javax.management.ObjectName[ ] |
welcomeFiles | RO |
java.lang.String[ ] |
workDir | R/W |
java.lang.String |
Servlet Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerType | R/W |
java.lang.String |
engineName | RO |
java.lang.String |
eventProvider | R/W |
boolean |
objectName | R/W |
java.lang.String |
stateManageable | R/W |
boolean |
statisticsProvider | R/W |
boolean |
processingTime | RO |
long |
maxTime | RO |
long |
requestCount | RO |
int |
errorCount | RO |
int |
loadTime | RO |
long |
classLoadTime | RO |
int |
Exposed Internal Tomcat Objects
RequestProcessor Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerType | R/W |
java.lang.String |
virtualHost | RO |
java.lang.String |
bytesSent | R/W |
long |
method | RO |
java.lang.String |
remoteAddr | RO |
java.lang.String |
requestBytesSent | RO |
long |
contentLength | RO |
int |
bytesReceived | R/W |
long |
requestProcessingTime | RO |
long |
globalProcessor | R/W |
org.apache.cotoe.RequestGroupInfo |
protocol | RO |
java.lang.String |
currentQueryString | RO |
java.lang.String |
maxRequestUri | R/W |
java.lang.String |
requestBytesReceived | RO |
long |
serverPort | RO |
int |
stage | R/W |
int |
requestCount | R/W |
int |
maxTime | R/W |
long |
processingTime | R/W |
long |
currentUri | RO |
java.lang.String |
errorCount | R/W |
int |
Cache Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerType | R/W |
java.lang.String |
accessCount | RO |
long |
cacheMaxSize | R/W |
int |
hitsCount | RO |
long |
maxAllocateIterations | R/W |
int |
spareNotFoundEntries | R/W |
int |
cacheSize | RO |
int |
desiredEntryAccessRatio | R/W |
long |
ThreadPool Manageable Objects |
||
Attribute Name | Read/Write |
Type |
modelerype | R/W |
java.lang.String |
name | R/W |
java.lang.String |
minSpareThreads | R/W |
int |
currentThreadsBusy | RO |
int |
daemon | R/W |
boolean |
threadStatus | RO |
java.lang.String[ ] |
sequence | RO |
int |
currentThreadCount | RO |
int |
maxSpareThreads | R/W |
int |
maxThreads | R/W |
int |
threadParam | RO |
java.lang.String[ ] |
Accessing JMX via the Manager Proxy
The Manager application has a JMX proxy that can be used to interact with Tomcats agent directly. The proxy enables monitoring of Tomcat components through the exposed MBeans. It also enables you to read the value of an MBean attribute, or change/set the value of a writeable MBean attributes.
There is a URL for working with the JMX proxy and you provide the operation details to the URL
Base URL | http://<host>:<port>/manager/jmxproxy/<operation details> Note: you must have access to the manager application, so check the tomcat-user.xml file. |
Complete listing | http://localhost:8080/manager/jmxproxy/?qry=*:* |
List Connectors | http://localhost:8080/manager/jmxproxy/?qry=*:type=Connector,* |
Modifying MBean Attributes | http://localhost:8080/manager/jmxproxy/?set=<full MBean name>&att=<attribute name>&val=<value to change to> ## Example |
You can also use the jconsole GUI to monitor Tomcat as well, you need to add support for this, so follow below
Add jconsole GUI support | # You need to add the below to the java startup -Dcom.sun.management.jmxremote |
Once you have done this then start the jconsole (see below picture) and connect using the remote process option and using localhost:8999
then you should get the below screen, the jconsole will start collecting and displaying the Tomcat statistics, etc.