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:
Maurice ONeal 2022-12-13 20:27:32 -05:00
parent 651ec96083
commit 954fdfba0b
6 changed files with 154 additions and 79 deletions

View File

@ -179,6 +179,10 @@ bool rdConf(shared_t *share)
share->recordUrl.clear();
share->postCmd.clear();
share->buffDir.clear();
share->recLogPath.clear();
share->detLogPath.clear();
share->recLogFile.close();
share->detLogFile.close();
share->retCode = 0;
share->frameGap = 10;
@ -187,7 +191,7 @@ bool rdConf(shared_t *share)
share->secs = 60;
share->maxDays = 15;
share->maxClips = 30;
share->maxLogLines = 1000;
share->maxLogSize = 10000;
share->camName = path(share->conf.c_str()).filename();
share->webRoot = "/var/www/html";
share->vidExt = "mp4";
@ -217,13 +221,15 @@ bool rdConf(shared_t *share)
rdLine("img_thresh = ", line, &share->imgThresh);
rdLine("max_days = ", line, &share->maxDays);
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);
}
} while(!line.empty());
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)
{

View File

@ -35,13 +35,16 @@ using namespace cv;
using namespace std;
using namespace std::filesystem;
#define APP_VER "1.5.t7"
#define APP_VER "1.5.t8"
#define APP_NAME "Motion Watch"
struct shared_t
{
vector<string> recLogLines;
vector<string> detLogLines;
ofstream recLogFile;
ofstream detLogFile;
string recLogPath;
string detLogPath;
string recordUrl;
string outDir;
string postCmd;
@ -63,7 +66,7 @@ struct shared_t
int secs;
int maxDays;
int maxClips;
int maxLogLines;
int maxLogSize;
int retCode;
};

View File

@ -14,53 +14,89 @@
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)
{
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;
return ret;
fileObj.open(filePath.c_str(), ofstream::app | ofstream::out);
}
}
void wrOutLogs(shared_t *share)
void initLogFrontPage(const string &filePath, const string &logLinesFile)
{
auto recLogFilePath = cleanDir(share->outDir) + "/recording_log.html";
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 += "<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 += "<link rel='stylesheet' href='/theme.css'>\n";
htmlText += "</head>\n";
htmlText += "<body>\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";
detFile << htmlText << combine(share->detLogLines) << "</p>\n</body>\n</html>\n";
ofstream outFile(filePath);
recFile.close();
detFile.close();
outFile << htmlText;
enforceMaxLogLines(share->recLogLines, share);
enforceMaxLogLines(share->detLogLines, share);
outFile.close();
}
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());
}

View File

@ -17,8 +17,8 @@
void recLog(const string &line, shared_t *share);
void detLog(const string &line, shared_t *share);
void wrOutLogs(shared_t *share);
void enforceMaxLogLines(vector<string> &log, shared_t *share);
string combine(const vector<string> &log);
void enforceMaxLogSize(const string &filePath, shared_t *share);
void initLogFile(const string &filePath, ofstream &fileObj);
void initLogFrontPages(shared_t *share);
#endif // lOGGER_H

View File

@ -16,9 +16,9 @@
void detectLoop(shared_t *share)
{
detLog("detectLoop() -- start", share);
wrOutLogs(share);
vector<string> bufFiles;
auto waitingForFiles = 0;
do
{
@ -50,30 +50,46 @@ void detectLoop(shared_t *share)
}
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);
detLog("detectLoop() -- finished", share);
wrOutLogs(share);
}
void recLoop(shared_t *share)
{
while (rdConf(share))
{
recLog("recLoop() -- start", share);
wrOutLogs(share);
enforceMaxLogSize(share->recLogPath, 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("webroot page = " + cleanDir(share->webRoot) + "/index.html", share);
system("touch /tmp/mow-lock");
genCSS(share);
genHTMLul(share->webRoot, string(APP_NAME) + " " + string(APP_VER), share);
system("rm /tmp/mow-lock");
remove("/tmp/mow-lock");
}
else
{
@ -81,6 +97,7 @@ void recLoop(shared_t *share)
}
genHTMLul(share->outDir, share->camName, share);
recLog("camera specific webroot page updated. page = " + share->outDir + "/index.html", share);
auto bufPath = cleanDir(share->buffDir) + "/%03d." + share->vidExt;
@ -90,33 +107,43 @@ void recLoop(shared_t *share)
thread th2(detectLoop, share);
recLog("detect_loop started in a seperate thread.", share);
recLog("ffmpeg = " + cmd, share);
recLog("detectLoop() -- started in a seperate thread.", 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;
th2.join();
wrOutLogs(share);
if (!share->skipCmd)
{
recLog("motion not detected by detect loop.", share);
recLog("running post command = " + share->postCmd, share);
system(share->postCmd.c_str());
recLog("motion not detected by the detection loop.", share);
if (share->postCmd.empty())
{
recLog("post command not defined, skipping.", share);
}
else
{
recLog("motion detected by detect loop, skpping the post command.", share);
recLog("running post command = " + share->postCmd, share);
system(share->postCmd.c_str());
}
}
else
{
recLog("motion detected by the detection loop, skipping the post command.", share);
}
recLog("recLoop() -- finished", share);
wrOutLogs(share);
}
share->logRun = false;
if (share->retCode != 0)
{
break;
}
}
}
int main(int argc, char** argv)

View File

@ -45,12 +45,15 @@ void genHTMLul(const string &outputDir, const string &title, shared_t *share)
{
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
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";
}
}