Add mutltiple Log Targets #4

pull/11/head
Geoffrey Merck 4 years ago
parent 626ae32e0d
commit 92ec8658fa

@ -36,6 +36,8 @@
#include "RepeaterProtocolHandlerFactory.h" #include "RepeaterProtocolHandlerFactory.h"
#include "XLXHostsFileDownloader.h" #include "XLXHostsFileDownloader.h"
#include "Log.h" #include "Log.h"
#include "LogFileTarget.h"
#include "LogConsoleTarget.h"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
@ -100,7 +102,8 @@ bool CDStarGatewayApp::createThread()
TLog log; TLog log;
config.getLog(log); config.getLog(log);
CLog::initialize(log.logDir + "dstargateway.log", LS_INFO, true); CLog::addTarget(new CLogConsoleTarget(LS_INFO));
CLog::addTarget(new CLogFileTarget(LS_INFO, log.logDir, true));
Tpaths paths; Tpaths paths;
config.getPaths(paths); config.getPaths(paths);

@ -18,18 +18,40 @@
*/ */
#include <ctime> #include <ctime>
#include <sstream>
#include <cassert>
#include "Log.h" #include "Log.h"
#include "LogConsoleTarget.h"
LOG_SEVERITY CLog::m_level = LS_INFO; LOG_SEVERITY CLog::m_level(LS_DEBUG);
std::string CLog::m_file = ""; bool CLog::m_addedTargets(false);
bool CLog::m_logToConsole = true; std::recursive_mutex CLog::m_targetsMutex;
std::vector<CLogTarget *> CLog::m_targets = { new CLogConsoleTarget(LS_DEBUG) };
void CLog::initialize(const std::string& logfile, LOG_SEVERITY logLevel, bool logToConsole) void CLog::addTarget(CLogTarget* target)
{ {
m_file = logfile; assert(target != nullptr);
m_level = logLevel;
m_logToConsole = logToConsole; std::lock_guard lockTargets(m_targetsMutex);
if(!m_addedTargets) {
// It is the first time we add an external target, clear the default one(s)
m_addedTargets = true;
finalise();
}
m_targets.push_back(target);
}
void CLog::finalise()
{
std::lock_guard lockTargets(m_targetsMutex);
for(auto target : m_targets) {
delete target;
}
m_targets.clear();
} }
void CLog::getTimeStamp(std::string & s) void CLog::getTimeStamp(std::string & s)

102
Log.h

@ -20,64 +20,26 @@
#pragma once #pragma once
#include <string> #include <string>
#include <iostream> #include <vector>
#include <fstream>
#include <chrono>
#include <sstream>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <mutex>
#include <sstream>
#include "StringUtils.h" #include "StringUtils.h"
#include "LogTarget.h"
enum LOG_SEVERITY {
LS_TRACE = 1,
LS_DEBUG,
LS_INFO,
LS_WARNING,
LS_ERROR,
LS_FATAL
};
class CLog class CLog
{ {
private: private:
static LOG_SEVERITY m_level; static LOG_SEVERITY m_level;
static std::string m_file; static std::vector<CLogTarget *> m_targets;
static bool m_logToConsole; static bool m_addedTargets;
static std::recursive_mutex m_targetsMutex;
static void getTimeStamp(std::string & s); static void getTimeStamp(std::string & s);
public: template<typename... Args> static void formatLogMessage(std::string& output, LOG_SEVERITY severity, const std::string & f, Args... args)
static void initialize(const std::string& logfile, LOG_SEVERITY logLevel, bool logToConsole);
template<typename... Args> static void logDebug(const std::string & f, Args... args)
{
log(LS_DEBUG, f, args...);
}
template<typename... Args> static void logInfo(const std::string & f, Args... args)
{
log(LS_INFO, f, args...);
}
template<typename... Args> static void logWarning(const std::string & f, Args... args)
{
log(LS_WARNING, f, args...);
}
template<typename... Args> static void logError(const std::string & f, Args... args)
{
log(LS_ERROR, f, args...);
}
template<typename... Args> static void logFatal(const std::string & f, Args... args)
{
log(LS_FATAL, f, args...);
}
template<typename... Args> static void log(LOG_SEVERITY severity, const std::string & f, Args... args)
{ {
if(severity >= CLog::m_level || CLog::m_file.empty()) {
std::string severityStr; std::string severityStr;
switch (severity) switch (severity)
{ {
@ -110,14 +72,48 @@ public:
std::stringstream s; std::stringstream s;
s << "[" << timeUtc << "] [" << severityStr << "] " << message << std::endl; s << "[" << timeUtc << "] [" << severityStr << "] " << message << std::endl;
if(CLog::m_logToConsole || CLog::m_file.empty()) output = s.str();
std::cout << s.str(); }
public:
static void addTarget(CLogTarget * target);
static void finalise();
template<typename... Args> static void logDebug(const std::string & f, Args... args)
{
log(LS_DEBUG, f, args...);
}
template<typename... Args> static void logInfo(const std::string & f, Args... args)
{
log(LS_INFO, f, args...);
}
template<typename... Args> static void logWarning(const std::string & f, Args... args)
{
log(LS_WARNING, f, args...);
}
template<typename... Args> static void logError(const std::string & f, Args... args)
{
log(LS_ERROR, f, args...);
}
template<typename... Args> static void logFatal(const std::string & f, Args... args)
{
log(LS_FATAL, f, args...);
}
template<typename... Args> static void log(LOG_SEVERITY severity, const std::string & f, Args... args)
{
std::lock_guard lockTarget(m_targetsMutex);
std::ofstream file; std::string msg;
file.open(CLog::m_file, std::ios::app); for(auto target : m_targets) {
if(file.is_open()) { if(target->getLevel() >= CLog::m_level) {
file << s.str(); if(msg.empty()) formatLogMessage(msg, severity, f, args...);
file.close(); target->printLog(msg);
} }
} }
} }

@ -0,0 +1,33 @@
/*
* Copyright (c) 2021-2022 by Geoffrey Merck F4FXL / KC3FRA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <iostream>
#include "LogConsoleTarget.h"
CLogConsoleTarget::CLogConsoleTarget(LOG_SEVERITY logLevel) :
CLogTarget(logLevel)
{
}
void CLogConsoleTarget::printLogInt(const std::string& msg)
{
std::cout << msg;
}

@ -0,0 +1,30 @@
/*
* Copyright (c) 2021-2022 by Geoffrey Merck F4FXL / KC3FRA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#pragma once
#include "LogTarget.h"
class CLogConsoleTarget : public CLogTarget
{
public:
CLogConsoleTarget(LOG_SEVERITY logLevel);
protected:
virtual void printLogInt(const std::string& msg);
};

@ -0,0 +1,57 @@
/*
* Copyright (c) 2021-2022 by Geoffrey Merck F4FXL / KC3FRA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <iostream>
#include <fstream>
#include <chrono>
#include <ctime>
#include "LogFileTarget.h"
CLogFileTarget::CLogFileTarget(LOG_SEVERITY logLevel, const std::string & dir, bool rotate) :
CLogTarget(logLevel),
m_dir(dir),
m_rotate(rotate)
{
}
void CLogFileTarget::printLogInt(const std::string& msg)
{
// construct filename
std::string fileName(m_dir);
if(fileName[fileName.length() - 1U] != '/') fileName.push_back('/');
fileName.append("dstargateway");
if(m_rotate) {
std::time_t now = std::time(0);
std::tm* now_tm = std::gmtime(&now);
char buf[64];
std::strftime(buf, 42, "-%Y-%m-%d", now_tm);
fileName.append(std::string(buf));
}
fileName.append(".log");
std::ofstream file;
file.open(fileName, std::ios::app);
if(file.is_open()) {
file << msg;
file.close();
}
}

@ -0,0 +1,36 @@
/*
* Copyright (c) 2021-2022 by Geoffrey Merck F4FXL / KC3FRA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#pragma once
#include <string>
#include "LogTarget.h"
class CLogFileTarget : public CLogTarget
{
public:
CLogFileTarget(LOG_SEVERITY logLevel, const std::string& directory, bool rotate);
protected:
virtual void printLogInt(const std::string& msg);
private:
std::string m_dir;
bool m_rotate;
};

@ -0,0 +1,35 @@
/*
* Copyright (c) 2021-2022 by Geoffrey Merck F4FXL / KC3FRA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "LogTarget.h"
CLogTarget::CLogTarget(LOG_SEVERITY logLevel) :
m_logLevel(logLevel)
{
}
CLogTarget::~CLogTarget()
{
}
void CLogTarget::printLog(const std::string& msg)
{
printLogInt(msg);
}

@ -0,0 +1,45 @@
/*
* Copyright (c) 2021-2022 by Geoffrey Merck F4FXL / KC3FRA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#pragma once
#include <string>
enum LOG_SEVERITY {
LS_TRACE = 1,
LS_DEBUG,
LS_INFO,
LS_WARNING,
LS_ERROR,
LS_FATAL
};
class CLogTarget
{
public:
CLogTarget(LOG_SEVERITY logLevel);
virtual ~CLogTarget();
void printLog(const std::string& msg);
LOG_SEVERITY getLevel() { return m_logLevel; }
protected:
virtual void printLogInt(const std::string& msg) = 0;
private:
LOG_SEVERITY m_logLevel;
};
Loading…
Cancel
Save

Powered by TurnKey Linux.