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 "XLXHostsFileDownloader.h"
#include "Log.h"
#include "LogFileTarget.h"
#include "LogConsoleTarget.h"
int main(int argc, char *argv[])
{
@ -100,7 +102,8 @@ bool CDStarGatewayApp::createThread()
TLog 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;
config.getPaths(paths);

@ -18,18 +18,40 @@
*/
#include <ctime>
#include <sstream>
#include <cassert>
#include "Log.h"
#include "LogConsoleTarget.h"
LOG_SEVERITY CLog::m_level = LS_INFO;
std::string CLog::m_file = "";
bool CLog::m_logToConsole = true;
LOG_SEVERITY CLog::m_level(LS_DEBUG);
bool CLog::m_addedTargets(false);
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;
m_level = logLevel;
m_logToConsole = logToConsole;
assert(target != nullptr);
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)
@ -39,4 +61,4 @@ void CLog::getTimeStamp(std::string & s)
char buf[64];
std::strftime(buf, 42, "%Y-%m-%d %T", now_tm);
s = std::string(buf);
}
}

102
Log.h

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