v1.5.t8
Logs are still being cutoff, I'm assuming the app is crashing but can't locate the problem without any logs. Reformed logging to never overwrite the logs and will instead append only. Size control will be in the form of the byte size of the log files.
This commit is contained in:
parent
651ec96083
commit
954fdfba0b
|
@ -179,6 +179,10 @@ bool rdConf(shared_t *share)
|
||||||
share->recordUrl.clear();
|
share->recordUrl.clear();
|
||||||
share->postCmd.clear();
|
share->postCmd.clear();
|
||||||
share->buffDir.clear();
|
share->buffDir.clear();
|
||||||
|
share->recLogPath.clear();
|
||||||
|
share->detLogPath.clear();
|
||||||
|
share->recLogFile.close();
|
||||||
|
share->detLogFile.close();
|
||||||
|
|
||||||
share->retCode = 0;
|
share->retCode = 0;
|
||||||
share->frameGap = 10;
|
share->frameGap = 10;
|
||||||
|
@ -187,7 +191,7 @@ bool rdConf(shared_t *share)
|
||||||
share->secs = 60;
|
share->secs = 60;
|
||||||
share->maxDays = 15;
|
share->maxDays = 15;
|
||||||
share->maxClips = 30;
|
share->maxClips = 30;
|
||||||
share->maxLogLines = 1000;
|
share->maxLogSize = 10000;
|
||||||
share->camName = path(share->conf.c_str()).filename();
|
share->camName = path(share->conf.c_str()).filename();
|
||||||
share->webRoot = "/var/www/html";
|
share->webRoot = "/var/www/html";
|
||||||
share->vidExt = "mp4";
|
share->vidExt = "mp4";
|
||||||
|
@ -217,13 +221,15 @@ bool rdConf(shared_t *share)
|
||||||
rdLine("img_thresh = ", line, &share->imgThresh);
|
rdLine("img_thresh = ", line, &share->imgThresh);
|
||||||
rdLine("max_days = ", line, &share->maxDays);
|
rdLine("max_days = ", line, &share->maxDays);
|
||||||
rdLine("max_clips = ", line, &share->maxClips);
|
rdLine("max_clips = ", line, &share->maxClips);
|
||||||
rdLine("max_log_lines = ", line, &share->maxLogLines);
|
rdLine("max_log_size = ", line, &share->maxLogSize);
|
||||||
rdLine("vid_container = ", line, &share->vidExt);
|
rdLine("vid_container = ", line, &share->vidExt);
|
||||||
}
|
}
|
||||||
|
|
||||||
} while(!line.empty());
|
} while(!line.empty());
|
||||||
|
|
||||||
share->outDir = cleanDir(share->webRoot) + "/" + share->camName;
|
share->outDir = cleanDir(share->webRoot) + "/" + share->camName;
|
||||||
|
share->recLogPath = share->outDir + "/rec_log_lines.html";
|
||||||
|
share->detLogPath = share->outDir + "/det_log_lines.html";
|
||||||
|
|
||||||
if (share->init)
|
if (share->init)
|
||||||
{
|
{
|
||||||
|
|
55
src/common.h
55
src/common.h
|
@ -35,36 +35,39 @@ using namespace cv;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace std::filesystem;
|
using namespace std::filesystem;
|
||||||
|
|
||||||
#define APP_VER "1.5.t7"
|
#define APP_VER "1.5.t8"
|
||||||
#define APP_NAME "Motion Watch"
|
#define APP_NAME "Motion Watch"
|
||||||
|
|
||||||
struct shared_t
|
struct shared_t
|
||||||
{
|
{
|
||||||
vector<string> recLogLines;
|
|
||||||
vector<string> detLogLines;
|
ofstream recLogFile;
|
||||||
string recordUrl;
|
ofstream detLogFile;
|
||||||
string outDir;
|
string recLogPath;
|
||||||
string postCmd;
|
string detLogPath;
|
||||||
string conf;
|
string recordUrl;
|
||||||
string buffDir;
|
string outDir;
|
||||||
string vidExt;
|
string postCmd;
|
||||||
string camName;
|
string conf;
|
||||||
string webBg;
|
string buffDir;
|
||||||
string webTxt;
|
string vidExt;
|
||||||
string webFont;
|
string camName;
|
||||||
string webRoot;
|
string webBg;
|
||||||
bool init;
|
string webTxt;
|
||||||
bool recLoopWait;
|
string webFont;
|
||||||
bool logRun;
|
string webRoot;
|
||||||
bool skipCmd;
|
bool init;
|
||||||
int frameGap;
|
bool recLoopWait;
|
||||||
int pixThresh;
|
bool logRun;
|
||||||
int imgThresh;
|
bool skipCmd;
|
||||||
int secs;
|
int frameGap;
|
||||||
int maxDays;
|
int pixThresh;
|
||||||
int maxClips;
|
int imgThresh;
|
||||||
int maxLogLines;
|
int secs;
|
||||||
int retCode;
|
int maxDays;
|
||||||
|
int maxClips;
|
||||||
|
int maxLogSize;
|
||||||
|
int retCode;
|
||||||
};
|
};
|
||||||
|
|
||||||
string genDstFile(const string &dirOut, const char *fmt, const string &ext);
|
string genDstFile(const string &dirOut, const char *fmt, const string &ext);
|
||||||
|
|
|
@ -14,53 +14,89 @@
|
||||||
|
|
||||||
void recLog(const string &line, shared_t *share)
|
void recLog(const string &line, shared_t *share)
|
||||||
{
|
{
|
||||||
share->recLogLines.push_back(genTimeStr("[%Y-%m-%d-%H-%M-%S] ") + line + "<br>\n");
|
share->recLogFile << genTimeStr("[%Y-%m-%d-%H-%M-%S] ") << line << "<br>" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void detLog(const string &line, shared_t *share)
|
void detLog(const string &line, shared_t *share)
|
||||||
{
|
{
|
||||||
share->detLogLines.push_back(genTimeStr("[%Y-%m-%d-%H-%M-%S] ") + line + "<br>\n");
|
share->detLogFile << genTimeStr("[%Y-%m-%d-%H-%M-%S] ") << line << "<br>" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void enforceMaxLogLines(vector<string> &log, shared_t *share)
|
void enforceMaxLogSize(const string &filePath, shared_t *share)
|
||||||
{
|
{
|
||||||
while (log.size() > share->maxLogLines)
|
if (file_size(filePath) >= share->maxLogSize)
|
||||||
{
|
{
|
||||||
log.erase(log.begin());
|
remove(filePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string combine(const vector<string> &log)
|
void initLogFile(const string &filePath, ofstream &fileObj)
|
||||||
{
|
{
|
||||||
string ret;
|
if (!fileObj.is_open())
|
||||||
|
{
|
||||||
|
if (!fileExists(filePath))
|
||||||
|
{
|
||||||
|
system(string("touch " + filePath).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
for (auto &&line : log) ret += line;
|
fileObj.open(filePath.c_str(), ofstream::app | ofstream::out);
|
||||||
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wrOutLogs(shared_t *share)
|
void initLogFrontPage(const string &filePath, const string &logLinesFile)
|
||||||
{
|
{
|
||||||
auto recLogFilePath = cleanDir(share->outDir) + "/recording_log.html";
|
string htmlText = "<!DOCTYPE html>\n";
|
||||||
auto detLogFilePath = cleanDir(share->outDir) + "/detection_log.html";
|
|
||||||
string htmlText = "<!DOCTYPE html>\n";
|
|
||||||
|
|
||||||
ofstream recFile(recLogFilePath.c_str());
|
|
||||||
ofstream detFile(detLogFilePath.c_str());
|
|
||||||
|
|
||||||
htmlText += "<html>\n";
|
htmlText += "<html>\n";
|
||||||
|
htmlText += "<script>\n";
|
||||||
|
htmlText += "function includeHTML() {\n";
|
||||||
|
htmlText += " var z, i, elmnt, file, xhttp;\n";
|
||||||
|
htmlText += " z = document.getElementsByTagName(\"*\");\n";
|
||||||
|
htmlText += " for (i = 0; i < z.length; i++) {\n";
|
||||||
|
htmlText += " elmnt = z[i];\n";
|
||||||
|
htmlText += " file = elmnt.getAttribute(\"include-html\");\n";
|
||||||
|
htmlText += " if (file) {\n";
|
||||||
|
htmlText += " xhttp = new XMLHttpRequest();\n";
|
||||||
|
htmlText += " xhttp.onreadystatechange = function() {\n";
|
||||||
|
htmlText += " if (this.readyState == 4) {\n";
|
||||||
|
htmlText += " if (this.status == 200) {elmnt.innerHTML = this.responseText;}\n";
|
||||||
|
htmlText += " if (this.status == 404) {elmnt.innerHTML = \"Page not found.\";}\n";
|
||||||
|
htmlText += " elmnt.removeAttribute(\"include-html\");\n";
|
||||||
|
htmlText += " includeHTML();\n";
|
||||||
|
htmlText += " }\n";
|
||||||
|
htmlText += " }\n";
|
||||||
|
htmlText += " xhttp.open(\"GET\", file, true);\n";
|
||||||
|
htmlText += " xhttp.send();\n";
|
||||||
|
htmlText += " return;\n";
|
||||||
|
htmlText += " }\n";
|
||||||
|
htmlText += " }\n";
|
||||||
|
htmlText += "};\n";
|
||||||
|
htmlText += "</script>\n";
|
||||||
htmlText += "<head>\n";
|
htmlText += "<head>\n";
|
||||||
htmlText += "<link rel='stylesheet' href='/theme.css'>\n";
|
htmlText += "<link rel='stylesheet' href='/theme.css'>\n";
|
||||||
htmlText += "</head>\n";
|
htmlText += "</head>\n";
|
||||||
htmlText += "<body>\n";
|
htmlText += "<body>\n";
|
||||||
htmlText += "<p>\n";
|
htmlText += "<p>\n";
|
||||||
|
htmlText += "<div include-html='" + logLinesFile + "'></div>\n";
|
||||||
|
htmlText += "<script>\n";
|
||||||
|
htmlText += "includeHTML();\n";
|
||||||
|
htmlText += "</script>\n";
|
||||||
|
htmlText += "</p>\n";
|
||||||
|
htmlText += "</body>\n";
|
||||||
|
htmlText += "</html>\n";
|
||||||
|
|
||||||
recFile << htmlText << combine(share->recLogLines) << "</p>\n</body>\n</html>\n";
|
ofstream outFile(filePath);
|
||||||
detFile << htmlText << combine(share->detLogLines) << "</p>\n</body>\n</html>\n";
|
|
||||||
|
|
||||||
recFile.close();
|
outFile << htmlText;
|
||||||
detFile.close();
|
|
||||||
|
|
||||||
enforceMaxLogLines(share->recLogLines, share);
|
outFile.close();
|
||||||
enforceMaxLogLines(share->detLogLines, share);
|
}
|
||||||
|
|
||||||
|
void initLogFrontPages(shared_t *share)
|
||||||
|
{
|
||||||
|
auto recLogFilePath = share->outDir + "/recording_log.html";
|
||||||
|
auto detLogFilePath = share->outDir + "/detection_log.html";
|
||||||
|
|
||||||
|
initLogFrontPage(recLogFilePath, path(share->recLogPath).filename().string());
|
||||||
|
initLogFrontPage(detLogFilePath, path(share->detLogPath).filename().string());
|
||||||
}
|
}
|
||||||
|
|
10
src/logger.h
10
src/logger.h
|
@ -15,10 +15,10 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
void recLog(const string &line, shared_t *share);
|
void recLog(const string &line, shared_t *share);
|
||||||
void detLog(const string &line, shared_t *share);
|
void detLog(const string &line, shared_t *share);
|
||||||
void wrOutLogs(shared_t *share);
|
void enforceMaxLogSize(const string &filePath, shared_t *share);
|
||||||
void enforceMaxLogLines(vector<string> &log, shared_t *share);
|
void initLogFile(const string &filePath, ofstream &fileObj);
|
||||||
string combine(const vector<string> &log);
|
void initLogFrontPages(shared_t *share);
|
||||||
|
|
||||||
#endif // lOGGER_H
|
#endif // lOGGER_H
|
||||||
|
|
65
src/main.cpp
65
src/main.cpp
|
@ -16,9 +16,9 @@
|
||||||
void detectLoop(shared_t *share)
|
void detectLoop(shared_t *share)
|
||||||
{
|
{
|
||||||
detLog("detectLoop() -- start", share);
|
detLog("detectLoop() -- start", share);
|
||||||
wrOutLogs(share);
|
|
||||||
|
|
||||||
vector<string> bufFiles;
|
vector<string> bufFiles;
|
||||||
|
auto waitingForFiles = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -50,30 +50,46 @@ void detectLoop(shared_t *share)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sleep(1);
|
if (waitingForFiles >= share->secs)
|
||||||
|
{
|
||||||
|
detLog("timed out waiting for buff files from ffmpeg, did it fail?", share);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(1); waitingForFiles++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (!bufFiles.empty() && !share->recLoopWait);
|
while (!bufFiles.empty() && !share->recLoopWait);
|
||||||
|
|
||||||
detLog("detectLoop() -- finished", share);
|
detLog("detectLoop() -- finished", share);
|
||||||
wrOutLogs(share);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void recLoop(shared_t *share)
|
void recLoop(shared_t *share)
|
||||||
{
|
{
|
||||||
while (rdConf(share))
|
while (rdConf(share))
|
||||||
{
|
{
|
||||||
recLog("recLoop() -- start", share);
|
enforceMaxLogSize(share->recLogPath, share);
|
||||||
wrOutLogs(share);
|
enforceMaxLogSize(share->detLogPath, share);
|
||||||
|
|
||||||
if (!fileExists("/tmp/mow-lock"))
|
initLogFile(share->recLogPath, share->recLogFile);
|
||||||
|
initLogFile(share->detLogPath, share->detLogFile);
|
||||||
|
|
||||||
|
initLogFrontPages(share);
|
||||||
|
|
||||||
|
recLog("recLoop() -- start", share);
|
||||||
|
|
||||||
|
if (!exists("/tmp/mow-lock"))
|
||||||
{
|
{
|
||||||
recLog("/tmp/mow-lock not found, assuming it is safe to update the webroot page.", share);
|
recLog("/tmp/mow-lock not found, assuming it is safe to update the webroot page.", share);
|
||||||
recLog("webroot page = " + cleanDir(share->webRoot) + "/index.html", share);
|
recLog("webroot page = " + cleanDir(share->webRoot) + "/index.html", share);
|
||||||
|
|
||||||
system("touch /tmp/mow-lock");
|
system("touch /tmp/mow-lock");
|
||||||
|
|
||||||
genCSS(share);
|
genCSS(share);
|
||||||
genHTMLul(share->webRoot, string(APP_NAME) + " " + string(APP_VER), share);
|
genHTMLul(share->webRoot, string(APP_NAME) + " " + string(APP_VER), share);
|
||||||
system("rm /tmp/mow-lock");
|
|
||||||
|
remove("/tmp/mow-lock");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -81,6 +97,7 @@ void recLoop(shared_t *share)
|
||||||
}
|
}
|
||||||
|
|
||||||
genHTMLul(share->outDir, share->camName, share);
|
genHTMLul(share->outDir, share->camName, share);
|
||||||
|
|
||||||
recLog("camera specific webroot page updated. page = " + share->outDir + "/index.html", share);
|
recLog("camera specific webroot page updated. page = " + share->outDir + "/index.html", share);
|
||||||
|
|
||||||
auto bufPath = cleanDir(share->buffDir) + "/%03d." + share->vidExt;
|
auto bufPath = cleanDir(share->buffDir) + "/%03d." + share->vidExt;
|
||||||
|
@ -90,33 +107,43 @@ void recLoop(shared_t *share)
|
||||||
|
|
||||||
thread th2(detectLoop, share);
|
thread th2(detectLoop, share);
|
||||||
|
|
||||||
recLog("detect_loop started in a seperate thread.", share);
|
recLog("detectLoop() -- started in a seperate thread.", share);
|
||||||
recLog("ffmpeg = " + cmd, share);
|
recLog("ffmpeg_run: " + cmd, share);
|
||||||
|
|
||||||
system(cmd.c_str());
|
auto retCode = system(cmd.c_str());
|
||||||
|
|
||||||
|
recLog("ffmpeg_retcode: " + to_string(retCode), share);
|
||||||
|
|
||||||
share->recLoopWait = true;
|
share->recLoopWait = true;
|
||||||
|
|
||||||
th2.join();
|
th2.join();
|
||||||
|
|
||||||
wrOutLogs(share);
|
|
||||||
|
|
||||||
if (!share->skipCmd)
|
if (!share->skipCmd)
|
||||||
{
|
{
|
||||||
recLog("motion not detected by detect loop.", share);
|
recLog("motion not detected by the detection loop.", share);
|
||||||
recLog("running post command = " + share->postCmd, share);
|
|
||||||
system(share->postCmd.c_str());
|
if (share->postCmd.empty())
|
||||||
|
{
|
||||||
|
recLog("post command not defined, skipping.", share);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
recLog("running post command = " + share->postCmd, share);
|
||||||
|
system(share->postCmd.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
recLog("motion detected by detect loop, skpping the post command.", share);
|
recLog("motion detected by the detection loop, skipping the post command.", share);
|
||||||
}
|
}
|
||||||
|
|
||||||
recLog("recLoop() -- finished", share);
|
recLog("recLoop() -- finished", share);
|
||||||
wrOutLogs(share);
|
|
||||||
}
|
|
||||||
|
|
||||||
share->logRun = false;
|
if (share->retCode != 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
|
|
|
@ -45,12 +45,15 @@ void genHTMLul(const string &outputDir, const string &title, shared_t *share)
|
||||||
{
|
{
|
||||||
logNames.push_back(regName);
|
logNames.push_back(regName);
|
||||||
}
|
}
|
||||||
else if (regName.ends_with(".html") && !regName.ends_with("index.html"))
|
else if (regName.ends_with(".html") &&
|
||||||
|
!regName.ends_with("index.html") &&
|
||||||
|
!regName.ends_with("rec_log_lines.html") &&
|
||||||
|
!regName.ends_with("det_log_lines.html"))
|
||||||
{
|
{
|
||||||
// regName.substr(0, regName.size() - 5) removes .html
|
// regName.substr(0, regName.size() - 5) removes .html
|
||||||
auto name = regName.substr(0, regName.size() - 5);
|
auto name = regName.substr(0, regName.size() - 5);
|
||||||
|
|
||||||
htmlText += "<a href='" + regName + "'><img src='" + name + ".jpg" + "' style='width:25%;height:25%;'</a>\n";
|
htmlText += "<a href='" + regName + "'><img src='" + name + ".jpg" + "' style='width:10%;height:10%;'</a>\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user