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/06/29 05:53:11 UTC

[camel] branch main updated: CAMEL-18237: TimeUtils.printDuration now output in short format by default (ala Kubernetes). Added printAge/printSince methods

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


The following commit(s) were added to refs/heads/main by this push:
     new ca8b653c50b CAMEL-18237: TimeUtils.printDuration now output in short format by default (ala Kubernetes). Added printAge/printSince methods
ca8b653c50b is described below

commit ca8b653c50b0ee32a522455635fbc4c7564c5972
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Jun 29 07:52:53 2022 +0200

    CAMEL-18237: TimeUtils.printDuration now output in short format by default (ala Kubernetes). Added printAge/printSince methods
---
 .../language/csimple/joor/JoorCSimpleCompiler.java |  2 +-
 .../camel/component/file/GenericFileConsumer.java  |  2 +-
 .../remote/DefaultFtpClientActivityListener.java   |  4 +-
 .../camel/component/file/remote/FtpConsumer.java   |  9 +---
 .../camel/component/file/remote/FtpOperations.java |  2 +-
 .../component/file/remote/SftpOperations.java      |  2 +-
 .../camel/component/jetty/HttpProxyRouteTest.java  |  2 +-
 .../camel/component/kafka/KafkaFetchRecords.java   |  4 +-
 .../camel/component/kafka/TaskHealthState.java     |  2 +-
 .../saxon/XPathSplitChoicePerformanceTest.java     |  2 +-
 .../StAXXPathSplitChoicePerformanceManualTest.java |  2 +-
 .../apache/camel/test/junit5/CamelTestSupport.java |  2 +-
 .../camel/test/main/junit5/CamelMainExtension.java |  2 +-
 .../junit5/StopWatchTestExecutionListener.java     |  2 +-
 .../spring/StopWatchTestExecutionListener.java     |  2 +-
 .../apache/camel/test/junit4/CamelTestSupport.java |  2 +-
 .../camel/impl/engine/AbstractCamelContext.java    | 20 +++----
 .../impl/engine/BaseExecutorServiceManager.java    |  6 +--
 .../camel/impl/engine/DefaultShutdownStrategy.java |  2 +-
 .../camel/impl/converter/DefaultTypeConverter.java |  4 +-
 .../apache/camel/impl/event/ExchangeSentEvent.java |  2 +-
 .../camel/impl/console/ContextDevConsole.java      |  6 +--
 .../impl/console/DefaultDevConsoleRegistry.java    |  2 +-
 .../apache/camel/impl/console/EventConsole.java    | 13 ++++-
 .../apache/camel/impl/console/RouteDevConsole.java |  6 +--
 .../apache/camel/impl/console/TopDevConsole.java   | 20 +++----
 .../impl/lw/LightweightRuntimeCamelContext.java    |  2 +-
 .../processor/aggregate/AggregateProcessor.java    |  4 +-
 .../camel/component/bean/BeanPerformanceTest.java  |  2 +-
 .../camel/impl/ClassicUuidGeneratorTest.java       |  2 +-
 .../camel/impl/DefaultUuidGeneratorTest.java       |  2 +-
 .../apache/camel/impl/ShortUuidGeneratorTest.java  |  2 +-
 .../apache/camel/impl/SimpleUuidGeneratorTest.java |  2 +-
 .../camel/impl/VanillaUuidGeneratorTest.java       |  2 +-
 ...irIteratorSplitChoicePerformanceManualTest.java |  2 +-
 .../XPathSplitChoicePerformanceManualTest.java     |  2 +-
 .../SplitterParallelBigFileManualTest.java         |  2 +-
 .../impl/health/DefaultHealthCheckRegistry.java    |  2 +-
 .../camel/main/DefaultMainShutdownStrategy.java    |  4 +-
 .../apache/camel/main/EagerClassloadedHelper.java  |  2 +-
 .../org/apache/camel/main/RoutesConfigurer.java    |  2 +-
 .../mbean/ManagedSupervisingRouteController.java   |  4 +-
 .../main/java/org/apache/camel/util/TimeUtils.java | 62 ++++++++++++++++------
 .../java/org/apache/camel/util/TimeUtilsTest.java  | 37 ++++++++++---
 .../ROOT/pages/camel-3x-upgrade-guide-3_18.adoc    |  3 ++
 .../camel/main/download/DownloadThreadPool.java    |  2 +-
 46 files changed, 162 insertions(+), 104 deletions(-)

diff --git a/components/camel-csimple-joor/src/main/java/org/apache/camel/language/csimple/joor/JoorCSimpleCompiler.java b/components/camel-csimple-joor/src/main/java/org/apache/camel/language/csimple/joor/JoorCSimpleCompiler.java
index f9c2261bf20..4ef12b57527 100644
--- a/components/camel-csimple-joor/src/main/java/org/apache/camel/language/csimple/joor/JoorCSimpleCompiler.java
+++ b/components/camel-csimple-joor/src/main/java/org/apache/camel/language/csimple/joor/JoorCSimpleCompiler.java
@@ -157,7 +157,7 @@ public class JoorCSimpleCompiler extends ServiceSupport implements CSimpleCompil
     protected void doStop() throws Exception {
         super.doStop();
         if (counter > 0) {
-            LOG.info("csimple-joor compiled {} scripts in {}", counter, TimeUtils.printDuration(taken));
+            LOG.info("csimple-joor compiled {} scripts in {}", counter, TimeUtils.printDuration(taken, true));
         }
     }
 
diff --git a/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java b/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java
index d62b814fe0c..a73072ffe72 100644
--- a/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java
+++ b/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java
@@ -151,7 +151,7 @@ public abstract class GenericFileConsumer<T> extends ScheduledBatchPollingConsum
 
         long delta = stop.taken();
         if (LOG.isDebugEnabled()) {
-            LOG.debug("Took {} to poll: {}", TimeUtils.printDuration(delta), name);
+            LOG.debug("Took {} to poll: {}", TimeUtils.printDuration(delta, true), name);
         }
 
         // log if we hit the limit
diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/DefaultFtpClientActivityListener.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/DefaultFtpClientActivityListener.java
index 2c2685990b5..c175ca41f79 100644
--- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/DefaultFtpClientActivityListener.java
+++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/DefaultFtpClientActivityListener.java
@@ -215,7 +215,7 @@ public class DefaultFtpClientActivityListener implements FtpClientActivityListen
             msg += " (size: " + StringHelper.humanReadableBytes(transferredBytes) + ")";
         }
         long taken = watch.taken();
-        String time = TimeUtils.printDuration(taken);
+        String time = TimeUtils.printDuration(taken, true);
         msg += " (took: " + time + ")";
         doLog(msg);
     }
@@ -269,7 +269,7 @@ public class DefaultFtpClientActivityListener implements FtpClientActivityListen
             msg += " (size: " + StringHelper.humanReadableBytes(transferredBytes) + ")";
         }
         long taken = watch.taken();
-        String time = TimeUtils.printDuration(taken);
+        String time = TimeUtils.printDuration(taken, true);
         msg += " (took: " + time + ")";
         doLog(msg);
     }
diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpConsumer.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpConsumer.java
index 1b51b21abba..2280d88adb5 100644
--- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpConsumer.java
+++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpConsumer.java
@@ -31,7 +31,6 @@ import org.apache.camel.component.file.GenericFileOperationFailedException;
 import org.apache.camel.component.file.GenericFileProcessStrategy;
 import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.ObjectHelper;
-import org.apache.camel.util.StopWatch;
 import org.apache.camel.util.StringHelper;
 import org.apache.camel.util.TimeUtils;
 import org.apache.camel.util.URISupport;
@@ -347,9 +346,7 @@ public class FtpConsumer extends RemoteFileConsumer<FTPFile> {
             if (log != null) {
                 long since = listener.getLastLogActivityTimestamp();
                 if (since > 0) {
-                    StopWatch watch = new StopWatch(new Date(since));
-                    long delta = watch.taken();
-                    String human = TimeUtils.printDuration(delta);
+                    String human = TimeUtils.printSince(since);
                     return log + " " + human + " ago";
                 } else {
                     return log;
@@ -368,9 +365,7 @@ public class FtpConsumer extends RemoteFileConsumer<FTPFile> {
             if (log != null) {
                 long since = listener.getLastVerboseLogActivityTimestamp();
                 if (since > 0) {
-                    StopWatch watch = new StopWatch(new Date(since));
-                    long delta = watch.taken();
-                    String human = TimeUtils.printDuration(delta);
+                    String human = TimeUtils.printSince(since);
                     return log + " " + human + " ago";
                 } else {
                     return log;
diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperations.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperations.java
index 951ef7e8e0c..e29ba3e1aae 100644
--- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperations.java
+++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperations.java
@@ -768,7 +768,7 @@ public class FtpOperations implements RemoteFileOperations<FTPFile> {
             if (log.isDebugEnabled()) {
                 long time = watch.taken();
                 log.debug("Took {} ({} millis) to store file: {} and FTP client returned: {}",
-                        TimeUtils.printDuration(time), time, targetName, answer);
+                        TimeUtils.printDuration(time, true), time, targetName, answer);
             }
 
             // store client reply information after the operation
diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java
index 3ab3df60131..7145e618a83 100644
--- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java
+++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java
@@ -1030,7 +1030,7 @@ public class SftpOperations implements RemoteFileOperations<SftpRemoteFile> {
             if (LOG.isDebugEnabled()) {
                 long time = watch.taken();
                 LOG.debug("Took {} ({} millis) to store file: {} and FTP client returned: true",
-                        TimeUtils.printDuration(time), time, targetName);
+                        TimeUtils.printDuration(time, true), time, targetName);
             }
 
             // after storing file, we may set chmod on the file
diff --git a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpProxyRouteTest.java b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpProxyRouteTest.java
index a2f741a2ddf..e4928eada32 100644
--- a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpProxyRouteTest.java
+++ b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpProxyRouteTest.java
@@ -44,7 +44,7 @@ public class HttpProxyRouteTest extends BaseJettyTest {
             assertEquals("Bye " + i, out);
         }
 
-        LOG.info("Time taken: " + TimeUtils.printDuration(watch.taken()));
+        LOG.info("Time taken: " + TimeUtils.printDuration(watch.taken(), true));
     }
 
     @Test
diff --git a/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/KafkaFetchRecords.java b/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/KafkaFetchRecords.java
index f6f7392a6ac..e92d08f4c19 100644
--- a/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/KafkaFetchRecords.java
+++ b/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/KafkaFetchRecords.java
@@ -167,7 +167,7 @@ public class KafkaFetchRecords implements Runnable {
     }
 
     private void setupInitializeErrorException(ForegroundTask task, int max) {
-        String time = TimeUtils.printDuration(task.elapsed());
+        String time = TimeUtils.printDuration(task.elapsed(), true);
         String topic = getPrintableTopic();
         String msg = "Gave up subscribing org.apache.kafka.clients.consumer.KafkaConsumer " +
                      threadId + " to " + topic + " after " + max + " attempts (elapsed: " + time + ").";
@@ -176,7 +176,7 @@ public class KafkaFetchRecords implements Runnable {
     }
 
     private void setupCreateConsumerException(ForegroundTask task, int max) {
-        String time = TimeUtils.printDuration(task.elapsed());
+        String time = TimeUtils.printDuration(task.elapsed(), true);
         String topic = getPrintableTopic();
         String msg = "Gave up creating org.apache.kafka.clients.consumer.KafkaConsumer "
                      + threadId + " to " + topic + " after " + max + " attempts (elapsed: " + time + ").";
diff --git a/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/TaskHealthState.java b/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/TaskHealthState.java
index b68033d6b15..1ce9a130d6e 100644
--- a/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/TaskHealthState.java
+++ b/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/TaskHealthState.java
@@ -89,7 +89,7 @@ public class TaskHealthState {
         if (isTerminated()) {
             msg += " (gave up recovering and terminated the kafka consumer; restart route or application to recover).";
         } else if (isRecoverable()) {
-            String time = TimeUtils.printDuration(getCurrentBackoffInterval());
+            String time = TimeUtils.printDuration(getCurrentBackoffInterval(), true);
             msg += " (recovery in progress using " + time + " intervals).";
         }
 
diff --git a/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/XPathSplitChoicePerformanceTest.java b/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/XPathSplitChoicePerformanceTest.java
index 98fbb607167..1278392c848 100644
--- a/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/XPathSplitChoicePerformanceTest.java
+++ b/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/XPathSplitChoicePerformanceTest.java
@@ -64,7 +64,7 @@ public class XPathSplitChoicePerformanceTest extends CamelTestSupport {
         NotifyBuilder notify = new NotifyBuilder(context).whenDone(size).create();
 
         boolean matches = notify.matches(60, TimeUnit.SECONDS);
-        LOG.info("Processed file with " + size + " elements in: " + TimeUtils.printDuration(watch.taken()));
+        LOG.info("Processed file with " + size + " elements in: " + TimeUtils.printDuration(watch.taken(), true));
 
         LOG.info("Processed " + tiny.get() + " tiny messages");
         LOG.info("Processed " + small.get() + " small messages");
diff --git a/components/camel-stax/src/test/java/org/apache/camel/component/stax/StAXXPathSplitChoicePerformanceManualTest.java b/components/camel-stax/src/test/java/org/apache/camel/component/stax/StAXXPathSplitChoicePerformanceManualTest.java
index d968f3117b7..bfaede92b9f 100644
--- a/components/camel-stax/src/test/java/org/apache/camel/component/stax/StAXXPathSplitChoicePerformanceManualTest.java
+++ b/components/camel-stax/src/test/java/org/apache/camel/component/stax/StAXXPathSplitChoicePerformanceManualTest.java
@@ -67,7 +67,7 @@ public class StAXXPathSplitChoicePerformanceManualTest extends CamelTestSupport
         NotifyBuilder notify = new NotifyBuilder(context).whenDone(size).create();
 
         boolean matches = notify.matches(60, TimeUnit.SECONDS);
-        log.info("Processed file with " + size + " elements in: " + TimeUtils.printDuration(watch.taken()));
+        log.info("Processed file with " + size + " elements in: " + TimeUtils.printDuration(watch.taken(), true));
 
         log.info("Processed " + tiny.get() + " tiny messages");
         log.info("Processed " + small.get() + " small messages");
diff --git a/components/camel-test/camel-test-junit5/src/main/java/org/apache/camel/test/junit5/CamelTestSupport.java b/components/camel-test/camel-test-junit5/src/main/java/org/apache/camel/test/junit5/CamelTestSupport.java
index 536dbade208..e97c321a4c4 100644
--- a/components/camel-test/camel-test-junit5/src/main/java/org/apache/camel/test/junit5/CamelTestSupport.java
+++ b/components/camel-test/camel-test-junit5/src/main/java/org/apache/camel/test/junit5/CamelTestSupport.java
@@ -571,7 +571,7 @@ public abstract class CamelTestSupport
 
         LOG.info("********************************************************************************");
         LOG.info("Testing done: {} ({})", currentTestName, getClass().getName());
-        LOG.info("Took: {} ({} millis)", TimeUtils.printDuration(time), time);
+        LOG.info("Took: {} ({} millis)", TimeUtils.printDuration(time, true), time);
 
         // if we should dump route stats, then write that to a file
         if (isRouteCoverageEnabled()) {
diff --git a/components/camel-test/camel-test-main-junit5/src/main/java/org/apache/camel/test/main/junit5/CamelMainExtension.java b/components/camel-test/camel-test-main-junit5/src/main/java/org/apache/camel/test/main/junit5/CamelMainExtension.java
index dfe036ce223..23366f55e14 100644
--- a/components/camel-test/camel-test-main-junit5/src/main/java/org/apache/camel/test/main/junit5/CamelMainExtension.java
+++ b/components/camel-test/camel-test-main-junit5/src/main/java/org/apache/camel/test/main/junit5/CamelMainExtension.java
@@ -97,7 +97,7 @@ final class CamelMainExtension
             final Class<?> requiredTestClass = context.getRequiredTestClass();
             LOG.info("********************************************************************************");
             LOG.info("Testing done: {} ({})", currentTestName, requiredTestClass.getName());
-            LOG.info("Took: {} ({} millis)", TimeUtils.printDuration(time), time);
+            LOG.info("Took: {} ({} millis)", TimeUtils.printDuration(time, true), time);
             LOG.info("********************************************************************************");
         }
         dumpRouteCoverageIfNeeded(context, time, currentTestName);
diff --git a/components/camel-test/camel-test-spring-junit5/src/main/java/org/apache/camel/test/spring/junit5/StopWatchTestExecutionListener.java b/components/camel-test/camel-test-spring-junit5/src/main/java/org/apache/camel/test/spring/junit5/StopWatchTestExecutionListener.java
index f83a5565c06..bd8b41f852d 100644
--- a/components/camel-test/camel-test-spring-junit5/src/main/java/org/apache/camel/test/spring/junit5/StopWatchTestExecutionListener.java
+++ b/components/camel-test/camel-test-spring-junit5/src/main/java/org/apache/camel/test/spring/junit5/StopWatchTestExecutionListener.java
@@ -63,7 +63,7 @@ public class StopWatchTestExecutionListener extends AbstractTestExecutionListene
 
             log.info("********************************************************************************");
             log.info("Testing done: {} ({})", testContext.getTestMethod().getName(), testContext.getTestClass().getName());
-            log.info("Took: {} ({} millis)", TimeUtils.printDuration(time), time);
+            log.info("Took: {} ({} millis)", TimeUtils.printDuration(time, true), time);
             log.info("********************************************************************************");
 
             threadStopWatch.remove();
diff --git a/components/camel-test/camel-test-spring/src/main/java/org/apache/camel/test/spring/StopWatchTestExecutionListener.java b/components/camel-test/camel-test-spring/src/main/java/org/apache/camel/test/spring/StopWatchTestExecutionListener.java
index 8b520832b06..27e115d0242 100644
--- a/components/camel-test/camel-test-spring/src/main/java/org/apache/camel/test/spring/StopWatchTestExecutionListener.java
+++ b/components/camel-test/camel-test-spring/src/main/java/org/apache/camel/test/spring/StopWatchTestExecutionListener.java
@@ -54,7 +54,7 @@ public class StopWatchTestExecutionListener extends AbstractTestExecutionListene
 
             log.info("********************************************************************************");
             log.info("Testing done: {} ({})", testContext.getTestMethod().getName(), testContext.getTestClass().getName());
-            log.info("Took: {} ({} millis)", TimeUtils.printDuration(time), time);
+            log.info("Took: {} ({} millis)", TimeUtils.printDuration(time, true), time);
             log.info("********************************************************************************");
 
             threadStopWatch.remove();
diff --git a/components/camel-test/camel-test/src/main/java/org/apache/camel/test/junit4/CamelTestSupport.java b/components/camel-test/camel-test/src/main/java/org/apache/camel/test/junit4/CamelTestSupport.java
index e9dbd8b986e..aba28f00486 100644
--- a/components/camel-test/camel-test/src/main/java/org/apache/camel/test/junit4/CamelTestSupport.java
+++ b/components/camel-test/camel-test/src/main/java/org/apache/camel/test/junit4/CamelTestSupport.java
@@ -497,7 +497,7 @@ public abstract class CamelTestSupport extends TestSupport {
 
         LOG.info("********************************************************************************");
         LOG.info("Testing done: {} ({})", getTestMethodName(), getClass().getName());
-        LOG.info("Took: {} ({} millis)", TimeUtils.printDuration(time), time);
+        LOG.info("Took: {} ({} millis)", TimeUtils.printDuration(time, true), time);
 
         // if we should dump route stats, then write that to a file
         if (isRouteCoverageEnabled()) {
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index 6a82ec38327..47976b7f312 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -2572,7 +2572,7 @@ public abstract class AbstractCamelContext extends BaseService
         watch.taken();
         if (LOG.isInfoEnabled()) {
             LOG.info("Apache Camel {} ({}) is suspended in {}", getVersion(), getName(),
-                    TimeUtils.printDuration(watch.taken()));
+                    TimeUtils.printDuration(watch.taken(), true));
         }
 
         EventHelper.notifyCamelContextSuspended(this);
@@ -2605,7 +2605,7 @@ public abstract class AbstractCamelContext extends BaseService
 
             if (LOG.isInfoEnabled()) {
                 LOG.info("Resumed {} routes", suspendedRouteServices.size());
-                LOG.info("Apache Camel {} ({}) resumed in {}", getVersion(), getName(), TimeUtils.printDuration(watch.taken()));
+                LOG.info("Apache Camel {} ({}) resumed in {}", getVersion(), getName(), TimeUtils.printDuration(watch.taken(), true));
             }
 
             // and clear the list as they have been resumed
@@ -2773,7 +2773,7 @@ public abstract class AbstractCamelContext extends BaseService
         startupStepRecorder.endStep(step);
 
         buildTaken = watch.taken();
-        LOG.debug("Apache Camel {} ({}) built in {}", getVersion(), getName(), TimeUtils.printDuration(buildTaken));
+        LOG.debug("Apache Camel {} ({}) built in {}", getVersion(), getName(), TimeUtils.printDuration(buildTaken, true));
     }
 
     protected void resetBuildTime() {
@@ -2972,7 +2972,7 @@ public abstract class AbstractCamelContext extends BaseService
         startupStepRecorder.endStep(step);
 
         initTaken = watch.taken();
-        LOG.debug("Apache Camel {} ({}) initialized in {}", getVersion(), getName(), TimeUtils.printDuration(initTaken));
+        LOG.debug("Apache Camel {} ({}) initialized in {}", getVersion(), getName(), TimeUtils.printDuration(initTaken, true));
     }
 
     @Override
@@ -3180,10 +3180,10 @@ public abstract class AbstractCamelContext extends BaseService
         if (startupSummaryLevel != StartupSummaryLevel.Off && LOG.isInfoEnabled()) {
             long taken = stopWatch.taken();
             long max = buildTaken + initTaken + taken;
-            String total = TimeUtils.printDuration(max);
-            String start = TimeUtils.printDuration(taken);
-            String init = TimeUtils.printDuration(initTaken);
-            String built = TimeUtils.printDuration(buildTaken);
+            String total = TimeUtils.printDuration(max, true);
+            String start = TimeUtils.printDuration(taken, true);
+            String init = TimeUtils.printDuration(initTaken, true);
+            String built = TimeUtils.printDuration(buildTaken, true);
             String jvm = logJvmUptime ? getJvmUptime() : null;
             if (jvm != null) {
                 LOG.info("Apache Camel {} ({}) started in {} (build:{} init:{} start:{} JVM-uptime:{})", getVersion(),
@@ -3381,7 +3381,7 @@ public abstract class AbstractCamelContext extends BaseService
         if (startupSummaryLevel != StartupSummaryLevel.Oneline && startupSummaryLevel != StartupSummaryLevel.Off) {
             if (shutdownStrategy != null && shutdownStrategy.getTimeUnit() != null) {
                 long timeout = shutdownStrategy.getTimeUnit().toMillis(shutdownStrategy.getTimeout());
-                String to = TimeUtils.printDuration(timeout);
+                String to = TimeUtils.printDuration(timeout, true);
                 LOG.info("Apache Camel {} ({}) shutting down (timeout:{})", getVersion(), getName(), to);
             } else {
                 LOG.info("Apache Camel {} ({}) shutting down", getVersion(), getName());
@@ -3515,7 +3515,7 @@ public abstract class AbstractCamelContext extends BaseService
 
         if (startupSummaryLevel != StartupSummaryLevel.Off) {
             if (LOG.isInfoEnabled()) {
-                String taken = TimeUtils.printDuration(stopWatch.taken());
+                String taken = TimeUtils.printDuration(stopWatch.taken(), true);
                 String jvm = logJvmUptime ? getJvmUptime() : null;
                 if (jvm != null) {
                     LOG.info("Apache Camel {} ({}) shutdown in {} (uptime:{} JVM-uptime:{})", getVersion(), getName(), taken,
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/BaseExecutorServiceManager.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/BaseExecutorServiceManager.java
index d9186a87da4..aaab70c6c52 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/BaseExecutorServiceManager.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/BaseExecutorServiceManager.java
@@ -338,11 +338,11 @@ public class BaseExecutorServiceManager extends ServiceSupport implements Execut
             if (warned) {
                 LOG.info("Shutdown of ExecutorService: {} is shutdown: {} and terminated: {} took: {}.",
                         executorService, executorService.isShutdown(), executorService.isTerminated(),
-                        TimeUtils.printDuration(watch.taken()));
+                        TimeUtils.printDuration(watch.taken(), true));
             } else if (LOG.isDebugEnabled()) {
                 LOG.debug("Shutdown of ExecutorService: {} is shutdown: {} and terminated: {} took: {}.",
                         executorService, executorService.isShutdown(), executorService.isTerminated(),
-                        TimeUtils.printDuration(watch.taken()));
+                        TimeUtils.printDuration(watch.taken(), true));
             }
         }
 
@@ -422,7 +422,7 @@ public class BaseExecutorServiceManager extends ServiceSupport implements Execut
             if (executorService.awaitTermination(interval, TimeUnit.MILLISECONDS)) {
                 done = true;
             } else {
-                LOG.info("Waited {} for ExecutorService: {} to terminate...", TimeUtils.printDuration(watch.taken()),
+                LOG.info("Waited {} for ExecutorService: {} to terminate...", TimeUtils.printDuration(watch.taken(), true),
                         executorService);
                 // recalculate interval
                 interval = Math.min(2000, shutdownAwaitTermination - watch.taken());
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultShutdownStrategy.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultShutdownStrategy.java
index 0c595bc0516..1f5c7438d7e 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultShutdownStrategy.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultShutdownStrategy.java
@@ -276,7 +276,7 @@ public class DefaultShutdownStrategy extends ServiceSupport implements ShutdownS
 
         if (logger.shouldLog()) {
             logger.log(String.format("Graceful shutdown of %s routes completed in %s", routesOrdered.size(),
-                    TimeUtils.printDuration(watch.taken())));
+                    TimeUtils.printDuration(watch.taken(), true)));
         }
         return true;
     }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java b/core/camel-base/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java
index c8a55df17fe..22c61d7ceef 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java
@@ -66,7 +66,7 @@ public class DefaultTypeConverter extends BaseTypeConverterRegistry implements A
         // core type converters is always loaded which does not use any classpath scanning and therefore is fast
         loadCoreAndFastTypeConverters();
 
-        String time = TimeUtils.printDuration(watch.taken());
+        String time = TimeUtils.printDuration(watch.taken(), true);
         LOG.debug("Loaded {} type converters in {}", typeMappings.size(), time);
 
         if (!loadTypeConvertersDone && isLoadTypeConverters()) {
@@ -114,7 +114,7 @@ public class DefaultTypeConverter extends BaseTypeConverterRegistry implements A
             }
         }
 
-        String time = TimeUtils.printDuration(watch.taken());
+        String time = TimeUtils.printDuration(watch.taken(), true);
         LOG.debug("Scanned {} type converters in {}", typeMappings.size(), time);
     }
 
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/event/ExchangeSentEvent.java b/core/camel-base/src/main/java/org/apache/camel/impl/event/ExchangeSentEvent.java
index 546d7a12de5..e737b87697f 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/event/ExchangeSentEvent.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/event/ExchangeSentEvent.java
@@ -56,7 +56,7 @@ public class ExchangeSentEvent extends AbstractExchangeEvent implements CamelEve
     @Override
     public String toString() {
         return getExchange().getExchangeId() + " exchange sent to: " + endpoint
-               + " took: " + TimeUtils.printDuration(timeTaken);
+               + " took: " + TimeUtils.printDuration(timeTaken, true);
     }
 
 }
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 8ff177aa693..4519ae69d57 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
@@ -44,9 +44,9 @@ public class ContextDevConsole extends AbstractDevConsole {
             sb.append(String.format("\n    Total: %s", mb.getExchangesTotal()));
             sb.append(String.format("\n    Failed: %s", mb.getExchangesFailed()));
             sb.append(String.format("\n    Inflight: %s", mb.getExchangesInflight()));
-            sb.append(String.format("\n    Mean Time: %s", TimeUtils.printDuration(mb.getMeanProcessingTime())));
-            sb.append(String.format("\n    Max Time: %s", TimeUtils.printDuration(mb.getMaxProcessingTime())));
-            sb.append(String.format("\n    Min Time: %s", TimeUtils.printDuration(mb.getMinProcessingTime())));
+            sb.append(String.format("\n    Mean Time: %s", TimeUtils.printDuration(mb.getMeanProcessingTime(), true)));
+            sb.append(String.format("\n    Max Time: %s", TimeUtils.printDuration(mb.getMaxProcessingTime(), true)));
+            sb.append(String.format("\n    Min Time: %s", TimeUtils.printDuration(mb.getMinProcessingTime(), true)));
             sb.append("\n");
         }
 
diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/DefaultDevConsoleRegistry.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/DefaultDevConsoleRegistry.java
index 7089201cff1..d5e3f1af968 100644
--- a/core/camel-console/src/main/java/org/apache/camel/impl/console/DefaultDevConsoleRegistry.java
+++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/DefaultDevConsoleRegistry.java
@@ -177,7 +177,7 @@ public class DefaultDevConsoleRegistry extends ServiceSupport implements DevCons
                 for (DevConsole console : col) {
                     register(console);
                 }
-                String time = TimeUtils.printDuration(watch.taken());
+                String time = TimeUtils.printDuration(watch.taken(), true);
                 LOG.info("Dev consoles (scanned: {}) loaded in {}", col.size(), time);
             }
         }
diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/EventConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/EventConsole.java
index ebb01ef6116..18a6a53e3f6 100644
--- a/core/camel-console/src/main/java/org/apache/camel/impl/console/EventConsole.java
+++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/EventConsole.java
@@ -27,6 +27,7 @@ import org.apache.camel.spi.Configurer;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.annotations.DevConsole;
 import org.apache.camel.support.EventNotifierSupport;
+import org.apache.camel.util.TimeUtils;
 import org.apache.camel.util.json.JsonObject;
 
 @DevConsole("event")
@@ -75,7 +76,11 @@ public class EventConsole extends AbstractDevConsole {
         if (!events.isEmpty()) {
             sb.append(String.format("Last %s Camel Events:", events.size()));
             for (CamelEvent event : events) {
-                sb.append(String.format("\n    %s", event));
+                if (event.getTimestamp() > 0) {
+                    sb.append(String.format("\n    %s (age: %s)", event, TimeUtils.printSince(event.getTimestamp())));
+                } else {
+                    sb.append(String.format("\n    %s", event));
+                }
             }
             sb.append("\n");
         }
@@ -83,7 +88,11 @@ public class EventConsole extends AbstractDevConsole {
             sb.append("\n");
             sb.append(String.format("Last %s Exchange Events:", exchangeEvents.size()));
             for (CamelEvent.ExchangeEvent event : exchangeEvents) {
-                sb.append(String.format("\n    %s", event));
+                if (event.getTimestamp() > 0) {
+                    sb.append(String.format("\n    %s (age: %s)", event, TimeUtils.printSince(event.getTimestamp())));
+                } else {
+                    sb.append(String.format("\n    %s", event));
+                }
             }
             sb.append("\n");
         }
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 2bad41f3c15..bfe154d7100 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
@@ -65,9 +65,9 @@ public class RouteDevConsole extends AbstractDevConsole {
             sb.append(String.format("\n    Total: %s", mrb.getExchangesTotal()));
             sb.append(String.format("\n    Failed: %s", mrb.getExchangesFailed()));
             sb.append(String.format("\n    Inflight: %s", mrb.getExchangesInflight()));
-            sb.append(String.format("\n    Mean Time: %s", TimeUtils.printDuration(mrb.getMeanProcessingTime())));
-            sb.append(String.format("\n    Max Time: %s", TimeUtils.printDuration(mrb.getMaxProcessingTime())));
-            sb.append(String.format("\n    Min Time: %s", TimeUtils.printDuration(mrb.getMinProcessingTime())));
+            sb.append(String.format("\n    Mean Time: %s", TimeUtils.printDuration(mrb.getMeanProcessingTime(), true)));
+            sb.append(String.format("\n    Max Time: %s", TimeUtils.printDuration(mrb.getMaxProcessingTime(), true)));
+            sb.append(String.format("\n    Min Time: %s", TimeUtils.printDuration(mrb.getMinProcessingTime(), true)));
             sb.append("\n");
             return null;
         };
diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/TopDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/TopDevConsole.java
index 390898c70f6..52eb671818d 100644
--- a/core/camel-console/src/main/java/org/apache/camel/impl/console/TopDevConsole.java
+++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/TopDevConsole.java
@@ -81,11 +81,11 @@ public class TopDevConsole extends AbstractDevConsole {
                     sb.append(String.format("\n    Total: %s", mrb.getExchangesTotal()));
                     sb.append(String.format("\n    Failed: %s", mrb.getExchangesFailed()));
                     sb.append(String.format("\n    Inflight: %s", mrb.getExchangesInflight()));
-                    sb.append(String.format("\n    Mean Time: %s", TimeUtils.printDuration(mrb.getMeanProcessingTime())));
-                    sb.append(String.format("\n    Max Time: %s", TimeUtils.printDuration(mrb.getMaxProcessingTime())));
-                    sb.append(String.format("\n    Min Time: %s", TimeUtils.printDuration(mrb.getMinProcessingTime())));
-                    sb.append(String.format("\n    Delta Time: %s", TimeUtils.printDuration(mrb.getDeltaProcessingTime())));
-                    sb.append(String.format("\n    Total Time: %s", TimeUtils.printDuration(mrb.getTotalProcessingTime())));
+                    sb.append(String.format("\n    Mean Time: %s", TimeUtils.printDuration(mrb.getMeanProcessingTime(), true)));
+                    sb.append(String.format("\n    Max Time: %s", TimeUtils.printDuration(mrb.getMaxProcessingTime(), true)));
+                    sb.append(String.format("\n    Min Time: %s", TimeUtils.printDuration(mrb.getMinProcessingTime(), true)));
+                    sb.append(String.format("\n    Delta Time: %s", TimeUtils.printDuration(mrb.getDeltaProcessingTime(), true)));
+                    sb.append(String.format("\n    Total Time: %s", TimeUtils.printDuration(mrb.getTotalProcessingTime(), true)));
                     sb.append("\n");
                     return null;
                 };
@@ -134,11 +134,11 @@ public class TopDevConsole extends AbstractDevConsole {
                     sb.append(String.format("\n    Total: %s", mpb.getExchangesTotal()));
                     sb.append(String.format("\n    Failed: %s", mpb.getExchangesFailed()));
                     sb.append(String.format("\n    Inflight: %s", mpb.getExchangesInflight()));
-                    sb.append(String.format("\n    Mean Time: %s", TimeUtils.printDuration(mpb.getMeanProcessingTime())));
-                    sb.append(String.format("\n    Max Time: %s", TimeUtils.printDuration(mpb.getMaxProcessingTime())));
-                    sb.append(String.format("\n    Min Time: %s", TimeUtils.printDuration(mpb.getMinProcessingTime())));
-                    sb.append(String.format("\n    Delta Time: %s", TimeUtils.printDuration(mpb.getDeltaProcessingTime())));
-                    sb.append(String.format("\n    Total Time: %s", TimeUtils.printDuration(mpb.getTotalProcessingTime())));
+                    sb.append(String.format("\n    Mean Time: %s", TimeUtils.printDuration(mpb.getMeanProcessingTime(), true)));
+                    sb.append(String.format("\n    Max Time: %s", TimeUtils.printDuration(mpb.getMaxProcessingTime(), true)));
+                    sb.append(String.format("\n    Min Time: %s", TimeUtils.printDuration(mpb.getMinProcessingTime(), true)));
+                    sb.append(String.format("\n    Delta Time: %s", TimeUtils.printDuration(mpb.getDeltaProcessingTime(), true)));
+                    sb.append(String.format("\n    Total Time: %s", TimeUtils.printDuration(mpb.getTotalProcessingTime(), true)));
                     sb.append("\n");
                     return null;
                 };
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
index 86d326fc684..cdfa5250766 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
@@ -362,7 +362,7 @@ public class LightweightRuntimeCamelContext implements ExtendedCamelContext, Cat
         if (LOG.isInfoEnabled()) {
             long l = System.currentTimeMillis() - startDate.getTime();
             LOG.info("Apache Camel {} ({}) {} routes started in {}",
-                    getVersion(), getName(), routes.size(), TimeUtils.printDuration(l));
+                    getVersion(), getName(), routes.size(), TimeUtils.printDuration(l, true));
         }
     }
 
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/AggregateProcessor.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/AggregateProcessor.java
index 8b971bd0c77..83f5fd9512d 100644
--- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/AggregateProcessor.java
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/AggregateProcessor.java
@@ -928,7 +928,7 @@ public class AggregateProcessor extends AsyncProcessorSupport
 
         // log duration of this task so end user can see how long it takes to pre-check this upon starting
         LOG.info("Restored {} CompletionTimeout conditions in the AggregationTimeoutChecker in {}",
-                timeoutMap.size(), TimeUtils.printDuration(watch.taken()));
+                timeoutMap.size(), TimeUtils.printDuration(watch.taken(), true));
     }
 
     /**
@@ -1706,7 +1706,7 @@ public class AggregateProcessor extends AsyncProcessorSupport
 
         if (expected > 0) {
             LOG.info("Forcing completion of all groups with {} exchanges completed in {}", expected,
-                    TimeUtils.printDuration(watch.taken()));
+                    TimeUtils.printDuration(watch.taken(), true));
         }
     }
 
diff --git a/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanPerformanceTest.java b/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanPerformanceTest.java
index 489ecaba89a..0637cbb5560 100644
--- a/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanPerformanceTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanPerformanceTest.java
@@ -47,7 +47,7 @@ public class BeanPerformanceTest extends ContextTestSupport {
         for (int i = 0; i < times; i++) {
             template.sendBody("direct:start", "Hello World");
         }
-        log.info("Took {} to invoke the bean {} times", TimeUtils.printDuration(watch.taken()), times);
+        log.info("Took {} to invoke the bean {} times", TimeUtils.printDuration(watch.taken(), true), times);
 
         assertEquals(times, INVOKED.get());
     }
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/ClassicUuidGeneratorTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/ClassicUuidGeneratorTest.java
index 4349ebe265c..f3058a3fc93 100644
--- a/core/camel-core/src/test/java/org/apache/camel/impl/ClassicUuidGeneratorTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/ClassicUuidGeneratorTest.java
@@ -52,7 +52,7 @@ public class ClassicUuidGeneratorTest {
         }
         LOG.info("Last id:  " + uuidGenerator.generateUuid());
 
-        LOG.info("Took " + TimeUtils.printDuration(watch.taken()));
+        LOG.info("Took " + TimeUtils.printDuration(watch.taken(), true));
     }
 
     @Test
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultUuidGeneratorTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultUuidGeneratorTest.java
index f654398bcd5..7dfd44ebb74 100644
--- a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultUuidGeneratorTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultUuidGeneratorTest.java
@@ -50,7 +50,7 @@ public class DefaultUuidGeneratorTest {
         }
         LOG.info("Last id:  " + uuidGenerator.generateUuid());
 
-        LOG.info("Took " + TimeUtils.printDuration(watch.taken()));
+        LOG.info("Took " + TimeUtils.printDuration(watch.taken(), true));
     }
 
 }
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/ShortUuidGeneratorTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/ShortUuidGeneratorTest.java
index 63ed7b0f91c..16db1a46459 100644
--- a/core/camel-core/src/test/java/org/apache/camel/impl/ShortUuidGeneratorTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/ShortUuidGeneratorTest.java
@@ -50,7 +50,7 @@ public class ShortUuidGeneratorTest {
         }
         LOG.info("Last id:  " + uuidGenerator.generateUuid());
 
-        LOG.info("Took " + TimeUtils.printDuration(watch.taken()));
+        LOG.info("Took " + TimeUtils.printDuration(watch.taken(), true));
     }
 
 }
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/SimpleUuidGeneratorTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/SimpleUuidGeneratorTest.java
index a61b9f76b74..57ad53376c0 100644
--- a/core/camel-core/src/test/java/org/apache/camel/impl/SimpleUuidGeneratorTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/SimpleUuidGeneratorTest.java
@@ -48,7 +48,7 @@ public class SimpleUuidGeneratorTest {
         }
         LOG.info("Last id:  " + uuidGenerator.generateUuid());
 
-        LOG.info("Took " + TimeUtils.printDuration(watch.taken()));
+        LOG.info("Took " + TimeUtils.printDuration(watch.taken(), true));
     }
 
 }
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/VanillaUuidGeneratorTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/VanillaUuidGeneratorTest.java
index 9ce3df73db4..5eef32ca438 100644
--- a/core/camel-core/src/test/java/org/apache/camel/impl/VanillaUuidGeneratorTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/VanillaUuidGeneratorTest.java
@@ -50,7 +50,7 @@ public class VanillaUuidGeneratorTest {
         }
         LOG.info("Last id:  " + uuidGenerator.generateUuid());
 
-        LOG.info("Took " + TimeUtils.printDuration(watch.taken()));
+        LOG.info("Took " + TimeUtils.printDuration(watch.taken(), true));
     }
 
 }
diff --git a/core/camel-core/src/test/java/org/apache/camel/language/TokenPairIteratorSplitChoicePerformanceManualTest.java b/core/camel-core/src/test/java/org/apache/camel/language/TokenPairIteratorSplitChoicePerformanceManualTest.java
index 064b0efa33e..99070007c7a 100644
--- a/core/camel-core/src/test/java/org/apache/camel/language/TokenPairIteratorSplitChoicePerformanceManualTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/language/TokenPairIteratorSplitChoicePerformanceManualTest.java
@@ -61,7 +61,7 @@ public class TokenPairIteratorSplitChoicePerformanceManualTest extends ContextTe
         NotifyBuilder notify = new NotifyBuilder(context).whenDone(size).create();
 
         boolean matches = notify.matches(5, TimeUnit.MINUTES);
-        log.info("Processed file with {} elements in: {}", size, TimeUtils.printDuration(watch.taken()));
+        log.info("Processed file with {} elements in: {}", size, TimeUtils.printDuration(watch.taken(), true));
 
         log.info("Processed " + tiny.get() + " tiny messages");
         log.info("Processed " + small.get() + " small messages");
diff --git a/core/camel-core/src/test/java/org/apache/camel/language/XPathSplitChoicePerformanceManualTest.java b/core/camel-core/src/test/java/org/apache/camel/language/XPathSplitChoicePerformanceManualTest.java
index 5a4c10a325e..6202b7f9529 100644
--- a/core/camel-core/src/test/java/org/apache/camel/language/XPathSplitChoicePerformanceManualTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/language/XPathSplitChoicePerformanceManualTest.java
@@ -61,7 +61,7 @@ public class XPathSplitChoicePerformanceManualTest extends ContextTestSupport {
         NotifyBuilder notify = new NotifyBuilder(context).whenDone(size).create();
 
         boolean matches = notify.matches(60, TimeUnit.SECONDS);
-        log.info("Processed file with {} elements in: {}", size, TimeUtils.printDuration(watch.taken()));
+        log.info("Processed file with {} elements in: {}", size, TimeUtils.printDuration(watch.taken(), true));
 
         log.info("Processed " + tiny.get() + " tiny messages");
         log.info("Processed " + small.get() + " small messages");
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/SplitterParallelBigFileManualTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/SplitterParallelBigFileManualTest.java
index 8a6b014ca97..652fef2af40 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/SplitterParallelBigFileManualTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/SplitterParallelBigFileManualTest.java
@@ -51,7 +51,7 @@ public class SplitterParallelBigFileManualTest extends ContextTestSupport {
         NotifyBuilder builder = new NotifyBuilder(context).whenDone(lines + 1).create();
         boolean done = builder.matches(120, TimeUnit.SECONDS);
 
-        log.info("Took " + TimeUtils.printDuration(watch.taken()));
+        log.info("Took " + TimeUtils.printDuration(watch.taken(), true));
 
         if (!done) {
             throw new CamelException("Could not split file in 2 minutes");
diff --git a/core/camel-health/src/main/java/org/apache/camel/impl/health/DefaultHealthCheckRegistry.java b/core/camel-health/src/main/java/org/apache/camel/impl/health/DefaultHealthCheckRegistry.java
index 2ff86e951cf..3ad0eaefbb9 100644
--- a/core/camel-health/src/main/java/org/apache/camel/impl/health/DefaultHealthCheckRegistry.java
+++ b/core/camel-health/src/main/java/org/apache/camel/impl/health/DefaultHealthCheckRegistry.java
@@ -302,7 +302,7 @@ public class DefaultHealthCheckRegistry extends ServiceSupport implements Health
             // register loaded health-checks
             col.forEach(this::register);
             if (col.size() > 0) {
-                String time = TimeUtils.printDuration(watch.taken());
+                String time = TimeUtils.printDuration(watch.taken(), true);
                 LOG.info("Health checks (scanned: {}) loaded in {}", col.size(), time);
             }
         }
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultMainShutdownStrategy.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultMainShutdownStrategy.java
index 632511a03d7..38ffc68e609 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultMainShutdownStrategy.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultMainShutdownStrategy.java
@@ -98,7 +98,7 @@ public class DefaultMainShutdownStrategy extends SimpleMainShutdownStrategy {
                 StopWatch watch = new StopWatch();
                 while (!main.getCamelContext().isStopped() && !done && watch.taken() < max) {
                     String msg = "Waiting for CamelContext to graceful shutdown (max:"
-                                 + TimeUtils.printDuration(max) + ", elapsed:" + TimeUtils.printDuration(watch.taken()) + ")";
+                                 + TimeUtils.printDuration(max, true) + ", elapsed:" + TimeUtils.printDuration(watch.taken(), true) + ")";
                     if (waits > 0 && waits % 5 == 0) {
                         // do some info logging every 5th time
                         LOG.info(msg);
@@ -116,7 +116,7 @@ public class DefaultMainShutdownStrategy extends SimpleMainShutdownStrategy {
                 boolean success = done || main.getCamelContext().isStopped();
                 if (!success) {
                     LOG.warn("CamelContext not yet shutdown completely after: {}. Forcing shutdown.",
-                            TimeUtils.printDuration(watch.taken()));
+                            TimeUtils.printDuration(watch.taken(), true));
                 }
                 tracker.close();
             }
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/EagerClassloadedHelper.java b/core/camel-main/src/main/java/org/apache/camel/main/EagerClassloadedHelper.java
index a67e340b405..1b48193f915 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/EagerClassloadedHelper.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/EagerClassloadedHelper.java
@@ -51,7 +51,7 @@ public final class EagerClassloadedHelper {
         org.apache.camel.support.UnitOfWorkHelper.onClassloaded(LOG);
         // EAGER-CLASSLOADED: END
 
-        String time = TimeUtils.printDuration(watch.taken());
+        String time = TimeUtils.printDuration(watch.taken(), true);
         LOG.debug("Eager loaded {} classes in {}", count, time);
     }
 }
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/RoutesConfigurer.java b/core/camel-main/src/main/java/org/apache/camel/main/RoutesConfigurer.java
index 430dbabb23b..84ba9a9471f 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/RoutesConfigurer.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/RoutesConfigurer.java
@@ -192,7 +192,7 @@ public class RoutesConfigurer {
 
                 if (LOG.isDebugEnabled() && !routesFromDirectory.isEmpty()) {
                     LOG.debug("Loaded {} additional RoutesBuilder from: {} (took {})", routesFromDirectory.size(),
-                            getRoutesIncludePattern(), TimeUtils.printDuration(watch.taken()));
+                            getRoutesIncludePattern(), TimeUtils.printDuration(watch.taken(), true));
                 }
             } catch (Exception e) {
                 throw RuntimeCamelException.wrapRuntimeException(e);
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedSupervisingRouteController.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedSupervisingRouteController.java
index b914aded0f3..c9cb01fa6ea 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedSupervisingRouteController.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedSupervisingRouteController.java
@@ -192,12 +192,12 @@ public class ManagedSupervisingRouteController extends ManagedService implements
                         ? state.getFirstAttemptTime() : 0;
                 if (time > 0) {
                     long delta = System.currentTimeMillis() - time;
-                    elapsed = TimeUtils.printDuration(delta);
+                    elapsed = TimeUtils.printDuration(delta, true);
                 }
                 time = state != null && BackOffTimer.Task.Status.Active == state.getStatus() ? state.getLastAttemptTime() : 0;
                 if (time > 0) {
                     long delta = System.currentTimeMillis() - time;
-                    last = TimeUtils.printDuration(delta);
+                    last = TimeUtils.printDuration(delta, true);
                 }
                 String error = "";
                 String stacktrace = "";
diff --git a/core/camel-util/src/main/java/org/apache/camel/util/TimeUtils.java b/core/camel-util/src/main/java/org/apache/camel/util/TimeUtils.java
index 13daedc2850..7013c870bc6 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/TimeUtils.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/TimeUtils.java
@@ -35,12 +35,33 @@ public final class TimeUtils {
         return dur.getSeconds() > 0 || dur.getNano() != 0;
     }
 
+    /**
+     * Prints the since ago in a human-readable format as 9s, 27m44s, 3h12m, 3d8h, as seen on Kubernetes etc.
+     *
+     * @param time time of the event (millis since epoch)
+     * @return ago in human-readable since the given time.
+     */
+    public static String printSince(long time) {
+        long age = System.currentTimeMillis() - time;
+        return printDuration(age, false);
+    }
+
+    /**
+     * Prints the ago in a human-readable format as 9s, 27m44s, 3h12m, 3d8h, as seen on Kubernetes etc.
+     *
+     * @param age age in millis
+     * @return ago in human-readable.
+     */
+    public static String printAge(long age) {
+        return printDuration(age, false);
+    }
+
     public static String printDuration(Duration uptime) {
         return printDuration(uptime.toMillis(), true);
     }
 
     /**
-     * Prints the duration in a human readable format as X days Y hours Z minutes etc.
+     * Prints the duration in a human-readable format as 9s, 27m44s, 3h12m, 3d8h, etc.
      *
      * @param  uptime the uptime in millis
      * @return        the time used for displaying on screen or in logs
@@ -50,10 +71,10 @@ public final class TimeUtils {
     }
 
     /**
-     * Prints the duration in a human readable format as X days Y hours Z minutes etc.
+     * Prints the duration in a human-readable format as 9s, 27m44s, 3h12m, 3d8h, etc.
      *
      * @param  uptime  the uptime in millis
-     * @param  precise whether to be precise and include all details including milli seconds
+     * @param  precise whether to be precise and include more details
      * @return         the time used for displaying on screen or in logs
      */
     public static String printDuration(long uptime, boolean precise) {
@@ -75,23 +96,32 @@ public final class TimeUtils {
         }
 
         if (days > 0) {
-            sb.append(days).append("d").append(hours % 24).append("h").append(minutes % 60).append("m").append(seconds % 60)
-                    .append("s");
+            sb.append(days).append("d").append(hours % 24).append("h");
+            if (precise) {
+                sb.append(minutes % 60).append("m").append(seconds % 60).append("s");
+            }
         } else if (hours > 0) {
-            sb.append(hours % 24).append("h").append(minutes % 60).append("m").append(seconds % 60).append("s");
+            sb.append(hours % 24).append("h").append(minutes % 60).append("m");
+            if (precise) {
+                sb.append(seconds % 60).append("s");
+            }
         } else if (minutes > 0) {
             sb.append(minutes % 60).append("m").append(seconds % 60).append("s");
+            if (precise) {
+                sb.append(millis).append("ms");
+            }
         } else if (seconds > 0) {
             sb.append(seconds % 60).append("s");
-            // lets include millis when there are only seconds by default
-            precise = true;
+            if (precise) {
+                sb.append(millis).append("ms");
+            }
         } else if (millis > 0) {
-            precise = false;
-            sb.append(millis).append("ms");
-        }
-
-        if (precise & millis > 0) {
-            sb.append(millis).append("ms");
+            if (!precise) {
+                // less than a second so just report it as zero
+                sb.append("0s");
+            } else {
+                sb.append(millis).append("ms");
+            }
         }
 
         return sb.toString();
@@ -146,7 +176,7 @@ public final class TimeUtils {
             if (source.length() - 1 <= pos) {
                 valid = true;
             } else {
-                // beware of minutes and not milli seconds
+                // beware of minutes and not milliseconds
                 valid = source.charAt(pos + 1) != 's';
             }
             if (valid) {
@@ -157,7 +187,7 @@ public final class TimeUtils {
         }
 
         pos = source.indexOf('s');
-        // beware of seconds and not milli seconds
+        // beware of seconds and not milliseconds
         if (pos != -1 && source.charAt(pos - 1) != 'm') {
             String s = source.substring(0, pos);
             seconds = Long.parseLong(s);
diff --git a/core/camel-util/src/test/java/org/apache/camel/util/TimeUtilsTest.java b/core/camel-util/src/test/java/org/apache/camel/util/TimeUtilsTest.java
index ebd7a8ef475..514239acf00 100644
--- a/core/camel-util/src/test/java/org/apache/camel/util/TimeUtilsTest.java
+++ b/core/camel-util/src/test/java/org/apache/camel/util/TimeUtilsTest.java
@@ -24,26 +24,47 @@ public class TimeUtilsTest {
 
     @Test
     public void testPrintDuration() throws Exception {
-        assertEquals("123ms", TimeUtils.printDuration(123));
-        assertEquals("1s250ms", TimeUtils.printDuration(1250));
+        assertEquals("0s", TimeUtils.printDuration(123));
+        assertEquals("123ms", TimeUtils.printDuration(123, true));
+        assertEquals("1s", TimeUtils.printDuration(1250));
+        assertEquals("1s250ms", TimeUtils.printDuration(1250, true));
         assertEquals("33s", TimeUtils.printDuration(33000));
-        assertEquals("33s1ms", TimeUtils.printDuration(33001));
-        assertEquals("33s444ms", TimeUtils.printDuration(33444));
+        assertEquals("33s", TimeUtils.printDuration(33001));
+        assertEquals("33s1ms", TimeUtils.printDuration(33001, true));
+        assertEquals("33s", TimeUtils.printDuration(33444));
+        assertEquals("33s444ms", TimeUtils.printDuration(33444, true));
         assertEquals("1m0s", TimeUtils.printDuration(60000));
         assertEquals("1m1s", TimeUtils.printDuration(61000));
         assertEquals("1m1s", TimeUtils.printDuration(61002));
         assertEquals("1m1s2ms", TimeUtils.printDuration(61002, true));
         assertEquals("30m55s", TimeUtils.printDuration(1855123));
         assertEquals("30m55s123ms", TimeUtils.printDuration(1855123, true));
-        assertEquals("1h30m0s", TimeUtils.printDuration(5400000));
-        assertEquals("1h30m1s", TimeUtils.printDuration(5401000));
-        assertEquals("2d23h57m12s", TimeUtils.printDuration(259032000));
+        assertEquals("1h30m", TimeUtils.printDuration(5400000));
+        assertEquals("1h30m1s", TimeUtils.printDuration(5401000, true));
+        assertEquals("2d23h", TimeUtils.printDuration(259032000));
+        assertEquals("2d23h57m12s", TimeUtils.printDuration(259032000, true));
+    }
+
+    @Test
+    public void testPrintAge() throws Exception {
+        assertEquals("0s", TimeUtils.printAge(123));
+        assertEquals("1s", TimeUtils.printAge(1250));
+        assertEquals("33s", TimeUtils.printAge(33000));
+        assertEquals("33s", TimeUtils.printAge(33001));
+        assertEquals("33s", TimeUtils.printAge(33444));
+        assertEquals("1m0s", TimeUtils.printAge(60000));
+        assertEquals("1m1s", TimeUtils.printAge(61000));
+        assertEquals("1m1s", TimeUtils.printAge(61002));
+        assertEquals("30m55s", TimeUtils.printAge(1855123));
+        assertEquals("1h30m", TimeUtils.printAge(5400000));
+        assertEquals("1h30m", TimeUtils.printAge(5401000));
+        assertEquals("2d23h", TimeUtils.printAge(259032000));
     }
 
     @Test
     public void testReverse() throws Exception {
         long time = 259032000;
-        long time2 = TimeUtils.toMilliSeconds(TimeUtils.printDuration(time));
+        long time2 = TimeUtils.toMilliSeconds(TimeUtils.printDuration(time, true));
         assertEquals(time, time2);
     }
 }
diff --git a/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_18.adoc b/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_18.adoc
index f8cf3a658aa..5fda331b8b1 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_18.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_18.adoc
@@ -13,6 +13,9 @@ such as from stacktraces. Previously only a sub set of known _secret_ keys was m
 
 The type converter from `InputStream` to `byte[]` will now close the input stream after the conversion.
 
+The `TimeUtils.printDuration` method outputs now in a more compact format (especially for long durations).
+Before `4d12h57m49s` and now `4d12h`. Use `precise=true` to include all details.
+
 === camel-endpointdsl
 
 The options for `lazyStartProducer` and `bridgeErrorHandler` has moved into the _advanced_ group.
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DownloadThreadPool.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DownloadThreadPool.java
index 99fc6f4c165..07dd293c646 100644
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DownloadThreadPool.java
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DownloadThreadPool.java
@@ -73,7 +73,7 @@ class DownloadThreadPool extends ServiceSupport implements CamelContextAware {
         // and then it is not downloaded over the internet
         long taken = watch.taken();
         String msg = "Downloaded:  " + gav + " (took: "
-                     + TimeUtils.printDuration(taken) + ")";
+                     + TimeUtils.printDuration(taken, true) + ")";
         if (taken < 1000) {
             log.debug(msg);
         } else {