/* * Copyright 2015-2016 http://hsweb.me * * 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 org.hsweb.web.controller.monitor; import org.hsweb.web.bean.po.user.User; import org.hsweb.web.core.authorize.annotation.Authorize; import org.hsweb.web.core.cache.monitor.MonitorCache; import org.hsweb.web.core.exception.NotFoundException; import org.hsweb.web.core.logger.annotation.AccessLogger; import org.hsweb.web.core.message.ResponseMessage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import java.util.*; /** * 缓存监控控制器,用于管理缓存,监控等操作 */ @RestController @RequestMapping("/monitor") @Authorize(module = "monitor-cache") @AccessLogger("缓存监控") public class CacheMonitorController { @Autowired(required = false) private Map<String, CacheManager> cacheManagerMap = new LinkedHashMap<>(); @RequestMapping(value = "/cache/managers", method = RequestMethod.GET) @AccessLogger("获取管理器") public ResponseMessage getManagerList() { return ResponseMessage.ok(cacheManagerMap.keySet()); } @RequestMapping(value = "/caches", method = RequestMethod.GET) @AccessLogger("获取缓存信息") public ResponseMessage getCacheTreeList() { List<Map<String, Object>> managers = new ArrayList<>(); cacheManagerMap.entrySet().forEach(entry -> { Map<String, Object> manager = new LinkedHashMap<>(); manager.put("name", entry.getKey()); manager.put("size", getTimes(entry.getValue(), MonitorCache::size)); manager.put("totalTimes", getTimes(entry.getValue(), MonitorCache::getTotalTimes)); manager.put("hitTimes", getTimes(entry.getValue(), MonitorCache::getHitTimes)); manager.put("putTimes", getTimes(entry.getValue(), MonitorCache::getPutTimes)); List<Map<String, Object>> caches = new LinkedList<>(); manager.put("caches", caches); entry.getValue().getCacheNames().forEach(cacheName -> { Map<String, Object> cacheData = new LinkedHashMap<>(); cacheData.put("name", cacheName); Cache cache = entry.getValue().getCache(cacheName); if (cache instanceof MonitorCache) { MonitorCache monitorCache = ((MonitorCache) cache); cacheData.put("size", monitorCache.size()); cacheData.put("totalTimes", monitorCache.getTotalTimes()); cacheData.put("hitTimes", monitorCache.getHitTimes()); cacheData.put("putTimes", monitorCache.getPutTimes()); } caches.add(cacheData); }); managers.add(manager); }); return ResponseMessage.ok(managers).onlyData(); } @RequestMapping(value = "/cache/{name:.+}", method = RequestMethod.GET) @AccessLogger("获取所有名称") public ResponseMessage getNameList(@PathVariable("name") String name) { CacheManager cacheManager = cacheManagerMap.get(name); if (cacheManager != null) { return ResponseMessage.ok(cacheManager.getCacheNames()); } throw new NotFoundException("缓存不存在"); } @AccessLogger("获取值") @RequestMapping(value = "/cache/{managerName}/{cacheName:.+}/{key:.+}", method = RequestMethod.GET) public ResponseMessage getValue(@PathVariable("managerName") String managerName, @PathVariable("cacheName") String cacheName, @PathVariable("key") String key) { Cache.ValueWrapper val = getCache(managerName, cacheName).get(key); if (val != null) return ResponseMessage.ok(val.get()) .exclude(User.class, "password", "modules", "userRoles"); throw new NotFoundException("值不存在"); } @RequestMapping(value = "/cache/{managerName}/{cacheName}/{key:.+}", method = RequestMethod.DELETE) @Authorize(action = "D") @AccessLogger("删除指定key的值") public ResponseMessage getEvict(@PathVariable("managerName") String managerName, @PathVariable("cacheName") String cacheName, @PathVariable("key") String key) { getCache(managerName, cacheName).evict(key); return ResponseMessage.ok(); } @RequestMapping(value = "/cache/{managerName}/{cacheName:.+}", method = RequestMethod.DELETE) @Authorize(action = "D") @AccessLogger("清空") public ResponseMessage clearEvict(@PathVariable("managerName") String managerName, @PathVariable("cacheName") String cacheName) { getCache(managerName, cacheName).clear(); return ResponseMessage.ok(); } @RequestMapping(value = "/cache/{managerName}/{cacheName:.+}", method = RequestMethod.GET) @AccessLogger("获取键列表") public ResponseMessage getKeySet(@PathVariable("managerName") String managerName, @PathVariable("cacheName") String cacheName) { return ResponseMessage.ok(getMonitorCache(managerName, cacheName).keySet()); } @AccessLogger("获取缓存命中次数") @RequestMapping(value = "/cache-hits/{managerName}/{cacheName:.+}", method = RequestMethod.GET) public ResponseMessage getHitTimes(@PathVariable("managerName") String managerName, @PathVariable("cacheName") String cacheName) { return ResponseMessage.ok(getMonitorCache(managerName, cacheName).getHitTimes()); } @AccessLogger("获取缓存更新次数") @RequestMapping(value = "/cache-puts/{managerName}/{cacheName:.+}", method = RequestMethod.GET) public ResponseMessage getPutTimes(@PathVariable("managerName") String managerName, @PathVariable("cacheName") String cacheName) { return ResponseMessage.ok(getMonitorCache(managerName, cacheName).getPutTimes()); } @AccessLogger("获取缓存数量") @RequestMapping(value = "/cache-size/{managerName}/{cacheName:.+}", method = RequestMethod.GET) public ResponseMessage getSize(@PathVariable("managerName") String managerName, @PathVariable("cacheName") String cacheName) { return ResponseMessage.ok(getMonitorCache(managerName, cacheName).size()); } @AccessLogger("获取缓存获取次数") @RequestMapping(value = "/cache-total/{managerName}/{cacheName:.+}", method = RequestMethod.GET) public ResponseMessage getTotalTimes(@PathVariable("managerName") String managerName, @PathVariable("cacheName") String cacheName) { return ResponseMessage.ok(getMonitorCache(managerName, cacheName).getTotalTimes()); } @AccessLogger("获取缓存命中总次数") @RequestMapping(value = "/cache-hits", method = RequestMethod.GET) public ResponseMessage getHitTimes() { return ResponseMessage.ok(getTimes(MonitorCache::getHitTimes)); } @AccessLogger("获取缓存更新次数") @RequestMapping(value = "/cache-puts", method = RequestMethod.GET) public ResponseMessage getPutTimes() { return ResponseMessage.ok(getTimes(MonitorCache::getPutTimes)); } @AccessLogger("获取缓存获取次数") @RequestMapping(value = "/cache-total", method = RequestMethod.GET) public ResponseMessage getTotalTimes() { return ResponseMessage.ok(getTimes(MonitorCache::getTotalTimes)); } @AccessLogger("获取缓存数量") @RequestMapping(value = "/cache-size", method = RequestMethod.GET) public ResponseMessage getSize() { return ResponseMessage.ok(getTimes(MonitorCache::size)); } protected long getTimes(TimesGetter getter) { long times = cacheManagerMap.values().stream() .mapToLong(cacheManager -> getTimes(cacheManager, getter)) .reduce(Math::addExact).orElse(0); return times; } protected long getTimes(CacheManager cacheManager, TimesGetter getter) { long times = cacheManager.getCacheNames().parallelStream() .map(name -> cacheManager.getCache(name)) .filter(cache -> cache instanceof MonitorCache) .map(cache -> (MonitorCache) cache) .mapToLong(getter::get) .reduce(Math::addExact).orElse(0); return times; } protected MonitorCache getMonitorCache(String managerName, String cacheName) { Cache cache = getCache(managerName, cacheName); if (cache instanceof MonitorCache) { return ((MonitorCache) cache); } throw new NotFoundException("缓存不支持监控"); } protected Cache getCache(String managerName, String cacheName) { CacheManager cacheManager = cacheManagerMap.get(managerName); if (cacheManager != null) { Cache cache = cacheManager.getCache(cacheName); if (cache != null) { return cache; } } throw new NotFoundException("缓存不存在"); } interface TimesGetter { long get(MonitorCache cache); } }