Commit 99b026ff authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Initial version. JM-934

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@6671 b35dd754-fafc-0310-a699-88a17e54d16e
parent bb9786e2
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Statistic Plugin Changelog</title>
<style type="text/css">
BODY {
font-size : 100%;
}
BODY, TD, TH {
font-family : tahoma, verdana, arial, helvetica, sans-serif;
font-size : 0.8em;
}
H2 {
font-size : 10pt;
font-weight : bold;
padding-left : 1em;
}
A:hover {
text-decoration : none;
}
H1 {
font-family : tahoma, arial, helvetica, sans-serif;
font-size : 1.4em;
font-weight: bold;
border-bottom : 1px #ccc solid;
padding-bottom : 2px;
}
TT {
font-family : courier new;
font-weight : bold;
color : #060;
}
PRE {
font-family : courier new;
font-size : 100%;
}
</style>
</head>
<body>
<h1>
Statistic Plugin Changelog
</h1>
<p><b>1.0.0</b> -- January 1, 2007</p>
<ul>
<li>Initial release.</li>
</ul>
</body>
</html>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<class>org.jivesoftware.wildfire.plugin.StatisticPlugin</class>
<name>Statistic</name>
<description>Logs server statistics to a file</description>
<author>Jive Software</author>
<version>1.0.0</version>
<date>1/31/2007</date>
<minServerVersion>3.2.0</minServerVersion>
</plugin>
\ No newline at end of file
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Statistic Plugin Readme</title>
<style type="text/css">
BODY {
font-size : 100%;
}
BODY, TD, TH {
font-family : tahoma, verdana, arial, helvetica, sans-serif;
font-size : 0.8em;
}
H2 {
font-size : 10pt;
font-weight : bold;
}
A:hover {
text-decoration : none;
}
H1 {
font-family : tahoma, arial, helvetica, sans-serif;
font-size : 1.4em;
font-weight: bold;
border-bottom : 1px #ccc solid;
padding-bottom : 2px;
}
TT {
font-family : courier new;
font-weight : bold;
color : #060;
}
PRE {
font-family : courier new;
font-size : 100%;
}
.events TH {
font-size: 8pt;
font-family: verdana;
font-weight: bold;
text-align: left;
background-color: #eee;
border-bottom: 1px #ccc solid;
}
.events .event {
font-weight: bold;
}
.events TD {
border-bottom: 1px #ccc dotted;
vertical-align: top;
}
</style>
</head>
<body>
<h1>
Statistic Plugin Readme
</h1>
<h2>Overview</h2>
<p>
The statistic plugin prints usage information of the database connection pool, thread pool used for processing
incoming traffic and the NIO networking layer.
</p>
<h2>Installation</h2>
<p>
Copy the file, &quot;statistic.jar&quot; into the plugins directory of your Wildfire installation. The plugin will
then be automatically deployed.
</p>
<h2>Configuration</h2>
At the moment there is no new page to configure the plugin. However, the plugin can be configured by setting
a few system properties. Read the "Using the Plugin" section to learn which system properties to use.
<h2>Using the Plugin</h2>
<p>
The plugin will collect information every few seconds and will print the collected information to a log file
every minute. The log file is a comma delimited file that can be easily processed in Excel. You can configure
the plugin by setting the system properties shown in the table below.
<p>
<table class="events" cellpadding="3" cellspacing="1" border="0">
<thead>
<tr>
<th>System Property</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<span class="event">statistic.frequency</span>
</td>
<td>
Number of milliseconds to wait before collecting information. Default value is 5000 (5 seconds)
</td>
</tr>
<tr>
<td>
<span class="event">statistic.filename</span>
</td>
<td>
Name of the file to use to store the statistics. The file will always be stored in the logs folder. Default value is "stats.txt".
</td>
</tr>
<tr>
<td>
<span class="event">statistic.connectionmanager</span>
</td>
<td>
True if statistics will be collected for Connection Managers traffic or false when statistics will be collected for clients directly connected to the server. Default value is "false".
</td>
</tr>
</tbody>
</table>
<p>
The format of the log file is the following:
<ol>
<li><b>Timestamp</b> - Timestamp when the data was collected</li>
<li><b>DB min</b> - Minimum number of connections the pool may have</li>
<li><b>DB max</b> - Maximum number of connectiosn the pool may have</li>
<li><b>DB current</b> - Current number of connections the pool has</li>
<li><b>DB used</b> - Current number of connections being used</li>
<li><b>Core Threads</b> - Number of threads for processing incoming traffic</li>
<li><b>Active Threads</b> - Number of threads that are actually processing incoming traffic</li>
<li><b>Queue Tasks</b> - Number of stanzas stored in the queue when all threads where busy</li>
<li><b>Completed Tasks</b> - Total number of stanzas that were processed</li>
<li><b>Sessions</b> - Current number of client sessions in the server</li>
<li><b>NIO Read</b> - Total number of stanzas that were read</li>
<li><b>NIO Written</b> - Total number of stanzas that were sent</li>
<li><b>Queued NIO events</b> - Current number of stanzas that are queued. Stanzas are queued when the same client sends many stanzas and the server is still processing a previous stanza. Queued stanzas are not yet considered read.</li>
<li><b>Queues NIO writes</b> - Current number of stanzas pending to be sent</li>
</ol>
</p>
When processing the file in Excel you may want to add the following columns:
<ul>
<li><b>NIO Reads Delta</b> - Difference between a <i>NIO Read</i> row and its previous row</li>
<li><b>NIO Writtens Delta</b> - Difference between a <i>NIO Written</i> row and its previous row</li>
<li><b>Sessions delta</b> - Difference between a <i>Sessions</i> row and its previous row</li>
</ul>
Excell charts are a great way for understanding the collected statistics. In particular, we found charts
of the following columns useful.
<ul>
<li><b>NIO Read</b> and <b>NIO Written</b></li>
<li><b>NIO Reads Delta</b> and <b>NIO Writtens Delta</b></li>
<li><b>Sessions</b></li>
<li><b>Sessions delta</b></li>
<li><b>Completed Tasks</b></li>
<li><b>DB used</b></li>
<li><b>Active Threads</b></li>
</ul>
</body>
</html>
/**
* $RCSfile: $
* $Revision: $
* $Date: $
*
* Copyright (C) 2007 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.
*/
package org.jivesoftware.wildfire.plugin;
import org.apache.mina.common.ExecutorThreadModel;
import org.apache.mina.transport.socket.nio.SocketAcceptor;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.TaskEngine;
import org.jivesoftware.wildfire.SessionManager;
import org.jivesoftware.wildfire.XMPPServer;
import org.jivesoftware.wildfire.spi.ConnectionManagerImpl;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimerTask;
import java.util.concurrent.ThreadPoolExecutor;
/**
* Collector of raw data that is print to a log file every minute.
*
* @author Gaston Dombiak
*/
public class StatCollector extends TimerTask {
private boolean headerPrinter = false;
private List<String> content = new ArrayList<String>();
private SocketAcceptor socketAcceptor;
// Take a sample every X seconds
private int frequency;
private boolean started = false;
private org.apache.mina.management.StatCollector statCollector;
public StatCollector(int frequency) {
this.frequency = frequency;
ConnectionManagerImpl connectionManager =
((ConnectionManagerImpl) XMPPServer.getInstance().getConnectionManager());
if (JiveGlobals.getBooleanProperty("statistic.connectionmanager", false)) {
socketAcceptor = connectionManager.getMultiplexerSocketAcceptor();
}
else {
socketAcceptor = connectionManager.getSocketAcceptor();
}
statCollector = new org.apache.mina.management.StatCollector(socketAcceptor, frequency - 1000);
}
public void run() {
try {
// Collect content
StringBuilder sb = new StringBuilder();
// Add current timestamp
sb.append(System.currentTimeMillis());
sb.append(',');
// Add info about the db connection pool
sb.append(DbConnectionManager.getConnectionProvider().toString());
sb.append(',');
// Add info about the thread pool that process incoming requests
ExecutorThreadModel threadModel = (ExecutorThreadModel) socketAcceptor.getDefaultConfig().getThreadModel();
ThreadPoolExecutor executor = (ThreadPoolExecutor) threadModel.getExecutor();
sb.append(executor.getCorePoolSize());
sb.append(',');
sb.append(executor.getActiveCount());
sb.append(',');
sb.append(executor.getQueue().size());
sb.append(',');
sb.append(executor.getCompletedTaskCount());
// Add info about number of connected sessions
sb.append(',');
sb.append(SessionManager.getInstance().getSessionCount());
// Add info about MINA statistics
sb.append(',');
sb.append(statCollector.getMsgRead());
sb.append(',');
sb.append(statCollector.getMsgWritten());
sb.append(',');
sb.append(statCollector.getQueuedEvents());
sb.append(',');
sb.append(statCollector.getScheduledWrites());
// Add new line of content with current stats
content.add(sb.toString());
// Check if we need to print content to file (print content every minute)
if (content.size() > (60f / frequency * 1000)) {
try {
File file = new File(JiveGlobals.getHomeDirectory() + File.separator + "logs", JiveGlobals.getProperty("statistic.filename", "stats.txt"));
if (!file.exists()) {
file.createNewFile();
}
BufferedWriter out = new BufferedWriter(new FileWriter(file, true));
if (!headerPrinter) {
out.write(new Date().toString());
out.write('\n');
out.write(
"Timestamp, DB min, DB max, DB current, DB used, Core Threads, Active Threads, Queue Tasks, Completed Tasks, Sessions, NIO Read, NIO Written, Queued NIO events, Queues NIO writes");
out.write('\n');
headerPrinter = true;
}
for (String line : content) {
out.write(line);
out.write('\n');
}
out.close();
} catch (IOException e) {
Log.error("Error creating statistics log file", e);
}
content.clear();
}
} catch (Exception e) {
Log.error("Error collecting and logging server statistics", e);
}
}
public synchronized void start() {
if (!started) {
started = true;
statCollector.start();
TaskEngine.getInstance().scheduleAtFixedRate(this, 1000, frequency);
}
}
public void stop() {
if (started) {
statCollector.stop();
TaskEngine.getInstance().cancelScheduledTask(this);
}
}
}
/**
* $RCSfile: $
* $Revision: $
* $Date: $
*
* Copyright (C) 2007 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.
*/
package org.jivesoftware.wildfire.plugin;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.wildfire.container.Plugin;
import org.jivesoftware.wildfire.container.PluginManager;
import java.io.File;
/**
* Plugins that prints usage information of the database connection pool, thread pool
* used for processing incoming traffic and the NIO networking layer.
*
* @author Gaston Dombiak
*/
public class StatisticPlugin implements Plugin {
private StatCollector task;
public void initializePlugin(PluginManager manager, File pluginDirectory) {
task = new StatCollector(JiveGlobals.getIntProperty("statistic.frequency", 5000));
// Run the task
task.start();
}
public void destroyPlugin() {
if (task != null) {
task.stop();
task = null;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment