LogDoctor/logdoctor/tools/crapview/crapview.cpp

530 lines
20 KiB
C++

#include "crapview.h"
#include <iostream> // !!! REMOVE !!!
Crapview::Crapview()
{
}
const int Crapview::getDialogLevel()
{
return this->dialog_level;
}
void Crapview::setDialogLevel( const int new_level )
{
this->dialog_level = new_level;
}
void Crapview::setDbPath( const std::string& path )
{
this->dbQuery.setDbPath( path );
}
const QString Crapview::printableDate( const QString& year, const int month, const QString& day )
{
QString date = QString("%1-").arg( year );
if ( month < 10 ) {
date += QString("0%1-").arg( month );
} else {
date += QString("%1-").arg( month );
}
if ( day.size() < 2 ) {
date += QString("0%1").arg( day );
} else {
date += day;
}
return date;
}
void Crapview::refreshDates()
{
std::tuple<bool, std::unordered_map<int, std::unordered_map<int, std::unordered_map<int, std::unordered_map<int, std::vector<int>>>>>> result;
this->dbQuery.refreshDates( result );
if ( std::get<0>(result) == true ) {
this->dates = std::get<1>(result);
}
}
int Crapview::getMonthNumber( const QString& month_str )
{
return this->Months_s2i.value( month_str );
}
const QStringList Crapview::getYears( const QString& web_server, const QString& logs_type )
{
QStringList years;
for ( const auto& [year, data] : this->dates.at( this->WebServer_s2i.value( web_server ) ).at( this->LogsType_s2i.value( logs_type ) ) ) {
years.push_back( QString::fromStdString( std::to_string( year ) ) );
}
return years;
}
const QStringList Crapview::getMonths( const QString& web_server, const QString& logs_type, const QString& year )
{
QStringList months;
for ( const auto& [month, data] : this->dates.at( this->WebServer_s2i.value( web_server ) ).at( this->LogsType_s2i.value( logs_type )).at( year.toInt() ) ) {
months.push_back( Months_i2s.value( month ) );
}
return months;
}
const QStringList Crapview::getDays( const QString& web_server, const QString& logs_type, const QString& year, const QString& month )
{
QStringList days;
for ( const int day : this->dates.at( this->WebServer_s2i.value( web_server ) ).at( this->LogsType_s2i.value( logs_type )).at( year.toInt() ).at( this->Months_s2i.value( month ) ) ) {
days.push_back( QString::fromStdString( std::to_string( day ) ) );
}
return days;
}
const QStringList Crapview::getHours( const QString& web_server, const QString& logs_type, const QString& year, const QString& month, const QString& day )
{
return QStringList({"00","01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23"});
}
const QStringList Crapview::getFields( const QString& tab, const QString& logs_type )
{
return this->fields.value( tab ).value( logs_type );
}
////////////////
//// CHARTS ////
////////////////
void drawWarn( QTableWidget* table, QtCharts::QChartView* chart, const std::unordered_map<std::string, QFont>& fonts, const QString& web_server, const QString& year, const QString& month, const QString& day, const QString& hour )
{
}
void Crapview::drawSpeed(QTableWidget* table, QtCharts::QChartView* chart, const std::unordered_map<std::string, QFont>& fonts, const QString& web_server, const QString& year, const QString& month, const QString& day, const QString& protocol, const QString& method, const QString& uri, const QString& query, const QString& response )
{
std::tuple<bool, std::vector<std::tuple<long long, std::vector<QString>>>> result;
this->dbQuery.getSpeedData(
result,
web_server,
year, month, day,
protocol, method, uri, query, response );
if ( std::get<0>(result) == true ) {
// get data
// { hour : { 10th_minutes : count } }
std::vector<std::tuple<long long, std::vector<QString>>> &items = std::get<1>(result);
// draw the relational chart
QLineSeries *line = new QLineSeries();
line->setName( this->printableDate( year, this->Months_s2i.value(month), day ));
// build the line upon data
int i=0, max_i=items.size(), max_t=0, aux;
long long time /* xD */, aux_time=0, t=0, aux_t, count=1;
time = std::get<0>(items.at(0));
QDateTime dt;
std::vector<QString> data;
for ( const auto& item : items ) {
i++;
// append a value to the chart
aux_time = std::get<0>(item);
data = std::get<1>(item);
aux_t = data.at( 0 ).toLongLong();
// append only if the second is different, else sum
if ( aux_time > time ) {
t = t/count;
line->append( time, t );
if ( t > max_t ) {
max_t = t;
}
time = aux_time;
t = aux_t;
count = 1;
if ( i == max_i ) {
// final
line->append( time, t );
if ( t > max_t ) {
max_t = t;
}
}
} else {
count ++;
t += aux_t;
if ( i == max_i ) {
// final
t = t/count;
line->append( aux_time, t );
if ( t > max_t ) {
max_t = t;
}
}
}
// fill the teble with data
if ( data.at(0).size() > 0 || data.at(1).size() > 0 || data.at(2).size() > 0 || data.at(3).size() > 0 || data.at(4).size() > 0 || data.at(5).size() > 0 ) {
aux = table->rowCount();
table->insertRow( aux );
table->setItem( aux, 0, new QTableWidgetItem( data.at(0) ));
table->setItem( aux, 1, new QTableWidgetItem( data.at(1) ));
table->setItem( aux, 2, new QTableWidgetItem( data.at(2) ));
table->setItem( aux, 3, new QTableWidgetItem( data.at(3) ));
table->setItem( aux, 4, new QTableWidgetItem( data.at(4) ));
table->setItem( aux, 5, new QTableWidgetItem( data.at(5) ));
dt = QDateTime::fromMSecsSinceEpoch( aux_time );
table->setItem( aux, 6, new QTableWidgetItem( dt.time().toString("hh:mm:ss") ));
}
}
table->verticalHeader()->setVisible( false );
// fictitious line
QLineSeries *line_ = new QLineSeries();
// color the area
QColor col1 = Qt::GlobalColor::red,
col2 = Qt::GlobalColor::green,
col3 = Qt::GlobalColor::blue;
//area->setColor( col );
QLinearGradient gradient(QPointF(0, 0), QPointF(0, 1));
gradient.setColorAt(0.3, col1.lighter( 90 ) );
gradient.setColorAt(0.7, col2.lighter( 90 ) );
gradient.setColorAt(1.0, col3.lighter( 90 ) );
gradient.setCoordinateMode(QGradient::ObjectBoundingMode);
QPen pen = line->pen();
pen.setBrush( gradient );
pen.setWidth( 1 );
line->setPen(pen);
pen = line_->pen();
pen.setBrush( gradient );
pen.setWidth( 1 );
line_->setPen(pen);
// build the chart
QChart *l_chart = new QChart();
l_chart->addSeries( line );
l_chart->addSeries( line_ );
l_chart->setTitle( this->TITLE_SPEED );
l_chart->setTitleFont( fonts.at("main") );
l_chart->legend()->setFont( fonts.at( "main_small" ) );
l_chart->legend()->setAlignment( Qt::AlignBottom );
// set-up the date-time axis (X)
QDateTimeAxis *axisX = new QDateTimeAxis();
axisX->setLabelsFont( fonts.at( "main_small" ) );
axisX->setFormat( "hh:mm" );
axisX->setTickCount( 25 );
l_chart->addAxis( axisX, Qt::AlignBottom );
line->attachAxis( axisX );
// set-up the count values axis (Y)
QValueAxis *axisY = new QValueAxis();
axisY->setLabelFormat( "%d" );
axisY->setTickCount( ( max_t < 16 ) ? max_t : 16 );
axisY->setRange( 0, max_t );
axisY->setLabelsFont( fonts.at( "main_small" ) );
l_chart->addAxis( axisY, Qt::AlignLeft );
line->attachAxis( axisY) ;
// add the chart to the view
chart->setChart( l_chart );
chart->setRenderHint(QPainter::Antialiasing);
items.clear();
}
}
void Crapview::drawCount( QTableWidget* table, QtCharts::QChartView* chart, const std::unordered_map<std::string, QFont>& fonts, const QString& web_server, const QString& log_type, const QString& year, const QString& month, const QString& day, const QString& field )
{
std::tuple<bool, std::vector<std::tuple<QString, int>>> result;
this->dbQuery.getItemsCount(
result,
web_server, log_type,
year, month, day,
field );
if ( std::get<0>(result) == true ) {
// get data
std::vector<std::tuple<QString, int>> &aux_items = std::get<1>(result);
// make the pie
QPieSeries *pie = new QPieSeries();
// cut off exdceeding elements for the chart
const int max_items=15;
int aux, count, oth_count=0;
QString item;
for ( int i=0; i<aux_items.size(); i++ ) {
item = std::get<0>( aux_items.at(i) );
count = std::get<1>( aux_items.at(i) );
if ( i >= max_items ) {
oth_count += count;
} else {
pie->append( item, count );
//items.push_back( aux_items.at( i ) );
}
aux = table->rowCount();
table->insertRow( aux );
table->setItem( aux, 0, new QTableWidgetItem( QString::fromStdString( std::to_string(count) )));
table->setItem( aux, 1, new QTableWidgetItem( std::get<0>( aux_items.at(i) ) ));
}
table->verticalHeader()->setVisible( false );
aux_items.clear();
if ( oth_count > 0 ) {
pie->append( this->TEXT_COUNT_OTHERS, oth_count );
QPieSlice *slice = pie->slices().at( pie->count()-1 );
slice->setBrush( Qt::gray );
}
pie->setLabelsVisible();
QChart *p_chart = new QChart();
p_chart->addSeries( pie );
p_chart->setTitle( field );
p_chart->setTitleFont( fonts.at( "main_big" ) );
p_chart->legend()->hide();
//p_chart->setTheme( QChart::ChartTheme::ChartThemeDark );
chart->setChart( p_chart );
chart->setRenderHint( QPainter::Antialiasing );
}
}
void Crapview::drawDay(QtCharts::QChartView* chart, const std::unordered_map<std::string, QFont>& fonts, const QString& web_server, const QString& log_type, const QString& from_year, const QString& from_month, const QString& from_day, const QString& to_year, const QString& to_month, const QString& to_day, const QString& field , const QString& filter )
{
std::tuple<bool, std::unordered_map<int, std::unordered_map<int, int>>> result;
this->dbQuery.getDaytimeCounts(
result,
web_server, log_type,
from_year, from_month, from_day,
to_year, to_month, to_day,
field, filter );
if ( std::get<0>(result) == true ) {
// get data
// { hour : { 10th_minutes : count } }
std::unordered_map<int, std::unordered_map<int, int>> &items = std::get<1>(result);
// draw the chart
QColor col = Qt::GlobalColor::darkGreen;
QBarSet *b_10 = new QBarSet( "" );
b_10->setColor( col );
QBarSet *b_20 = new QBarSet( "" );
b_20->setColor( col );
QBarSet *b_30 = new QBarSet( this->LEGEND_DAY );
b_30->setColor( col );
QBarSet *b_40 = new QBarSet( "" );
b_40->setColor( col );
QBarSet *b_50 = new QBarSet( "" );
b_50->setColor( col );
QBarSet *b_60 = new QBarSet( "" );
b_60->setColor( col );
// build the bars upon data
int count, max_count=0;
for ( int h=0; h<24; h++ ) {
auto& data = items.at( h );
count = data.at( 0 );
*b_10 << count;
if ( count > max_count ) {
max_count = count;
}
count = data.at( 10 );
*b_20 << count;
if ( count > max_count ) {
max_count = count;
}
count = data.at( 20 );
*b_30 << count;
if ( count > max_count ) {
max_count = count;
}
count = data.at( 30 );
*b_40 << count;
if ( count > max_count ) {
max_count = count;
}
count = data.at( 40 );
*b_50 << count;
if ( count > max_count ) {
max_count = count;
}
count = data.at( 50 );
*b_60 << count;
if ( count > max_count ) {
max_count = count;
}
}
// apply the bars to the bars serie
QBarSeries *bars = new QBarSeries();
bars->append( b_10 ); bars->append( b_20 ); bars->append( b_30 );
bars->append( b_40 ); bars->append( b_50 ); bars->append( b_60 );
bars->setBarWidth( 1 );
// set-up the bars chart
QChart *b_chart = new QChart();
b_chart->addSeries( bars );
b_chart->setTitle( QString("%1: %2").arg( this->TITLE_DAY ).arg( field ) );
b_chart->setTitleFont( fonts.at("main") );
b_chart->legend()->setFont( fonts.at("main_small") );
//b_chart->legend()->setVisible( true );
b_chart->legend()->setAlignment( Qt::AlignBottom );
b_chart->setAnimationOptions( QChart::SeriesAnimations );
//b_chart->setTheme( QChart::ChartTheme::ChartThemeBrownSand );
//t_chart->setBackgroundBrush( Qt::darkGray );
// craft the X-axis labels
QStringList categories;
categories << "00" << "01" << "02" << "03" << "04" << "05" << "06" << "07" << "08" << "09" << "10" << "11"
<< "12" << "13" << "14" << "15" << "16" << "17" << "18" << "19" << "20" << "21" << "22" << "23";
// set-up the time-of-day axis (X)
QBarCategoryAxis *axisX = new QBarCategoryAxis();
axisX->append( categories );
axisX->setLabelsFont( fonts.at( "main_small" ) );
b_chart->addAxis( axisX, Qt::AlignBottom );
bars->attachAxis( axisX );
// set-up the count values axis (Y)
QValueAxis *axisY = new QValueAxis();
axisY->setLabelFormat( "%d" );
axisY->setTickCount( ( max_count < 16 ) ? max_count : 16 );
axisY->setRange( 0, max_count );
axisY->setLabelsFont( fonts.at( "main_small" ) );
b_chart->addAxis( axisY, Qt::AlignLeft );
bars->attachAxis( axisY) ;
// apply the chart to the view
chart->setChart( b_chart );
chart->setRenderHint( QPainter::Antialiasing );
items.clear();
}
}
void Crapview::drawRelat(QtCharts::QChartView* chart, const std::unordered_map<std::string, QFont>& fonts, const QString& web_server, const QString& log_type, const QString& from_year, const QString& from_month, const QString& from_day, const QString& to_year, const QString& to_month, const QString& to_day, const QString& field_1, const QString& filter_1, const QString& field_2, const QString& filter_2 )
{
bool period = true;
std::tuple<bool, std::vector<std::tuple<long long, int>>> result;
if ( from_year == to_year
&& from_month == to_month
&& from_day == to_day ) {
period = false;
this->dbQuery.getRelationalCountsDay(
result,
web_server, log_type,
from_year, from_month, from_day,
field_1, filter_1,
field_2, filter_2 );
} else {
this->dbQuery.getRelationalCountsPeriod(
result,
web_server, log_type,
from_year, from_month, from_day,
to_year, to_month, to_day,
field_1, filter_1,
field_2, filter_2 );
}
if ( std::get<0>(result) == true ) {
// get data
// { hour : { 10th_minutes : count } }
std::vector<std::tuple<long long, int>> &items = std::get<1>(result);
// draw the relational chart
QLineSeries *line = new QLineSeries();
// build the line upon data
int count, max_count=0;
long long time; // xD
for ( const auto& item : items ) {
time = std::get<0>(item);
count = std::get<1>(item);
line->append( time, (double)count );
//*line << QPoint( time, (double)count );
if ( count > max_count ) {
max_count = count;
}
}
// build the area
QAreaSeries *area = new QAreaSeries( line );
if ( period == false ) {
area->setName( this->printableDate( from_year, this->Months_s2i.value(from_month), from_day ));
} else {
area->setName(QString("%1 %2 %3 %4")
.arg( this->LEGEND_RELAT_FROM )
.arg( this->printableDate( from_year, this->Months_s2i.value(from_month), from_day ))
.arg( this->LEGEND_RELAT_TO )
.arg( this->printableDate( to_year, this->Months_s2i.value(to_month), to_day )));
}
// color the area
QColor col1 = Qt::GlobalColor::red,
col2 = Qt::GlobalColor::yellow,
col3 = Qt::GlobalColor::magenta;
//area->setColor( col );
QLinearGradient gradient(QPointF(0, 0), QPointF(0, 1));
gradient.setColorAt(0.25, col3.lighter( 70 ) );
gradient.setColorAt(0.5, col1.lighter( 80 ) );
gradient.setColorAt(1.0, col2.lighter( 90 ) );
gradient.setCoordinateMode(QGradient::ObjectBoundingMode);
area->setBrush( gradient );
area->setBorderColor( col1.lighter( 50 ) );
// fictitious area, just to have another label
QAreaSeries *area_ = new QAreaSeries( );
area_->setBrush( gradient );
area_->setBorderColor( col1.lighter( 50 ) );
// build the area
QChart *a_chart = new QChart();
a_chart->addSeries( area );
a_chart->addSeries( area_ );
a_chart->setTitle( QString("%1: %2 -> %3").arg(this->TITLE_RELAT).arg(field_1).arg(field_2) );
a_chart->setTitleFont( fonts.at("main") );
a_chart->legend()->setFont( fonts.at( "main_small" ) );
a_chart->legend()->setAlignment( Qt::AlignBottom );
// set-up the date-time axis (X)
QDateTimeAxis *axisX = new QDateTimeAxis();
axisX->setLabelsFont( fonts.at( "main_small" ) );
if ( period == true ) {
//axisX->setLabelsVisible( false );
axisX->setFormat( "yyyy-MM" );
int ticks = this->dbQuery.getMonthsCount( from_year, from_month, to_year, to_month );
if ( ticks == 1 ) {
axisX->setFormat( "yyyy-MM-dd" );
ticks = to_day.toInt() - from_day.toInt() +2;
}
axisX->setTickCount( ticks+1 );
} else {
axisX->setFormat( "hh:mm" );
axisX->setTickCount( 25 );
}
a_chart->addAxis( axisX, Qt::AlignBottom );
area->attachAxis( axisX );
// set-up the count values axis (Y)
QValueAxis *axisY = new QValueAxis();
axisY->setLabelFormat( "%d" );
axisY->setTickCount( ( max_count < 16 ) ? max_count : 16 );
axisY->setRange( 0, max_count );
axisY->setLabelsFont( fonts.at( "main_small" ) );
a_chart->addAxis( axisY, Qt::AlignLeft );
area->attachAxis( axisY) ;
// add the chart to the view
chart->setChart( a_chart );
chart->setRenderHint(QPainter::Antialiasing);
items.clear();
}
}