/* * Copyright 2008-2014 LinkedIn, Inc * * 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 voldemort.store.quota; import java.util.concurrent.atomic.AtomicLong; import voldemort.annotations.jmx.JmxGetter; import voldemort.store.stats.SimpleCounter; import voldemort.store.stats.Tracked; public class QuotaLimitStats { private static final int QUOTA_STATS_RESET_INTERVAL_MS = 60000; private final AtomicLong rateLimitedGets; private final AtomicLong rateLimitedPuts; private final AtomicLong rateLimitedGetAlls; private final AtomicLong rateLimitedDeletes; private final SimpleCounter pctGetQuotaUsed; private final SimpleCounter pctPutQuotaUsed; private final SimpleCounter pctGetAllQuotaUsed; private final SimpleCounter pctDeleteQuotaUsed; private final QuotaLimitStats parent; public QuotaLimitStats(QuotaLimitStats parent) { this(parent, QUOTA_STATS_RESET_INTERVAL_MS); } public QuotaLimitStats(QuotaLimitStats parent, long resetIntervalMs) { rateLimitedGets = new AtomicLong(); rateLimitedPuts = new AtomicLong(); rateLimitedGetAlls = new AtomicLong(); rateLimitedDeletes = new AtomicLong(); pctGetQuotaUsed = new SimpleCounter(resetIntervalMs); pctPutQuotaUsed = new SimpleCounter(resetIntervalMs); pctDeleteQuotaUsed = new SimpleCounter(resetIntervalMs); pctGetAllQuotaUsed = new SimpleCounter(resetIntervalMs); this.parent = parent; } private void reportRateLimitedGet() { rateLimitedGets.incrementAndGet(); if(parent != null) { parent.reportRateLimitedGet(); } } private void reportRateLimitedPut() { rateLimitedPuts.incrementAndGet(); if(parent != null) { parent.reportRateLimitedPut(); } } private void reportRateLimitedGetAll() { rateLimitedGetAlls.incrementAndGet(); if(parent != null) { parent.reportRateLimitedGetAll(); } } private void reportRateLimitedDelete() { rateLimitedDeletes.incrementAndGet(); if(parent != null) { parent.reportRateLimitedDelete(); } } public void reportRateLimitedOp(Tracked op) { if(Tracked.GET == op) { reportRateLimitedGet(); } else if(Tracked.PUT == op) { reportRateLimitedPut(); } else if(Tracked.GET_ALL == op) { reportRateLimitedGetAll(); } else if(Tracked.DELETE == op) { reportRateLimitedDelete(); } } private void reportGetQuotaUsedPct(long pctUsed) { pctGetQuotaUsed.count(pctUsed); if(parent != null) { parent.reportGetQuotaUsedPct(pctUsed); } } private void reportPutQuotaUsedPct(long pctUsed) { pctPutQuotaUsed.count(pctUsed); if(parent != null) { parent.reportPutQuotaUsedPct(pctUsed); } } private void reportGetAllQuotaUsedPct(long pctUsed) { pctGetAllQuotaUsed.count(pctUsed); if(parent != null) { parent.reportGetAllQuotaUsedPct(pctUsed); } } private void reportDeleteQuotaUsedPct(long pctUsed) { pctDeleteQuotaUsed.count(pctUsed); if(parent != null) { parent.reportDeleteQuotaUsedPct(pctUsed); } } public void reportQuotaUsed(Tracked op, long pctUsed) { if(Tracked.GET == op) { reportGetQuotaUsedPct(pctUsed); } else if(Tracked.PUT == op) { reportPutQuotaUsedPct(pctUsed); } else if(Tracked.GET_ALL == op) { reportGetAllQuotaUsedPct(pctUsed); } else if(Tracked.DELETE == op) { reportDeleteQuotaUsedPct(pctUsed); } } @JmxGetter(name = "rateLimitedGets", description = "Counter of Number of GETs rate limited") public long getRateLimitedGets() { return rateLimitedGets.get(); } @JmxGetter(name = "rateLimitedPuts", description = "Counter of Number of PUTs rate limited") public long getRateLimitedPuts() { return rateLimitedPuts.get(); } @JmxGetter(name = "rateLimitedGetAlls", description = "Counter of Number of GET_ALLs rate limited") public long getRateLimitedGetAlls() { return rateLimitedGetAlls.get(); } @JmxGetter(name = "rateLimitedDeletes", description = "Counter of Number of DELETEs rate limited") public long getRateLimitedDeletes() { return rateLimitedDeletes.get(); } /** * Defensive checks against measured usage pct * * @param pctUsedVal * @return */ private long computePctUsed(Double pctUsedVal) { if(pctUsedVal <= 1.0) { return 0; } else { return Math.round(pctUsedVal); } } @JmxGetter(name = "GetQuotaUsedPct", description = "Average usage of Get quota in the last 60 secs") public long getQuotaPctUsedGet() { return computePctUsed(pctGetQuotaUsed.getAvgEventValue()); } @JmxGetter(name = "GetAllQuotaUsedPct", description = "Average usage of GetAll quota in the last 60 secs") public long getQuotaPctUsedGetAll() { return computePctUsed(pctGetAllQuotaUsed.getAvgEventValue()); } @JmxGetter(name = "PutQuotaUsedPct", description = "Average usage of Put quota in the last 60 secs") public long getQuotaPctUsedPut() { return computePctUsed(pctPutQuotaUsed.getAvgEventValue()); } @JmxGetter(name = "DeleteQuotaUsedPct", description = "Average usage of Delete quota in the last 60 secs") public long getQuotaPctUsedDelete() { return computePctUsed(pctDeleteQuotaUsed.getAvgEventValue()); } }