/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ // Portions Copyright [2016] [Payara Foundation and/or its affiliates] package com.sun.enterprise.v3.services.impl.monitor; import com.sun.enterprise.v3.services.impl.monitor.probes.ConnectionQueueProbeProvider; import com.sun.enterprise.v3.services.impl.monitor.probes.FileCacheProbeProvider; import com.sun.enterprise.v3.services.impl.monitor.probes.KeepAliveProbeProvider; import com.sun.enterprise.v3.services.impl.monitor.probes.ThreadPoolProbeProvider; import com.sun.enterprise.v3.services.impl.monitor.stats.ConnectionQueueStatsProvider; import com.sun.enterprise.v3.services.impl.monitor.stats.ConnectionQueueStatsProviderGlobal; import com.sun.enterprise.v3.services.impl.monitor.stats.FileCacheStatsProvider; import com.sun.enterprise.v3.services.impl.monitor.stats.FileCacheStatsProviderGlobal; import com.sun.enterprise.v3.services.impl.monitor.stats.KeepAliveStatsProvider; import com.sun.enterprise.v3.services.impl.monitor.stats.KeepAliveStatsProviderGlobal; import com.sun.enterprise.v3.services.impl.monitor.stats.ThreadPoolStatsProvider; import com.sun.enterprise.v3.services.impl.monitor.stats.ThreadPoolStatsProviderGlobal; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.glassfish.external.probe.provider.PluginPoint; import org.glassfish.external.probe.provider.StatsProviderManager; import org.glassfish.grizzly.threadpool.ThreadPoolConfig; /** * Grizzly monitoring manager, which is responsible for registering, unregistering * Grizzly statistics probes. * * @author Alexey Stashok */ public class GrizzlyMonitoring { private static final String CONFIG_ELEMENT = "http-service"; // network-listener->thread-pool-stats Map private final Map<String, ThreadPoolStatsProvider> threadPoolStatsProvidersMap = new ConcurrentHashMap<String, ThreadPoolStatsProvider>(); // network-listener->file-cache-stats Map private final Map<String, FileCacheStatsProvider> fileCacheStatsProvidersMap = new ConcurrentHashMap<String, FileCacheStatsProvider>(); // network-listener->keep-alive-stats Map private final Map<String, KeepAliveStatsProvider> keepAliveStatsProvidersMap = new ConcurrentHashMap<String, KeepAliveStatsProvider>(); // network-listener->connection-queue-stats Map private final Map<String, ConnectionQueueStatsProvider> connectionQueueStatsProvidersMap = new ConcurrentHashMap<String, ConnectionQueueStatsProvider>(); // thread-pool emitter probe private final ThreadPoolProbeProvider threadPoolProbeProvider; // file-cache emitter probe private final FileCacheProbeProvider fileCacheProbeProvider; // keep-alive emitter probe private final KeepAliveProbeProvider keepAliveProbeProvider; // connection queue emitter probe private final ConnectionQueueProbeProvider connectionQueueProbeProvider; public GrizzlyMonitoring() { threadPoolProbeProvider = new ThreadPoolProbeProvider(); fileCacheProbeProvider = new FileCacheProbeProvider(); keepAliveProbeProvider = new KeepAliveProbeProvider(); connectionQueueProbeProvider = new ConnectionQueueProbeProvider(); } /** * Get thread-pool probe provider * * @return thread-pool probe provider */ public ThreadPoolProbeProvider getThreadPoolProbeProvider() { return threadPoolProbeProvider; } /** * Get file-cache probe provider * * @return file-cache probe provider */ public FileCacheProbeProvider getFileCacheProbeProvider() { return fileCacheProbeProvider; } /** * Get keep-alive probe provider * * @return keep-alive probe provider */ public KeepAliveProbeProvider getKeepAliveProbeProvider() { return keepAliveProbeProvider; } /** * Get connection queue probe provider * * @return connection queue probe provider */ public ConnectionQueueProbeProvider getConnectionQueueProbeProvider() { return connectionQueueProbeProvider; } /** * Register thread-pool statistics provider for a network listener * * @param name network listener name */ public void registerThreadPoolStatsProvider(String name) { ThreadPoolStatsProvider threadPoolStatsProvider = new ThreadPoolStatsProvider(name); ThreadPoolStatsProvider oldthreadPoolStatsProvider = threadPoolStatsProvidersMap.put(name, threadPoolStatsProvider); if (oldthreadPoolStatsProvider != null) { StatsProviderManager.unregister(oldthreadPoolStatsProvider); } StatsProviderManager.register(CONFIG_ELEMENT, PluginPoint.SERVER, subtreePrefix(name) + "/thread-pool", threadPoolStatsProvider); updateGlobalThreadPoolStatsProvider(); } /** * Unregister thread-pool statistics provider for a network listener * * @param name network listener name */ public void unregisterThreadPoolStatsProvider(String name) { final ThreadPoolStatsProvider threadPoolStatsProvider = threadPoolStatsProvidersMap.remove(name); if (threadPoolStatsProvider != null) { StatsProviderManager.unregister(threadPoolStatsProvider); updateGlobalThreadPoolStatsProvider(); } } /** * Updates the global thread pool stats provider with the most current * total values. */ private void updateGlobalThreadPoolStatsProvider() { final ThreadPoolStatsProvider globalThreadPoolStatsProvider = threadPoolStatsProvidersMap.get(""); // Exit method if global stats provider not registered if (globalThreadPoolStatsProvider == null) { return; } int coreThreadTotal = 0; int maxThreadTotal = 0; // If multiple listeners use the same thread pool, we don't want to // count the threads twice, so we'll store the names of those we've // already counted in here List<String> countedThreadPoolNames = new ArrayList<>(); // Calculate the totals for each of the metrics for (Map.Entry<String, ThreadPoolStatsProvider> threadPoolStatsProvider : threadPoolStatsProvidersMap.entrySet()) { if (!threadPoolStatsProvider.getKey().equals("")) { // Get the pool config so we can check the thread pool name ThreadPoolConfig threadPoolConfig = (ThreadPoolConfig) threadPoolStatsProvider.getValue().getStatsObject(); if (threadPoolConfig != null) { String threadPoolName = threadPoolConfig.getPoolName(); // Check we haven't already counted the threads in this // thread pool if (!countedThreadPoolNames.contains(threadPoolName)) { // Safe to cast from long to int, as the values cannot // actually be higher than max int. coreThreadTotal += (int) (long) threadPoolStatsProvider .getValue().getCoreThreadsCount().getCount(); maxThreadTotal += (int) (long) threadPoolStatsProvider .getValue().getMaxThreadsCount().getCount(); // Add to the list of counted thread pools so we don't // count the threads twice countedThreadPoolNames.add(threadPoolName); } } } } // Now that we've calculated the global core and max values, set them globalThreadPoolStatsProvider.setCoreThreadsEvent("", "", coreThreadTotal); globalThreadPoolStatsProvider.setMaxThreadsEvent("", "", maxThreadTotal); } /** * Register keep-alive statistics provider for a network listener * * @param name network listener name */ public void registerKeepAliveStatsProvider(String name) { KeepAliveStatsProvider keepAliveStatsProvider = new KeepAliveStatsProvider(name); KeepAliveStatsProvider oldKeepAliveStatsProvider = keepAliveStatsProvidersMap.put(name, keepAliveStatsProvider); if (oldKeepAliveStatsProvider != null) { StatsProviderManager.unregister(oldKeepAliveStatsProvider); } StatsProviderManager.register(CONFIG_ELEMENT, PluginPoint.SERVER, subtreePrefix(name) + "/keep-alive", keepAliveStatsProvider); } /** * Unregister keep-alive statistics provider for a network listener * * @param name network listener name */ public void unregisterKeepAliveStatsProvider(String name) { final KeepAliveStatsProvider keepAliveStatsProvider = keepAliveStatsProvidersMap.remove(name); if (keepAliveStatsProvider != null) { StatsProviderManager.unregister(keepAliveStatsProvider); } } /** * Register file-cache statistics provider for a network listener * * @param name network listener name */ public void registerFileCacheStatsProvider(String name) { FileCacheStatsProvider fileCacheStatsProvider = new FileCacheStatsProvider(name); FileCacheStatsProvider oldFileCacheStatsProvider = fileCacheStatsProvidersMap.put(name, fileCacheStatsProvider); if (oldFileCacheStatsProvider != null) { StatsProviderManager.unregister(oldFileCacheStatsProvider); } StatsProviderManager.register(CONFIG_ELEMENT, PluginPoint.SERVER, subtreePrefix(name) + "/file-cache", fileCacheStatsProvider); } /** * Unregister file-cache statistics provider for a network listener * * @param name network listener name */ public void unregisterFileCacheStatsProvider(String name) { final FileCacheStatsProvider fileCacheStatsProvider = fileCacheStatsProvidersMap.remove(name); if (fileCacheStatsProvider != null) { StatsProviderManager.unregister(fileCacheStatsProvider); } } /** * Register connection queue statistics provider for a network listener * * @param name network listener name */ public void registerConnectionQueueStatsProvider(String name) { ConnectionQueueStatsProvider connectionQueueStatsProvider = new ConnectionQueueStatsProvider(name); ConnectionQueueStatsProvider oldConnectionQueueStatsProvider = connectionQueueStatsProvidersMap.put(name, connectionQueueStatsProvider); if (oldConnectionQueueStatsProvider != null) { StatsProviderManager.unregister(oldConnectionQueueStatsProvider); } StatsProviderManager.register(CONFIG_ELEMENT, PluginPoint.SERVER, subtreePrefix(name) + "/connection-queue", connectionQueueStatsProvider); } /** * Unregister connection queue statistics provider for a network listener * * @param name network listener name */ public void unregisterConnectionQueueStatsProvider(String name) { final ConnectionQueueStatsProvider connectionQueueStatsProvider = connectionQueueStatsProvidersMap.remove(name); if (connectionQueueStatsProvider != null) { StatsProviderManager.unregister(connectionQueueStatsProvider); } } /** * Register server wide thread-pool statistics provider */ public void registerThreadPoolStatsProviderGlobal(String name) { ThreadPoolStatsProvider threadPoolStatsProvider = new ThreadPoolStatsProviderGlobal(name); ThreadPoolStatsProvider oldthreadPoolStatsProvider = threadPoolStatsProvidersMap.put(name, threadPoolStatsProvider); if (oldthreadPoolStatsProvider != null) { StatsProviderManager.unregister(oldthreadPoolStatsProvider); } StatsProviderManager.register(CONFIG_ELEMENT, PluginPoint.SERVER, subtreePrefix(name) + "/global-thread-pool-stats", threadPoolStatsProvider); updateGlobalThreadPoolStatsProvider(); } /** * Unregister server wide thread-pool statistics provider */ public void unregisterThreadPoolStatsProviderGlobal(String name) { final ThreadPoolStatsProvider threadPoolStatsProvider = threadPoolStatsProvidersMap.remove(name); if (threadPoolStatsProvider != null) { StatsProviderManager.unregister(threadPoolStatsProvider); } } /** * Register server wide keep-alive statistics provider for a network listener */ public void registerKeepAliveStatsProviderGlobal(String name) { KeepAliveStatsProvider keepAliveStatsProvider = new KeepAliveStatsProviderGlobal(name); KeepAliveStatsProvider oldKeepAliveStatsProvider = keepAliveStatsProvidersMap.put(name, keepAliveStatsProvider); if (oldKeepAliveStatsProvider != null) { StatsProviderManager.unregister(oldKeepAliveStatsProvider); } StatsProviderManager.register(CONFIG_ELEMENT, PluginPoint.SERVER, subtreePrefix(name) + "/keep-alive", keepAliveStatsProvider); } /** * Unregister server wide keep-alive statistics provider */ public void unregisterKeepAliveStatsProviderGlobal(String name) { final KeepAliveStatsProvider keepAliveStatsProvider = keepAliveStatsProvidersMap.remove(name); if (keepAliveStatsProvider != null) { StatsProviderManager.unregister(keepAliveStatsProvider); } } /** * Register server wide file-cache statistics provider for a network listener */ public void registerFileCacheStatsProviderGlobal(String name) { FileCacheStatsProvider fileCacheStatsProvider = new FileCacheStatsProviderGlobal(name); FileCacheStatsProvider oldFileCacheStatsProvider = fileCacheStatsProvidersMap.put(name, fileCacheStatsProvider); if (oldFileCacheStatsProvider != null) { StatsProviderManager.unregister(oldFileCacheStatsProvider); } StatsProviderManager.register(CONFIG_ELEMENT, PluginPoint.SERVER, subtreePrefix(name) + "/file-cache", fileCacheStatsProvider); } /** * Unregister serve wide file-cache statistics provider for a network listener */ public void unregisterFileCacheStatsProviderGlobal(String name) { final FileCacheStatsProvider fileCacheStatsProvider = fileCacheStatsProvidersMap.remove(name); if (fileCacheStatsProvider != null) { StatsProviderManager.unregister(fileCacheStatsProvider); } } /** * Register server wide connection queue statistics provider for a network listener */ public void registerConnectionQueueStatsProviderGlobal(String name) { ConnectionQueueStatsProvider connectionQueueStatsProvider = new ConnectionQueueStatsProviderGlobal(name); ConnectionQueueStatsProvider oldConnectionQueueStatsProvider = connectionQueueStatsProvidersMap.put(name, connectionQueueStatsProvider); if (oldConnectionQueueStatsProvider != null) { StatsProviderManager.unregister(oldConnectionQueueStatsProvider); } StatsProviderManager.register(CONFIG_ELEMENT, PluginPoint.SERVER, subtreePrefix(name) + "/connection-queue", connectionQueueStatsProvider); } /** * Unregister server wide connection queue statistics provider for a network listener */ public void unregisterConnectionQueueStatsProviderGlobal(String name) { final ConnectionQueueStatsProvider connectionQueueStatsProvider = connectionQueueStatsProvidersMap.remove(name); if (connectionQueueStatsProvider != null) { StatsProviderManager.unregister(connectionQueueStatsProvider); } } public ConnectionQueueStatsProvider getConnectionQueueStatsProvider(String name) { return connectionQueueStatsProvidersMap.get(name); } public FileCacheStatsProvider getFileCacheStatsProvider(String name) { return fileCacheStatsProvidersMap.get(name); } public KeepAliveStatsProvider getKeepAliveStatsProvider(String name) { return keepAliveStatsProvidersMap.get(name); } public ThreadPoolStatsProvider getThreadPoolStatsProvider(String name) { return threadPoolStatsProvidersMap.get(name); } private String subtreePrefix(String name) { return "network/" + name; } }