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('-', '.'); + } + +}