isearch/comm/stat/StatTool.cc
2021-03-19 18:38:34 +08:00

614 lines
12 KiB
C++

#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include "StatClient.h"
#include "StatAttn.h"
#include "formater.h"
#include "DtcStatAlarmReporter.h"
#include "stat_index.h"
//#include "daemon.h"
//#include "ttc_global.h"
const char progname[] = "stattool";
const char usage_argv[] = "dump Id or reporter";
char cacheFile[256] = "index.conf";
char tableFile[256] = "";
CStatClient stc;
std::vector<CStatClient::iterator> idset;
CTableFormater out;
int outfmt = CTableFormater::FORMAT_ALIGNED;
unsigned char outnoname;
unsigned char rawdata;
unsigned char alldata;
unsigned char nobase;
#if __WORDSIZE >= 64
#define F64 "%ld"
#else
#define F64 "%lld"
#endif
static inline void cell_id(unsigned int id)
{
out.Cell("%u", id);
}
static inline void cell_sample_id(unsigned int id, unsigned int n)
{
if(outnoname)
out.Cell("%u.%u", id, n);
else
out.Cell("%u", id);
}
static inline void cell_name(const char *name)
{
if(outnoname) return;
if(outfmt == CTableFormater::FORMAT_ALIGNED)
out.Cell("%s:", name);
else
out.Cell("%s", name);
}
static inline void cell_dummy(void)
{
if(outfmt == CTableFormater::FORMAT_ALIGNED)
out.Cell("-");
else
#if GCC_MAJOR < 3
out.Cell(" ");
#else
out.Cell(NULL);
#endif
}
static inline void cell_base(int64_t v)
{
if(outnoname) return;
if(outfmt == CTableFormater::FORMAT_ALIGNED)
out.Cell("count[>="F64"]:", v);
else
out.Cell("count[>="F64"]", v);
}
static inline void cell_nbase(int v)
{
if(outfmt == CTableFormater::FORMAT_ALIGNED)
out.Cell("[%d]", v);
else
out.Cell("%d", v);
}
static inline void cell_int(int64_t val)
{
out.Cell(F64, val);
}
static inline void cell_fixed(int64_t val, int n, int div)
{
const char *sign = "";
if(val < 0)
{
val = - val;
sign = "-";
}
out.Cell("%s"F64".%0*d", sign, val/div, n, (int)(val%div));
}
static inline void cell_percent(int64_t val)
{
out.Cell(F64"%%", val);
}
static inline void cell_percent_fixed(int64_t val, int n, int div)
{
const char *sign = "";
if(val < 0)
{
val = - val;
sign = "-";
}
out.Cell("%s"F64".%0*d%%", sign, val/div, n, (int)(val%div));
}
static inline void cell_hms(int64_t val)
{
const char *sign = "";
if(val < 0)
{
val = - val;
sign = "-";
}
if(val < 60)
out.Cell("%s%d", sign, (int)val);
else if(val < 60*60)
out.Cell("%s%d:%02d", sign, (int)(val/60), (int)(val%60));
else
out.Cell("%s"F64":%02d:%02d", sign, val/3600, (int)((val/60)%60), (int)(val%60));
}
static inline void cell_hmsmsec(int64_t val)
{
const char *sign = "";
if(val < 0)
{
val = - val;
sign = "-";
}
if(val < 60*1000)
out.Cell("%s%d.%03d", sign, (int)(val/1000), (int)(val%1000));
else if(val < 60*60*1000)
out.Cell("%s%d:%02d.%03d", sign, (int)(val/60000), (int)((val/1000)%60), (int)(val%1000));
else
out.Cell("%s"F64":%02d:%02d.%03d", sign,
val/3600000, (int)((val/60000)%60), (int)((val/1000)%60), (int)(val%1000));
}
static inline void cell_hmsusec(int64_t val)
{
const char *sign = "";
if(val < 0)
{
val = - val;
sign = "-";
}
out.Cell("%s"F64".%06d", sign, val/1000000, (int)(val%1000000));
}
static inline void cell_datetime(int64_t v)
{
if(v==0) {
out.CellV("-");
return;
}
time_t t = v;
struct tm tm;
localtime_r(&t, &tm);
out.CellV("%d-%d-%d %d:%02d:%02d",
tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
}
static inline void cell_date(int64_t v)
{
if(v==0) {
out.CellV("-");
return;
}
time_t t = v;
struct tm tm;
localtime_r(&t, &tm);
out.CellV("%d-%d-%d",
tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday);
}
static inline void cell_version(int64_t v)
{
out.CellV("%d.%d.%d", (int)v/10000, (int)v/100%100, (int)v%100);
}
static inline void cell_bool(int64_t v)
{
if(0 == v)
{
out.CellV("NO");
}
else
{
out.CellV("YES");
}
}
inline void row_init(void)
{
out.NewRow();
}
inline void row_clear(void)
{
out.ClearRow();
}
inline void dump_table(void)
{
out.Dump(stdout, outfmt);
}
void cell_value(int unit, int64_t val)
{
if(rawdata) unit = SU_INT;
switch(unit)
{
default:
case SU_HIDE:
case SU_INT: cell_int(val); break;
case SU_INT_1: cell_fixed(val, 1, 10); break;
case SU_INT_2: cell_fixed(val, 2, 100); break;
case SU_INT_3: cell_fixed(val, 3, 1000); break;
case SU_INT_4: cell_fixed(val, 4, 10000); break;
case SU_INT_5: cell_fixed(val, 5, 100000); break;
case SU_INT_6: cell_fixed(val, 6, 1000000); break;
case SU_MSEC: cell_hmsmsec(val); break;
case SU_USEC: cell_hmsusec(val); break;
case SU_TIME: cell_hms(val); break;
case SU_DATE: cell_date(val); break;
case SU_DATETIME: cell_datetime(val); break;
case SU_VERSION: cell_version(val); break;
case SU_BOOL: cell_bool(val); break;
case SU_PERCENT: cell_percent(val); break;
case SU_PERCENT_1: cell_percent_fixed(val, 1, 10); break;
case SU_PERCENT_2: cell_percent_fixed(val, 2, 100); break;
case SU_PERCENT_3: cell_percent_fixed(val, 3, 1000); break;
}
}
void dump_data(void)
{
int64_t sc[16];
int sn;
unsigned int i;
CStatClient::iterator s;
stc.CheckPoint();
//printf("dump data %d\n",idset.size());
for(i = 0; i < idset.size(); i++)
{
s = idset[i];
if(alldata==0 && s->unit() == SU_HIDE)
continue;
row_init();
switch(s->type())
{
case SA_SAMPLE:
cell_id(s->id());
cell_name(s->name());
//cell_value(s->unit(), stc.ReadSampleAverage(s, SC_CUR));
cell_value(s->unit(), stc.ReadSampleAverage(s, SCC_10S));
cell_value(s->unit(), stc.ReadSampleAverage(s, SCC_10M));
cell_value(s->unit(), stc.ReadSampleAverage(s, SCC_ALL));
if(nobase<2)
{
row_init();
cell_sample_id(s->id(), 1);
cell_name("count[all]");
//cell_value(SU_INT, stc.ReadSampleCounter(s, SC_CUR));
cell_value(SU_INT, stc.ReadSampleCounter(s, SCC_10S));
cell_value(SU_INT, stc.ReadSampleCounter(s, SCC_10M));
cell_value(SU_INT, stc.ReadSampleCounter(s, SCC_ALL));
}
if(nobase==0)
{
sn = stc.GetCountBase(s->id(), sc);
for(int n=1; n<=sn; n++)
{
row_init();
cell_sample_id(s->id(), n+1);
cell_base(sc[n-1]);
//cell_value(SU_INT, stc.ReadSampleCounter(s, SC_CUR, n));
cell_value(SU_INT, stc.ReadSampleCounter(s, SCC_10S, n));
cell_value(SU_INT, stc.ReadSampleCounter(s, SCC_10M, n));
cell_value(SU_INT, stc.ReadSampleCounter(s, SCC_ALL, n));
}
}
break;
case SA_COUNT:
cell_id(s->id());
cell_name(s->name());
//cell_value(s->unit(), stc.ReadCounterValue(s, SC_CUR));
cell_value(s->unit(), stc.ReadCounterValue(s, SCC_10S));
cell_value(s->unit(), stc.ReadCounterValue(s, SCC_10M));
cell_value(s->unit(), stc.ReadCounterValue(s, SCC_ALL));
break;
case SA_VALUE:
cell_id(s->id());
cell_name(s->name());
//cell_value(s->unit(), stc.ReadCounterValue(s, SC_CUR));
cell_value(s->unit(), stc.ReadCounterValue(s, SCC_10S));
cell_value(s->unit(), stc.ReadCounterValue(s, SCC_10M));
cell_dummy();
break;
case SA_CONST:
cell_id(s->id());
cell_name(s->name());
cell_value(s->unit(), stc.ReadCounterValue(s, SCC_10S));
switch(s->unit())
{
case SU_DATETIME:
case SU_DATE:
case SU_VERSION:
case SU_BOOL:
break;
default:
//cell_dummy();
cell_dummy();
cell_dummy();
break;
}
break;
case SA_EXPR:
cell_id(s->id());
cell_name(s->name());
cell_dummy();
cell_value(s->unit(), stc.ReadCounterValue(s, SCC_10S));
cell_value(s->unit(), stc.ReadCounterValue(s, SCC_10M));
cell_value(s->unit(), stc.ReadCounterValue(s, SCC_ALL));
break;
default:
row_clear();
}
}
dump_table();
}
void dump_base(void)
{
int64_t sc[16];
int sn;
unsigned int i;
CStatClient::iterator s;
stc.CheckPoint();
for(i = 0; i < idset.size(); i++)
{
s = idset[i];
row_init();
sn = stc.GetCountBase(s->id(), sc);
cell_id(s->id());
cell_name(s->name());
cell_nbase(sn);
for(int n=0; n<sn; n++)
cell_value(s->unit(), sc[n]);
}
dump_table();
}
void create_files(const char *name)
{
char buf[256];
if(statmgr.CreateStatIndex(name, STATIDX, StatDefinition, buf, sizeof(buf)) < 0)
{
fprintf(stderr, "Fail to create stat index file: %s\n", buf);
exit(-3);
}
fprintf(stderr, "stat index created: %s\n", STATIDX);
}
void init(const char *name)
{
int ret;
ret = stc.InitStatInfo(name, STATIDX);
if(ret < 0)
{
fprintf(stderr, "Cannot Initialize StatInfo: %s\n", stc.ErrorMessage());
exit(-1);
}
}
void parse_stat_id(int argc, char **argv)
{
CStatClient::iterator n;
if(argc==0)
{
for(n = stc.begin(); n != stc.end(); n++)
idset.push_back(n);
return;
}
for(; argc>0; argc--, argv++)
{
int s, e;
switch(sscanf(argv[0], "%d-%d", &s, &e))
{
case 2:
for(n = stc.begin(); n != stc.end(); n++)
{
if((int)n->id() >= s && (int)n->id() <= e)
idset.push_back(n);
}
break;
case 1:
if((n = stc[s]) != NULL)
{
idset.push_back(n);
break;
}
// fall through
default:
fprintf(stderr, "Invalid stat id [%s]\n", argv[0]);
exit(-4);
}
}
}
void parse_sample_id(int argc, char **argv)
{
CStatClient::iterator n;
if(argc==0)
{
for(n = stc.begin(); n != stc.end(); n++)
if(n->issample())
idset.push_back(n);
return;
}
for(; argc>0; argc--, argv++)
{
int s, e;
switch(sscanf(argv[0], "%d-%d", &s, &e))
{
case 2:
for(n = stc.begin(); n != stc.end(); n++)
{
if((int)n->id() >= s && (int)n->id() <= e && n->issample())
idset.push_back(n);
}
break;
case 1:
if((n = stc[s]) != NULL && n->issample())
{
idset.push_back(n);
break;
}
// fall through
default:
fprintf(stderr, "Invalid stat sample id [%s]\n", argv[0]);
exit(-4);
}
}
}
void alter_base(int argc, char **argv)
{
CStatClient::iterator n = NULL;
int64_t sc[16];
if(argc==0 || (n=stc[atoi(argv[0])])==NULL)
{
fprintf(stderr, "A stat sample id required\n");
exit(-5);
}
argv++, argc--;
if(argc > 16)
{
fprintf(stderr, "number of count base must <= 16\n");
exit(-5);
}
for(int i=0; i<argc; i++)
sc[i] = strtoll(argv[i], 0, 0);
int ret = stc.SetCountBase(n->id(), sc, argc);
if(ret < 0)
{
fprintf(stderr, "setbase failed for id: %d\n", n->id());
exit(-5);
}
idset.push_back(n);
dump_base();
}
void usage(void)
{
fprintf(stderr,
"Usage: stattool [-nct] cmd [args...]\n"
"options list:\n"
" -a output hidden id too\n"
" -r output unformatted data\n"
" -n Don't output stat name\n"
" -t use tab seperated format\n"
" -c use [,] seperated format\n"
"command list:\n"
" create\n"
" dump name [id|id-id]...\n"
" getbase name [id|id-id]...\n"
" setbase name id v1 v2...\n"
);
exit(-2);
}
int main(int argc, char **argv)
{
argv++, --argc;
while(argc > 0 && argv[0][0]=='-')
{
const char *p = argv[0];
char c;
while((c=*++p))
{
switch(c)
{
case 'a':
alldata = 1;
break;
case 'b':
nobase++;
break;
case 'r':
rawdata = 1;
break;
case 't':
outfmt = CTableFormater::FORMAT_TABBED;
break;
case 'c':
outfmt = CTableFormater::FORMAT_COMMA;
break;
case 'n':
outnoname = 1;
break;
case 'h':
case '?':
default:
fprintf(stderr, "Unknown options [%c]\n", c);
usage();
}
}
argv++, --argc;
}
if(argc <= 0)
usage();
else if(!strcasecmp(argv[0], "help"))
usage();
else if(!strcasecmp(argv[0], "create"))
{
if(argc <= 1)
usage();
create_files(argv[1]);
}
else if(!strcasecmp(argv[0], "dump"))
{
if(argc <= 1)
usage();
init(argv[1]);
parse_stat_id(argc-=2, argv+=2);
dump_data();
}
else if(!strcasecmp(argv[0], "getbase"))
{
if(argc <= 1)
usage();
init(argv[1]);
parse_sample_id(argc-=2, argv+=2);
dump_base();
}
else if(!strcasecmp(argv[0], "setbase"))
{
if(argc <= 1)
usage();
init(argv[1]);
alter_base(argc-=2, argv+=2);
}
else if(!strcasecmp(argv[0], "reporter"))
{
// if(TTC_DaemonInit (argc, argv) < 0)
// return -1;
if(argc <= 2)
usage();
init(argv[1]);
ALARM_REPORTER->SetStatClient(&stc);
ALARM_REPORTER->SetTimeOut(5);
RunReporter(stc, argv[2]?:"");
} else
usage();
return 0;
}