diff --git a/common/pom.xml b/common/pom.xml
index 0f07a4105ab..326d490d5da 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -152,6 +152,11 @@
org.slf4j
jcl-over-slf4j
+
+ io.dropwizard.metrics
+ metrics-core
+
+
com.lmax
diff --git a/extensions-core/kafka-indexing-service/src/main/java/io/druid/indexing/kafka/KafkaIndexTask.java b/extensions-core/kafka-indexing-service/src/main/java/io/druid/indexing/kafka/KafkaIndexTask.java
index 734c8321aac..b156d3a6a28 100644
--- a/extensions-core/kafka-indexing-service/src/main/java/io/druid/indexing/kafka/KafkaIndexTask.java
+++ b/extensions-core/kafka-indexing-service/src/main/java/io/druid/indexing/kafka/KafkaIndexTask.java
@@ -50,7 +50,6 @@ import io.druid.discovery.DiscoveryDruidNode;
import io.druid.discovery.DruidNodeDiscoveryProvider;
import io.druid.discovery.LookupNodeService;
import io.druid.indexer.IngestionState;
-import io.druid.indexer.TaskMetricsGetter;
import io.druid.indexing.appenderator.ActionBasedSegmentAllocator;
import io.druid.indexing.appenderator.ActionBasedUsedSegmentChecker;
import io.druid.indexing.common.IngestionStatsAndErrorsTaskReport;
@@ -63,6 +62,8 @@ import io.druid.indexing.common.actions.CheckPointDataSourceMetadataAction;
import io.druid.indexing.common.actions.ResetDataSourceMetadataAction;
import io.druid.indexing.common.actions.SegmentTransactionalInsertAction;
import io.druid.indexing.common.actions.TaskActionClient;
+import io.druid.indexing.common.stats.RowIngestionMeters;
+import io.druid.indexing.common.stats.RowIngestionMetersFactory;
import io.druid.indexing.common.task.AbstractTask;
import io.druid.indexing.common.task.IndexTaskUtils;
import io.druid.indexing.common.task.RealtimeIndexTask;
@@ -86,7 +87,6 @@ import io.druid.segment.indexing.DataSchema;
import io.druid.segment.indexing.RealtimeIOConfig;
import io.druid.segment.realtime.FireDepartment;
import io.druid.segment.realtime.FireDepartmentMetrics;
-import io.druid.segment.realtime.FireDepartmentMetricsTaskMetricsGetter;
import io.druid.segment.realtime.appenderator.Appenderator;
import io.druid.segment.realtime.appenderator.AppenderatorDriverAddResult;
import io.druid.segment.realtime.appenderator.Appenderators;
@@ -244,6 +244,7 @@ public class KafkaIndexTask extends AbstractTask implements ChatHandler
private final CountDownLatch waitForPublishes = new CountDownLatch(1);
private final AtomicReference throwableAtomicReference = new AtomicReference<>();
private final String topic;
+ private final RowIngestionMeters rowIngestionMeters;
private volatile CopyOnWriteArrayList sequences;
private ListeningExecutorService publishExecService;
@@ -251,7 +252,6 @@ public class KafkaIndexTask extends AbstractTask implements ChatHandler
private CircularBuffer savedParseExceptions;
private IngestionState ingestionState;
- private TaskMetricsGetter metricsGetter;
private String errorMsg;
@JsonCreator
@@ -263,7 +263,8 @@ public class KafkaIndexTask extends AbstractTask implements ChatHandler
@JsonProperty("ioConfig") KafkaIOConfig ioConfig,
@JsonProperty("context") Map context,
@JacksonInject ChatHandlerProvider chatHandlerProvider,
- @JacksonInject AuthorizerMapper authorizerMapper
+ @JacksonInject AuthorizerMapper authorizerMapper,
+ @JacksonInject RowIngestionMetersFactory rowIngestionMetersFactory
)
{
super(
@@ -284,6 +285,7 @@ public class KafkaIndexTask extends AbstractTask implements ChatHandler
this.topic = ioConfig.getStartPartitions().getTopic();
this.sequences = new CopyOnWriteArrayList<>();
this.ingestionState = IngestionState.NOT_STARTED;
+ this.rowIngestionMeters = rowIngestionMetersFactory.createRowIngestionMeters();
if (context != null && context.get(KafkaSupervisor.IS_INCREMENTAL_HANDOFF_SUPPORTED) != null
&& ((boolean) context.get(KafkaSupervisor.IS_INCREMENTAL_HANDOFF_SUPPORTED))) {
@@ -511,8 +513,8 @@ public class KafkaIndexTask extends AbstractTask implements ChatHandler
null
);
fireDepartmentMetrics = fireDepartmentForMetrics.getMetrics();
- metricsGetter = new FireDepartmentMetricsTaskMetricsGetter(fireDepartmentMetrics);
- toolbox.getMonitorScheduler().addMonitor(TaskRealtimeMetricsMonitorBuilder.build(this, fireDepartmentForMetrics));
+ toolbox.getMonitorScheduler()
+ .addMonitor(TaskRealtimeMetricsMonitorBuilder.build(this, fireDepartmentForMetrics, rowIngestionMeters));
LookupNodeService lookupNodeService = getContextValue(RealtimeIndexTask.CTX_KEY_LOOKUP_TIER) == null ?
toolbox.getLookupNodeService() :
@@ -758,10 +760,10 @@ public class KafkaIndexTask extends AbstractTask implements ChatHandler
if (addResult.getParseException() != null) {
handleParseException(addResult.getParseException(), record);
} else {
- fireDepartmentMetrics.incrementProcessed();
+ rowIngestionMeters.incrementProcessed();
}
} else {
- fireDepartmentMetrics.incrementThrownAway();
+ rowIngestionMeters.incrementThrownAway();
}
}
if (isPersistRequired) {
@@ -950,8 +952,8 @@ public class KafkaIndexTask extends AbstractTask implements ChatHandler
null
);
fireDepartmentMetrics = fireDepartmentForMetrics.getMetrics();
- metricsGetter = new FireDepartmentMetricsTaskMetricsGetter(fireDepartmentMetrics);
- toolbox.getMonitorScheduler().addMonitor(TaskRealtimeMetricsMonitorBuilder.build(this, fireDepartmentForMetrics));
+ toolbox.getMonitorScheduler()
+ .addMonitor(TaskRealtimeMetricsMonitorBuilder.build(this, fireDepartmentForMetrics, rowIngestionMeters));
LookupNodeService lookupNodeService = getContextValue(RealtimeIndexTask.CTX_KEY_LOOKUP_TIER) == null ?
toolbox.getLookupNodeService() :
@@ -1148,10 +1150,10 @@ public class KafkaIndexTask extends AbstractTask implements ChatHandler
if (addResult.getParseException() != null) {
handleParseException(addResult.getParseException(), record);
} else {
- fireDepartmentMetrics.incrementProcessed();
+ rowIngestionMeters.incrementProcessed();
}
} else {
- fireDepartmentMetrics.incrementThrownAway();
+ rowIngestionMeters.incrementThrownAway();
}
}
@@ -1296,9 +1298,9 @@ public class KafkaIndexTask extends AbstractTask implements ChatHandler
private void handleParseException(ParseException pe, ConsumerRecord record)
{
if (pe.isFromPartiallyValidRow()) {
- fireDepartmentMetrics.incrementProcessedWithErrors();
+ rowIngestionMeters.incrementProcessedWithError();
} else {
- fireDepartmentMetrics.incrementUnparseable();
+ rowIngestionMeters.incrementUnparseable();
}
if (tuningConfig.isLogParseExceptions()) {
@@ -1314,7 +1316,7 @@ public class KafkaIndexTask extends AbstractTask implements ChatHandler
savedParseExceptions.add(pe);
}
- if (fireDepartmentMetrics.unparseable() + fireDepartmentMetrics.processedWithErrors()
+ if (rowIngestionMeters.getUnparseable() + rowIngestionMeters.getProcessedWithError()
> tuningConfig.getMaxParseExceptions()) {
log.error("Max parse exceptions exceeded, terminating task...");
throw new RuntimeException("Max parse exceptions exceeded, terminating task...");
@@ -1341,7 +1343,7 @@ public class KafkaIndexTask extends AbstractTask implements ChatHandler
Map unparseableEventsMap = Maps.newHashMap();
List buildSegmentsParseExceptionMessages = IndexTaskUtils.getMessagesFromSavedParseExceptions(savedParseExceptions);
if (buildSegmentsParseExceptionMessages != null) {
- unparseableEventsMap.put("buildSegments", buildSegmentsParseExceptionMessages);
+ unparseableEventsMap.put(RowIngestionMeters.BUILD_SEGMENTS, buildSegmentsParseExceptionMessages);
}
return unparseableEventsMap;
}
@@ -1349,12 +1351,10 @@ public class KafkaIndexTask extends AbstractTask implements ChatHandler
private Map getTaskCompletionRowStats()
{
Map metrics = Maps.newHashMap();
- if (metricsGetter != null) {
- metrics.put(
- "buildSegments",
- metricsGetter.getTotalMetrics()
- );
- }
+ metrics.put(
+ RowIngestionMeters.BUILD_SEGMENTS,
+ rowIngestionMeters.getTotals()
+ );
return metrics;
}
@@ -1574,14 +1574,18 @@ public class KafkaIndexTask extends AbstractTask implements ChatHandler
authorizationCheck(req, Action.READ);
Map returnMap = Maps.newHashMap();
Map totalsMap = Maps.newHashMap();
+ Map averagesMap = Maps.newHashMap();
- if (metricsGetter != null) {
- totalsMap.put(
- "buildSegments",
- metricsGetter.getTotalMetrics()
- );
- }
+ totalsMap.put(
+ RowIngestionMeters.BUILD_SEGMENTS,
+ rowIngestionMeters.getTotals()
+ );
+ averagesMap.put(
+ RowIngestionMeters.BUILD_SEGMENTS,
+ rowIngestionMeters.getMovingAverages()
+ );
+ returnMap.put("movingAverages", averagesMap);
returnMap.put("totals", totalsMap);
return Response.ok(returnMap).build();
}
@@ -1885,6 +1889,12 @@ public class KafkaIndexTask extends AbstractTask implements ChatHandler
return fireDepartmentMetrics;
}
+ @VisibleForTesting
+ RowIngestionMeters getRowIngestionMeters()
+ {
+ return rowIngestionMeters;
+ }
+
private boolean isPaused()
{
return status == Status.PAUSED;
diff --git a/extensions-core/kafka-indexing-service/src/main/java/io/druid/indexing/kafka/KafkaIndexTaskClient.java b/extensions-core/kafka-indexing-service/src/main/java/io/druid/indexing/kafka/KafkaIndexTaskClient.java
index 315cc0fda93..544aa53c8bd 100644
--- a/extensions-core/kafka-indexing-service/src/main/java/io/druid/indexing/kafka/KafkaIndexTaskClient.java
+++ b/extensions-core/kafka-indexing-service/src/main/java/io/druid/indexing/kafka/KafkaIndexTaskClient.java
@@ -23,7 +23,6 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
-import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
@@ -39,6 +38,7 @@ import io.druid.java.util.common.IOE;
import io.druid.java.util.common.ISE;
import io.druid.java.util.common.StringUtils;
import io.druid.java.util.common.concurrent.Execs;
+import io.druid.java.util.common.jackson.JacksonUtils;
import io.druid.java.util.emitter.EmittingLogger;
import io.druid.java.util.http.client.HttpClient;
import io.druid.java.util.http.client.Request;
@@ -57,6 +57,7 @@ import java.io.IOException;
import java.net.Socket;
import java.net.URI;
import java.nio.charset.StandardCharsets;
+import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.Callable;
@@ -215,8 +216,10 @@ public class KafkaIndexTaskClient
return ImmutableMap.of();
}
catch (IOException | InterruptedException e) {
- log.error("Exception [%s] while pausing Task [%s]", e.getMessage(), id);
- throw Throwables.propagate(e);
+ throw new RuntimeException(
+ StringUtils.format("Exception [%s] while pausing Task [%s]", e.getMessage(), id),
+ e
+ );
}
}
@@ -232,7 +235,7 @@ public class KafkaIndexTaskClient
return KafkaIndexTask.Status.NOT_STARTED;
}
catch (IOException e) {
- throw Throwables.propagate(e);
+ throw new RuntimeException(e);
}
}
@@ -250,10 +253,48 @@ public class KafkaIndexTaskClient
return null;
}
catch (IOException e) {
- throw Throwables.propagate(e);
+ throw new RuntimeException(e);
}
}
+ public Map getMovingAverages(final String id)
+ {
+ log.debug("GetMovingAverages task[%s]", id);
+
+ try {
+ final FullResponseHolder response = submitRequest(
+ id,
+ HttpMethod.GET,
+ "rowStats",
+ null,
+ true
+ );
+ return response.getContent() == null || response.getContent().isEmpty()
+ ? Collections.emptyMap()
+ : jsonMapper.readValue(response.getContent(), JacksonUtils.TYPE_REFERENCE_MAP_STRING_OBJECT);
+ }
+ catch (NoTaskLocationException e) {
+ return Collections.emptyMap();
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public ListenableFuture
+
+ io.dropwizard.metrics
+ metrics-core
+ ${dropwizard.metrics.version}
+
diff --git a/server/src/main/java/io/druid/indexing/overlord/supervisor/Supervisor.java b/server/src/main/java/io/druid/indexing/overlord/supervisor/Supervisor.java
index 681421b4800..d5efd8e7444 100644
--- a/server/src/main/java/io/druid/indexing/overlord/supervisor/Supervisor.java
+++ b/server/src/main/java/io/druid/indexing/overlord/supervisor/Supervisor.java
@@ -19,9 +19,11 @@
package io.druid.indexing.overlord.supervisor;
+import com.google.common.collect.ImmutableMap;
import io.druid.indexing.overlord.DataSourceMetadata;
import javax.annotation.Nullable;
+import java.util.Map;
public interface Supervisor
{
@@ -37,6 +39,11 @@ public interface Supervisor
SupervisorReport getStatus();
+ default Map> getStats()
+ {
+ return ImmutableMap.of();
+ }
+
void reset(DataSourceMetadata dataSourceMetadata);
/**
diff --git a/server/src/main/java/io/druid/segment/realtime/FireDepartmentMetricsTaskMetricsGetter.java b/server/src/main/java/io/druid/segment/realtime/FireDepartmentMetricsTaskMetricsGetter.java
deleted file mode 100644
index 9c7ee60fde1..00000000000
--- a/server/src/main/java/io/druid/segment/realtime/FireDepartmentMetricsTaskMetricsGetter.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to Metamarkets Group Inc. (Metamarkets) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. Metamarkets 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 io.druid.segment.realtime;
-
-import com.google.common.collect.ImmutableMap;
-import io.druid.indexer.TaskMetricsGetter;
-import io.druid.indexer.TaskMetricsUtils;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-public class FireDepartmentMetricsTaskMetricsGetter implements TaskMetricsGetter
-{
- public static final List KEYS = Arrays.asList(
- TaskMetricsUtils.ROWS_PROCESSED,
- TaskMetricsUtils.ROWS_PROCESSED_WITH_ERRORS,
- TaskMetricsUtils.ROWS_THROWN_AWAY,
- TaskMetricsUtils.ROWS_UNPARSEABLE
- );
-
- private final FireDepartmentMetrics fireDepartmentMetrics;
-
- public FireDepartmentMetricsTaskMetricsGetter(
- FireDepartmentMetrics fireDepartmentMetrics
- )
- {
- this.fireDepartmentMetrics = fireDepartmentMetrics;
- }
-
- @Override
- public List getKeys()
- {
- return KEYS;
- }
-
- @Override
- public Map getTotalMetrics()
- {
- return ImmutableMap.of(
- TaskMetricsUtils.ROWS_PROCESSED, fireDepartmentMetrics.processed(),
- TaskMetricsUtils.ROWS_PROCESSED_WITH_ERRORS, fireDepartmentMetrics.processedWithErrors(),
- TaskMetricsUtils.ROWS_THROWN_AWAY, fireDepartmentMetrics.thrownAway(),
- TaskMetricsUtils.ROWS_UNPARSEABLE, fireDepartmentMetrics.unparseable()
- );
- }
-}
diff --git a/server/src/main/java/io/druid/segment/realtime/RealtimeMetricsMonitor.java b/server/src/main/java/io/druid/segment/realtime/RealtimeMetricsMonitor.java
index 38f82326792..6cea578983d 100644
--- a/server/src/main/java/io/druid/segment/realtime/RealtimeMetricsMonitor.java
+++ b/server/src/main/java/io/druid/segment/realtime/RealtimeMetricsMonitor.java
@@ -33,6 +33,10 @@ import java.util.List;
import java.util.Map;
/**
+ * RealtimeMetricsMonitor is only used by RealtimeIndexTask, this monitor only supports FireDepartmentMetrics.
+ * New ingestion task types should support RowIngestionMeters and use TaskRealtimeMetricsMonitor instead.
+ * Please see the comment on RowIngestionMeters for more information regarding the relationship between
+ * RowIngestionMeters and FireDepartmentMetrics.
*/
public class RealtimeMetricsMonitor extends AbstractMonitor
{
diff --git a/services/src/main/java/io/druid/cli/CliMiddleManager.java b/services/src/main/java/io/druid/cli/CliMiddleManager.java
index ed4d44a2762..934e63d2eeb 100644
--- a/services/src/main/java/io/druid/cli/CliMiddleManager.java
+++ b/services/src/main/java/io/druid/cli/CliMiddleManager.java
@@ -24,6 +24,7 @@ import com.google.inject.Binder;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.Provides;
+import com.google.inject.multibindings.MapBinder;
import com.google.inject.name.Names;
import com.google.inject.util.Providers;
import io.airlift.airline.Command;
@@ -37,8 +38,11 @@ import io.druid.guice.JsonConfigProvider;
import io.druid.guice.LazySingleton;
import io.druid.guice.LifecycleModule;
import io.druid.guice.ManageLifecycle;
+import io.druid.guice.PolyBind;
import io.druid.guice.annotations.Self;
import io.druid.indexing.common.config.TaskConfig;
+import io.druid.indexing.common.stats.DropwizardRowIngestionMetersFactory;
+import io.druid.indexing.common.stats.RowIngestionMetersFactory;
import io.druid.indexing.overlord.ForkingTaskRunner;
import io.druid.indexing.overlord.TaskRunner;
import io.druid.indexing.worker.Worker;
@@ -92,6 +96,19 @@ public class CliMiddleManager extends ServerRunnable
binder.bind(ForkingTaskRunner.class).in(LazySingleton.class);
binder.bind(ChatHandlerProvider.class).toProvider(Providers.of(null));
+ PolyBind.createChoice(
+ binder,
+ "druid.indexer.task.rowIngestionMeters.type",
+ Key.get(RowIngestionMetersFactory.class),
+ Key.get(DropwizardRowIngestionMetersFactory.class)
+ );
+ final MapBinder rowIngestionMetersHandlerProviderBinder = PolyBind.optionBinder(
+ binder, Key.get(RowIngestionMetersFactory.class)
+ );
+ rowIngestionMetersHandlerProviderBinder.addBinding("dropwizard")
+ .to(DropwizardRowIngestionMetersFactory.class).in(LazySingleton.class);
+ binder.bind(DropwizardRowIngestionMetersFactory.class).in(LazySingleton.class);
+
binder.bind(WorkerTaskMonitor.class).in(ManageLifecycle.class);
binder.bind(WorkerCuratorCoordinator.class).in(ManageLifecycle.class);
diff --git a/services/src/main/java/io/druid/cli/CliOverlord.java b/services/src/main/java/io/druid/cli/CliOverlord.java
index 1faba1f4f32..3bad59440ae 100644
--- a/services/src/main/java/io/druid/cli/CliOverlord.java
+++ b/services/src/main/java/io/druid/cli/CliOverlord.java
@@ -54,6 +54,8 @@ import io.druid.indexing.common.actions.TaskActionClientFactory;
import io.druid.indexing.common.actions.TaskActionToolbox;
import io.druid.indexing.common.config.TaskConfig;
import io.druid.indexing.common.config.TaskStorageConfig;
+import io.druid.indexing.common.stats.DropwizardRowIngestionMetersFactory;
+import io.druid.indexing.common.stats.RowIngestionMetersFactory;
import io.druid.indexing.common.tasklogs.SwitchingTaskLogStreamer;
import io.druid.indexing.common.tasklogs.TaskRunnerTaskLogStreamer;
import io.druid.indexing.overlord.ForkingTaskRunnerFactory;
@@ -184,6 +186,19 @@ public class CliOverlord extends ServerRunnable
binder.bind(ChatHandlerProvider.class).toProvider(Providers.of(null));
+ PolyBind.createChoice(
+ binder,
+ "druid.indexer.task.rowIngestionMeters.type",
+ Key.get(RowIngestionMetersFactory.class),
+ Key.get(DropwizardRowIngestionMetersFactory.class)
+ );
+ final MapBinder rowIngestionMetersHandlerProviderBinder = PolyBind.optionBinder(
+ binder, Key.get(RowIngestionMetersFactory.class)
+ );
+ rowIngestionMetersHandlerProviderBinder.addBinding("dropwizard")
+ .to(DropwizardRowIngestionMetersFactory.class).in(LazySingleton.class);
+ binder.bind(DropwizardRowIngestionMetersFactory.class).in(LazySingleton.class);
+
configureTaskStorage(binder);
configureAutoscale(binder);
configureRunners(binder);
diff --git a/services/src/main/java/io/druid/cli/CliPeon.java b/services/src/main/java/io/druid/cli/CliPeon.java
index aa6f0b13583..136645d2e7a 100644
--- a/services/src/main/java/io/druid/cli/CliPeon.java
+++ b/services/src/main/java/io/druid/cli/CliPeon.java
@@ -62,6 +62,8 @@ import io.druid.indexing.common.actions.TaskActionClientFactory;
import io.druid.indexing.common.actions.TaskActionToolbox;
import io.druid.indexing.common.config.TaskConfig;
import io.druid.indexing.common.config.TaskStorageConfig;
+import io.druid.indexing.common.stats.DropwizardRowIngestionMetersFactory;
+import io.druid.indexing.common.stats.RowIngestionMetersFactory;
import io.druid.indexing.common.task.Task;
import io.druid.indexing.overlord.HeapMemoryTaskStorage;
import io.druid.indexing.overlord.IndexerMetadataStorageCoordinator;
@@ -159,6 +161,19 @@ public class CliPeon extends GuiceRunnable
binder.bindConstant().annotatedWith(Names.named("servicePort")).to(0);
binder.bindConstant().annotatedWith(Names.named("tlsServicePort")).to(-1);
+ PolyBind.createChoice(
+ binder,
+ "druid.indexer.task.rowIngestionMeters.type",
+ Key.get(RowIngestionMetersFactory.class),
+ Key.get(DropwizardRowIngestionMetersFactory.class)
+ );
+ final MapBinder rowIngestionMetersHandlerProviderBinder = PolyBind.optionBinder(
+ binder, Key.get(RowIngestionMetersFactory.class)
+ );
+ rowIngestionMetersHandlerProviderBinder.addBinding("dropwizard")
+ .to(DropwizardRowIngestionMetersFactory.class).in(LazySingleton.class);
+ binder.bind(DropwizardRowIngestionMetersFactory.class).in(LazySingleton.class);
+
PolyBind.createChoice(
binder,
"druid.indexer.task.chathandler.type",
diff --git a/services/src/main/java/io/druid/guice/RealtimeModule.java b/services/src/main/java/io/druid/guice/RealtimeModule.java
index 827b94956b0..01b1ba6d6b3 100644
--- a/services/src/main/java/io/druid/guice/RealtimeModule.java
+++ b/services/src/main/java/io/druid/guice/RealtimeModule.java
@@ -27,6 +27,8 @@ import com.google.inject.multibindings.MapBinder;
import io.druid.cli.QueryJettyServerInitializer;
import io.druid.client.cache.CacheConfig;
import io.druid.client.coordinator.CoordinatorClient;
+import io.druid.indexing.common.stats.DropwizardRowIngestionMetersFactory;
+import io.druid.indexing.common.stats.RowIngestionMetersFactory;
import io.druid.metadata.MetadataSegmentPublisher;
import io.druid.query.QuerySegmentWalker;
import io.druid.segment.realtime.FireDepartment;
@@ -66,6 +68,19 @@ public class RealtimeModule implements Module
publisherBinder.addBinding("noop").to(NoopSegmentPublisher.class).in(LazySingleton.class);
publisherBinder.addBinding("metadata").to(MetadataSegmentPublisher.class).in(LazySingleton.class);
+ PolyBind.createChoice(
+ binder,
+ "druid.realtime.rowIngestionMeters.type",
+ Key.get(RowIngestionMetersFactory.class),
+ Key.get(DropwizardRowIngestionMetersFactory.class)
+ );
+ final MapBinder rowIngestionMetersHandlerProviderBinder = PolyBind.optionBinder(
+ binder, Key.get(RowIngestionMetersFactory.class)
+ );
+ rowIngestionMetersHandlerProviderBinder.addBinding("dropwizard")
+ .to(DropwizardRowIngestionMetersFactory.class).in(LazySingleton.class);
+ binder.bind(DropwizardRowIngestionMetersFactory.class).in(LazySingleton.class);
+
PolyBind.createChoice(
binder,
"druid.realtime.chathandler.type",