Skip to content

Instantly share code, notes, and snippets.

@pilhuhn
Created January 18, 2018 13:58
Show Gist options
  • Save pilhuhn/3fd62a2447edd027bd607503c75b3abe to your computer and use it in GitHub Desktop.
Save pilhuhn/3fd62a2447edd027bd607503c75b3abe to your computer and use it in GitHub Desktop.

MicroProfile Metrics and Applications (and other specs)

Currently we assume one MicroProfile Server == 1 Application (deployment). This may hold true, but some severs implementing MicroProfile allow to deploy more than one app and those need to be addressed as well.

Applications

The Scenarios

  • Scenario 1: as today one server hosts 1 app with 1 context-root

  • Scenario 2: a server hosts more than one 1 app, where it is possible that metric names overlap

Data structures

Application data currently lives in the application scope and can be retrieved from /metrics/application/. Internally this corresponds to a MetricsRegistry with the name 'application'. This also covers scenario 1.

For scenario 2 we need to provide a registry per application. There are 2 options

  1. Sub-registries below application

  2. A (main) registry per application. Here we have again options in case of scenario 1

    1. continue to use 'application'

    2. require the application to provide a name (or let the server pick a value)

In any case the registries need a name. Metrics should try to determine that automatically from the deployment. The following come to mind

  • Get context-root from configuration

  • Get the value from @ApplicationPath in case of JAX-RS

If both does not work or the user wants to use a different name, we can add an annotation @MetricRegistryName(<name>) on a deployment level, that provides the name.

The server MUST reject two applications providing the same name and throw an IllegalArgumentException.

Once a (Sub)Registry has been provided per deployment, Metrics are added to it as of today.

The implementation MUST ensure that an application can only write into its own registry and. For reading no restriction exists (It could get that from /metrics if wanted).

Requesting data

So far we have the scopes where data of a scope can be retrieved via

GET /metrics/<scope>

If we do not use sub-registries below the application one, we need to tag them as being application registries — especially if we decide to add more parallel registries in the future. One could in theory, for a request to /metrics/application, just require that everything is returned that is neither base nor vendor.

We also currently support getting individual metrics

GET /metrics/application/hitCount

This makes it more complicated to introduce the applications below /metrics/application in a way that easily works for scenario 1 and 2 and which is compatible with what we have today. A big question here is certainly if users are actually addressing those individual metrics or if they only request bundles of the entire data.

If we decide that addressing individual metrics is out of scope going forward, we can use this to put the applications in this place

GET /metrics/application/A would then return the metrics of the registry with name A. Only requesting GET /metrics/application would return all application metrics as before.

Exports as Json

For Json output format, we currently pretty much follow the hierarchy on the http-request path. With support for multiple applications we would also introduce the hierarchy there

{
  "application":{
     "A": {
        "hitCount" : 3
     },
     "B": {
        "hitCount" : 4,
        "errors" : 42
     }
  },
  "base":....

Exports in Prometheus format

For Prometheus using labels to identify the deployed application looks like a good choice. A label of registry=<name> could be used (other keys are doable too)

Note
I would not name the label key 'app' or 'application', as an application may include more than the MP-server.

So with applications A and B and a metric with name 'hit.count' the result could look like

application:hit_count{registry=A} 123.1
application:hit_count{registry=B} 42.0

When only one application is deployed (scenario 1), the registry label could be omitted.

Other specs

Related to the above there are specs like FaultTolerance that should be able to expose their data in well-known places.

There are several options to place this

  • new top-level scope "integration"

  • within application scope per application

The place probably depends on if the specification is a per-application one (like FT) or a once per-server one.

Third-party stuff

Related to the above :-) We want to also provide a place where other technologies could expose their data. While one could argue that this can go into the vendor space, there may be common technologies like Servlets, that are not part of MicroProfile, but which are very common from the Java EE "legacy".

Those should nevertheless end up in places that are "well known" — at least for data that is common for the various implemntations.

@donbourne
Copy link

what are the cases today where we can't determine the application name at metric registration time?

where would @MetricRegistryName() be placed?

"The implementation MUST ensure that an application can only write into its own registry"
seems expensive to enforce this. might be safer to say any metrics created by an app must go into its own registry

"This makes it more complicated to introduce the applications below /metrics/application in a way that easily works for scenario 1 and 2 and which is compatible with what we have today."
could things like GET /metrics/application/hitCount just return that subtree? if it is a single metric, return one metric...if it is an entire application subtree, return the whole subtree

"I would not name the label key 'app' or 'application', as an application may include more than the MP-server."
not sure I get why 'app' would be bad, even if app includes more than one server... wouldn't that just show the collection of metrics that are related to that app on that server?

@donbourne
Copy link

like this form for querying (for individual metric) : /metrics/application/_/hitCount

a registry per app might be nice - can remove the whole registry when the app goes away

add FT and others to application registry - perhaps with a well known name at start of metric name

put app name in the config (the config spec)?

do some investigation - where could we put the default app name

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment