Сбор статистики руками из базы

Технические вопросы по UTM 5.0
Ответить
das-ich
Сообщения: 9
Зарегистрирован: Чт мар 03, 2005 13:08

Сбор статистики руками из базы

Сообщение das-ich »

Версия UTM с номером сборки: 5.1.10-005-linux
Версия ОС (например, FreeBSD 5.3 или RedHat Linux 9): RH EL AS 3.0
Всем привет
Не подскажете какой должен быть прямой запрос к базе данных для снятия детальной статистики. А то у нас переодически через админский интерфейс она не формируется. И хотелось бы ее просто ручками забрать

SJ
Сообщения: 40
Зарегистрирован: Пт янв 21, 2005 16:22
Откуда: SPb

Сообщение SJ »

детальная статистика хранится не в SQL базе данных

das-ich
Сообщения: 9
Зарегистрирован: Чт мар 03, 2005 13:08

Сообщение das-ich »

ну да я вспомнил что она в .dbs хранится. А как ее ручуми от туда достать? Ведь админский интерфейс это какой-то командой делает

Marat Suyargulov
Сообщения: 3
Зарегистрирован: Чт мар 03, 2005 11:12

Сообщение Marat Suyargulov »

Почитайте внимательно FAQ там есть примеры работы с файлами детального трафика.

das-ich
Сообщения: 9
Зарегистрирован: Чт мар 03, 2005 13:08

Сообщение das-ich »

Поставил себе этот гигабасе (про который в FAQ пишут) и не чего он ни делает, а тока ругается при открытии файла
Invalid symbol at line 1 position 0
и усё.
Может кто знает в чем проблема с этим гигабасе.

Vitay
Сообщения: 1
Зарегистрирован: Ср мар 23, 2005 10:55

Странная ошибка

Сообщение Vitay »

Хотел взять детальную статистику 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 просят, что не есть хорошо.

Sandello
Сообщения: 26
Зарегистрирован: Чт фев 10, 2005 18:54

Сообщение Sandello »

Наваял для удобства программку на C++. Работает под FBSD 5.3. Может кому пригодится.
Компилить:

Код: Выделить всё

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 &#123; // &#123;&#123;&#123;
        public&#58;
                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&#40;&#40;
                        KEY&#40;slink_id, INDEXED&#41;,
                        FIELD&#40;srcaddr&#41;,
                        FIELD&#40;dstaddr&#41;,
                        FIELD&#40;nexthop&#41;,
                        FIELD&#40;input&#41;,
                        FIELD&#40;output&#41;,
                        FIELD&#40;dPkts&#41;,
                        FIELD&#40;dOctets&#41;,
                        FIELD&#40;First&#41;,
                        FIELD&#40;Last&#41;,
                        FIELD&#40;srcport&#41;,
                        FIELD&#40;dstport&#41;,
                        FIELD&#40;pad&#41;,
                        FIELD&#40;tcp_flags&#41;,
                        FIELD&#40;prot&#41;,
                        FIELD&#40;tos&#41;,
                        FIELD&#40;src_as&#41;,
                        FIELD&#40;dst_as&#41;,
                        FIELD&#40;src_mask&#41;,
                        FIELD&#40;dst_mask&#41;,
                        FIELD&#40;t_class&#41;,
                        FIELD&#40;account_id&#41;,
                        KEY&#40;timestamp, INDEXED&#41;
                &#41;&#41;;
&#125;; // &#125;&#125;&#125;

static std&#58;&#58;string formatip&#40;unsigned int ip&#41; &#123; // &#123;&#123;&#123;
        std&#58;&#58;ostringstream oss;
        oss
                << static_cast<unsigned int>&#40;ip >> 24&#41; << '.'
                << static_cast<unsigned int>&#40; &#40;ip >> 16&#41; & 0xFF &#41; << '.'
                << static_cast<unsigned int>&#40; &#40;ip >> 8&#41; & 0xFF &#41; << '.'
                << static_cast<unsigned int>&#40; &#40;ip&#41; & 0xFF &#41;;

        return oss.str&#40;&#41;;
&#125; // &#125;&#125;&#125;

static std&#58;&#58;string formatdate&#40;int date&#41; &#123; // &#123;&#123;&#123;
        char buf&#91;128&#93;;

        strftime&#40;buf, 128, "%d.%m.%Y %H&#58;%M&#58;%S", localtime&#40;static_cast<time_t *>&#40;&date&#41;&#41;&#41;;

        return std&#58;&#58;string&#40;buf&#41;;
&#125; // &#125;&#125;&#125;

static void usage&#40;&#41; &#123; // &#123;&#123;&#123;
        std&#58;&#58;cout << "Usage&#58; " << std&#58;&#58;endl;
        std&#58;&#58;cout << " -f     -- FROM-Time &#40;in UNIX timestamp&#41;" << std&#58;&#58;endl;
        std&#58;&#58;cout << " -t     -- TO-Time &#40;in UNIX timestamp&#41;" << std&#58;&#58;endl;
        std&#58;&#58;cout << " -a     -- Account ID" << std&#58;&#58;endl;
        std&#58;&#58;cout << " -s     -- Service Link ID" << std&#58;&#58;endl;
        std&#58;&#58;cout << " -d     -- Directory with DB Files" << std&#58;&#58;endl;
        std&#58;&#58;cout << " -o     -- Output File" << std&#58;&#58;endl;
        std&#58;&#58;cout << "You have to specify &#40;-a&#41; or &#40;-s&#41;." << std&#58;&#58;endl;
&#125; // &#125;&#125;&#125;

REGISTER&#40;iptraffic_raw&#41;;

int main&#40;int argc, char *argv&#91;&#93;&#41; &#123;
        int4 t_from = 0, t_to = 0;
        int account_id = 0, slink_id = 0;

        char traffic_dir&#91;MAXNAMLEN + 1&#93;;
        memset&#40;traffic_dir, 0, MAXNAMLEN + 1&#41;;
        char output_file&#91;MAXNAMLEN + 1&#93;;
        memset&#40;output_file, 0, MAXNAMLEN + 1&#41;;

        &#123; // Arguments &#123;&#123;&#123;
                int c = 0;

                while&#40; &#40;c = getopt&#40;argc, argv, "f&#58;t&#58;a&#58;s&#58;d&#58;o&#58;"&#41;&#41; != -1 &#41; &#123;
                        switch&#40;c&#41; &#123;
                                case 'f'&#58;
                                        t_from = strtoul&#40;optarg, NULL, 10&#41;;
                                        break;
                                case 't'&#58;
                                        t_to = strtoul&#40;optarg, NULL, 10&#41;;
                                        break;
                                case 'a'&#58;
                                        account_id = strtoul&#40;optarg, NULL, 10&#41;;
                                        break;
                                case 's'&#58;
                                        slink_id = strtoul&#40;optarg, NULL, 10&#41;;
                                        break;
                                case 'd'&#58;
                                        strncpy&#40;traffic_dir, optarg, MAXNAMLEN&#41;;
                                        break;
                                case 'o'&#58;
                                        strncpy&#40;output_file, optarg, MAXNAMLEN&#41;;
                                        break;
                        &#125;
                &#125;
                argc -= optind;
                argv += optind;
        &#125; // &#125;&#125;&#125;

        // Arguments validation &#123;&#123;&#123;
        if&#40;0 == account_id && 0 == slink_id&#41; &#123;
                std&#58;&#58;cerr << "Neither account ID or service link ID specified." << std&#58;&#58;endl;
                usage&#40;&#41;;
                return 1;
        &#125;
        if&#40;0 != account_id && 0 != slink_id&#41; &#123;
                std&#58;&#58;cerr << "You can specify only account ID or a service link ID, but not both of them." << std&#58;&#58;endl;
                usage&#40;&#41;;
                return 1;
        &#125;
        if&#40;0 == t_to&#41; &#123;
                t_to = t_now;
        &#125;
        if&#40;t_from > t_to&#41; &#123;
                std&#58;&#58;cerr << "From-time is larger, than To-time" << std&#58;&#58;endl;
                usage&#40;&#41;;
                return 1;
        &#125;
        if&#40;0 == traffic_dir&#91;0&#93;&#41; &#123;
                strncpy&#40;traffic_dir, "/netup/utm5/db/", MAXNAMLEN&#41;;
        &#125;
        if&#40;0 == output_file&#91;0&#93;&#41; &#123;
                strncpy&#40;output_file, "detail.xml", MAXNAMLEN&#41;;
        &#125;

        std&#58;&#58;cout << " -- Got CLI parameters&#58; " << std&#58;&#58;endl;
        std&#58;&#58;cout << "    Fetching traffic information for ";
        if&#40;0 != account_id&#41; &#123;
                std&#58;&#58;cout << "account #" << account_id;
        &#125;
        if&#40;0 != slink_id&#41; &#123;
                std&#58;&#58;cout << "service link #" << slink_id;
        &#125;
        std&#58;&#58;cout << std&#58;&#58;endl;

        std&#58;&#58;cout << "    Time range&#58; &#91;" << t_from << " -> " << t_to << "&#93;" << std&#58;&#58;endl;
        std&#58;&#58;cout << "    Traffic directory&#58; " << traffic_dir << std&#58;&#58;endl;
        // &#125;&#125;&#125;

        // Raw files gathering &#123;&#123;&#123;
        std&#58;&#58;vector<int4> v_dates;
        v_dates.reserve&#40;256&#41;;

        &#123;
                DIR *traffic_dp = opendir&#40;traffic_dir&#41;;
                if&#40;NULL == traffic_dp&#41; &#123;
                        std&#58;&#58;cout << "Cannot open traffic directory." << std&#58;&#58;endl;
                        return 1;
                &#125;

                struct dirent *traffic_entry = NULL;
                while&#40; &#40;traffic_entry = readdir&#40;traffic_dp&#41;&#41; != NULL&#41; &#123;
                        if&#40;0 == strncmp&#40;"iptraffic_raw", traffic_entry->d_name, strlen&#40;"iptraffic_raw"&#41;&#41;&#41; &#123;
                                if&#40;0 == strncmp&#40;"iptraffic_raw.dbs", traffic_entry->d_name, MAXNAMLEN&#41;&#41;
                                        v_dates.push_back&#40;t_now&#41;;
                                else &#123;
                                        v_dates.push_back&#40;strtoul&#40;traffic_entry->d_name + strlen&#40;"iptraffic_raw"&#41; + 1, NULL, 10&#41;&#41;;
                                &#125;
                        &#125;
                &#125;

                closedir&#40;traffic_dp&#41;;
        &#125;

        std&#58;&#58;sort&#40;v_dates.begin&#40;&#41;, v_dates.end&#40;&#41;&#41;;

#ifdef DEBUG
//      std&#58;&#58;cout << "DEBUG&#58; Got these dates&#58; " << std&#58;&#58;endl;
//      std&#58;&#58;copy&#40;v_dates.begin&#40;&#41;, v_dates.end&#40;&#41;, std&#58;&#58;ostream_iterator<int4>&#40;std&#58;&#58;cout, "\n"&#41;&#41;;
#endif

        std&#58;&#58;vector<int4>&#58;&#58;iterator it = v_dates.begin&#40;&#41;, jt = v_dates.end&#40;&#41;;

        it = std&#58;&#58;find_if&#40;
                v_dates.begin&#40;&#41;, v_dates.end&#40;&#41;,
                std&#58;&#58;bind2nd&#40;std&#58;&#58;greater_equal<std&#58;&#58;vector<int4>&#58;&#58;value_type>&#40;&#41;, t_from&#41;
        &#41;;

        jt = std&#58;&#58;find_if&#40;
                it, v_dates.end&#40;&#41;,
                std&#58;&#58;bind2nd&#40;std&#58;&#58;greater<std&#58;&#58;vector<int4>&#58;&#58;value_type>&#40;&#41;, t_to&#41;
        &#41;;

#ifdef DEBUG
        std&#58;&#58;cout << "Start & End iterators are pointing to&#58; " << *it << " and " << *jt << std&#58;&#58;endl;
#endif

        v_dates.erase&#40;jt, v_dates.end&#40;&#41;&#41;;
        v_dates.erase&#40;v_dates.begin&#40;&#41;, it&#41;;

        it = v_dates.begin&#40;&#41;;
        jt = v_dates.end&#40;&#41;;
#ifdef DEBUG
        std&#58;&#58;cout << "DEBUG&#58; Will use these dates&#58; " << std&#58;&#58;endl;
        std&#58;&#58;copy&#40;it, jt, std&#58;&#58;ostream_iterator<int4>&#40;std&#58;&#58;cout, "\n"&#41;&#41;;
#endif
        // &#125;&#125;&#125;

        std&#58;&#58;ostringstream oss;
        std&#58;&#58;ofstream out&#40;output_file, std&#58;&#58;ios&#58;&#58;out&#41;;
        if&#40;!out&#41; &#123;
                std&#58;&#58;cerr << "Cannot open output file." << std&#58;&#58;endl;
                return 1;
        &#125;

        out << "<?xml version=\"1.0\" encoding=\"Windows-1251\"?>" << std&#58;&#58;endl;
        out << "<UTM>" << std&#58;&#58;endl;

        dbDatabase db&#40;dbDatabase&#58;&#58;dbReadOnly&#41;;

        db.attach&#40;&#41;;

        dbQuery query;
        dbQueryExpression q_filter;

        if&#40;0 != account_id&#41; &#123;
                q_filter = "account_id =", account_id;
        &#125; else if&#40;0 != slink_id&#41; &#123;
                q_filter = "slink_id =", slink_id;
        &#125;

        if&#40;t_now == t_to && 0 == t_from&#41; &#123;
                query = q_filter;
        &#125; else &#123;
                dbQueryExpression q_time;

                if&#40;t_now == t_to&#41; &#123;
                        q_time = "timestamp >=", t_from;
                &#125; else if&#40;0 == t_from&#41; &#123;
                        q_time = "timestamp <=", t_to;
                &#125; else &#123;
                        q_time = "timestamp between", t_from, "and", t_to;
                &#125;

                query = q_time, "and", q_filter;
        &#125;

#ifdef DEBUG
        &#123;
                char *buffer = new char&#91;256&#93;;
                query.dump&#40;buffer&#41;;
                std&#58;&#58;cout << "DEBUG&#58; Constructed query&#58; " << buffer << std&#58;&#58;endl;
                delete&#91;&#93; buffer;
        &#125;
#endif

        dbCursor<iptraffic_raw> cursor&#40;&db&#41;;

        unsigned long affrows = 0;

        while&#40;it != jt&#41; &#123;
                oss.str&#40;""&#41;;
                oss << traffic_dir << '/';
                if&#40;*it == t_now&#41; oss << "iptraffic_raw.dbs";
                else oss << "iptraffic_raw_" << *it << ".dbs";
                std&#58;&#58;cout << "Giga&#58; Opening " << oss.str&#40;&#41; << "... " << std&#58;&#58;flush;

                if&#40;db.open&#40;oss.str&#40;&#41;.c_str&#40;&#41;&#41;&#41; &#123;
                        std&#58;&#58;cout << "File opened successfully." << std&#58;&#58;endl;

                        std&#58;&#58;cout << "Performing 'SELECT'... " << std&#58;&#58;flush;
                        affrows = cursor.select&#40;query, dbCursorViewOnly&#41;;
                        std&#58;&#58;cout << "Affected rows&#58; " << affrows << std&#58;&#58;endl;

                        if&#40;affrows > 0&#41; &#123;
                                // Fetching results &#123;&#123;&#123;
                                do &#123;
                                        out << "<account "
                                                << "Дата=\"" << formatdate&#40;cursor->timestamp&#41; << "\" "
                                                << "ID_связки=\"" << cursor->slink_id << "\" "
                                                << "Account_ID=\"" << cursor->account_id << "\" "
                                                << "Класс_трафика=\"" << cursor->t_class << "\" "
                                                << "Источник=\"" << formatip&#40;cursor->srcaddr&#41; << "\" "
                                                << "Получатель=\"" << formatip&#40;cursor->dstaddr&#41; << "\" "
                                                << "Пакетов=\"" << cursor->dPkts << "\" "
                                                << "Байт=\"" << cursor->dOctets << "\" "
                                                << "Порт_ист.=\"" << cursor->srcport << "\" "
                                                << "Порт_получ.=\"" << cursor->dstport << "\" "
                                                << "TCP-флаги=\"" << cursor->tcp_flags << "\" "
                                                << "протокол=\"" << cursor->prot << "\" "
                                                << "Tos=\"" << cursor->tos << "\" "
                                                << "/>" << std&#58;&#58;endl;
                                &#125; while&#40;cursor.next&#40;&#41;&#41;;
                                // &#125;&#125;&#125;
                        &#125;

                        db.close&#40;&#41;;
                &#125; else &#123;
                        std&#58;&#58;cerr << "Cannot open file." << std&#58;&#58;endl;
                &#125;

                ++it;
        &#125;

        out << "</UTM>" << std&#58;&#58;endl;
        out.close&#40;&#41;;
        return 0;
&#125;
Единственное что заметил, так это то, что текущий файл с трафиком, в который пишет UTM5, не открывается. Но я программку делал, чтобы старую детальку вытаскивать -- мне не мешает. + не стоит вторгаться и в без того не отличающуюся стабильностью систему :)
UTM5/FreeBSD 5.3/MySQL 4.1/ipcad

Dmitry
Сообщения: 21
Зарегистрирован: Чт фев 03, 2005 16:53

Сообщение Dmitry »

А под пингвином не пробовал собирать?
У меня собирается, но при запуске:
# ./utm_det -h
./utm_det: symbol lookup error: ./utm_det: undefined symbol: _ZN17dbTableDescriptorC1EPKcP10dbDatabasejPFP17dbFieldDescriptorvEPS_

Sandello
Сообщения: 26
Зарегистрирован: Чт фев 10, 2005 18:54

Сообщение Sandello »

Попробовал: собирается и запускается.
1) Собирал под gigabase 3.31 в обоих системах. Какая у вас версия gigabase?
2) Линух - гентушный, gcc 3.4.

Код: Выделить всё

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

Dmitry
Сообщения: 21
Зарегистрирован: Чт фев 03, 2005 16:53

Сообщение Dmitry »

как раз гента и стоит :)
преставил gigabase с sourceforge (стоял судя по всему из дерева), заработало.
большое спасибо :)

Ответить