---
title: Tomcat
description: >-
  Track requests per second, bytes served, cache hits, servlet metrics, and
  more.
breadcrumbs: Docs > Integrations > Tomcat
---

# Tomcat
Supported OS Integration version4.2.0


## Overview{% #overview %}

This check collects Tomcat metrics, for example:

- Overall activity metrics: error count, request count, processing times, etc.
- Thread pool metrics: thread count, number of threads busy, etc.
- Servlet processing times

**Minimum Agent version:** 6.0.0

## Setup{% #setup %}

### Installation{% #installation %}

The Tomcat check is included in the [Datadog Agent](https://app.datadoghq.com/account/settings/agent/latest) package, so you don't need to install anything else on your Tomcat servers.

This check is JMX-based, so you need to enable JMX Remote on your Tomcat servers. Follow the instructions in [Monitoring and Managing Tomcat](https://tomcat.apache.org/tomcat-10.1-doc/monitoring.html).

### Configuration{% #configuration %}

{% tab title="Host" %}
#### Host{% #host %}

To configure this check for an Agent running on a host:

1. Edit the `tomcat.d/conf.yaml` file, in the `conf.d/` folder at the root of your [Agent's configuration directory](https://docs.datadoghq.com/agent/guide/agent-configuration-files/#agent-configuration-directory) to collect Tomcat metrics and logs. See the [sample tomcat.d/conf.yaml](https://github.com/DataDog/integrations-core/blob/master/tomcat/datadog_checks/tomcat/data/conf.yaml.example) for all available configuration options.

1. [Restart the Agent](https://docs.datadoghq.com/agent/guide/agent-commands/#start-stop-and-restart-the-agent).

See the [JMX Check documentation](https://docs.datadoghq.com/integrations/java/) for a list of configuration options usable by all JMX-based checks.

#### List of metrics{% #list-of-metrics %}

The `conf` parameter is a list of metrics to be collected by the integration. Only two keys are allowed:

- `include` (**mandatory**): A dictionary of filters. Any attribute that matches these filters is collected unless it also matches the `exclude` filters (see below).
- `exclude` (**optional**): A dictionary of filters. Attributes that match these filters are not collected.

For a given bean, metrics get tagged in the following manner:

```text
mydomain:attr0=val0,attr1=val1
```

In this example, your metric is `mydomain` (or some variation depending on the attribute inside the bean) and has the tags `attr0:val0`, `attr1:val1`, and `domain:mydomain`.

If you specify an alias in an `include` key that is formatted as *camel case*, it is converted to *snake case*. For example, `MyMetricName` is shown in Datadog as `my_metric_name`.

##### The attribute filter{% #the-attribute-filter %}

The `attribute` filter can accept two types of values:

- A dictionary whose keys are attributes names (see below). For this case, you can specify an alias for the metric that becomes the metric name in Datadog. You can also specify the metric type as a gauge or counter. If you choose counter, a rate per second is computed for the metric.

  ```yaml
  conf:
    - include:
      attribute:
        maxThreads:
          alias: tomcat.threads.max
          metric_type: gauge
        currentThreadCount:
          alias: tomcat.threads.count
          metric_type: gauge
        bytesReceived:
          alias: tomcat.bytes_rcvd
          metric_type: counter
  ```

- A list of attributes names (see below). For this case, the metric type is a gauge, and the metric name is `jmx.\[DOMAIN_NAME].\[ATTRIBUTE_NAME]`.

  ```yaml
  conf:
    - include:
      domain: org.apache.cassandra.db
      attribute:
        - BloomFilterDiskSpaceUsed
        - BloomFilterFalsePositives
        - BloomFilterFalseRatio
        - Capacity
        - CompressionRatio
        - CompletedTasks
        - ExceptionCount
        - Hits
        - RecentHitRate
  ```

#### Log collection{% #log-collection %}

1. To submit logs to Datadog, Tomcat uses the `log4j` logger. For versions of Tomcat before 8.0, `log4j` is configured by default. For Tomcat 8.0+, you must configure Tomcat to use `log4j`, see [Using Log4j](https://tomcat.apache.org/tomcat-8.0-doc/logging.html#Using_Log4j). In the first step of those instructions, edit the `log4j.properties` file in the `$CATALINA_BASE/lib` directory as follows:

   ```gdscript3
     log4j.rootLogger = INFO, CATALINA
   
     # Define all the appenders
     log4j.appender.CATALINA = org.apache.log4j.DailyRollingFileAppender
     log4j.appender.CATALINA.File = /var/log/tomcat/catalina.log
     log4j.appender.CATALINA.Append = true
   
     # Roll-over the log once per day
     log4j.appender.CATALINA.layout = org.apache.log4j.PatternLayout
     log4j.appender.CATALINA.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %-5p [%t] %c{1}:%L - %m%n
   
     log4j.appender.LOCALHOST = org.apache.log4j.DailyRollingFileAppender
     log4j.appender.LOCALHOST.File = /var/log/tomcat/localhost.log
     log4j.appender.LOCALHOST.Append = true
     log4j.appender.LOCALHOST.layout = org.apache.log4j.PatternLayout
     log4j.appender.LOCALHOST.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %-5p [%t] %c{1}:%L - %m%n
   
     log4j.appender.MANAGER = org.apache.log4j.DailyRollingFileAppender
     log4j.appender.MANAGER.File = /var/log/tomcat/manager.log
     log4j.appender.MANAGER.Append = true
     log4j.appender.MANAGER.layout = org.apache.log4j.PatternLayout
     log4j.appender.MANAGER.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %-5p [%t] %c{1}:%L - %m%n
   
     log4j.appender.HOST-MANAGER = org.apache.log4j.DailyRollingFileAppender
     log4j.appender.HOST-MANAGER.File = /var/log/tomcat/host-manager.log
     log4j.appender.HOST-MANAGER.Append = true
     log4j.appender.HOST-MANAGER.layout = org.apache.log4j.PatternLayout
     log4j.appender.HOST-MANAGER.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %-5p [%t] %c{1}:%L - %m%n
   
     log4j.appender.CONSOLE = org.apache.log4j.ConsoleAppender
     log4j.appender.CONSOLE.layout = org.apache.log4j.PatternLayout
     log4j.appender.CONSOLE.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %-5p [%t] %c{1}:%L - %m%n
   
     # Configure which loggers log to which appenders
     log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost] = INFO, LOCALHOST
     log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager] =\
       INFO, MANAGER
     log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager] =\
       INFO, HOST-MANAGER
   ```

Then follow the remaining steps in [the Tomcat docs](https://tomcat.apache.org/tomcat-8.0-doc/logging.html#Using_Log4j) for configuring `log4j`.

1. By default, Datadog's integration pipeline support the following conversion patterns:

   ```text
     %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
     %d [%t] %-5p %c - %m%n
   ```

Clone and edit the [integration pipeline](https://docs.datadoghq.com/logs/processing/#integration-pipelines) if you have a different format. See [Logging in Tomcat](https://tomcat.apache.org/tomcat-7.0-doc/logging.html) for details on Tomcat logging capabilities.

1. Collecting logs is disabled by default in the Datadog Agent, enable it in your `datadog.yaml` file:

   ```yaml
   logs_enabled: true
   ```

1. Add this configuration block to your `tomcat.d/conf.yaml` file to start collecting your Tomcat Logs:

   ```yaml
   logs:
     - type: file
       path: /var/log/tomcat/*.log
       source: tomcat
       service: "<SERVICE>"
       #To handle multi line that starts with yyyy-mm-dd use the following pattern
       #log_processing_rules:
       #  - type: multi_line
       #    name: log_start_with_date
       #    pattern: \d{4}\-(0?[1-9]|1[012])\-(0?[1-9]|[12][0-9]|3[01])
   ```

Change the `path` and `service` parameter values and configure them for your environment. See the [sample tomcat.yaml](https://github.com/DataDog/integrations-core/blob/master/tomcat/datadog_checks/tomcat/data/conf.yaml.example) for all available configuration options.

1. [Restart the Agent](https://docs.datadoghq.com/agent/guide/agent-commands/#start-stop-and-restart-the-agent).

{% /tab %}

{% tab title="Containerized" %}
#### Containerized{% #containerized %}

For containerized environments, see the [Autodiscovery with JMX](https://docs.datadoghq.com/agent/guide/autodiscovery-with-jmx/?tab=containerizedagent) guide.
{% /tab %}

### Validation{% #validation %}

[Run the Agent's status subcommand](https://docs.datadoghq.com/agent/guide/agent-commands/#agent-status-and-information) and look for `tomcat` under the **Checks** section.

## Data Collected{% #data-collected %}

### Metrics{% #metrics %}

|  |
|  |
| **tomcat.bytes\_rcvd**(gauge)                       | Bytes per second received by all request processors.*Shown as byte*                                                     |
| **tomcat.bytes\_sent**(gauge)                       | Bytes per second sent by all the request processors.*Shown as byte*                                                     |
| **tomcat.error\_count**(gauge)                      | The number of errors per second on all request processors.*Shown as error*                                              |
| **tomcat.jdbc.connection\_pool.active**(gauge)      | The number of established connections in the pool that are in use.                                                      |
| **tomcat.jdbc.connection\_pool.idle**(gauge)        | The number of established connections in the pool that are idle.                                                        |
| **tomcat.jdbc.connection\_pool.max\_active**(gauge) | The maximum number of open connections.                                                                                 |
| **tomcat.jdbc.connection\_pool.max\_idle**(gauge)   | The maximum number of idle connections.                                                                                 |
| **tomcat.jdbc.connection\_pool.min\_idle**(gauge)   | The minimum number of idle connections.                                                                                 |
| **tomcat.jdbc.connection\_pool.size**(gauge)        | The number of established connections in the pool, idle and in use.                                                     |
| **tomcat.jsp.count**(gauge)                         | The number of JSPs per second that have been loaded in the web module.*Shown as page*                                   |
| **tomcat.jsp.reload\_count**(gauge)                 | The number of JSPs per second that have been reloaded in the web module.*Shown as page*                                 |
| **tomcat.max\_time**(gauge)                         | The longest request processing time (in milliseconds).*Shown as millisecond*                                            |
| **tomcat.min\_time**(gauge)                         | The shortest request processing time (in milliseconds).*Shown as millisecond*                                           |
| **tomcat.processing\_time**(gauge)                  | The sum of request processing times across all requests handled by the request processors (in milliseconds) per second. |
| **tomcat.request\_count**(gauge)                    | The number of requests per second across all request processors.*Shown as request*                                      |
| **tomcat.servlet.error\_count**(gauge)              | The number of erroneous requests received by the servlet per second.*Shown as error*                                    |
| **tomcat.servlet.max\_time**(gauge)                 | The maximum processing time of a request*Shown as millisecond*                                                          |
| **tomcat.servlet.min\_time**(gauge)                 | The minimum processing time of a request*Shown as millisecond*                                                          |
| **tomcat.servlet.processing\_time**(gauge)          | The sum of request processing times across all requests to the servlet (in milliseconds) per second.                    |
| **tomcat.servlet.request\_count**(gauge)            | The number of requests received by the servlet per second.*Shown as request*                                            |
| **tomcat.string\_cache.access\_count**(gauge)       | The number of accesses to the string cache per second.*Shown as get*                                                    |
| **tomcat.string\_cache.cache\_size**(gauge)         | The size of the String cache*Shown as byte*                                                                             |
| **tomcat.string\_cache.hit\_count**(gauge)          | The number of string cache hits per second.*Shown as hit*                                                               |
| **tomcat.string\_cache.max\_size**(gauge)           | The maximum size of the String cache*Shown as byte*                                                                     |
| **tomcat.threads.busy**(gauge)                      | The number of threads that are in use.*Shown as thread*                                                                 |
| **tomcat.threads.count**(gauge)                     | The number of threads managed by the thread pool.*Shown as thread*                                                      |
| **tomcat.threads.max**(gauge)                       | The maximum number of allowed worker threads.*Shown as thread*                                                          |
| **tomcat.threads.min**(gauge)                       | The minimum number of allowed worker threads.*Shown as thread*                                                          |
| **tomcat.web.cache.hit\_count**(gauge)              | The number of web resource cache hits per second.*Shown as hit*                                                         |
| **tomcat.web.cache.lookup\_count**(gauge)           | The number of lookups to the web resource cache per second.*Shown as get*                                               |

### Events{% #events %}

The Tomcat check does not include any events.

### Service Checks{% #service-checks %}

**tomcat.can\_connect**

Returns `CRITICAL` if the Agent is unable to connect to and collect metrics from the monitored Tomcat instance, `WARNING` if no metrics are collected, and `OK` otherwise.

*Statuses: ok, critical, warning*

## Troubleshooting{% #troubleshooting %}

### Missing `tomcat.*` metrics{% #missing-tomcat-metrics %}

The Datadog Agent collects JMX metrics with either `Catalina` or `Tomcat` as bean domain names with the Datadog Agent version **7.49.0** or later. Older versions only collect metrics with `Catalina` as the bean domain name. Standalone Tomcat deployments have metrics under domain `Catalina`, but embedded Tomcat deployments (such as with Spring Boot) have metrics under domain `Tomcat`.

If the Datadog Agent version is older than **7.49.0**, and if the exposed Tomcat metrics are prefixed with a different bean domain name such as `Tomcat`, copy the default metrics from the `metrics.yaml` file to the `conf` section of the `tomcat.d/conf.yaml` file and modify the `domain` filter to use the applicable bean domain name.

```yaml
- include:
    domain: Tomcat
    type: ThreadPool
    attribute:
      maxThreads:
        alias: tomcat.threads.max
        metric_type: gauge
      currentThreadCount:
        alias: tomcat.threads.count
        metric_type: gauge
      currentThreadsBusy:
        alias: tomcat.threads.busy
        metric_type: gauge
```

See the [JMX Check documentation](https://docs.datadoghq.com/integrations/java/) for more detailed information.

### Commands to view the available metrics{% #commands-to-view-the-available-metrics %}

The `datadog-agent jmx` command allows you to run troubleshooting commands on JMXFetch integrations. On Linux systems, you will need to prepend the command with `sudo -u dd-agent` so that the Datadog Agent runs as the correct user.

#### datadog-agent jmx collect{% #datadog-agent-jmx-collect %}

Running `datadog-agent jmx collect` starts the collection of metrics based on your current configuration and displays them in the console.

#### datadog-agent jmx list{% #datadog-agent-jmx-list %}

The `datadog-agent jmx list` has a number of available subcommands:

- `collected` - List attributes that will actually be collected by your current instance's configuration.
- `everything` - List every attribute available that has a type supported by JMXFetch.
- `limited` - List attributes that match one of your instances' configurations but that are not being collected because it would exceed the number of metrics that can be collected.
- `matching` - List attributes that match at least one of your instances' configurations.
- `not-matching` - List attributes that don't match any of your instances' configurations.
- `with-metrics` - List attributes and metrics data that match at least one of your instances' configurations.
- `with-rate-metrics` - List attributes and metrics data that match at least one of your instances' configurations, including rates and counters.

## Further Reading{% #further-reading %}

- [Monitor Tomcat metrics with Datadog](https://www.datadoghq.com/blog/monitor-tomcat-metrics)
- [Understanding the Tomcat architecture and key performance metrics](https://www.datadoghq.com/blog/tomcat-architecture-and-performance)
- [Analyzing Tomcat logs and metrics with Datadog](https://www.datadoghq.com/blog/analyzing-tomcat-logs-and-metrics-with-datadog)
