You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2022/10/26 11:36:07 UTC

[camel] branch main updated (756b3c08063 -> 0c8364a8e02)

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

davsclaus pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


    from 756b3c08063 CAMEL-18148: fixed incorrect cache registration
     new 91c68bd6978 CAMEL-18650: camel-micrometer - Add dev console. Reuse created MetricRegistry if none exists.
     new f4cb93e6963 CAMEL-18650: camel-micrometer - Fix sorting
     new be94fddf515 CAMEL-18650: camel-micrometer - Polished
     new 0c8364a8e02 Add Dovetail to commercial support

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 components/camel-micrometer/pom.xml                |  10 +-
 .../org/apache/camel/dev-console/micrometer        |   2 +
 .../micrometer/DistributionSummaryProducer.java    |   6 -
 .../component/micrometer/MicrometerConsole.java    | 188 +++++++++++++++++++++
 .../component/micrometer/MicrometerEndpoint.java   |   2 +-
 .../component/micrometer/MicrometerUtils.java      |  12 +-
 .../camel/component/micrometer/TimerProducer.java  |   8 -
 .../micrometer/json/MicrometerModule.java          |   9 +-
 .../micrometer/MicrometerComponentTest.java        |  13 --
 .../messagehistory/ManagedMessageHistoryTest.java  |   1 -
 .../ROOT/pages/commercial-camel-offerings.adoc     |   7 +
 11 files changed, 218 insertions(+), 40 deletions(-)
 create mode 100644 components/camel-micrometer/src/generated/resources/META-INF/services/org/apache/camel/dev-console/micrometer
 create mode 100644 components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerConsole.java


[camel] 03/04: CAMEL-18650: camel-micrometer - Polished

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit be94fddf51501601176a07c8e21c4503a8cc484d
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Oct 26 13:32:53 2022 +0200

    CAMEL-18650: camel-micrometer - Polished
---
 .../camel/component/micrometer/DistributionSummaryProducer.java   | 6 ------
 .../java/org/apache/camel/component/micrometer/TimerProducer.java | 8 --------
 2 files changed, 14 deletions(-)

diff --git a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/DistributionSummaryProducer.java b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/DistributionSummaryProducer.java
index 181cd788cd0..830f1009870 100644
--- a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/DistributionSummaryProducer.java
+++ b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/DistributionSummaryProducer.java
@@ -22,15 +22,11 @@ import io.micrometer.core.instrument.DistributionSummary;
 import io.micrometer.core.instrument.MeterRegistry;
 import io.micrometer.core.instrument.Tag;
 import org.apache.camel.Exchange;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import static org.apache.camel.component.micrometer.MicrometerConstants.HEADER_HISTOGRAM_VALUE;
 
 public class DistributionSummaryProducer extends AbstractMicrometerProducer<DistributionSummary> {
 
-    private static final Logger LOG = LoggerFactory.getLogger(DistributionSummaryProducer.class);
-
     public DistributionSummaryProducer(MicrometerEndpoint endpoint) {
         super(endpoint);
     }
@@ -46,8 +42,6 @@ public class DistributionSummaryProducer extends AbstractMicrometerProducer<Dist
         Double finalValue = getDoubleHeader(exchange.getIn(), HEADER_HISTOGRAM_VALUE, value);
         if (finalValue != null) {
             summary.record(finalValue);
-        } else {
-            LOG.warn("Cannot update histogram \"{}\" with null value", summary.getId().getName());
         }
     }
 }
diff --git a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/TimerProducer.java b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/TimerProducer.java
index e7205493559..cc7d05640fd 100644
--- a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/TimerProducer.java
+++ b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/TimerProducer.java
@@ -23,15 +23,11 @@ import io.micrometer.core.instrument.Tag;
 import io.micrometer.core.instrument.Timer;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import static org.apache.camel.component.micrometer.MicrometerConstants.HEADER_TIMER_ACTION;
 
 public class TimerProducer extends AbstractMicrometerProducer<Timer> {
 
-    private static final Logger LOG = LoggerFactory.getLogger(TimerProducer.class);
-
     public TimerProducer(MicrometerEndpoint endpoint) {
         super(endpoint);
     }
@@ -59,8 +55,6 @@ public class TimerProducer extends AbstractMicrometerProducer<Timer> {
             handleStart(exchange, registry, metricsName);
         } else if (finalAction == MicrometerTimerAction.stop) {
             handleStop(exchange, metricsName, tags);
-        } else {
-            LOG.warn("No action provided for timer \"{}\"", metricsName);
         }
     }
 
@@ -76,8 +70,6 @@ public class TimerProducer extends AbstractMicrometerProducer<Timer> {
         if (sample == null) {
             sample = Timer.start(registry);
             exchange.setProperty(propertyName, sample);
-        } else {
-            LOG.warn("Timer \"{}\" already running", metricsName);
         }
     }
 


[camel] 04/04: Add Dovetail to commercial support

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 0c8364a8e028b5df643af28269e14af971298d2d
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Oct 26 13:35:56 2022 +0200

    Add Dovetail to commercial support
---
 .../user-manual/modules/ROOT/pages/commercial-camel-offerings.adoc | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/docs/user-manual/modules/ROOT/pages/commercial-camel-offerings.adoc b/docs/user-manual/modules/ROOT/pages/commercial-camel-offerings.adoc
index fd5ef068721..1ba0e7899dc 100644
--- a/docs/user-manual/modules/ROOT/pages/commercial-camel-offerings.adoc
+++ b/docs/user-manual/modules/ROOT/pages/commercial-camel-offerings.adoc
@@ -22,6 +22,13 @@ Software. We specialize in helping our clients to realize new projects
 and support the delivery of the project from end to end.
 
 
+== https://integrationmadeeasy.com[Dovetail]
+
+https://integrationmadeeasy.com[Dovetail] is a company based in the Netherlands.
+It offers a low-code integration platform based on Apache Camel, Apache ActiveMQ and
+https://assimbly.org[Assimbly]. The aim is to make integration as easy as possible.
+We provide cloud services, support and training.
+
 
 == http://ibm.biz/OSSupport[IBM]
 


[camel] 01/04: CAMEL-18650: camel-micrometer - Add dev console. Reuse created MetricRegistry if none exists.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 91c68bd69788efc5ad0f660619fbcdb20d193799
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Oct 26 13:17:53 2022 +0200

    CAMEL-18650: camel-micrometer - Add dev console. Reuse created MetricRegistry if none exists.
---
 components/camel-micrometer/pom.xml                |  10 +-
 .../org/apache/camel/dev-console/micrometer        |   2 +
 .../component/micrometer/MicrometerConsole.java    | 188 +++++++++++++++++++++
 .../component/micrometer/MicrometerEndpoint.java   |   2 +-
 .../component/micrometer/MicrometerUtils.java      |  12 +-
 .../micrometer/MicrometerComponentTest.java        |  13 --
 .../messagehistory/ManagedMessageHistoryTest.java  |   1 -
 7 files changed, 206 insertions(+), 22 deletions(-)

diff --git a/components/camel-micrometer/pom.xml b/components/camel-micrometer/pom.xml
index 4f9642a51bd..938c73f76df 100644
--- a/components/camel-micrometer/pom.xml
+++ b/components/camel-micrometer/pom.xml
@@ -38,9 +38,10 @@
             <artifactId>camel-support</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-databind</artifactId>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-console</artifactId>
         </dependency>
+
         <dependency>
             <groupId>io.micrometer</groupId>
             <artifactId>micrometer-core</artifactId>
@@ -53,6 +54,11 @@
             <optional>true</optional>
         </dependency>
 
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+
         <!-- testing -->
         <dependency>
             <groupId>org.apache.camel</groupId>
diff --git a/components/camel-micrometer/src/generated/resources/META-INF/services/org/apache/camel/dev-console/micrometer b/components/camel-micrometer/src/generated/resources/META-INF/services/org/apache/camel/dev-console/micrometer
new file mode 100644
index 00000000000..6d80ff62594
--- /dev/null
+++ b/components/camel-micrometer/src/generated/resources/META-INF/services/org/apache/camel/dev-console/micrometer
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.micrometer.MicrometerConsole
diff --git a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerConsole.java b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerConsole.java
new file mode 100644
index 00000000000..021b7073c74
--- /dev/null
+++ b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerConsole.java
@@ -0,0 +1,188 @@
+/*
+ * 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.micrometer;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import io.micrometer.core.instrument.Counter;
+import io.micrometer.core.instrument.DistributionSummary;
+import io.micrometer.core.instrument.Gauge;
+import io.micrometer.core.instrument.LongTaskTimer;
+import io.micrometer.core.instrument.Meter;
+import io.micrometer.core.instrument.MeterRegistry;
+import org.apache.camel.impl.console.AbstractDevConsole;
+import org.apache.camel.spi.annotations.DevConsole;
+import org.apache.camel.util.json.JsonObject;
+
+@DevConsole("micrometer")
+public class MicrometerConsole extends AbstractDevConsole {
+
+    public MicrometerConsole() {
+        super("camel", "micrometer", "Micrometer", "Display runtime metrics");
+    }
+
+    @Override
+    protected String doCallText(Map<String, Object> options) {
+        StringBuilder sb = new StringBuilder();
+
+        MeterRegistry mr = lookupMeterRegistry();
+        int i = 0;
+        for (Meter m : mr.getMeters()) {
+            if (m instanceof Counter) {
+                Counter c = (Counter) m;
+                if (i == 0) {
+                    sb.append("Counters:\n");
+                }
+                i++;
+                String name = c.getId().getName();
+                double cnt = c.count();
+                sb.append(String.format("    %s: %s\n", name, cnt));
+            }
+        }
+        i = 0;
+        for (Meter m : mr.getMeters()) {
+            if (m instanceof Gauge) {
+                Gauge g = (Gauge) m;
+                if (i == 0) {
+                    sb.append("\nGauges:\n");
+                }
+                i++;
+                String name = g.getId().getName();
+                double cnt = g.value();
+                sb.append(String.format("    %s: %s\n", name, cnt));
+            }
+        }
+        i = 0;
+        for (Meter m : mr.getMeters()) {
+            if (m instanceof LongTaskTimer) {
+                LongTaskTimer t = (LongTaskTimer) m;
+                if (i == 0) {
+                    sb.append("\nLongTaskTimer:\n");
+                }
+                i++;
+                String name = t.getId().getName();
+                int tasks = t.activeTasks();
+                double mean = t.mean(TimeUnit.MILLISECONDS);
+                double max = t.max(TimeUnit.MILLISECONDS);
+                double duration = t.duration(TimeUnit.MILLISECONDS);
+                sb.append(String.format("    %s: %d (duration: %f mean: %f max: %f)\n", name, tasks, duration, mean, max));
+            }
+        }
+        i = 0;
+        for (Meter m : mr.getMeters()) {
+            if (m instanceof DistributionSummary) {
+                DistributionSummary d = (DistributionSummary) m;
+                if (i == 0) {
+                    sb.append("\nDistributionSummary:\n");
+                }
+                i++;
+                String name = d.getId().getName();
+                long count = d.count();
+                double mean = d.mean();
+                double max = d.max();
+                double total = d.totalAmount();
+                sb.append(String.format("    %s: %d (total: %f mean: %f max: %f)\n", name, count, total, mean, max));
+            }
+        }
+
+        return sb.toString();
+    }
+
+    @Override
+    protected JsonObject doCallJson(Map<String, Object> options) {
+        JsonObject root = new JsonObject();
+
+        MeterRegistry mr = lookupMeterRegistry();
+        int i = 0;
+        for (Meter m : mr.getMeters()) {
+            final List<JsonObject> list = new ArrayList<>();
+            if (m instanceof Counter) {
+                Counter c = (Counter) m;
+                if (i == 0) {
+                    root.put("counters", list);
+                }
+                i++;
+                JsonObject jo = new JsonObject();
+                jo.put("name", c.getId().getName());
+                jo.put("count", c.count());
+                list.add(jo);
+            }
+        }
+        i = 0;
+        for (Meter m : mr.getMeters()) {
+            final List<JsonObject> list = new ArrayList<>();
+            if (m instanceof Gauge) {
+                Gauge g = (Gauge) m;
+                if (i == 0) {
+                    root.put("gauges", list);
+                }
+                i++;
+                JsonObject jo = new JsonObject();
+                jo.put("name", g.getId().getName());
+                jo.put("value", g.value());
+                list.add(jo);
+            }
+        }
+        i = 0;
+        for (Meter m : mr.getMeters()) {
+            if (m instanceof LongTaskTimer) {
+                final List<JsonObject> list = new ArrayList<>();
+                LongTaskTimer t = (LongTaskTimer) m;
+                if (i == 0) {
+                    root.put("timers", list);
+                }
+                i++;
+                JsonObject jo = new JsonObject();
+                jo.put("name", t.getId().getName());
+                jo.put("activeTasks", t.activeTasks());
+                jo.put("mean", t.mean(TimeUnit.MILLISECONDS));
+                jo.put("max", t.max(TimeUnit.MILLISECONDS));
+                jo.put("duration", t.duration(TimeUnit.MILLISECONDS));
+                list.add(jo);
+            }
+        }
+        i = 0;
+        for (Meter m : mr.getMeters()) {
+            if (m instanceof DistributionSummary) {
+                final List<JsonObject> list = new ArrayList<>();
+                DistributionSummary d = (DistributionSummary) m;
+                if (i == 0) {
+                    root.put("distribution", list);
+                }
+                i++;
+                JsonObject jo = new JsonObject();
+                jo.put("name", d.getId().getName());
+                jo.put("count", d.count());
+                jo.put("mean", d.mean());
+                jo.put("max", d.max());
+                jo.put("totalAmount", d.totalAmount());
+                list.add(jo);
+            }
+        }
+
+        return root;
+    }
+
+    private MeterRegistry lookupMeterRegistry() {
+        return MicrometerUtils.getOrCreateMeterRegistry(getCamelContext().getRegistry(),
+                MicrometerConstants.METRICS_REGISTRY_NAME);
+    }
+
+}
diff --git a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerEndpoint.java b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerEndpoint.java
index f459a2cfe13..a2ca49af90f 100644
--- a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerEndpoint.java
+++ b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerEndpoint.java
@@ -41,7 +41,7 @@ public class MicrometerEndpoint extends DefaultEndpoint {
 
     protected MeterRegistry registry;
 
-    @UriPath(description = "Type of metrics", enums = "counter, distribution_summary, timer")
+    @UriPath(description = "Type of metrics", enums = "counter,distribution_summary,timer")
     @Metadata(required = true)
     protected final Meter.Type metricsType;
     @UriPath(description = "Name of metrics")
diff --git a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerUtils.java b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerUtils.java
index 4639a440f7d..3236043a697 100644
--- a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerUtils.java
+++ b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerUtils.java
@@ -56,13 +56,15 @@ public abstract class MicrometerUtils {
         }
     }
 
-    public static MeterRegistry getOrCreateMeterRegistry(Registry camelRegistry, String registryName) {
-        LOG.debug("Looking up MeterRegistry from Camel Registry for name \"{}\"", registryName);
-        MeterRegistry result = getMeterRegistryFromCamelRegistry(camelRegistry, registryName);
+    public static MeterRegistry getOrCreateMeterRegistry(Registry camelRegistry, String name) {
+        MeterRegistry result = getMeterRegistryFromCamelRegistry(camelRegistry, name);
         if (result == null) {
-            LOG.debug("MeterRegistry not found from Camel Registry for name \"{}\"", registryName);
-            LOG.info("Creating new default MeterRegistry");
+            LOG.debug("Creating new MeterRegistry: {}", name);
             result = createMeterRegistry();
+            // enlist in registry so it can be reused
+            camelRegistry.bind(name, result);
+        } else {
+            LOG.debug("Using existing MeterRegistry: {}", name);
         }
         return result;
     }
diff --git a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/MicrometerComponentTest.java b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/MicrometerComponentTest.java
index 1698b2de9d6..142004e9dfd 100644
--- a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/MicrometerComponentTest.java
+++ b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/MicrometerComponentTest.java
@@ -39,7 +39,6 @@ import org.mockito.junit.jupiter.MockitoExtension;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.instanceOf;
 import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.mockito.Mockito.times;
@@ -156,18 +155,6 @@ public class MicrometerComponentTest {
         inOrder.verifyNoMoreInteractions();
     }
 
-    @Test
-    public void testGetOrCreateMetricRegistryNotFoundInCamelRegistry() {
-        when(camelRegistry.lookupByNameAndType("name", MeterRegistry.class)).thenReturn(null);
-        when(camelRegistry.findByType(MeterRegistry.class)).thenReturn(Collections.emptySet());
-        MeterRegistry result = MicrometerUtils.getOrCreateMeterRegistry(camelRegistry, "name");
-        assertThat(result, is(notNullValue()));
-        assertThat(result, is(not(metricRegistry)));
-        inOrder.verify(camelRegistry, times(1)).lookupByNameAndType("name", MeterRegistry.class);
-        inOrder.verify(camelRegistry, times(1)).findByType(MeterRegistry.class);
-        inOrder.verifyNoMoreInteractions();
-    }
-
     @Test
     public void testGetMetricRegistryFromCamelRegistry() {
         when(camelRegistry.lookupByNameAndType("name", MeterRegistry.class)).thenReturn(metricRegistry);
diff --git a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/ManagedMessageHistoryTest.java b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/ManagedMessageHistoryTest.java
index 548530e862f..ce1e0bd1993 100644
--- a/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/ManagedMessageHistoryTest.java
+++ b/components/camel-micrometer/src/test/java/org/apache/camel/component/micrometer/messagehistory/ManagedMessageHistoryTest.java
@@ -99,7 +99,6 @@ public class ManagedMessageHistoryTest extends CamelTestSupport {
         // there should be 3 mbeans
         Set<ObjectName> set
                 = getMBeanServer().queryNames(new ObjectName("org.apache.camel.micrometer:type=timers,name=*"), null);
-        System.out.println(set);
         assertEquals(3, set.size());
 
         ObjectName fooMBean = set.stream().filter(on -> on.getCanonicalName().contains("foo")).findFirst()


[camel] 02/04: CAMEL-18650: camel-micrometer - Fix sorting

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit f4cb93e6963f8f17c5e8bb2119fc806036edd7e4
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Oct 26 13:29:45 2022 +0200

    CAMEL-18650: camel-micrometer - Fix sorting
---
 .../apache/camel/component/micrometer/json/MicrometerModule.java | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/json/MicrometerModule.java b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/json/MicrometerModule.java
index 26a271b07e1..f499fda1cc5 100644
--- a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/json/MicrometerModule.java
+++ b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/json/MicrometerModule.java
@@ -19,6 +19,7 @@ package org.apache.camel.component.micrometer.json;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Comparator;
+import java.util.LinkedHashSet;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Predicate;
@@ -128,8 +129,8 @@ public class MicrometerModule extends Module {
             json.writeNumberField("total", snapshot.total(timeUnit));
             ValueAtPercentile[] percentiles = snapshot.percentileValues();
             for (ValueAtPercentile percentile : percentiles) {
-                // TODO format "p%0.3d" is incorrect
-                json.writeNumberField(String.format("p%0.3d", percentile.percentile()), percentile.value(timeUnit));
+                int p = (int) percentile.percentile() * 100;
+                json.writeNumberField("p" + p, percentile.value(timeUnit));
             }
         }
     }
@@ -278,12 +279,12 @@ public class MicrometerModule extends Module {
                 return ((CompositeMeterRegistry) meterRegistry).getRegistries().stream()
                         .flatMap(reg -> meters(reg, clazz, matchingNames, matchingTags).stream())
                         .sorted(Comparator.comparing(o -> o.getId().getName()))
-                        .collect(Collectors.toSet());
+                        .collect(Collectors.toCollection(LinkedHashSet::new));
             }
             return Search.in(meterRegistry).name(matchingNames).tags(matchingTags).meters().stream()
                     .filter(clazz::isInstance)
                     .sorted(Comparator.comparing(o -> o.getId().getName()))
-                    .collect(Collectors.toSet());
+                    .collect(Collectors.toCollection(LinkedHashSet::new));
         }
 
     }