SpitfireLoad Testing & Observabilityv1.4.9 · What's new

Version: 1.4.9This documentation is for Spitfire 1.4.9.

Infrastructure — Java application servers (Beta)

For Tomcat, WildFly, WebLogic, WebSphere Liberty and any JVM (Spring Boot etc.) Spitfire reads heap, GC, threads, requests, the thread pool, the JDBC pool and sessions. Each server is one monitored system; one monitored system can take several addresses, comma separated (app1:9404,app2:9404).

Tomcat

Quick install

  1. Run it on the Tomcat server and answer the questions.
    bash
    curl -fsSL "https://<spitfire>/api/v1/setup/ds/tomcat.sh?t=<token>&lang=en" -o /tmp/sf-tomcat.sh && bash /tmp/sf-tomcat.sh
  2. When you see OK: ..., you are done.
Note

The script puts the javaagent and its rules file in /opt/spitfire/jmx, adds one line to bin/setenv.sh (backed up to setenv.sh.spitfire.bak first) and asks before restarting Tomcat. The exporter only reads JMX. In the product this line comes ready, with the address and a fresh token.

Manual install

  1. Download the javaagent.
    bash
    sudo mkdir -p /opt/spitfire/jmx && sudo curl -fsSL -o /opt/spitfire/jmx/jmx_prometheus_javaagent.jar https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/1.0.1/jmx_prometheus_javaagent-1.0.1.jar
  2. Write the rules file.
    bash
    sudo tee /opt/spitfire/jmx/spitfire-tomcat.yml >/dev/null <<'SPITFIRE_YML'
    # Spitfire tomcat: Prometheus JMX exporter javaagent 1.0.1 rules (read-only).
    lowercaseOutputName: false
    includeObjectNames:
      - "java.lang:type=Memory"
      - "java.lang:type=GarbageCollector,*"
      - "java.lang:type=Threading"
      - "java.lang:type=ClassLoading"
      - "java.lang:type=OperatingSystem"
      - "Catalina:type=GlobalRequestProcessor,*"
      - "Catalina:type=ThreadPool,*"
      - "Catalina:type=Manager,*"
      - "Catalina:type=DataSource,*"
      - "Tomcat:type=GlobalRequestProcessor,*"
      - "Tomcat:type=ThreadPool,*"
      - "Tomcat:type=Manager,*"
      - "Tomcat:type=DataSource,*"
      - "com.zaxxer.hikari:*"
    rules:
      - pattern: 'java.lang<type=Memory><HeapMemoryUsage>used'
        name: java_heap_used_bytes
        type: GAUGE
      - pattern: 'java.lang<type=Memory><HeapMemoryUsage>max'
        name: java_heap_max_bytes
        type: GAUGE
      - pattern: 'java.lang<type=Memory><NonHeapMemoryUsage>used'
        name: java_nonheap_used_bytes
        type: GAUGE
      - pattern: 'java.lang<type=Memory><NonHeapMemoryUsage>max'
        name: java_nonheap_max_bytes
        type: GAUGE
      - pattern: 'java.lang<(?=(?:[^>]*, )?type=GarbageCollector[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>CollectionCount'
        name: java_gc_count
        type: GAUGE
        labels:
          name: "$1"
      - pattern: 'java.lang<(?=(?:[^>]*, )?type=GarbageCollector[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>CollectionTime'
        name: java_gc_seconds
        type: GAUGE
        valueFactor: 0.001
        labels:
          name: "$1"
      - pattern: 'java.lang<type=Threading><>ThreadCount'
        name: java_threads_live
        type: GAUGE
      - pattern: 'java.lang<type=Threading><>DaemonThreadCount'
        name: java_threads_daemon
        type: GAUGE
      - pattern: 'java.lang<type=ClassLoading><>LoadedClassCount'
        name: java_classes_loaded
        type: GAUGE
      - pattern: 'java.lang<type=OperatingSystem><>ProcessCpuLoad'
        name: java_cpu_load
        type: GAUGE
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=GlobalRequestProcessor[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>requestCount'
        name: java_requests
        type: GAUGE
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=GlobalRequestProcessor[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>errorCount'
        name: java_request_errors
        type: GAUGE
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=GlobalRequestProcessor[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>processingTime'
        name: java_request_seconds
        type: GAUGE
        valueFactor: 0.001
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=ThreadPool[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>currentThreadsBusy'
        name: java_threadpool_busy
        type: GAUGE
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=ThreadPool[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>maxThreads'
        name: java_threadpool_max
        type: GAUGE
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=ThreadPool[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>currentThreadCount'
        name: java_threadpool_size
        type: GAUGE
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=Manager[,>])(?=(?:[^>]*, )?context="?([^",>]+)"?[,>])(?=(?:[^>]*, )?host="?([^",>]+)"?[,>])[^>]*><>activeSessions'
        name: java_sessions_active
        type: GAUGE
        labels:
          context: "$1"
          host: "$2"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=DataSource[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>numActive'
        name: java_jdbc_active
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=DataSource[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>numIdle'
        name: java_jdbc_idle
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=DataSource[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>(?:maxTotal|maxActive)'
        name: java_jdbc_max
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=DataSource[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>waitCount'
        name: java_jdbc_waiting
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.zaxxer.hikari<type=Pool \(([^)]+)\)><>ActiveConnections'
        name: java_jdbc_active
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.zaxxer.hikari<type=Pool \(([^)]+)\)><>IdleConnections'
        name: java_jdbc_idle
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.zaxxer.hikari<type=Pool \(([^)]+)\)><>TotalConnections'
        name: java_jdbc_size
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.zaxxer.hikari<type=Pool \(([^)]+)\)><>ThreadsAwaitingConnection'
        name: java_jdbc_waiting
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.zaxxer.hikari<type=PoolConfig \(([^)]+)\)><>MaximumPoolSize'
        name: java_jdbc_max
        type: GAUGE
        labels:
          datasource: "$1"
    SPITFIRE_YML
  3. Add the JVM option to setenv.sh.
    bash
    grep -q jmx_prometheus_javaagent /opt/tomcat/bin/setenv.sh 2>/dev/null || echo 'CATALINA_OPTS="$CATALINA_OPTS -javaagent:/opt/spitfire/jmx/jmx_prometheus_javaagent.jar=9404:/opt/spitfire/jmx/spitfire-tomcat.yml"' | sudo tee -a /opt/tomcat/bin/setenv.sh
  4. Restart Tomcat.
    bash
    sudo systemctl restart tomcat
  5. Add the monitored system: Infrastructure sources → Tomcat, address <host>:9404.
  6. Check the exporter.
    bash
    curl -fsS http://localhost:9404/metrics | grep -q java_heap_used_bytes && echo "OK: tomcat"

Windows (PowerShell)

  1. Open PowerShell as Administrator and run it.
    powershell
    Invoke-WebRequest -UseBasicParsing -Uri "https://<spitfire>/api/v1/setup/ds/tomcat.ps1?t=<token>&lang=en" -OutFile "$env:TEMP\sf-tomcat.ps1"; powershell -NoProfile -ExecutionPolicy Bypass -File "$env:TEMP\sf-tomcat.ps1"
  2. When you see OK: ..., you are done.

Manual install (Windows):

  1. Download the javaagent.
    powershell
    New-Item -ItemType Directory -Force C:\spitfire\jmx | Out-Null; Invoke-WebRequest -UseBasicParsing -Uri https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/1.0.1/jmx_prometheus_javaagent-1.0.1.jar -OutFile C:\spitfire\jmx\jmx_prometheus_javaagent.jar
  2. Write the rules file.
    powershell
    $Rules = @'
    # Spitfire tomcat: Prometheus JMX exporter javaagent 1.0.1 rules (read-only).
    lowercaseOutputName: false
    includeObjectNames:
      - "java.lang:type=Memory"
      - "java.lang:type=GarbageCollector,*"
      - "java.lang:type=Threading"
      - "java.lang:type=ClassLoading"
      - "java.lang:type=OperatingSystem"
      - "Catalina:type=GlobalRequestProcessor,*"
      - "Catalina:type=ThreadPool,*"
      - "Catalina:type=Manager,*"
      - "Catalina:type=DataSource,*"
      - "Tomcat:type=GlobalRequestProcessor,*"
      - "Tomcat:type=ThreadPool,*"
      - "Tomcat:type=Manager,*"
      - "Tomcat:type=DataSource,*"
      - "com.zaxxer.hikari:*"
    rules:
      - pattern: 'java.lang<type=Memory><HeapMemoryUsage>used'
        name: java_heap_used_bytes
        type: GAUGE
      - pattern: 'java.lang<type=Memory><HeapMemoryUsage>max'
        name: java_heap_max_bytes
        type: GAUGE
      - pattern: 'java.lang<type=Memory><NonHeapMemoryUsage>used'
        name: java_nonheap_used_bytes
        type: GAUGE
      - pattern: 'java.lang<type=Memory><NonHeapMemoryUsage>max'
        name: java_nonheap_max_bytes
        type: GAUGE
      - pattern: 'java.lang<(?=(?:[^>]*, )?type=GarbageCollector[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>CollectionCount'
        name: java_gc_count
        type: GAUGE
        labels:
          name: "$1"
      - pattern: 'java.lang<(?=(?:[^>]*, )?type=GarbageCollector[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>CollectionTime'
        name: java_gc_seconds
        type: GAUGE
        valueFactor: 0.001
        labels:
          name: "$1"
      - pattern: 'java.lang<type=Threading><>ThreadCount'
        name: java_threads_live
        type: GAUGE
      - pattern: 'java.lang<type=Threading><>DaemonThreadCount'
        name: java_threads_daemon
        type: GAUGE
      - pattern: 'java.lang<type=ClassLoading><>LoadedClassCount'
        name: java_classes_loaded
        type: GAUGE
      - pattern: 'java.lang<type=OperatingSystem><>ProcessCpuLoad'
        name: java_cpu_load
        type: GAUGE
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=GlobalRequestProcessor[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>requestCount'
        name: java_requests
        type: GAUGE
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=GlobalRequestProcessor[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>errorCount'
        name: java_request_errors
        type: GAUGE
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=GlobalRequestProcessor[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>processingTime'
        name: java_request_seconds
        type: GAUGE
        valueFactor: 0.001
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=ThreadPool[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>currentThreadsBusy'
        name: java_threadpool_busy
        type: GAUGE
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=ThreadPool[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>maxThreads'
        name: java_threadpool_max
        type: GAUGE
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=ThreadPool[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>currentThreadCount'
        name: java_threadpool_size
        type: GAUGE
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=Manager[,>])(?=(?:[^>]*, )?context="?([^",>]+)"?[,>])(?=(?:[^>]*, )?host="?([^",>]+)"?[,>])[^>]*><>activeSessions'
        name: java_sessions_active
        type: GAUGE
        labels:
          context: "$1"
          host: "$2"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=DataSource[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>numActive'
        name: java_jdbc_active
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=DataSource[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>numIdle'
        name: java_jdbc_idle
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=DataSource[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>(?:maxTotal|maxActive)'
        name: java_jdbc_max
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=DataSource[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>waitCount'
        name: java_jdbc_waiting
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.zaxxer.hikari<type=Pool \(([^)]+)\)><>ActiveConnections'
        name: java_jdbc_active
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.zaxxer.hikari<type=Pool \(([^)]+)\)><>IdleConnections'
        name: java_jdbc_idle
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.zaxxer.hikari<type=Pool \(([^)]+)\)><>TotalConnections'
        name: java_jdbc_size
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.zaxxer.hikari<type=Pool \(([^)]+)\)><>ThreadsAwaitingConnection'
        name: java_jdbc_waiting
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.zaxxer.hikari<type=PoolConfig \(([^)]+)\)><>MaximumPoolSize'
        name: java_jdbc_max
        type: GAUGE
        labels:
          datasource: "$1"
    '@
    [IO.File]::WriteAllText('C:\spitfire\jmx\spitfire-tomcat.yml', $Rules + "`n")
  3. Add the JVM option to the Tomcat service (service name Tomcat10).
    powershell
    & "C:\Program Files\Apache Software Foundation\Tomcat 10.1\bin\tomcat10.exe" //US//Tomcat10 ++JvmOptions "-javaagent:C:\spitfire\jmx\jmx_prometheus_javaagent.jar=9404:C:\spitfire\jmx\spitfire-tomcat.yml"
  4. Restart the service.
    powershell
    Restart-Service Tomcat10
  5. Check the exporter.
    powershell
    if ((Invoke-WebRequest -UseBasicParsing http://localhost:9404/metrics).Content -match 'java_heap_used_bytes') { 'OK: tomcat' }

WildFly

Quick install

  1. Run it on the WildFly server, as the user that runs WildFly.
    bash
    curl -fsSL "https://<spitfire>/api/v1/setup/ds/wildfly.sh?t=<token>&lang=en" -o /tmp/sf-wildfly.sh && bash /tmp/sf-wildfly.sh
  2. When you see OK: ..., you are done.
Note

WildFly already serves /metrics on its management port (9990); no javaagent is needed. The script turns on the Undertow and data source statistics and asks before the reload. When the Tower is on another machine it also offers to bind the management interface to 0.0.0.0; allow 9990 only to the Tower. Undertow's error count counts 5xx responses only.

Manual install

  1. Turn on the Undertow statistics.
    bash
    /opt/wildfly/bin/jboss-cli.sh --connect --command='/subsystem=undertow:write-attribute(name=statistics-enabled,value=true)'
  2. Turn on the data source statistics (your own data source instead of ExampleDS).
    bash
    /opt/wildfly/bin/jboss-cli.sh --connect --command='/subsystem=datasources/data-source=ExampleDS:write-attribute(name=statistics-enabled,value=true)'
  3. Reload.
    bash
    /opt/wildfly/bin/jboss-cli.sh --connect --command=':reload'
  4. Add the monitored system: Infrastructure sources → WildFly, address <host>:9990.
  5. Check /metrics.
    bash
    curl -fsS http://localhost:9990/metrics | grep -q base_memory_usedHeap_bytes && echo "OK: wildfly"

WebLogic

Beta: tested only against emulated WebLogic MBeans, not on a real WebLogic.

Quick install

  1. Run it on the WebLogic server, once per server (AdminServer, managed servers).
    bash
    curl -fsSL "https://<spitfire>/api/v1/setup/ds/weblogic.sh?t=<token>&lang=en" -o /tmp/sf-weblogic.sh && bash /tmp/sf-weblogic.sh
  2. When you see OK: ..., you are done.
Note

The exporter reads the com.bea runtime MBeans from the platform MBean server ("Platform MBean Server Used" must be on in the domain, the default since 10.3.3). No user or password is asked. Give each server on one machine its own exporter port (9404, 9405…).

Manual install

  1. Download the javaagent.
    bash
    sudo mkdir -p /opt/spitfire/jmx && sudo curl -fsSL -o /opt/spitfire/jmx/jmx_prometheus_javaagent.jar https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/1.0.1/jmx_prometheus_javaagent-1.0.1.jar
  2. Write the rules file.
    bash
    sudo tee /opt/spitfire/jmx/spitfire-weblogic.yml >/dev/null <<'SPITFIRE_YML'
    # Spitfire weblogic: Prometheus JMX exporter javaagent 1.0.1 rules (read-only).
    lowercaseOutputName: false
    includeObjectNames:
      - "java.lang:type=Memory"
      - "java.lang:type=GarbageCollector,*"
      - "java.lang:type=Threading"
      - "java.lang:type=ClassLoading"
      - "java.lang:type=OperatingSystem"
      - "com.bea:Type=ServerRuntime,*"
      - "com.bea:Type=ThreadPoolRuntime,*"
      - "com.bea:Type=JDBCDataSourceRuntime,*"
      - "com.bea:Type=JMSDestinationRuntime,*"
      - "com.bea:Type=WebAppComponentRuntime,*"
    rules:
      - pattern: 'java.lang<type=Memory><HeapMemoryUsage>used'
        name: java_heap_used_bytes
        type: GAUGE
      - pattern: 'java.lang<type=Memory><HeapMemoryUsage>max'
        name: java_heap_max_bytes
        type: GAUGE
      - pattern: 'java.lang<type=Memory><NonHeapMemoryUsage>used'
        name: java_nonheap_used_bytes
        type: GAUGE
      - pattern: 'java.lang<type=Memory><NonHeapMemoryUsage>max'
        name: java_nonheap_max_bytes
        type: GAUGE
      - pattern: 'java.lang<(?=(?:[^>]*, )?type=GarbageCollector[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>CollectionCount'
        name: java_gc_count
        type: GAUGE
        labels:
          name: "$1"
      - pattern: 'java.lang<(?=(?:[^>]*, )?type=GarbageCollector[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>CollectionTime'
        name: java_gc_seconds
        type: GAUGE
        valueFactor: 0.001
        labels:
          name: "$1"
      - pattern: 'java.lang<type=Threading><>ThreadCount'
        name: java_threads_live
        type: GAUGE
      - pattern: 'java.lang<type=Threading><>DaemonThreadCount'
        name: java_threads_daemon
        type: GAUGE
      - pattern: 'java.lang<type=ClassLoading><>LoadedClassCount'
        name: java_classes_loaded
        type: GAUGE
      - pattern: 'java.lang<type=OperatingSystem><>ProcessCpuLoad'
        name: java_cpu_load
        type: GAUGE
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ServerRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>StateVal'
        name: java_server_state
        type: GAUGE
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ServerRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>State: RUNNING'
        name: java_server_running
        type: GAUGE
        value: 1
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ServerRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>State: '
        name: java_server_running
        type: GAUGE
        value: 0
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ThreadPoolRuntime[,>])(?=(?:[^>]*, )?ServerRuntime="?([^",>]+)"?[,>])[^>]*><>StuckThreadCount'
        name: java_stuck_threads
        type: GAUGE
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ThreadPoolRuntime[,>])(?=(?:[^>]*, )?ServerRuntime="?([^",>]+)"?[,>])[^>]*><>HoggingThreadCount'
        name: java_hogging_threads
        type: GAUGE
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ThreadPoolRuntime[,>])(?=(?:[^>]*, )?ServerRuntime="?([^",>]+)"?[,>])[^>]*><>PendingUserRequestCount'
        name: java_requests_pending
        type: GAUGE
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ThreadPoolRuntime[,>])(?=(?:[^>]*, )?ServerRuntime="?([^",>]+)"?[,>])[^>]*><>CompletedRequestCount'
        name: java_requests
        type: GAUGE
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ThreadPoolRuntime[,>])(?=(?:[^>]*, )?ServerRuntime="?([^",>]+)"?[,>])[^>]*><>ExecuteThreadTotalCount'
        name: java_threadpool_size
        type: GAUGE
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ThreadPoolRuntime[,>])(?=(?:[^>]*, )?ServerRuntime="?([^",>]+)"?[,>])[^>]*><>ExecuteThreadIdleCount'
        name: java_threadpool_idle
        type: GAUGE
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=JDBCDataSourceRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>ActiveConnectionsCurrentCount'
        name: java_jdbc_active
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=JDBCDataSourceRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>NumAvailable'
        name: java_jdbc_idle
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=JDBCDataSourceRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>CurrCapacity'
        name: java_jdbc_size
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=JDBCDataSourceRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>WaitingForConnectionCurrentCount'
        name: java_jdbc_waiting
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=JMSDestinationRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>MessagesCurrentCount'
        name: java_jms_messages
        type: GAUGE
        labels:
          destination: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=JMSDestinationRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>MessagesPendingCount'
        name: java_jms_pending
        type: GAUGE
        labels:
          destination: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=WebAppComponentRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>OpenSessionsCurrentCount'
        name: java_sessions_active
        type: GAUGE
        labels:
          app: "$1"
    SPITFIRE_YML
  3. Add the JVM option for AdminServer to setUserOverrides.sh.
    bash
    grep -q "spitfire AdminServer" /u01/oracle/user_projects/domains/base_domain/bin/setUserOverrides.sh 2>/dev/null || echo 'if [ "${SERVER_NAME:-}" = "AdminServer" ]; then JAVA_OPTIONS="$JAVA_OPTIONS -javaagent:/opt/spitfire/jmx/jmx_prometheus_javaagent.jar=9404:/opt/spitfire/jmx/spitfire-weblogic.yml"; fi # spitfire AdminServer' >> /u01/oracle/user_projects/domains/base_domain/bin/setUserOverrides.sh
  4. Restart AdminServer.
    bash
    /u01/oracle/user_projects/domains/base_domain/bin/stopWebLogic.sh; nohup /u01/oracle/user_projects/domains/base_domain/bin/startWebLogic.sh >/dev/null 2>&1 &
  5. Add the monitored system: Infrastructure sources → WebLogic, address <host>:9404.
  6. Check the exporter.
    bash
    curl -fsS http://localhost:9404/metrics | grep -q java_server_state && echo "OK: weblogic"

Windows (PowerShell)

  1. Open PowerShell as Administrator and run it.
    powershell
    Invoke-WebRequest -UseBasicParsing -Uri "https://<spitfire>/api/v1/setup/ds/weblogic.ps1?t=<token>&lang=en" -OutFile "$env:TEMP\sf-weblogic.ps1"; powershell -NoProfile -ExecutionPolicy Bypass -File "$env:TEMP\sf-weblogic.ps1"
  2. When you see OK: ..., you are done.

Manual install (Windows):

  1. Download the javaagent.
    powershell
    New-Item -ItemType Directory -Force C:\spitfire\jmx | Out-Null; Invoke-WebRequest -UseBasicParsing -Uri https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/1.0.1/jmx_prometheus_javaagent-1.0.1.jar -OutFile C:\spitfire\jmx\jmx_prometheus_javaagent.jar
  2. Write the rules file.
    powershell
    $Rules = @'
    # Spitfire weblogic: Prometheus JMX exporter javaagent 1.0.1 rules (read-only).
    lowercaseOutputName: false
    includeObjectNames:
      - "java.lang:type=Memory"
      - "java.lang:type=GarbageCollector,*"
      - "java.lang:type=Threading"
      - "java.lang:type=ClassLoading"
      - "java.lang:type=OperatingSystem"
      - "com.bea:Type=ServerRuntime,*"
      - "com.bea:Type=ThreadPoolRuntime,*"
      - "com.bea:Type=JDBCDataSourceRuntime,*"
      - "com.bea:Type=JMSDestinationRuntime,*"
      - "com.bea:Type=WebAppComponentRuntime,*"
    rules:
      - pattern: 'java.lang<type=Memory><HeapMemoryUsage>used'
        name: java_heap_used_bytes
        type: GAUGE
      - pattern: 'java.lang<type=Memory><HeapMemoryUsage>max'
        name: java_heap_max_bytes
        type: GAUGE
      - pattern: 'java.lang<type=Memory><NonHeapMemoryUsage>used'
        name: java_nonheap_used_bytes
        type: GAUGE
      - pattern: 'java.lang<type=Memory><NonHeapMemoryUsage>max'
        name: java_nonheap_max_bytes
        type: GAUGE
      - pattern: 'java.lang<(?=(?:[^>]*, )?type=GarbageCollector[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>CollectionCount'
        name: java_gc_count
        type: GAUGE
        labels:
          name: "$1"
      - pattern: 'java.lang<(?=(?:[^>]*, )?type=GarbageCollector[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>CollectionTime'
        name: java_gc_seconds
        type: GAUGE
        valueFactor: 0.001
        labels:
          name: "$1"
      - pattern: 'java.lang<type=Threading><>ThreadCount'
        name: java_threads_live
        type: GAUGE
      - pattern: 'java.lang<type=Threading><>DaemonThreadCount'
        name: java_threads_daemon
        type: GAUGE
      - pattern: 'java.lang<type=ClassLoading><>LoadedClassCount'
        name: java_classes_loaded
        type: GAUGE
      - pattern: 'java.lang<type=OperatingSystem><>ProcessCpuLoad'
        name: java_cpu_load
        type: GAUGE
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ServerRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>StateVal'
        name: java_server_state
        type: GAUGE
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ServerRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>State: RUNNING'
        name: java_server_running
        type: GAUGE
        value: 1
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ServerRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>State: '
        name: java_server_running
        type: GAUGE
        value: 0
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ThreadPoolRuntime[,>])(?=(?:[^>]*, )?ServerRuntime="?([^",>]+)"?[,>])[^>]*><>StuckThreadCount'
        name: java_stuck_threads
        type: GAUGE
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ThreadPoolRuntime[,>])(?=(?:[^>]*, )?ServerRuntime="?([^",>]+)"?[,>])[^>]*><>HoggingThreadCount'
        name: java_hogging_threads
        type: GAUGE
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ThreadPoolRuntime[,>])(?=(?:[^>]*, )?ServerRuntime="?([^",>]+)"?[,>])[^>]*><>PendingUserRequestCount'
        name: java_requests_pending
        type: GAUGE
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ThreadPoolRuntime[,>])(?=(?:[^>]*, )?ServerRuntime="?([^",>]+)"?[,>])[^>]*><>CompletedRequestCount'
        name: java_requests
        type: GAUGE
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ThreadPoolRuntime[,>])(?=(?:[^>]*, )?ServerRuntime="?([^",>]+)"?[,>])[^>]*><>ExecuteThreadTotalCount'
        name: java_threadpool_size
        type: GAUGE
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=ThreadPoolRuntime[,>])(?=(?:[^>]*, )?ServerRuntime="?([^",>]+)"?[,>])[^>]*><>ExecuteThreadIdleCount'
        name: java_threadpool_idle
        type: GAUGE
        labels:
          server: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=JDBCDataSourceRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>ActiveConnectionsCurrentCount'
        name: java_jdbc_active
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=JDBCDataSourceRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>NumAvailable'
        name: java_jdbc_idle
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=JDBCDataSourceRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>CurrCapacity'
        name: java_jdbc_size
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=JDBCDataSourceRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>WaitingForConnectionCurrentCount'
        name: java_jdbc_waiting
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=JMSDestinationRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>MessagesCurrentCount'
        name: java_jms_messages
        type: GAUGE
        labels:
          destination: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=JMSDestinationRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>MessagesPendingCount'
        name: java_jms_pending
        type: GAUGE
        labels:
          destination: "$1"
      - pattern: 'com.bea<(?=(?:[^>]*, )?Type=WebAppComponentRuntime[,>])(?=(?:[^>]*, )?Name="?([^",>]+)"?[,>])[^>]*><>OpenSessionsCurrentCount'
        name: java_sessions_active
        type: GAUGE
        labels:
          app: "$1"
    '@
    [IO.File]::WriteAllText('C:\spitfire\jmx\spitfire-weblogic.yml', $Rules + "`n")
  3. Add the JVM option for AdminServer to setUserOverrides.cmd.
    powershell
    Add-Content -Encoding ASCII C:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain\bin\setUserOverrides.cmd 'if "%SERVER_NAME%"=="AdminServer" set "JAVA_OPTIONS=%JAVA_OPTIONS% -javaagent:C:\spitfire\jmx\jmx_prometheus_javaagent.jar=9404:C:\spitfire\jmx\spitfire-weblogic.yml" & rem spitfire AdminServer'
  4. Restart AdminServer, then check the exporter.
    powershell
    if ((Invoke-WebRequest -UseBasicParsing http://localhost:9404/metrics).Content -match 'java_server_state') { 'OK: weblogic' }

WebSphere Liberty

Liberty only (Open Liberty, WebSphere Liberty). Traditional WebSphere Application Server is not supported.

Quick install

  1. Run it on the Liberty server.
    bash
    curl -fsSL "https://<spitfire>/api/v1/setup/ds/websphere.sh?t=<token>&lang=en" -o /tmp/sf-websphere.sh && bash /tmp/sf-websphere.sh
  2. When you see OK: ..., you are done.
Note

The script writes configDropins/overrides/spitfire-metrics.xml; Liberty reads it without a restart and server.xml does not change. /metrics opens on the HTTP port without authentication; allow the port only to the Tower. If the mpMetrics feature is not installed: featureUtility installFeature mpMetrics-5.1. Liberty does not publish the thread pool's maximum or deadlocks. The script picks the mpMetrics version from server.xml: 5.1 for Jakarta EE 10+, 4.0 for EE 9.1, 3.0 for Java EE 8 (javaee-8.0). In the manual install use the same; a mismatch logs CWWKF0033E and Liberty drops its features.

Manual install

  1. Write the mpMetrics dropin.
    bash
    sudo mkdir -p /opt/wlp/usr/servers/defaultServer/configDropins/overrides && sudo tee /opt/wlp/usr/servers/defaultServer/configDropins/overrides/spitfire-metrics.xml >/dev/null <<'SPITFIRE_XML'
    <?xml version="1.0" encoding="UTF-8"?>
    <server>
        <featureManager>
            <feature>mpMetrics-5.1</feature>
        </featureManager>
        <mpMetrics authentication="false"/>
    </server>
    SPITFIRE_XML
  2. Add the monitored system: Infrastructure sources → WebSphere Liberty, address <host>:9080.
  3. Check /metrics.
    bash
    curl -fsS http://localhost:9080/metrics | grep -q memory_usedHeap_bytes && echo "OK: websphere"

Java / JMX (Spring Boot)

Quick install

  1. Run it on the app's server.
    bash
    curl -fsSL "https://<spitfire>/api/v1/setup/ds/jmx.sh?t=<token>&lang=en" -o /tmp/sf-jmx.sh && bash /tmp/sf-jmx.sh
  2. When you see OK: ..., you are done.
Note

For a systemd service the script adds JAVA_TOOL_OPTIONS in a drop-in and asks before the restart; for an app that runs any other way it prints the option. In Spring Boot, the embedded Tomcat and HikariCP metrics need server.tomcat.mbeanregistry.enabled=true and spring.datasource.hikari.register-mbeans=true.

Manual install

  1. Download the javaagent.
    bash
    sudo mkdir -p /opt/spitfire/jmx && sudo curl -fsSL -o /opt/spitfire/jmx/jmx_prometheus_javaagent.jar https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/1.0.1/jmx_prometheus_javaagent-1.0.1.jar
  2. Write the rules file.
    bash
    sudo tee /opt/spitfire/jmx/spitfire-jmx.yml >/dev/null <<'SPITFIRE_YML'
    # Spitfire jmx: Prometheus JMX exporter javaagent 1.0.1 rules (read-only).
    lowercaseOutputName: false
    includeObjectNames:
      - "java.lang:type=Memory"
      - "java.lang:type=GarbageCollector,*"
      - "java.lang:type=Threading"
      - "java.lang:type=ClassLoading"
      - "java.lang:type=OperatingSystem"
      - "Catalina:type=GlobalRequestProcessor,*"
      - "Catalina:type=ThreadPool,*"
      - "Catalina:type=Manager,*"
      - "Catalina:type=DataSource,*"
      - "Tomcat:type=GlobalRequestProcessor,*"
      - "Tomcat:type=ThreadPool,*"
      - "Tomcat:type=Manager,*"
      - "Tomcat:type=DataSource,*"
      - "com.zaxxer.hikari:*"
    rules:
      - pattern: 'java.lang<type=Memory><HeapMemoryUsage>used'
        name: java_heap_used_bytes
        type: GAUGE
      - pattern: 'java.lang<type=Memory><HeapMemoryUsage>max'
        name: java_heap_max_bytes
        type: GAUGE
      - pattern: 'java.lang<type=Memory><NonHeapMemoryUsage>used'
        name: java_nonheap_used_bytes
        type: GAUGE
      - pattern: 'java.lang<type=Memory><NonHeapMemoryUsage>max'
        name: java_nonheap_max_bytes
        type: GAUGE
      - pattern: 'java.lang<(?=(?:[^>]*, )?type=GarbageCollector[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>CollectionCount'
        name: java_gc_count
        type: GAUGE
        labels:
          name: "$1"
      - pattern: 'java.lang<(?=(?:[^>]*, )?type=GarbageCollector[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>CollectionTime'
        name: java_gc_seconds
        type: GAUGE
        valueFactor: 0.001
        labels:
          name: "$1"
      - pattern: 'java.lang<type=Threading><>ThreadCount'
        name: java_threads_live
        type: GAUGE
      - pattern: 'java.lang<type=Threading><>DaemonThreadCount'
        name: java_threads_daemon
        type: GAUGE
      - pattern: 'java.lang<type=ClassLoading><>LoadedClassCount'
        name: java_classes_loaded
        type: GAUGE
      - pattern: 'java.lang<type=OperatingSystem><>ProcessCpuLoad'
        name: java_cpu_load
        type: GAUGE
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=GlobalRequestProcessor[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>requestCount'
        name: java_requests
        type: GAUGE
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=GlobalRequestProcessor[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>errorCount'
        name: java_request_errors
        type: GAUGE
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=GlobalRequestProcessor[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>processingTime'
        name: java_request_seconds
        type: GAUGE
        valueFactor: 0.001
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=ThreadPool[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>currentThreadsBusy'
        name: java_threadpool_busy
        type: GAUGE
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=ThreadPool[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>maxThreads'
        name: java_threadpool_max
        type: GAUGE
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=ThreadPool[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>currentThreadCount'
        name: java_threadpool_size
        type: GAUGE
        labels:
          connector: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=Manager[,>])(?=(?:[^>]*, )?context="?([^",>]+)"?[,>])(?=(?:[^>]*, )?host="?([^",>]+)"?[,>])[^>]*><>activeSessions'
        name: java_sessions_active
        type: GAUGE
        labels:
          context: "$1"
          host: "$2"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=DataSource[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>numActive'
        name: java_jdbc_active
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=DataSource[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>numIdle'
        name: java_jdbc_idle
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=DataSource[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>(?:maxTotal|maxActive)'
        name: java_jdbc_max
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: '(?:Catalina|Tomcat)<(?=(?:[^>]*, )?type=DataSource[,>])(?=(?:[^>]*, )?name="?([^",>]+)"?[,>])[^>]*><>waitCount'
        name: java_jdbc_waiting
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.zaxxer.hikari<type=Pool \(([^)]+)\)><>ActiveConnections'
        name: java_jdbc_active
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.zaxxer.hikari<type=Pool \(([^)]+)\)><>IdleConnections'
        name: java_jdbc_idle
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.zaxxer.hikari<type=Pool \(([^)]+)\)><>TotalConnections'
        name: java_jdbc_size
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.zaxxer.hikari<type=Pool \(([^)]+)\)><>ThreadsAwaitingConnection'
        name: java_jdbc_waiting
        type: GAUGE
        labels:
          datasource: "$1"
      - pattern: 'com.zaxxer.hikari<type=PoolConfig \(([^)]+)\)><>MaximumPoolSize'
        name: java_jdbc_max
        type: GAUGE
        labels:
          datasource: "$1"
    SPITFIRE_YML
  3. Start the app with the javaagent.
    bash
    java -javaagent:/opt/spitfire/jmx/jmx_prometheus_javaagent.jar=9404:/opt/spitfire/jmx/spitfire-jmx.yml -Dserver.tomcat.mbeanregistry.enabled=true -Dspring.datasource.hikari.register-mbeans=true -jar /opt/app/app.jar
  4. Add the monitored system: Infrastructure sources → Java / JMX, address <host>:9404.
  5. Check the exporter.
    bash
    curl -fsS http://localhost:9404/metrics | grep -q java_heap_used_bytes && echo "OK: jmx"

Threshold findings

Finding Source Severity
The target does not answer (up = 0) All Critical
Heap above 85% / above 95% All Warning / critical
Deadlocked threads Tomcat, WebLogic, Java / JMX Critical
Thread pool more than 90% busy Tomcat, WildFly, Java / JMX Warning
JDBC pool more than 90% used Tomcat, WildFly, Java / JMX Warning
Requests waiting for a JDBC connection Tomcat, WebLogic, Java / JMX, WildFly, Liberty Warning
Request errors went up Tomcat, WildFly, Liberty, Java / JMX Warning
WebLogic stuck threads WebLogic Critical
WebLogic server not RUNNING WebLogic Critical

Success check

  1. On the server the matching curl command prints OK: ....
  2. Last test = Connected, and within 1-2 minutes the dashboard shows heap and thread lines.