/*
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Jasig 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 the following location:
*
* 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 org.jasig.cas.monitor;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.validation.constraints.NotNull;
import net.spy.memcached.MemcachedClientIF;
/**
* Monitors the memcached hosts known to an instance of {@link net.spy.memcached.MemcachedClientIF}.
*
* @author Marvin S. Addison
* @since 3.5.1
*/
public class MemcachedMonitor extends AbstractCacheMonitor {
@NotNull
private final MemcachedClientIF memcachedClient;
/**
* Creates a new monitor that observes the given memcached client.
*
* @param client Memcached client.
*/
public MemcachedMonitor(final MemcachedClientIF client) {
this.memcachedClient = client;
}
/**
* Supersede the default cache status algorithm by considering unavailable memcached nodes above cache statistics.
* If all nodes are unavailable, raise an error; if one or more nodes are unavailable, raise a warning; otherwise
* delegate to examination of cache statistics.
*
* @return Cache status descriptor.
*/
public CacheStatus observe() {
if (memcachedClient.getAvailableServers().size() == 0) {
return new CacheStatus(StatusCode.ERROR, "No memcached servers available.");
}
final Collection<SocketAddress> unavailableList = memcachedClient.getUnavailableServers();
final CacheStatus status;
if (unavailableList.size() > 0) {
final String description = "One or more memcached servers is unavailable: " + unavailableList;
status = new CacheStatus(StatusCode.WARN, description, getStatistics());
} else {
status = super.observe();
}
return status;
}
/**
* Get cache statistics for all memcached hosts known to {@link MemcachedClientIF}.
*
* @return Statistics for all available hosts.
*/
protected CacheStatistics[] getStatistics() {
long evictions;
long size;
long capacity;
String name;
Map<String, String> statsMap;
final Map<SocketAddress, Map<String, String>> allStats = memcachedClient.getStats();
final List<CacheStatistics> statsList = new ArrayList<CacheStatistics>();
for (final SocketAddress address : allStats.keySet()) {
statsMap = allStats.get(address);
if (statsMap.size() > 0) {
size = Long.parseLong(statsMap.get("bytes"));
capacity = Long.parseLong(statsMap.get("limit_maxbytes"));
evictions = Long.parseLong(statsMap.get("evictions"));
if (address instanceof InetSocketAddress) {
name = ((InetSocketAddress) address).getHostName();
} else {
name = address.toString();
}
statsList.add(new SimpleCacheStatistics(size, capacity, evictions, name));
}
}
return statsList.toArray(new CacheStatistics[statsList.size()]);
}
}