6 posts categorized "tomcat admin"


The New Manager Roles in Tomcat 7 are Wonderful

I just found the changes that the Apache Tomcat team have made to admin and manager roles to be a very pleasant surprise. This is almost like delegated administration—a very neat addition to the tomcat 7 feature set.

Prior to tomcat 7, if you needed or wanted to be able to unlock the status pages within your tomcat container in order to view things like number of threads, max threads, which ip addresses were connected, etc., you needed to unlock the Tomcat Manager. Unlocking the tomcat manager was a simple matter of creating a "manager" role and assigning accounts to that role. The problem that this created for us was that doing this resulted in the tomcat manager, the status pages, and the jmxproxy were all available to anyone with access to the server and assigned that "manager" role.

With Tomcat 7, there are now 4 built-in roles that allow administrators to delegate access to specific accounts so that they can only do certain things, like view stats and not deploy apps. The four roles are named: manager-gui, manager-script, manager-jmx, and manager-status.


manager-gui provides access to the status pages and the tomcat manager web console.  Accounts with this level of access can do anything through the traditional tomcat manager web console. This includes deploying/undeploying apps, viewing stats, generating leak detection diagnostics, expiring sessions, etc.


manager-script, provides all the functionality that manager-gui provides but using the text interface instead of the html gui. A savvy scripter using curl or some perl/groovy/java/ruby/powershell/python/etc., scripts can do anything that a user with a web browser can do with the tomcat manager HTML console. If you are an app server administrator who loves the command-line, the manager-script role is for you.  One item to note is that the context path for the text interface has changed in Tomcat 7 so existing scripts may need to be reworked.


manager-jmx provides access to the jmxproxy, which is something monitoring tools & scripts, administrators, and developers may find useful.  In addition, this role also has access to the status pages.  Existing scripts should work as-is because, unlike the text interface, the context path for the jmxproxy has not changed.


manager-status provides the users assigned to that role with access to the statistics that tomcat provides like current threads, max threads, etc. Users belonging to this role will be able to access the Status link on the main tomcat index page but will receive a 403 - Access Denied when attempting to access the Tomcat Manager.

All four roles provide access to the status pages.  

The "admin" role has been broken down further which allows for access control to the Host-Manager application.  There are two roles, "admin-gui" and "admin-script".  Like the manager-* roles, both admin roles provide access to the status pages.  The "admin-gui" role in Tomcat 7 now provides access to the host-manager HTML console while the "admin-script" role provides access to the host-manager text interface. 

The addition of these new roles in the long run is going to make our lives easier as administrators with the only real downside being the reworking of any scripts that made use of the text interface and some time to re-do user access.  I'm very pleased that roles have been expanded in Tomcat 7. 

I would love to know what your impressions are, what your experiences have been in the past with the previous "manager" and "admin" roles, and whether you agree with me that this is a nice new addition to the Tomcat 7 feature set.


Tomcat Management: Jmx4Perl Makes it Easier

For the intermediate level application server administrator like me, "knowing" that I can manage my tomcat containers remotely using jmx is a lot different than actually writing some useful script that utilizes it.  The problem with jmx, in my opinion, is that it's a systems administration technology built into the Java Virtual Machine that is marketed to Developers, not Systems Administrators.  Monitoring and Management is probably the last thing on a developer's mind and sometimes I think that the cost in terms of time learning jmx is too high.  The payoff in portability from one job to another is probably better than it was having to learn Tcl to write BigIP iRules but probably not much higher.  Many sysadmins I've talked to have never heard of it and when they do find out what it is, the need to learn Java first is usually the first barrier that gets thrown up.  When you're supporting hundreds of servers and you use a combination of shell scripts and perl scripts most of the time to manage the entire server and not just the VM, learning Java is one of those things that would be nice to learn but who has the time?

While sifting through the keywords reports in this site's google analytics data over this long holiday weekend, I came across Jmx4Perl and I'm really glad I took the time to look it up.  Previously, I had heard about JMX4R, which required JRuby and a JVM but all that Jmx4Perl requires is Perl.  Installation via 'cpan' is probably the easiest way to do it.  Simply open up a cpan shell and then type "install JMX::Jmx4Perl" and you're all set.  

The edge that Jmx4Perl has over other JMX implementations, in my systems administrator opinion, is the inclusion of j4p, a small (approximately 92K) web application that you deploy to your app server container webapps directory, which proxies jmx requests on your behalf. This is a lot easier to deploy and protect, especially on Windows systems where securing the jmxremote.password file can be incredibly difficult. Jmx4Perl includes 'out-of-the-box' support for many popular open sourced application server containers, including JBoss, Tomcat, Jetty, and GlassFish as well as the two main commercial application server offerings WebLogic and WebSphere.

Once you have copied j4p.war to your application server's deployment directory and deployed the application, you can begin to use it. No additional firewall ports are needed—heck, you don't even need to enable JMX within your tomcat container to use it with the j4p proxy. Just keep in mind that securing it the way you would secure any web application you don't want others to be able to use would make your security guys happy.

To make things even easier, Jmx4Perl contains a list of aliases that allow you to get off and running writing some useful jmx scripts without having to learn the verbose jmx syntax for getting attributes or invoking methods on management beans, which can differ across app server platforms. For example, to get the version number of your app server on JBoss, you would get the attribute VersionNumber of the MBean jboss.system:type=Server, but on Jetty you would get attribute version from MBean org.mortbay:jetty=default. With Jmx4Perl, you simply get_attribute(SERVER_VERSION) and the correct, corresponding MBean and attribute will be utilized for whichever app server you are using. Aliases for most of the common server operations are included within Jmx4Perl but you can also use the native JMX naming syntax as well.

The sample script below provides the number of currently executing threads on my test tomcat container, to give you an idea how easy it is to begin interacting with Jmx4Perl.

#!/usr/bin/env perl 
#         FILE:  jmx4perl_test.pl
#        USAGE:  ./jmx4perl_test.pl  
#  DESCRIPTION:  Connects to a local container
#                 and displays current thread counts.
#                Demonstrates Jmx4Perl.
#      OPTIONS:  None
#         BUGS:  Probably
#        NOTES:  ---
#       AUTHOR:  Chris Mahns 
#      COMPANY:  techstacks.com
#      VERSION:  0.1
#      CREATED:  09/06/2009
#     REVISION:  ---

use strict;
use warnings;
use feature ':5.10';

use JMX::Jmx4Perl;
use JMX::Jmx4Perl::Alias;

my $jmx = JMX::Jmx4Perl->new(url => "http://localhost:8080/j4p");
my $threads = $jmx->get_attribute(THREAD_COUNT);

say "There are $threads active threads";

Running this script from the command line provides me with the current number of executing threads within my tomcat container, which is almost always asked by development on phone calls during problems. My next batch of Tomcat Management articles will look into Jmx4Perl further because this seems like such a useful module!

Other posts within this series:

  1. Tomcat Management: Setting up the Tomcat Manager Application
  2. Tomcat Management: Use Groovy to Interact with Tomcat Manager
  3. Tomcat Management: Using the JMXProxy
  4. Tomcat Management: Use the JMXProxy to Change Configuration


Tomcat Management: Use the JMXProxy to Change Configuration

After a short break to cover some interesting news over the past couple weeks and to switch templates in Blogger, this series returns with setting configuration values using the JMXProxy. Also, breaking with tradition in this series using Groovy and HTTPBuilder for the 'getting' script examples, the 'setting' portion of this series will use Ruby with the HTTParty gem. There is a fairly good reason why I'm not using Groovy and HTTPBuilder for this next batch of posts--it doesn't work! However, I do not believe that this is the fault of Groovy, HTTPBuilder, or Tomcat. Blame can solidly be placed on my limited programming skills.

One important thing to keep in mind when setting configuration values with the JMXProxy: It ain't permanent! Like the JMX-Console in JBoss, the JMXProxy allows you to Get or Set configuration details at run-time and if one were to restart tomcat, any changes that were made would be reverted back to values stored in your web.xml, server.xml, or other configuration files. So what good is it? Well, you can set logging levels at run-time to better debug a production issue or you could, in theory, create a run-time configuration that is built dynamically after startup without ever having to modify a configuration file outside of tomcat-users.xml.

The example below provides (hopefully!) a useful example meant to illustrate some basic changes that can be made to tomcat. It prints the current configuration of the http connector, then it enables HTTP compression and raises MaxThreads to 400, then reverts everything back pausing after each step so that you can witness the changes. For simplicity, I've set a basic tomcat manager UID and Password to "tomcat".

#!/usr/bin/env ruby

require 'rubygems'
require 'httparty'

class JMXProxy
 include HTTParty
 format :html
 basic_auth 'tomcat', 'tomcat'

puts JMXProxy.get('http://localhost:8080/manager/jmxproxy/?qry=Catalina:type=Connector,port=8080')
puts 'Pausing 10 seconds - Changing Settings'

puts JMXProxy.get('http://localhost:8080/manager/jmxproxy/?set=Catalina:type=Connector,port=8080&att=compression&val=on')
puts JMXProxy.get('http://localhost:8080/manager/jmxproxy/?set=Catalina:type=Connector,port=8080&att=maxThreads&val=400')
puts JMXProxy.get('http://localhost:8080/manager/jmxproxy/?qry=Catalina:type=Connector,port=8080')
puts "Check it out! Resetting changes in 10 seconds..."

puts JMXProxy.get('http://localhost:8080/manager/jmxproxy/?set=Catalina:type=Connector,port=8080&att=compression&val=off')
puts JMXProxy.get('http://localhost:8080/manager/jmxproxy/?set=Catalina:type=Connector,port=8080&att=maxThreads&val=40')
puts JMXProxy.get('http://localhost:8080/manager/jmxproxy/?qry=Catalina:type=Connector,port=8080')