add log file writing
This commit is contained in:
parent
d897ac32b0
commit
51ea3cec2a
|
@ -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>
|
||||
|
|
|
@ -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());
|
||||
|
||||
String logPath=configPath+DIR_SEPARATOR_STR+"furnace.log";
|
||||
startLogFile(logPath.c_str());
|
||||
|
||||
loadConf();
|
||||
}
|
||||
|
||||
bool DivEngine::init() {
|
||||
loadSampleROMs();
|
||||
|
||||
// set default system preset
|
||||
|
|
|
@ -1012,6 +1012,9 @@ class DivEngine {
|
|||
// quit dispatch
|
||||
void quitDispatch();
|
||||
|
||||
// pre-initialize the engine.
|
||||
void preInit();
|
||||
|
||||
// initialize the engine.
|
||||
bool init();
|
||||
|
||||
|
|
121
src/log.cpp
121
src/log.cpp
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue