/** * Copyright 2016 LinkedIn Corp. All rights reserved. * * Licensed 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. */ package com.github.ambry.rest; import com.codahale.metrics.Counter; import com.codahale.metrics.Gauge; import com.codahale.metrics.Histogram; import com.codahale.metrics.Meter; import com.codahale.metrics.MetricRegistry; import java.util.concurrent.atomic.AtomicLong; /** * Netty specific metrics tracking. * <p/> * Exports metrics that are triggered by Netty to the provided {@link MetricRegistry}. */ public class NettyMetrics { private final MetricRegistry metricRegistry; // Rates // NettyMessageProcessor public final Meter bytesReadRate; public final Meter channelCreationRate; public final Meter channelDestructionRate; public final Meter requestArrivalRate; public final Meter multipartPostRequestRate; // NettyResponseChannel public final Meter bytesWriteRate; public final Meter requestCompletionRate; // PublicAccessLogHandler public final Meter publicAccessLogRequestRate; // HealthCheckRequestHandler public final Meter healthCheckRequestRate; // Latencies // NettyMessageProcessor public final Histogram requestChunkProcessingTimeInMs; // NettyResponseChannel public final Histogram channelWriteFailureProcessingTimeInMs; public final Histogram chunkDispenseTimeInMs; public final Histogram chunkQueueTimeInMs; public final Histogram channelWriteTimeInMs; public final Histogram chunkResolutionProcessingTimeInMs; public final Histogram errorResponseProcessingTimeInMs; public final Histogram headerSetTimeInMs; public final Histogram responseFinishProcessingTimeInMs; public final Histogram responseMetadataAfterWriteProcessingTimeInMs; public final Histogram responseMetadataProcessingTimeInMs; public final Histogram writeProcessingTimeInMs; // PublicAccessLogHandler public final Histogram publicAccessLogRequestProcessingTimeInMs; public final Histogram publicAccessLogResponseProcessingTimeInMs; // HealthCheckRequestHandler public final Histogram healthCheckRequestProcessingTimeInMs; public final Histogram healthCheckRequestRoundTripTimeInMs; public final Histogram healthCheckResponseProcessingTimeInMs; // Errors // NettyMessageProcessor public final Counter contentAdditionError; public final Counter duplicateRequestError; public final Counter exceptionCaughtTasksError; public final Counter malformedRequestError; public final Counter missingResponseChannelError; public final Counter noRequestError; public final Counter unknownHttpObjectError; // NettyMultipartRequest public final Counter multipartRequestAlreadyClosedError; public final Counter multipartRequestDecodeError; public final Counter multipartRequestSizeMismatchError; public final Counter repeatedPartsError; public final Counter unsupportedPartError; // NettyRequest public final Counter requestAlreadyClosedError; public final Counter unsupportedHttpMethodError; // NettyResponseChannel public final Counter channelWriteError; public final Counter deadResponseAccessError; public final Counter responseCompleteTasksError; // NettyServer public final Counter nettyServerShutdownError; public final Counter nettyServerStartError; // Other // NettyRequest public final Counter contentCopyCount; public final Histogram digestCalculationTimeInMs; public final Counter watermarkOverflowCount; // NettyMessageProcessor public final Histogram channelReadIntervalInMs; public final Counter idleConnectionCloseCount; public final Counter processorErrorAfterCloseCount; public final Counter processorExceptionCaughtCount; public final Counter processorIOExceptionCount; public final Counter processorRestServiceExceptionCount; public final Counter processorThrowableCount; public final Counter processorUnknownExceptionCount; // NettyResponseChannel public final Counter acceptedCount; public final Counter createdCount; public final Counter okCount; public final Counter partialContentCount; public final Counter notModifiedCount; public final Counter badRequestCount; public final Counter unauthorizedCount; public final Counter goneCount; public final Counter internalServerErrorCount; public final Counter notFoundCount; public final Counter forbiddenCount; public final Counter proxyAuthRequiredCount; public final Counter rangeNotSatisfiableCount; public final Counter throwableCount; public final Counter unknownResponseStatusCount; // NettyServer public final Histogram nettyServerShutdownTimeInMs; public final Histogram nettyServerStartTimeInMs; // ConnectionStatsHandler public final Counter connectionsConnectedCount; public final Counter connectionsDisconnectedCount; // PublicAccessLogHandler public final Counter publicAccessLogRequestDisconnectWhileInProgressCount; public final Counter publicAccessLogRequestCloseWhileRequestInProgressCount; // HealthCheckRequestHandler public final Counter healthCheckHandlerChannelCloseOnWriteCount; /** * Creates an instance of NettyMetrics using the given {@code metricRegistry}. * @param metricRegistry the {@link MetricRegistry} to use for the metrics. */ public NettyMetrics(MetricRegistry metricRegistry) { this.metricRegistry = metricRegistry; // Rates // NettyMessageProcessor bytesReadRate = metricRegistry.meter(MetricRegistry.name(NettyMessageProcessor.class, "BytesReadRate")); channelCreationRate = metricRegistry.meter(MetricRegistry.name(NettyMessageProcessor.class, "ChannelCreationRate")); channelDestructionRate = metricRegistry.meter(MetricRegistry.name(NettyMessageProcessor.class, "ChannelDestructionRate")); requestArrivalRate = metricRegistry.meter(MetricRegistry.name(NettyMessageProcessor.class, "RequestArrivalRate")); multipartPostRequestRate = metricRegistry.meter(MetricRegistry.name(NettyMessageProcessor.class, "MultipartPostRequestRate")); // NettyResponseChannel bytesWriteRate = metricRegistry.meter(MetricRegistry.name(NettyResponseChannel.class, "BytesWriteRate")); requestCompletionRate = metricRegistry.meter(MetricRegistry.name(NettyResponseChannel.class, "RequestCompletionRate")); publicAccessLogRequestRate = metricRegistry.meter(MetricRegistry.name(PublicAccessLogHandler.class, "RequestArrivalRate")); healthCheckRequestRate = metricRegistry.meter(MetricRegistry.name(HealthCheckHandler.class, "RequestArrivalRate")); // Latencies // NettyMessageProcessor requestChunkProcessingTimeInMs = metricRegistry.histogram(MetricRegistry.name(NettyMessageProcessor.class, "RequestChunkProcessingTimeInMs")); // NettyResponseChannel channelWriteFailureProcessingTimeInMs = metricRegistry.histogram( MetricRegistry.name(NettyResponseChannel.class, "ChannelWriteFailureProcessingTimeInMs")); chunkDispenseTimeInMs = metricRegistry.histogram(MetricRegistry.name(NettyResponseChannel.class, "ChunkDispenseTimeInMs")); chunkQueueTimeInMs = metricRegistry.histogram(MetricRegistry.name(NettyResponseChannel.class, "ChunkQueueTimeInMs")); channelWriteTimeInMs = metricRegistry.histogram(MetricRegistry.name(NettyResponseChannel.class, "ChannelWriteTimeInMs")); chunkResolutionProcessingTimeInMs = metricRegistry.histogram(MetricRegistry.name(NettyResponseChannel.class, "ChunkResolutionProcessingTimeInMs")); errorResponseProcessingTimeInMs = metricRegistry.histogram(MetricRegistry.name(NettyResponseChannel.class, "ErrorResponseProcessingTimeInMs")); headerSetTimeInMs = metricRegistry.histogram(MetricRegistry.name(NettyResponseChannel.class, "HeaderSetTimeInMs")); responseFinishProcessingTimeInMs = metricRegistry.histogram(MetricRegistry.name(NettyResponseChannel.class, "ResponseFinishProcessingTimeInMs")); responseMetadataAfterWriteProcessingTimeInMs = metricRegistry.histogram( MetricRegistry.name(NettyResponseChannel.class, "ResponseMetadataAfterWriteProcessingTimeInMs")); responseMetadataProcessingTimeInMs = metricRegistry.histogram(MetricRegistry.name(NettyResponseChannel.class, "ResponseMetadataProcessingTimeInMs")); writeProcessingTimeInMs = metricRegistry.histogram(MetricRegistry.name(NettyResponseChannel.class, "WriteProcessingTimeInMs")); // PublicAccessLogHandler publicAccessLogRequestProcessingTimeInMs = metricRegistry.histogram(MetricRegistry.name(PublicAccessLogHandler.class, "RequestProcessingTimeInMs")); publicAccessLogResponseProcessingTimeInMs = metricRegistry.histogram(MetricRegistry.name(PublicAccessLogHandler.class, "ResponseProcessingTimeInMs")); // HealthCheckHandler healthCheckRequestProcessingTimeInMs = metricRegistry.histogram(MetricRegistry.name(HealthCheckHandler.class, "RequestProcessingTimeInMs")); healthCheckRequestRoundTripTimeInMs = metricRegistry.histogram(MetricRegistry.name(HealthCheckHandler.class, "RequestRoundTripTimeInMs")); healthCheckResponseProcessingTimeInMs = metricRegistry.histogram(MetricRegistry.name(HealthCheckHandler.class, "ResponseProcessingTimeInMs")); // Errors // NettyMessageProcessor contentAdditionError = metricRegistry.counter(MetricRegistry.name(NettyMessageProcessor.class, "ContentAdditionError")); duplicateRequestError = metricRegistry.counter(MetricRegistry.name(NettyMessageProcessor.class, "DuplicateRequestError")); exceptionCaughtTasksError = metricRegistry.counter(MetricRegistry.name(NettyMessageProcessor.class, "ExceptionCaughtTasksError")); malformedRequestError = metricRegistry.counter(MetricRegistry.name(NettyMessageProcessor.class, "MalformedRequestError")); missingResponseChannelError = metricRegistry.counter(MetricRegistry.name(NettyMessageProcessor.class, "MissingResponseChannelError")); noRequestError = metricRegistry.counter(MetricRegistry.name(NettyMessageProcessor.class, "NoRequestError")); unknownHttpObjectError = metricRegistry.counter(MetricRegistry.name(NettyMessageProcessor.class, "UnknownHttpObjectError")); // NettyMultipartRequest multipartRequestAlreadyClosedError = metricRegistry.counter(MetricRegistry.name(NettyMultipartRequest.class, "AlreadyClosedError")); multipartRequestDecodeError = metricRegistry.counter(MetricRegistry.name(NettyMultipartRequest.class, "DecodeError")); multipartRequestSizeMismatchError = metricRegistry.counter(MetricRegistry.name(NettyMultipartRequest.class, "SizeMismatchError")); repeatedPartsError = metricRegistry.counter(MetricRegistry.name(NettyMultipartRequest.class, "RepeatedPartsError")); unsupportedPartError = metricRegistry.counter(MetricRegistry.name(NettyMultipartRequest.class, "UnsupportedPartError")); // NettyRequest requestAlreadyClosedError = metricRegistry.counter(MetricRegistry.name(NettyRequest.class, "AlreadyClosedError")); unsupportedHttpMethodError = metricRegistry.counter(MetricRegistry.name(NettyRequest.class, "UnsupportedHttpMethodError")); // NettyResponseChannel channelWriteError = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "ChannelWriteError")); deadResponseAccessError = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "DeadResponseAccessError")); responseCompleteTasksError = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "ResponseCompleteTasksError")); // NettyServer nettyServerShutdownError = metricRegistry.counter(MetricRegistry.name(NettyServer.class, "ShutdownError")); nettyServerStartError = metricRegistry.counter(MetricRegistry.name(NettyServer.class, "StartError")); // PublicAccessLogHandler publicAccessLogRequestDisconnectWhileInProgressCount = metricRegistry.counter( MetricRegistry.name(PublicAccessLogHandler.class, "ChannelDisconnectWhileRequestInProgressCount")); publicAccessLogRequestCloseWhileRequestInProgressCount = metricRegistry.counter( MetricRegistry.name(PublicAccessLogHandler.class, "ChannelCloseWhileRequestInProgressCount")); // HealthCheckHandler healthCheckHandlerChannelCloseOnWriteCount = metricRegistry.counter(MetricRegistry.name(HealthCheckHandler.class, "ChannelCloseOnWriteCount")); // Other // NettyRequest contentCopyCount = metricRegistry.counter(MetricRegistry.name(NettyRequest.class, "ContentCopyCount")); digestCalculationTimeInMs = metricRegistry.histogram(MetricRegistry.name(NettyRequest.class, "DigestCalculationTimeInMs")); watermarkOverflowCount = metricRegistry.counter(MetricRegistry.name(NettyRequest.class, "WatermarkOverflowCount")); // NettyMessageProcessor channelReadIntervalInMs = metricRegistry.histogram(MetricRegistry.name(NettyMessageProcessor.class, "ChannelReadIntervalInMs")); idleConnectionCloseCount = metricRegistry.counter(MetricRegistry.name(NettyMessageProcessor.class, "IdleConnectionCloseCount")); processorErrorAfterCloseCount = metricRegistry.counter(MetricRegistry.name(NettyMessageProcessor.class, "ErrorAfterCloseCount")); processorExceptionCaughtCount = metricRegistry.counter(MetricRegistry.name(NettyMessageProcessor.class, "ExceptionCaughtCount")); processorIOExceptionCount = metricRegistry.counter(MetricRegistry.name(NettyMessageProcessor.class, "IOExceptionCount")); processorRestServiceExceptionCount = metricRegistry.counter(MetricRegistry.name(NettyMessageProcessor.class, "RestServiceExceptionCount")); processorThrowableCount = metricRegistry.counter(MetricRegistry.name(NettyMessageProcessor.class, "ThrowableCount")); processorUnknownExceptionCount = metricRegistry.counter(MetricRegistry.name(NettyMessageProcessor.class, "UnknownExceptionCount")); // NettyResponseChannel acceptedCount = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "AcceptedCount")); createdCount = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "CreatedCount")); okCount = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "OkCount")); partialContentCount = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "PartialContentCount")); notModifiedCount = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "NotModifiedCount")); badRequestCount = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "BadRequestCount")); unauthorizedCount = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "UnauthorizedCount")); goneCount = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "GoneCount")); internalServerErrorCount = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "InternalServerErrorCount")); notFoundCount = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "NotFoundCount")); forbiddenCount = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "ForbiddenCount")); proxyAuthRequiredCount = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "ProxyAuthenticationRequiredCount")); rangeNotSatisfiableCount = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "RangeNotSatisfiableCount")); throwableCount = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "ThrowableCount")); unknownResponseStatusCount = metricRegistry.counter(MetricRegistry.name(NettyResponseChannel.class, "UnknownResponseStatusCount")); // NettyServer nettyServerShutdownTimeInMs = metricRegistry.histogram(MetricRegistry.name(NettyServer.class, "ShutdownTimeInMs")); nettyServerStartTimeInMs = metricRegistry.histogram(MetricRegistry.name(NettyServer.class, "StartTimeInMs")); // ConnectionStatsHandler connectionsConnectedCount = metricRegistry.counter(MetricRegistry.name(ConnectionStatsHandler.class, "ConnectionsConnectedCount")); connectionsDisconnectedCount = metricRegistry.counter(MetricRegistry.name(ConnectionStatsHandler.class, "ConnectionsDisconnectedCount")); } /** * Registers the {@link ConnectionStatsHandler} to track open connections * @param openConnectionsCount open connections count to be tracked */ void registerConnectionsStatsHandler(final AtomicLong openConnectionsCount) { Gauge<Long> openConnections = new Gauge<Long>() { @Override public Long getValue() { return openConnectionsCount.get(); } }; metricRegistry.register(MetricRegistry.name(ConnectionStatsHandler.class, "OpenConnections"), openConnections); } }