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/09/09 08:17:59 UTC
[camel] 01/03: CAMEL-18488: camel-management - Statistic for current throughput
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 037de46fcca244c1b386aea1a2636408f9fd2896
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Fri Sep 9 09:31:37 2022 +0200
CAMEL-18488: camel-management - Statistic for current throughput
---
.../camel/impl/console/ContextDevConsole.java | 11 ++++
.../apache/camel/impl/console/RouteDevConsole.java | 11 ++++
.../management/mbean/ManagedCamelContextMBean.java | 3 +
.../api/management/mbean/ManagedRouteMBean.java | 3 +
.../camel/management/mbean/LoadThroughput.java | 64 ++++++++++++++++++++++
.../management/mbean/ManagedCamelContext.java | 13 +++++
.../camel/management/mbean/ManagedRoute.java | 13 +++++
.../main/java/org/apache/camel/util/StopWatch.java | 13 ++++-
.../core/commands/process/CamelContextStatus.java | 14 +++++
.../core/commands/process/CamelRouteStatus.java | 14 +++++
10 files changed, 157 insertions(+), 2 deletions(-)
diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/ContextDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/ContextDevConsole.java
index 0f1cafa1196..b93b346a317 100644
--- a/core/camel-console/src/main/java/org/apache/camel/impl/console/ContextDevConsole.java
+++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/ContextDevConsole.java
@@ -129,6 +129,10 @@ public class ContextDevConsole extends AbstractDevConsole {
stats.put("load05", load5);
stats.put("load15", load15);
}
+ String thp = getThroughput(mb);
+ if (!thp.isEmpty()) {
+ stats.put("exchangesThroughput", thp);
+ }
stats.put("exchangesTotal", mb.getExchangesTotal());
stats.put("exchangesFailed", mb.getExchangesFailed());
stats.put("exchangesInflight", mb.getExchangesInflight());
@@ -179,4 +183,11 @@ public class ContextDevConsole extends AbstractDevConsole {
return s;
}
+ private String getThroughput(ManagedCamelContextMBean mb) {
+ String s = mb.getThroughput();
+ // lets use dot as separator
+ s = s.replace(',', '.');
+ return s;
+ }
+
}
diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDevConsole.java
index 7be50248e07..0a31a67f147 100644
--- a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDevConsole.java
+++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDevConsole.java
@@ -121,6 +121,10 @@ public class RouteDevConsole extends AbstractDevConsole {
stats.put("load05", load5);
stats.put("load15", load15);
}
+ String thp = getThroughput(mrb);
+ if (!thp.isEmpty()) {
+ stats.put("exchangesThroughput", thp);
+ }
stats.put("exchangesTotal", mrb.getExchangesTotal());
stats.put("exchangesFailed", mrb.getExchangesFailed());
stats.put("exchangesInflight", mrb.getExchangesInflight());
@@ -207,4 +211,11 @@ public class RouteDevConsole extends AbstractDevConsole {
return s;
}
+ private String getThroughput(ManagedRouteMBean mrb) {
+ String s = mrb.getThroughput();
+ // lets use dot as separator
+ s = s.replace(',', '.');
+ return s;
+ }
+
}
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
index 75c2fa1a022..d5924f3ed79 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
+++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
@@ -123,6 +123,9 @@ public interface ManagedCamelContextMBean extends ManagedPerformanceCounterMBean
@ManagedAttribute(description = "Average load over the last fifteen minutes")
String getLoad15();
+ @ManagedAttribute(description = "Throughput message/second")
+ String getThroughput();
+
@ManagedAttribute(description = "Whether breadcrumbs is in use")
boolean isUseBreadcrumb();
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
index 83867af9540..72b00aa6a43 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
+++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
@@ -88,6 +88,9 @@ public interface ManagedRouteMBean extends ManagedPerformanceCounterMBean {
@ManagedAttribute(description = "Average load over the last fifteen minutes")
String getLoad15();
+ @ManagedAttribute(description = "Throughput message/second")
+ String getThroughput();
+
@ManagedOperation(description = "Start route")
void start() throws Exception;
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/LoadThroughput.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/LoadThroughput.java
new file mode 100644
index 00000000000..546f00d7bae
--- /dev/null
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/LoadThroughput.java
@@ -0,0 +1,64 @@
+/*
+ * 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.management.mbean;
+
+import org.apache.camel.util.StopWatch;
+
+/**
+ * Holds the load throughput messages/second
+ */
+public final class LoadThroughput {
+
+ private final StopWatch watch = new StopWatch(false);
+ private long last;
+ private double thp = Double.NaN;
+
+ /**
+ * Update the load statistics
+ *
+ * @param currentReading the current reading
+ */
+ public void update(long currentReading) {
+ if (watch.taken() == 0) {
+ watch.restart();
+ thp = 0;
+ } else {
+ long time = watch.takenAndRestart();
+ if (time > 0) {
+ long delta = currentReading - last;
+ if (delta > 0) {
+ thp = (1000 / time) * delta;
+ } else {
+ thp = 0;
+ }
+ } else {
+ thp = 0;
+ }
+ }
+ last = currentReading;
+ }
+
+ public double getThroughput() {
+ return thp;
+ }
+
+ @Override
+ public String toString() {
+ return "" + thp;
+ }
+
+}
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
index 44a0c7d1701..15a7a0c9974 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
@@ -58,6 +58,7 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
private final CamelContext context;
private final LoadTriplet load = new LoadTriplet();
+ private final LoadThroughput thp = new LoadThroughput();
private final String jmxDomain;
public ManagedCamelContext(CamelContext context) {
@@ -256,6 +257,17 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
}
}
+ @Override
+ public String getThroughput() {
+ double d = thp.getThroughput();
+ if (Double.isNaN(d)) {
+ // empty string if load statistics is disabled
+ return "";
+ } else {
+ return String.format("%.2f", d);
+ }
+ }
+
@Override
public boolean isUseBreadcrumb() {
return context.isUseBreadcrumb();
@@ -289,6 +301,7 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
@Override
public void onTimer() {
load.update(getInflightExchanges());
+ thp.update(getExchangesTotal());
}
@Override
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
index ec490f49bb6..6b1ad0db16c 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
@@ -77,6 +77,7 @@ public class ManagedRoute extends ManagedPerformanceCounter implements TimerList
protected final String sourceLocationShort;
protected final CamelContext context;
private final LoadTriplet load = new LoadTriplet();
+ private final LoadThroughput thp = new LoadThroughput();
private final String jmxDomain;
public ManagedRoute(CamelContext context, Route route) {
@@ -277,9 +278,21 @@ public class ManagedRoute extends ManagedPerformanceCounter implements TimerList
}
}
+ @Override
+ public String getThroughput() {
+ double d = thp.getThroughput();
+ if (Double.isNaN(d)) {
+ // empty string if load statistics is disabled
+ return "";
+ } else {
+ return String.format("%.2f", d);
+ }
+ }
+
@Override
public void onTimer() {
load.update(getInflightExchanges());
+ thp.update(getExchangesTotal());
}
@Override
diff --git a/core/camel-util/src/main/java/org/apache/camel/util/StopWatch.java b/core/camel-util/src/main/java/org/apache/camel/util/StopWatch.java
index 71d6625e31b..9615d4094a7 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/StopWatch.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/StopWatch.java
@@ -67,13 +67,22 @@ public final class StopWatch {
public long taken() {
if (start > 0) {
long delta = System.nanoTime() - start;
-
return Duration.ofNanos(delta).toMillis();
}
-
return 0;
}
+ /**
+ * Returns the time taken in millis and restarts the timer.
+ *
+ * @return time in millis, or <tt>0</tt> if not started yet.
+ */
+ public long takenAndRestart() {
+ long answer = taken();
+ restart();
+ return answer;
+ }
+
/**
* Utility method to provide the elapsed time using milliseconds since epoch. This serves as an alternative for the
* former constructor based on a Date argument. This should be used only when converting old code that relies on
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java
index 09bd9bdcb49..33c719c8b9d 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java
@@ -74,6 +74,10 @@ public class CamelContextStatus extends ProcessBaseCommand {
row.camelVersion = context.getString("version");
Map<String, ?> stats = context.getMap("statistics");
if (stats != null) {
+ Object thp = stats.get("exchangesThroughput");
+ if (thp != null) {
+ row.throughput = thp.toString();
+ }
row.total = stats.get("exchangesTotal").toString();
row.inflight = stats.get("exchangesInflight").toString();
row.failed = stats.get("exchangesFailed").toString();
@@ -129,6 +133,7 @@ public class CamelContextStatus extends ProcessBaseCommand {
.with(r -> r.reloaded),
new Column().header("AGE").headerAlign(HorizontalAlign.CENTER).with(r -> r.ago),
new Column().header("ROUTE").with(this::getRoutes),
+ new Column().header("MSG/S").with(this::getThroughput),
new Column().header("TOTAL").with(r -> r.total),
new Column().header("FAIL").with(r -> r.failed),
new Column().header("INFLIGHT").with(r -> r.inflight),
@@ -178,6 +183,14 @@ public class CamelContextStatus extends ProcessBaseCommand {
return s1 + "/" + s2 + "/" + s3;
}
+ private String getThroughput(Row r) {
+ String s = r.throughput;
+ if ("0.00".equals(s) || s.isEmpty()) {
+ s = "-";
+ }
+ return s;
+ }
+
private String getRoutes(Row r) {
return r.routeStarted + "/" + r.routeTotal;
}
@@ -195,6 +208,7 @@ public class CamelContextStatus extends ProcessBaseCommand {
String reloaded;
String ago;
long uptime;
+ String throughput;
String total;
String failed;
String inflight;
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java
index 90c7140bc37..f77cce19600 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java
@@ -94,6 +94,10 @@ public class CamelRouteStatus extends ProcessBaseCommand {
if (load != null) {
row.load15 = load.toString();
}
+ Object thp = stats.get("exchangesThroughput");
+ if (thp != null) {
+ row.throughput = thp.toString();
+ }
row.total = stats.get("exchangesTotal").toString();
row.inflight = stats.get("exchangesInflight").toString();
row.failed = stats.get("exchangesFailed").toString();
@@ -153,6 +157,7 @@ public class CamelRouteStatus extends ProcessBaseCommand {
new Column().header("STATUS").headerAlign(HorizontalAlign.CENTER)
.with(r -> r.state),
new Column().header("AGE").headerAlign(HorizontalAlign.CENTER).with(r -> r.age),
+ new Column().header("MSG/S").with(this::getThroughput),
new Column().header("TOTAL").with(r -> r.total),
new Column().header("FAIL").with(r -> r.failed),
new Column().header("INFLIGHT").with(r -> r.inflight),
@@ -182,6 +187,14 @@ public class CamelRouteStatus extends ProcessBaseCommand {
}
}
+ private String getThroughput(Row r) {
+ String s = r.throughput;
+ if ("0.00".equals(s) || s.isEmpty()) {
+ s = "-";
+ }
+ return s;
+ }
+
static class Row {
String pid;
String name;
@@ -191,6 +204,7 @@ public class CamelRouteStatus extends ProcessBaseCommand {
String source;
String state;
String age;
+ String throughput;
String total;
String failed;
String inflight;