⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 statsengine.java

📁 openfire 服务器源码下载
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/**
 * $Revision: 3034 $
 * $Date: 2005-11-04 21:02:33 -0300 (Fri, 04 Nov 2005) $
 *
 * Copyright (C) 2008 Jive Software. All rights reserved.
 *
 * This software is published under the terms of the GNU Public License (GPL),
 * a copy of which is included in this distribution, or a commercial license
 * agreement with Jive.
 */
package org.jivesoftware.openfire.reporting.stats;

import org.jivesoftware.openfire.cluster.ClusterManager;
import org.jivesoftware.openfire.reporting.util.TaskEngine;
import org.jivesoftware.openfire.stats.Statistic;
import org.jivesoftware.openfire.stats.StatisticsManager;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.cache.CacheFactory;
import org.jrobin.core.*;
import org.picocontainer.Startable;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * The stats workhorse. Handles the job of sampling the different statistics existing in
 * the system and persiting them to the database. Also, it tracks through a <i>StatDefinition</i>
 * for each stat all the meta information related to a stat.
 *
 * @author Alexander Wenckus
 */
public class StatsEngine implements Startable {

    private static final int STAT_RESOULUTION = 60;

    private final TaskEngine taskEngine;

    private final StatisticsManager statsManager;

    private final Map<String, StatDefinition> definitionMap = new HashMap<String, StatDefinition>();

    private final Map<String, List<StatDefinition>> multiMap = new HashMap<String, List<StatDefinition>>();

    private SampleTask samplingTask = new SampleTask();

    /**
     * The default constructor used by the plugin container.
     *
     * @param taskEngine Used to execute tasks.
     */
    public StatsEngine(TaskEngine taskEngine) {
        this.taskEngine = taskEngine;
        statsManager = StatisticsManager.getInstance();
    }

    public void start() {
        try {
            // Set that RRD files will be stored in the database
            RrdBackendFactory.registerAndSetAsDefaultFactory(new RrdSqlBackendFactory());

            // After 10 milliseconds begin sampling in 60 second intervals. Note: We need to start
            // asap so that the UI can access this info upon start up
            taskEngine.scheduleAtFixedRate(samplingTask, 10, STAT_RESOULUTION * 1000L);
        }
        catch (RrdException e) {
            Log.error("Error initializing RrdbPool.", e);
        }
    }

    public void stop() {
        // Clean-up sampling task
        samplingTask.cancel();
    }

    private void checkDatabase(StatDefinition[] def) throws RrdException, IOException {
        File directory = new File(getStatsDirectroy());
        if (directory.exists()) {
            // check if the rrd exists
            File rrdFile = new File(getRrdFilePath(def[0].getDbPath()));
            if (rrdFile.exists() && rrdFile.canRead()) {
                try {
                    // Import existing RRD file into the DB
                    RrdSqlBackend.importRRD(def[0].getDbPath(), rrdFile);
                    // Delete the RRD file
                    rrdFile.delete();
                } catch (IOException e) {
                    Log.error("Error importing rrd file: " + rrdFile, e);
                }
            }
        }

        // check if the rrd exists
        if (!RrdSqlBackend.exists(def[0].getDbPath())) {
            RrdDb db = null;
            try {
                RrdDef rrdDef = new RrdDef(def[0].getDbPath(), STAT_RESOULUTION);
                for (StatDefinition stat : def) {
                    String dsType = determineDsType(stat.getStatistic().getStatType());
                    rrdDef.addDatasource(stat.getDatasourceName(), dsType, 5 * STAT_RESOULUTION, 0,
                            Double.NaN);
                }

                // Every minute for 1 hour.
                rrdDef.addArchive(((DefaultStatDefinition) def[0]).
                        consolidationFunction, 0.5, 1, 60);
                // Every half-hour for 1 day.
                rrdDef.addArchive(ConsolFuns.CF_AVERAGE, 0.5, 30, 48);
                // Every day for 5 years.
                rrdDef.addArchive(ConsolFuns.CF_AVERAGE, 0.5, 1440, 1825);
                // Every week for 5 years.
                rrdDef.addArchive(ConsolFuns.CF_AVERAGE, 0.5, 10080, 260);
                // Every month for 5 years.
                rrdDef.addArchive(ConsolFuns.CF_AVERAGE, 0.5, 43200, 60);

                db = new RrdDb(rrdDef);
            }
            finally {
                if(db != null) {
                    db.close();
                }
            }
        }
    }

    private String determineDsType(Statistic.Type statType) {
        return DsTypes.DT_GAUGE;
    }

    /**
     * Returns the path to the RRD file.
     *
     * @param datasourceName the name of the data source.
     * @return the path to the RRD file.
     */
    private String getRrdFilePath(String datasourceName) {
        return getStatsDirectroy() + datasourceName + ".rrd";
    }

    /**
     * Returns the directory in which all of the stat databases will be stored.
     *
     * @return Returns the directory in which all of the stat databases will be stored.
     */
    private String getStatsDirectroy() {
        return JiveGlobals.getHomeDirectory() + File.separator + "monitoring"
                + File.separator + "stats" + File.separator;
    }

    private StatDefinition createDefintion(String key) {
        StatDefinition def = definitionMap.get(key);
        if (def == null) {
            Statistic statistic = statsManager.getStatistic(key);
            String statGroup = statsManager.getMultistatGroup(key);
            try {
                def = new DefaultStatDefinition(statGroup != null ? statGroup : key, key, statistic);

                // If the definition is a part of a group check to see all defiintions have been
                // made for that group
                StatDefinition[] definitions;
                if (statGroup != null) {
                    definitions = checkAndCreateGroup(statGroup, def, true);
                }
                else {
                    definitions = new StatDefinition[]{def};
                    multiMap.put(key, Arrays.asList(definitions));
                }

                if (definitions != null) {
                    checkDatabase(definitions);
                }
                definitionMap.put(key, def);
            }
            catch (RrdException e) {
                Log.error("Error creating database definition", e);
            }
            catch (IOException e) {
                Log.error("Error creating database definition", e);
            }
        }
        return def;
    }

    /**
     * Checks to see that all StatDefinitions for a stat group have been created. If they have
     * then an array of the StatDefinitions will be returned, if they haven't Null will be returned.
     * <p>
     * The purpose of this is to know when a database should be initialized, after all the StatDefinitions
     * have been created.
     *
     * @param statGroup The statGroup being checked
     * @param def The statdefinition that is being added to the statGroup
     * @return Null if the statgroup is completely defined and an array of statdefinitions if it is.
     */
    private StatDefinition[] checkAndCreateGroup(String statGroup, StatDefinition def,
                                                 boolean shouldCreate)
    {
        List<StatDefinition> statList = multiMap.get(statGroup);
        if (shouldCreate && statList == null) {
            statList = new ArrayList<StatDefinition>();
            multiMap.put(statGroup, statList);
        }
        if (statList == null) {
            return null;
        }
        if (shouldCreate) {
            statList.add(def);
        }
        StatDefinition[] definitions;
        if (statsManager.getStatGroup(statGroup).size() == statList.size()) {
            definitions = statList.toArray(new StatDefinition[statList.size()]);
        }
        else {
            definitions = null;
        }
        return definitions;
    }

    /**
     * Returns the last minute that passed in seconds since the epoch.
     *
     * @return the last minute that passed in seconds since the epoch.
     */
    private static long getLastMinute() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * Returns the definition or definitions related to a statkey. There can be multiple
     * definitions if a stat is a multistat.
     *
     * @param statKey The key for which the definition is desired.
     * @return Returns the definition or definitions related to a statkey. There can be multiple
     * definitions if a stat is a multistat.
     */
    StatDefinition[] getDefinition(String statKey) {
        List<StatDefinition> defs = multiMap.get(statKey);
        if (defs == null) {
            StatDefinition def = definitionMap.get(statKey);
            if (def != null) {
                return new StatDefinition[] {def};
            }
            else {
                return null;
            }
        }
        else {
            return defs.toArray(new StatDefinition[defs.size()]);
        }
    }

    /**
     * Returns any multistat group names and any stats that are not part of a multistat.
     *
     * @return Returns any multistat group names and any stats that are not part of a multistat.
     */
    String [] getAllHighLevelNames() {
        Set<String> keySet = multiMap.keySet();

        return keySet.toArray(new String[keySet.size()]);
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -