RedisProviderApiStats.java
/*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.facebook.presto.statistic;
import com.facebook.airlift.log.Logger;
import com.facebook.airlift.stats.CounterStat;
import com.facebook.airlift.stats.TimeStat;
import io.lettuce.core.RedisException;
import org.weakref.jmx.Managed;
import org.weakref.jmx.Nested;
import javax.annotation.concurrent.ThreadSafe;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeoutException;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@ThreadSafe
public class RedisProviderApiStats
{
private static final Logger log = Logger.get(RedisProviderApiStats.class);
enum Operation
{
FetchStats,
PutStats
}
private final TimeStat fetchTime = new TimeStat(MILLISECONDS);
private final TimeStat putTime = new TimeStat(MILLISECONDS);
private final CounterStat putStatRequest = new CounterStat();
private final CounterStat putStatGenericFailure = new CounterStat();
private final CounterStat putStatTimeoutFailure = new CounterStat();
private final CounterStat putStatRedisFailure = new CounterStat();
private final CounterStat fetchStatRequest = new CounterStat();
private final CounterStat fetchStatGenericFailure = new CounterStat();
private final CounterStat fetchStatTimeoutFailure = new CounterStat();
private final CounterStat fetchStatRedisFailure = new CounterStat();
public TimeStat getTime(Operation operation)
{
return (operation == Operation.FetchStats) ? fetchTime : putTime;
}
public CounterStat getStatRequest(Operation operation)
{
return (operation == Operation.FetchStats) ? fetchStatRequest : putStatRequest;
}
public CounterStat getGenericFailureStat(Operation operation)
{
return (operation == Operation.FetchStats) ? fetchStatGenericFailure : putStatGenericFailure;
}
public CounterStat getTimeoutFailureStat(Operation operation)
{
return (operation == Operation.FetchStats) ? fetchStatTimeoutFailure : putStatTimeoutFailure;
}
public CounterStat getRedisFailureStat(Operation operation)
{
return (operation == Operation.FetchStats) ? fetchStatRedisFailure : putStatRedisFailure;
}
public <V> V execute(Callable<V> callable, Operation operation)
{
try {
return wrap(callable, operation).call();
}
catch (TimeoutException e) {
getTimeoutFailureStat(operation).update(1);
log.error(String.format("Redis Stat Provider Error:" +
" Request %s failed with Timeout %s", operation, (e.getMessage() == null) ? "" : e.getMessage()));
}
catch (RedisException e) {
getRedisFailureStat(operation).update(1);
log.error(String.format("Redis Stat Provider Error:" +
" Request %s failed with RedisException %s", operation, (e.getMessage() == null) ? "" : e.getMessage()));
}
catch (Exception e) {
getGenericFailureStat(operation).update(1);
log.error(String.format("Redis Stat Provider Error:" +
" Request %s failed with GenericException %s", operation, (e.getMessage() == null) ? "" : e.getMessage()));
}
return null;
}
public <V> Callable<V> wrap(Callable<V> callable, Operation operation)
{
return () -> {
try (TimeStat.BlockTimer ignored = getTime(operation).time()) {
getStatRequest(operation).update(1);
return callable.call();
}
catch (Exception e) {
// Will be caught outside
throw e;
}
};
}
@Managed
@Nested
public CounterStat getPutStatTimeoutFailure()
{
return putStatTimeoutFailure;
}
@Managed
@Nested
public CounterStat getPutStatGenericFailure()
{
return putStatGenericFailure;
}
@Managed
@Nested
public CounterStat getPutStatRequest()
{
return putStatRequest;
}
@Managed
@Nested
public CounterStat getPutStatRedisFailure()
{
return putStatRedisFailure;
}
@Managed
@Nested
public CounterStat getFetchStatRedisFailure()
{
return fetchStatRedisFailure;
}
@Managed
@Nested
public CounterStat getFetchStatRequest()
{
return fetchStatRequest;
}
@Managed
@Nested
public CounterStat getFetchStatGenericFailure()
{
return fetchStatGenericFailure;
}
@Managed
@Nested
public CounterStat getFetchStatTimeoutFailure()
{
return fetchStatTimeoutFailure;
}
@Managed
@Nested
public TimeStat getFetchTime()
{
return fetchTime;
}
@Managed
@Nested
public TimeStat getPutTime()
{
return putTime;
}
}