001/*
002 * ====================================================================
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *   http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied.  See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 * ====================================================================
020 *
021 * This software consists of voluntary contributions made by many
022 * individuals on behalf of the Apache Software Foundation.  For more
023 * information on the Apache Software Foundation, please see
024 * <http://www.apache.org/>.
025 *
026 */
027package org.apache.http.impl.client;
028
029import java.util.concurrent.atomic.AtomicLong;
030
031/**
032 * Collection of different counters used to gather metrics for {@link FutureRequestExecutionService}.
033 */
034public final class FutureRequestExecutionMetrics {
035
036    private final AtomicLong activeConnections = new AtomicLong();
037    private final AtomicLong scheduledConnections = new AtomicLong();
038    private final DurationCounter successfulConnections = new DurationCounter();
039    private final DurationCounter failedConnections = new DurationCounter();
040    private final DurationCounter requests = new DurationCounter();
041    private final DurationCounter tasks = new DurationCounter();
042
043    FutureRequestExecutionMetrics() {
044    }
045
046    AtomicLong getActiveConnections() {
047        return activeConnections;
048    }
049
050    AtomicLong getScheduledConnections() {
051        return scheduledConnections;
052    }
053
054    DurationCounter getSuccessfulConnections() {
055        return successfulConnections;
056    }
057
058    DurationCounter getFailedConnections() {
059        return failedConnections;
060    }
061
062    DurationCounter getRequests() {
063        return requests;
064    }
065
066    DurationCounter getTasks() {
067        return tasks;
068    }
069
070    public long getActiveConnectionCount() {
071        return activeConnections.get();
072    }
073
074    public long getScheduledConnectionCount() {
075        return scheduledConnections.get();
076    }
077
078    public long getSuccessfulConnectionCount() {
079        return successfulConnections.count();
080    }
081
082    public long getSuccessfulConnectionAverageDuration() {
083        return successfulConnections.averageDuration();
084    }
085
086    public long getFailedConnectionCount() {
087        return failedConnections.count();
088    }
089
090    public long getFailedConnectionAverageDuration() {
091        return failedConnections.averageDuration();
092    }
093
094    public long getRequestCount() {
095        return requests.count();
096    }
097
098    public long getRequestAverageDuration() {
099        return requests.averageDuration();
100    }
101
102    public long getTaskCount() {
103        return tasks.count();
104    }
105
106    public long getTaskAverageDuration() {
107        return tasks.averageDuration();
108    }
109
110    @Override
111    public String toString() {
112        final StringBuilder builder = new StringBuilder();
113        builder.append("[activeConnections=").append(activeConnections)
114                .append(", scheduledConnections=").append(scheduledConnections)
115                .append(", successfulConnections=").append(successfulConnections)
116                .append(", failedConnections=").append(failedConnections)
117                .append(", requests=").append(requests)
118                .append(", tasks=").append(tasks)
119                .append("]");
120        return builder.toString();
121    }
122
123    /**
124     * A counter that can measure duration and number of events.
125     */
126    static class DurationCounter {
127
128        private final AtomicLong count = new AtomicLong(0);
129        private final AtomicLong cumulativeDuration = new AtomicLong(0);
130
131        public void increment(final long startTime) {
132            count.incrementAndGet();
133            cumulativeDuration.addAndGet(System.currentTimeMillis() - startTime);
134        }
135
136        public long count() {
137            return count.get();
138        }
139
140        public long averageDuration() {
141            final long counter = count.get();
142            return counter > 0 ? cumulativeDuration.get() / counter : 0;
143        }
144
145        @Override
146        public String toString() {
147            final StringBuilder builder = new StringBuilder();
148            builder.append("[count=").append(count())
149                    .append(", averageDuration=").append(averageDuration())
150                    .append("]");
151            return builder.toString();
152        }
153
154    }
155
156}