added basic log file handler

This commit is contained in:
staviq 2023-08-23 16:03:30 +02:00
parent 727af3ea16
commit d5156d3345
2 changed files with 81 additions and 23 deletions

View file

@ -1,39 +1,57 @@
#pragma once
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <chrono>
#include <atomic>
#include <cstring>
// Specifies a log target.
// default simply prints log to stderr
// default uses log_handler() with "llama.log" log file
// this can be changed, by defining LOG_TARGET
// like so:
//
// #define LOG_TARGET (a valid FILE*)
// #include "log.h"
//
// The log target can also be redirected to a function
// or it can be simply redirected to stdout or stderr
// like so:
//
// #define LOG_TARGET log_handler()
// #define LOG_TARGET stderr
// #include "log.h"
//
// FILE* log_handler()
// The log target can also be redirected to a diffrent function
// like so:
//
// #define LOG_TARGET log_handler_diffrent()
// #include "log.h"
//
// FILE* log_handler_diffrent()
// {
// return stderr;
// }
//
// or:
//
// #define LOG_TARGET log_handler("somelog.log")
// #define LOG_TARGET log_handler_another_one("somelog.log")
// #include "log.h"
//
// FILE* log_handler(char*filename)
// FILE* log_handler_another_one(char*filename)
// {
// static FILE* logfile = nullptr;
// (...)
// return fopen(...)
// if( !logfile )
// {
// fopen(...)
// }
// (...)
// return logfile
// }
//
#ifndef LOG_TARGET
#define LOG_TARGET stderr
#define LOG_TARGET log_handler()
#endif
// Allows disabling timestamps.
@ -75,4 +93,57 @@
// This us a trick to bypass the silly
// "warning: ISO C++11 requires at least one argument for the "..." in a variadic macro"
// so we xan gave a single macro which can be called just like printf.
#define LOG(...) _LOG(__VA_ARGS__, '\n')
#define LOG(...) _LOG(__VA_ARGS__, '\n')
inline FILE *log_handler(std::string s = "llama.log")
{
static std::atomic_bool _initialized{false};
static std::atomic_bool _logfileopened{false};
static FILE* logfile = nullptr;
if (_initialized)[[likely]]
{
// with fallback in case something went wrong
return logfile ? logfile : stderr;
}
else
{
// Mutex-less threadsafe synchronisation.
// we need to make sure not more than one invocation of this function
// attempts to open a file at once.
// compare_exchange_strong checks and updates a flag
// in a single atomic operation.
bool expected{false};
if( _logfileopened.compare_exchange_strong(expected,true) )
{
// If the flag was previously false, and we managed to turn it true
// ew are now responsible for opening the log file
logfile = fopen( s.c_str(), "wa" );
if( !logfile )
{
// Verify whether the file was opened, otherwise fallback to stderr
logfile = stderr;
fprintf(stderr, "Failed to open logfile '%s' with error '%s'\n", s.c_str(), std::strerror(errno));
fflush(stderr);
}
_initialized.store(true);
}
else
{
// We are not first to open the log file
//
// TODO: Better thread-safe option, possibly std::condition_variable
return stderr;
}
// with fallback in case something went wrong
return logfile ? logfile : stderr;
}
return stderr;
}

View file

@ -3,7 +3,7 @@
#define _GNU_SOURCE
#endif
#define LOG_TARGET log_handler("asd")
//#define LOG_TARGET log_handler("asd")
//#define LOG_NO_TIMESTAMPS
#include "common.h"
@ -58,19 +58,6 @@ void sigint_handler(int signo) {
}
#endif
inline FILE *log_handler(std::string s)
{
static bool initialized{false};
if (!initialized)[[unlikely]]
{
fprintf(stderr,"arg: %s", s.c_str());
initialized=true;
}
return stderr;
}
int main(int argc, char ** argv) {
gpt_params params;