blob: 4113599a59ca5037e82ad47360b53b02b3256c23 [file] [log] [blame]
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ========================================================================
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
[[using-jmx]]
=== Using JMX with Jetty
Jetty JMX integration uses the platform MBean server implementation that Java VM provides.
The integration is based on the `ObjectMBean` implementation of `DynamicMBean`.
This implementation allows you to wrap an arbitrary POJO in an MBean and annotate it appropriately to expose it via JMX.
See xref:jetty-jmx-annotations[].
The `MBeanContainer` implementation of the `Container.Listener` interface coordinates creation of MBeans.
The Jetty Server and it's components use a link:{JDURL}/org/eclipse/jetty/util/component/Container.html[Container] to maintain a containment tree of components and to support notification of changes to that tree.
The `MBeanContainer` class listens for Container events and creates and destroys MBeans as required to wrap all Jetty components.
You can access the MBeans that Jetty publishes both through built-in Java VM connector via JConsole or JMC, or by registering a remote JMX connector and using a remote JMX agent to monitor Jetty.
[[configuring-jmx]]
==== Configuring JMX
This guide describes how to initialize and configure the Jetty JMX integration.
To monitor an application using JMX, perform the following steps:
* Configure the application to instantiate an MBean container.
* Instrument objects to be MBeans.
* Provide access for JMX agents to MBeans.
[[accessing-jetty-mbeans]]
===== Using JConsole to Access Jetty MBeans
The simplest way to access the MBeans that Jetty publishes is to use the http://java.sun.com/developer/technicalArticles/J2SE/jconsole.html[JConsole utility] the Java Virtual Machine supplies.
See xref:jetty-jconsole[] for instructions on how to configure JVM for use with JConsole or JMC.
To access Jetty MBeans via JConsole or JMC, you must:
* Enable the registration of Jetty MBeans into the platform MBeanServer.
* Enable a `JMXConnectorServer` so that JConsole/JMC can connect and visualize the MBeans.
[[registering-jetty-mbeans]]
===== Registering Jetty MBeans
Configuring Jetty JMX integration differs for standalone and embedded Jetty.
[[jmx-standalone-jetty]]
====== Standalone Jetty
JMX is not enabled by default in the Jetty distribution.
To enable JMX in the Jetty distribution, run the following, where `{$jetty.home}` is the directory where you have the Jetty distribution located (see link:#startup-base-and-home[the documentation for Jetty base vs. home examples]):
[source, screen, subs="{sub-order}"]
....
$ java -jar {$jetty.home}/start.jar --add-to-start=jmx
....
Running the above command will append the available configurable elements of the JMX module to the `{$jetty.base}/start.ini` file.
If you are managing separate ini files for your modules in the distribution, use `--add-to-start.d=jmx` instead.
If you wish to add remote access for JMX, you will also need to enable the JMX-Remote module:
[source, screen, subs="{sub-order}"]
....
$ java -jar {$jetty.home}/start.jar --add-to-start=jmx-remote
....
[[jmx-embedded-jetty]]
====== Embedded Jetty
When running Jetty embedded into an application, create and configure an MBeanContainer instance as follows:
[source, java]
----
Server server = new Server();
// Setup JMX
MBeanContainer mbContainer=new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
server.addEventListener(mbContainer);
server.addBean(mbContainer);
// Add loggers MBean to server (will be picked up by MBeanContainer above)
server.addBean(Log.getLog());
----
Notice that Jetty creates the `MBeanContainer` immediately after creating the Server, and immediately after registering it as an `EventListener` of the Server object (which is also a Container object).
Because logging is initialized prior to the `MBeanContainer` (even before the Server itself), it is necessary to register the logger manually via `server.addBean()` so that the loggers may show up in the JMX tree.
[[jmx-using-jetty-maven-plugin]]
===== Using the Jetty Maven Plugin with JMX
If you are using the link:#jetty-maven-plugin[Jetty Maven plugin] you should copy the `/etc/jetty-jmx.xml` file into your webapp project somewhere, such as `/src/etc,` then add a `<jettyconfig>` element to the plugin `<configuration>`:
[source, xml, subs="{sub-order}"]
----
<plugin>
<groupid>org.eclipse.jetty</groupid>
<artifactid>jetty-maven-plugin</artifactid>
<version>{VERSION}</version>
<configuration>
<scanintervalseconds>10</scanintervalseconds>
<jettyXml>src/etc/jetty-jmx.xml</jettyXml>
</configuration>
</plugin>
----
[[enabling-jmxconnectorserver-for-remote-access]]
==== Enabling JMXConnectorServer for Remote Access
There are two ways of enabling remote connectivity so that JConsole or JMC can connect to visualize MBeans.
* Use the `com.sun.management.jmxremote` system property on the command line.
Unfortunately, this solution does not work well with firewalls and is not flexible.
* Use Jetty's `ConnectorServer` class.
To enable use of this class, uncomment the correspondent portion in `/etc/jetty-jmx.xml,` like this:
[source, xml, subs="{sub-order}"]
----
<New id="ConnectorServer" class="org.eclipse.jetty.jmx.ConnectorServer">
<Arg>
<New class="javax.management.remote.JMXServiceURL">
<Arg type="java.lang.String">rmi</Arg>
<Arg type="java.lang.String" />
<Arg type="java.lang.Integer"><SystemProperty name="jetty.jmxrmiport" default="1099"/></Arg>
<Arg type="java.lang.String">/jndi/rmi://<SystemProperty name="jetty.jmxrmihost" default="localhost"/>:<SystemProperty name="jetty.jmxrmiport" default="1099"/>/jmxrmi</Arg>
</New>
</Arg>
<Arg>org.eclipse.jetty.jmx:name=rmiconnectorserver</Arg>
<Call name="start" />
</New>
----
This configuration snippet starts an `RMIRegistry` and a `JMXConnectorServer` both on port 1099 (by default), so that firewalls should open just that one port to allow connections from JConsole or JMC.
[[securing-remote-access]]
==== Securing Remote Access
`JMXConnectorServer` several options to restrict access.
For a complete guide to controlling authentication and authorization in JMX, see https://blogs.oracle.com/lmalventosa/entry/jmx_authentication_authorization[Authentication and Authorization in JMX RMI connectors] in Luis-Miguel Alventosa's blog.
To restrict access to the `JMXConnectorServer`, you can use this configuration, where the `jmx.password` and `jmx.access` files have the format specified in the blog entry above:
[source, xml, subs="{sub-order}"]
----
<New id="ConnectorServer" class="org.eclipse.jetty.jmx.ConnectorServer">
<Arg>
<New class="javax.management.remote.JMXServiceURL">
<Arg type="java.lang.String">rmi</Arg>
<Arg type="java.lang.String" />
<Arg type="java.lang.Integer"><SystemProperty name="jetty.jmxrmiport" default="1099"/></Arg>
<Arg type="java.lang.String">/jndi/rmi://<SystemProperty name="jetty.jmxrmihost" default="localhost"/>:<SystemProperty name="jetty.jmxrmiport" default="1099"/>/jmxrmi</Arg>
</New>
</Arg>
<Arg>
<Map>
<Entry>
<Item>jmx.remote.x.password.file</Item>
<Item>
<New class="java.lang.String"><Arg><Property name="jetty.home" default="." />/resources/jmx.password</Arg></New>
</Item>
</Entry>
<Entry>
<Item>jmx.remote.x.access.file</Item>
<Item>
<New class="java.lang.String"><Arg><Property name="jetty.home" default="." />/resources/jmx.access</Arg></New>
</Item>
</Entry>
</Map>
</Arg>
<Arg>org.eclipse.jetty.jmx:name=rmiconnectorserver</Arg>
<Call name="start" />
</New>
----
[[custom-monitor-applcation]]
==== Custom Monitor Application
Using the JMX API, you can also write a custom application to monitor your Jetty server.
To allow this application to connect to your Jetty server, you need to uncomment the last section of the `/etc/jetty-jmx.xml` configuration file and optionally modify the endpoint name.
Doing so creates a JMX HTTP connector and registers a JMX URL that outputs to the `Stderr` log.
You should provide the URL that appears in the log to your monitor application in order to create an `MBeanServerConnection.`
You can use the same URL to connect to your Jetty instance from a remote machine using JConsole or JMC.
See the link:{GITBROWSEURL}/jetty-jmx/src/main/config/etc/jetty-jmx.xml[configuration file] for more details.