Metrics

Last modified: July 25, 2025

Introduction

Mendix supports reporting metrics through Micrometer.

The Metrics can be configured in the following ways:

Metrics Registries Configuration

Micrometer can send metrics to multiple registries. To configure micrometer for a specific registry, use the following syntax in runtime settings with the custom runtime setting name Metrics.Registries. See Runtime Customization for more information. The setting is in JSON format.

  • Custom Runtime Setting – Name: Metrics.Registries
[
  {
    "type": "<registry1>",
    "settings": { <settings> },
    "filters": [ <list-of-filters> ]
  },
  {
    "type": "<registry2>",
    "settings": { <settings> },
    "filters": [ <list-of-filters> ]
  },
  
]

The details of each settings are listed below.

  • type (mandatory) – the type of registry to use. Currently supported types are prometheus, jmx, influx, statsd, and opentelemetry. Depending on the type of the registry the settings may vary.
  • settings (conditional mandatory) – settings for the registry. Each registry has different settings depending upon the type specified. Follow the links below to see the settings for each type:
  • filters (optional) – instructions on which metrics to accept or deny. See the Filters section, below, for more information.

Settings

The following settings can be used, depending on the type of metrics being generated:

SettingDataTypeManda-toryTypeDescriptionDefault ValueExamples
dbStringNoinfluxthe database to which to send the metricsmydbcustomDb, metricDb
passwordStringYesinfluxAuthenticate requests with this password--
uriStringNoinfluxThe URI for the back endhttp://localhost:8086 (for Influx)-
urlStringNoopentelemetryThe URL for the back endhttp://localhost:4318/v1/metrics-
userNameStringYesinfluxAuthenticate requests with this user--
protocolStringNoinfluxProtocol of the statsd connectionUDPTCP, UDP
domainStringNojmxJmx domain to publish the metrics tometrics"Mendix", "Employee"
enabledBooleanNoinflux / statsdEnables / Disables the metertruetrue, false
flavorStatsdFlavorNostatsdThe variant of the StatsD protocolDATADOGETSY, TELEGRAF, SYSDIG
hostStringNostatsdThe host name of the StatsD agentlocalhost-
portIntNostatsdThe port of the StatsD agent8125-
stepDurationNoallThe step size (reporting frequency) to use1m1ms, 2s, 3m, 4h, 5d or ISO8601 -> P3Y6M4DT12H30M5S
filtersJsonNoallCustom setting from Mendix to filter metrics-See below
aggregationTemporalityStringNoopentelemetryDetermines how the additive quantities are expressed, in relation to timecumulativecumulative or delta
headersStringNoopentelemetryAdditional headers to send with exported metrics, this can be used for authorization headers-"header1=value1,header2=value2"
resourceAttributesStringNoopentelemetryList of attributes which can be used for including information about the environment-"attribute1=value1,attribute2=value2"

Prometheus

We do not support multiple Prometheus. When the Prometheus registry is set, it can be accessed through the /prometheus context path over the admin endpoint.

  • step – the step size or reporting frequency to use.

Example 1

[
  {
    "type": "prometheus",
    "settings": {
      "step": "3m"
    }
  }
]

Example 2

[
  {
    "type": "prometheus",
    "settings": {
      "step": "P3Y6M4DT12H30M5S"
    }
  }
]

Jmx

  • step – The step size or reporting frequency to use.
  • domain – The Jmx domain to which to publish the metrics.

Example 1

[
  {
    "type": "jmx",
    "settings": {
      "step": "3m",
      "domain": "Mendix"
    }
  }
]

Example 2

[
  {
    "type": "jmx",
    "settings": {
      "step": "P3Y6M4DT12H30M5S"
    }
  }
]

Influx

  • uri – the URI for the Influx back end.
  • db – the database name to which to send the metrics.
  • userName – the userName for authentication.
  • password – the password for authentication.
  • step – the step size or reporting frequency to use.
  • enabled – set to true to enable the registry. This means you can switch the meter on and off while keeping the settings in the configuration.

Example 1

[
  {
    "type": "influx",
    "settings": {
      "userName": "mendix",
      "password": "MayBeThis**"
    }
  }
]

Example 2

[
  {
    "type": "influx",
    "settings": {
      "uri": "http://mendix.influx.com",
      "db": "mx.metrics",
      "userName": "mendix",
      "password": "MayBeThis**",
      "step": "P2Y6M4DT12H21M5S"
    }
  }
]

StatsD

  • flavor – specifies the variant of the StatsD protocol to use.
  • host – the host name of the StatsD agent.
  • port – the port used by the StatsD agent.
  • step – the step size or reporting frequency to use.
  • protocol – the protocol of the connection.
  • enabled – set to true to enable the registry. This means you can switch the meter on and off while keeping the settings in the configuration.

Example 1

[
  {
    "type": "statsd",
    "settings": {
      "host": "mx.datadog.com",
      "port": "8181",
      "protocol": "TCP",
      "flavor": "TELEGRAF"
    }
  }
]

Example 2

[
  {
    "type": "statsd",
    "settings": {
      "flavor": "SYSDIG",
      "step": "3m"
    }
  }
]

OpenTelemetry

  • url – the OpenTelemetry metrics endpoint url to which data is reported.
  • aggregationTemporality – determines how the additive quantities are expressed, in relation to time. The supported values are cumulative or delta. Defaults to cumulative.
  • headers – additional headers to send with exported metrics, this can be used for authorization headers.
  • step – the step size or reporting frequency to use.
  • resourceAttributes – additional attributes used for all metrics published. You can use this, for example, to include information about the environment.
  • enabled – set to true to enable the registry. This means you can switch the meter on and off while keeping the settings in the configuration.

Example 1

[
  {
    "type": "opentelemetry",
    "settings": {
      "url": "http://localhost:4318/v1/metrics",
      "step": "30s"
    }
  }
]

Example 2

[
  {
    "type": "opentelemetry",
    "settings": {
      "url": "https://otlp.example.com:4318/v1/metrics",
      "aggregationTemporality": "delta",
      "step": "20s",
      "headers": "header1=value1,header2=value2",
      "resourceAttributes": "service.name=shoppingcart,env=test"
    }
  }
]

Filters

Filters are optional, but can help in filtering metrics based on given criteria. Below is the syntax:

"filters" : [
  {"type" : "<filter-type>", "result" : "filter-result", "values": [ "<list-of-filter-values>"] }
]
  • filter-type – the type of filter to apply. Currently we support the following:
    • nameStartsWith – matches the metric if its name begins with the given list-of-filter-values.
  • filter-result – the desired result of applying the filter-type to the list-of-filter-values. Supported values are:
    • accept – metrics matching the criteria are passed to the registry
    • deny – metrics matching the criteria are not passed to the registry
  • list-of-filter-values – a list of values used in the given filter type

Example 1

[
  {
    "type": "statsd",
    "settings": { "protocol": "TCP" },
    "filters": [
      { "type" : "nameStartsWith", "result" : "accept", "values" : ["app.", "employee.", "myapp."] }
    ]
  }
]

The above filter accepts metrics which starts with app., employee., or myapp..

Example 2

[
  {
    "type": "influx",
    "settings": {
      "userName": "mendix",
      "password": "MayBeThis**"
    },
    "filters": [
      { "type" : "nameStartsWith", "result" : "deny", "values" : ["Unnamed.", "Invalid.", "Internal."] }
    ]
  }
]

The above filter discards metrics which start with Unnamed., Invalid., or Internal..

Notes

  1. Filters also affect internal metrics used by Mendix. For example, metrics emitted by Mendix which start with mx..

  2. If you have two metrics with the same name but one has additional tags, these are considered as different metrics. For example, metrics app.counter1 with tag "version" -> "1" and app.counter1 with no tag are different.

  3. Filters are executed on a first come, first served basis. In other words, the first matching filter gets the priority. For example, take the filters defined below:

    [
      {
        "type": "statsd",
        "settings": { "protocol": "TCP" },
        "filters": [
          { "type" : "nameStartsWith", "result" : "accept", "values" : ["app."] },
          { "type" : "nameStartsWith", "result" : "deny", "values" : ["app.others."] }
        ]
      }
    ]

    This example allows metrics like app.others.counter as they pass the first accept filter, nameStartsWith "app.". However, if you reverse the filters, app.others.counter would be denied, while app.somethingelse. would still be accepted.

  4. To accept only specific filters and deny all others, add a deny filter with the value "" as the last filter. For example, to accept only metrics starting with app.

    [
      {
        "type": "statsd",
        "settings": { "protocol": "TCP" },
        "filters": [
          { "type" : "nameStartsWith", "result" : "accept", "values" : ["app."] },
          { "type" : "nameStartsWith", "result" : "deny", "values" : [""] }
        ]
      }
    ]

Application Tags

Common tags which should be reported by every metric can be specified using the Metrics.ApplicationTags setting. This setting should be in JSON format.

  • Custom Runtime Setting – Name: Metrics.ApplicationTags
{
  "hostId": "7a3c0356-4dab-42ab-a139-87efb497f3e9",
  "environment": "prod"
}

Microflow Activities

You can use activities to provide custom metrics from your app. See Metrics Activities for information about these activities .

Java API

Micrometer metrics can be accessed through Mendix Runtime Java APIs as well inside Mendix. This can be achieved by using the custom runtime setting com.mendix.metrics.Type. This setting defaults to micrometer.

  • Custom Runtime Setting – Name: com.mendix.metrics.Type
  • Value: micrometer

Current Metrics and Usage

Currently supported metrics are counter, gauge, and timer. We support Bloch's builder pattern to create the metrics and support Tag and Description which can be added to each metric.

To create the metrics,

import com.mendix.metrics.Counter;
import com.mendix.core.Core;


// Create a counter
Counter counter1 = Core.metrics().createCounter("app.strikes")
                                .withTag("app", "myapp")
                                .withDescription("Metrics to count the strike outs")
                                .build();
Counter counter2 = Core.metrics().createCounter("app.count").build();

In the same way, we can also create a gauge and a timer using the createGauge and createTimer methods respectively.

The name must adhere to the following rules:

  • The name can only contain alpha-numeric characters, dots or underscores.
  • The name must start with a letter.
  • The name cannot start with mx, because this prefix is reserved for Mendix internal metrics.
  • The name is case-insensitive.

⚠ Deprecated Usages

The following deprecated usages will be removed in the future releases,

  1. The Core.metrics() Mendix Runtime Java API methods counter(), timer(), gauges(), and sets(), and the corresponding Counters, Timers, Gauges and Sets interfaces are deprecated.

Logging

Metering-related log messages are sent to the Metering log node. If a registry is enabled, they will be reported with severity debug.

List of Metrics

The Runtime Server produces various metrics. Some of these metrics are controlled by Mendix: these are prefixed with mx.

Other metrics are produced by Micrometer, the library that is used for metrics. This library outputs metrics for other libraries that it recognizes, such as the Jetty server that is embedded in the Runtime Server. These additional Micrometer metrics are not under our control and might change.

Runtime Server Metrics

The Runtime Server produces the following metrics out-of-the-box:

NameTypeTagsDescription
mx.runtime.stats.handler_requestscounterXASId, nameThe total number of requests on a request handler (name) that were received by a node (XASId) since it was started.
mx.runtime.stats.sessions.named_usersgaugeThe current number of active, named users in the database.
mx.runtime.stats.sessions.named_user_sessionsgaugeThe current number of sessions in the database for named users.
mx.runtime.stats.sessions.anonymous_sessionsgaugeThe current number of sessions in the database for anonymous users.
mx.runtime.stats.connectionbus.transactionscounterXASIdThe total number of transactions on the database that were created by a node (XASId) since it was started.
mx.runtime.stats.connectionbus.selectscounterXASIdThe total number of SELECT statements that were executed on the database by a node (XASId) since it was started.
mx.runtime.stats.connectionbus.insertscounterXASIdThe total number of INSERT statements that were executed on the database by a node (XASId) since it was started.
mx.runtime.stats.connectionbus.updatescounterXASIdThe total number of UPDATE statements that were executed on the database by a node (XASId) since it was started.
mx.runtime.stats.connectionbus.deletescounterXASIdThe total number of DELETE statements that were executed on the database by a node (XASId) since it was started.
mx.odata.consume.createdcounterentityThe total number of objects of a certain entity type (entity) that were created using the Send External Object activity.
mx.odata.consume.updatedcounterentityThe total number of objects of a certain entity type (entity) that were updated using the Send External Object activity.
mx.odata.consume.deletedcounterentityThe total number of objects of a certain entity type (entity) that were created using the Delete External Object activity.
mx.odata.publish.objectscounterentityThe total number of objects that were served for a particular type of object (entity) by a published OData/GraphQL service.
mx.odata.publish.createdcounterentityThe total number of objects of a certain entity type (entity) that were created due to client requests to a published OData service.
mx.odata.publish.updatedcounterentityThe total number of objects of a certain entity type (entity) that were updated due to client requests to a published OData service.
mx.odata.publish.deletedcounterentityThe total number of objects of a certain entity type (entity) that were deleted due to client requests to a published OData service.
mx.odata.retrievecounterentityThe total number of objects of a certain entity type (entity) that were retrieved from an OData service.

Additional Metrics

System and Process Metrics

NameTypeDescription
system.cpu.countgaugeThe number of processors available to the Java Virtual Machine.
system.cpu.usagegaugeThe recent CPU usage of the system the Runtime Server is running on (in the range [0…1]).
system.load.average.1mgaugeThe average number of runnable (queued and running) threads on the available processors.
process.cpu.usagegaugeThe recent CPU usage for the Java Virtual Machine process (in the range [0…1]).

Java Virtual Machine Metrics

NameTypeTagsDescription
jvm_infogaugevendor, runtime, versionDetails about the Java Virtual Machine (represented in the tags, the value is always 1).
jvm.classes.loadedgaugeThe number of classes that are currently loaded in the Java Virtual Machine.
jvm.classes.unloadedcounterThe total number of classes unloaded since the Java Virtual Machine started execution.
jvm.buffer.countgaugeidAn estimate of the number of buffers in a Java Virtual Machine memory pool (id).
jvm.buffer.memory_usedgaugeidAn estimate of the memory (in bytes) that the Java Virtual Machine is using for a buffer pool (id).
jvm.buffer.total_capacitygaugeidAn estimate of the total capacity (in bytes) of the buffers in a buffer pool (id).
jvm.memory.usedgaugeid, areaThe amount of memory (in bytes) used for a certain area (area): heap or nonheap.
jvm.memory.committedgaugeid, areaThe amount of memory (in bytes) that is committed for the Java Virtual Machine to use.
jvm.memory.maxgaugeid, areaThe maximum amount of memory (in bytes) that can be used for memory management.
jvm.memory.usage.after.gcgaugearea, poolThe percentage of long-lived heap pool used after the last Garbage Collection (GC) event (in the range [0…1]).
jvm.threads.live_threadsgaugeThe current number of live threads (both daemon and non-daemon threads).
jvm.threads.daemon_threadsgaugeThe current number of live daemon threads.
jvm.threads.peak_threadsgaugeThe peak live thread count since the Java Virtual Machine started or peak was reset.
jvm.threads.states_threadsgaugestateThe current number of threads having in a certain state (state).
jvm.gc.live.data.sizegaugeThe current size (in bytes) of the long-lived heap memory pool.
jvm.gc.max.data.sizegaugeThe maximum size (in bytes) of the long-lived heap memory pool.
jvm.gc.memory.allocatedcounterIncremented for an increase in the size of the (young) heap memory pool after one GC to before the next.
jvm.gc.memory.promotedcounterCount of positive increases in the size of the old generation memory pool before GC or to after GC.
jvm.gc.pausetimeraction, causeThe time spent in GC pause.
jvm.gc.concurrent.phase.timetimeraction, causeThe time spent in the concurrent GC phase.
jvm.gc.overheadgaugeAn approximation of the percent of CPU time used by GC activities over the last lookback period or since monitoring began, whichever is shorter (in the range [0…1]).

Refer to the Java Virtual Machine documentation for more details.

Jetty HTTP Server Metrics

NameTypeDescription
jetty.connections.messages.incounterThe number of messages received by tracked connections.
jetty.connections.messages.outcounterThe number of messages sent by tracked connections.
jetty.connections.bytes.ingaugeThe number of bytes received by tracked connections.
jetty.connections.bytes.outgaugeThe number of bytes sent by tracked connections.
jetty.connections.currentgaugeThe current number of open Jetty connections.
jetty.connections.maxgaugeThe maximum number of observed connections over a rolling 2-minute interval.
jetty.threads.currentgaugeThe total number of threads in the Jetty pool.
jetty.threads.idlegaugeThe number of idle threads in the Jetty pool.
jetty.threads.busygaugeThe number of busy threads in the Jetty pool.
jetty.threads.jobsgaugeThe number of jobs queued waiting for a thread.
jetty.threads.config.mingaugeThe minimum number of threads in the Jetty pool.
jetty.threads.config.maxgaugeThe maximum number of threads in the Jetty pool.

Database Connection Pool Metrics

NameTypeDescription
commons.pool2.num.idlegaugeThe number of connections currently idle in the pool.
commons.pool2.num.activegaugeThe number of connections currently active in the pool.
commons.pool2.num.waitersgaugeAn estimate of the number of threads currently blocked waiting for a connection from the pool.
commons.pool2.mean.activegaugeThe mean time for which connections are active.
commons.pool2.mean.idlegaugeThe mean time for which connections are idle.
commons.pool2.mean.borrow.waitgaugeThe mean time threads wait to get a connection.
commons.pool2.max.borrow.waitgaugeThe maximum time a thread has waited to get a connection from the pool.
commons.pool2.createdcounterThe total number of connections created for the pool over its lifetime.
commons.pool2.borrowedcounterThe total number of connections borrowed from the pool over its lifetime.
commons.pool2.returnedcounterThe total number of connections returned to the pool over its lifetime.
commons.pool2.destroyedcounterThe total number of connections destroyed by the pool over its lifetime.
commons.pool2.destroyed.by.evictorcounterThe total number of connections destroyed by the evictor associated with the pool over its lifetime.
commons.pool2.destroyed.by.borrow.validationcounterThe total number of connections destroyed by the pool over its lifetime as a result of failing validation during borrowing.

Read More