From c226967f95d98ec05199039d21c55dba62a851cd Mon Sep 17 00:00:00 2001 From: Stefan Sayer Date: Thu, 12 Feb 2009 21:23:17 +0000 Subject: [PATCH] functions to retrieve only an attribute, and filter the list: o listByFilter o listByRegex o getAttribute [Active/Finished] renamed 'unfinished' to 'active' git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@1271 8eb893ce-cfd4-0310-b710-fb5ebe64c474 --- apps/monitoring/Monitoring.cpp | 125 ++++++++++++++++++++++++++++++--- apps/monitoring/Monitoring.h | 9 ++- doc/Readme.monitoring | 31 +++++--- 3 files changed, 143 insertions(+), 22 deletions(-) diff --git a/apps/monitoring/Monitoring.cpp b/apps/monitoring/Monitoring.cpp index 59768ce9..9dc76cda 100644 --- a/apps/monitoring/Monitoring.cpp +++ b/apps/monitoring/Monitoring.cpp @@ -29,6 +29,9 @@ #include "log.h" +#include +#include + //EXPORT_PLUGIN_CLASS_FACTORY(Monitor, MOD_NAME); extern "C" void* plugin_class_create() { @@ -67,20 +70,30 @@ void Monitor::invoke(const string& method, logAdd(args,ret); } else if(method == "markFinished"){ markFinished(args,ret); + } else if(method == "get"){ + get(args,ret); + } else if(method == "getAttribute"){ + getAttribute(args,ret); + } else if(method == "getAttributeFinished"){ + getAttributeFinished(args,ret); + } else if(method == "getAttributeActive"){ + getAttributeActive(args,ret); + } else if(method == "list"){ + listAll(args,ret); + } else if(method == "listByFilter"){ + listByFilter(args,ret); + } else if(method == "listByRegex"){ + listByRegex(args,ret); + } else if(method == "listFinished"){ + listFinished(args,ret); + } else if(method == "listActive"){ + listActive(args,ret); } else if(method == "clear"){ clear(args,ret); } else if(method == "clearFinished"){ clearFinished(args,ret); } else if(method == "erase"){ clear(args,ret); - } else if(method == "get"){ - get(args,ret); - } else if(method == "list"){ - list(args,ret); - } else if(method == "listFinished"){ - listFinished(args,ret); - } else if(method == "listUnfinished"){ - listUnfinished(args,ret); } else if(method == "_list"){ ret.push(AmArg("log")); ret.push(AmArg("logAdd")); @@ -89,9 +102,14 @@ void Monitor::invoke(const string& method, ret.push(AmArg("clear")); ret.push(AmArg("clearFinished")); ret.push(AmArg("get")); + ret.push(AmArg("getAttribute")); + ret.push(AmArg("getAttributeActive")); + ret.push(AmArg("getAttributeFinished")); ret.push(AmArg("list")); + ret.push(AmArg("listByFilter")); + ret.push(AmArg("listByRegex")); ret.push(AmArg("listFinished")); - ret.push(AmArg("listUnfinished")); + ret.push(AmArg("listActive")); } else throw AmDynInvoke::NotImplemented(method); } @@ -201,7 +219,32 @@ void Monitor::get(const AmArg& args, AmArg& ret) { bucket.log_lock.unlock(); } -void Monitor::list(const AmArg& args, AmArg& ret) { +#define DEF_GET_ATTRIB_FUNC(func_name, cond) \ + void Monitor::func_name(const AmArg& args, AmArg& ret) { \ + assertArgCStr(args[0]); \ + string attr_name = args[0].asCStr(); \ + for (int i=0;i::iterator it= \ + logs[i].log.begin();it != logs[i].log.end();it++) { \ + if (cond) { \ + ret.push(AmArg()); \ + AmArg& val = ret.get(ret.size()-1); \ + val.push(AmArg(it->first.c_str())); \ + val.push(it->second.info[attr_name]); \ + } \ + } \ + logs[i].log_lock.unlock(); \ + } \ + } + +DEF_GET_ATTRIB_FUNC(getAttribute, true) +DEF_GET_ATTRIB_FUNC(getAttributeActive, (!it->second.finished)) +DEF_GET_ATTRIB_FUNC(getAttributeFinished, (it->second.finished)) + +#undef DEF_GET_ATTRIB_FUNC + +void Monitor::listAll(const AmArg& args, AmArg& ret) { for (int i=0;i::iterator it= @@ -212,6 +255,66 @@ void Monitor::list(const AmArg& args, AmArg& ret) { } } +void Monitor::listByFilter(const AmArg& args, AmArg& ret) { + for (int i=0;i::iterator it= + logs[i].log.begin(); it != logs[i].log.end(); it++) { + bool match = true; + for (size_t i=0;isecond.info[p.get(0).asCStr()]==p.get(1))) { + match = false; + break; + } + } + + if (!match) + continue; + + ret.push(AmArg(it->first.c_str())); + } + } catch(...) { + logs[i].log_lock.unlock(); + throw; + } + logs[i].log_lock.unlock(); + } +} + +void Monitor::listByRegex(const AmArg& args, AmArg& ret) { + assertArgCStr(args[0]); + assertArgCStr(args[1]); + + regex_t attr_reg; + if(regcomp(&attr_reg,args[1].asCStr(),REG_NOSUB)){ + ERROR("could not compile regex '%s'\n", args[1].asCStr()); + return; + } + + for (int i=0;i::iterator it= + logs[i].log.begin(); it != logs[i].log.end(); it++) { + if (!it->second.info.hasMember(args[0].asCStr()) || + !isArgCStr(it->second.info[args[0].asCStr()]) || + regexec(&attr_reg,it->second.info[args[0].asCStr()].asCStr(),0,0,0)) + continue; + + ret.push(AmArg(it->first.c_str())); + } + } catch(...) { + logs[i].log_lock.unlock(); + throw; + } + logs[i].log_lock.unlock(); + } + + regfree(&attr_reg); +} + void Monitor::listFinished(const AmArg& args, AmArg& ret) { for (int i=0;i::iterator it= diff --git a/apps/monitoring/Monitoring.h b/apps/monitoring/Monitoring.h index 4af75387..55e74227 100644 --- a/apps/monitoring/Monitoring.h +++ b/apps/monitoring/Monitoring.h @@ -68,9 +68,14 @@ class Monitor void clearFinished(const AmArg& args, AmArg& ret); void erase(const AmArg& args, AmArg& ret); void get(const AmArg& args, AmArg& ret); - void list(const AmArg& args, AmArg& ret); + void getAttribute(const AmArg& args, AmArg& ret); + void getAttributeActive(const AmArg& args, AmArg& ret); + void getAttributeFinished(const AmArg& args, AmArg& ret); + void listAll(const AmArg& args, AmArg& ret); + void listByFilter(const AmArg& args, AmArg& ret); + void listByRegex(const AmArg& args, AmArg& ret); void listFinished(const AmArg& args, AmArg& ret); - void listUnfinished(const AmArg& args, AmArg& ret); + void listActive(const AmArg& args, AmArg& ret); public: diff --git a/doc/Readme.monitoring b/doc/Readme.monitoring index 75abcaa3..83e24fbc 100644 --- a/doc/Readme.monitoring +++ b/doc/Readme.monitoring @@ -9,7 +9,7 @@ monitoring information is explicitely pushed to monitoring module via DI calls (See ampi/MonitoringAPI.h for useful macros). Info is always accessed via primary key, usually call-id. Info for every call is organized as attribute-value pairs (one or more values), value can be any type -representable by AmArg (SEMS' variable type). +representable by AmArg (SEMS' variant type). A call can be marked as finished. If not done before, this is done by the session container when deleting a session (i.e., as the session @@ -30,16 +30,29 @@ DI API ------ functions to log, e.g. from inside SEMS: log(ID, key, value [, key, value [, key, value [...]]]) - set one or multiple AVPs - logAdd(ID, key, value) - add a value to an AVPs + logAdd(ID, key, value) - add a value to a AVPs + markFinished(ID) - mark call as finished functions to get log, e.g. from the outside: - list - list IDs of calls - listFinished - list IDs of finished calls - listUnfinished - list IDs of unfinished (active) calls - get - get info for a specific call, parameter is the ID - erase - erase info of a specific call, parameter is the ID (+free used memory) - clear - erase info of all calls (+free used memory) - clearFinished - erase info of all finished calls (+free used memory) + list() - list IDs of calls + listByFilter(exp, exp, exp, ...) - list IDs of calls that match the filter expressions: + exp of the form array of attr_name-value, + e.g. listByFilter(['dir', 'in'], ['codec_name', 'GSM']) + listByRegex(attr_name, regexp) - list IDs of calls that match the regular expression + on the attribute (string attributes only), e.g. + listByRegex('r_uri', '.*mydomain.net.*') + listActive() - list IDs of active (unfinished) calls + listFinished() - list IDs of finished calls + get(ID) - get info for a specific call, parameter is the call ID + getAttribute(attr_name) + - get a specific attribute from all calls, parameter is the attribute name + getAttributeActive(attr_name) + - get a specific attribute from all active calls, parameter is the attribute name + getAttributeFinished(attr_name) + - get a specific attribute from all finished calls, parameter is the attribute name + erase(ID) - erase info of a specific call, parameter is the call ID (+free used memory) + clear() - erase info of all calls (+free used memory) + clearFinished() - erase info of all finished calls (+free used memory) (of course, log()/logAdd() functions can also be accessed via e.g. XMLRPC.)