added basic log file handler
This commit is contained in:
parent
727af3ea16
commit
d5156d3345
2 changed files with 81 additions and 23 deletions
89
common/log.h
89
common/log.h
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue