lokinet/llarp/util/logging/logger.cpp

183 lines
4.1 KiB
C++
Raw Normal View History

2019-09-01 12:10:49 +00:00
#include <util/logging/logger.hpp>
#include <util/logging/logger.h>
#include <util/logging/ostream_logger.hpp>
#include <util/logging/logger_syslog.hpp>
#include <util/logging/file_logger.hpp>
#include <util/logging/json_logger.hpp>
2019-04-11 12:58:23 +00:00
#if defined(_WIN32)
2019-09-01 12:10:49 +00:00
#include <util/logging/win32_logger.hpp>
2019-04-11 12:58:23 +00:00
#endif
#if defined(ANDROID)
2019-09-01 12:10:49 +00:00
#include <util/logging/android_logger.hpp>
2019-04-11 12:58:23 +00:00
#endif
#include <util/str.hpp>
#include <stdexcept>
namespace llarp
{
2019-04-11 12:58:23 +00:00
#if defined(_WIN32)
using Stream_t = Win32LogStream;
#define _LOGSTREAM_INIT std::cout
#else
#if defined(ANDROID)
using Stream_t = AndroidLogStream;
#define _LOGSTREAM_INIT
#else
using Stream_t = OStreamLogStream;
2019-09-16 19:40:31 +00:00
#define _LOGSTREAM_INIT true, std::cout
2019-04-11 12:58:23 +00:00
#endif
#endif
LogType
LogTypeFromString(const std::string& str)
{
if (str == "unknown") return LogType::Unknown;
else if (str == "file") return LogType::File;
else if (str == "json") return LogType::Json;
else if (str == "syslog") return LogType::Syslog;
return LogType::Unknown;
}
2019-04-11 12:58:23 +00:00
LogContext::LogContext()
: logStream(std::make_unique<Stream_t>(_LOGSTREAM_INIT)), started(llarp::time_now_ms())
2019-04-11 12:58:23 +00:00
{
}
LogContext&
LogContext::Instance()
{
static LogContext ctx;
return ctx;
}
2019-12-09 13:08:30 +00:00
void
LogContext::DropToRuntimeLevel()
{
curLevel = runtimeLevel;
}
void
LogContext::RevertRuntimeLevel()
{
curLevel = startupLevel;
}
2019-06-10 13:20:48 +00:00
log_timestamp::log_timestamp() : log_timestamp("%c %Z")
{
}
log_timestamp::log_timestamp(const char* fmt)
: format(fmt)
, now(llarp::time_now_ms())
, delta(llarp::time_now_ms() - LogContext::Instance().started)
{
}
void
SetLogLevel(LogLevel lvl)
{
2019-12-09 13:08:30 +00:00
LogContext::Instance().curLevel = lvl;
if (lvl == eLogDebug)
{
LogContext::Instance().runtimeLevel = lvl;
}
}
void
LogContext::ImmediateFlush()
{
logStream->ImmediateFlush();
}
void
LogContext::Initialize(LogLevel level,
LogType type,
const std::string& file,
const std::string& nickname,
std::shared_ptr<thread::ThreadPool> threadpool)
{
SetLogLevel(level);
nodeName = nickname;
FILE* logfile = nullptr;
if (file == "stdout")
{
logfile = stdout;
}
else
{
logfile = ::fopen(file.c_str(), "a");
if (not logfile)
{
throw std::runtime_error(stringify(
"could not open logfile ", file, ", errno: ", strerror(errno)));
}
}
switch (type)
{
case LogType::Unknown:
throw std::invalid_argument("Cannot use LogType::Unknown");
case LogType::File:
if (logfile != stdout)
{
LogInfo("Switching logger to file ", file);
std::cout << std::flush;
LogContext::Instance().logStream =
std::make_unique< FileLogStream >(threadpool, logfile, 100ms, true);
}
else
{
LogInfo("Logger remains stdout");
}
break;
case LogType::Json:
LogInfo("Switching logger to JSON with file: ", file);
std::cout << std::flush;
LogContext::Instance().logStream = std::make_unique< JSONLogStream >(
threadpool, logfile, 100ms, logfile != stdout);
break;
case LogType::Syslog:
if (logfile)
{
// TODO: this logic should be handled in Config
// TODO: this won't even work because of default value for 'file' (== "stdout")
::fclose(logfile);
throw std::invalid_argument("Cannot mix log type=syslog and file=*");
}
#if defined(_WIN32)
throw std::runtime_error("syslog not supported on win32");
#else
LogInfo("Switching logger to syslog");
std::cout << std::flush;
LogContext::Instance().logStream = std::make_unique< SysLogStream >();
#endif
break;
}
}
2018-07-09 03:34:29 +00:00
} // namespace llarp
extern "C"
{
void
cSetLogLevel(LogLevel lvl)
{
llarp::SetLogLevel((llarp::LogLevel)lvl);
}
void
cSetLogNodeName(const char* name)
{
2019-04-11 12:58:23 +00:00
llarp::LogContext::Instance().nodeName = name;
}
}