Make the websocket/rest server distinctions a bit more clear. Now the logs are in websocket/restserver subdirectories, the LP file watchers will resume from the last log point (server-type aware), and a couple other changes for saving server-dependent variables.

This commit is contained in:
Ken Moore
2016-02-03 10:12:01 -05:00
parent b2cde628fb
commit 37224472cc
7 changed files with 63 additions and 35 deletions

View File

@@ -12,7 +12,6 @@ EventWatcher::EventWatcher(){
qRegisterMetaType<EventWatcher::EVENT_TYPE>("EventWatcher::EVENT_TYPE");
starting = true;
LPlog_pos = LPrep_pos = LPerr_pos = 0; //no pos yet
watcher = new QFileSystemWatcher(this);
filechecktimer = new QTimer(this);
filechecktimer->setSingleShot(false);
@@ -28,9 +27,6 @@ EventWatcher::~EventWatcher(){
void EventWatcher::start(){
// - DISPATCH Events
starting = true;
//if(!QFile::exists(DISPATCHWORKING)){ QProcess::execute("touch "+DISPATCHWORKING); }
//qDebug() << " Dispatcher Events:" << DISPATCHWORKING;
//WatcherUpdate(DISPATCHWORKING); //load it initially (will also add it to the watcher)
// - Life Preserver Events
WatcherUpdate(LPLOG); //load it initially (will also add it to the watcher);
WatcherUpdate(LPERRLOG); //load it initially (will also add it to the watcher);
@@ -45,6 +41,12 @@ EventWatcher::EVENT_TYPE EventWatcher::typeFromString(QString typ){
else{ return BADEVENT; }
}
QString EventWatcher::typeToString(EventWatcher::EVENT_TYPE typ){
if(typ==DISPATCHER){ return "dispatcher"; }
else if(typ==LIFEPRESERVER){ return "life-preserver"; }
else{ return ""; }
}
QJsonValue EventWatcher::lastEvent(EVENT_TYPE type){
CheckLogFiles();
if(HASH.contains(type)){ return HASH.value(type); }
@@ -143,9 +145,14 @@ void EventWatcher::ReadLPLogFile(){
QFile LPlogfile(LPLOG);
if( !LPlogfile.open(QIODevice::ReadOnly) ){ return; } //could not open file
QTextStream STREAM(&LPlogfile);
if(LPlog_pos>0){ STREAM.seek(LPlog_pos); }
qint64 LPlog_pos = CONFIG->value("internal/"+QString(WS_MODE ? "ws" : "tcp")+"/lp-log-pos",0).toLongLong();
if(LPlog_pos>0 && QFileInfo(LPlogfile).created() < CONFIG->value("internal/"+QString(WS_MODE ? "ws" : "tcp")+"/lp-log-lastread").toDateTime() ){
STREAM.seek(LPlog_pos);
}
QStringList info = STREAM.readAll().split("\n");
LPlog_pos = STREAM.pos();
//Now save the file pointer for later
CONFIG->setValue("internal/"+QString(WS_MODE ? "ws" : "tcp")+"/lp-log-pos",STREAM.pos());
CONFIG->setValue("internal/"+QString(WS_MODE ? "ws" : "tcp")+"/lp-log-lastread",QDateTime::currentDateTime());
LPlogfile.close();
//Now parse the new info line-by-line
for(int i=0; i<info.length(); i++){
@@ -174,7 +181,7 @@ void EventWatcher::ReadLPLogFile(){
//Setup the file watcher for this new log file
//qDebug() << " - Found Rep Start:" << dev << message;
tmpLPRepFile = dev;
LPrep_pos = 0; //reset file position
CONFIG->setValue("internal/"+QString(WS_MODE ? "ws" : "tcp")+"/lp-rep-pos",0);
dev = message.section(" on ",1,1,QString::SectionSkipEmpty);
//qDebug() << " - New Dev:" << dev << "Valid Pools:" << reppools;
//Make sure the device is currently setup for replication
@@ -192,7 +199,7 @@ void EventWatcher::ReadLPLogFile(){
}else if(message.contains("finished replication task", Qt::CaseInsensitive)){
//Done with this replication - close down the rep file watcher
tmpLPRepFile.clear();
LPrep_pos = 0; //reset file position
CONFIG->setValue("internal/"+QString(WS_MODE ? "ws" : "tcp")+"/lp-rep-pos",0);
dev = message.section(" -> ",0,0).section(" ",-1).simplified();
//Make sure the device is currently setup for replication
//if( reppools.contains(dev) ){
@@ -208,7 +215,7 @@ void EventWatcher::ReadLPLogFile(){
sendLPEvent("replication", 1, timestamp+": "+msg);
}else if( message.contains("FAILED replication", Qt::CaseInsensitive) ){
tmpLPRepFile.clear();
LPrep_pos = 0; //reset file position
CONFIG->setValue("internal/"+QString(WS_MODE ? "ws" : "tcp")+"/lp-rep-pos",0);
//Now set the status of the process
dev = message.section(" -> ",0,0).section(" ",-1).simplified();
//Make sure the device is currently setup for replication
@@ -233,13 +240,14 @@ void EventWatcher::ReadLPErrFile(){
}
void EventWatcher::ReadLPRepFile(){
static QString stat = "";
static QString repTotK = "";
static QString lastSize = "";
QString stat = CONFIG->value("internal/"+QString(WS_MODE ? "ws" : "tcp")+"/lp-rep-s","").toString();
QString repTotK = CONFIG->value("internal/"+QString(WS_MODE ? "ws" : "tcp")+"/lp-rep-totk","").toString();
QString lastSize = CONFIG->value("internal/"+QString(WS_MODE ? "ws" : "tcp")+"/lp-rep-lastsize","").toString();
//Open/Read any new info in the file
QFile LPlogfile(LPLOG);
if( !LPlogfile.open(QIODevice::ReadOnly) ){ return; } //could not open file
QTextStream STREAM(&LPlogfile);
qint64 LPrep_pos = CONFIG->value("internal/"+QString(WS_MODE ? "ws" : "tcp")+"/lp-rep-pos",0).toLongLong();
if(LPrep_pos<=0 || !STREAM.seek(LPrep_pos) ){
//New file location
stat.clear();
@@ -247,7 +255,7 @@ void EventWatcher::ReadLPRepFile(){
lastSize.clear();
}
QStringList info = STREAM.readAll().split("\n");
LPrep_pos = STREAM.pos();
CONFIG->setValue("internal/"+QString(WS_MODE ? "ws" : "tcp")+"/lp-rep-pos",STREAM.pos());
LPlogfile.close();
//Now parse the new info line-by-line
for(int i=0; i<info.length(); i++){
@@ -290,5 +298,9 @@ void EventWatcher::ReadLPRepFile(){
HASH.insert(123,txt);
emit sendLPEvent("replication", 0, txt);
}
}
}
//Save the internal values
CONFIG->setValue("internal/"+QString(WS_MODE ? "ws" : "tcp")+"/lp-rep-stat",stat);
if(repTotK!="??"){CONFIG->setValue("internal/"+QString(WS_MODE ? "ws" : "tcp")+"/lp-rep-totk",repTotK); }
CONFIG->setValue("internal/"+QString(WS_MODE ? "ws" : "tcp")+"/lp-rep-lastsize",lastSize);
}

View File

@@ -22,9 +22,10 @@ public:
EventWatcher();
~EventWatcher();
//Convert a string into the type flag
//Convert between strings and type flags
static EVENT_TYPE typeFromString(QString);
static QString typeToString(EventWatcher::EVENT_TYPE);
//Retrieve the most recent event message for a particular type of event
QJsonValue lastEvent(EVENT_TYPE type);
@@ -38,7 +39,6 @@ private:
//Life Preserver Event variables/functions
QString tmpLPRepFile;
qint64 LPlog_pos, LPrep_pos, LPerr_pos; //file position markers
void sendLPEvent(QString system, int priority, QString msg);

View File

@@ -1,17 +1,34 @@
// ===============================
// PC-BSD REST/JSON API Server
// Available under the 3-clause BSD License
// Written by: Ken Moore <ken@pcbsd.org> 2016
// =================================
#include "LogManager.h"
#include "globals.h"
#define TMPBREAK "<!!line-break!!>"
//Overall check/creation of the log directory
void LogManager::checkLogDir(){
if(!QFile::exists(LOGDIR)){
QDir dir(LOGDIR);
dir.mkpath(LOGDIR);
//Determing the log dir based on type of server
QString logd = LOGDIR; //base log dir
if(WS_MODE){ logd.append("/websocket"); }
else{ logd.append("/restserver"); }
//Check/create the dir
if(!QFile::exists(logd)){
QDir dir(logd);
dir.mkpath(logd);
}
}
//Main Log write function (all the overloaded versions end up calling this one)
void LogManager::log(QString file, QStringList msgs, QDateTime time){
qDebug() << "Log to File:" << file << msgs;
if(file.isEmpty()){ return; }
else if(!file.startsWith("/")){
//relative path - put it in the main log dir
if(WS_MODE){ file.prepend(LOGDIR+"/websocket/"); }
else{ file.prepend(LOGDIR+"/restserver/"); }
}
//qDebug() << "Log to File:" << file << msgs;
if(file.isEmpty()){ return; }
QFile LOG(file);
//if(!LOG.exists()){ system( QString("touch "+file).toLocal8Bit() ); }

View File

@@ -49,7 +49,7 @@ public:
//Log a list of strings (same timestamp for all lines)
static void log(QString file, QStringList msgs, QDateTime time = QDateTime::currentDateTime());
static void log(LogManager::LOG_FILE file, QStringList msgs, QDateTime time = QDateTime::currentDateTime()){
log(LOGDIR+"/"+flagToPath(file).arg(time.date().toString(Qt::ISODate)), msgs, time);
log(flagToPath(file).arg(time.date().toString(Qt::ISODate)), msgs, time);
}
//Log a simple text string
@@ -57,7 +57,7 @@ public:
log(file, QStringList() << msg, time);
}
static void log(LogManager::LOG_FILE file, QString msg, QDateTime time = QDateTime::currentDateTime()){
log(LOGDIR+"/"+flagToPath(file).arg(time.date().toString(Qt::ISODate)), QStringList() << msg, time);
log(flagToPath(file).arg(time.date().toString(Qt::ISODate)), QStringList() << msg, time);
}
//Log a JSON Object
@@ -65,15 +65,15 @@ public:
log(file, QStringList() << QJsonDocument(obj).toJson(QJsonDocument::Compact), time);
}
static void log(LogManager::LOG_FILE file, QJsonObject obj, QDateTime time = QDateTime::currentDateTime()){
log(LOGDIR+"/"+flagToPath(file).arg(time.date().toString(Qt::ISODate)), QStringList() << QJsonDocument(obj).toJson(QJsonDocument::Compact), time);
log(flagToPath(file).arg(time.date().toString(Qt::ISODate)), QStringList() << QJsonDocument(obj).toJson(QJsonDocument::Compact), time);
}
//Log a JSON Array
static void log(QString file, QJsonArray array, QDateTime time = QDateTime::currentDateTime()){
log(LOGDIR+"/"+file, QStringList() << QJsonDocument(array).toJson(QJsonDocument::Compact), time);
log(file, QStringList() << QJsonDocument(array).toJson(QJsonDocument::Compact), time);
}
static void log(LogManager::LOG_FILE file, QJsonArray array, QDateTime time = QDateTime::currentDateTime()){
log(LOGDIR+"/"+flagToPath(file).arg(time.date().toString(Qt::ISODate)), QStringList() << QJsonDocument(array).toJson(QJsonDocument::Compact), time);
log(flagToPath(file).arg(time.date().toString(Qt::ISODate)), QStringList() << QJsonDocument(array).toJson(QJsonDocument::Compact), time);
}
// === READ FROM LOG FUNCTIONS ===

View File

@@ -371,11 +371,7 @@ void WebSocket::EventUpdate(EventWatcher::EVENT_TYPE evtype, QJsonValue msg){
out.in_struct.namesp = "events";
out.out_args = msg;
out.Header << "Content-Type: text/json; charset=utf-8"; //REST header info
if(evtype==EventWatcher::DISPATCHER){
out.in_struct.name = "dispatcher";
}else if(evtype==EventWatcher::LIFEPRESERVER){
out.in_struct.name = "life-preserver";
}
out.in_struct.name = EventWatcher::typeToString(evtype);
//Now send the message back through the socket
this->sendReply(out.assembleMessage());

View File

@@ -12,6 +12,7 @@
//Global variables/classes (intially created in main.cpp)
extern QSettings *CONFIG;
extern bool WS_MODE;
#include "EventWatcher.h"
extern EventWatcher *EVENTS;

View File

@@ -10,12 +10,13 @@
#include "WebServer.h"
#define DEBUG 1
#define DEBUG 0
//Create any global classes
QSettings *CONFIG = new QSettings("PCBSD","sysadm");
EventWatcher *EVENTS = new EventWatcher();
Dispatcher *DISPATCHER = new Dispatcher();
bool WS_MODE = false;
//Create the default logfile
QFile logfile;
@@ -52,13 +53,13 @@ int main( int argc, char ** argv )
qDebug() << "sysadm-server must be started as root!";
return 1;
}
LogManager::checkLogDir(); //ensure the logging directry exists
//Evaluate input arguments
bool websocket = false;
quint16 port = 0;
for(int i=1; i<argc; i++){
if( QString(argv[i])=="-ws" ){ websocket = true; }
if( QString(argv[i])=="-ws" ){ websocket = true; WS_MODE = true;}
else if( QString(argv[i])=="-p" && (i+1<argc) ){ i++; port = QString(argv[i]).toUInt(); }
}
if(port==0){
@@ -66,6 +67,7 @@ int main( int argc, char ** argv )
else{ port = PORTNUMBER; }
}
//Setup the log file
LogManager::checkLogDir(); //ensure the logging directory exists
if(!websocket){ logfile.setFileName("/var/log/sysadm-server-tcp.log"); }
else{ logfile.setFileName("/var/log/sysadm-server-ws.log"); }
if(DEBUG){ qDebug() << "Log File:" << logfile.fileName(); }