3 Commits

Author SHA1 Message Date
acetone b263c89799 ver changed 2023-02-10 11:34:04 +03:00
acetone 8cfbf76ef7 v0.0.2 2023-02-10 11:26:39 +03:00
acetone 971dad786b total history 2023-02-10 10:55:04 +03:00
12 changed files with 96 additions and 22 deletions
+25 -4
View File
@@ -78,11 +78,32 @@ void DBManager::initAtStart()
query.exec ("VACUUM"); query.exec ("VACUUM");
} }
TopDestinationList DBManager::totalTop() const DestinationList DBManager::allHistory() const
{ {
QSqlQuery query(m_db); QSqlQuery query(m_db);
TopDestinationList result; DestinationList result;
if (not query.exec("SELECT * FROM total_history ORDER BY request_counter DESC"))
{
qCritical() << "Db query failed:" << query.lastError().text();
}
else
{
while (query.next())
{
result.push_back( {query.value(0).toString(), query.value(1).toULongLong()} );
}
}
return result;
}
DestinationList DBManager::totalTop() const
{
QSqlQuery query(m_db);
DestinationList result;
if (not query.exec("SELECT * FROM total_history ORDER BY request_counter DESC LIMIT " + QString::number(g::p::LAST_AND_TOP_LIST_SIZE))) if (not query.exec("SELECT * FROM total_history ORDER BY request_counter DESC LIMIT " + QString::number(g::p::LAST_AND_TOP_LIST_SIZE)))
{ {
@@ -99,11 +120,11 @@ TopDestinationList DBManager::totalTop() const
return result; return result;
} }
TopDestinationList DBManager::dailyTop() const DestinationList DBManager::dailyTop() const
{ {
QSqlQuery query(m_db); QSqlQuery query(m_db);
TopDestinationList result; DestinationList result;
if (not query.exec("SELECT * FROM daily_history ORDER BY request_counter DESC LIMIT " + QString::number(g::p::LAST_AND_TOP_LIST_SIZE))) if (not query.exec("SELECT * FROM daily_history ORDER BY request_counter DESC LIMIT " + QString::number(g::p::LAST_AND_TOP_LIST_SIZE)))
{ {
+3 -2
View File
@@ -43,8 +43,9 @@ public:
DBManager(); DBManager();
void initAtStart(); void initAtStart();
TopDestinationList totalTop() const; DestinationList allHistory() const;
TopDestinationList dailyTop() const; DestinationList totalTop() const;
DestinationList dailyTop() const;
quint64 totalTopCount(const QString& dest) const; quint64 totalTopCount(const QString& dest) const;
quint64 dailyTopCount(const QString& dest) const; quint64 dailyTopCount(const QString& dest) const;
quint64 incrementTotalTopCount(const QString& dest); quint64 incrementTotalTopCount(const QString& dest);
+2 -2
View File
@@ -31,8 +31,8 @@ namespace g {
namespace c { namespace c {
const QString SOFTWARE_NAME = "3proxy-eagle"; const QString SOFTWARE_NAME = "3proxy-eagle";
const QString SOFTWARE_VERSION = "0.0.1"; const QString SOFTWARE_VERSION = "0.0.2";
const QString COPYRIGHT = "GPLv3 (c) acetone, 2022"; const QString COPYRIGHT = "GPLv3+ &copy acetone, 2022-2023";
const qint64 DB_DAILY_TOP_TABLE_ACTUALIZE_MINIMAL_INTERVAL_MS = 300000; // 5 min const qint64 DB_DAILY_TOP_TABLE_ACTUALIZE_MINIMAL_INTERVAL_MS = 300000; // 5 min
const qint64 CACHE_ACTUALIZE_TOP_LISTS_FROM_DB_MINIMAL_INTERVAL_MS = 5000; // 5 sec const qint64 CACHE_ACTUALIZE_TOP_LISTS_FROM_DB_MINIMAL_INTERVAL_MS = 5000; // 5 sec
const QString HA_PAGE_TITLE = "{{PAGE_TITLE}}"; const QString HA_PAGE_TITLE = "{{PAGE_TITLE}}";
+1 -1
View File
@@ -27,7 +27,7 @@ class QFile;
class ProxyInstanse; class ProxyInstanse;
class QThread; class QThread;
using TopDestinationList = QList<QPair<QString, quint64>>; using DestinationList = QList<QPair<QString, quint64>>;
namespace g /* for Global */ { namespace g /* for Global */ {
+1 -1
View File
@@ -99,7 +99,7 @@
</section>{{INFORMATION}} </section>{{INFORMATION}}
<section class="proxyService__topDestinations topDestinations section"> <section class="proxyService__topDestinations topDestinations section">
<div class="section__title"> <div class="section__title">
Top {{TOP_MEASURE}} Top {{TOP_MEASURE}} <a href="/~stats.txt" target="_blank" style="color: gray">(all)</a>
</div> </div>
<div class="topDestinations__block"> <div class="topDestinations__block">
<div class="topDestinations__title"> <div class="topDestinations__title">
+16
View File
@@ -82,6 +82,22 @@ void HttpDocument::setBody(const QByteArray &body)
m_body = body; m_body = body;
} }
void HttpDocument::setBody(const QString &body, const QString &oldETag)
{
QString eTag = g::hash(body.toUtf8());
if (oldETag == eTag)
{
qDebug() << "Data cached by user (not file on disk) / Hash:" << oldETag;
setCode(Code::_304);
return;
}
setBody(body.toUtf8());
setHeader(CommonHeader::ETag, eTag);
}
void HttpDocument::setBody(const QJsonObject &body) void HttpDocument::setBody(const QJsonObject &body)
{ {
m_body = QJsonDocument(body).toJson(QJsonDocument::JsonFormat::Compact); m_body = QJsonDocument(body).toJson(QJsonDocument::JsonFormat::Compact);
+1
View File
@@ -74,6 +74,7 @@ public:
void setBody(const QByteArray& body); void setBody(const QByteArray& body);
void setBody(const QJsonObject& body); void setBody(const QJsonObject& body);
void setBody(QFile&& payload, const QString& eTag = QString()); void setBody(QFile&& payload, const QString& eTag = QString());
void setBody(const QString& body, const QString& eTag);
void setBodySingleHTMLLabel(const QString& text, const QString& title = "Notice"); void setBodySingleHTMLLabel(const QString& text, const QString& title = "Notice");
QByteArray body() const { return m_body; } QByteArray body() const { return m_body; }
+7 -1
View File
@@ -18,6 +18,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include "socketrunnable.h" #include "socketrunnable.h"
#include "statistics.h"
#include "g.h" #include "g.h"
#include "webpage.h" #include "webpage.h"
@@ -49,7 +50,12 @@ void SocketRunnable::get()
QString eTag = g::getValue(m_headers, "If-None-Match", g::GetValueType::HttpHeader); QString eTag = g::getValue(m_headers, "If-None-Match", g::GetValueType::HttpHeader);
if (urlPath() == "/main.css") if (urlPath() == "/~stats.txt")
{
httpDocument().setBody(Statistics::statsTxt(), eTag);
httpDocument().setHeader(HttpDocument::CommonHeader::ContentType, HttpDocument::ContentType::TEXT);
}
else if (urlPath() == "/main.css")
{ {
httpDocument().setBody(QFile(":/html/main.css"), eTag); httpDocument().setBody(QFile(":/html/main.css"), eTag);
} }
+31 -4
View File
@@ -19,6 +19,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "statistics.h" #include "statistics.h"
#include "dbmanager.h" #include "dbmanager.h"
#include "webpage.h"
#include "g.h" #include "g.h"
#include <QRegularExpression> #include <QRegularExpression>
@@ -36,8 +37,8 @@ std::atomic<quint64> Statistics::m_totalUpload {0};
std::atomic<quint64> Statistics::m_totalDownload {0}; std::atomic<quint64> Statistics::m_totalDownload {0};
QMutex Statistics::m_topDestinationsMtx; QMutex Statistics::m_topDestinationsMtx;
TopDestinationList Statistics::m_dailyTopDestinations; DestinationList Statistics::m_dailyTopDestinations;
TopDestinationList Statistics::m_totalTopDestinations; DestinationList Statistics::m_totalTopDestinations;
bool Statistics::m_cacheUpdatedAfterLastReport = false; bool Statistics::m_cacheUpdatedAfterLastReport = false;
qint64 Statistics::m_actualizeTopListsLastTimestamp = 0; qint64 Statistics::m_actualizeTopListsLastTimestamp = 0;
@@ -91,7 +92,7 @@ const QStringList Statistics::lastDestinations()
return m_lastDestinations; return m_lastDestinations;
} }
const TopDestinationList Statistics::dailyTopDestinations() const DestinationList Statistics::dailyTopDestinations()
{ {
if (not m_cacheUpdatedAfterLastReport) if (not m_cacheUpdatedAfterLastReport)
{ {
@@ -101,7 +102,7 @@ const TopDestinationList Statistics::dailyTopDestinations()
return m_dailyTopDestinations; return m_dailyTopDestinations;
} }
const TopDestinationList Statistics::totalTopDestinations() const DestinationList Statistics::totalTopDestinations()
{ {
QMutexLocker lock (&m_topDestinationsMtx); QMutexLocker lock (&m_topDestinationsMtx);
return m_totalTopDestinations; return m_totalTopDestinations;
@@ -116,6 +117,32 @@ void Statistics::initTrafficCounters()
m_totalUpload = db.totalUploadTraffic(); m_totalUpload = db.totalUploadTraffic();
} }
QString Statistics::statsTxt()
{
static QMutex mtx;
if (not mtx.tryLock())
{
return "Service is busy, try again later.";
}
auto raw = DBManager().allHistory();
quint64 totalRequests = 0;
QString result;
for (const auto& record: raw)
{
result += WebPage::counterToHumanReadableString(record.second) + "\t" + record.first + "\n";
totalRequests += record.second;
}
result.push_front("Total destinations: " + WebPage::counterToHumanReadableString(raw.size()) + "\n"
"Total requests: " + WebPage::counterToHumanReadableString(totalRequests) + "\n\n");
mtx.unlock();
return result;
}
void Statistics::actualizeTopLists() void Statistics::actualizeTopLists()
{ {
QMutexLocker lock (&m_topDestinationsMtx); QMutexLocker lock (&m_topDestinationsMtx);
+6 -4
View File
@@ -40,8 +40,8 @@ public:
static const QStringList lastDestinations(); static const QStringList lastDestinations();
static const TopDestinationList dailyTopDestinations(); static const DestinationList dailyTopDestinations();
static const TopDestinationList totalTopDestinations(); static const DestinationList totalTopDestinations();
static void initTrafficCounters(); static void initTrafficCounters();
static quint64 dailyUpload() { return m_dailyUpload; } static quint64 dailyUpload() { return m_dailyUpload; }
@@ -49,6 +49,8 @@ public:
static quint64 dailyDownload() { return m_dailyDownload; } static quint64 dailyDownload() { return m_dailyDownload; }
static quint64 totalDownload() { return m_totalDownload; } static quint64 totalDownload() { return m_totalDownload; }
static QString statsTxt();
private: private:
static void actualizeTopLists(); static void actualizeTopLists();
static bool isIpAddress(const QString& dest); static bool isIpAddress(const QString& dest);
@@ -65,7 +67,7 @@ private:
static std::atomic<quint64> m_totalDownload; static std::atomic<quint64> m_totalDownload;
static QMutex m_topDestinationsMtx; static QMutex m_topDestinationsMtx;
static TopDestinationList m_dailyTopDestinations; static DestinationList m_dailyTopDestinations;
static TopDestinationList m_totalTopDestinations; static DestinationList m_totalTopDestinations;
}; };
+2 -2
View File
@@ -192,10 +192,10 @@ quint64 WebPage::trafficBlock(QString &document, quint64 lastTrafficVolume)
document.replace(g::c::HA_DAILY_DOWNLOAD_MEASURE, dailyDownload.measure); document.replace(g::c::HA_DAILY_DOWNLOAD_MEASURE, dailyDownload.measure);
auto totalUpload = bytesToHumanReadableString( Statistics::totalUpload() ); auto totalUpload = bytesToHumanReadableString( Statistics::totalUpload() );
document.replace(g::c::HA_TOTAL_UPLOAD, totalUpload.integer + " " + totalUpload.measure); document.replace(g::c::HA_TOTAL_UPLOAD, totalUpload.integer + totalUpload.decimal + " " + totalUpload.measure);
auto totalDownload = bytesToHumanReadableString( Statistics::totalDownload() ); auto totalDownload = bytesToHumanReadableString( Statistics::totalDownload() );
document.replace(g::c::HA_TOTAL_DOWNLOAD, totalDownload.integer + " " + totalDownload.measure); document.replace(g::c::HA_TOTAL_DOWNLOAD, totalDownload.integer + totalDownload.decimal + " " + totalDownload.measure);
return currentVolume; return currentVolume;
} }
+1 -1
View File
@@ -29,6 +29,7 @@ class WebPage
public: public:
WebPage() = delete; WebPage() = delete;
static QByteArray document(quint64 lastTrafficVolume, quint64* currentTrafficVolume = nullptr); static QByteArray document(quint64 lastTrafficVolume, quint64* currentTrafficVolume = nullptr);
static QString counterToHumanReadableString(quint64 count);
private: private:
static void setTitle(QString& document); static void setTitle(QString& document);
@@ -45,7 +46,6 @@ private:
static QString topDestinationItem(const QString& destination, quint64 count); static QString topDestinationItem(const QString& destination, quint64 count);
static QString blockedDestinationItem(const QString& destination, const QStringList& addresses); static QString blockedDestinationItem(const QString& destination, const QStringList& addresses);
static HumanReadableValue bytesToHumanReadableString(quint64 bytes); static HumanReadableValue bytesToHumanReadableString(quint64 bytes);
static QString counterToHumanReadableString(quint64 count);
static const QString m_lastDestinationItemAllowed; static const QString m_lastDestinationItemAllowed;
static const QString m_lastDestinationItemBlocked; static const QString m_lastDestinationItemBlocked;