You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ja...@apache.org on 2019/09/20 06:16:16 UTC

[camel] branch master updated: CAMEL-13977: Expose additional Camel metrics from MicroProfile metrics component

This is an automated email from the ASF dual-hosted git repository.

jamesnetherton pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new 95b5737  CAMEL-13977: Expose additional Camel metrics from MicroProfile metrics component
95b5737 is described below

commit 95b5737c324ebcd73139a84e9f40408b0da39423
Author: James Netherton <ja...@gmail.com>
AuthorDate: Thu Sep 19 10:49:50 2019 +0100

    CAMEL-13977: Expose additional Camel metrics from MicroProfile metrics component
    
    - Added additional camel metrics
    - Improved metric & tag names
    - Removed redundant metric tags
---
 .../main/docs/microprofile-metrics-component.adoc  |  15 ++-
 .../metrics/MicroProfileMetricsComponent.java      |   2 -
 .../metrics/MicroProfileMetricsConstants.java      |  62 ++++++++--
 .../MicroProfileMetricsExchangeRecorder.java       | 132 +++++++++++++++++++++
 .../metrics/MicroProfileMetricsGaugeProducer.java  |   9 +-
 ...oProfileMetricsEventNotifierNamingStrategy.java |  14 +--
 ...croProfileMetricsCamelContextEventNotifier.java |  80 +++++++++++++
 ...csCamelContextEventNotifierNamingStrategy.java} |  41 ++++---
 .../MicroProfileMetricsExchangeEventNotifier.java  |  30 ++++-
 ...MetricsExchangeEventNotifierNamingStrategy.java |  15 +--
 .../MicroProfileMetricsRouteEventNotifier.java     |  53 +++++++--
 ...ileMetricsRouteEventNotifierNamingStrategy.java |  12 +-
 .../AtomicIntegerGauge.java}                       |  22 ++--
 .../LambdaGauge.java}                              |  26 ++--
 .../SimpleGauge.java}                              |   4 +-
 .../history/MicroProfileMetricsMessageHistory.java |  18 +--
 ...ProfileMetricsMessageHistoryNamingStrategy.java |  12 +-
 .../policy/MicroProfileMetricsRoutePolicy.java     |  19 ++-
 ...croProfileMetricsRoutePolicyNamingStrategy.java |  16 +--
 .../MicroProfileMetricsExchangeRecorderTest.java   | 109 +++++++++++++++++
 .../metrics/MicroProfileMetricsGaugeTest.java      |   7 +-
 .../metrics/MicroProfileMetricsTestSupport.java    |  24 +++-
 ...rofileMetricsCamelContextEventNotifierTest.java |  58 +++++++++
 ...croProfileMetricsExchangeEventNotifierTest.java |  55 ++++++++-
 .../MicroProfileMetricsRouteEventNotifierTest.java |  23 ++--
 .../MicroProfileMetricsMessageHistoryTest.java     |   6 +-
 .../policy/MicroProfileMetricsRoutePolicyTest.java |  74 ++++++++++--
 .../ROOT/pages/microprofile-metrics-component.adoc |  15 ++-
 28 files changed, 793 insertions(+), 160 deletions(-)

diff --git a/components/camel-microprofile-metrics/src/main/docs/microprofile-metrics-component.adoc b/components/camel-microprofile-metrics/src/main/docs/microprofile-metrics-component.adoc
index d11aec0..f33fad2 100644
--- a/components/camel-microprofile-metrics/src/main/docs/microprofile-metrics-component.adoc
+++ b/components/camel-microprofile-metrics/src/main/docs/microprofile-metrics-component.adoc
@@ -437,7 +437,7 @@ context.setMessageHistoryFactory(new MicroProfileMetricsMessageHistoryFactory())
 
 == MicroProfileMetricsExchangeEventNotifier
 
-The exchange event notifer times exchanges from creation through to completion.
+The exchange event notifier times exchanges from creation through to completion.
 
 EventNotifiers can be added to the `CamelContext`, e.g.:
 
@@ -449,7 +449,7 @@ camelContext.getManagementStrategy().addEventNotifier(new MicroProfileMetricsExc
 
 == MicroProfileMetricsRouteEventNotifier
 
-The route event notifer counts added and running routes within the `CamelContext`.
+The route event notifier counts added and running routes within the `CamelContext`.
 
 EventNotifiers can be added to the `CamelContext`, e.g.:
 
@@ -457,3 +457,14 @@ EventNotifiers can be added to the `CamelContext`, e.g.:
 ----
 camelContext.getManagementStrategy().addEventNotifier(new MicroProfileMetricsRouteEventNotifier())
 ----
+
+== MicroProfileMetricsCamelContextEventNotifier
+
+The Camel Context event notifier adds some basic metrics about the state of the `CamelContext`.
+
+EventNotifiers can be added to the `CamelContext`, e.g.:
+
+[source,java]
+----
+camelContext.getManagementStrategy().addEventNotifier(new MicroProfileMetricsCamelContextEventNotifier())
+----
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsComponent.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsComponent.java
index 5e4092f..76bf60c 100644
--- a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsComponent.java
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsComponent.java
@@ -16,7 +16,6 @@
  */
 package org.apache.camel.component.microprofile.metrics;
 
-import java.util.List;
 import java.util.Map;
 
 import org.apache.camel.Endpoint;
@@ -25,7 +24,6 @@ import org.apache.camel.spi.annotations.Component;
 import org.apache.camel.support.DefaultComponent;
 import org.eclipse.microprofile.metrics.MetricRegistry;
 import org.eclipse.microprofile.metrics.MetricType;
-import org.eclipse.microprofile.metrics.Tag;
 
 @Component("microprofile-metrics")
 public class MicroProfileMetricsComponent extends DefaultComponent {
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsConstants.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsConstants.java
index 6bcb7cd..b1bab4e 100644
--- a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsConstants.java
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsConstants.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.microprofile.metrics;
 
+import org.apache.camel.ServiceStatus;
+
 public final class MicroProfileMetricsConstants {
 
     public static final String HEADER_PREFIX = "CamelMicroProfileMetrics";
@@ -34,20 +36,66 @@ public final class MicroProfileMetricsConstants {
     public static final String HEADER_METRIC_UNIT = HEADER_PREFIX + "Units";
     public static final String HEADER_TIMER_ACTION = HEADER_PREFIX + "TimerAction";
 
-    public static final String DEFAULT_CAMEL_MESSAGE_HISTORY_METRIC_NAME = "org.apache.camel.message.history";
-    public static final String DEFAULT_CAMEL_ROUTE_POLICY_METRIC_NAME = "org.apache.camel.route";
-    public static final String DEFAULT_CAMEL_EXCHANGE_EVENT_METRIC_NAME = "org.apache.camel.exchange";
-    public static final String DEFAULT_CAMEL_ROUTES_ADDED_METRIC_NAME = "org.apache.camel.route.total";
-    public static final String DEFAULT_CAMEL_ROUTES_RUNNING_METRIC_NAME = "org.apache.camel.route.running.total";
+    public static final String CAMEL_METRIC_PREFIX = "camel";
+    public static final String CAMEL_CONTEXT_METRIC_NAME = CAMEL_METRIC_PREFIX + ".context";
+
+    public static final String PROCESSING_METRICS_SUFFIX = ".processing";
+
+    public static final String DEFAULT_CAMEL_MESSAGE_HISTORY_METRIC_NAME = CAMEL_METRIC_PREFIX + ".message.history" + PROCESSING_METRICS_SUFFIX;
+    public static final String DEFAULT_CAMEL_ROUTE_POLICY_METRIC_NAME = CAMEL_METRIC_PREFIX + ".route";
+    public static final String DEFAULT_CAMEL_ROUTE_POLICY_PROCESSING_METRIC_NAME = DEFAULT_CAMEL_ROUTE_POLICY_METRIC_NAME + PROCESSING_METRICS_SUFFIX;
+    public static final String DEFAULT_CAMEL_EXCHANGE_EVENT_METRIC_NAME = CAMEL_METRIC_PREFIX + ".exchange";
+    public static final String DEFAULT_CAMEL_EXCHANGE_EVENT_PROCESSING_METRIC_NAME = DEFAULT_CAMEL_EXCHANGE_EVENT_METRIC_NAME + PROCESSING_METRICS_SUFFIX;
+    public static final String DEFAULT_CAMEL_ROUTES_ADDED_METRIC_NAME = CAMEL_METRIC_PREFIX + ".route.count";
+    public static final String DEFAULT_CAMEL_ROUTES_RUNNING_METRIC_NAME = CAMEL_METRIC_PREFIX + ".route.running.count";
+
+    public static final String CAMEL_CONTEXT_UPTIME_METRIC_NAME = CAMEL_CONTEXT_METRIC_NAME + ".uptime";
+    public static final String CAMEL_CONTEXT_UPTIME_DISPLAY_NAME = "Camel Context uptime";
+    public static final String CAMEL_CONTEXT_UPTIME_DESCRIPTION = "The amount of time since the Camel Context was started.";
+
+    public static final String CAMEL_CONTEXT_STATUS_METRIC_NAME = CAMEL_CONTEXT_METRIC_NAME + ".status";
+    public static final String CAMEL_CONTEXT_STATUS_DISPLAY_NAME = "Camel Context status";
+    public static final String CAMEL_CONTEXT_STATUS_DESCRIPTION = "The status of the Camel Context represented by the enum ordinal of " + ServiceStatus.class.getName() + ".";
+
+    public static final String EXCHANGES_METRIC_PREFIX = ".exchanges";
+    public static final String EXCHANGES_COMPLETED_METRIC_NAME = EXCHANGES_METRIC_PREFIX + ".completed.total";
+    public static final String EXCHANGES_COMPLETED_DISPLAY_NAME = "Exchanges completed";
+    public static final String EXCHANGES_COMPLETED_DESCRIPTION = "The total number of completed exchanges for a route or Camel Context";
+
+    public static final String EXCHANGES_FAILED_METRIC_NAME = EXCHANGES_METRIC_PREFIX + ".failed.total";
+    public static final String EXCHANGES_FAILED_DISPLAY_NAME = "Exchanges failed";
+    public static final String EXCHANGES_FAILED_DESCRIPTION = "The total number of failed exchanges for a route or Camel Context";
+
+    public static final String EXCHANGES_TOTAL_METRIC_NAME = EXCHANGES_METRIC_PREFIX + ".total";
+    public static final String EXCHANGES_TOTAL_DISPLAY_NAME = "Exchanges total";
+    public static final String EXCHANGES_TOTAL_DESCRIPTION = "The total number of exchanges for a route or Camel Context";
+
+    public static final String EXCHANGES_INFLIGHT_METRIC_NAME = EXCHANGES_METRIC_PREFIX + ".inflight.count";
+    public static final String EXCHANGES_INFLIGHT_DISPLAY_NAME = "Exchanges inflight";
+    public static final String EXCHANGES_INFLIGHT_DESCRIPTION = "The count of exchanges inflight for a route or Camel Context";
+
+    public static final String EXCHANGES_EXTERNAL_REDELIVERIES_METRIC_NAME = ".externalRedeliveries.total";
+    public static final String EXCHANGES_EXTERNAL_REDELIVERIES_DISPLAY_NAME = "Exchanges external redeliveries";
+    public static final String EXCHANGES_EXTERNAL_REDELIVERIES_DESCRIPTION = "The total number of external redeliveries for a route or Camel Context";
+
+    public static final String EXCHANGES_FAILURES_HANDLED_METRIC_NAME = ".failuresHandled.total";
+    public static final String EXCHANGES_FAILURES_HANDLED_DISPLAY_NAME = "Exchanges failures handled";
+    public static final String EXCHANGES_FAILURES_HANDLED_DESCRIPTION = "The total number of failures handled for a route or Camel Context";
+
+    public static final String ROUTES_ADDED_DISPLAY_NAME = "Routes count";
+    public static final String ROUTES_ADDED_DESCRIPTION = "The count of routes.";
+    public static final String ROUTES_RUNNING_DISPLAY_NAME = "Routes running count";
+    public static final String ROUTES_RUNNING_DESCRIPTION = "The count of running routes.";
+
+    public static final String MESSAGE_HISTORY_DISPLAY_NAME = "Route node processing time";
+    public static final String MESSAGE_HISTORY_DESCRIPTION = "The time taken to process an individual route node";
 
     public static final String ROUTE_ID_TAG = "routeId";
     public static final String NODE_ID_TAG = "nodeId";
-    public static final String FAILED_TAG = "failed";
     public static final String CAMEL_CONTEXT_TAG = "camelContext";
     public static final String EVENT_TYPE_TAG = "eventType";
     public static final String METRIC_REGISTRY_NAME = "metricRegistry";
 
-    public static final String SERVICE_NAME = "serviceName";
     public static final String ENDPOINT_NAME = "endpointName";
 
     private MicroProfileMetricsConstants() {
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsExchangeRecorder.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsExchangeRecorder.java
new file mode 100644
index 0000000..3d605ca
--- /dev/null
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsExchangeRecorder.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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 org.apache.camel.component.microprofile.metrics;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.microprofile.metrics.gauge.AtomicIntegerGauge;
+import org.apache.camel.support.ExchangeHelper;
+import org.eclipse.microprofile.metrics.Counter;
+import org.eclipse.microprofile.metrics.Metadata;
+import org.eclipse.microprofile.metrics.MetadataBuilder;
+import org.eclipse.microprofile.metrics.MetricRegistry;
+import org.eclipse.microprofile.metrics.MetricType;
+import org.eclipse.microprofile.metrics.Tag;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_COMPLETED_DESCRIPTION;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_COMPLETED_DISPLAY_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_COMPLETED_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_EXTERNAL_REDELIVERIES_DESCRIPTION;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_EXTERNAL_REDELIVERIES_DISPLAY_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_EXTERNAL_REDELIVERIES_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_FAILED_DESCRIPTION;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_FAILED_DISPLAY_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_FAILED_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_FAILURES_HANDLED_DESCRIPTION;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_FAILURES_HANDLED_DISPLAY_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_FAILURES_HANDLED_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_INFLIGHT_DESCRIPTION;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_INFLIGHT_DISPLAY_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_INFLIGHT_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_TOTAL_DESCRIPTION;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_TOTAL_DISPLAY_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_TOTAL_METRIC_NAME;
+
+public class MicroProfileMetricsExchangeRecorder {
+
+    private Counter exchangesCompleted;
+    private Counter exchangesFailed;
+    private Counter exchangesTotal;
+    private AtomicIntegerGauge exchangesInflight;
+    private Counter externalRedeliveries;
+    private Counter failuresHandled;
+
+    public MicroProfileMetricsExchangeRecorder(MetricRegistry metricRegistry, String metricName, Tag... tags) {
+        configureMetrics(metricRegistry, metricName, tags);
+    }
+
+    public void recordExchangeBegin() {
+        exchangesInflight.increment();
+    }
+
+    public void recordExchangeComplete(Exchange exchange) {
+        exchangesTotal.inc();
+        exchangesInflight.decrement();
+
+        if (!exchange.isFailed()) {
+            exchangesCompleted.inc();
+
+            if (ExchangeHelper.isFailureHandled(exchange)) {
+                failuresHandled.inc();
+            }
+
+            if (exchange.isExternalRedelivered() != null && exchange.isExternalRedelivered()) {
+                externalRedeliveries.inc();
+            }
+        } else {
+            exchangesFailed.inc();
+        }
+    }
+
+    protected void configureMetrics(MetricRegistry metricRegistry, String metricName, Tag... tags) {
+        Metadata exchangesCompletedMetadata = new MetadataBuilder()
+            .withName(metricName + EXCHANGES_COMPLETED_METRIC_NAME)
+            .withDisplayName(EXCHANGES_COMPLETED_DISPLAY_NAME)
+            .withDescription(EXCHANGES_COMPLETED_DESCRIPTION)
+            .withType(MetricType.COUNTER)
+            .build();
+        this.exchangesCompleted = metricRegistry.counter(exchangesCompletedMetadata, tags);
+
+        Metadata exchangesFailedMetadata = new MetadataBuilder()
+            .withName(metricName + EXCHANGES_FAILED_METRIC_NAME)
+            .withDisplayName(EXCHANGES_FAILED_DISPLAY_NAME)
+            .withDescription(EXCHANGES_FAILED_DESCRIPTION)
+            .withType(MetricType.COUNTER)
+            .build();
+        this.exchangesFailed = metricRegistry.counter(exchangesFailedMetadata, tags);
+
+        Metadata exchangesTotalMetadata = new MetadataBuilder()
+            .withName(metricName + EXCHANGES_TOTAL_METRIC_NAME)
+            .withDisplayName(EXCHANGES_TOTAL_DISPLAY_NAME)
+            .withDescription(EXCHANGES_TOTAL_DESCRIPTION)
+            .withType(MetricType.COUNTER)
+            .build();
+        this.exchangesTotal = metricRegistry.counter(exchangesTotalMetadata, tags);
+
+        Metadata exchangesInflightMetadata = new MetadataBuilder()
+            .withName(metricName + EXCHANGES_INFLIGHT_METRIC_NAME)
+            .withDisplayName(EXCHANGES_INFLIGHT_DISPLAY_NAME)
+            .withDescription(EXCHANGES_INFLIGHT_DESCRIPTION)
+            .withType(MetricType.GAUGE)
+            .build();
+        this.exchangesInflight = metricRegistry.register(exchangesInflightMetadata, new AtomicIntegerGauge(), tags);
+
+        Metadata externalRedeliveriesMetadata = new MetadataBuilder()
+            .withName(metricName + EXCHANGES_EXTERNAL_REDELIVERIES_METRIC_NAME)
+            .withDisplayName(EXCHANGES_EXTERNAL_REDELIVERIES_DISPLAY_NAME)
+            .withDescription(EXCHANGES_EXTERNAL_REDELIVERIES_DESCRIPTION)
+            .withType(MetricType.COUNTER)
+            .build();
+        this.externalRedeliveries = metricRegistry.counter(externalRedeliveriesMetadata, tags);
+
+        Metadata failuresHandledMetadata = new MetadataBuilder()
+            .withName(metricName + EXCHANGES_FAILURES_HANDLED_METRIC_NAME)
+            .withDisplayName(EXCHANGES_FAILURES_HANDLED_DISPLAY_NAME)
+            .withDescription(EXCHANGES_FAILURES_HANDLED_DESCRIPTION)
+            .withType(MetricType.COUNTER)
+            .build();
+        this.failuresHandled = metricRegistry.counter(failuresHandledMetadata, tags);
+    }
+}
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsGaugeProducer.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsGaugeProducer.java
index 2259513..be02e38 100644
--- a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsGaugeProducer.java
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsGaugeProducer.java
@@ -21,19 +21,20 @@ import java.util.function.Function;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
+import org.apache.camel.component.microprofile.metrics.gauge.SimpleGauge;
 import org.eclipse.microprofile.metrics.Metadata;
 import org.eclipse.microprofile.metrics.MetricRegistry;
 import org.eclipse.microprofile.metrics.Tag;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.HEADER_GAUGE_VALUE;
 
-public class MicroProfileMetricsGaugeProducer extends AbstractMicroProfileMetricsProducer<MicroProfileMetricsCamelGauge> {
+public class MicroProfileMetricsGaugeProducer extends AbstractMicroProfileMetricsProducer<SimpleGauge> {
 
     public MicroProfileMetricsGaugeProducer(MicroProfileMetricsEndpoint endpoint) {
         super(endpoint);
     }
 
     @Override
-    protected void doProcess(Exchange exchange, MicroProfileMetricsEndpoint endpoint, MicroProfileMetricsCamelGauge gauge) {
+    protected void doProcess(Exchange exchange, MicroProfileMetricsEndpoint endpoint, SimpleGauge gauge) {
         Message in = exchange.getIn();
         Number finalGaugeValue = getNumericHeader(in, HEADER_GAUGE_VALUE, endpoint.getGaugeValue());
 
@@ -43,7 +44,7 @@ public class MicroProfileMetricsGaugeProducer extends AbstractMicroProfileMetric
     }
 
     @Override
-    protected Function<MetricRegistry, MicroProfileMetricsCamelGauge> registerMetric(Metadata metadata, List<Tag> tags) {
-        return metricRegistry -> metricRegistry.register(metadata, new MicroProfileMetricsCamelGauge(), tags.toArray(new Tag[0]));
+    protected Function<MetricRegistry, SimpleGauge> registerMetric(Metadata metadata, List<Tag> tags) {
+        return metricRegistry -> metricRegistry.register(metadata, new SimpleGauge(), tags.toArray(new Tag[0]));
     }
 }
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/MicroProfileMetricsEventNotifierNamingStrategy.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/MicroProfileMetricsEventNotifierNamingStrategy.java
index c2f3970..ba7147a 100644
--- a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/MicroProfileMetricsEventNotifierNamingStrategy.java
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/MicroProfileMetricsEventNotifierNamingStrategy.java
@@ -18,25 +18,21 @@ package org.apache.camel.component.microprofile.metrics.event.notifier;
 
 import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
-import org.apache.camel.component.microprofile.metrics.MicroProfileMetricsHelper;
 import org.apache.camel.spi.CamelEvent.ExchangeEvent;
 import org.eclipse.microprofile.metrics.Tag;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_TAG;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.ENDPOINT_NAME;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EVENT_TYPE_TAG;
-import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.FAILED_TAG;
-import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.SERVICE_NAME;
 
 public interface MicroProfileMetricsEventNotifierNamingStrategy {
 
     String getName(Exchange exchange, Endpoint endpoint);
 
     default Tag[] getTags(ExchangeEvent event, Endpoint endpoint) {
-        String[] tags = {
-            SERVICE_NAME + "=" + MicroProfileMetricsEventNotifierService.class.getSimpleName(),
-            EVENT_TYPE_TAG + "=" + event.getClass().getSimpleName(),
-            ENDPOINT_NAME + "=" + endpoint.getEndpointUri(),
-            FAILED_TAG + "=" + event.getExchange().isFailed()
+        return new Tag[] {
+            new Tag(CAMEL_CONTEXT_TAG, event.getExchange().getContext().getName()),
+            new Tag(ENDPOINT_NAME, endpoint.getEndpointUri()),
+            new Tag(EVENT_TYPE_TAG, event.getClass().getSimpleName()),
         };
-        return MicroProfileMetricsHelper.parseTagArray(tags);
     }
 }
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/context/MicroProfileMetricsCamelContextEventNotifier.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/context/MicroProfileMetricsCamelContextEventNotifier.java
new file mode 100644
index 0000000..fe22572
--- /dev/null
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/context/MicroProfileMetricsCamelContextEventNotifier.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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 org.apache.camel.component.microprofile.metrics.event.notifier.context;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.component.microprofile.metrics.event.notifier.AbstractMicroProfileMetricsEventNotifier;
+import org.apache.camel.component.microprofile.metrics.gauge.LambdaGauge;
+import org.apache.camel.spi.CamelEvent;
+import org.apache.camel.spi.CamelEvent.CamelContextStartingEvent;
+import org.eclipse.microprofile.metrics.Metadata;
+import org.eclipse.microprofile.metrics.MetadataBuilder;
+import org.eclipse.microprofile.metrics.MetricRegistry;
+import org.eclipse.microprofile.metrics.MetricType;
+import org.eclipse.microprofile.metrics.MetricUnits;
+import org.eclipse.microprofile.metrics.Tag;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_STATUS_DESCRIPTION;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_STATUS_DISPLAY_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_UPTIME_DESCRIPTION;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_UPTIME_DISPLAY_NAME;
+
+public class MicroProfileMetricsCamelContextEventNotifier extends AbstractMicroProfileMetricsEventNotifier<CamelContextStartingEvent> {
+
+    private MicroProfileMetricsCamelContextEventNotifierNamingStrategy namingStrategy = MicroProfileMetricsCamelContextEventNotifierNamingStrategy.DEFAULT;
+
+    public MicroProfileMetricsCamelContextEventNotifier() {
+        super(CamelContextStartingEvent.class);
+    }
+
+    public MicroProfileMetricsCamelContextEventNotifierNamingStrategy getNamingStrategy() {
+        return namingStrategy;
+    }
+
+    public void setNamingStrategy(MicroProfileMetricsCamelContextEventNotifierNamingStrategy namingStrategy) {
+        this.namingStrategy = namingStrategy;
+    }
+
+    @Override
+    public void notify(CamelEvent event) throws Exception {
+        if (event instanceof CamelContextStartingEvent) {
+            registerCamelContextMetrics(((CamelContextStartingEvent) event).getContext());
+        }
+    }
+
+    public void registerCamelContextMetrics(CamelContext camelContext) {
+        MetricRegistry metricRegistry = getMetricRegistry();
+
+        Tag[] tags = namingStrategy.getTags(camelContext);
+
+        Metadata uptimeMetadata = new MetadataBuilder()
+            .withName(namingStrategy.getCamelContextUptimeName())
+            .withDisplayName(CAMEL_CONTEXT_UPTIME_DISPLAY_NAME)
+            .withDescription(CAMEL_CONTEXT_UPTIME_DESCRIPTION)
+            .withType(MetricType.GAUGE)
+            .withUnit(MetricUnits.MILLISECONDS)
+            .build();
+        metricRegistry.register(uptimeMetadata, new LambdaGauge(() -> camelContext.getUptimeMillis()), tags);
+
+        Metadata statusMetadata = new MetadataBuilder()
+            .withName(namingStrategy.getCamelContextStatusName())
+            .withDisplayName(CAMEL_CONTEXT_STATUS_DISPLAY_NAME)
+            .withDescription(CAMEL_CONTEXT_STATUS_DESCRIPTION)
+            .withType(MetricType.GAUGE)
+            .build();
+        metricRegistry.register(statusMetadata, new LambdaGauge(() -> camelContext.getStatus().ordinal()), tags);
+    }
+}
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/MicroProfileMetricsEventNotifierNamingStrategy.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/context/MicroProfileMetricsCamelContextEventNotifierNamingStrategy.java
similarity index 52%
copy from components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/MicroProfileMetricsEventNotifierNamingStrategy.java
copy to components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/context/MicroProfileMetricsCamelContextEventNotifierNamingStrategy.java
index c2f3970..3f33c5c 100644
--- a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/MicroProfileMetricsEventNotifierNamingStrategy.java
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/context/MicroProfileMetricsCamelContextEventNotifierNamingStrategy.java
@@ -14,29 +14,34 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.component.microprofile.metrics.event.notifier;
+package org.apache.camel.component.microprofile.metrics.event.notifier.context;
 
-import org.apache.camel.Endpoint;
-import org.apache.camel.Exchange;
-import org.apache.camel.component.microprofile.metrics.MicroProfileMetricsHelper;
-import org.apache.camel.spi.CamelEvent.ExchangeEvent;
+import org.apache.camel.CamelContext;
 import org.eclipse.microprofile.metrics.Tag;
-import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.ENDPOINT_NAME;
-import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EVENT_TYPE_TAG;
-import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.FAILED_TAG;
-import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.SERVICE_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_STATUS_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_TAG;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_UPTIME_METRIC_NAME;
 
-public interface MicroProfileMetricsEventNotifierNamingStrategy {
+public interface MicroProfileMetricsCamelContextEventNotifierNamingStrategy {
 
-    String getName(Exchange exchange, Endpoint endpoint);
+    MicroProfileMetricsCamelContextEventNotifierNamingStrategy DEFAULT = new MicroProfileMetricsCamelContextEventNotifierNamingStrategy() {
+        @Override
+        public String getCamelContextUptimeName() {
+            return CAMEL_CONTEXT_UPTIME_METRIC_NAME;
+        }
 
-    default Tag[] getTags(ExchangeEvent event, Endpoint endpoint) {
-        String[] tags = {
-            SERVICE_NAME + "=" + MicroProfileMetricsEventNotifierService.class.getSimpleName(),
-            EVENT_TYPE_TAG + "=" + event.getClass().getSimpleName(),
-            ENDPOINT_NAME + "=" + endpoint.getEndpointUri(),
-            FAILED_TAG + "=" + event.getExchange().isFailed()
+        @Override
+        public String getCamelContextStatusName() {
+            return CAMEL_CONTEXT_STATUS_METRIC_NAME;
+        }
+    };
+
+    String getCamelContextUptimeName();
+    String getCamelContextStatusName();
+
+    default Tag[] getTags(CamelContext camelContext) {
+        return new Tag[] {
+            new Tag(CAMEL_CONTEXT_TAG, camelContext.getName()),
         };
-        return MicroProfileMetricsHelper.parseTagArray(tags);
     }
 }
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/exchange/MicroProfileMetricsExchangeEventNotifier.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/exchange/MicroProfileMetricsExchangeEventNotifier.java
index 1dd702b..9b43b63 100644
--- a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/exchange/MicroProfileMetricsExchangeEventNotifier.java
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/exchange/MicroProfileMetricsExchangeEventNotifier.java
@@ -19,21 +19,28 @@ package org.apache.camel.component.microprofile.metrics.event.notifier.exchange;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Predicate;
 
+import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
+import org.apache.camel.component.microprofile.metrics.MicroProfileMetricsExchangeRecorder;
 import org.apache.camel.component.microprofile.metrics.event.notifier.AbstractMicroProfileMetricsEventNotifier;
 import org.apache.camel.spi.CamelEvent;
 import org.apache.camel.spi.CamelEvent.ExchangeCompletedEvent;
 import org.apache.camel.spi.CamelEvent.ExchangeCreatedEvent;
 import org.apache.camel.spi.CamelEvent.ExchangeEvent;
 import org.apache.camel.spi.CamelEvent.ExchangeSentEvent;
+import org.eclipse.microprofile.metrics.MetricRegistry;
 import org.eclipse.microprofile.metrics.Tag;
 import org.eclipse.microprofile.metrics.Timer;
 import org.eclipse.microprofile.metrics.Timer.Context;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_TAG;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.PROCESSING_METRICS_SUFFIX;
 
 public class MicroProfileMetricsExchangeEventNotifier extends AbstractMicroProfileMetricsEventNotifier<ExchangeEvent> {
 
     private Predicate<Exchange> ignoreExchanges = exchange -> false;
     private MicroProfileMetricsExchangeEventNotifierNamingStrategy namingStrategy = MicroProfileMetricsExchangeEventNotifierNamingStrategy.DEFAULT;
+    private MicroProfileMetricsExchangeRecorder exchangeRecorder;
 
     public MicroProfileMetricsExchangeEventNotifier() {
         super(ExchangeEvent.class);
@@ -52,6 +59,16 @@ public class MicroProfileMetricsExchangeEventNotifier extends AbstractMicroProfi
     }
 
     @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+
+        CamelContext camelContext = getCamelContext();
+        MetricRegistry metricRegistry = getMetricRegistry();
+        Tag tag = new Tag(CAMEL_CONTEXT_TAG, camelContext.getName());
+        exchangeRecorder = new MicroProfileMetricsExchangeRecorder(metricRegistry, CAMEL_CONTEXT_METRIC_NAME, tag);
+    }
+
+    @Override
     public void notify(CamelEvent event) throws Exception {
         if (!(getIgnoreExchanges().test(((ExchangeEvent) event).getExchange()))) {
             if (event instanceof ExchangeSentEvent) {
@@ -67,9 +84,10 @@ public class MicroProfileMetricsExchangeEventNotifier extends AbstractMicroProfi
     protected void handleCreatedEvent(ExchangeCreatedEvent createdEvent) {
         String name = namingStrategy.getName(createdEvent.getExchange(), createdEvent.getExchange().getFromEndpoint());
         Tag[] tags = namingStrategy.getTags(createdEvent, createdEvent.getExchange().getFromEndpoint());
-        Timer timer = getMetricRegistry().timer(name, tags);
+        Timer timer = getMetricRegistry().timer(name + PROCESSING_METRICS_SUFFIX, tags);
         createdEvent.getExchange().setProperty("eventTimer:" + name, timer);
         createdEvent.getExchange().setProperty("eventTimerContext:" + name, timer.time());
+        exchangeRecorder.recordExchangeBegin();
     }
 
     protected void handleSentEvent(ExchangeSentEvent sentEvent) {
@@ -77,18 +95,20 @@ public class MicroProfileMetricsExchangeEventNotifier extends AbstractMicroProfi
         Timer timer = sentEvent.getExchange().getProperty("eventTimer:" + name, Timer.class);
         if (timer == null) {
             Tag[] tags = namingStrategy.getTags(sentEvent, sentEvent.getEndpoint());
-            timer = getMetricRegistry().timer(name, tags);
+            timer = getMetricRegistry().timer(name + PROCESSING_METRICS_SUFFIX, tags);
             sentEvent.getExchange().setProperty("eventTimer:" + name, timer);
         }
         timer.update(sentEvent.getTimeTaken(), TimeUnit.MILLISECONDS);
     }
 
     protected void handleDoneEvent(ExchangeEvent doneEvent) {
-        String name = namingStrategy.getName(doneEvent.getExchange(), doneEvent.getExchange().getFromEndpoint());
-        doneEvent.getExchange().removeProperty("eventTimer:" + name);
-        Context context = (Context) doneEvent.getExchange().removeProperty("eventTimerContext:" + name);
+        Exchange exchange = doneEvent.getExchange();
+        String name = namingStrategy.getName(exchange, exchange.getFromEndpoint());
+        exchange.removeProperty("eventTimer:" + name);
+        Context context = (Context) exchange.removeProperty("eventTimerContext:" + name);
         if (context != null) {
             context.stop();
         }
+        exchangeRecorder.recordExchangeComplete(exchange);
     }
 }
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/exchange/MicroProfileMetricsExchangeEventNotifierNamingStrategy.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/exchange/MicroProfileMetricsExchangeEventNotifierNamingStrategy.java
index 7cba4c3..1be6d48 100644
--- a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/exchange/MicroProfileMetricsExchangeEventNotifierNamingStrategy.java
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/exchange/MicroProfileMetricsExchangeEventNotifierNamingStrategy.java
@@ -18,16 +18,12 @@ package org.apache.camel.component.microprofile.metrics.event.notifier.exchange;
 
 import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
-import org.apache.camel.component.microprofile.metrics.MicroProfileMetricsHelper;
-import org.apache.camel.component.microprofile.metrics.event.notifier.MicroProfileMetricsEventNotifierService;
 import org.apache.camel.spi.CamelEvent.ExchangeEvent;
 import org.eclipse.microprofile.metrics.Tag;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_TAG;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.DEFAULT_CAMEL_EXCHANGE_EVENT_METRIC_NAME;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.ENDPOINT_NAME;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EVENT_TYPE_TAG;
-import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.FAILED_TAG;
-import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.SERVICE_NAME;
 
 public interface MicroProfileMetricsExchangeEventNotifierNamingStrategy {
 
@@ -36,13 +32,10 @@ public interface MicroProfileMetricsExchangeEventNotifierNamingStrategy {
     String getName(Exchange exchange, Endpoint endpoint);
 
     default Tag[] getTags(ExchangeEvent event, Endpoint endpoint) {
-        String[] tags = {
-            SERVICE_NAME + "=" + MicroProfileMetricsEventNotifierService.class.getSimpleName(),
-            CAMEL_CONTEXT_TAG + "=" + event.getExchange().getContext().getName(),
-            EVENT_TYPE_TAG + "=" + event.getClass().getSimpleName(),
-            ENDPOINT_NAME + "=" + endpoint.getEndpointUri(),
-            FAILED_TAG + "=" + event.getExchange().isFailed()
+        return new Tag[] {
+            new Tag(CAMEL_CONTEXT_TAG, event.getExchange().getContext().getName()),
+            new Tag(ENDPOINT_NAME, endpoint.getEndpointUri()),
+            new Tag(EVENT_TYPE_TAG, event.getClass().getSimpleName())
         };
-        return MicroProfileMetricsHelper.parseTagArray(tags);
     }
 }
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/route/MicroProfileMetricsRouteEventNotifier.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/route/MicroProfileMetricsRouteEventNotifier.java
index 61dcc8e..e0d9c20 100644
--- a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/route/MicroProfileMetricsRouteEventNotifier.java
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/route/MicroProfileMetricsRouteEventNotifier.java
@@ -18,11 +18,21 @@ package org.apache.camel.component.microprofile.metrics.event.notifier.route;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.component.microprofile.metrics.event.notifier.AbstractMicroProfileMetricsEventNotifier;
+import org.apache.camel.component.microprofile.metrics.gauge.AtomicIntegerGauge;
 import org.apache.camel.spi.CamelEvent;
 import org.apache.camel.spi.CamelEvent.RouteEvent;
-import org.eclipse.microprofile.metrics.ConcurrentGauge;
+import org.eclipse.microprofile.metrics.Metadata;
+import org.eclipse.microprofile.metrics.MetadataBuilder;
+import org.eclipse.microprofile.metrics.Metric;
+import org.eclipse.microprofile.metrics.MetricFilter;
+import org.eclipse.microprofile.metrics.MetricID;
 import org.eclipse.microprofile.metrics.MetricRegistry;
+import org.eclipse.microprofile.metrics.MetricType;
 import org.eclipse.microprofile.metrics.Tag;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.ROUTES_ADDED_DESCRIPTION;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.ROUTES_ADDED_DISPLAY_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.ROUTES_RUNNING_DESCRIPTION;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.ROUTES_RUNNING_DISPLAY_NAME;
 import static org.apache.camel.spi.CamelEvent.Type.RouteAdded;
 import static org.apache.camel.spi.CamelEvent.Type.RouteRemoved;
 import static org.apache.camel.spi.CamelEvent.Type.RouteStarted;
@@ -30,8 +40,8 @@ import static org.apache.camel.spi.CamelEvent.Type.RouteStopped;
 
 public class MicroProfileMetricsRouteEventNotifier extends AbstractMicroProfileMetricsEventNotifier<RouteEvent> {
 
-    private ConcurrentGauge routesAdded;
-    private ConcurrentGauge routesRunning;
+    private AtomicIntegerGauge routesAdded = new AtomicIntegerGauge();
+    private AtomicIntegerGauge routesRunning = new AtomicIntegerGauge();
     private MicroProfileMetricsRouteEventNotifierNamingStrategy namingStrategy = MicroProfileMetricsRouteEventNotifierNamingStrategy.DEFAULT;
 
     public MicroProfileMetricsRouteEventNotifier() {
@@ -45,8 +55,33 @@ public class MicroProfileMetricsRouteEventNotifier extends AbstractMicroProfileM
         CamelContext camelContext = getCamelContext();
         MetricRegistry metricRegistry = getMetricRegistry();
         Tag[] tags = namingStrategy.getTags(camelContext);
-        routesAdded = metricRegistry.concurrentGauge(namingStrategy.getRouteAddedName(), tags);
-        routesRunning = metricRegistry.concurrentGauge(namingStrategy.getRouteRunningName(), tags);
+
+        String routeAddedName = namingStrategy.getRouteAddedName();
+        String routeRunningName = namingStrategy.getRouteRunningName();
+
+        metricRegistry.removeMatching(new MetricFilter() {
+            @Override
+            public boolean matches(MetricID metricID, Metric metric) {
+                return metricID.getName().equals(routeAddedName) || metricID.getName().equals(routeRunningName);
+            }
+        });
+
+        Metadata routesAddedMetadata = new MetadataBuilder()
+            .withName(routeAddedName)
+            .withDisplayName(ROUTES_ADDED_DISPLAY_NAME)
+            .withDescription(ROUTES_ADDED_DESCRIPTION)
+            .withType(MetricType.GAUGE)
+            .build();
+
+        metricRegistry.register(routesAddedMetadata, routesAdded, tags);
+
+        Metadata routesRunningMetadata = new MetadataBuilder()
+            .withName(routeRunningName)
+            .withDisplayName(ROUTES_RUNNING_DISPLAY_NAME)
+            .withDescription(ROUTES_RUNNING_DESCRIPTION)
+            .withType(MetricType.GAUGE)
+            .build();
+        metricRegistry.register(routesRunningMetadata, routesRunning, tags);
     }
 
     @Override
@@ -56,13 +91,13 @@ public class MicroProfileMetricsRouteEventNotifier extends AbstractMicroProfileM
         }
 
         if (event.getType().equals(RouteAdded)) {
-            routesAdded.inc();
+            routesAdded.increment();
         } else if (event.getType().equals(RouteRemoved)) {
-            routesAdded.dec();
+            routesAdded.decrement();
         } else if (event.getType().equals(RouteStarted)) {
-            routesRunning.inc();
+            routesRunning.increment();
         } else if (event.getType().equals(RouteStopped)) {
-            routesRunning.dec();
+            routesRunning.decrement();
         }
     }
 
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/route/MicroProfileMetricsRouteEventNotifierNamingStrategy.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/route/MicroProfileMetricsRouteEventNotifierNamingStrategy.java
index 14dbf03..d8f26fc 100644
--- a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/route/MicroProfileMetricsRouteEventNotifierNamingStrategy.java
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/event/notifier/route/MicroProfileMetricsRouteEventNotifierNamingStrategy.java
@@ -17,15 +17,10 @@
 package org.apache.camel.component.microprofile.metrics.event.notifier.route;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.component.microprofile.metrics.MicroProfileMetricsHelper;
-import org.apache.camel.component.microprofile.metrics.event.notifier.MicroProfileMetricsEventNotifierService;
-import org.apache.camel.spi.CamelEvent;
 import org.eclipse.microprofile.metrics.Tag;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_TAG;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.DEFAULT_CAMEL_ROUTES_ADDED_METRIC_NAME;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.DEFAULT_CAMEL_ROUTES_RUNNING_METRIC_NAME;
-import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EVENT_TYPE_TAG;
-import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.SERVICE_NAME;
 
 public interface MicroProfileMetricsRouteEventNotifierNamingStrategy {
 
@@ -45,11 +40,8 @@ public interface MicroProfileMetricsRouteEventNotifierNamingStrategy {
     String getRouteRunningName();
 
     default Tag[] getTags(CamelContext camelContext) {
-        String[] tags = {
-            SERVICE_NAME + "=" + MicroProfileMetricsEventNotifierService.class.getSimpleName(),
-            CAMEL_CONTEXT_TAG + "=" + camelContext.getName(),
-            EVENT_TYPE_TAG + "=" + CamelEvent.RouteEvent.class.getSimpleName(),
+        return new Tag[] {
+            new Tag(CAMEL_CONTEXT_TAG, camelContext.getName())
         };
-        return MicroProfileMetricsHelper.parseTagArray(tags);
     }
 }
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsCamelGauge.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/gauge/AtomicIntegerGauge.java
similarity index 66%
copy from components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsCamelGauge.java
copy to components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/gauge/AtomicIntegerGauge.java
index 7966747..8bed76b 100644
--- a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsCamelGauge.java
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/gauge/AtomicIntegerGauge.java
@@ -14,19 +14,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.component.microprofile.metrics;
+package org.apache.camel.component.microprofile.metrics.gauge;
+
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.eclipse.microprofile.metrics.Gauge;
 
-class MicroProfileMetricsCamelGauge implements Gauge<Number> {
-    private Number value = 0;
+public class AtomicIntegerGauge implements Gauge<Integer> {
+    private final AtomicInteger gaugeValue = new AtomicInteger();
 
     @Override
-    public Number getValue() {
-        return this.value;
+    public Integer getValue() {
+        return gaugeValue.get();
+    }
+
+    public void increment() {
+        gaugeValue.incrementAndGet();
     }
 
-    public void setValue(Number value) {
-        this.value = value;
+    public void decrement() {
+        gaugeValue.decrementAndGet();
     }
-}
+}
\ No newline at end of file
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsCamelGauge.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/gauge/LambdaGauge.java
similarity index 59%
copy from components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsCamelGauge.java
copy to components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/gauge/LambdaGauge.java
index 7966747..e432504 100644
--- a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsCamelGauge.java
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/gauge/LambdaGauge.java
@@ -14,19 +14,29 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.component.microprofile.metrics;
+package org.apache.camel.component.microprofile.metrics.gauge;
+
+import java.util.concurrent.Callable;
 
 import org.eclipse.microprofile.metrics.Gauge;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-class MicroProfileMetricsCamelGauge implements Gauge<Number> {
-    private Number value = 0;
+public class LambdaGauge implements Gauge<Number> {
+    private static final Logger LOG = LoggerFactory.getLogger(LambdaGauge.class);
+    private final Callable<Number> callable;
 
-    @Override
-    public Number getValue() {
-        return this.value;
+    public LambdaGauge(Callable<Number> callable) {
+        this.callable = callable;
     }
 
-    public void setValue(Number value) {
-        this.value = value;
+    @Override
+    public Number getValue() {
+        try {
+            return this.callable.call();
+        } catch (Exception e) {
+            LOG.debug("Error retrieving LambdaGauge value due to: {}", e.getMessage());
+            return 0;
+        }
     }
 }
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsCamelGauge.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/gauge/SimpleGauge.java
similarity index 89%
rename from components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsCamelGauge.java
rename to components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/gauge/SimpleGauge.java
index 7966747..b192483 100644
--- a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsCamelGauge.java
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/gauge/SimpleGauge.java
@@ -14,11 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.component.microprofile.metrics;
+package org.apache.camel.component.microprofile.metrics.gauge;
 
 import org.eclipse.microprofile.metrics.Gauge;
 
-class MicroProfileMetricsCamelGauge implements Gauge<Number> {
+public class SimpleGauge implements Gauge<Number> {
     private Number value = 0;
 
     @Override
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/message/history/MicroProfileMetricsMessageHistory.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/message/history/MicroProfileMetricsMessageHistory.java
index 33e59b8..2dcfe2d 100644
--- a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/message/history/MicroProfileMetricsMessageHistory.java
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/message/history/MicroProfileMetricsMessageHistory.java
@@ -20,22 +20,26 @@ import org.apache.camel.Message;
 import org.apache.camel.NamedNode;
 import org.apache.camel.Route;
 import org.apache.camel.support.DefaultMessageHistory;
+import org.eclipse.microprofile.metrics.Metadata;
+import org.eclipse.microprofile.metrics.MetadataBuilder;
 import org.eclipse.microprofile.metrics.MetricRegistry;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.MESSAGE_HISTORY_DESCRIPTION;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.MESSAGE_HISTORY_DISPLAY_NAME;
 import static org.eclipse.microprofile.metrics.Timer.Context;
 
 public class MicroProfileMetricsMessageHistory extends DefaultMessageHistory {
-    private final Route route;
     private final Context context;
-    private final MetricRegistry metricRegistry;
-    private final MicroProfileMetricsMessageHistoryNamingStrategy namingStrategy;
 
     public MicroProfileMetricsMessageHistory(MetricRegistry metricRegistry, Route route, NamedNode namedNode,
             MicroProfileMetricsMessageHistoryNamingStrategy namingStrategy, long timestamp, Message message) {
         super(route.getId(), namedNode, timestamp, message);
-        this.metricRegistry = metricRegistry;
-        this.route = route;
-        this.namingStrategy = namingStrategy;
-        this.context = metricRegistry.timer(namingStrategy.getName(route, getNode()), namingStrategy.getTags(route, getNode())).time();
+
+        Metadata routeNodeMetadata = new MetadataBuilder()
+            .withName(namingStrategy.getName(route, getNode()))
+            .withDisplayName(MESSAGE_HISTORY_DISPLAY_NAME)
+            .withDescription(MESSAGE_HISTORY_DESCRIPTION)
+            .build();
+        this.context = metricRegistry.timer(routeNodeMetadata, namingStrategy.getTags(route, getNode())).time();
     }
 
     @Override
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/message/history/MicroProfileMetricsMessageHistoryNamingStrategy.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/message/history/MicroProfileMetricsMessageHistoryNamingStrategy.java
index 774b2f8..79dfd45 100644
--- a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/message/history/MicroProfileMetricsMessageHistoryNamingStrategy.java
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/message/history/MicroProfileMetricsMessageHistoryNamingStrategy.java
@@ -18,13 +18,11 @@ package org.apache.camel.component.microprofile.metrics.message.history;
 
 import org.apache.camel.NamedNode;
 import org.apache.camel.Route;
-import org.apache.camel.component.microprofile.metrics.MicroProfileMetricsHelper;
 import org.eclipse.microprofile.metrics.Tag;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_TAG;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.DEFAULT_CAMEL_MESSAGE_HISTORY_METRIC_NAME;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.NODE_ID_TAG;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.ROUTE_ID_TAG;
-import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.SERVICE_NAME;
 
 public interface MicroProfileMetricsMessageHistoryNamingStrategy {
 
@@ -33,12 +31,10 @@ public interface MicroProfileMetricsMessageHistoryNamingStrategy {
     String getName(Route route, NamedNode node);
 
     default Tag[] getTags(Route route, NamedNode node) {
-        String[] tags = {
-            SERVICE_NAME + "=" + MicroProfileMetricsMessageHistory.class.getSimpleName(),
-            CAMEL_CONTEXT_TAG + "=" + route.getCamelContext().getName(),
-            ROUTE_ID_TAG + "=" + route.getId(),
-            NODE_ID_TAG + "=" + node.getId(),
+        return new Tag[] {
+            new Tag(CAMEL_CONTEXT_TAG, route.getCamelContext().getName()),
+            new Tag(ROUTE_ID_TAG, route.getId()),
+            new Tag(NODE_ID_TAG, node.getId())
         };
-        return MicroProfileMetricsHelper.parseTagArray(tags);
     }
 }
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/route/policy/MicroProfileMetricsRoutePolicy.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/route/policy/MicroProfileMetricsRoutePolicy.java
index 5ea3e98..29ea6ac 100644
--- a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/route/policy/MicroProfileMetricsRoutePolicy.java
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/route/policy/MicroProfileMetricsRoutePolicy.java
@@ -20,6 +20,7 @@ import org.apache.camel.Exchange;
 import org.apache.camel.NonManagedService;
 import org.apache.camel.Route;
 import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.component.microprofile.metrics.MicroProfileMetricsExchangeRecorder;
 import org.apache.camel.component.microprofile.metrics.MicroProfileMetricsHelper;
 import org.apache.camel.support.RoutePolicySupport;
 import org.apache.camel.support.service.ServiceHelper;
@@ -28,12 +29,14 @@ import org.eclipse.microprofile.metrics.MetricRegistry;
 import org.eclipse.microprofile.metrics.Timer;
 import org.eclipse.microprofile.metrics.Timer.Context;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.DEFAULT_CAMEL_ROUTE_POLICY_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.PROCESSING_METRICS_SUFFIX;
 
 public class MicroProfileMetricsRoutePolicy extends RoutePolicySupport implements NonManagedService {
 
     private MetricRegistry metricRegistry;
     private MetricsStatistics statistics;
     private MicroProfileMetricsRoutePolicyNamingStrategy namingStrategy = MicroProfileMetricsRoutePolicyNamingStrategy.DEFAULT;
+    private MicroProfileMetricsExchangeRecorder exchangeRecorder;
 
     private static final class MetricsStatistics {
         private final MetricRegistry metricRegistry;
@@ -47,9 +50,8 @@ public class MicroProfileMetricsRoutePolicy extends RoutePolicySupport implement
         }
 
         public void onExchangeBegin(Exchange exchange) {
-            namingStrategy.getName(route);
-
-            Timer timer = metricRegistry.timer(namingStrategy.getName(route), namingStrategy.getTags(route, exchange));
+            String name = namingStrategy.getName(route);
+            Timer timer = metricRegistry.timer(name + PROCESSING_METRICS_SUFFIX, namingStrategy.getTags(route));
             exchange.setProperty(propertyName(exchange), timer.time());
         }
 
@@ -89,6 +91,8 @@ public class MicroProfileMetricsRoutePolicy extends RoutePolicySupport implement
             metricRegistry = MicroProfileMetricsHelper.getMetricRegistry(route.getCamelContext());
         }
 
+        exchangeRecorder = new MicroProfileMetricsExchangeRecorder(metricRegistry, namingStrategy.getName(route), namingStrategy.getTags(route));
+
         try {
             MicroProfileMetricsRoutePolicyService registryService = route.getCamelContext().hasService(MicroProfileMetricsRoutePolicyService.class);
             if (registryService == null) {
@@ -103,12 +107,15 @@ public class MicroProfileMetricsRoutePolicy extends RoutePolicySupport implement
         statistics = new MetricsStatistics(metricRegistry, route, getNamingStrategy());
     }
 
-
     @Override
     public void onExchangeBegin(Route route, Exchange exchange) {
         if (statistics != null) {
             statistics.onExchangeBegin(exchange);
         }
+
+        if (exchangeRecorder != null) {
+            exchangeRecorder.recordExchangeBegin();
+        }
     }
 
     @Override
@@ -116,5 +123,9 @@ public class MicroProfileMetricsRoutePolicy extends RoutePolicySupport implement
         if (statistics != null) {
             statistics.onExchangeDone(exchange);
         }
+
+        if (exchangeRecorder != null) {
+            exchangeRecorder.recordExchangeComplete(exchange);
+        }
     }
 }
diff --git a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/route/policy/MicroProfileMetricsRoutePolicyNamingStrategy.java b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/route/policy/MicroProfileMetricsRoutePolicyNamingStrategy.java
index 49cbda3..c0cee12 100644
--- a/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/route/policy/MicroProfileMetricsRoutePolicyNamingStrategy.java
+++ b/components/camel-microprofile-metrics/src/main/java/org/apache/camel/component/microprofile/metrics/route/policy/MicroProfileMetricsRoutePolicyNamingStrategy.java
@@ -16,15 +16,11 @@
  */
 package org.apache.camel.component.microprofile.metrics.route.policy;
 
-import org.apache.camel.Exchange;
 import org.apache.camel.Route;
-import org.apache.camel.component.microprofile.metrics.MicroProfileMetricsHelper;
 import org.eclipse.microprofile.metrics.Tag;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_TAG;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.DEFAULT_CAMEL_ROUTE_POLICY_METRIC_NAME;
-import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.FAILED_TAG;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.ROUTE_ID_TAG;
-import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.SERVICE_NAME;
 
 public interface MicroProfileMetricsRoutePolicyNamingStrategy {
 
@@ -32,14 +28,10 @@ public interface MicroProfileMetricsRoutePolicyNamingStrategy {
 
     String getName(Route route);
 
-    default Tag[] getTags(Route route, Exchange exchange) {
-        String[] tags = {
-            SERVICE_NAME + "=" + MicroProfileMetricsRoutePolicyService.class.getSimpleName(),
-            CAMEL_CONTEXT_TAG + "=" + route.getCamelContext().getName(),
-            ROUTE_ID_TAG + "=" + route.getId(),
-            FAILED_TAG + "=" + exchange.isFailed(),
+    default Tag[] getTags(Route route) {
+        return new Tag[] {
+            new Tag(CAMEL_CONTEXT_TAG, route.getCamelContext().getName()),
+            new Tag(ROUTE_ID_TAG, route.getId()),
         };
-        return MicroProfileMetricsHelper.parseTagArray(tags);
     }
-
 }
diff --git a/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsExchangeRecorderTest.java b/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsExchangeRecorderTest.java
new file mode 100644
index 0000000..2e03a5e
--- /dev/null
+++ b/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsExchangeRecorderTest.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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 org.apache.camel.component.microprofile.metrics;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.ExchangeBuilder;
+import org.apache.camel.component.microprofile.metrics.gauge.AtomicIntegerGauge;
+import org.eclipse.microprofile.metrics.Counter;
+import org.eclipse.microprofile.metrics.Tag;
+import org.junit.Before;
+import org.junit.Test;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_METRIC_PREFIX;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_COMPLETED_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_EXTERNAL_REDELIVERIES_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_FAILED_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_FAILURES_HANDLED_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_INFLIGHT_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_TOTAL_METRIC_NAME;
+
+public class MicroProfileMetricsExchangeRecorderTest extends MicroProfileMetricsTestSupport {
+
+    private static final Tag[] TAGS = new Tag[] {new Tag("foo", "bar")};
+    private MicroProfileMetricsExchangeRecorder recorder;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        recorder = new MicroProfileMetricsExchangeRecorder(metricRegistry, CAMEL_METRIC_PREFIX, TAGS);
+    }
+
+    @Test
+    public void testMetricsRecorderExchangeComplete() {
+        recorder.recordExchangeBegin();
+        Exchange exchange = ExchangeBuilder.anExchange(context).build();
+        recorder.recordExchangeComplete(exchange);
+
+        Counter exchangesCompleted = getCounter(CAMEL_METRIC_PREFIX + EXCHANGES_COMPLETED_METRIC_NAME, TAGS);
+        assertEquals(1, exchangesCompleted.getCount());
+
+        Counter exchangesFailed = getCounter(CAMEL_METRIC_PREFIX + EXCHANGES_FAILED_METRIC_NAME, TAGS);
+        assertEquals(0, exchangesFailed.getCount());
+
+        Counter exchangesTotal = getCounter(CAMEL_METRIC_PREFIX + EXCHANGES_TOTAL_METRIC_NAME, TAGS);
+        assertEquals(1, exchangesTotal.getCount());
+
+        AtomicIntegerGauge exchangesInflight = getAtomicIntegerGauge(CAMEL_METRIC_PREFIX + EXCHANGES_INFLIGHT_METRIC_NAME, TAGS);
+        assertEquals(0, exchangesInflight.getValue().intValue());
+
+        Counter externalRedeliveries = getCounter(CAMEL_METRIC_PREFIX + EXCHANGES_EXTERNAL_REDELIVERIES_METRIC_NAME, TAGS);
+        assertEquals(0, externalRedeliveries.getCount());
+
+        Counter failuresHandled = getCounter(CAMEL_METRIC_PREFIX + EXCHANGES_FAILURES_HANDLED_METRIC_NAME, TAGS);
+        assertEquals(0, failuresHandled.getCount());
+    }
+
+    @Test
+    public void testMetricsRecorderExchangeInflight() {
+        recorder.recordExchangeBegin();
+        AtomicIntegerGauge exchangesInflight = getAtomicIntegerGauge(CAMEL_METRIC_PREFIX + EXCHANGES_INFLIGHT_METRIC_NAME, TAGS);
+        assertEquals(1, exchangesInflight.getValue().intValue());
+
+        Exchange exchange = ExchangeBuilder.anExchange(context).build();
+        recorder.recordExchangeComplete(exchange);
+        assertEquals(0, exchangesInflight.getValue().intValue());
+    }
+
+    @Test
+    public void testMetricsRecorderExternalRedeliveries() {
+        Exchange exchange = ExchangeBuilder.anExchange(context)
+            .withProperty(Exchange.EXTERNAL_REDELIVERED, true)
+            .build();
+        recorder.recordExchangeComplete(exchange);
+        Counter externalRedeliveries = getCounter(CAMEL_METRIC_PREFIX + EXCHANGES_EXTERNAL_REDELIVERIES_METRIC_NAME, TAGS);
+        assertEquals(1, externalRedeliveries.getCount());
+    }
+
+    @Test
+    public void testMetricsRecorderFailuresHandled() {
+        Exchange exchange = ExchangeBuilder.anExchange(context)
+            .withProperty(Exchange.FAILURE_HANDLED, true)
+            .build();
+        recorder.recordExchangeComplete(exchange);
+        Counter failuresHandled = getCounter(CAMEL_METRIC_PREFIX + EXCHANGES_FAILURES_HANDLED_METRIC_NAME, TAGS);
+        assertEquals(1, failuresHandled.getCount());
+    }
+
+    @Test
+    public void testMetricsRecorderExchangesFailed() {
+        Exchange exchange = ExchangeBuilder.anExchange(context).build();
+        exchange.setException(new Exception());
+        recorder.recordExchangeComplete(exchange);
+        Counter exchangesFailed = getCounter(CAMEL_METRIC_PREFIX + EXCHANGES_FAILED_METRIC_NAME, TAGS);
+        assertEquals(1, exchangesFailed.getCount());
+    }
+}
diff --git a/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsGaugeTest.java b/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsGaugeTest.java
index 000a070..ceffd8d 100644
--- a/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsGaugeTest.java
+++ b/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsGaugeTest.java
@@ -18,6 +18,7 @@ package org.apache.camel.component.microprofile.metrics;
 
 import org.apache.camel.RoutesBuilder;
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.microprofile.metrics.gauge.SimpleGauge;
 import org.junit.Test;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.HEADER_GAUGE_VALUE;
 
@@ -26,21 +27,21 @@ public class MicroProfileMetricsGaugeTest extends MicroProfileMetricsTestSupport
     @Test
     public void testGaugeMetric() {
         template.sendBody("direct:gaugeValue", null);
-        MicroProfileMetricsCamelGauge gauge = getGauge("test-gauge");
+        SimpleGauge gauge = getSimpleGauge("test-gauge");
         assertEquals(10, gauge.getValue().intValue());
     }
 
     @Test
     public void testGaugeMetricHeaderValue() {
         template.sendBody("direct:gaugeValueHeader", null);
-        MicroProfileMetricsCamelGauge gauge = getGauge("test-gauge-header");
+        SimpleGauge gauge = getSimpleGauge("test-gauge-header");
         assertEquals(20, gauge.getValue().intValue());
     }
 
     @Test
     public void testGaugeMetricHeaderOverrideValue() {
         template.sendBodyAndHeader("direct:gaugeValue", null, HEADER_GAUGE_VALUE, 20);
-        MicroProfileMetricsCamelGauge gauge = getGauge("test-gauge");
+        SimpleGauge gauge = getSimpleGauge("test-gauge");
         assertEquals(20, gauge.getValue().intValue());
     }
 
diff --git a/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsTestSupport.java b/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsTestSupport.java
index 3855faf..4274d52 100644
--- a/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsTestSupport.java
+++ b/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/MicroProfileMetricsTestSupport.java
@@ -16,13 +16,17 @@
  */
 package org.apache.camel.component.microprofile.metrics;
 
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
 import io.smallrye.metrics.MetricRegistries;
+import io.smallrye.metrics.exporters.JsonExporter;
 
 import org.apache.camel.BindToRegistry;
+import org.apache.camel.component.microprofile.metrics.gauge.AtomicIntegerGauge;
+import org.apache.camel.component.microprofile.metrics.gauge.SimpleGauge;
 import org.apache.camel.test.junit4.CamelTestSupport;
 import org.eclipse.microprofile.metrics.ConcurrentGauge;
 import org.eclipse.microprofile.metrics.Counter;
@@ -59,12 +63,20 @@ public class MicroProfileMetricsTestSupport extends CamelTestSupport {
         return findMetric(metricRegistry, metricName, Counter.class);
     }
 
+    protected Counter getCounter(String metricName, Tag[] tags) {
+        return findMetric(metricRegistry, metricName, Counter.class, Arrays.asList(tags));
+    }
+
+    protected AtomicIntegerGauge getAtomicIntegerGauge(String metricName, Tag[] tags) {
+        return findMetric(metricRegistry, metricName, AtomicIntegerGauge.class, Arrays.asList(tags));
+    }
+
     protected ConcurrentGauge getConcurrentGauge(String metricName) {
         return findMetric(metricRegistry, metricName, ConcurrentGauge.class);
     }
 
-    protected MicroProfileMetricsCamelGauge getGauge(String metricName) {
-        return findMetric(metricRegistry, metricName, MicroProfileMetricsCamelGauge.class);
+    protected SimpleGauge getSimpleGauge(String metricName) {
+        return findMetric(metricRegistry, metricName, SimpleGauge.class);
     }
 
     protected Histogram getHistogram(String metricName) {
@@ -79,6 +91,10 @@ public class MicroProfileMetricsTestSupport extends CamelTestSupport {
         return findMetric(metricRegistry, metricName, Timer.class);
     }
 
+    protected Timer getTimer(String metricName, Tag[] tags) {
+        return findMetric(metricRegistry, metricName, Timer.class, Arrays.asList(tags));
+    }
+
     protected Metadata getMetricMetadata(String metricName) {
         Map<String, Metadata> metadataMap = metricRegistry.getMetadata();
         for (Map.Entry<String, Metadata> entry : metadataMap.entrySet()) {
@@ -99,4 +115,8 @@ public class MicroProfileMetricsTestSupport extends CamelTestSupport {
         }
         return Collections.emptyList();
     }
+
+    protected void dumpMetrics() {
+        System.out.println(new JsonExporter().exportAllScopes());
+    }
 }
diff --git a/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/event/notifier/context/MicroProfileMetricsCamelContextEventNotifierTest.java b/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/event/notifier/context/MicroProfileMetricsCamelContextEventNotifierTest.java
new file mode 100644
index 0000000..5b80789
--- /dev/null
+++ b/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/event/notifier/context/MicroProfileMetricsCamelContextEventNotifierTest.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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 org.apache.camel.component.microprofile.metrics.event.notifier.context;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ServiceStatus;
+import org.apache.camel.component.microprofile.metrics.MicroProfileMetricsTestSupport;
+import org.apache.camel.component.microprofile.metrics.gauge.LambdaGauge;
+import org.eclipse.microprofile.metrics.Tag;
+import org.junit.Test;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_STATUS_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_TAG;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_UPTIME_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsHelper.findMetric;
+
+public class MicroProfileMetricsCamelContextEventNotifierTest extends MicroProfileMetricsTestSupport {
+
+    @Test
+    public void testMicroProfileMetricsEventNotifier() throws Exception {
+        List<Tag> tags = new ArrayList<>();
+        tags.add(new Tag(CAMEL_CONTEXT_TAG, context.getName()));
+
+        LambdaGauge uptime = findMetric(metricRegistry, CAMEL_CONTEXT_UPTIME_METRIC_NAME, LambdaGauge.class, tags);
+        assertNotNull(uptime);
+        assertTrue(uptime.getValue().intValue() > 0);
+
+        LambdaGauge status = findMetric(metricRegistry, CAMEL_CONTEXT_STATUS_METRIC_NAME, LambdaGauge.class, tags);
+        assertNotNull(status);
+        assertEquals(ServiceStatus.Started.ordinal(), status.getValue().intValue());
+
+        context.stop();
+        assertEquals(ServiceStatus.Stopped.ordinal(), status.getValue().intValue());
+    }
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext camelContext = super.createCamelContext();
+        camelContext.getManagementStrategy().addEventNotifier(new MicroProfileMetricsCamelContextEventNotifier());
+        return camelContext;
+    }
+}
diff --git a/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/event/notifier/exchange/MicroProfileMetricsExchangeEventNotifierTest.java b/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/event/notifier/exchange/MicroProfileMetricsExchangeEventNotifierTest.java
index 600684e..9c09d11 100644
--- a/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/event/notifier/exchange/MicroProfileMetricsExchangeEventNotifierTest.java
+++ b/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/event/notifier/exchange/MicroProfileMetricsExchangeEventNotifierTest.java
@@ -22,10 +22,22 @@ import org.apache.camel.Exchange;
 import org.apache.camel.RoutesBuilder;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.microprofile.metrics.MicroProfileMetricsTestSupport;
+import org.apache.camel.component.microprofile.metrics.gauge.AtomicIntegerGauge;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.support.ExpressionAdapter;
+import org.eclipse.microprofile.metrics.Counter;
+import org.eclipse.microprofile.metrics.Tag;
 import org.eclipse.microprofile.metrics.Timer;
 import org.junit.Test;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_TAG;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_COMPLETED_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_EXTERNAL_REDELIVERIES_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_FAILED_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_FAILURES_HANDLED_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_INFLIGHT_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_TOTAL_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.PROCESSING_METRICS_SUFFIX;
 
 public class MicroProfileMetricsExchangeEventNotifierTest extends MicroProfileMetricsTestSupport {
 
@@ -50,12 +62,36 @@ public class MicroProfileMetricsExchangeEventNotifierTest extends MicroProfileMe
         mockEndpoint.expectedMessageCount(count);
 
         for (int i = 0; i < count; i++) {
-            template.sendBody("direct:start", null);
+            try {
+                template.sendBody("direct:start", i);
+            } catch (Exception e) {
+                // Expected
+            }
         }
 
-        Timer timer = getTimer("mock://result");
-        assertEquals(count, timer.getCount());
+        Timer timer = getTimer("mock://result" + PROCESSING_METRICS_SUFFIX);
+        assertEquals(5, timer.getCount());
         assertTrue(timer.getSnapshot().getMean() > delay.doubleValue());
+
+        Tag[] tags = new Tag[] {new Tag(CAMEL_CONTEXT_TAG, context.getName())};
+
+        Counter exchangesCompleted = getCounter(CAMEL_CONTEXT_METRIC_NAME + EXCHANGES_COMPLETED_METRIC_NAME, tags);
+        assertEquals(count, exchangesCompleted.getCount());
+
+        Counter exchangesFailed = getCounter(CAMEL_CONTEXT_METRIC_NAME + EXCHANGES_FAILED_METRIC_NAME, tags);
+        assertEquals(0, exchangesFailed.getCount());
+
+        Counter exchangesTotal = getCounter(CAMEL_CONTEXT_METRIC_NAME + EXCHANGES_TOTAL_METRIC_NAME, tags);
+        assertEquals(count, exchangesTotal.getCount());
+
+        AtomicIntegerGauge exchangesInflight = getAtomicIntegerGauge(CAMEL_CONTEXT_METRIC_NAME + EXCHANGES_INFLIGHT_METRIC_NAME, tags);
+        assertEquals(0, exchangesInflight.getValue().intValue());
+
+        Counter externalRedeliveries = getCounter(CAMEL_CONTEXT_METRIC_NAME + EXCHANGES_EXTERNAL_REDELIVERIES_METRIC_NAME, tags);
+        assertEquals(0, externalRedeliveries.getCount());
+
+        Counter failuresHandled = getCounter(CAMEL_CONTEXT_METRIC_NAME + EXCHANGES_FAILURES_HANDLED_METRIC_NAME, tags);
+        assertEquals(5, failuresHandled.getCount());
     }
 
     @Override
@@ -74,8 +110,19 @@ public class MicroProfileMetricsExchangeEventNotifierTest extends MicroProfileMe
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
+                onException(IllegalStateException.class)
+                    .handled(true);
+
                 from("direct:start").routeId("test")
-                        .to("mock:result");
+                    .process(exchange -> {
+                        Integer count = exchange.getIn().getBody(Integer.class);
+
+                        IllegalStateException foo = new IllegalStateException("Invalid count");
+                        if (count % 2 == 0) {
+                            throw foo;
+                        }
+                    })
+                    .to("mock:result");
             }
         };
     }
diff --git a/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/event/notifier/route/MicroProfileMetricsRouteEventNotifierTest.java b/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/event/notifier/route/MicroProfileMetricsRouteEventNotifierTest.java
index 7062fd4..5a91dce 100644
--- a/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/event/notifier/route/MicroProfileMetricsRouteEventNotifierTest.java
+++ b/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/event/notifier/route/MicroProfileMetricsRouteEventNotifierTest.java
@@ -20,20 +20,21 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.RoutesBuilder;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.microprofile.metrics.MicroProfileMetricsTestSupport;
-import org.eclipse.microprofile.metrics.ConcurrentGauge;
+import org.eclipse.microprofile.metrics.Gauge;
 import org.junit.Test;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.DEFAULT_CAMEL_ROUTES_ADDED_METRIC_NAME;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.DEFAULT_CAMEL_ROUTES_RUNNING_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsHelper.findMetric;
 
 public class MicroProfileMetricsRouteEventNotifierTest extends MicroProfileMetricsTestSupport {
 
     @Test
     public void testMicroProfileMetricsEventNotifier() throws Exception {
-        ConcurrentGauge routesAdded = getConcurrentGauge(DEFAULT_CAMEL_ROUTES_ADDED_METRIC_NAME);
-        ConcurrentGauge routesRunning = getConcurrentGauge(DEFAULT_CAMEL_ROUTES_RUNNING_METRIC_NAME);
+        Gauge routesAdded = findMetric(metricRegistry, DEFAULT_CAMEL_ROUTES_ADDED_METRIC_NAME, Gauge.class);
+        Gauge routesRunning = findMetric(metricRegistry, DEFAULT_CAMEL_ROUTES_RUNNING_METRIC_NAME, Gauge.class);
 
-        assertEquals(1, routesAdded.getCount());
-        assertEquals(1, routesRunning.getCount());
+        assertEquals(1, routesAdded.getValue());
+        assertEquals(1, routesRunning.getValue());
 
         context.addRoutes(new RouteBuilder() {
             @Override
@@ -43,16 +44,16 @@ public class MicroProfileMetricsRouteEventNotifierTest extends MicroProfileMetri
             }
         });
 
-        assertEquals(2, routesAdded.getCount());
-        assertEquals(2, routesRunning.getCount());
+        assertEquals(2, routesAdded.getValue());
+        assertEquals(2, routesRunning.getValue());
 
         context.getRouteController().stopRoute("test");
-        assertEquals(2, routesAdded.getCount());
-        assertEquals(1, routesRunning.getCount());
+        assertEquals(2, routesAdded.getValue());
+        assertEquals(1, routesRunning.getValue());
 
         context.removeRoute("test");
-        assertEquals(1, routesAdded.getCount());
-        assertEquals(1, routesRunning.getCount());
+        assertEquals(1, routesAdded.getValue());
+        assertEquals(1, routesRunning.getValue());
     }
 
     @Override
diff --git a/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/message/history/MicroProfileMetricsMessageHistoryTest.java b/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/message/history/MicroProfileMetricsMessageHistoryTest.java
index 7b7cd49..a2660de 100644
--- a/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/message/history/MicroProfileMetricsMessageHistoryTest.java
+++ b/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/message/history/MicroProfileMetricsMessageHistoryTest.java
@@ -56,15 +56,15 @@ public class MicroProfileMetricsMessageHistoryTest extends MicroProfileMetricsTe
         assertEquals(3, timers.size());
 
         String contextTag = "camelContext=" + context.getName();
-        Tag[] fooTags = getTags(new String[] {contextTag, "nodeId=foo", "routeId=routeA", "serviceName=MicroProfileMetricsMessageHistory"});
+        Tag[] fooTags = getTags(new String[] {contextTag, "nodeId=foo", "routeId=routeA"});
         Timer fooTimer = MicroProfileMetricsHelper.findMetric(metricRegistry, DEFAULT_CAMEL_MESSAGE_HISTORY_METRIC_NAME, Timer.class, Arrays.asList(fooTags));
         assertEquals(count / 2, fooTimer.getCount());
 
-        Tag[] barTags = getTags(new String[] {contextTag, "nodeId=bar", "routeId=routeB", "serviceName=MicroProfileMetricsMessageHistory"});
+        Tag[] barTags = getTags(new String[] {contextTag, "nodeId=bar", "routeId=routeB"});
         Timer barTimer = MicroProfileMetricsHelper.findMetric(metricRegistry, DEFAULT_CAMEL_MESSAGE_HISTORY_METRIC_NAME, Timer.class, Arrays.asList(barTags));
         assertEquals(count / 2, barTimer.getCount());
 
-        Tag[] bazTags = getTags(new String[] {contextTag, "nodeId=baz", "routeId=routeB", "serviceName=MicroProfileMetricsMessageHistory"});
+        Tag[] bazTags = getTags(new String[] {contextTag, "nodeId=baz", "routeId=routeB"});
         Timer bazTimer = MicroProfileMetricsHelper.findMetric(metricRegistry, DEFAULT_CAMEL_MESSAGE_HISTORY_METRIC_NAME, Timer.class, Arrays.asList(bazTags));
         assertEquals(count / 2, bazTimer.getCount());
 
diff --git a/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/route/policy/MicroProfileMetricsRoutePolicyTest.java b/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/route/policy/MicroProfileMetricsRoutePolicyTest.java
index f518613..915f46e 100644
--- a/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/route/policy/MicroProfileMetricsRoutePolicyTest.java
+++ b/components/camel-microprofile-metrics/src/test/java/org/apache/camel/component/microprofile/metrics/route/policy/MicroProfileMetricsRoutePolicyTest.java
@@ -24,12 +24,23 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.microprofile.metrics.MicroProfileMetricsHelper;
 import org.apache.camel.component.microprofile.metrics.MicroProfileMetricsTestSupport;
+import org.apache.camel.component.microprofile.metrics.gauge.AtomicIntegerGauge;
 import org.apache.camel.component.mock.MockEndpoint;
+import org.eclipse.microprofile.metrics.Counter;
 import org.eclipse.microprofile.metrics.Snapshot;
 import org.eclipse.microprofile.metrics.Tag;
 import org.eclipse.microprofile.metrics.Timer;
 import org.junit.Test;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.CAMEL_CONTEXT_TAG;
 import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.DEFAULT_CAMEL_ROUTE_POLICY_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.DEFAULT_CAMEL_ROUTE_POLICY_PROCESSING_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_COMPLETED_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_EXTERNAL_REDELIVERIES_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_FAILED_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_FAILURES_HANDLED_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_INFLIGHT_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.EXCHANGES_TOTAL_METRIC_NAME;
+import static org.apache.camel.component.microprofile.metrics.MicroProfileMetricsConstants.ROUTE_ID_TAG;
 
 public class MicroProfileMetricsRoutePolicyTest extends MicroProfileMetricsTestSupport {
 
@@ -40,19 +51,19 @@ public class MicroProfileMetricsRoutePolicyTest extends MicroProfileMetricsTestS
     public void testMetricsRoutePolicy() throws Exception {
         int count = 10;
         MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
-        mockEndpoint.expectedMessageCount(count);
+        mockEndpoint.expectedMessageCount(7);
 
         for (int i = 0; i < count; i++) {
             if (i % 2 == 0) {
-                template.sendBody("direct:foo", "Hello " + i);
+                template.sendBody("direct:foo", i);
             } else {
-                template.sendBody("direct:bar", "Hello " + i);
+                template.sendBody("direct:bar", i);
             }
         }
 
         assertMockEndpointsSatisfied();
 
-        Timer fooTimer = getTimer(DEFAULT_CAMEL_ROUTE_POLICY_METRIC_NAME);
+        Timer fooTimer = getTimer(DEFAULT_CAMEL_ROUTE_POLICY_PROCESSING_METRIC_NAME);
         assertEquals(count / 2, fooTimer.getCount());
 
         Snapshot fooSnapshot = fooTimer.getSnapshot();
@@ -60,15 +71,43 @@ public class MicroProfileMetricsRoutePolicyTest extends MicroProfileMetricsTestS
         assertTrue(fooSnapshot.getMax() > DELAY_FOO);
 
         String contextTag = "camelContext=" + context.getName();
-        String[] tagStrings = new String[] {contextTag, "failed=false", "routeId=foo", "serviceName=MicroProfileMetricsRoutePolicyService"};
+        String[] tagStrings = new String[] {contextTag, "routeId=foo"};
         Tag[] tags = TagsUtils.parseTagsAsArray(tagStrings);
 
-        Timer barTimer = MicroProfileMetricsHelper.findMetric(metricRegistry, DEFAULT_CAMEL_ROUTE_POLICY_METRIC_NAME, Timer.class, Arrays.asList(tags));
+        Timer barTimer = MicroProfileMetricsHelper.findMetric(metricRegistry, DEFAULT_CAMEL_ROUTE_POLICY_PROCESSING_METRIC_NAME, Timer.class, Arrays.asList(tags));
         assertEquals(count / 2, barTimer.getCount());
 
         Snapshot barSnapshot = fooTimer.getSnapshot();
         assertTrue(barSnapshot.getMean() > DELAY_FOO);
         assertTrue(barSnapshot.getMax() > DELAY_FOO);
+
+        assertRouteExchangeMetrics("foo", 2);
+        assertRouteExchangeMetrics("bar", 1);
+    }
+
+    private void assertRouteExchangeMetrics(String routeId, int expectedFailuresHandled) {
+        Tag[] tags = new Tag[] {
+            new Tag(CAMEL_CONTEXT_TAG, context.getName()),
+            new Tag(ROUTE_ID_TAG, routeId)
+        };
+
+        Counter exchangesCompleted = getCounter(DEFAULT_CAMEL_ROUTE_POLICY_METRIC_NAME + EXCHANGES_COMPLETED_METRIC_NAME, tags);
+        assertEquals(5, exchangesCompleted.getCount());
+
+        Counter exchangesFailed = getCounter(DEFAULT_CAMEL_ROUTE_POLICY_METRIC_NAME + EXCHANGES_FAILED_METRIC_NAME, tags);
+        assertEquals(0, exchangesFailed.getCount());
+
+        Counter exchangesTotal = getCounter(DEFAULT_CAMEL_ROUTE_POLICY_METRIC_NAME + EXCHANGES_TOTAL_METRIC_NAME, tags);
+        assertEquals(5, exchangesTotal.getCount());
+
+        AtomicIntegerGauge exchangesInflight = getAtomicIntegerGauge(DEFAULT_CAMEL_ROUTE_POLICY_METRIC_NAME + EXCHANGES_INFLIGHT_METRIC_NAME, tags);
+        assertEquals(0, exchangesInflight.getValue().intValue());
+
+        Counter externalRedeliveries = getCounter(DEFAULT_CAMEL_ROUTE_POLICY_METRIC_NAME + EXCHANGES_EXTERNAL_REDELIVERIES_METRIC_NAME, tags);
+        assertEquals(0, externalRedeliveries.getCount());
+
+        Counter failuresHandled = getCounter(DEFAULT_CAMEL_ROUTE_POLICY_METRIC_NAME + EXCHANGES_FAILURES_HANDLED_METRIC_NAME, tags);
+        assertEquals(expectedFailuresHandled, failuresHandled.getCount());
     }
 
     @Override
@@ -76,9 +115,26 @@ public class MicroProfileMetricsRoutePolicyTest extends MicroProfileMetricsTestS
         return new RouteBuilder() {
             @Override
             public void configure() {
-                from("direct:foo").routeId("foo").delay(DELAY_FOO).to("mock:result");
-
-                from("direct:bar").routeId("bar").delay(DELAY_BAR).to("mock:result");
+                onException(IllegalStateException.class)
+                    .handled(true);
+
+                from("direct:foo").routeId("foo")
+                    .process(exchange -> {
+                        Integer count = exchange.getIn().getBody(Integer.class);
+                        if (count % 3 == 0) {
+                            throw new IllegalStateException("Invalid count");
+                        }
+                    })
+                    .delay(DELAY_FOO).to("mock:result");
+
+                from("direct:bar").routeId("bar")
+                    .process(exchange -> {
+                        Integer count = exchange.getIn().getBody(Integer.class);
+                        if (count % 5 == 0) {
+                            throw new IllegalStateException("Invalid count");
+                        }
+                    })
+                    .delay(DELAY_BAR).to("mock:result");
             }
         };
     }
diff --git a/docs/components/modules/ROOT/pages/microprofile-metrics-component.adoc b/docs/components/modules/ROOT/pages/microprofile-metrics-component.adoc
index 08c7c9a..f08a779 100644
--- a/docs/components/modules/ROOT/pages/microprofile-metrics-component.adoc
+++ b/docs/components/modules/ROOT/pages/microprofile-metrics-component.adoc
@@ -438,7 +438,7 @@ context.setMessageHistoryFactory(new MicroProfileMetricsMessageHistoryFactory())
 
 == MicroProfileMetricsExchangeEventNotifier
 
-The exchange event notifer times exchanges from creation through to completion.
+The exchange event notifier times exchanges from creation through to completion.
 
 EventNotifiers can be added to the `CamelContext`, e.g.:
 
@@ -450,7 +450,7 @@ camelContext.getManagementStrategy().addEventNotifier(new MicroProfileMetricsExc
 
 == MicroProfileMetricsRouteEventNotifier
 
-The route event notifer counts added and running routes within the `CamelContext`.
+The route event notifier counts added and running routes within the `CamelContext`.
 
 EventNotifiers can be added to the `CamelContext`, e.g.:
 
@@ -458,3 +458,14 @@ EventNotifiers can be added to the `CamelContext`, e.g.:
 ----
 camelContext.getManagementStrategy().addEventNotifier(new MicroProfileMetricsRouteEventNotifier())
 ----
+
+== MicroProfileMetricsCamelContextEventNotifier
+
+The Camel Context event notifier adds some basic metrics about the state of the `CamelContext`.
+
+EventNotifiers can be added to the `CamelContext`, e.g.:
+
+[source,java]
+----
+camelContext.getManagementStrategy().addEventNotifier(new MicroProfileMetricsCamelContextEventNotifier())
+----