tutorial

Monitoring Eclipse GlassFish with Vigilmon

Eclipse GlassFish is the Jakarta EE reference implementation — here's how to monitor its admin console, Grizzly HTTP listeners, JVM heap, JDBC connection pools, OpenMQ JMS broker, EJB container, and cluster health with Vigilmon.

Eclipse GlassFish is the open source reference implementation of the Jakarta EE specification, maintained by the Eclipse Foundation. Originally developed by Sun Microsystems in 2006 as the Java EE 5 reference implementation, GlassFish is now the first server to implement each new Jakarta EE version — making it both the specification proving ground and a production-capable application server used by teams who want the latest Jakarta EE features. When you self-host Eclipse GlassFish, you're running a multi-subsystem stack: the Grizzly NIO HTTP framework, Jersey JAX-RS implementation, OpenMQ embedded JMS broker, EclipseLink JPA, and a web-based admin console on port 4848. Any failure in these subsystems can silently take down deployed applications, stall JMS message processing, or exhaust your JDBC connection pool. Vigilmon gives you end-to-end monitoring across every critical layer of your GlassFish deployment.

What You'll Set Up

  • Admin console (port 4848) reachability monitor
  • Grizzly HTTP listener health check
  • JVM heap usage and GC pause monitoring
  • Grizzly thread pool saturation alert
  • JDBC connection pool health via REST management API
  • OpenMQ JMS broker health check
  • Application deployment status monitoring
  • GlassFish cluster node health
  • EJB container pool monitoring
  • Log error rate monitoring

Prerequisites

  • Eclipse GlassFish 7+ running with the default domain (domain1)
  • Admin console accessible on port 4848
  • REST management API enabled (enabled by default)
  • A free Vigilmon account

Step 1: Monitor the GlassFish Admin Console

The GlassFish admin web console on port 4848 doubles as the REST management API gateway. If this port is unreachable, you lose both the GUI administration interface and programmatic access to runtime metrics and server state.

  1. Log in to vigilmon.online and click Add Monitor.
  2. Set Type to HTTP / HTTPS.
  3. URL: http://your-server:4848/ (or https:// if you've enabled secure admin).
  4. Set Check interval to 1 minute.
  5. Set Expected HTTP status to 200 (the admin login page).
  6. Under Keyword check, enter GlassFish to verify the page content is the actual admin console.
  7. Click Save.

For a deeper check that confirms the management REST API is responding:

  1. Click Add MonitorHTTP / HTTPS.
  2. URL: http://your-server:4848/management/domain.
  3. Expected HTTP status: 200.
  4. Under Request headers, add Accept: application/json.
  5. Keyword check: GlassFish.
  6. Check interval: 2 minutes.
  7. Click Save.

Step 2: Monitor Grizzly HTTP Listener Health

Grizzly is the NIO framework powering all GlassFish HTTP and AJP connectors. The default HTTP listener on port 8080 handles all inbound application traffic. A stopped or crashed Grizzly listener makes every deployed application unreachable.

  1. Click Add MonitorTCP Port.
  2. Host: your GlassFish server hostname or IP.
  3. Port: 8080 (default HTTP) or 8181 (default HTTPS).
  4. Check interval: 1 minute.
  5. Click Save.

Add a content-level check against a deployed application health endpoint:

  1. Click Add MonitorHTTP / HTTPS.
  2. URL: http://your-server:8080/your-app/health.
  3. Expected HTTP status: 200.
  4. Check interval: 1 minute.
  5. Enable Monitor SSL certificate if using port 8181, and set expiry alert to 21 days.
  6. Click Save.

To add a health endpoint to a JAX-RS application deployed on GlassFish:

@Path("/health")
@ApplicationScoped
public class HealthResource {
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response check() {
        return Response.ok("{\"status\":\"UP\"}").build();
    }
}

Step 3: Monitor JVM Heap and Garbage Collection

GlassFish runs entirely on the JVM. Heap exhaustion causes OutOfMemoryError and crashes the server process; sustained GC pauses degrade response times across all deployed applications simultaneously.

Query JVM memory metrics via the GlassFish REST monitoring API:

#!/bin/bash
BASE="http://localhost:4848/monitoring/domain/server/jvm"

HEAP=$(curl -s "$BASE/memory.json" | jq -r '.extraProperties.entity')

USED=$(echo "$HEAP" | jq -r '.usedheapsize.current')
MAX=$(echo "$HEAP" | jq -r '.maxheapsize.current')

HEAP_PCT=$(( USED * 100 / MAX ))

if [ "$HEAP_PCT" -lt 85 ]; then
  curl -s "https://vigilmon.online/heartbeat/YOUR_HEAP_HEARTBEAT_ID" > /dev/null
fi
  1. Click Add MonitorCron Heartbeat.
  2. Set expected interval to 2 minutes.
  3. Add the script to cron: * * * * * /opt/scripts/glassfish-heap-check.sh.
  4. Alert fires when heap stays above 85% for more than 2 consecutive checks.

For GC pause monitoring, query the GC MBean via the REST monitoring endpoint at /monitoring/domain/server/jvm/garbage-collectors.


Step 4: Monitor Grizzly Thread Pool

Grizzly uses thread pools for HTTP request processing. When all threads are busy, new requests queue up and response latency climbs. Thread pool saturation is an early warning of traffic spikes that will soon exceed your server's capacity.

#!/bin/bash
BASE="http://localhost:4848/monitoring/domain/server"

TP=$(curl -s "$BASE/thread-pools/http-thread-pool.json" \
  | jq -r '.extraProperties.entity')

CURRENT=$(echo "$TP" | jq -r '.currentthreadcount.current')
MAX=$(echo "$TP" | jq -r '.maxthreadpoolsize.current')
QUEUE=$(echo "$TP" | jq -r '.currentthreadsbusycount.current')

UTIL=$(( CURRENT * 100 / MAX ))

# Ping heartbeat when thread utilization is below 80%
if [ "$UTIL" -lt 80 ]; then
  curl -s "https://vigilmon.online/heartbeat/YOUR_TP_HEARTBEAT_ID" > /dev/null
fi

Create a Cron Heartbeat with 2-minute interval. Alert threshold: thread pool utilization above 80% for two consecutive checks indicates saturation approaching — time to scale horizontally or tune the pool size.


Step 5: Monitor JDBC Connection Pool

GlassFish JDBC connection pools provide database connectivity to all deployed applications. Pool exhaustion causes applications to block waiting for connections, appearing as slow responses or request timeouts before the actual root cause surfaces.

#!/bin/bash
POOL_NAME="jdbc/__default"  # Replace with your pool name
BASE="http://localhost:4848/monitoring/domain/server/resources"

POOL=$(curl -s "$BASE/${POOL_NAME}.json" | jq -r '.extraProperties.entity')

NUM_CON=$(echo "$POOL" | jq -r '.numconnused.current')
NUM_FREE=$(echo "$POOL" | jq -r '.numconnfree.current')
TIMEOUT=$(echo "$POOL" | jq -r '.connectionrequestwaittime.current // 0')

TOTAL=$(( NUM_CON + NUM_FREE ))

# Alert if pool is more than 90% utilized
if [ "$TOTAL" -gt 0 ] && [ $(( NUM_CON * 100 / TOTAL )) -lt 90 ]; then
  curl -s "https://vigilmon.online/heartbeat/YOUR_POOL_HEARTBEAT_ID" > /dev/null
fi
  1. Create a Cron Heartbeat with 2-minute interval.
  2. Alert when connection pool utilization exceeds 90% — exhausted pools cause application-level failures before the TCP port shows any problem.

Step 6: Monitor OpenMQ JMS Broker Health

GlassFish includes OpenMQ as its built-in JMS broker for asynchronous messaging. If the broker service stops, message-driven beans (MDBs) stop receiving messages and any asynchronous workflows dependent on JMS halt silently.

  1. Click Add MonitorTCP Port.
  2. Host: localhost (OpenMQ runs embedded in GlassFish by default).
  3. Port: 7676 (default OpenMQ broker port).
  4. Check interval: 1 minute.
  5. Click Save.

For queue depth monitoring:

#!/bin/bash
# Use imqcmd to check queue depth (OpenMQ admin CLI)
QUEUE="YourQueueName"
DEPTH=$(/opt/glassfish7/mq/bin/imqcmd query dst \
  -t q -n "$QUEUE" -u admin -p admin -b localhost:7676 2>/dev/null \
  | grep "Current Number of Messages" | awk '{print $NF}')

CONSUMERS=$(/opt/glassfish7/mq/bin/imqcmd query dst \
  -t q -n "$QUEUE" -u admin -p admin -b localhost:7676 2>/dev/null \
  | grep "Number of Consumers" | awk '{print $NF}')

if [ "${CONSUMERS:-0}" -gt 0 ] && [ "${DEPTH:-0}" -lt 500 ]; then
  curl -s "https://vigilmon.online/heartbeat/YOUR_JMS_HEARTBEAT_ID" > /dev/null
fi

Set heartbeat interval to 3 minutes. A missed ping means either the broker is down or messages are accumulating without consumers.


Step 7: Monitor Application Deployment Health

GlassFish tracks each deployed application's enabled/disabled status and runtime state via the REST management API. A failed deployment may leave a previous version running or serve a 404 — catching deployment failures immediately prevents silent rollbacks going unnoticed.

#!/bin/bash
BASE="http://localhost:4848/management/domain/applications"

APPS=$(curl -s "$BASE/application.json" \
  | jq -r '.extraProperties.childResources | keys[]')

ALL_OK=1
while IFS= read -r APP; do
  STATE=$(curl -s "$BASE/application/$APP.json" \
    | jq -r '.extraProperties.entity.enabled')
  if [ "$STATE" != "true" ]; then
    ALL_OK=0
    break
  fi
done <<< "$APPS"

if [ "$ALL_OK" -eq 1 ]; then
  curl -s "https://vigilmon.online/heartbeat/YOUR_DEPLOY_HEARTBEAT_ID" > /dev/null
fi
  1. Create a Cron Heartbeat with 5-minute interval.
  2. The heartbeat pings only when all deployed applications are in enabled=true state.
  3. A missed ping means at least one application has been disabled, failed, or was undeployed unexpectedly.

Step 8: Monitor GlassFish Cluster Health

GlassFish supports clustered deployment where multiple server instances share configuration and replicate HTTP sessions. A node failure in a cluster can leave it running but with reduced capacity and broken session replication.

#!/bin/bash
BASE="http://localhost:4848/management/domain/clusters"
CLUSTER="cluster1"  # Replace with your cluster name

NODES=$(curl -s "$BASE/cluster/$CLUSTER/server-ref.json" \
  | jq -r '.extraProperties.childResources | length')

RUNNING=$(curl -s \
  "http://localhost:4848/management/domain/clusters/cluster/$CLUSTER/list-instances" \
  | jq -r '[.extraProperties.instanceList[] | select(.status == "running")] | length')

# Alert if running instance count falls below expected
EXPECTED=2  # Set to your minimum required cluster size
if [ "$RUNNING" -ge "$EXPECTED" ]; then
  curl -s "https://vigilmon.online/heartbeat/YOUR_CLUSTER_HEARTBEAT_ID" > /dev/null
fi

Create a Cron Heartbeat with 2-minute interval. A missed ping fires when the running instance count drops below your minimum — catching node failures before they exhaust remaining cluster capacity.


Step 9: Monitor EJB Container Health

The GlassFish EJB container manages stateless session beans, stateful session beans, and message-driven beans. EJB pool exhaustion causes concurrent request processing to stall while threads wait for bean instances to become available.

#!/bin/bash
BASE="http://localhost:4848/monitoring/domain/server/ejb-pool"

# Query EJB pool statistics for a specific bean
BEAN="YourStatelessBean"  # Replace with your EJB name

POOL=$(curl -s "$BASE/$BEAN.json" | jq -r '.extraProperties.entity // empty')

if [ -n "$POOL" ]; then
  POOLED=$(echo "$POOL" | jq -r '.beansinjpool.current // 0')
  MAX=$(echo "$POOL" | jq -r '.maxbeansinjpool.current // 1')
  UTIL=$(( POOLED * 100 / MAX ))

  if [ "$UTIL" -lt 90 ]; then
    curl -s "https://vigilmon.online/heartbeat/YOUR_EJB_HEARTBEAT_ID" > /dev/null
  fi
fi

Alert when EJB pool utilization exceeds 90% — fully exhausted pools cause requests to queue and response times to spike across any component that invokes those EJBs.


Step 10: Monitor GlassFish Log Error Rate

GlassFish writes server logs to glassfish/domains/domain1/logs/server.log. A sudden increase in SEVERE log entries is often the first sign of a subsystem problem before it becomes a user-visible outage.

#!/bin/bash
LOG="/opt/glassfish7/glassfish/domains/domain1/logs/server.log"

# Count SEVERE entries in the last 5 minutes
RECENT_SEVERE=$(awk \
  -v cutoff="$(date -d '5 minutes ago' '+%Y-%m-%dT%H:%M')" \
  '$0 ~ cutoff || $0 > cutoff' "$LOG" \
  | grep -c '|SEVERE|' || true)

# Allow up to 5 SEVERE entries per 5 minutes before alerting
if [ "$RECENT_SEVERE" -le 5 ]; then
  curl -s "https://vigilmon.online/heartbeat/YOUR_LOG_HEARTBEAT_ID" > /dev/null
fi
  1. Create a Cron Heartbeat with 5-minute interval.
  2. Set cron to run every 5 minutes: */5 * * * * /opt/scripts/glassfish-log-check.sh.
  3. A missed ping means more than 5 SEVERE log entries occurred in the last 5 minutes — prompting log investigation before the error cascade reaches users.

Alerting Configuration

Configure alert channels in Vigilmon to reach your team quickly:

  1. Go to Alert Channels in your Vigilmon dashboard.
  2. Add Email for all monitors (critical baseline).
  3. Add Slack or PagerDuty webhook for the admin console, HTTP listener, and JMS broker monitors.
  4. Set 2 consecutive failures before alerting to avoid noise from momentary network blips.

Recommended alert thresholds:

| Monitor | Alert Condition | |---|---| | Admin console (4848) | Unreachable for 2 minutes | | HTTP listener (8080) | TCP connection refused | | JVM heap | > 85% for 4 minutes | | Thread pool utilization | > 80% for 4 minutes | | JDBC pool utilization | > 90% | | OpenMQ broker (7676) | TCP connection refused | | Application status | Any app enabled=false | | Cluster node count | Below minimum for 2 minutes | | SEVERE log rate | > 5 entries per 5 minutes |


Conclusion

Eclipse GlassFish's built-in REST monitoring API makes it straightforward to query metrics from every subsystem — Grizzly thread pools, JDBC connection pools, EJB container stats, OpenMQ queue depth — and route those signals into Vigilmon heartbeats. Combined with TCP checks on the admin console and HTTP listeners, you get full-stack observability across the GlassFish runtime. Set up these monitors before you need them, and you'll catch heap exhaustion, pool saturation, and deployment failures before they become production incidents.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →