changed things to include plog
This commit is contained in:
parent
b018a44f10
commit
68a1618743
34 changed files with 2702 additions and 27 deletions
47
include/plog/Appenders/AndroidAppender.h
Normal file
47
include/plog/Appenders/AndroidAppender.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
#pragma once
|
||||
#include <plog/Appenders/IAppender.h>
|
||||
#include <android/log.h>
|
||||
|
||||
namespace plog
|
||||
{
|
||||
template<class Formatter>
|
||||
class PLOG_LINKAGE_HIDDEN AndroidAppender : public IAppender
|
||||
{
|
||||
public:
|
||||
AndroidAppender(const char* tag) : m_tag(tag)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void write(const Record& record) PLOG_OVERRIDE
|
||||
{
|
||||
std::string str = Formatter::format(record);
|
||||
|
||||
__android_log_print(toPriority(record.getSeverity()), m_tag, "%s", str.c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
static android_LogPriority toPriority(Severity severity)
|
||||
{
|
||||
switch (severity)
|
||||
{
|
||||
case fatal:
|
||||
return ANDROID_LOG_FATAL;
|
||||
case error:
|
||||
return ANDROID_LOG_ERROR;
|
||||
case warning:
|
||||
return ANDROID_LOG_WARN;
|
||||
case info:
|
||||
return ANDROID_LOG_INFO;
|
||||
case debug:
|
||||
return ANDROID_LOG_DEBUG;
|
||||
case verbose:
|
||||
return ANDROID_LOG_VERBOSE;
|
||||
default:
|
||||
return ANDROID_LOG_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const char* const m_tag;
|
||||
};
|
||||
}
|
23
include/plog/Appenders/ArduinoAppender.h
Normal file
23
include/plog/Appenders/ArduinoAppender.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
#include <plog/Appenders/IAppender.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
namespace plog
|
||||
{
|
||||
template<class Formatter>
|
||||
class PLOG_LINKAGE_HIDDEN ArduinoAppender : public IAppender
|
||||
{
|
||||
public:
|
||||
ArduinoAppender(Stream &stream) : m_stream(stream)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void write(const Record &record) PLOG_OVERRIDE
|
||||
{
|
||||
m_stream.print(Formatter::format(record).c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
Stream &m_stream;
|
||||
};
|
||||
}
|
108
include/plog/Appenders/ColorConsoleAppender.h
Normal file
108
include/plog/Appenders/ColorConsoleAppender.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
#pragma once
|
||||
#include <plog/Appenders/ConsoleAppender.h>
|
||||
#include <plog/WinApi.h>
|
||||
|
||||
namespace plog
|
||||
{
|
||||
template<class Formatter>
|
||||
class PLOG_LINKAGE_HIDDEN ColorConsoleAppender : public ConsoleAppender<Formatter>
|
||||
{
|
||||
public:
|
||||
#ifdef _WIN32
|
||||
# ifdef _MSC_VER
|
||||
# pragma warning(suppress: 26812) // Prefer 'enum class' over 'enum'
|
||||
# endif
|
||||
ColorConsoleAppender(OutputStream outStream = streamStdOut)
|
||||
: ConsoleAppender<Formatter>(outStream)
|
||||
, m_originalAttr()
|
||||
{
|
||||
if (this->m_isatty)
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
|
||||
GetConsoleScreenBufferInfo(this->m_outputHandle, &csbiInfo);
|
||||
|
||||
m_originalAttr = csbiInfo.wAttributes;
|
||||
}
|
||||
}
|
||||
#else
|
||||
ColorConsoleAppender(OutputStream outStream = streamStdOut)
|
||||
: ConsoleAppender<Formatter>(outStream)
|
||||
{}
|
||||
#endif
|
||||
|
||||
virtual void write(const Record& record) PLOG_OVERRIDE
|
||||
{
|
||||
util::nstring str = Formatter::format(record);
|
||||
util::MutexLock lock(this->m_mutex);
|
||||
|
||||
setColor(record.getSeverity());
|
||||
this->writestr(str);
|
||||
resetColor();
|
||||
}
|
||||
|
||||
protected:
|
||||
void setColor(Severity severity)
|
||||
{
|
||||
if (this->m_isatty)
|
||||
{
|
||||
switch (severity)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
case fatal:
|
||||
SetConsoleTextAttribute(this->m_outputHandle, foreground::kRed | foreground::kGreen | foreground::kBlue | foreground::kIntensity | background::kRed); // white on red background
|
||||
break;
|
||||
|
||||
case error:
|
||||
SetConsoleTextAttribute(this->m_outputHandle, static_cast<WORD>(foreground::kRed | foreground::kIntensity | (m_originalAttr & 0xf0))); // red
|
||||
break;
|
||||
|
||||
case warning:
|
||||
SetConsoleTextAttribute(this->m_outputHandle, static_cast<WORD>(foreground::kRed | foreground::kGreen | foreground::kIntensity | (m_originalAttr & 0xf0))); // yellow
|
||||
break;
|
||||
|
||||
case debug:
|
||||
case verbose:
|
||||
SetConsoleTextAttribute(this->m_outputHandle, static_cast<WORD>(foreground::kGreen | foreground::kBlue | foreground::kIntensity | (m_originalAttr & 0xf0))); // cyan
|
||||
break;
|
||||
#else
|
||||
case fatal:
|
||||
this->m_outputStream << "\x1B[97m\x1B[41m"; // white on red background
|
||||
break;
|
||||
|
||||
case error:
|
||||
this->m_outputStream << "\x1B[91m"; // red
|
||||
break;
|
||||
|
||||
case warning:
|
||||
this->m_outputStream << "\x1B[93m"; // yellow
|
||||
break;
|
||||
|
||||
case debug:
|
||||
case verbose:
|
||||
this->m_outputStream << "\x1B[96m"; // cyan
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void resetColor()
|
||||
{
|
||||
if (this->m_isatty)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SetConsoleTextAttribute(this->m_outputHandle, m_originalAttr);
|
||||
#else
|
||||
this->m_outputStream << "\x1B[0m\x1B[0K";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
#ifdef _WIN32
|
||||
WORD m_originalAttr;
|
||||
#endif
|
||||
};
|
||||
}
|
83
include/plog/Appenders/ConsoleAppender.h
Normal file
83
include/plog/Appenders/ConsoleAppender.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
#pragma once
|
||||
#include <plog/Appenders/IAppender.h>
|
||||
#include <plog/Util.h>
|
||||
#include <plog/WinApi.h>
|
||||
#include <iostream>
|
||||
|
||||
namespace plog
|
||||
{
|
||||
enum OutputStream
|
||||
{
|
||||
streamStdOut,
|
||||
streamStdErr
|
||||
};
|
||||
|
||||
template<class Formatter>
|
||||
class PLOG_LINKAGE_HIDDEN ConsoleAppender : public IAppender
|
||||
{
|
||||
public:
|
||||
#ifdef _WIN32
|
||||
# ifdef _MSC_VER
|
||||
# pragma warning(suppress: 26812) // Prefer 'enum class' over 'enum'
|
||||
# endif
|
||||
ConsoleAppender(OutputStream outStream = streamStdOut)
|
||||
: m_isatty(!!_isatty(_fileno(outStream == streamStdOut ? stdout : stderr)))
|
||||
, m_outputStream(outStream == streamStdOut ? std::cout : std::cerr)
|
||||
, m_outputHandle()
|
||||
{
|
||||
if (m_isatty)
|
||||
{
|
||||
m_outputHandle = GetStdHandle(outStream == streamStdOut ? stdHandle::kOutput : stdHandle::kErrorOutput);
|
||||
}
|
||||
}
|
||||
#else
|
||||
ConsoleAppender(OutputStream outStream = streamStdOut)
|
||||
: m_isatty(!!isatty(fileno(outStream == streamStdOut ? stdout : stderr)))
|
||||
, m_outputStream(outStream == streamStdOut ? std::cout : std::cerr)
|
||||
{}
|
||||
#endif
|
||||
|
||||
virtual void write(const Record& record) PLOG_OVERRIDE
|
||||
{
|
||||
util::nstring str = Formatter::format(record);
|
||||
util::MutexLock lock(m_mutex);
|
||||
|
||||
writestr(str);
|
||||
}
|
||||
|
||||
protected:
|
||||
void writestr(const util::nstring& str)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (m_isatty)
|
||||
{
|
||||
const std::wstring& wstr = util::toWide(str);
|
||||
WriteConsoleW(m_outputHandle, wstr.c_str(), static_cast<DWORD>(wstr.size()), NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
# if PLOG_CHAR_IS_UTF8
|
||||
m_outputStream << str << std::flush;
|
||||
# else
|
||||
m_outputStream << util::toNarrow(str, codePage::kActive) << std::flush;
|
||||
# endif
|
||||
}
|
||||
#else
|
||||
m_outputStream << str << std::flush;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
#ifdef __BORLANDC__
|
||||
static int _isatty(int fd) { return ::isatty(fd); }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
util::Mutex m_mutex;
|
||||
const bool m_isatty;
|
||||
std::ostream& m_outputStream;
|
||||
#ifdef _WIN32
|
||||
HANDLE m_outputHandle;
|
||||
#endif
|
||||
};
|
||||
}
|
16
include/plog/Appenders/DebugOutputAppender.h
Normal file
16
include/plog/Appenders/DebugOutputAppender.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
#include <plog/Appenders/IAppender.h>
|
||||
#include <plog/WinApi.h>
|
||||
|
||||
namespace plog
|
||||
{
|
||||
template<class Formatter>
|
||||
class PLOG_LINKAGE_HIDDEN DebugOutputAppender : public IAppender
|
||||
{
|
||||
public:
|
||||
virtual void write(const Record& record) PLOG_OVERRIDE
|
||||
{
|
||||
OutputDebugStringW(util::toWide(Formatter::format(record)).c_str());
|
||||
}
|
||||
};
|
||||
}
|
42
include/plog/Appenders/DynamicAppender.h
Normal file
42
include/plog/Appenders/DynamicAppender.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
#include <plog/Appenders/IAppender.h>
|
||||
#include <set>
|
||||
|
||||
namespace plog
|
||||
{
|
||||
class PLOG_LINKAGE_HIDDEN DynamicAppender : public IAppender
|
||||
{
|
||||
public:
|
||||
DynamicAppender& addAppender(IAppender* appender)
|
||||
{
|
||||
assert(appender != this);
|
||||
|
||||
util::MutexLock lock(m_mutex);
|
||||
m_appenders.insert(appender);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
DynamicAppender& removeAppender(IAppender* appender)
|
||||
{
|
||||
util::MutexLock lock(m_mutex);
|
||||
m_appenders.erase(appender);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual void write(const Record& record) PLOG_OVERRIDE
|
||||
{
|
||||
util::MutexLock lock(m_mutex);
|
||||
|
||||
for (std::set<IAppender*>::iterator it = m_appenders.begin(); it != m_appenders.end(); ++it)
|
||||
{
|
||||
(*it)->write(record);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
mutable util::Mutex m_mutex;
|
||||
std::set<IAppender*> m_appenders;
|
||||
};
|
||||
}
|
117
include/plog/Appenders/EventLogAppender.h
Normal file
117
include/plog/Appenders/EventLogAppender.h
Normal file
|
@ -0,0 +1,117 @@
|
|||
#pragma once
|
||||
#include <plog/Appenders/IAppender.h>
|
||||
#include <plog/WinApi.h>
|
||||
|
||||
namespace plog
|
||||
{
|
||||
template <class Formatter>
|
||||
class PLOG_LINKAGE_HIDDEN EventLogAppender : public IAppender
|
||||
{
|
||||
public:
|
||||
EventLogAppender(const util::nchar* sourceName) : m_eventSource(RegisterEventSourceW(NULL, util::toWide(sourceName).c_str()))
|
||||
{
|
||||
}
|
||||
|
||||
~EventLogAppender()
|
||||
{
|
||||
DeregisterEventSource(m_eventSource);
|
||||
}
|
||||
|
||||
virtual void write(const Record& record) PLOG_OVERRIDE
|
||||
{
|
||||
util::nstring str = Formatter::format(record);
|
||||
|
||||
write(record.getSeverity(), util::toWide(str).c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
void write(Severity severity, const wchar_t* str)
|
||||
{
|
||||
const wchar_t* logMessagePtr[] = { str };
|
||||
|
||||
ReportEventW(m_eventSource, logSeverityToType(severity), static_cast<WORD>(severity), 0, NULL, 1, 0, logMessagePtr, NULL);
|
||||
}
|
||||
|
||||
static WORD logSeverityToType(plog::Severity severity)
|
||||
{
|
||||
switch (severity)
|
||||
{
|
||||
case plog::fatal:
|
||||
case plog::error:
|
||||
return eventLog::kErrorType;
|
||||
|
||||
case plog::warning:
|
||||
return eventLog::kWarningType;
|
||||
|
||||
case plog::info:
|
||||
case plog::debug:
|
||||
case plog::verbose:
|
||||
default:
|
||||
return eventLog::kInformationType;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE m_eventSource;
|
||||
};
|
||||
|
||||
class EventLogAppenderRegistry
|
||||
{
|
||||
public:
|
||||
static bool add(const util::nchar* sourceName, const util::nchar* logName = PLOG_NSTR("Application"))
|
||||
{
|
||||
std::wstring logKeyName;
|
||||
std::wstring sourceKeyName;
|
||||
getKeyNames(sourceName, logName, sourceKeyName, logKeyName);
|
||||
|
||||
HKEY sourceKey;
|
||||
if (0 != RegCreateKeyExW(hkey::kLocalMachine, sourceKeyName.c_str(), 0, NULL, 0, regSam::kSetValue, NULL, &sourceKey, NULL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const DWORD kTypesSupported = eventLog::kErrorType | eventLog::kWarningType | eventLog::kInformationType;
|
||||
RegSetValueExW(sourceKey, L"TypesSupported", 0, regType::kDword, reinterpret_cast<const BYTE*>(&kTypesSupported), sizeof(kTypesSupported));
|
||||
|
||||
const wchar_t kEventMessageFile[] = L"%windir%\\Microsoft.NET\\Framework\\v4.0.30319\\EventLogMessages.dll;%windir%\\Microsoft.NET\\Framework\\v2.0.50727\\EventLogMessages.dll";
|
||||
RegSetValueExW(sourceKey, L"EventMessageFile", 0, regType::kExpandSz, reinterpret_cast<const BYTE*>(kEventMessageFile), sizeof(kEventMessageFile) - sizeof(*kEventMessageFile));
|
||||
|
||||
RegCloseKey(sourceKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool exists(const util::nchar* sourceName, const util::nchar* logName = PLOG_NSTR("Application"))
|
||||
{
|
||||
std::wstring logKeyName;
|
||||
std::wstring sourceKeyName;
|
||||
getKeyNames(sourceName, logName, sourceKeyName, logKeyName);
|
||||
|
||||
HKEY sourceKey;
|
||||
if (0 != RegOpenKeyExW(hkey::kLocalMachine, sourceKeyName.c_str(), 0, regSam::kQueryValue, &sourceKey))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RegCloseKey(sourceKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void remove(const util::nchar* sourceName, const util::nchar* logName = PLOG_NSTR("Application"))
|
||||
{
|
||||
std::wstring logKeyName;
|
||||
std::wstring sourceKeyName;
|
||||
getKeyNames(sourceName, logName, sourceKeyName, logKeyName);
|
||||
|
||||
RegDeleteKeyW(hkey::kLocalMachine, sourceKeyName.c_str());
|
||||
RegDeleteKeyW(hkey::kLocalMachine, logKeyName.c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
static void getKeyNames(const util::nchar* sourceName, const util::nchar* logName, std::wstring& sourceKeyName, std::wstring& logKeyName)
|
||||
{
|
||||
const std::wstring kPrefix = L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\";
|
||||
logKeyName = kPrefix + util::toWide(logName);
|
||||
sourceKeyName = logKeyName + L"\\" + util::toWide(sourceName);
|
||||
}
|
||||
};
|
||||
}
|
16
include/plog/Appenders/IAppender.h
Normal file
16
include/plog/Appenders/IAppender.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
#include <plog/Record.h>
|
||||
#include <plog/Util.h>
|
||||
|
||||
namespace plog
|
||||
{
|
||||
class PLOG_LINKAGE IAppender
|
||||
{
|
||||
public:
|
||||
virtual ~IAppender()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void write(const Record& record) = 0;
|
||||
};
|
||||
}
|
148
include/plog/Appenders/RollingFileAppender.h
Normal file
148
include/plog/Appenders/RollingFileAppender.h
Normal file
|
@ -0,0 +1,148 @@
|
|||
#pragma once
|
||||
#include <plog/Appenders/IAppender.h>
|
||||
#include <plog/Converters/UTF8Converter.h>
|
||||
#include <plog/Converters/NativeEOLConverter.h>
|
||||
#include <plog/Util.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace plog
|
||||
{
|
||||
template<class Formatter, class Converter = NativeEOLConverter<UTF8Converter> >
|
||||
class PLOG_LINKAGE_HIDDEN RollingFileAppender : public IAppender
|
||||
{
|
||||
public:
|
||||
RollingFileAppender(const util::nchar* fileName, size_t maxFileSize = 0, int maxFiles = 0)
|
||||
: m_fileSize()
|
||||
, m_maxFileSize()
|
||||
, m_maxFiles(maxFiles)
|
||||
, m_firstWrite(true)
|
||||
{
|
||||
setFileName(fileName);
|
||||
setMaxFileSize(maxFileSize);
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !PLOG_CHAR_IS_UTF8
|
||||
RollingFileAppender(const char* fileName, size_t maxFileSize = 0, int maxFiles = 0)
|
||||
: m_fileSize()
|
||||
, m_maxFileSize()
|
||||
, m_maxFiles(maxFiles)
|
||||
, m_firstWrite(true)
|
||||
{
|
||||
setFileName(fileName);
|
||||
setMaxFileSize(maxFileSize);
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void write(const Record& record) PLOG_OVERRIDE
|
||||
{
|
||||
util::MutexLock lock(m_mutex);
|
||||
|
||||
if (m_firstWrite)
|
||||
{
|
||||
openLogFile();
|
||||
m_firstWrite = false;
|
||||
}
|
||||
else if (m_maxFiles > 0 && m_fileSize > m_maxFileSize && static_cast<size_t>(-1) != m_fileSize)
|
||||
{
|
||||
rollLogFiles();
|
||||
}
|
||||
|
||||
size_t bytesWritten = m_file.write(Converter::convert(Formatter::format(record)));
|
||||
|
||||
if (static_cast<size_t>(-1) != bytesWritten)
|
||||
{
|
||||
m_fileSize += bytesWritten;
|
||||
}
|
||||
}
|
||||
|
||||
void setFileName(const util::nchar* fileName)
|
||||
{
|
||||
util::MutexLock lock(m_mutex);
|
||||
|
||||
util::splitFileName(fileName, m_fileNameNoExt, m_fileExt);
|
||||
|
||||
m_file.close();
|
||||
m_firstWrite = true;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !PLOG_CHAR_IS_UTF8
|
||||
void setFileName(const char* fileName)
|
||||
{
|
||||
setFileName(util::toWide(fileName).c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
void setMaxFiles(int maxFiles)
|
||||
{
|
||||
m_maxFiles = maxFiles;
|
||||
}
|
||||
|
||||
void setMaxFileSize(size_t maxFileSize)
|
||||
{
|
||||
m_maxFileSize = (std::max)(maxFileSize, static_cast<size_t>(1000)); // set a lower limit for the maxFileSize
|
||||
}
|
||||
|
||||
void rollLogFiles()
|
||||
{
|
||||
m_file.close();
|
||||
|
||||
util::nstring lastFileName = buildFileName(m_maxFiles - 1);
|
||||
util::File::unlink(lastFileName);
|
||||
|
||||
for (int fileNumber = m_maxFiles - 2; fileNumber >= 0; --fileNumber)
|
||||
{
|
||||
util::nstring currentFileName = buildFileName(fileNumber);
|
||||
util::nstring nextFileName = buildFileName(fileNumber + 1);
|
||||
|
||||
util::File::rename(currentFileName, nextFileName);
|
||||
}
|
||||
|
||||
openLogFile();
|
||||
m_firstWrite = false;
|
||||
}
|
||||
|
||||
private:
|
||||
void openLogFile()
|
||||
{
|
||||
m_fileSize = m_file.open(buildFileName());
|
||||
|
||||
if (0 == m_fileSize)
|
||||
{
|
||||
size_t bytesWritten = m_file.write(Converter::header(Formatter::header()));
|
||||
|
||||
if (static_cast<size_t>(-1) != bytesWritten)
|
||||
{
|
||||
m_fileSize += bytesWritten;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
util::nstring buildFileName(int fileNumber = 0)
|
||||
{
|
||||
util::nostringstream ss;
|
||||
ss << m_fileNameNoExt;
|
||||
|
||||
if (fileNumber > 0)
|
||||
{
|
||||
ss << '.' << fileNumber;
|
||||
}
|
||||
|
||||
if (!m_fileExt.empty())
|
||||
{
|
||||
ss << '.' << m_fileExt;
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
util::Mutex m_mutex;
|
||||
util::File m_file;
|
||||
size_t m_fileSize;
|
||||
size_t m_maxFileSize;
|
||||
int m_maxFiles;
|
||||
util::nstring m_fileExt;
|
||||
util::nstring m_fileNameNoExt;
|
||||
bool m_firstWrite;
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue