Сбор статистики руками из базы
Сбор статистики руками из базы
Версия UTM с номером сборки: 5.1.10-005-linux
Версия ОС (например, FreeBSD 5.3 или RedHat Linux 9): RH EL AS 3.0
Всем привет
Не подскажете какой должен быть прямой запрос к базе данных для снятия детальной статистики. А то у нас переодически через админский интерфейс она не формируется. И хотелось бы ее просто ручками забрать
Версия ОС (например, FreeBSD 5.3 или RedHat Linux 9): RH EL AS 3.0
Всем привет
Не подскажете какой должен быть прямой запрос к базе данных для снятия детальной статистики. А то у нас переодически через админский интерфейс она не формируется. И хотелось бы ее просто ручками забрать
-
- Сообщения: 3
- Зарегистрирован: Чт мар 03, 2005 11:12
Странная ошибка
Хотел взять детальную статистику perl-ом. Всё-бы хорошо, sybsql работает, сервер отвечает, и перловые модуля для Gigabse с ней-же даются. Тыкался к гигаБАЗЕ и через перловый DBI и через CLI-интерфейсы. fetch()-еобразные команды хотят выполниться. На время забыв про УТМ и попользовав всячески examples, которые с gigabse даются, получал всякий раз одну и ту-же ошибку: substr outside of string at /usr/local/lib/perl5/site_perl/5.8.0/Gigabase.pm line 149.
Грабли скорее всего в @INC/Gigabase.pm, что не есть хорошо. И документации совсем немного.
Версии gigabase 3.xx разные пробовал, perl-ы 5.6.x -5.8.x пробовал, ось FreeBSD5.1 По-другому статистику завсегда взять можно, а хотелось перлом. Может кто сталкивался с такой бякой?
P.S. Ай-пи адреса в базах детальной статистики select inet_ntoa() из MySQL просят, что не есть хорошо.
Грабли скорее всего в @INC/Gigabase.pm, что не есть хорошо. И документации совсем немного.
Версии gigabase 3.xx разные пробовал, perl-ы 5.6.x -5.8.x пробовал, ось FreeBSD5.1 По-другому статистику завсегда взять можно, а хотелось перлом. Может кто сталкивался с такой бякой?
P.S. Ай-пи адреса в базах детальной статистики select inet_ntoa() из MySQL просят, что не есть хорошо.
Наваял для удобства программку на C++. Работает под FBSD 5.3. Может кому пригодится.
Компилить:
Запускать:
Сорц:
Единственное что заметил, так это то, что текущий файл с трафиком, в который пишет UTM5, не открывается. Но я программку делал, чтобы старую детальку вытаскивать -- мне не мешает. + не стоит вторгаться и в без того не отличающуюся стабильностью систему 
Компилить:
Код: Выделить всё
g++ -g -I/usr/local/include/gigabase -L/usr/local/lib -lgigabase_r -pthread -o utm_det utm_detail.cpp
Код: Выделить всё
./utm_det -d /netup/trafficdb -s 3357 -o out -t 1106390340
Код: Выделить всё
#undef DEBUG
#include "gigabase.h"
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <functional>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <dirent.h>
#include <sys/types.h>
#include <unistd.h>
#ifndef USE_GIGABASE_NAMESPACE
#define USE_GIGABASE_NAMESPACE
#endif
USE_GIGABASE_NAMESPACE
const int4 t_now = 0x7FFFFFFF;
class iptraffic_raw { // {{{
public:
int4 slink_id;
int4 srcaddr;
int4 dstaddr;
int4 nexthop;
int4 input;
int4 output;
int4 dPkts;
int4 dOctets;
int4 First;
int4 Last;
int4 srcport;
int4 dstport;
int4 pad;
int4 tcp_flags;
int4 prot;
int4 tos;
int4 src_as;
int4 dst_as;
int4 src_mask;
int4 dst_mask;
int4 t_class;
int4 account_id;
int4 timestamp;
TYPE_DESCRIPTOR((
KEY(slink_id, INDEXED),
FIELD(srcaddr),
FIELD(dstaddr),
FIELD(nexthop),
FIELD(input),
FIELD(output),
FIELD(dPkts),
FIELD(dOctets),
FIELD(First),
FIELD(Last),
FIELD(srcport),
FIELD(dstport),
FIELD(pad),
FIELD(tcp_flags),
FIELD(prot),
FIELD(tos),
FIELD(src_as),
FIELD(dst_as),
FIELD(src_mask),
FIELD(dst_mask),
FIELD(t_class),
FIELD(account_id),
KEY(timestamp, INDEXED)
));
}; // }}}
static std::string formatip(unsigned int ip) { // {{{
std::ostringstream oss;
oss
<< static_cast<unsigned int>(ip >> 24) << '.'
<< static_cast<unsigned int>( (ip >> 16) & 0xFF ) << '.'
<< static_cast<unsigned int>( (ip >> 8) & 0xFF ) << '.'
<< static_cast<unsigned int>( (ip) & 0xFF );
return oss.str();
} // }}}
static std::string formatdate(int date) { // {{{
char buf[128];
strftime(buf, 128, "%d.%m.%Y %H:%M:%S", localtime(static_cast<time_t *>(&date)));
return std::string(buf);
} // }}}
static void usage() { // {{{
std::cout << "Usage: " << std::endl;
std::cout << " -f -- FROM-Time (in UNIX timestamp)" << std::endl;
std::cout << " -t -- TO-Time (in UNIX timestamp)" << std::endl;
std::cout << " -a -- Account ID" << std::endl;
std::cout << " -s -- Service Link ID" << std::endl;
std::cout << " -d -- Directory with DB Files" << std::endl;
std::cout << " -o -- Output File" << std::endl;
std::cout << "You have to specify (-a) or (-s)." << std::endl;
} // }}}
REGISTER(iptraffic_raw);
int main(int argc, char *argv[]) {
int4 t_from = 0, t_to = 0;
int account_id = 0, slink_id = 0;
char traffic_dir[MAXNAMLEN + 1];
memset(traffic_dir, 0, MAXNAMLEN + 1);
char output_file[MAXNAMLEN + 1];
memset(output_file, 0, MAXNAMLEN + 1);
{ // Arguments {{{
int c = 0;
while( (c = getopt(argc, argv, "f:t:a:s:d:o:")) != -1 ) {
switch(c) {
case 'f':
t_from = strtoul(optarg, NULL, 10);
break;
case 't':
t_to = strtoul(optarg, NULL, 10);
break;
case 'a':
account_id = strtoul(optarg, NULL, 10);
break;
case 's':
slink_id = strtoul(optarg, NULL, 10);
break;
case 'd':
strncpy(traffic_dir, optarg, MAXNAMLEN);
break;
case 'o':
strncpy(output_file, optarg, MAXNAMLEN);
break;
}
}
argc -= optind;
argv += optind;
} // }}}
// Arguments validation {{{
if(0 == account_id && 0 == slink_id) {
std::cerr << "Neither account ID or service link ID specified." << std::endl;
usage();
return 1;
}
if(0 != account_id && 0 != slink_id) {
std::cerr << "You can specify only account ID or a service link ID, but not both of them." << std::endl;
usage();
return 1;
}
if(0 == t_to) {
t_to = t_now;
}
if(t_from > t_to) {
std::cerr << "From-time is larger, than To-time" << std::endl;
usage();
return 1;
}
if(0 == traffic_dir[0]) {
strncpy(traffic_dir, "/netup/utm5/db/", MAXNAMLEN);
}
if(0 == output_file[0]) {
strncpy(output_file, "detail.xml", MAXNAMLEN);
}
std::cout << " -- Got CLI parameters: " << std::endl;
std::cout << " Fetching traffic information for ";
if(0 != account_id) {
std::cout << "account #" << account_id;
}
if(0 != slink_id) {
std::cout << "service link #" << slink_id;
}
std::cout << std::endl;
std::cout << " Time range: [" << t_from << " -> " << t_to << "]" << std::endl;
std::cout << " Traffic directory: " << traffic_dir << std::endl;
// }}}
// Raw files gathering {{{
std::vector<int4> v_dates;
v_dates.reserve(256);
{
DIR *traffic_dp = opendir(traffic_dir);
if(NULL == traffic_dp) {
std::cout << "Cannot open traffic directory." << std::endl;
return 1;
}
struct dirent *traffic_entry = NULL;
while( (traffic_entry = readdir(traffic_dp)) != NULL) {
if(0 == strncmp("iptraffic_raw", traffic_entry->d_name, strlen("iptraffic_raw"))) {
if(0 == strncmp("iptraffic_raw.dbs", traffic_entry->d_name, MAXNAMLEN))
v_dates.push_back(t_now);
else {
v_dates.push_back(strtoul(traffic_entry->d_name + strlen("iptraffic_raw") + 1, NULL, 10));
}
}
}
closedir(traffic_dp);
}
std::sort(v_dates.begin(), v_dates.end());
#ifdef DEBUG
// std::cout << "DEBUG: Got these dates: " << std::endl;
// std::copy(v_dates.begin(), v_dates.end(), std::ostream_iterator<int4>(std::cout, "\n"));
#endif
std::vector<int4>::iterator it = v_dates.begin(), jt = v_dates.end();
it = std::find_if(
v_dates.begin(), v_dates.end(),
std::bind2nd(std::greater_equal<std::vector<int4>::value_type>(), t_from)
);
jt = std::find_if(
it, v_dates.end(),
std::bind2nd(std::greater<std::vector<int4>::value_type>(), t_to)
);
#ifdef DEBUG
std::cout << "Start & End iterators are pointing to: " << *it << " and " << *jt << std::endl;
#endif
v_dates.erase(jt, v_dates.end());
v_dates.erase(v_dates.begin(), it);
it = v_dates.begin();
jt = v_dates.end();
#ifdef DEBUG
std::cout << "DEBUG: Will use these dates: " << std::endl;
std::copy(it, jt, std::ostream_iterator<int4>(std::cout, "\n"));
#endif
// }}}
std::ostringstream oss;
std::ofstream out(output_file, std::ios::out);
if(!out) {
std::cerr << "Cannot open output file." << std::endl;
return 1;
}
out << "<?xml version=\"1.0\" encoding=\"Windows-1251\"?>" << std::endl;
out << "<UTM>" << std::endl;
dbDatabase db(dbDatabase::dbReadOnly);
db.attach();
dbQuery query;
dbQueryExpression q_filter;
if(0 != account_id) {
q_filter = "account_id =", account_id;
} else if(0 != slink_id) {
q_filter = "slink_id =", slink_id;
}
if(t_now == t_to && 0 == t_from) {
query = q_filter;
} else {
dbQueryExpression q_time;
if(t_now == t_to) {
q_time = "timestamp >=", t_from;
} else if(0 == t_from) {
q_time = "timestamp <=", t_to;
} else {
q_time = "timestamp between", t_from, "and", t_to;
}
query = q_time, "and", q_filter;
}
#ifdef DEBUG
{
char *buffer = new char[256];
query.dump(buffer);
std::cout << "DEBUG: Constructed query: " << buffer << std::endl;
delete[] buffer;
}
#endif
dbCursor<iptraffic_raw> cursor(&db);
unsigned long affrows = 0;
while(it != jt) {
oss.str("");
oss << traffic_dir << '/';
if(*it == t_now) oss << "iptraffic_raw.dbs";
else oss << "iptraffic_raw_" << *it << ".dbs";
std::cout << "Giga: Opening " << oss.str() << "... " << std::flush;
if(db.open(oss.str().c_str())) {
std::cout << "File opened successfully." << std::endl;
std::cout << "Performing 'SELECT'... " << std::flush;
affrows = cursor.select(query, dbCursorViewOnly);
std::cout << "Affected rows: " << affrows << std::endl;
if(affrows > 0) {
// Fetching results {{{
do {
out << "<account "
<< "Дата=\"" << formatdate(cursor->timestamp) << "\" "
<< "ID_связки=\"" << cursor->slink_id << "\" "
<< "Account_ID=\"" << cursor->account_id << "\" "
<< "Класс_трафика=\"" << cursor->t_class << "\" "
<< "Источник=\"" << formatip(cursor->srcaddr) << "\" "
<< "Получатель=\"" << formatip(cursor->dstaddr) << "\" "
<< "Пакетов=\"" << cursor->dPkts << "\" "
<< "Байт=\"" << cursor->dOctets << "\" "
<< "Порт_ист.=\"" << cursor->srcport << "\" "
<< "Порт_получ.=\"" << cursor->dstport << "\" "
<< "TCP-флаги=\"" << cursor->tcp_flags << "\" "
<< "протокол=\"" << cursor->prot << "\" "
<< "Tos=\"" << cursor->tos << "\" "
<< "/>" << std::endl;
} while(cursor.next());
// }}}
}
db.close();
} else {
std::cerr << "Cannot open file." << std::endl;
}
++it;
}
out << "</UTM>" << std::endl;
out.close();
return 0;
}

UTM5/FreeBSD 5.3/MySQL 4.1/ipcad
Попробовал: собирается и запускается.
1) Собирал под gigabase 3.31 в обоих системах. Какая у вас версия gigabase?
2) Линух - гентушный, gcc 3.4.
Понадобилось статический каст в 93-ей строке на reinterpret заменить (3.4-ый gcc не хочет иначе указатель кастовать).
3) Библиотека gigabase подгружается? (ldd на бинарник - должен найти либу).
1) Собирал под gigabase 3.31 в обоих системах. Какая у вас версия gigabase?
2) Линух - гентушный, gcc 3.4.
Код: Выделить всё
g++ -g -lgigabase_r -lpthread -I/usr/include/gigabase -o utm_det utm_detail.cpp
3) Библиотека gigabase подгружается? (ldd на бинарник - должен найти либу).
UTM5/FreeBSD 5.3/MySQL 4.1/ipcad