Author: sayer
Date: 2009-02-12 22:23:17 +0100 (Thu, 12 Feb 2009)
New Revision: 1271
Modified:
trunk/apps/monitoring/Monitoring.cpp
trunk/apps/monitoring/Monitoring.h
trunk/doc/Readme.monitoring
Log:
functions to retrieve only an attribute, and filter the list:
o listByFilter
o listByRegex
o getAttribute [Active/Finished]
renamed 'unfinished' to 'active'
Modified: trunk/apps/monitoring/Monitoring.cpp
===================================================================
--- trunk/apps/monitoring/Monitoring.cpp 2009-02-12 20:58:40 UTC (rev
1270)
+++ trunk/apps/monitoring/Monitoring.cpp 2009-02-12 21:23:17 UTC (rev
1271)
@@ -29,6 +29,9 @@
#include "log.h"
+#include <sys/types.h>
+#include <regex.h>
+
//EXPORT_PLUGIN_CLASS_FACTORY(Monitor, MOD_NAME);
extern "C" void* plugin_class_create()
{
@@ -67,20 +70,30 @@
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 @@
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 @@
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<NUM_LOG_BUCKETS;i++) { \
+ logs[i].log_lock.lock(); \
+ for (std::map<string, LogInfo>::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<NUM_LOG_BUCKETS;i++) {
logs[i].log_lock.lock();
for (std::map<string, LogInfo>::iterator it=
@@ -212,6 +255,66 @@
}
}
+void Monitor::listByFilter(const AmArg& args, AmArg& ret) {
+ for (int i=0;i<NUM_LOG_BUCKETS;i++) {
+ logs[i].log_lock.lock();
+ try {
+ for (std::map<string, LogInfo>::iterator it=
+ logs[i].log.begin(); it != logs[i].log.end(); it++) {
+ bool match = true;
+ for (size_t i=0;i<args.size();i++) {
+ AmArg& p = args.get(i);
+ if (!(it->second.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<NUM_LOG_BUCKETS;i++) {
+ logs[i].log_lock.lock();
+ try {
+ for (std::map<string, LogInfo>::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<NUM_LOG_BUCKETS;i++) {
logs[i].log_lock.lock();
@@ -225,7 +328,7 @@
}
-void Monitor::listUnfinished(const AmArg& args, AmArg& ret) {
+void Monitor::listActive(const AmArg& args, AmArg& ret) {
for (int i=0;i<NUM_LOG_BUCKETS;i++) {
logs[i].log_lock.lock();
for (std::map<string, LogInfo>::iterator it=
Modified: trunk/apps/monitoring/Monitoring.h
===================================================================
--- trunk/apps/monitoring/Monitoring.h 2009-02-12 20:58:40 UTC (rev 1270)
+++ trunk/apps/monitoring/Monitoring.h 2009-02-12 21:23:17 UTC (rev 1271)
@@ -68,9 +68,14 @@
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:
Modified: trunk/doc/Readme.monitoring
===================================================================
--- trunk/doc/Readme.monitoring 2009-02-12 20:58:40 UTC (rev 1270)
+++ trunk/doc/Readme.monitoring 2009-02-12 21:23:17 UTC (rev 1271)
@@ -9,7 +9,7 @@
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 @@
------
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.)
_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev