Update monitor behaviour
This commit is contained in:
parent
545a145605
commit
d308be58b3
@ -20,6 +20,7 @@
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include <QUrl>
|
||||
#include <QFileInfo>
|
||||
#include <QCoreApplication>
|
||||
#include <QLoggingCategory>
|
||||
#include <QCommandLineParser>
|
||||
@ -50,9 +51,20 @@ int main(int argc, char *argv[])
|
||||
QCommandLineOption socketOption(QStringList() << "s" << "socket", "The socket descriptor for the nymea-remoteproxy monitor socket. Default is /tmp/nymea-remoteproxy-monitor.sock", "socket");
|
||||
socketOption.setDefaultValue("/tmp/nymea-remoteproxy-monitor.sock");
|
||||
parser.addOption(socketOption);
|
||||
|
||||
parser.process(application);
|
||||
|
||||
// Check socket file
|
||||
QFileInfo fileInfo(parser.value(socketOption));
|
||||
if (!fileInfo.exists()) {
|
||||
qWarning() << "Could not find socket descriptor" << fileInfo.canonicalFilePath();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!fileInfo.isReadable()) {
|
||||
qWarning() << "Could not open socket descriptor" << fileInfo.canonicalFilePath();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Monitor monitor(parser.value(socketOption));
|
||||
|
||||
return application.exec();
|
||||
|
||||
@ -23,10 +23,24 @@
|
||||
|
||||
Monitor::Monitor(const QString &serverName, QObject *parent) : QObject(parent)
|
||||
{
|
||||
m_terminal = new TerminalWindow(this);
|
||||
m_monitorClient = new MonitorClient(serverName, this);
|
||||
|
||||
connect(m_monitorClient, &MonitorClient::dataReady, m_terminal, &TerminalWindow::refreshWindow);
|
||||
connect(m_monitorClient, &MonitorClient::connected, this, &Monitor::onConnected);
|
||||
connect(m_monitorClient, &MonitorClient::disconnected, this, &Monitor::onDisconnected);
|
||||
|
||||
m_monitorClient->connectMonitor();
|
||||
}
|
||||
|
||||
void Monitor::onConnected()
|
||||
{
|
||||
m_terminal = new TerminalWindow(this);
|
||||
connect(m_monitorClient, &MonitorClient::dataReady, m_terminal, &TerminalWindow::refreshWindow);
|
||||
}
|
||||
|
||||
void Monitor::onDisconnected()
|
||||
{
|
||||
if (!m_terminal)
|
||||
return;
|
||||
|
||||
m_terminal->deleteLater();
|
||||
m_terminal = nullptr;
|
||||
}
|
||||
|
||||
@ -37,6 +37,10 @@ private:
|
||||
TerminalWindow *m_terminal = nullptr;
|
||||
MonitorClient *m_monitorClient = nullptr;
|
||||
|
||||
private slots:
|
||||
void onConnected();
|
||||
void onDisconnected();
|
||||
|
||||
};
|
||||
|
||||
#endif // MONITOR_H
|
||||
|
||||
@ -32,16 +32,19 @@ MonitorClient::MonitorClient(const QString &serverName, QObject *parent) :
|
||||
connect(m_socket, &QLocalSocket::connected, this, &MonitorClient::onConnected);
|
||||
connect(m_socket, &QLocalSocket::disconnected, this, &MonitorClient::onDisconnected);
|
||||
connect(m_socket, &QLocalSocket::readyRead, this, &MonitorClient::onReadyRead);
|
||||
connect(m_socket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(onErrorOccured(QLocalSocket::LocalSocketError)));
|
||||
}
|
||||
|
||||
void MonitorClient::onConnected()
|
||||
{
|
||||
qDebug() << "Monitor connected to" << m_serverName;
|
||||
emit connected();
|
||||
}
|
||||
|
||||
void MonitorClient::onDisconnected()
|
||||
{
|
||||
qDebug() << "Monitor disconnected from" << m_serverName;
|
||||
emit disconnected();
|
||||
}
|
||||
|
||||
void MonitorClient::onReadyRead()
|
||||
@ -62,6 +65,13 @@ void MonitorClient::onReadyRead()
|
||||
emit dataReady(dataMap);
|
||||
}
|
||||
|
||||
void MonitorClient::onErrorOccured(QLocalSocket::LocalSocketError socketError)
|
||||
{
|
||||
Q_UNUSED(socketError)
|
||||
qWarning() << "Local socket error occured" << m_socket->errorString();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void MonitorClient::connectMonitor()
|
||||
{
|
||||
m_socket->connectToServer(m_serverName, QLocalSocket::ReadOnly);
|
||||
|
||||
@ -36,13 +36,17 @@ public:
|
||||
private:
|
||||
QString m_serverName;
|
||||
QLocalSocket *m_socket = nullptr;
|
||||
|
||||
signals:
|
||||
void connected();
|
||||
void disconnected();
|
||||
void dataReady(const QVariantMap &data);
|
||||
|
||||
private slots:
|
||||
void onConnected();
|
||||
void onDisconnected();
|
||||
void onReadyRead();
|
||||
void onErrorOccured(QLocalSocket::LocalSocketError socketError);
|
||||
|
||||
public slots:
|
||||
void connectMonitor();
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
|
||||
#include "terminalwindow.h"
|
||||
|
||||
#include <QTime>
|
||||
#include <QDebug>
|
||||
#include <QDateTime>
|
||||
#include <QMetaObject>
|
||||
@ -30,40 +31,48 @@ TerminalWindow::TerminalWindow(QObject *parent) :
|
||||
{
|
||||
// Create main window
|
||||
m_mainWindow = initscr();
|
||||
start_color();
|
||||
|
||||
init_pair(1, COLOR_BLACK, COLOR_GREEN);
|
||||
init_pair(2, COLOR_BLACK, COLOR_RED);
|
||||
// Enable colors if available
|
||||
if (has_colors()) {
|
||||
start_color();
|
||||
init_pair(1, COLOR_BLACK, COLOR_GREEN);
|
||||
init_pair(2, COLOR_BLACK, COLOR_RED);
|
||||
}
|
||||
|
||||
// Configure behaviour
|
||||
cbreak();
|
||||
noecho();
|
||||
nonl();;
|
||||
nodelay(stdscr, TRUE);
|
||||
curs_set(FALSE);
|
||||
|
||||
//clear();
|
||||
clear();
|
||||
|
||||
keypad(m_mainWindow, true);
|
||||
nodelay(m_mainWindow, true);
|
||||
getmaxyx(stdscr, m_terminalSizeY, m_terminalSizeX);
|
||||
getmaxyx(m_mainWindow, m_terminalSizeY, m_terminalSizeX);
|
||||
wrefresh(m_mainWindow);
|
||||
|
||||
// Create header and content window
|
||||
m_headerWindow = newwin(m_headerHeight, m_terminalSizeX, 0, 0);
|
||||
m_contentWindow = newwin(m_terminalSizeY - m_headerHeight, m_terminalSizeX, m_headerHeight, 0);
|
||||
|
||||
// Draw borders
|
||||
wclear(m_headerWindow);
|
||||
wclear(m_contentWindow);
|
||||
werase(m_headerWindow);
|
||||
werase(m_contentWindow);
|
||||
drawWindowBorder(m_headerWindow);
|
||||
drawWindowBorder(m_contentWindow);
|
||||
|
||||
mvwprintw(m_headerWindow, 1, 2, convertString("Connecting..."));
|
||||
|
||||
box(m_headerWindow, 0 , 0);
|
||||
box(m_contentWindow, 0 , 0);
|
||||
//box(m_headerWindow, 0 , 0);
|
||||
//box(m_contentWindow, 0 , 0);
|
||||
|
||||
// Refresh windows
|
||||
wrefresh(m_headerWindow);
|
||||
wrefresh(m_contentWindow);
|
||||
|
||||
refresh();
|
||||
|
||||
eventLoop();
|
||||
}
|
||||
|
||||
TerminalWindow::~TerminalWindow()
|
||||
@ -80,6 +89,18 @@ const char *TerminalWindow::convertString(const QString &string)
|
||||
return reinterpret_cast<const char *>(string.toLatin1().data());
|
||||
}
|
||||
|
||||
QString TerminalWindow::getDurationString(uint timestamp)
|
||||
{
|
||||
uint duration = QDateTime::currentDateTime().toTime_t() - timestamp;
|
||||
QString res;
|
||||
int seconds = static_cast<int>(duration % 60);
|
||||
duration /= 60;
|
||||
int minutes = static_cast<int>(duration % 60);
|
||||
duration /= 60;
|
||||
int hours = static_cast<int>(duration % 24);
|
||||
return res.sprintf("%02d:%02d:%02d", hours, minutes, seconds);
|
||||
}
|
||||
|
||||
void TerminalWindow::resizeWindow()
|
||||
{
|
||||
int terminalSizeX;
|
||||
@ -93,30 +114,61 @@ void TerminalWindow::resizeWindow()
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalWindow::drawWindowBorder(WINDOW *window)
|
||||
{
|
||||
int x, y, i;
|
||||
getmaxyx(window, y, x);
|
||||
|
||||
// corners
|
||||
mvwprintw(window, 0, 0, "+");
|
||||
mvwprintw(window, y - 1, 0, "+");
|
||||
mvwprintw(window, 0, x - 1, "+");
|
||||
mvwprintw(window, y - 1, x - 1, "+");
|
||||
|
||||
// sides
|
||||
for (i = 1; i < (y - 1); i++) {
|
||||
mvwprintw(window, i, 0, "|");
|
||||
mvwprintw(window, i, x - 1, "|");
|
||||
}
|
||||
|
||||
// top and bottom
|
||||
for (i = 1; i < (x - 1); i++) {
|
||||
mvwprintw(window, 0, i, "-");
|
||||
mvwprintw(window, y - 1, i, "-");
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalWindow::paintHeader()
|
||||
{
|
||||
QString headerString = QString(" Server: %1 %2 | API version %3 | Clients: %4 | Tunnels %5 | %6 %7")
|
||||
.arg(m_dataMap.value("serverName").toString())
|
||||
.arg(m_dataMap.value("serverVersion").toString())
|
||||
.arg(m_dataMap.value("apiVersion").toString())
|
||||
.arg(m_dataMap.value("proxyStatistic").toMap().value("clientCount").toInt())
|
||||
.arg(m_dataMap.value("proxyStatistic").toMap().value("tunnelCount").toInt())
|
||||
.arg((m_view == ViewClients ? "Clients" : "Tunnels"))
|
||||
.arg("", m_terminalSizeX, ' ');
|
||||
QString headerString = QString(" Server: %1 %2 | API version %3 | Clients: %4 | Tunnels %5 | %6 ")
|
||||
.arg(m_dataMap.value("serverName", "-").toString())
|
||||
.arg(m_dataMap.value("serverVersion", "-").toString())
|
||||
.arg(m_dataMap.value("apiVersion", "-").toString())
|
||||
.arg(m_dataMap.value("proxyStatistic").toMap().value("clientCount", 0).toInt())
|
||||
.arg(m_dataMap.value("proxyStatistic").toMap().value("tunnelCount", 0).toInt())
|
||||
.arg((m_view == ViewClients ? "-- Clients --" : "-- Tunnels --"));
|
||||
|
||||
int delta = m_terminalSizeX - headerString.count();
|
||||
|
||||
// Fill string for background color
|
||||
for (int i = 0; i < delta; i++)
|
||||
headerString.append(" ");
|
||||
|
||||
|
||||
wclear(m_headerWindow);
|
||||
wattron(m_headerWindow, A_BOLD | COLOR_PAIR(1));
|
||||
mvwprintw(m_headerWindow, 1, 2, convertString(headerString));
|
||||
wattroff(m_headerWindow, A_BOLD | COLOR_PAIR(1));
|
||||
box(m_headerWindow, 0 , 0);
|
||||
drawWindowBorder(m_headerWindow);
|
||||
wrefresh(m_headerWindow);
|
||||
}
|
||||
|
||||
void TerminalWindow::paintContentClients()
|
||||
{
|
||||
int i = 1;
|
||||
if (m_clientHash.isEmpty())
|
||||
return;
|
||||
|
||||
int i = 1;
|
||||
wclear(m_contentWindow);
|
||||
foreach (const QVariant &clientVariant, m_clientHash.values()) {
|
||||
QVariantMap clientMap = clientVariant.toMap();
|
||||
@ -124,20 +176,21 @@ void TerminalWindow::paintContentClients()
|
||||
uint timeStamp = clientMap.value("timestamp").toUInt();
|
||||
QString clientConnectionTime = QDateTime::fromTime_t(timeStamp).toString("dd.MM.yyyy hh:mm:ss");
|
||||
|
||||
QString clientPrint = QString("%1 | %2 | %3 | %4 | %5 | %6 |")
|
||||
QString clientPrint = QString("%1 | %2 | %3 | %4 | %5 | %6 | %7")
|
||||
.arg(clientConnectionTime)
|
||||
.arg(clientMap.value("duration").toString())
|
||||
.arg(clientMap.value("address").toString())
|
||||
.arg(clientMap.value("uuid").toString())
|
||||
.arg(clientMap.value("name").toString(), -30)
|
||||
.arg((clientMap.value("authenticated").toBool() ? "auth" : "no auth"), -9)
|
||||
.arg((clientMap.value("tunnelConnected").toBool() ? "<--->" : " | "));
|
||||
.arg((clientMap.value("authenticated").toBool() ? "A" : "-"))
|
||||
.arg((clientMap.value("tunnelConnected").toBool() ? "T" : "-"))
|
||||
.arg(clientMap.value("name").toString(), -30);
|
||||
|
||||
mvwprintw(m_contentWindow, i, 2, convertString(clientPrint));
|
||||
mvwprintw(m_contentWindow, i, 2, convertString(clientPrint.trimmed()));
|
||||
i++;
|
||||
}
|
||||
|
||||
// Draw borders
|
||||
box(m_contentWindow, 0 , 0);
|
||||
drawWindowBorder(m_contentWindow);
|
||||
wrefresh(m_contentWindow);
|
||||
}
|
||||
|
||||
@ -159,7 +212,7 @@ void TerminalWindow::paintContentTunnels()
|
||||
.arg(tunnelConnectionTime)
|
||||
.arg(clientOne.value("address").toString())
|
||||
.arg(clientOne.value("name").toString())
|
||||
.arg("<--->", 10)
|
||||
.arg(" <---> ")
|
||||
.arg(clientTwo.value("address").toString())
|
||||
.arg(clientTwo.value("name").toString())
|
||||
;
|
||||
@ -169,7 +222,7 @@ void TerminalWindow::paintContentTunnels()
|
||||
}
|
||||
|
||||
// Draw borders
|
||||
box(m_contentWindow, 0 , 0);
|
||||
drawWindowBorder(m_contentWindow);
|
||||
wrefresh(m_contentWindow);
|
||||
}
|
||||
|
||||
@ -191,6 +244,7 @@ void TerminalWindow::eventLoop()
|
||||
delwin(m_contentWindow);
|
||||
delwin(m_mainWindow);
|
||||
endwin();
|
||||
qDebug() << "Closing window monitor. Have a nice day!";
|
||||
exit(0);
|
||||
break;
|
||||
default:
|
||||
@ -213,10 +267,10 @@ void TerminalWindow::eventLoop()
|
||||
refresh();
|
||||
|
||||
// Reinvoke the method for the next event loop run
|
||||
QMetaObject::invokeMethod(this, "eventLoop", Qt::QueuedConnection);
|
||||
//QMetaObject::invokeMethod(this, "eventLoop", Qt::QueuedConnection);
|
||||
QTimer::singleShot(50, this, &TerminalWindow::eventLoop);
|
||||
}
|
||||
|
||||
|
||||
void TerminalWindow::refreshWindow(const QVariantMap &dataMap)
|
||||
{
|
||||
m_dataMap = dataMap;
|
||||
@ -224,11 +278,11 @@ void TerminalWindow::refreshWindow(const QVariantMap &dataMap)
|
||||
QVariantMap statisticMap = m_dataMap.value("proxyStatistic").toMap();
|
||||
|
||||
m_clientHash.clear();
|
||||
|
||||
foreach (const QVariant &clientVariant, statisticMap.value("clients").toList()) {
|
||||
QVariantMap clientMap = clientVariant.toMap();
|
||||
clientMap.insert("duration", getDurationString(clientMap.value("timestamp").toUInt()));
|
||||
m_clientHash.insert(clientMap.value("id").toString(), clientMap);
|
||||
}
|
||||
|
||||
eventLoop();
|
||||
}
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include <QTimer>
|
||||
#include <QVariantMap>
|
||||
|
||||
#include <ncurses.h>
|
||||
@ -56,9 +57,11 @@ private:
|
||||
QHash<QString, QVariantMap> m_clientHash;
|
||||
|
||||
const char *convertString(const QString &string);
|
||||
QString getDurationString(uint timestamp);
|
||||
|
||||
// content paint methods
|
||||
void resizeWindow();
|
||||
void drawWindowBorder(WINDOW *window);
|
||||
void paintHeader();
|
||||
void paintContentClients();
|
||||
void paintContentTunnels();
|
||||
|
||||
@ -23,7 +23,7 @@ ccache {
|
||||
QMAKE_CXX = ccache g++
|
||||
}
|
||||
|
||||
coverage {
|
||||
coverage {<
|
||||
# Note: this works only if you build in the source dir
|
||||
OBJECTS_DIR =
|
||||
MOC_DIR =
|
||||
|
||||
Reference in New Issue
Block a user