summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdwin Eefting <edwin@datux.nl>2010-12-11 18:05:41 (GMT)
committer Edwin Eefting <edwin@datux.nl>2010-12-11 18:05:41 (GMT)
commit36025053dcf3c37d95442e8cb3ac595a80d5d19b (patch)
treebe36b0e1681e5074a86b71f19078bc711369da84
parent986742b2dacaaa051f6f242d4593248ed61509f3 (diff)
adding better statistics overview
-rwxr-xr-xautorestart1
-rw-r--r--ccallman.cpp51
-rw-r--r--ccallman.h6
-rw-r--r--cmessageman.cpp14
-rw-r--r--cmessageman.h5
-rw-r--r--cuserman.cpp34
-rw-r--r--cuserman.h3
-rw-r--r--etc/synapse/userman.conf2
-rw-r--r--modules/core.module/module.cpp8
-rw-r--r--wwwdir/status.html199
10 files changed, 270 insertions, 53 deletions
diff --git a/autorestart b/autorestart
index e589dfc..e9725d7 100755
--- a/autorestart
+++ b/autorestart
@@ -8,6 +8,7 @@ while true; do
if [ "$STAT" != "$OLDSTAT" ]; then
OLDSTAT=$STAT
killall -9 synapse
+ sleep 1
echo "############# PROGRAM CHANGED, RESTARTING #############"
./synapse $ARGS &
fi
diff --git a/ccallman.cpp b/ccallman.cpp
index 70cedf2..9f08061 100644
--- a/ccallman.cpp
+++ b/ccallman.cpp
@@ -35,7 +35,9 @@ namespace synapse
CcallMan::CcallMan()
{
- statsTotal=0;
+ statCallsTotal=0;
+ statCallsQueuedMax=0;
+ statCallsQueued=0;
}
@@ -52,7 +54,10 @@ CcallMan::~CcallMan()
void CcallMan::addCall(const CmsgPtr & msg, const CsessionPtr & dst, FsoHandler soHandler)
{
callList.push_back(Ccall(msg,dst,soHandler));
- statsTotal++;
+ statCallsTotal++;
+ statCallsQueued++;
+ if (statCallsQueued>statCallsQueuedMax)
+ statCallsQueuedMax=statCallsQueued;
// DEB( "(" << callList.size() << ")" << " " << msg->event << " FROM " << msg->src << " TO " << msg->dst << " CALLDST " << dst->id);
}
@@ -74,6 +79,7 @@ CcallList::iterator CcallMan::startCall(const CthreadPtr & threadPtr)
{
callI->threadPtr=threadPtr;
callI->started=1;
+ statCallsQueued--;
// DEB( callI->msg->event << " FROM " << callI->msg->src << " TO " << callI->msg->dst << " CALLDST " << callI->dst->id);
return callI;
@@ -92,40 +98,26 @@ void CcallMan::endCall(CcallList::iterator callI)
}
-/*!
- \fn CcallMan::print()
- */
-string CcallMan::getStatusStr(bool queue, bool verbose)
+void CcallMan::getStatus(Cvar & var)
{
- stringstream status;
- int running=0;
for (CcallList::iterator callI=callList.begin(); callI!=callList.end(); callI++)
{
- if (queue)
- {
- status << " |";
- if (callI->started)
- status << "RUNNING";
- else if (!verbose)
- continue;
- else
- status << "QUEUED ";
-
- status << " " << callI->msg->event <<
- " FROM " << callI->msg->src <<
- " TO " << callI->dst->id << ":" << callI->dst->user->getName() <<
- "@" << callI->dst->module->name << callI->msg->getPrint(" |") <<
- "\n";
- }
-
- if (callI->started)
- running++;
+ Cvar c;
+ c["running"]=callI->started;
+ c["event"]=callI->msg->event;
+ c["src"]=callI->msg->src;
+ c["dst"]=callI->dst->id;
+ c["dstUserName"]=callI->dst->user->getName();
+ c["dstModule"]=callI->dst->module->name;
+ c["data"]=*callI->msg;
+ var["queue"].list().push_back(c);
}
- status << statsTotal << " calls processed, " << running << "/" << callList.size() << " calls running.\n";
+ var["statCallsQueued"]=statCallsQueued;
+ var["statCallsQueuedMax"]=statCallsQueuedMax;
+ var["statCallsTotal"]=statCallsTotal;
- return (status.str());
}
bool CcallMan::interruptCall(string event, int src, int dst)
@@ -149,6 +141,7 @@ bool CcallMan::interruptCall(string event, int src, int dst)
{
DEB("Cancelling call: " << event << " FROM " << src << " TO " << dst);
callList.erase(callI);
+ statCallsQueued--;
return (true);
}
diff --git a/ccallman.h b/ccallman.h
index 9d945fd..16c98d9 100644
--- a/ccallman.h
+++ b/ccallman.h
@@ -51,9 +51,11 @@ public:
void endCall(CcallList::iterator callI);
bool interruptCall(string event, int src, int dst);
bool interruptAll();
- string getStatusStr(bool queue, bool verbose);
+ void getStatus(Cvar & var);
- int statsTotal;
+ int statCallsTotal; //total calls processed
+ int statCallsQueued;//current length of queued calls
+ int statCallsQueuedMax; //maximum length of queued calls
CcallList callList;
diff --git a/cmessageman.cpp b/cmessageman.cpp
index 8cb46f0..94ab255 100644
--- a/cmessageman.cpp
+++ b/cmessageman.cpp
@@ -64,6 +64,7 @@ CmessageMan::CmessageMan()
defaultModifyGroup=userMan.getGroup("modules");
defaultRecvGroup=userMan.getGroup("everyone");
+ statMaxThreads=0;
activeThreads=0;
currentThreads=0;
maxActiveThreads=0;
@@ -444,8 +445,11 @@ void CmessageMan::activeThread()
activeThreads++;
//keep maximum active threads, so the reaper knows when there are too much threads
if (activeThreads>maxActiveThreads)
+ {
maxActiveThreads=activeThreads;
-
+ if (activeThreads>statMaxThreads)
+ statMaxThreads=activeThreads;
+ }
}
@@ -703,12 +707,12 @@ void CmessageMan::doShutdown(int exit=0)
threadCond.notify_all();
}
-string CmessageMan::getStatusStr()
+void CmessageMan::getStatus(Cvar & var)
{
- stringstream s;
- s << maxActiveThreads << "/" << wantCurrentThreads << " threads running. ";
+ var["activeThreads"]=activeThreads;
+ var["currentThreads"]=currentThreads;
+ var["statMaxThreads"]=statMaxThreads;
- return(s.str());
}
diff --git a/cmessageman.h b/cmessageman.h
index 82cb06c..be58bf1 100644
--- a/cmessageman.h
+++ b/cmessageman.h
@@ -105,7 +105,7 @@ public:
string firstModuleName;
//for administrator/debugging
- string getStatusStr();
+ void getStatus(Cvar & var);
void setModuleThreads(CmodulePtr module, int maxThreads);
void setSessionThreads(CsessionPtr session, int maxThreads);
@@ -129,8 +129,9 @@ private:
int currentThreads; //number of threads in memory
int wantCurrentThreads; //number of threads we want. threads will be added/deleted accordingly.
int maxThreads; //max number of threads. system will never create more then this many
- int activeThreads; //threads that are actually executing actively
+ int activeThreads; //threads that are actually executing actively
int maxActiveThreads; //max number of active threads seen (reset every X seconds by reaper)
+ int statMaxThreads; //maximum number of threads ever reached, just for statistics
bool shutdown; //program shutdown: end all threads
int exit; //shutdown exit code
diff --git a/cuserman.cpp b/cuserman.cpp
index e0a642c..6749ff0 100644
--- a/cuserman.cpp
+++ b/cuserman.cpp
@@ -41,6 +41,7 @@ namespace synapse
using namespace std;
CuserMan::CuserMan()
{
+ statMaxSessions=0;
sessionCounter=0;
sessionMaxPerUser=1000;
shutdown=false;
@@ -159,20 +160,27 @@ int CuserMan::addSession( CsessionPtr session)
//too much for this user already?
int userSessions=0;
+ int activeSessions=0;
for (int sessionId=1; sessionId<MAX_SESSIONS; sessionId++)
{
CsessionPtr chkSession;
chkSession=getSession(sessionId);
- if (chkSession && chkSession->user==session->user)
+ if (chkSession)
{
- userSessions++;
- if (userSessions>=sessionMaxPerUser)
+ activeSessions++;
+ if (chkSession->user==session->user)
{
- ERROR("User " << session->user->getName() << " has reached max sessions of " << sessionMaxPerUser);
- return (SESSION_DISABLED);
+ userSessions++;
+ if (userSessions>=sessionMaxPerUser)
+ {
+ ERROR("User " << session->user->getName() << " has reached max sessions of " << sessionMaxPerUser);
+ return (SESSION_DISABLED);
+ }
}
}
}
+ if (activeSessions>statMaxSessions)
+ statMaxSessions=activeSessions;
//find free session ID. Start at the counter position, to prevent that we use the same numbers
//all the time. (which will be confusing)
@@ -262,17 +270,25 @@ list<int> CuserMan::delCookieSessions(int cookie, CmodulePtr module)
}
-string CuserMan::getStatusStr()
+void CuserMan::getStatus(Cvar & var)
{
- stringstream s;
+ int activeSessions=0;
for (int sessionId=0; sessionId<MAX_SESSIONS; sessionId++)
{
if (sessions[sessionId])
{
- s << "session " << sessionId << " = " << sessions[sessionId]->user->getName() << "@" << sessions[sessionId]->module->name << ": " << sessions[sessionId]->description << "\n";
+ activeSessions++;
+ Cvar s;
+ s["id"]=sessionId;
+ s["user"]=sessions[sessionId]->user->getName();
+ s["module"]=sessions[sessionId]->module->name;
+ s["desc"]=sessions[sessionId]->description;
+ var["sessions"].list().push_back(s);
}
}
- return (s.str());
+
+ var["statMaxSessions"]=statMaxSessions;
+ var["activeSessions"]=activeSessions;
}
void CuserMan::doShutdown()
diff --git a/cuserman.h b/cuserman.h
index 2e8631b..15b0fd0 100644
--- a/cuserman.h
+++ b/cuserman.h
@@ -61,7 +61,7 @@ public:
CsessionPtr getSession(const int & sessionId);
bool delSession(const int id);
list<int> delCookieSessions(int cookie, CmodulePtr module);
- string getStatusStr();
+ void getStatus(Cvar & var);
void doShutdown();
string login(const int & sessionId, const string & userName, const string & password);
@@ -73,6 +73,7 @@ private:
int sessionCounter;
CsessionPtr sessions[MAX_SESSIONS+1];
int sessionMaxPerUser;
+ int statMaxSessions; //maximum sessions ever used, for statistics
};
}
diff --git a/etc/synapse/userman.conf b/etc/synapse/userman.conf
index eaf324e..b0cbd30 100644
--- a/etc/synapse/userman.conf
+++ b/etc/synapse/userman.conf
@@ -16,7 +16,7 @@
"passwd" : "",
"groups": [ "users", "everyone", "anonymous" ] },
"admin" : {
- "passwd" : "",
+ "passwd" : "bla",
"groups": [ "users", "core", "modules", "everyone", "anonymous" ] }
}
}
diff --git a/modules/core.module/module.cpp b/modules/core.module/module.cpp
index 5dfab6f..fdf7bfc 100644
--- a/modules/core.module/module.cpp
+++ b/modules/core.module/module.cpp
@@ -899,7 +899,7 @@ SYNAPSE_REGISTER(core_ChangeLogging)
Usefull for debugging and administration.
\par Replies \c core_Status:
- Contains several status fields.
+ Contains several status fields. Mainly used by status.html.
*/
SYNAPSE_REGISTER(core_GetStatus)
{
@@ -908,9 +908,9 @@ SYNAPSE_REGISTER(core_GetStatus)
lock_guard<mutex> lock(messageMan->threadMutex);
out.event="core_Status";
out.dst=msg.src;
- out["callMan"]=messageMan->callMan.getStatusStr(msg["queue"], msg["verbose"]);
- out["userMan"]=messageMan->userMan.getStatusStr();
- out["threads"]=messageMan->getStatusStr();
+ messageMan->callMan.getStatus(out);
+ messageMan->userMan.getStatus(out);
+ messageMan->getStatus(out);
}
out.send();
diff --git a/wwwdir/status.html b/wwwdir/status.html
new file mode 100644
index 0000000..d84b541
--- /dev/null
+++ b/wwwdir/status.html
@@ -0,0 +1,199 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+
+<html>
+
+<head>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+ <title>Synapse status page</title>
+
+ <script type="text/javascript" src="synapse.js"></script>
+
+ <script type="text/javascript">
+
+ /// SYNAPSE EVENT HANDLERS
+
+ synapse_register("error",function(errortxt)
+ {
+ $('#error').html(errortxt);
+ });
+
+ synapse_register("default",function(msg_src, msg_dst, msg_event, msg)
+ {
+ var msgStr="(undefined)";
+ if (typeof msg != "undefined")
+ {
+ msgStr=JSON.stringify(msg);
+ }
+
+ $('#broadcastLog').append(
+ "<pre>From: "+msg_src+
+ " To:"+msg_dst+
+ " Event:"+msg_event+
+ "\n"+msgStr+"</pre>");
+
+ var objDiv = document.getElementById("broadcastLog");
+ objDiv.scrollTop = objDiv.scrollHeight;
+
+ });
+
+ synapse_register("core_Status",function(msg_src, msg_dst, msg_event, msg)
+ {
+
+ $('#queueBar').progressbar("option", "value", msg["statCallsQueued"]/msg["statCallsQueuedMax"]*100);
+ $('#queueValue').html(
+ "Queued: "+ msg["statCallsQueued"]+
+ "/"+msg["statCallsQueuedMax"]+
+ "<br>("+msg["statCallsTotal"]+
+ " calls)");
+
+ $('#threadValue').html("Threads: "+msg["activeThreads"]+"/"+msg["statMaxThreads"]);
+ $('#threadBar').progressbar("option", "value", msg["activeThreads"]/msg["statMaxThreads"]*100);
+
+ $('#sessionValue').html("Sessions: "+msg["activeSessions"]+"/"+msg["statMaxSessions"]);
+ $('#sessionBar').progressbar("option", "value", msg["activeSessions"]/msg["statMaxSessions"]*100);
+
+ $('#core_Status').html(
+ "Call queue:\n"+msg["callMan"]+"\nThreads:\n"+msg["threads"]+"\nSessions:\n"+msg["userMan"]
+ );
+ });
+
+ synapse_register("http_json_Status",function(msg_src, msg_dst, msg_event, msg)
+ {
+ $('#http_json_Status').html(
+ "Network status:\n"+msg["net"] + "\nHTTP sessions:\n"+msg["httpSessionMan"]
+
+ );
+ });
+
+
+ synapse_register("module_SessionStart",function(msg_src, msg_dst, msg_event, msg)
+ {
+ $('.bar').progressbar();
+
+ $('#authCookie').html(msg["authCookie"]);
+ $('#dst').html(msg_dst);
+ //synapse_login();
+ send(0,"core_Login", {
+ "username": "admin",
+ "password": "bla"
+ });
+
+ });
+
+ synapse_register("module_Error",function(msg_src, msg_dst, msg_event, msg)
+ {
+ $('#module_Error').html(msg["description"]);
+ });
+
+ synapse_register("module_Login",function(msg_src, msg_dst, msg_event, msg)
+ {
+ $('#module_Login').html("Logged in as " + msg["username"]);
+
+ window.setInterval(function() {
+ send(1,"core_GetStatus", {
+ "queue": 1,
+ "verbose": 0
+ });
+
+ send(0,"http_json_GetStatus", {
+ });
+
+ }, 1000);
+ });
+
+
+ /// JAVA SCRIPT EVENT HANDLERS
+ $(document).ready(function(){
+
+
+ });
+
+
+ </script>
+
+<style>
+.bar {
+ width:50%;
+ display: inline-block;
+}
+.value {
+ width:30%;
+ display: inline-block;
+}
+
+</style>
+
+</head>
+
+<body
+ class='ui-widget'
+ style='
+ height:100%;
+'>
+ <div
+ class='ui-widget-content'
+ style='
+ position:absolute;
+ left:0;
+ top:0;
+ width:50%;
+ height:50%;
+ overflow:auto;
+ '>
+ <div class='ui-widget-header'>Core status:</div>
+ <pre >
+ <div id='core_Status' ></div>
+ </pre>
+ </div>
+
+ <div
+ class='ui-widget-content'
+ style='
+ position:absolute;
+ left:50%;
+ top:0;
+ width:50%;
+ height:50%;
+ overflow:auto;
+ '>
+ <div class='ui-widget-header'>HTTP server status:</div>
+ <pre>
+ <div id='http_json_Status' ></div>
+ </pre>
+ </div>
+
+ <div
+ class='ui-widget-content'
+ id='broadcastLog'
+ style='
+ position:absolute;
+ left:0%;
+ top:50%;
+ width:50%;
+ height:50%;
+ overflow:auto;
+ '>
+ <div class='ui-widget-header'>Broadcast messages:</div>
+ </div>
+
+ <div
+ class='ui-widget-content'
+ style='
+ position:absolute;
+ left:50%;
+ top:50%;
+ width:50%;
+ height:50%;
+ overflow:auto;
+ '>
+ <div class='ui-widget-header'>Statistieken:</div>
+
+ <div class='value' id='queueValue'></div><div class='bar' id='queueBar'></div>
+
+ <div class='value' id='threadValue'></div><div class='bar' id='threadBar' ></div>
+
+ <div class='value' id='sessionValue'></div><div class='bar' id='sessionBar' ></div>
+ </div>
+
+</body>
+</html> \ No newline at end of file