/* * Opennaru, Inc. http://www.opennaru.com/ * * Copyright (C) 2014 Opennaru, Inc. and/or its affiliates. * All rights reserved by Opennaru, Inc. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package com.opennaru.khan.session.management; import com.opennaru.khan.counter.*; import com.opennaru.khan.session.manager.KhanSessionManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.management.NotCompliantMBeanException; import javax.management.StandardMBean; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; /** * SessionMonitorMBeanImpl, 세션 정보에 대한 MBean 구현체 * * @author Junshik Jeon([email protected], [email protected]) */ public class SessionMonitorMBeanImpl extends StandardMBean implements SessionMonitorMBean { private static final int DEFAULT_HISTORY_SIZE = 30; private static final int DEFAULT_INTERVAL_SECS = 1; private final KhanSessionManager sessionManager; private final AtomicLong duplicatedLogin; private final Counter duplicatedLoginStatistic; private final SampledStatistic duplicatedLoginSampled; private final AtomicLong sessionsCreated; private final Counter sessionsCreatedStatistic; private final SampledStatistic sessionsCreatedSampled; private final AtomicLong sessionsDestroyed; private final Counter sessionsDestroyedStatistic; private final SampledStatistic sessionsDestroyedSampled; private Logger log = LoggerFactory.getLogger(this.getClass()); private boolean statisticsEnabled = false; private volatile SampledStatisticManager samplingManager; /** * SessionMBeanImpl * * @throws javax.management.NotCompliantMBeanException */ public SessionMonitorMBeanImpl(KhanSessionManager sessionManager) throws NotCompliantMBeanException { super(SessionMonitorMBean.class); this.sessionManager = sessionManager; samplingManager = new SampledStatisticManager(); sessionsCreatedStatistic = new SimpleCounterImpl(); sessionsCreatedSampled = createSampledStatistic(sessionsCreatedStatistic); sessionsCreated = new AtomicLong(); duplicatedLoginStatistic = new SimpleCounterImpl(); duplicatedLoginSampled = createSampledStatistic(duplicatedLoginStatistic); duplicatedLogin = new AtomicLong(); sessionsDestroyedStatistic = new SimpleCounterImpl(); sessionsDestroyedSampled = createSampledStatistic(sessionsDestroyedStatistic); sessionsDestroyed = new AtomicLong(); if (log.isDebugEnabled()) { log.debug("Session Monitor MBean Constructed"); } } public void shutdown() { this.samplingManager.shutdown(); } private SampledStatistic createSampledStatistic(Statistic statistic) { return samplingManager.createSampler(statistic, DEFAULT_INTERVAL_SECS, DEFAULT_HISTORY_SIZE, true); } public String getAppName() { return sessionManager.getAppName(); } public synchronized boolean isStatisticsEnabled() { return statisticsEnabled; } /** * Set Statistics Enabled * * @param enabled */ public void setStatisticsEnabled(boolean enabled) { boolean oldValue = isStatisticsEnabled(); if (oldValue != enabled) { synchronized (this) { this.statisticsEnabled = enabled; if (enabled) { reset(); } } } } /** * Increase Duplicate Login Count */ public void duplicatedLogin() { if (isStatisticsEnabled()) { synchronized (this) { duplicatedLogin.incrementAndGet(); duplicatedLoginStatistic.increment(); } } } /** * Get duplicate login count * @return */ public long getDuplicatedLoginCount() { return duplicatedLogin.get(); } /** * Duplicated Login count sampling * @return */ public long getDuplicatedLoginRateMostRecentSample() { return duplicatedLoginSampled.getMostRecentSample().getValue(); } /** * Get created Session count * @return */ public long getCreatedSessionCount() { return sessionsCreated.get(); } /** * Get created session count sampling * @return */ public long getCreatedSessionRateMostRecentSample() { return sessionsCreatedSampled.getMostRecentSample().getValue(); } /** * Get destroyed session count * @return */ public long getDestroyedSessionCount() { return sessionsDestroyed.get(); } /** * Get destroyed session count sampling * @return */ public long getDestroyedSessionRateMostRecentSample() { return sessionsDestroyedSampled.getMostRecentSample().getValue(); } /** * Get active session count * @return */ public synchronized long getActiveSessionCount() { return sessionManager.getSessionIdCount(); } /** * Get sampling data : * Session created count per seconds * Session destroyed count per seconds * Duplicated login count per seconds * @return */ public Map<String, Long> getPerformanceMetrics() { Map<String, Long> result = new HashMap<String, Long>(); result.put("SessionsCreatedPerSecond", getCreatedSessionRateMostRecentSample()); result.put("SessionsDestroyedPerSecond", getDestroyedSessionRateMostRecentSample()); result.put("DuplicatedLoginPerSecond", getDuplicatedLoginRateMostRecentSample()); return result; } /** * Reset all statistics */ public synchronized void reset() { sessionsCreatedStatistic.getAndReset(); sessionsCreated.set(0); sessionsDestroyedStatistic.getAndReset(); sessionsDestroyed.set(0); duplicatedLoginStatistic.getAndReset(); duplicatedLogin.set(0); } /** * Increase session created count */ public void sessionCreated() { if (isStatisticsEnabled()) { synchronized (this) { sessionsCreated.incrementAndGet(); sessionsCreatedStatistic.increment(); } } } /** * Increase session destroyed count */ public void sessionDestroyed() { if (isStatisticsEnabled()) { synchronized (this) { sessionsDestroyed.incrementAndGet(); sessionsDestroyedStatistic.increment(); } } } /** * Get list of session id * @param batchSize * @return */ public ArrayList<String> getSessionIds(int batchSize) { return sessionManager.getSessionIds(batchSize); } /** * get session attributes * @param sessionId * @return */ public Map<String, Object> getSessionAttributes(String sessionId) { return sessionManager.getSessionAttributes(sessionId); } /** * Infinispan에 저장된 Session의 총 갯수 * 세션은 메타데이터와 Attribute 두 개의 키로 나누어 저장되어 / 2 값이 세션의 총 갯수 * @return */ public int getTotalSessionCount() { return sessionManager.getTotalSessionCount(); } /** * get session id count * @return */ public long getSessionIdCount() { return sessionManager.getSessionIdCount(); } /** * get memory size of sessions * @return */ public long getMemorySize() { return sessionManager.getSessionMemorySize(); } /** * Get occupied memory size of sessionId * @param sessionId * @return */ public long getMemorySize(String sessionId) { return sessionManager.getSessionMemorySize(sessionId); } }