diff --git a/micronaut-camunda-bpm-example/build.gradle b/micronaut-camunda-bpm-example/build.gradle
index c0660fd13..c65432938 100644
--- a/micronaut-camunda-bpm-example/build.gradle
+++ b/micronaut-camunda-bpm-example/build.gradle
@@ -16,6 +16,13 @@ micronaut {
dependencies {
implementation(project(":micronaut-camunda-bpm-feature"))
+
+ // imported to enable http endpoint for metrics
+ implementation("io.micronaut:micronaut-management")
+
+ // imported to activate metrics
+ implementation("io.micronaut.micrometer:micronaut-micrometer-core")
+
runtimeOnly("com.h2database:h2")
runtimeOnly("ch.qos.logback:logback-classic")
diff --git a/micronaut-camunda-bpm-example/src/main/resources/application.yml b/micronaut-camunda-bpm-example/src/main/resources/application.yml
index 2386cb6fe..3fd025fa0 100644
--- a/micronaut-camunda-bpm-example/src/main/resources/application.yml
+++ b/micronaut-camunda-bpm-example/src/main/resources/application.yml
@@ -1,6 +1,22 @@
micronaut:
application:
name: micronaut-camunda-example
+ metrics:
+ export:
+ logging:
+ enabled: true
+ binders:
+ camunda:
+ enabled: true
+ bpmnExecution:
+ enabled: true
+ dmnExecution:
+ enabled: true
+ jobExecutor:
+ enabled: true
+ historyCleanUp:
+ enabled: true
+
camunda:
admin-user:
id: admin
diff --git a/micronaut-camunda-bpm-feature/build.gradle b/micronaut-camunda-bpm-feature/build.gradle
index 01c31ea67..ded15711e 100644
--- a/micronaut-camunda-bpm-feature/build.gradle
+++ b/micronaut-camunda-bpm-feature/build.gradle
@@ -24,6 +24,7 @@ dependencies {
implementation("io.micronaut:micronaut-runtime")
api("org.camunda.bpm:camunda-engine:$camundaVersion")
+ compileOnly("io.micronaut.micrometer:micronaut-micrometer-core")
compileOnly("io.micronaut.servlet:micronaut-servlet-engine")
compileOnly("io.micronaut:micronaut-http-server-netty")
compileOnly("io.micronaut.servlet:micronaut-http-server-jetty")
diff --git a/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/BpmnExecutionMetrics.java b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/BpmnExecutionMetrics.java
new file mode 100644
index 000000000..3b0be571a
--- /dev/null
+++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/BpmnExecutionMetrics.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2021 original authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package info.novatec.micronaut.camunda.bpm.feature.metrics;
+
+import io.micronaut.configuration.metrics.annotation.RequiresMetrics;
+import io.micronaut.context.BeanProvider;
+import io.micronaut.context.annotation.Requires;
+import io.micronaut.core.util.StringUtils;
+import org.camunda.bpm.engine.ManagementService;
+import org.camunda.bpm.engine.management.Metrics;
+
+import javax.inject.Singleton;
+
+import static io.micronaut.configuration.metrics.micrometer.MeterRegistryFactory.MICRONAUT_METRICS_BINDERS;
+
+/**
+ * Holder class to count bpmn execution metrics.
+ *
+ * It is not possible to execute the following code directly in BpmnExectionMetricsBinder
+ *
+ * Gauge.builder("MyMetricName", providerManagementService.get().createMetricsQuery().name(Metrics.ROOT_PROCESS_INSTANCE_START), MetricsQuery::sum).register(...)
+ *
+ * therefore we have this HolderClass.
+ */
+@Singleton
+@RequiresMetrics
+@Requires(property = MICRONAUT_METRICS_BINDERS + ".camunda.enabled", value = StringUtils.TRUE, defaultValue = StringUtils.FALSE)
+@Requires(property = MICRONAUT_METRICS_BINDERS + ".camunda.bpmnExecution.enabled", value = StringUtils.TRUE, defaultValue = StringUtils.FALSE)
+public class BpmnExecutionMetrics extends CamundaMetrics {
+
+ public BpmnExecutionMetrics(BeanProvider providerManagementService) {
+ super(providerManagementService);
+ }
+
+ public long countRootProcessInstanceStart() {
+ return sumMetric(Metrics.ROOT_PROCESS_INSTANCE_START);
+ }
+
+ public long countActivityInstanceStart() {
+ return sumMetric(Metrics.ACTIVTY_INSTANCE_START);
+ }
+
+ public long countActivityInstanceEnd() {
+ return sumMetric(Metrics.ACTIVTY_INSTANCE_END);
+ }
+
+}
diff --git a/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/BpmnExecutionMetricsBinder.java b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/BpmnExecutionMetricsBinder.java
new file mode 100644
index 000000000..c259d0bb5
--- /dev/null
+++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/BpmnExecutionMetricsBinder.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2021 original authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package info.novatec.micronaut.camunda.bpm.feature.metrics;
+
+import io.micrometer.core.instrument.Gauge;
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.Tags;
+import io.micrometer.core.instrument.binder.MeterBinder;
+import io.micrometer.core.lang.NonNull;
+import io.micronaut.configuration.metrics.annotation.RequiresMetrics;
+import io.micronaut.context.annotation.Requires;
+import io.micronaut.core.util.StringUtils;
+import org.camunda.bpm.engine.management.Metrics;
+
+import javax.inject.Singleton;
+
+import static info.novatec.micronaut.camunda.bpm.feature.metrics.CamundaMetricsBinderTags.BPMN_EXECUTION_DEFAULT_TAGS;
+import static info.novatec.micronaut.camunda.bpm.feature.metrics.CamundaMetricsBinderTags.TAG_KEY_NAME;
+import static io.micronaut.configuration.metrics.micrometer.MeterRegistryFactory.MICRONAUT_METRICS_BINDERS;
+
+/**
+ * Provides Metrics about BPMN Execution.
+ */
+@Singleton
+@RequiresMetrics
+@Requires(property = MICRONAUT_METRICS_BINDERS + ".camunda.enabled", value = StringUtils.TRUE, defaultValue = StringUtils.FALSE)
+@Requires(property = MICRONAUT_METRICS_BINDERS + ".camunda.bpmnExecution.enabled", value = StringUtils.TRUE, defaultValue = StringUtils.FALSE)
+public class BpmnExecutionMetricsBinder implements MeterBinder {
+
+ protected final BpmnExecutionMetrics bpmnExecutionMetrics;
+
+ public BpmnExecutionMetricsBinder(BpmnExecutionMetrics bpmnExecutionMetrics) {
+ this.bpmnExecutionMetrics = bpmnExecutionMetrics;
+ }
+
+ @Override
+ public void bindTo(@NonNull MeterRegistry registry) {
+
+ /*
+ This Code
+
+ Gauge.builder("camunda.bpmn." + Metrics.ROOT_PROCESS_INSTANCE_START.replace('-', '.'),
+ providerManagementService.get().createMetricsQuery().name(Metrics.ROOT_PROCESS_INSTANCE_START),
+ MetricsQuery::sum
+ ).description("The number of root process instance executions started. This is also known as Root Process Instances (RPI). A root process instance has no parent process instance, i.e. it is a top-level execution.")
+ .tags(Tags.concat(BPMN_EXECUTION_DEFAULT_TAGS, TAG_KEY_NAME, Metrics.ROOT_PROCESS_INSTANCE_START))
+ .register(registry);
+
+ is executed to early and the bean for providerManagementService is not instanciated
+ so that we would run into a boot loop and then the application crashes.
+
+ To avoid this, we implemented some "holder" objects. In this case info.novatec.micronaut.camunda.bpm.feature.metrics.BpmnExecutionMetrics
+ */
+ Gauge.builder(
+ createMetricName(Metrics.ROOT_PROCESS_INSTANCE_START),
+ bpmnExecutionMetrics,
+ BpmnExecutionMetrics::countRootProcessInstanceStart
+ )
+ .description("The number of root process instance executions started. This is also known as Root Process Instances (RPI). A root process instance has no parent process instance, i.e. it is a top-level execution.")
+ .tags(Tags.concat(BPMN_EXECUTION_DEFAULT_TAGS, TAG_KEY_NAME, Metrics.ROOT_PROCESS_INSTANCE_START))
+ .register(registry);
+
+ Gauge.builder(
+ createMetricName(Metrics.ACTIVTY_INSTANCE_START),
+ bpmnExecutionMetrics,
+ BpmnExecutionMetrics::countActivityInstanceStart
+ )
+ .description("The number of activity instances started. This is also known as flow node instances (FNI).")
+ .tags(Tags.concat(BPMN_EXECUTION_DEFAULT_TAGS, TAG_KEY_NAME, Metrics.ACTIVTY_INSTANCE_START))
+ .register(registry);
+
+ Gauge.builder(
+ createMetricName(Metrics.ACTIVTY_INSTANCE_END),
+ bpmnExecutionMetrics,
+ BpmnExecutionMetrics::countActivityInstanceEnd
+ )
+ .description("The number of activity instances ended.")
+ .tags(Tags.concat(BPMN_EXECUTION_DEFAULT_TAGS, TAG_KEY_NAME, Metrics.ACTIVTY_INSTANCE_END))
+ .register(registry);
+ }
+
+ private String createMetricName(String camundaName) {
+ return "camunda.bpmn." + camundaName.replace('-', '.');
+ }
+
+}
diff --git a/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/CamundaMetrics.java b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/CamundaMetrics.java
new file mode 100644
index 000000000..3f75d47cb
--- /dev/null
+++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/CamundaMetrics.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2021 original authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package info.novatec.micronaut.camunda.bpm.feature.metrics;
+
+import io.micronaut.context.BeanProvider;
+import io.micronaut.context.exceptions.BeanInstantiationException;
+import org.camunda.bpm.engine.ManagementService;
+import org.camunda.bpm.engine.management.MetricsQuery;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Base class to use inbuild camunda metrics.
+ * see also https://docs.camunda.org/manual/latest/user-guide/process-engine/metrics/
+ */
+abstract public class CamundaMetrics {
+
+ protected final BeanProvider providerManagementService;
+
+ protected final Map metricsQueryMap = new HashMap<>();
+
+ protected CamundaMetrics(BeanProvider providerManagementService) {
+ this.providerManagementService = providerManagementService;
+ }
+
+ protected long sumMetric(String metricName) {
+ MetricsQuery metricsQuery = getMetricsQuery(metricName);
+ if (metricsQuery != null) {
+ return metricsQuery.sum();
+ }
+ throw new BeanInstantiationException("Camunda MetricsQuery is null");
+ }
+
+ protected MetricsQuery getMetricsQuery(String metricName) {
+ if (metricsQueryMap.containsKey(metricName)) {
+ return metricsQueryMap.get(metricName);
+ }
+ MetricsQuery metricsQuery = providerManagementService.get().createMetricsQuery().name(metricName);
+ metricsQueryMap.put(metricName, metricsQuery); // does not return the initialized metrics query
+ return metricsQuery;
+ }
+
+}
diff --git a/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/CamundaMetricsBinderTags.java b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/CamundaMetricsBinderTags.java
new file mode 100644
index 000000000..f07786b92
--- /dev/null
+++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/CamundaMetricsBinderTags.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 original authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package info.novatec.micronaut.camunda.bpm.feature.metrics;
+
+import io.micrometer.core.instrument.Tag;
+
+import java.util.Arrays;
+
+/**
+ * Constants for our MetricsBinders.
+ */
+public final class CamundaMetricsBinderTags {
+
+ static final String TAG_KEY_NAME = "name";
+
+ static final String TAG_KEY_CATEGORY = "category";
+
+ static final Tag TAG_CLASS_CAMUNDA = Tag.of("class", "camunda");
+
+ static final Iterable JOB_EXECUTOR_DEFAULT_TAGS = Arrays.asList(TAG_CLASS_CAMUNDA, Tag.of(TAG_KEY_CATEGORY, "job-executor"));
+
+ static final Iterable DMN_EXECUTION_DEFAULT_TAGS = Arrays.asList(TAG_CLASS_CAMUNDA, Tag.of(TAG_KEY_CATEGORY, "dmn-execution"));
+
+ static final Iterable BPMN_EXECUTION_DEFAULT_TAGS = Arrays.asList(TAG_CLASS_CAMUNDA, Tag.of(TAG_KEY_CATEGORY, "bpmn-execution"));
+
+ static final Iterable HISTORY_CLEAN_UP_DEFAULT_TAGS = Arrays.asList(TAG_CLASS_CAMUNDA, Tag.of(TAG_KEY_CATEGORY, "history-clean-up"));
+
+ private CamundaMetricsBinderTags() {}
+}
diff --git a/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/DmnExecutionMetrics.java b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/DmnExecutionMetrics.java
new file mode 100644
index 000000000..1a36766f8
--- /dev/null
+++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/DmnExecutionMetrics.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2021 original authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package info.novatec.micronaut.camunda.bpm.feature.metrics;
+
+import io.micronaut.configuration.metrics.annotation.RequiresMetrics;
+import io.micronaut.context.BeanProvider;
+import io.micronaut.context.annotation.Requires;
+import io.micronaut.core.util.StringUtils;
+import org.camunda.bpm.engine.ManagementService;
+import org.camunda.bpm.engine.management.Metrics;
+
+import javax.inject.Singleton;
+
+import static io.micronaut.configuration.metrics.micrometer.MeterRegistryFactory.MICRONAUT_METRICS_BINDERS;
+
+/**
+ * Holder class to count dmn execution metrics.
+ */
+@Singleton
+@RequiresMetrics
+@Requires(property = MICRONAUT_METRICS_BINDERS + ".camunda.enabled", value = StringUtils.TRUE, defaultValue = StringUtils.FALSE)
+@Requires(property = MICRONAUT_METRICS_BINDERS + ".camunda.dmnExecution.enabled", value = StringUtils.TRUE, defaultValue = StringUtils.FALSE)
+public class DmnExecutionMetrics extends CamundaMetrics {
+
+ public DmnExecutionMetrics(BeanProvider providerManagementService) {
+ super(providerManagementService);
+ }
+
+ public long countExecutedDecisionInstances() {
+ return sumMetric(Metrics.EXECUTED_DECISION_INSTANCES);
+ }
+
+ public long countExecutedDecisionElements() {
+ return sumMetric(Metrics.EXECUTED_DECISION_ELEMENTS);
+ }
+
+}
diff --git a/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/DmnExecutionMetricsBinder.java b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/DmnExecutionMetricsBinder.java
new file mode 100644
index 000000000..5d211249d
--- /dev/null
+++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/DmnExecutionMetricsBinder.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2021 original authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package info.novatec.micronaut.camunda.bpm.feature.metrics;
+
+import io.micrometer.core.instrument.Gauge;
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.Tags;
+import io.micrometer.core.instrument.binder.MeterBinder;
+import io.micrometer.core.lang.NonNull;
+import io.micronaut.configuration.metrics.annotation.RequiresMetrics;
+import io.micronaut.context.annotation.Requires;
+import io.micronaut.core.util.StringUtils;
+import org.camunda.bpm.engine.management.Metrics;
+
+import javax.inject.Singleton;
+
+import static info.novatec.micronaut.camunda.bpm.feature.metrics.CamundaMetricsBinderTags.DMN_EXECUTION_DEFAULT_TAGS;
+import static info.novatec.micronaut.camunda.bpm.feature.metrics.CamundaMetricsBinderTags.TAG_KEY_NAME;
+import static io.micronaut.configuration.metrics.micrometer.MeterRegistryFactory.MICRONAUT_METRICS_BINDERS;
+
+/**
+ * Provides Metrics about DMN Execution.
+ */
+@Singleton
+@RequiresMetrics
+@Requires(property = MICRONAUT_METRICS_BINDERS + ".camunda.enabled", value = StringUtils.TRUE, defaultValue = StringUtils.FALSE)
+@Requires(property = MICRONAUT_METRICS_BINDERS + ".camunda.dmnExecution.enabled", value = StringUtils.TRUE, defaultValue = StringUtils.FALSE)
+public class DmnExecutionMetricsBinder implements MeterBinder {
+
+ protected final DmnExecutionMetrics dmnExecutionMetrics;
+
+ public DmnExecutionMetricsBinder(DmnExecutionMetrics dmnExecutionMetrics) {
+ this.dmnExecutionMetrics = dmnExecutionMetrics;
+ }
+
+ @Override
+ public void bindTo(@NonNull MeterRegistry registry) {
+
+ Gauge.builder(
+ createMetricName(Metrics.EXECUTED_DECISION_INSTANCES),
+ dmnExecutionMetrics,
+ DmnExecutionMetrics::countExecutedDecisionInstances
+ )
+ .description("The number of evaluated decision instances (EDI). A decision instance is a DMN decision table or a DMN Literal Expression.")
+ .tags(Tags.concat(DMN_EXECUTION_DEFAULT_TAGS, TAG_KEY_NAME, Metrics.EXECUTED_DECISION_INSTANCES))
+ .register(registry);
+
+ Gauge.builder(
+ createMetricName(Metrics.EXECUTED_DECISION_ELEMENTS),
+ dmnExecutionMetrics,
+ DmnExecutionMetrics::countExecutedDecisionElements
+ )
+ .description("The number of decision elements executed during evaluation of DMN decision tables. For one table, this is calculated as the number of clauses multiplied by the number of rules.")
+ .tags(Tags.concat(DMN_EXECUTION_DEFAULT_TAGS, TAG_KEY_NAME, Metrics.EXECUTED_DECISION_ELEMENTS))
+ .register(registry);
+ }
+
+ private String createMetricName(String camundaName) {
+ return "camunda.dmn." + camundaName.replace('-', '.');
+ }
+
+}
diff --git a/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/HistoryCleanUpMetrics.java b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/HistoryCleanUpMetrics.java
new file mode 100644
index 000000000..71fc948b3
--- /dev/null
+++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/HistoryCleanUpMetrics.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2021 original authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package info.novatec.micronaut.camunda.bpm.feature.metrics;
+
+import io.micronaut.configuration.metrics.annotation.RequiresMetrics;
+import io.micronaut.context.BeanProvider;
+import io.micronaut.context.annotation.Requires;
+import io.micronaut.core.util.StringUtils;
+import org.camunda.bpm.engine.ManagementService;
+import org.camunda.bpm.engine.management.Metrics;
+
+import javax.inject.Singleton;
+
+import static io.micronaut.configuration.metrics.micrometer.MeterRegistryFactory.MICRONAUT_METRICS_BINDERS;
+
+/**
+ * Holder class to count history cleanup execution metrics.
+ */
+@Singleton
+@RequiresMetrics
+@Requires(property = MICRONAUT_METRICS_BINDERS + ".camunda.enabled", value = StringUtils.TRUE, defaultValue = StringUtils.FALSE)
+@Requires(property = MICRONAUT_METRICS_BINDERS + ".camunda.historyCleanUp.enabled", value = StringUtils.TRUE, defaultValue = StringUtils.FALSE)
+public class HistoryCleanUpMetrics extends CamundaMetrics {
+
+ public HistoryCleanUpMetrics(BeanProvider providerManagementService) {
+ super(providerManagementService);
+ }
+
+ public long getRemovedProcessInstances() {
+ return sumMetric(Metrics.HISTORY_CLEANUP_REMOVED_PROCESS_INSTANCES);
+ }
+
+ public long getRemovedDecisionInstances() {
+ return sumMetric(Metrics.HISTORY_CLEANUP_REMOVED_DECISION_INSTANCES);
+ }
+
+ public long getRemovedBatchOperations() {
+ return sumMetric(Metrics.HISTORY_CLEANUP_REMOVED_BATCH_OPERATIONS);
+ }
+
+}
diff --git a/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/HistoryCleanUpMetricsBinder.java b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/HistoryCleanUpMetricsBinder.java
new file mode 100644
index 000000000..c30b62c8f
--- /dev/null
+++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/HistoryCleanUpMetricsBinder.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2021 original authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package info.novatec.micronaut.camunda.bpm.feature.metrics;
+
+import io.micrometer.core.instrument.Gauge;
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.Tags;
+import io.micrometer.core.instrument.binder.MeterBinder;
+import io.micrometer.core.lang.NonNull;
+import io.micronaut.configuration.metrics.annotation.RequiresMetrics;
+import io.micronaut.context.annotation.Requires;
+import io.micronaut.core.util.StringUtils;
+import org.camunda.bpm.engine.management.Metrics;
+
+import javax.inject.Singleton;
+
+import static info.novatec.micronaut.camunda.bpm.feature.metrics.CamundaMetricsBinderTags.HISTORY_CLEAN_UP_DEFAULT_TAGS;
+import static info.novatec.micronaut.camunda.bpm.feature.metrics.CamundaMetricsBinderTags.TAG_KEY_NAME;
+import static io.micronaut.configuration.metrics.micrometer.MeterRegistryFactory.MICRONAUT_METRICS_BINDERS;
+
+/**
+ * Provides Metrics about History Cleanup Execution.
+ */
+@Singleton
+@RequiresMetrics
+@Requires(property = MICRONAUT_METRICS_BINDERS + ".camunda.enabled", value = StringUtils.TRUE, defaultValue = StringUtils.FALSE)
+@Requires(property = MICRONAUT_METRICS_BINDERS + ".camunda.historyCleanUp.enabled", value = StringUtils.TRUE, defaultValue = StringUtils.FALSE)
+public class HistoryCleanUpMetricsBinder implements MeterBinder {
+
+ protected final HistoryCleanUpMetrics historyCleanUpMetrics;
+
+ public HistoryCleanUpMetricsBinder(HistoryCleanUpMetrics historyCleanUpMetrics) {
+ this.historyCleanUpMetrics = historyCleanUpMetrics;
+ }
+
+ @Override
+ public void bindTo(@NonNull MeterRegistry registry) {
+
+ Gauge.builder(
+ createMetricName(Metrics.HISTORY_CLEANUP_REMOVED_PROCESS_INSTANCES),
+ historyCleanUpMetrics,
+ HistoryCleanUpMetrics::getRemovedProcessInstances
+ )
+ .description("The number of process instances removed by history clean up.")
+ .tags(Tags.concat(HISTORY_CLEAN_UP_DEFAULT_TAGS, TAG_KEY_NAME, Metrics.HISTORY_CLEANUP_REMOVED_PROCESS_INSTANCES))
+ .register(registry);
+
+ Gauge.builder(
+ createMetricName(Metrics.HISTORY_CLEANUP_REMOVED_DECISION_INSTANCES),
+ historyCleanUpMetrics,
+ HistoryCleanUpMetrics::getRemovedDecisionInstances
+ )
+ .description("The number of decision instances removed by history clean up.")
+ .tags(Tags.concat(HISTORY_CLEAN_UP_DEFAULT_TAGS, TAG_KEY_NAME, Metrics.HISTORY_CLEANUP_REMOVED_DECISION_INSTANCES))
+ .register(registry);
+
+ Gauge.builder(
+ createMetricName(Metrics.HISTORY_CLEANUP_REMOVED_BATCH_OPERATIONS),
+ historyCleanUpMetrics,
+ HistoryCleanUpMetrics::getRemovedBatchOperations
+ )
+ .description("The number of batch operations removed by history clean up.")
+ .tags(Tags.concat(HISTORY_CLEAN_UP_DEFAULT_TAGS, TAG_KEY_NAME, Metrics.HISTORY_CLEANUP_REMOVED_BATCH_OPERATIONS))
+ .register(registry);
+ }
+
+ private String createMetricName(String camundaName) {
+ return "camunda." + camundaName.replace('-', '.');
+ }
+
+}
diff --git a/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/JobExecutorMetrics.java b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/JobExecutorMetrics.java
new file mode 100644
index 000000000..0ff1c2123
--- /dev/null
+++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/JobExecutorMetrics.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2021 original authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package info.novatec.micronaut.camunda.bpm.feature.metrics;
+
+import io.micronaut.configuration.metrics.annotation.RequiresMetrics;
+import io.micronaut.context.BeanProvider;
+import io.micronaut.context.annotation.Requires;
+import io.micronaut.core.util.StringUtils;
+import org.camunda.bpm.engine.ManagementService;
+import org.camunda.bpm.engine.management.Metrics;
+
+import javax.inject.Provider;
+import javax.inject.Singleton;
+
+import static io.micronaut.configuration.metrics.micrometer.MeterRegistryFactory.MICRONAUT_METRICS_BINDERS;
+
+/**
+ * Holder class to count job execution metrics.
+ */
+@Singleton
+@RequiresMetrics
+@Requires(property = MICRONAUT_METRICS_BINDERS + ".camunda.enabled", value = StringUtils.TRUE, defaultValue = StringUtils.FALSE)
+@Requires(property = MICRONAUT_METRICS_BINDERS + ".camunda.jobExecutor.enabled", value = StringUtils.TRUE, defaultValue = StringUtils.FALSE)
+public class JobExecutorMetrics extends CamundaMetrics {
+
+ public JobExecutorMetrics(BeanProvider providerManagementService) {
+ super(providerManagementService);
+ }
+
+ public long countJobSuccessful() {
+ return sumMetric(Metrics.JOB_SUCCESSFUL);
+ }
+
+ public long countJobFailed() {
+ return sumMetric(Metrics.JOB_FAILED);
+ }
+
+ public long countJobAcquiredSuccess() {
+ return sumMetric(Metrics.JOB_ACQUISITION_ATTEMPT);
+ }
+
+ public long countJobAcquisitionAttempt() {
+ return sumMetric(Metrics.JOB_ACQUIRED_SUCCESS);
+ }
+
+ public long countJobAcquiredFailure() {
+ return sumMetric(Metrics.JOB_ACQUIRED_FAILURE);
+ }
+
+ public long countJobExecutionRejected() {
+ return sumMetric(Metrics.JOB_EXECUTION_REJECTED);
+ }
+
+ public long countJobLockedExclusive() {
+ return sumMetric(Metrics.JOB_LOCKED_EXCLUSIVE);
+ }
+
+}
diff --git a/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/JobExecutorMetricsBinder.java b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/JobExecutorMetricsBinder.java
new file mode 100644
index 000000000..3d2f38722
--- /dev/null
+++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/JobExecutorMetricsBinder.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2021 original authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package info.novatec.micronaut.camunda.bpm.feature.metrics;
+
+import io.micrometer.core.instrument.Gauge;
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.Tags;
+import io.micrometer.core.instrument.binder.MeterBinder;
+import io.micrometer.core.lang.NonNull;
+import io.micronaut.configuration.metrics.annotation.RequiresMetrics;
+import io.micronaut.context.annotation.Requires;
+import io.micronaut.core.util.StringUtils;
+import org.camunda.bpm.engine.management.Metrics;
+
+import javax.inject.Singleton;
+
+import static info.novatec.micronaut.camunda.bpm.feature.metrics.CamundaMetricsBinderTags.JOB_EXECUTOR_DEFAULT_TAGS;
+import static info.novatec.micronaut.camunda.bpm.feature.metrics.CamundaMetricsBinderTags.TAG_KEY_NAME;
+import static io.micronaut.configuration.metrics.micrometer.MeterRegistryFactory.MICRONAUT_METRICS_BINDERS;
+
+/**
+ * Provides Metrics about Job Execution.
+ */
+@Singleton
+@RequiresMetrics
+@Requires(property = MICRONAUT_METRICS_BINDERS + ".camunda.enabled", value = StringUtils.TRUE, defaultValue = StringUtils.FALSE)
+@Requires(property = MICRONAUT_METRICS_BINDERS + ".camunda.jobExecutor.enabled", value = StringUtils.TRUE, defaultValue = StringUtils.FALSE)
+public class JobExecutorMetricsBinder implements MeterBinder {
+
+ protected final JobExecutorMetrics jobExecutorMetrics;
+
+ public JobExecutorMetricsBinder(JobExecutorMetrics jobExecutorMetrics) {
+ this.jobExecutorMetrics = jobExecutorMetrics;
+ }
+
+ @Override
+ public void bindTo(@NonNull MeterRegistry registry) {
+
+ Gauge.builder(
+ createMetricName(Metrics.JOB_SUCCESSFUL),
+ jobExecutorMetrics,
+ JobExecutorMetrics::countJobSuccessful
+ )
+ .description("The number of jobs successfully executed.")
+ .tags(Tags.concat(JOB_EXECUTOR_DEFAULT_TAGS, TAG_KEY_NAME, Metrics.JOB_SUCCESSFUL))
+ .register(registry);
+
+ Gauge.builder(
+ createMetricName(Metrics.JOB_FAILED),
+ jobExecutorMetrics,
+ JobExecutorMetrics::countJobFailed
+ )
+ .description("The number of jobs that failed to execute and that were submitted for retry. Every failed attempt to execute a job is counted.")
+ .tags(Tags.concat(JOB_EXECUTOR_DEFAULT_TAGS, TAG_KEY_NAME, Metrics.JOB_FAILED))
+ .register(registry);
+
+ Gauge.builder(
+ createMetricName(Metrics.JOB_ACQUISITION_ATTEMPT),
+ jobExecutorMetrics,
+ JobExecutorMetrics::countJobAcquisitionAttempt
+ )
+ .description("The number of job acquisition cycles performed.")
+ .tags(Tags.concat(JOB_EXECUTOR_DEFAULT_TAGS, TAG_KEY_NAME, Metrics.JOB_ACQUISITION_ATTEMPT))
+ .register(registry);
+ Gauge.builder(
+ createMetricName(Metrics.JOB_ACQUIRED_SUCCESS),
+ jobExecutorMetrics,
+ JobExecutorMetrics::countJobAcquiredSuccess
+ )
+ .description("The number of jobs that were acquired and successfully locked for execution.")
+ .tags(Tags.concat(JOB_EXECUTOR_DEFAULT_TAGS, TAG_KEY_NAME, Metrics.JOB_ACQUIRED_SUCCESS))
+ .register(registry);
+
+ Gauge.builder(
+ createMetricName(Metrics.JOB_ACQUIRED_FAILURE),
+ jobExecutorMetrics,
+ JobExecutorMetrics::countJobAcquiredFailure
+ )
+ .description("The number of jobs that were acquired but could not be locked for execution due to another job executor locking/executing the jobs in parallel.")
+ .tags(Tags.concat(JOB_EXECUTOR_DEFAULT_TAGS, TAG_KEY_NAME, Metrics.JOB_ACQUIRED_FAILURE))
+ .register(registry);
+
+ Gauge.builder(
+ createMetricName(Metrics.JOB_EXECUTION_REJECTED),
+ jobExecutorMetrics,
+ JobExecutorMetrics::countJobExecutionRejected
+ )
+ .description("The number of successfully acquired jobs submitted for execution that were rejected due to saturated execution resources. This is an indicator that the execution thread pool's job queue is full.")
+ .tags(Tags.concat(JOB_EXECUTOR_DEFAULT_TAGS, TAG_KEY_NAME, Metrics.JOB_EXECUTION_REJECTED))
+ .register(registry);
+
+ Gauge.builder(
+ createMetricName(Metrics.JOB_LOCKED_EXCLUSIVE),
+ jobExecutorMetrics,
+ JobExecutorMetrics::countJobLockedExclusive
+ )
+ .description("The number of exclusive jobs that are immediately locked and executed.")
+ .tags(Tags.concat(JOB_EXECUTOR_DEFAULT_TAGS, TAG_KEY_NAME, Metrics.JOB_LOCKED_EXCLUSIVE))
+ .register(registry);
+ }
+
+ private String createMetricName(String camundaName) {
+ return "camunda." + camundaName.replace('-', '.');
+ }
+
+}