This is an automated email from the ASF dual-hosted git repository.
orpiske 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 c20223c9b75 CAMEL-19398: cleanup type statistics (#11456)
c20223c9b75 is described below
commit c20223c9b75861f7f0a3590451a6fdc9d7ed5f1e
Author: Otavio Rodolfo Piske <[email protected]>
AuthorDate: Tue Sep 19 11:59:03 2023 +0200
CAMEL-19398: cleanup type statistics (#11456)
Move the statistics code to separate classes and interfaces
---
.../camel/impl/converter/ConverterStatistics.java | 75 +++++++++++++
.../impl/converter/CoreTypeConverterRegistry.java | 110 +++++--------------
.../impl/converter/TypeConverterStatistics.java | 118 +++++++++++++++++++++
3 files changed, 217 insertions(+), 86 deletions(-)
diff --git
a/core/camel-base/src/main/java/org/apache/camel/impl/converter/ConverterStatistics.java
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/ConverterStatistics.java
new file mode 100644
index 00000000000..8bee3d9199f
--- /dev/null
+++
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/ConverterStatistics.java
@@ -0,0 +1,75 @@
+/*
+ * 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.impl.converter;
+
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.camel.TypeConverter;
+import org.apache.camel.converter.TypeConvertible;
+import org.apache.camel.spi.TypeConverterRegistry;
+
+/**
+ * Converter-specific statistics
+ */
+interface ConverterStatistics extends TypeConverterRegistry.Statistics {
+
+ /**
+ * Increment the count of failed conversions
+ */
+ void incrementFailed();
+
+ /**
+ * Increment the count of noop conversions (i.e.; ones in which a type
conversion was not needed)
+ */
+ void incrementNoop();
+
+ /**
+ * Increment the count of conversions that hit the cache
+ */
+ void incrementHit();
+
+ /**
+ * Increment the count of conversions that missed the cache
+ */
+ void incrementMiss();
+
+ /**
+ * Increment the count of total conversion attempts
+ */
+ void incrementAttempt();
+
+ /**
+ * Compute the total number of cached missed conversions
+ *
+ * @param converters the converters cache instance
+ * @param missConverter the type that represents a type conversion miss
+ * @return The number of cached missed conversions as an
AtomicInteger instance
+ */
+ static AtomicInteger computeCachedMisses(
+ Map<TypeConvertible<?, ?>, TypeConverter> converters,
TypeConverter missConverter) {
+ AtomicInteger misses = new AtomicInteger();
+
+ converters.forEach((k, v) -> {
+ if (v == missConverter) {
+ misses.incrementAndGet();
+ }
+ });
+ return misses;
+ }
+}
diff --git
a/core/camel-base/src/main/java/org/apache/camel/impl/converter/CoreTypeConverterRegistry.java
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/CoreTypeConverterRegistry.java
index 5bc52486d81..30f97d2c67a 100644
---
a/core/camel-base/src/main/java/org/apache/camel/impl/converter/CoreTypeConverterRegistry.java
+++
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/CoreTypeConverterRegistry.java
@@ -22,7 +22,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.LongAdder;
import org.apache.camel.CamelContext;
import org.apache.camel.CamelExecutionException;
@@ -64,12 +63,7 @@ public class CoreTypeConverterRegistry extends
ServiceSupport implements TypeCon
// special enum converter for optional performance
protected final TypeConverter enumTypeConverter = new EnumTypeConverter();
- protected final Statistics statistics = new UtilizationStatistics();
- protected final LongAdder noopCounter = new LongAdder();
- protected final LongAdder attemptCounter = new LongAdder();
- protected final LongAdder missCounter = new LongAdder();
- protected final LongAdder hitCounter = new LongAdder();
- protected final LongAdder failedCounter = new LongAdder();
+ private final ConverterStatistics statistics = new
TypeConverterStatistics();
protected TypeConverterExists typeConverterExists =
TypeConverterExists.Ignore;
protected LoggingLevel typeConverterExistsLoggingLevel =
LoggingLevel.DEBUG;
@@ -292,16 +286,15 @@ public class CoreTypeConverterRegistry extends
ServiceSupport implements TypeCon
final Class<?> type, final Exchange exchange, final Object value,
final boolean tryConvert) {
- boolean statisticsEnabled = !tryConvert &&
statistics.isStatisticsEnabled(); // we only capture if not try-convert in use
-
Object answer = null;
try {
answer = doConvertTo(type, exchange, value, tryConvert);
} catch (Exception e) {
// only record if not try
- if (statisticsEnabled) {
- failedCounter.increment();
+ if (!tryConvert) {
+ statistics.incrementFailed();
}
+
if (tryConvert) {
return null;
}
@@ -309,15 +302,17 @@ public class CoreTypeConverterRegistry extends
ServiceSupport implements TypeCon
wrapConversionException(type, exchange, value, e);
}
if (answer == TypeConverter.MISS_VALUE) {
- // Could not find suitable conversion
- if (statisticsEnabled) {
- missCounter.increment();
+ if (!tryConvert) {
+ // Could not find suitable conversion
+ statistics.incrementMiss();
}
+
return null;
} else {
- if (statisticsEnabled) {
- hitCounter.increment();
+ if (!tryConvert) {
+ statistics.incrementHit();
}
+
return answer;
}
}
@@ -366,13 +361,13 @@ public class CoreTypeConverterRegistry extends
ServiceSupport implements TypeCon
protected Object doConvertTo(
final Class<?> type, final Exchange exchange, final Object value,
final boolean tryConvert) {
- boolean statisticsEnabled = !tryConvert &&
statistics.isStatisticsEnabled(); // we only capture if not try-convert in use
if (value == null) {
// no type conversion was needed
- if (statisticsEnabled) {
- noopCounter.increment();
+ if (!tryConvert) {
+ statistics.incrementNoop();
}
+
// lets avoid NullPointerException when converting to primitives
for null values
if (type.isPrimitive()) {
return nullToPrimitiveType(type);
@@ -383,14 +378,16 @@ public class CoreTypeConverterRegistry extends
ServiceSupport implements TypeCon
// same instance type
if (type.isInstance(value)) {
// no type conversion was needed
- if (statisticsEnabled) {
- noopCounter.increment();
+
+ if (!tryConvert) {
+ statistics.incrementNoop();
}
+
return value;
}
- if (statisticsEnabled) {
- attemptCounter.increment();
+ if (!tryConvert) {
+ statistics.incrementAttempt();
}
// attempt bulk first which is the fastest (also taking into account
primitives)
@@ -628,76 +625,17 @@ public class CoreTypeConverterRegistry extends
ServiceSupport implements TypeCon
super.doStop();
// log utilization statistics when stopping, including mappings
if (statistics.isStatisticsEnabled()) {
- String info = statistics.toString();
- AtomicInteger misses = new AtomicInteger();
- converters.forEach((k, v) -> {
- if (v == MISS_CONVERTER) {
- misses.incrementAndGet();
- }
- });
- info += String.format(" mappings[total=%s, misses=%s]", size(),
misses);
+ final String info = generateMappingStatisticsMessage();
LOG.info(info);
}
statistics.reset();
}
- /**
- * Represents utilization statistics
- */
- private final class UtilizationStatistics implements Statistics {
-
- private boolean statisticsEnabled;
-
- @Override
- public long getNoopCounter() {
- return noopCounter.longValue();
- }
-
- @Override
- public long getAttemptCounter() {
- return attemptCounter.longValue();
- }
-
- @Override
- public long getHitCounter() {
- return hitCounter.longValue();
- }
-
- @Override
- public long getMissCounter() {
- return missCounter.longValue();
- }
+ private String generateMappingStatisticsMessage() {
+ final AtomicInteger misses =
ConverterStatistics.computeCachedMisses(converters, MISS_CONVERTER);
- @Override
- public long getFailedCounter() {
- return failedCounter.longValue();
- }
-
- @Override
- public void reset() {
- noopCounter.reset();
- attemptCounter.reset();
- hitCounter.reset();
- missCounter.reset();
- failedCounter.reset();
- }
-
- @Override
- public boolean isStatisticsEnabled() {
- return statisticsEnabled;
- }
-
- @Override
- public void setStatisticsEnabled(boolean statisticsEnabled) {
- this.statisticsEnabled = statisticsEnabled;
- }
-
- @Override
- public String toString() {
- return String.format("TypeConverterRegistry utilization[noop=%s,
attempts=%s, hits=%s, misses=%s, failures=%s]",
- getNoopCounter(), getAttemptCounter(), getHitCounter(),
getMissCounter(), getFailedCounter());
- }
+ return String.format("%s mappings[total=%s, misses=%s]", statistics,
size(), misses);
}
/**
diff --git
a/core/camel-base/src/main/java/org/apache/camel/impl/converter/TypeConverterStatistics.java
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/TypeConverterStatistics.java
new file mode 100644
index 00000000000..2a813d6a26e
--- /dev/null
+++
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/TypeConverterStatistics.java
@@ -0,0 +1,118 @@
+/*
+ * 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.impl.converter;
+
+import java.util.concurrent.atomic.LongAdder;
+
+/**
+ * Represents utilization statistics
+ */
+final class TypeConverterStatistics implements ConverterStatistics {
+
+ private boolean statisticsEnabled;
+ private final LongAdder noopCounter = new LongAdder();
+ private final LongAdder attemptCounter = new LongAdder();
+ private final LongAdder missCounter = new LongAdder();
+ private final LongAdder hitCounter = new LongAdder();
+ private final LongAdder failedCounter = new LongAdder();
+
+ @Override
+ public long getNoopCounter() {
+ return noopCounter.longValue();
+ }
+
+ @Override
+ public long getAttemptCounter() {
+ return attemptCounter.longValue();
+ }
+
+ @Override
+ public long getHitCounter() {
+ return hitCounter.longValue();
+ }
+
+ @Override
+ public long getMissCounter() {
+ return missCounter.longValue();
+ }
+
+ @Override
+ public long getFailedCounter() {
+ return failedCounter.longValue();
+ }
+
+ @Override
+ public void incrementFailed() {
+ if (statisticsEnabled) {
+ failedCounter.increment();
+ }
+ }
+
+ @Override
+ public void incrementNoop() {
+ if (statisticsEnabled) {
+ noopCounter.increment();
+ }
+ }
+
+ @Override
+ public void incrementHit() {
+ if (statisticsEnabled) {
+ hitCounter.increment();
+ }
+ }
+
+ @Override
+ public void incrementMiss() {
+ if (statisticsEnabled) {
+ missCounter.increment();
+ }
+ }
+
+ @Override
+ public void incrementAttempt() {
+ if (statisticsEnabled) {
+ attemptCounter.increment();
+ }
+ }
+
+ @Override
+ public void reset() {
+ noopCounter.reset();
+ attemptCounter.reset();
+ hitCounter.reset();
+ missCounter.reset();
+ failedCounter.reset();
+ }
+
+ @Override
+ public boolean isStatisticsEnabled() {
+ return statisticsEnabled;
+ }
+
+ @Override
+ public void setStatisticsEnabled(boolean statisticsEnabled) {
+ this.statisticsEnabled = statisticsEnabled;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("TypeConverterRegistry utilization[noop=%s,
attempts=%s, hits=%s, misses=%s, failures=%s]",
+ getNoopCounter(), getAttemptCounter(), getHitCounter(),
getMissCounter(), getFailedCounter());
+ }
+}