Expose Prometheus-compatible metrics

You can expose metrics collected by an input module using NXLog Agent’s Prometheus output module. This module starts an HTTP listener that Prometheus can scrape on demand.

The following examples show how to expose Windows Performance Counters and Osquery metrics to a Prometheus scrape endpoint. NXLog Platform also provides configuration templates for both sources, making setup easier with pre-built configurations.

Expose metrics from Windows Performance Counters

Windows Performance Counters provide a wide range of host metrics, including CPU, memory, and disk usage. The following example collects total CPU usage across all processors and exposes it as a Prometheus gauge.

Example 1. Exposing Windows CPU usage to Prometheus

This configuration collects total processor utilization with the Windows Performance Counters input module. It uses the Rewrite extension to rename the counter field to a Prometheus-compatible name and retain only necessary fields. The Prometheus output module exposes the metric on port 9400.

nxlog.conf
<Extension rewrite>
    Module          xm_rewrite
    Rename          ${\Processor(_Total)\% Processor Time}, $cpu_usage_percent (1)
    Keep            Hostname, cpu_usage_percent
</Extension>

<Input winperfcount>
    Module          im_winperfcount
    Counter         \Processor(_Total)\% Processor Time (2)
    PollInterval    60
    Exec            rewrite->process();
</Input>

<Output prometheus>
    Module          om_prometheus
    ListenAddr      0.0.0.0:9400 (3)
    MappingFile     'C:\Program Files\nxlog\conf\prometheus_mapping.json' (4)
</Output>
<Route r1>
    Path            winperfcount => prometheus
</Route>
1 Renames the counter field to cpu_usage_percent.
2 Collects total processor utilization across all CPUs using the _Total instance.
3 Accepts Prometheus scrape requests on all interfaces at port 9400.
4 Loads metric type and label definitions from the mapping file defined below.
prometheus_mapping.json
{
  "metrics": {
    "gauge": [
      { "name": "cpu_usage_percent", "labels": ["Hostname"] }
    ]
  }
}

When Prometheus scrapes the endpoint, it receives the following output.

Output sample
# TYPE cpu_usage_percent gauge
cpu_usage_percent{Hostname="SRV01"} 5.661893

Expose metrics from Osquery

Osquery can query CPU load, memory, and disk usage directly from the operating system. The following example collects Osquery metrics and exposes them through a single Prometheus scrape endpoint.

Example 2. Exposing system metrics to Prometheus

This configuration uses the Osquery input module with two scheduled queries. An Exec block assigns the query results to named fields. The Prometheus output module exposes the metrics on port 9400.

nxlog.conf
<Extension rewrite>
    Module                xm_rewrite
    Keep                  Hostname, cpu_load_1m, memory_total_bytes, memory_free_bytes
</Extension>

<Input osquery>
    Module                im_osquery

    <QueryMap>
        Name              cpu_load   (1)
        Query             "SELECT average FROM load_average WHERE period = '1m'"
        Interval          60
        OsqueryEventType  Added
    </QueryMap>

    <QueryMap>
        Name              memory   (2)
        Query             "SELECT memory_total, memory_free FROM memory_info"
        Interval          60
        OsqueryEventType  Added
    </QueryMap>

    <Exec>
        if defined($columns('average')) {
            $cpu_load_1m = $columns('average');
        }
        else if defined($columns('memory_total')) {
            $memory_total_bytes = $columns('memory_total');
            $memory_free_bytes = $columns('memory_free');
        }

        rewrite->process();
    </Exec>
</Input>

<Output prometheus>
    Module              om_prometheus
    ListenAddr          0.0.0.0:9400   (3)
    MappingFile         /opt/nxlog/etc/prometheus_mapping.json   (4)
</Output>

<Route r1>
    Path                osquery => prometheus
</Route>
1 Queries the one-minute CPU load average from the load_average table every 60 seconds.
2 Queries total and free memory from the memory_info table every 60 seconds.
3 Accepts Prometheus scrape requests on all interfaces at port 9400.
4 Loads metric type and label definitions from the mapping file defined below.
prometheus_mapping.json
{
  "metrics": {
    "gauge": [
      { "name": "cpu_load_1m", "labels": ["Hostname"] },
      { "name": "memory_total_bytes", "labels": ["Hostname"] },
      { "name": "memory_free_bytes", "labels": ["Hostname"] }
    ]
  }
}

When Prometheus scrapes the endpoint, it receives the following output.

Output sample
# TYPE cpu_load_1m gauge
cpu_load_1m{Hostname="SRV02"} 1.25
# TYPE memory_total_bytes gauge
memory_total_bytes{Hostname="SRV02"} 8589934592
# TYPE memory_free_bytes gauge
memory_free_bytes{Hostname="SRV02"} 3145728000