stats server extended:

o set_loglevel 
 o get_loglevel
 o DI : call function via DI API 
 o which : get command list

query_stats program extended to accept commands

AmArgArray throws outofbound exception instead of assert



git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@253 8eb893ce-cfd4-0310-b710-fb5ebe64c474
sayer/1.4-spce2.6
Stefan Sayer 20 years ago
parent 4a82d793a3
commit 00e3b5b89f

@ -88,6 +88,10 @@ class AmArgArray
vector<AmArg> v;
public:
struct OutOfBoundsException {
OutOfBoundsException() { }
};
AmArgArray() : v() {}
AmArgArray(const AmArgArray& a) : v(a.v) {}
@ -97,7 +101,9 @@ public:
const AmArg& get(size_t idx) const {
assert(idx < v.size());
if (idx >= v.size())
throw OutOfBoundsException();
// assert(idx < v.size());
return v[idx];
}

@ -6,3 +6,6 @@ module_ldflags =
module_cflags =
include ../Makefile.app_module
query_stats: query_stats.c Makefile
$(GPP) $(CXX_FLAGS) -o query_stats query_stats.c

@ -1,3 +1,31 @@
/*
* $Id$
*
* Copyright (C) 2002-2003 Fhg Fokus
* Copyright (C) 2007 iptego GmbH
*
* This file is part of sems, a free SIP media server.
*
* sems is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version
*
* For a license to use the ser software under conditions
* other than those described here, or to purchase support for this
* software, please contact iptel.org by e-mail at the following addresses:
* info@iptel.org
*
* sems is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "StatsUDPServer.h"
#include "Statistics.h"
#include "AmConfigReader.h"
@ -5,6 +33,8 @@
#include "AmUtils.h"
#include "AmConfig.h"
#include "log.h"
#include "AmPlugIn.h"
#include "AmApi.h"
#include <string>
using std::string;
@ -212,8 +242,117 @@ int StatsUDPServer::execute(char* msg_buf, string& reply,
if(cmd_str == "calls")
reply = "Active calls: " + int2str(sc->getSize()) + "\n";
else
reply = "Unknown command: '" + cmd_str + "'\n";
else if (cmd_str == "which") {
reply =
"calls - number of active calls (Session Container size)\n"
"which - print available commands\n"
"set_loglevel <loglevel> - set log level\n"
"get_loglevel - get log level\n"
"\n"
"DI <factory> <function> (<args>)* - invoke DI command\n"
;
}
else if (cmd_str.length() > 4 && cmd_str.substr(0, 4) == "set_") {
// setters
if (cmd_str.substr(4, 8) == "loglevel") {
if (!AmConfig::setLoglevel(&cmd_str.c_str()[13]))
reply= "invalid loglevel value.\n";
else
reply= "loglevel set to "+int2str(log_level)+".\n";
}
else reply = "Unknown command: '" + cmd_str + "'\n";
}
else if (cmd_str.length() > 4 && cmd_str.substr(0, 4) == "get_") {
// setters
if (cmd_str.substr(4, 8) == "loglevel") {
reply= "loglevel is "+int2str(log_level)+".\n";
}
else reply = "Unknown command: '" + cmd_str + "'\n";
}
else if (cmd_str.length() > 4 && cmd_str.substr(0, 3) == "DI ") {
// Dynamic Invocation
size_t p = cmd_str.find(' ', 4);
string fact_name = cmd_str.substr(3, p-3);
if (!fact_name.length()) {
reply = "could not parse DI factory name.\n";
return 0;
}
size_t p2 = cmd_str.find(' ', p+1);
if (p2 == string::npos)
p2 = cmd_str.length();
string fct_name = cmd_str.substr(p+1, p2-p-1);
p=p2+1;
if (!fct_name.length()) {
reply = "could not parse function name.\n";
return 0;
}
try {
AmArgArray args;
while (p<cmd_str.length()) {
p2 = cmd_str.find(' ', p);
if (p2 == string::npos) {
if (p+1<cmd_str.length())
p2=cmd_str.length();
else
break;
}
args.push(cmd_str.substr(p, p2-p).c_str());
// DBG("mod '%s' added arg '%s'\n",
// fact_name.c_str(),
// cmd_str.substr(p, p2-p).c_str());
p=p2+1;
}
AmDynInvokeFactory* di_f = AmPlugIn::instance()->getFactory4Di(fact_name);
if(!di_f){
reply = "could not get '" + fact_name + "' factory\n";
return 0;
}
AmDynInvoke* di = di_f->getInstance();
if(!di){
reply = "could not get DI instance from factory\n";
return 0;
}
AmArgArray ret;
di->invoke(fct_name, args, ret);
if (ret.size()) {
reply="[";
for (unsigned int i=0;i<ret.size();i++) {
const AmArg& r = ret.get(i);
switch (r.getType()) {
case AmArg::CStr:
reply=reply + r.asCStr(); break;
case AmArg::Int:
reply=reply + int2str(r.asInt()); break;
case AmArg::Double: {
char res[10];
snprintf(res, 10, "%e", r.asDouble());
reply=reply + res;
} break;
default: break;
}
if (i<ret.size()-1) reply = reply + ",";
}
reply+="]\n";
} else
reply = "(none)\n";
} catch (const AmDynInvoke::NotImplemented& e) {
reply = "Exception occured: AmDynInvoke::NotImplemented '"+
e.what+"'\n";
return 0;
} catch (...) {
reply = "Exception occured.\n";
return 0;
}
}
else
reply = "Unknown command: '" + cmd_str + "'\n";
return 0;
}

@ -1,21 +1,40 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <map>
using std::map;
#include <string>
using std::string;
#define MSG_BUF_SIZE 256
#define MSG_BUF_SIZE 2048
void print_usage(const char * progname)
{
fprintf(stderr,
"Syntax: %s ip_address port\n",
progname
"Syntax: %s [<options>]\n"
"\n"
"where <options>: \n"
" -s <server> : server name|ip (default: 127.0.0.1)\n"
" -p <port> : server port (default: 50040)\n"
" -c <cmd> : command (default: calls)\n"
"\n"
"Tips: \n"
" o quote the command if it has arguments (e.g. %s -c \"set_loglevel 1\")\n"
" o \"which\" prints available commands\n"
,
progname, progname
);
}
static int parse_args(int argc, char* argv[], const string& flags,
const string& options, map<char,string>& args);
/* returns non-zero if error occured */
int str2i(const char* str, unsigned short* result)
@ -47,44 +66,60 @@ error_char:
return -1;
}
char* append_str(const char* buf, const char* str, unsigned int str_s)
{
memcpy(buf,str,str_s);
buf += str_s;
}
int main(int argc, char** argv)
{
char msg_buf[MSG_BUF_SIZE];
char *p_buf;
int msg_size=10, sd, err;
char rcv_buf[MSG_BUF_SIZE];
string msg_buf;
int sd, err;
struct sockaddr_in addr;
map<char,string> args;
if(argc != 3){
print_usage(argv[0]);
return -1;
if(parse_args(argc, argv, "h","spc", args)){
print_usage(argv[0]);
return -1;
}
if(!inet_aton(argv[1],&addr.sin_addr)){
fprintf(stderr,"'%s' is an invalid IP address\n",argv[1]);
return -1;
string server="127.0.0.1";
string port="50040";
string cmd="calls";
for(map<char,string>::iterator it = args.begin();
it != args.end(); ++it){
if(it->second.empty())
continue;
switch( it->first ){
case 'h': { print_usage(argv[0]); exit(1); } break;
case 's': { server=it->second; } break;
case 'p': { port=it->second; } break;
case 'c': { cmd=it->second; } break;
}
}
if(!inet_aton(server.c_str(),&addr.sin_addr)){
fprintf(stderr,"server '%s' is an invalid IP address\n",server.c_str());
return -1;
}
if(str2i(argv[2],&addr.sin_port) == -1){
fprintf(stderr,"'%s' is not a valid integer\n",argv[2]);
return -1;
if(str2i(port.c_str(),&addr.sin_port) == -1){
fprintf(stderr,"port '%s' is not a valid integer\n",port.c_str());
return -1;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(addr.sin_port);
/*TODO: build msg to send */
p_buf = msg_buf;
p_buf = append_str(p_buf,"calls\n",6);
msg_buf = cmd;
printf("sending '%s\\n' to %s:%s\n", msg_buf.c_str(),
server.c_str(), port.c_str());
msg_buf += "\n";
sd = socket(PF_INET,SOCK_DGRAM,0);
err = sendto(sd,msg_buf,msg_size,0,
err = sendto(sd,msg_buf.c_str(),msg_buf.length(),0,
(const struct sockaddr*)&addr,
sizeof(struct sockaddr_in));
@ -92,13 +127,49 @@ int main(int argc, char** argv)
fprintf(stderr,"sendto: %s\n",strerror(errno));
}
else {
msg_size = recv(sd,msg_buf,MSG_BUF_SIZE,0);
int msg_size = recv(sd,rcv_buf,MSG_BUF_SIZE,0);
if(msg_size == -1)
fprintf(stderr,"recv: %s\n",strerror(errno));
else
printf("received:\n%.*s",msg_size-1,msg_buf);
printf("received:\n%.*s",msg_size-1,rcv_buf);
}
close(sd);
return 0;
}
static int parse_args(int argc, char* argv[],
const string& flags,
const string& options,
map<char,string>& args)
{
for(int i=1; i<argc; i++){
char* arg = argv[i];
if( (*arg != '-') || !*(++arg) ) {
fprintf(stderr,"%s: invalid parameter: '%s'\n",argv[0],argv[i]);
return -1;
}
if( flags.find(*arg) != string::npos ) {
args[*arg] = "yes";
}
else if(options.find(*arg) != string::npos) {
if(!argv[++i]){
fprintf(stderr,"%s: missing argument for parameter '-%c'\n",argv[0],*arg);
return -1;
}
args[*arg] = argv[i];
}
else {
fprintf(stderr,"%s: unknown parameter '-%c'\n",argv[0],arg[1]);
return -1;
}
}
return 0;
}

Loading…
Cancel
Save