add log file writing

This commit is contained in:
tildearrow 2022-12-18 01:55:21 -05:00
parent d897ac32b0
commit 51ea3cec2a
6 changed files with 142 additions and 1 deletions

View file

@ -23,6 +23,7 @@
#ifdef _WIN32
#include "winStuff.h"
#define CONFIG_FILE "\\furnace.cfg"
#define LOG_FILE "\\furnace.log"
#else
#ifdef __HAIKU__
#include <support/SupportDefs.h>

View file

@ -4221,7 +4221,7 @@ bool DivEngine::deinitAudioBackend(bool dueToSwitchMaster) {
return true;
}
bool DivEngine::init() {
void DivEngine::preInit() {
// register systems
if (!systemsRegistered) registerSystems();
@ -4229,8 +4229,13 @@ bool DivEngine::init() {
initConfDir();
logD("config path: %s",configPath.c_str());
loadConf();
String logPath=configPath+DIR_SEPARATOR_STR+"furnace.log";
startLogFile(logPath.c_str());
loadConf();
}
bool DivEngine::init() {
loadSampleROMs();
// set default system preset

View file

@ -1012,6 +1012,9 @@ class DivEngine {
// quit dispatch
void quitDispatch();
// pre-initialize the engine.
void preInit();
// initialize the engine.
bool init();

View file

@ -18,6 +18,8 @@
*/
#include "ta-log.h"
#include <thread>
#include <condition_variable>
#ifdef IS_MOBILE
int logLevel=LOGLEVEL_TRACE;
@ -25,11 +27,54 @@ int logLevel=LOGLEVEL_TRACE;
int logLevel=LOGLEVEL_INFO;
#endif
FILE* logFile;
char* logFileBuf;
unsigned int logFilePosI=0;
unsigned int logFilePosO=0;
std::thread* logFileThread;
std::mutex logFileLock;
std::mutex logFileLockI;
std::condition_variable logFileNotify;
bool logFileAvail=false;
std::atomic<unsigned short> logPosition;
LogEntry logEntries[TA_LOG_SIZE];
static constexpr unsigned int TA_LOG_MASK=TA_LOG_SIZE-1;
static constexpr unsigned int TA_LOGFILE_BUF_MASK=TA_LOGFILE_BUF_SIZE-1;
const char* logTypes[5]={
"ERROR",
"warning",
"info",
"debug",
"trace"
};
void appendLogBuf(const char* msg, size_t len) {
logFileLockI.lock();
int remaining=logFilePosO-logFilePosI;
if (remaining<=0) remaining+=TA_LOGFILE_BUF_SIZE;
if (len>=(unsigned int)remaining) {
printf("line too long to fit in log buffer!\n");
logFileLockI.unlock();
return;
}
if ((logFilePosI+len)>=TA_LOGFILE_BUF_SIZE) {
size_t firstWrite=TA_LOGFILE_BUF_SIZE-logFilePosI;
memcpy(logFileBuf+logFilePosI,msg,firstWrite);
memcpy(logFileBuf,msg+firstWrite,len-firstWrite);
} else {
memcpy(logFileBuf+logFilePosI,msg,len);
}
logFilePosI=(logFilePosI+len)&TA_LOGFILE_BUF_MASK;
logFileLockI.unlock();
}
int writeLog(int level, const char* msg, fmt::printf_args args) {
time_t thisMakesNoSense=time(NULL);
@ -54,6 +99,20 @@ int writeLog(int level, const char* msg, fmt::printf_args args) {
logEntries[pos].loglevel=level;
logEntries[pos].ready=true;
// write to log file
if (logFileAvail) {
std::string toWrite=fmt::sprintf(
"%02d:%02d:%02d [%s] %s\n",
logEntries[pos].time.tm_hour,
logEntries[pos].time.tm_min,
logEntries[pos].time.tm_sec,
logTypes[logEntries[pos].loglevel],
logEntries[pos].text
);
appendLogBuf(toWrite.c_str(),toWrite.size());
logFileNotify.notify_one();
}
if (logLevel<level) return 0;
switch (level) {
case LOGLEVEL_ERROR:
@ -71,8 +130,70 @@ int writeLog(int level, const char* msg, fmt::printf_args args) {
}
void initLog() {
// initalize log buffer
logPosition=0;
for (int i=0; i<TA_LOG_SIZE; i++) {
logEntries[i].text.reserve(128);
}
// initialize log to file thread
logFileAvail=false;
}
void _logFileThread() {
std::unique_lock<std::mutex> lock(logFileLock);
while (true) {
unsigned int logFilePosICopy=logFilePosI;
if (logFilePosICopy!=logFilePosO) {
// write
if (logFilePosO>logFilePosICopy) {
fwrite(logFileBuf+logFilePosO,1,TA_LOGFILE_BUF_SIZE-logFilePosO,logFile);
logFilePosO=0;
} else {
fwrite(logFileBuf+logFilePosO,1,logFilePosICopy-logFilePosO,logFile);
logFilePosO=logFilePosICopy;
}
} else {
// wait
if (!logFileAvail) break;
fflush(logFile);
logFileNotify.wait(lock);
}
}
}
bool startLogFile(const char* path) {
if (logFileAvail) return true;
// rotate log file if possible
// open log file
if ((logFile=fopen(path,"w+"))==NULL) {
logFileAvail=false;
logW("could not open log file! (%s)",strerror(errno));
return false;
}
logFileBuf=new char[TA_LOGFILE_BUF_SIZE];
logFilePosI=0;
logFilePosO=0;
logFileAvail=true;
logFileThread=new std::thread(_logFileThread);
return true;
}
bool finishLogFile() {
if (!logFileAvail) return false;
logFileAvail=false;
// flush
logFileLockI.lock();
logFileNotify.notify_one();
logFileThread->join();
logFileLockI.unlock();
fclose(logFile);
return true;
}

View file

@ -416,7 +416,11 @@ int main(int argc, char** argv) {
logI("usage: %s file",argv[0]);
return 1;
}
logI("Furnace version " DIV_VERSION ".");
e.preInit();
if (!fileName.empty()) {
logI("loading module...");
FILE* f=ps_fopen(fileName.c_str(),"rb");
@ -584,6 +588,8 @@ int main(int argc, char** argv) {
logI("stopping engine.");
e.quit();
finishLogFile();
#ifdef _WIN32
if (coResult==S_OK || coResult==S_FALSE) {
CoUninitialize();

View file

@ -35,6 +35,9 @@
// this has to be a power of 2
#define TA_LOG_SIZE 2048
// this as well
#define TA_LOGFILE_BUF_SIZE 65536
extern int logLevel;
extern std::atomic<unsigned short> logPosition;
@ -76,4 +79,6 @@ template<typename... T> int logE(const char* msg, const T&... args) {
}
void initLog();
bool startLogFile(const char* path);
bool finishLogFile();
#endif