Metrics Logs
JSON-format metrics logging allows you to collect system health and performance metrics from the container at regular intervals.
On this page:
- Introduction
- JSON-format metrics logs
- Configure the Log4j JSON-format metrics log appender
- Disable the Log4j JSON-format metrics log appender
- ECS-based JSON metrics log format
- Capture metrics from additional monitoring panels
- Add additional metrics to the monitoring panel
- Customize the health monitoring panel
- Configure the metric logging interval
Introduction
Akana generates metrics logs by running a scheduled background job at a configurable interval on each container. During each run, the job reads the monitorables configured in the container health panel and records their current values in a single structured log entry.
Each entry uses JSON format and includes information such as the timestamp, container name, and the name-value pairs for the monitorables collected during that interval.
Because the background job runs independently of request traffic, Akana generates metrics logs at regular intervals rather than for individual requests. This approach provides a consistent time-series view of container health and resource status alongside the existing access and trace logs.
JSON-format metrics logs
Configure the Log4j appender, enable JSON-format metrics logging, and customize monitoring panels to capture the metrics relevant to your environment.
Configure the Log4j JSON-format metrics log appender
The Akana platform supports metrics logs in JSON format. You can use the recipe to enable or disable JSON-formatted metrics logging for a container.
To enable JSON-format metrics logging
The metric-log-config.json recipe creates the akana-monitoring health panel on the Health tab in the Administration Console. It also configures and enables the Log4j appender and logger for JSON-format metrics output, and schedules a configuration job.
Run the recipe by using the following structure:
./jython.sh -m akana.container --recipe ../recipes/metric-log-config.json --name <container-name> --home <application-runtime-path>
Replace the following:
- <container-name> - The name of your container instance.
- <application-runtime-path> - The full path to your application runtime directory.
The following shows the content of the metric-log-config.json recipe:
{
"name": "metric-log-json-rolling-config",
"description": "Rolling Appender Configuration for Periodic Metric Log",
"phases": ["finalize"],
"configurations": [
{
"factoryPid": "com.soa.admin.health",
"add": {
"id": "akana-monitoring",
"name": "Akana Monitoring",
"editable": "true",
"auth": "false"
}
},
{
"factoryPid": "com.soa.admin.health",
"add": {
"id": "com.soa.vmstats",
"parent": "akana-monitoring",
"variables": "free.memory.pct",
"editable": "true",
"auth": "false"
}
},
{
"factoryPid": "com.soa.admin.health",
"add": {
"id": "akana.health.lifecycle",
"parent": "akana-monitoring",
"variables": "lifecycle.state",
"threshold.normal.lifecycle.state": "value eq 'STARTED'",
"threshold.failure.lifecycle.state": "value ne 'STARTED'",
"editable": "true",
"auth": "false"
}
},
{
"factoryPid": "com.soa.admin.health",
"add": {
"id": "com.soa.container.config.stats",
"parent": "akana-monitoring",
"variables": "configuration.state,time.since.last.config",
"threshold.normal.configuration.state": "value eq 'CONFIGURED'",
"threshold.warning.configuration.state": "value eq 'CONFIGURING' or value eq 'RECONFIGURING'",
"threshold.failure.configuration.state": "value eq 'NOT_CONFIGURED'",
"editable": "true",
"auth": "false"
}
},
{
"factoryPid": "com.soa.admin.health",
"add": {
"id": "com.akana.endpoint.deployment.stats",
"parent": "akana-monitoring",
"variables": "managed.service.count,deployed.transport.count",
"editable": "true",
"auth": "false"
}
},
{
"pid": "com.soa.log",
"update": {
"appender.metric.name": "metric",
"appender.metric.type": "RollingFile",
"appender.metric.fileName": "log/metric-$${container.name}.json",
"appender.metric.filePattern": "log/metric-$${container.name}-%i.json",
"appender.metric.bufferedIO": true,
"appender.metric.layout.type": "PatternLayout",
"appender.metric.layout.pattern": "%m%n",
"appender.metric.policies.type": "Policies",
"appender.metric.policies.size.type": "SizeBasedTriggeringPolicy",
"appender.metric.policies.size.size": "5MB",
"appender.metric.strategy.type": "DefaultRolloverStrategy",
"appender.metric.strategy.max": "10",
"appender.metric.strategy.fileIndex": "min",
"logger.metric.name": "com.soa.admin.service.monitoring.metric.MetricLogService",
"logger.metric.level": "info",
"logger.metric.additivity": "false",
"logger.metric.appenderRef.metric.ref": "metric"
}
},
{
"pid": "com.soa.metric.log",
"update": {
"metric.log.enabled": "true",
"metric.log.health.ids": "akana-monitoring"
}
}
]
}
To add custom metrics to the akana-monitoring panel, see Add additional metrics to the monitoring panel.
Disable the Log4j JSON-format metrics log appender
Use the following recipe to disable the Log4j JSON metrics log appender. Run the recipe by using the following structure:
./jython.sh -m akana.container --recipe ../recipes/metric-log-disable-config.json --name <container-name> --home <application-runtime-path>
The following shows the content of the metric-log-disable-config.json recipe:
{
"name": "metric-log-json-rolling-disable-config",
"description": "Disables the periodic metric logger. Leaves the akana-monitoring HealthMeasurable tree and metric appender/logger config in place so re-enable via metric-log-config.json is a single-flag flip.",
"phases": ["finalize"],
"configurations": [
{
"pid": "com.soa.metric.log",
"update": {
"metric.log.enabled": "false"
}
}
]
}
ECS-based JSON metrics log format
Akana supports an ECS (Elastic Common Schema) template for metrics logs in JSON format. You can customize the template to meet the requirements of your monitoring tool.
Each log entry is written to metrics.log as a single-line JSON object in newline-delimited JSON (NDJSON) format.
For more information, refer to JSON Template Layout: Apache Log4j.
A JSON-based metric log generated by Log4j appears in the following format:
{
"@timestamp": "2026-09-16T06:41:28.825Z",
"event": { "type": "metric" },
"service": {
"name": "akana",
"version": "2026.3.0.33494876838"
},
"container": {
"name": "pmcm"
},
"message": {
"akana-monitoring": {
"state": "NORMAL",
"com.soa.container.config.stats": {
"state": "NORMAL",
"configuration.state": "CONFIGURED",
"time.since.last.config": 9491
},
"com.soa.vmstats": {
"state": "NORMAL",
"free.memory.pct": 71.0
},
"com.akana.endpoint.deployment.stats": {
"state": "NORMAL",
"managed.service.count": 121,
"deployed.transport.count": 1
},
"akana.health.lifecycle": {
"state": "NORMAL",
"lifecycle.state": "STARTED"
}
}
}
}
Capture metrics from additional monitoring panels
You can use the metric.log.health.ids property to specify which additional monitoring panel to include in the metric log.
The metric.log.health.ids property is required for health-panel metrics emission. If no health IDs are configured, the metric log emits a JVM-metrics fallback event containing uptime, thread, and GC counters.
-
In the Admin Console, go to the Configuration tab.
-
Under Configuration Categories, select com.soa.metric.log PID.
-
Locate the metric.log.health.ids property.
-
Enter a comma-separated list of the Health Measurable IDs in the metric.log.health.ids property that you want to include in the metric log. (For example: akana-monitoring,custom-panel).
-
Select Apply changes.
For more information about this configuration property, see com.soa.metric.log PID.
Add additional metrics to the monitoring panel
You can extend the built-in capabilities of the akana-monitoring panel to collect application, system health, and resource utilization metrics.
The following example shows the metric-log-config-additional-metrics.json recipe to specify the additional metrics to collect.
{
"name":"metric-log-json-rolling-config",
"description":"Rolling Appender Configuration for Periodic Metric Log",
"phases":["finalize"],
"configurations":[
{
"factoryPid":"com.soa.admin.health",
"add":{
"id":"com.soa.mongodb",
"parent":"akana-monitoring",
"variables":"connection-health,failed-commands,connections-used,total-heartbeats,connections,success-heartbeats,total-commands,success-commands,failed-heartbeats",
"editable":"true",
"auth":"false"
}
},
{
"factoryPid":"com.soa.admin.health",
"add":{
"id":"com.soa.jvm",
"parent":"akana-monitoring",
"variables":"thread.count,thread.peak,thread.daemon.count,thread.deadlock.count,uptime.seconds,classes.loaded,classes.unloaded,gc.count,gc.time.seconds,available.processors,process.cpu.load",
"editable":"true",
"auth":"false"
}
},
{
"factoryPid":"com.soa.admin.health",
"add":{
"id":"com.soa.db.stats",
"parent":"akana-monitoring",
"variables":"available.pool.headroom.pct,active.connections",
"editable":"true",
"auth":"false"
}
},
{
"factoryPid":"com.soa.admin.health",
"add":{
"id":"com.soa.transport.http.client",
"parent":"akana-monitoring",
"variables":"available.connections.in.pool,leased.connections.in.pool,max.connections.in.pool,pending.connections.in.pool,pool.headroom.pct",
"editable":"true",
"auth":"false"
}
},
{
"factoryPid":"com.soa.admin.health",
"add":{
"id":"soa.jetty.connector:portservice",
"parent":"akana-monitoring",
"variables":"connections.duration.max,connections.duration.stddev,connections.request.rate,connections.response.rate,connections.open,connections.open.max",
"editable":"true",
"auth":"false"
}
},
{
"factoryPid":"com.soa.admin.health",
"add":{
"id":"soa.transport.jetty",
"parent":"akana-monitoring",
"variables":"context.count,pool.idle.threads,pool.threads,pool.headroom,pool.headroom.pct",
"editable":"true",
"auth":"false"
}
},
{
"factoryPid":"com.soa.admin.health",
"add":{
"id":"com.soa.vmstats",
"parent":"akana-monitoring",
"variables":"free.memory.pct,heap.bytes.used,heap.bytes.committed,heap.bytes.init,non.heap.bytes.used,heap.used.pct",
"editable":"true",
"auth":"false"
}
}
]
}
Run the recipe by using the following structure:
./jython.sh -m akana.container --recipe ../recipes/metric-log-config-additional-metrics.json --name <container-name> --home <application-runtime-path>
Replace the following:
- <container-name> - The name of your container instance.
- <application-runtime-path> - The full path to your application runtime directory.
Customize the health monitoring panel
The akana-monitoring health panel displays system metrics for your deployment. You can customize the panel to include additional metrics that support your monitoring requirements.
The metrics configured for the health panel are recorded in the metrics log. You can configure additional metrics in either of the following ways:
-
Recipe: Use metric-log-config-additional-metrics.json recipe. See Add additional metrics to the monitoring panel.
-
Admin Console: See System Health Panel user interface.
Configure the metric logging interval
By default, metrics are logged every 60 seconds. You can configure the logging interval to control how frequently the system logs metrics by using either the Admin Console or a recipe.
To configure the scheduler frequency in the Admin Console
-
In the Admin Console, go to the Configuration tab.
-
Under Configuration Categories, select com.soa.metric.log PID.
- Select Add property and enter the following values:
property name = metric.log.interval property value = 120
-
Select Apply Changes.
The value 120 configures the system to log metrics every 120 seconds.
Configure the scheduler frequency by using a recipe
In the metric-log-config.json recipe, add the metric.log.interval property to the com.soa.metric.log PID. The following example configures the system to log metrics every 120 seconds:
{
"pid": "com.soa.metric.log",
"update": {
"metric.log.enabled": "true",
"metric.log.health.ids": "akana-monitoring",
"metric.log.interval": 120
}
Run the recipe by using the following structure:
./jython.sh -m akana.container --recipe ../recipes/metric-log-config.json --name <container-name> --home <application-runtime-path>