Documentation Index
Fetch the complete documentation index at: https://docs.apinizer.com/llms.txt
Use this file to discover all available pages before exploring further.
1-) How Does It Work?
This guide describes a simple monitoring solution that periodically collects diagnostic metrics from an Apinizer Worker pod and, at the end of the day, generates a single-file interactive HTML report from this data. The solution consists of three parts:- A collector shell script (
monitor.sh) — periodically reads the Worker Diagnostics API (/allendpoint) of the given environment and appends to a JSONL file with one JSON record per line. The same script can be run in parallel for multiple environments using environment name + Worker URL + Env ID arguments. - A Python report generator (
generate_report.py) — reads the JSONL file of the specified environment; normalizes memory, thread, GC, connection, and health metrics; and produces a single HTML file enriched with statistics, anomaly detection, and Chart.js-based interactive charts. - An orchestrator script (
make-report.sh) — locates the JSONL file based on the given environment name and date, checks the minimum number of records, and invokes the report generator.
The flow is as follows: Apinizer Worker (
/apinizer/diagnostics/all) → monitor.sh <environment> (every 2 minutes) → <environment>-worker-diagnostics-YYYYMMDD.jsonl → make-report.sh <environment> → generate_report.py → apinizer-worker-report-<environment>-YYYYMMDD.html2-) Prerequisites
The following requirements must be met on the machine where you will run the solution:bash,curl,sed,wc(available in a typical Linux environment)python3(3.9 or higher; required for type hints such aslist[dict])- The report generator uses only the standard library; no
pip installis required. Chart.js, required for rendering charts, is embedded in the generated HTML file via CDN — an internet connection is sufficient while viewing the report. - Network access to the Diagnostics API of the Worker pods (e.g., via NodePort or Ingress from outside the cluster).
Authorization header in Diagnostics API calls.
3-) Diagnostics API
The Apinizer Worker provides the following diagnostic endpoints to query the current state of the pod:| Endpoint | Description |
|---|---|
/jvm | Returns JVM-level memory (heap, non-heap), GC counters, and uptime information. |
/threads | Contains thread counts, thread state distribution (RUNNABLE / WAITING / TIMED_WAITING), and executor pool states. |
/threaddump | Returns instant stack traces of all threads. Intended for diagnostic purposes; not suitable for periodic collection. |
/connections | Contains Worker-specific HTTP connection pool metrics (leased, available, pending, maxTotal). |
/env | Returns runtime environment information (environment variables, system properties). |
/health | Pod health status (UP / DOWN) and sub-health checks (memory, threads, connections). |
/hazelcast | Returns cache-specific metrics (cluster members, distributed data structure states). |
/pod-version | Returns the version information of the pod. |
/all | Combines all the above metrics into a single JSON response. |
4-) Setting Up the Collector Script
A singlemonitor.sh file takes the information about which environment to monitor as an argument. This way, there is no need for separate script files to monitor different environments (e.g., dev, prod, staging); the same script file can be run in multiple terminals with different arguments to perform parallel monitoring.
You can access ready-to-use copies of the three scripts described in this guide (
monitor.sh, generate_report.py, make-report.sh) from the following link:Download script filesIt is sufficient to download the files to the same directory and make them executable with the command chmod +x monitor.sh make-report.sh.monitor.sh — Dynamic Collector Script
Save the following script with the namemonitor.sh. During use, pass the environment name, Worker URL, and Env ID values as arguments on the command line.
Making the Script Executable and Starting It
dev-worker-diagnostics-20260422.jsonl, prod-worker-diagnostics-20260422.jsonl, etc.); files do not mix with each other.
The script samples every 120 seconds by default. For more or less frequent sampling, you can pass a value in seconds as the fourth argument (e.g.,
./monitor.sh prod <url> <id> 60). Going below 60 seconds may cause unnecessary load on the Worker; above 300 seconds may miss short-term spikes.Continuous Background Execution
Since the monitoring scripts run with awhile true loop, they stop when the terminal session is closed. To keep them running continuously, one of the following methods can be preferred depending on your use case:
tmuxorscreenfor test/development environments — If you start the script in a separate tmux session, it will continue to run even if you close your SSH connection. You can later reconnect to the session and watch the output live. It is a fast and simple solution; however, the script does not automatically come up when the server is restarted.systemdservice for production environments — The standard method for managing background services on Linux. A.serviceunit file is written for each environment; arguments such asExecStart=/path/to/monitor.sh prod <url> <id>are provided as the command line. This way, the service starts automatically when the server restarts, retries automatically if it exits unexpectedly (Restart=always), and its output goes to system logs (journalctl). For production use, this is the preferred method in terms of continuity and observability.
Deployment or a scheduled CronJob.
5-) JSONL Output Format
At each sampling, the collector injects thecollectedAt field at the very beginning of the JSON response returned from the Worker and appends it to the output file as a single line. This format is known as JSONL (JSON Lines) — each line is an independent and valid JSON object.
<ENV_NAME>-worker-diagnostics-YYYYMMDD.jsonl
For example:
dev-worker-diagnostics-20260422.jsonlprod-worker-diagnostics-20260422.jsonlstaging-worker-diagnostics-20260422.jsonl
6-) Report Generator
The report generator reads the JSONL file of the specified environment and outputs a single HTML file. The output file is self-contained; it does not require any other assets, can be sent as an email attachment, or opened from a shared disk.generate_report.py — Report Generator Script
Save thegenerate_report.py file to the directory where the collector script produces output (next to the JSONL files). The script is written entirely with the Python standard library and requires no additional dependencies. The full source code is included in the appendix at the end of the document; the main functions and operating logic are summarized below.
The script works in four main stages:
THRESHOLDS dictionary according to your own SLAs.
make-report.sh — Orchestrator Script
The following script finds the JSONL file based on the given environment name and date and invokes the report generator. Save it asmake-report.sh in the same directory as generate_report.py.
CLI Usage
generate_report.py can also be run directly. Supported options:
apinizer-worker-report-<ENV>-YYYYMMDD.html to the same directory as the JSONL file.
7-) Report Content
The generated HTML file is a single-page interactive dashboard. The environment label, report summary, and anomaly badges are at the top; the content is divided into six tabs.
Tabs
- Overview — Summary cards of key metrics such as Heap %, Heap Max, thread count, response time, active connections, GC Young rate, GC Old, and deadlocks; below, time series charts comparing all pods on the same chart (Heap %, response time, thread count, active connections). It is the tab selected when the page opens.
- Memory — Heap usage (MB and %) and non-heap / metaspace charts. Ideal for seeing how heap usage changes over time; in a stable environment, the heap forms a sawtooth pattern, while a pod experiencing a memory leak shows a constantly upward trend.

- Threads — Thread state distribution (RUNNABLE / WAITING / TIMED_WAITING),
apinizer-asyncexecutor pool status (pool size, active, queue), and total started thread count per pod.

- GC — G1 Young and Concurrent GC counters and cumulative GC time charts.
- Connections — Leased and available metrics of the HTTP connection pool and maintenance pool queue charts.
- Anomalies — List of metrics where threshold exceedance is detected; shows in which metric, in how many samples, and at which peak value the warning or critical level was reached. At the bottom of the page, there is a per-pod summary table.

Tab contents work with “lazy build” logic: charts are created only when tabs are clicked. This way, even if the report contains thousands of data points, the initial load remains fast.
Comparing Multiple Environments
Since the report is now generated for a single environment, when you want to compare two environments, it is sufficient to generate a separate report for each environment and open the HTML files side by side:8-) Troubleshooting
ERROR: 401 Unauthorized — check the ENV_ID value.
The ENV_ID is incorrect or the ID of another environment was entered. Re-obtain the correct ID for the environment from the API Manager → Environments menu.
ERROR: Could not reach Worker ({WORKER_URL})
There is no TCP-level access to the Worker address. Network rules, Ingress/NodePort definitions, or proxy settings should be checked. Quick verification can be done by sending a manual request with curl -v "${WORKER_URL}/apinizer/diagnostics/all?internal=true".
ERROR: ENV_NAME, WORKER_URL, and ENV_ID are required.
monitor.sh was run without arguments or with missing arguments. If you have not filled in the DEFAULT_* values at the beginning of the script, you must pass all three arguments on the command line.
ERROR: <env>-worker-diagnostics-YYYYMMDD.jsonl does not exist. Is monitor.sh <env> ... running?
make-report.sh looks for the JSONL file of the specified environment. The collector may not have been started yet, may have been run with another environment name, or may be running in another directory. The collector script and the report generator must run in the same directory.
WARNING: At least 3 records are needed for meaningful charts.
If the collector has just been started, sufficient samples may not have accumulated yet. With the default 120-second interval, waiting at least 6 minutes is sufficient for a meaningful report.
Some pods do not appear in the report at all.
If the Worker Deployment is running with multiple replicas, requests coming through a Service or Ingress are distributed to different pods. The collector may hit a random pod on each request; in short-term monitoring, some pods have a low chance of being sampled. To monitor per pod, additional collectors targeting each pod separately (e.g., via headless service or pod DNS) can be run.
