From 0733843e8dc1265dbb938461d4ba93e08734ed1e Mon Sep 17 00:00:00 2001 From: arolfes Date: Wed, 3 Mar 2021 21:28:24 +0100 Subject: [PATCH] Close #83: provide camunda metrics --- README.md | 56 +++++++++ micronaut-camunda-bpm-example/build.gradle | 7 ++ .../src/main/resources/application.yml | 15 +++ micronaut-camunda-bpm-feature/build.gradle | 2 + .../feature/metrics/BpmnExecutionMetrics.java | 59 +++++++++ .../metrics/BpmnExecutionMetricsBinder.java | 98 +++++++++++++++ .../bpm/feature/metrics/CamundaMetrics.java | 57 +++++++++ .../metrics/CamundaMetricsBinderTags.java | 42 +++++++ .../feature/metrics/DmnExecutionMetrics.java | 49 ++++++++ .../metrics/DmnExecutionMetricsBinder.java | 74 +++++++++++ .../metrics/HistoryCleanUpMetrics.java | 53 ++++++++ .../metrics/HistoryCleanUpMetricsBinder.java | 83 ++++++++++++ .../feature/metrics/JobExecutorMetrics.java | 70 +++++++++++ .../metrics/JobExecutorMetricsBinder.java | 118 ++++++++++++++++++ .../metrics/test/BpmExecutionMetricsTest.kt | 35 ++++++ 15 files changed, 818 insertions(+) create mode 100644 micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/BpmnExecutionMetrics.java create mode 100644 micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/BpmnExecutionMetricsBinder.java create mode 100644 micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/CamundaMetrics.java create mode 100644 micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/CamundaMetricsBinderTags.java create mode 100644 micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/DmnExecutionMetrics.java create mode 100644 micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/DmnExecutionMetricsBinder.java create mode 100644 micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/HistoryCleanUpMetrics.java create mode 100644 micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/HistoryCleanUpMetricsBinder.java create mode 100644 micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/JobExecutorMetrics.java create mode 100644 micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/JobExecutorMetricsBinder.java create mode 100644 micronaut-camunda-bpm-feature/src/test/kotlin/info/novatec/micronaut/camunda/bpm/feature/metrics/test/BpmExecutionMetricsTest.kt diff --git a/README.md b/README.md index bdd6193ed..16d094f85 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ Micronaut + Camunda = :heart: * [Custom JobExecutor Configuration](#custom-jobexecutor-configuration) * [Transaction Management](#transaction-management) * [Process Tests](#process-tests) + * [Camunda Metrics](#camunda-metrics) * [Pitfalls](#pitfalls) * [Releases](#releases) * [Contact](#contact) @@ -598,6 +599,61 @@ Note: the integration automatically disables the job executor and the process en See also a test in our example application: [HelloWorldProcessTest](/micronaut-camunda-bpm-example/src/test/java/info/novatec/micronaut/camunda/bpm/example/HelloWorldProcessTest.java) +## Camunda Metrics + +To export Camunda Metrics via micronaut-micrometer you need to add the dependency and enable it __explicitly__ in your `application.yml`. + +We currently support all Camunda Build-In Metrics. See [Process Engine / Metrics](https://docs.camunda.org/manual/latest/user-guide/process-engine/metrics/) + +
+Click to show Gradle dependencies + +```groovy +implementation("io.micronaut.micrometer:micronaut-micrometer-core") + +// optional enable http endpoint for metrics +implementation("io.micronaut:micronaut-management") +``` +
+ +
+Click to show Maven dependencies + +```xml + + io.micronaut.micrometer + micronaut-micrometer-core + + + + + io.micronaut + micronaut-management + +``` +
+ +
+Click to show configuration + +```yaml +micronaut: + metrics: + binders: + camunda: + bpmnExecution: + enabled: true + dmnExecution: + enabled: true + jobExecutor: + enabled: true + historyCleanUp: + enabled: true +``` +
+ +One note about performance: The metrics execute queries against the underlying database. If you have many nodes and everywhere the metrics are enabled it can cause performance problems. + ## Pitfalls ### No version information in Fat/Uber/Shadow JAR 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..15dc6571a 100644 --- a/micronaut-camunda-bpm-example/src/main/resources/application.yml +++ b/micronaut-camunda-bpm-example/src/main/resources/application.yml @@ -1,6 +1,21 @@ micronaut: application: name: micronaut-camunda-example + metrics: + export: + logging: + enabled: true + binders: + camunda: + 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..148e4b219 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") @@ -56,6 +57,7 @@ dependencies { // Test testImplementation("org.junit.jupiter:junit-jupiter-params") + testImplementation("org.camunda.bpm.assert:camunda-bpm-assert:8.0.0") testImplementation("org.mockito:mockito-core:3.8.0") testImplementation("ch.qos.logback:logback-classic") testRuntimeOnly("com.h2database:h2") 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..50da538bf --- /dev/null +++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/BpmnExecutionMetrics.java @@ -0,0 +1,59 @@ +/* + * 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.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..df5de3ef3 --- /dev/null +++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/BpmnExecutionMetricsBinder.java @@ -0,0 +1,98 @@ +/* + * 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.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..5c6dd9379 --- /dev/null +++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/DmnExecutionMetrics.java @@ -0,0 +1,49 @@ +/* + * 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.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..59b4d5ac4 --- /dev/null +++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/DmnExecutionMetricsBinder.java @@ -0,0 +1,74 @@ +/* + * 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.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..fc1fc4200 --- /dev/null +++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/HistoryCleanUpMetrics.java @@ -0,0 +1,53 @@ +/* + * 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.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..10e716601 --- /dev/null +++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/HistoryCleanUpMetricsBinder.java @@ -0,0 +1,83 @@ +/* + * 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.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..41c43e9aa --- /dev/null +++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/JobExecutorMetrics.java @@ -0,0 +1,70 @@ +/* + * 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.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..3a2976f97 --- /dev/null +++ b/micronaut-camunda-bpm-feature/src/main/java/info/novatec/micronaut/camunda/bpm/feature/metrics/JobExecutorMetricsBinder.java @@ -0,0 +1,118 @@ +/* + * 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.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('-', '.'); + } + +} diff --git a/micronaut-camunda-bpm-feature/src/test/kotlin/info/novatec/micronaut/camunda/bpm/feature/metrics/test/BpmExecutionMetricsTest.kt b/micronaut-camunda-bpm-feature/src/test/kotlin/info/novatec/micronaut/camunda/bpm/feature/metrics/test/BpmExecutionMetricsTest.kt new file mode 100644 index 000000000..3cd231f19 --- /dev/null +++ b/micronaut-camunda-bpm-feature/src/test/kotlin/info/novatec/micronaut/camunda/bpm/feature/metrics/test/BpmExecutionMetricsTest.kt @@ -0,0 +1,35 @@ +/* + * 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.test + +import io.micronaut.test.extensions.junit5.annotation.MicronautTest +import org.junit.jupiter.api.Test + + +@MicronautTest +internal class BpmExecutionMetricsTest { + + + @Test + fun `should count One rootProcessInstance`() { + + } + + + companion object { + + } +} \ No newline at end of file