📄 statsengine.java
字号:
/**
* $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 + -