mirror of
https://github.com/badaix/snapcast.git
synced 2025-08-04 00:59:32 +02:00
update logger
This commit is contained in:
parent
2955b20e9d
commit
ce55f15c02
36 changed files with 967 additions and 389 deletions
132
common/log.cpp
132
common/log.cpp
|
@ -1,132 +0,0 @@
|
|||
/***
|
||||
This file is part of snapcast
|
||||
Copyright (C) 2014-2017 Johannes Pohl
|
||||
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "log.h"
|
||||
#include <iomanip>
|
||||
#include <ctime>
|
||||
#include <sstream>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
Log::Log(std::string ident, int facility)
|
||||
{
|
||||
facility_ = facility;
|
||||
priority_ = kLogDebug;
|
||||
strncpy(ident_, ident.c_str(), sizeof(ident_));
|
||||
ident_[sizeof(ident_)-1] = '\0';
|
||||
|
||||
openlog(ident_, LOG_PID, facility_);
|
||||
}
|
||||
|
||||
|
||||
std::string Log::Timestamp() const
|
||||
{
|
||||
struct tm * dt;
|
||||
char buffer [30];
|
||||
std::time_t t = std::time(nullptr);
|
||||
dt = localtime(&t);
|
||||
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H-%M-%S", dt);
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
|
||||
std::string Log::toString(LogPriority logPriority) const
|
||||
{
|
||||
switch (logPriority)
|
||||
{
|
||||
case kDbg:
|
||||
return "dbg";
|
||||
case kOut:
|
||||
return "out";
|
||||
case kState:
|
||||
return "state";
|
||||
case kErr:
|
||||
return "err";
|
||||
|
||||
case kLogEmerg:
|
||||
return "Emerg";
|
||||
case kLogAlert:
|
||||
return "Alert";
|
||||
case kLogCrit:
|
||||
return "Crit";
|
||||
case kLogErr:
|
||||
return "Err";
|
||||
case kLogWarning:
|
||||
return "Warning";
|
||||
case kLogNotice:
|
||||
return "Notice";
|
||||
case kLogInfo:
|
||||
return "Info";
|
||||
case kLogDebug:
|
||||
return "Debug";
|
||||
default:
|
||||
std::stringstream ss;
|
||||
ss << logPriority;
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Log::sync()
|
||||
{
|
||||
if (buffer_.str().length())
|
||||
{
|
||||
if (priority_ == kDbg)
|
||||
#ifdef DEBUG_LOG
|
||||
std::cout << Timestamp() << " [dbg] " << buffer_.str() << std::flush;
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
else if ((priority_ == kOut) || (priority_ == kState) || (priority_ == kErr))
|
||||
std::cout << Timestamp() << " [" << toString(priority_) << "] " << buffer_.str() << std::flush;
|
||||
else
|
||||
{
|
||||
std::cout << Timestamp() << " [" << toString(priority_) << "] " << buffer_.str() << std::flush;
|
||||
syslog(priority_, "%s", buffer_.str().c_str());
|
||||
}
|
||||
buffer_.str("");
|
||||
buffer_.clear();
|
||||
priority_ = kLogDebug; // default to debug for each message
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Log::overflow(int c)
|
||||
{
|
||||
if (c != EOF)
|
||||
{
|
||||
buffer_ << static_cast<char>(c);
|
||||
if (c == '\n')
|
||||
sync();
|
||||
}
|
||||
else
|
||||
{
|
||||
sync();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, const LogPriority& log_priority)
|
||||
{
|
||||
static_cast<Log*>(os.rdbuf())->priority_ = log_priority;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
759
common/log.h
759
common/log.h
|
@ -1,6 +1,13 @@
|
|||
/***
|
||||
This file is part of snapcast
|
||||
Copyright (C) 2014-2017 Johannes Pohl
|
||||
__ __ _ _ __ __ ___
|
||||
/ _\ ( )( \/ )( ) / \ / __)
|
||||
/ \ )( ) ( / (_/\( O )( (_ \
|
||||
\_/\_/(__)(_/\_)\____/ \__/ \___/
|
||||
version 0.6.0
|
||||
https://github.com/badaix/aixlog
|
||||
|
||||
This file is part of aixlog
|
||||
Copyright (C) 2017 Johannes Pohl
|
||||
|
||||
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
|
||||
|
@ -16,57 +23,749 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
/// inspired by "eater":
|
||||
/// https://stackoverflow.com/questions/2638654/redirect-c-stdclog-to-syslog-on-unix
|
||||
|
||||
#ifndef LOG_H
|
||||
#define LOG_H
|
||||
/// TODO: add global log level
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
#ifndef AIX_LOG_HPP
|
||||
#define AIX_LOG_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#include <os/log.h>
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
#define logD std::clog << kDbg
|
||||
#define logO std::clog << kOut
|
||||
#define logE std::clog << kErr
|
||||
#define logState std::clog << kState
|
||||
#define logS(P) std::clog << P
|
||||
//#define log logO
|
||||
|
||||
enum LogPriority
|
||||
/// Internal helper defines
|
||||
#define LOG_WO_TAG(P) std::clog << (LogPriority)P << Tag(__func__) << LogType::normal
|
||||
#define SLOG_WO_TAG(P) std::clog << (LogPriority)P << Tag(__func__) << LogType::special
|
||||
|
||||
#define LOG_TAG(P, T) std::clog << (LogPriority)P << Tag(T) << LogType::normal
|
||||
#define SLOG_TAG(P, T) std::clog << (LogPriority)P << Tag(T) << LogType::special
|
||||
|
||||
#define LOG_X(x,P,T,FUNC, ...) FUNC
|
||||
#define SLOG_X(x,P,T,FUNC, ...) FUNC
|
||||
|
||||
|
||||
/// External logger defines
|
||||
#define LOG(...) LOG_X(,##__VA_ARGS__, LOG_TAG(__VA_ARGS__), LOG_WO_TAG(__VA_ARGS__))
|
||||
#define SLOG(...) SLOG_X(,##__VA_ARGS__, SLOG_TAG(__VA_ARGS__), SLOG_WO_TAG(__VA_ARGS__))
|
||||
|
||||
#define FUNC __func__
|
||||
#define TAG Tag
|
||||
#define COND Conditional
|
||||
|
||||
|
||||
enum class LogType
|
||||
{
|
||||
kLogEmerg = LOG_EMERG, // system is unusable
|
||||
kLogAlert = LOG_ALERT, // action must be taken immediately
|
||||
kLogCrit = LOG_CRIT, // critical conditions
|
||||
kLogErr = LOG_ERR, // error conditions
|
||||
kLogWarning = LOG_WARNING, // warning conditions
|
||||
kLogNotice = LOG_NOTICE, // normal, but significant, condition
|
||||
kLogInfo = LOG_INFO, // informational message
|
||||
kLogDebug = LOG_DEBUG, // debug-level message
|
||||
kDbg, kOut, kState, kErr
|
||||
normal,
|
||||
special
|
||||
};
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, const LogPriority& log_priority);
|
||||
|
||||
enum Priority
|
||||
{
|
||||
EMERG = 0, // 0 system is unusable
|
||||
ALERT = 1, // 1 action must be taken immediately
|
||||
CRIT = 2, // 2 critical conditions
|
||||
ERROR = 3, // 3 error conditions
|
||||
WARNING = 4, // 4 warning conditions
|
||||
NOTICE = 5, // 5 normal, but significant, condition
|
||||
INFO = 6, // 6 informational message
|
||||
DEBUG = 7 // 7 debug-level message
|
||||
};
|
||||
|
||||
|
||||
enum class LogPriority : std::int8_t
|
||||
{
|
||||
emerg = EMERG,
|
||||
alert = ALERT,
|
||||
critical= CRIT,
|
||||
error = ERROR,
|
||||
warning = WARNING,
|
||||
notice = NOTICE,
|
||||
info = INFO,
|
||||
debug = DEBUG
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum class Color
|
||||
{
|
||||
none = 0,
|
||||
black = 1,
|
||||
red = 2,
|
||||
green = 3,
|
||||
yellow = 4,
|
||||
blue = 5,
|
||||
magenta = 6,
|
||||
cyan = 7,
|
||||
white = 8
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct LogColor
|
||||
{
|
||||
LogColor(Color foreground = Color::none, Color background = Color::none) :
|
||||
foreground(foreground),
|
||||
background(background)
|
||||
{
|
||||
}
|
||||
|
||||
Color foreground;
|
||||
Color background;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct Conditional
|
||||
{
|
||||
Conditional() : Conditional(true)
|
||||
{
|
||||
}
|
||||
|
||||
Conditional(bool value) : is_true_(value)
|
||||
{
|
||||
}
|
||||
|
||||
void set(bool value)
|
||||
{
|
||||
is_true_ = value;
|
||||
}
|
||||
|
||||
bool is_true() const
|
||||
{
|
||||
return is_true_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool is_true_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct Tag
|
||||
{
|
||||
Tag(std::nullptr_t) : tag(""), is_null(true)
|
||||
{
|
||||
}
|
||||
|
||||
Tag() : Tag(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Tag(const std::string& tag) : tag(tag), is_null(false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual explicit operator bool() const
|
||||
{
|
||||
return !is_null;
|
||||
}
|
||||
|
||||
std::string tag;
|
||||
|
||||
private:
|
||||
bool is_null;
|
||||
};
|
||||
|
||||
|
||||
typedef std::chrono::time_point<std::chrono::system_clock> time_point_sys_clock;
|
||||
|
||||
struct LogSink
|
||||
{
|
||||
enum class Type
|
||||
{
|
||||
normal,
|
||||
special,
|
||||
all
|
||||
};
|
||||
|
||||
LogSink(LogPriority priority, Type type) : priority(priority), sink_type_(type)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~LogSink()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void log(const time_point_sys_clock& timestamp, LogPriority priority, LogType type, const Tag& tag, const std::string& message) const = 0;
|
||||
virtual Type get_type() const
|
||||
{
|
||||
return sink_type_;
|
||||
}
|
||||
|
||||
virtual LogSink& set_type(Type sink_type)
|
||||
{
|
||||
sink_type_ = sink_type;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogPriority priority;
|
||||
|
||||
protected:
|
||||
Type sink_type_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static std::ostream& operator<< (std::ostream& os, const LogPriority& log_priority);
|
||||
static std::ostream& operator<< (std::ostream& os, const LogType& log_type);
|
||||
static std::ostream& operator<< (std::ostream& os, const Tag& tag);
|
||||
static std::ostream& operator<< (std::ostream& os, const Conditional& conditional);
|
||||
|
||||
typedef std::shared_ptr<LogSink> log_sink_ptr;
|
||||
|
||||
|
||||
class Log : public std::basic_streambuf<char, std::char_traits<char> >
|
||||
{
|
||||
public:
|
||||
explicit Log(std::string ident, int facility);
|
||||
static Log& instance()
|
||||
{
|
||||
static Log instance_;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
/// Without "init" every LOG(X) will simply go to clog
|
||||
static void init(const std::vector<log_sink_ptr> log_sinks = {})
|
||||
{
|
||||
for (auto sink: log_sinks)
|
||||
Log::instance().add_logsink(sink);
|
||||
|
||||
std::clog.rdbuf(&Log::instance());
|
||||
}
|
||||
|
||||
void add_logsink(log_sink_ptr sink)
|
||||
{
|
||||
logSinks.push_back(sink);
|
||||
}
|
||||
|
||||
void remove_logsink(log_sink_ptr sink)
|
||||
{
|
||||
logSinks.erase(std::remove(logSinks.begin(), logSinks.end(), sink), logSinks.end());
|
||||
}
|
||||
|
||||
static std::string toString(LogPriority logPriority)
|
||||
{
|
||||
switch (logPriority)
|
||||
{
|
||||
case LogPriority::emerg:
|
||||
return "Emerg";
|
||||
case LogPriority::alert:
|
||||
return "Alert";
|
||||
case LogPriority::critical:
|
||||
return "Crit";
|
||||
case LogPriority::error:
|
||||
return "Err";
|
||||
case LogPriority::warning:
|
||||
return "Warn";
|
||||
case LogPriority::notice:
|
||||
return "Notice";
|
||||
case LogPriority::info:
|
||||
return "Info";
|
||||
case LogPriority::debug:
|
||||
return "Debug";
|
||||
default:
|
||||
std::stringstream ss;
|
||||
ss << logPriority;
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
int sync();
|
||||
int overflow(int c);
|
||||
Log() : type_(LogType::normal)
|
||||
{
|
||||
}
|
||||
|
||||
int sync()
|
||||
{
|
||||
if (!buffer_.str().empty())
|
||||
{
|
||||
auto now = std::chrono::system_clock::now();
|
||||
if (conditional_.is_true())
|
||||
{
|
||||
for (const auto sink: logSinks)
|
||||
{
|
||||
if (
|
||||
(sink->get_type() == LogSink::Type::all) ||
|
||||
((type_ == LogType::special) && (sink->get_type() == LogSink::Type::special)) ||
|
||||
((type_ == LogType::normal) && (sink->get_type() == LogSink::Type::normal))
|
||||
)
|
||||
if (priority_ <= sink->priority)
|
||||
sink->log(now, priority_, type_, tag_, buffer_.str());
|
||||
}
|
||||
}
|
||||
buffer_.str("");
|
||||
buffer_.clear();
|
||||
//priority_ = debug; // default to debug for each message
|
||||
//type_ = kNormal;
|
||||
tag_ = nullptr;
|
||||
conditional_.set(true);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overflow(int c)
|
||||
{
|
||||
/* if (
|
||||
(priority_ > loglevel_) &&
|
||||
((type_ == kNormal) || !syslog_enabled_) // || (syslogpriority_ > loglevel_))
|
||||
)
|
||||
return c;
|
||||
*/ if (c != EOF)
|
||||
{
|
||||
if (c == '\n')
|
||||
sync();
|
||||
else
|
||||
buffer_ << static_cast<char>(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "EOF\n";
|
||||
sync();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
friend std::ostream& operator<< (std::ostream& os, const LogPriority& log_priority);
|
||||
std::string toString(LogPriority logPriority) const;
|
||||
std::string Timestamp() const;
|
||||
friend std::ostream& operator<< (std::ostream& os, const LogType& log_type);
|
||||
friend std::ostream& operator<< (std::ostream& os, const Tag& tag);
|
||||
friend std::ostream& operator<< (std::ostream& os, const Conditional& conditional);
|
||||
|
||||
std::stringstream buffer_;
|
||||
int facility_;
|
||||
LogPriority priority_;
|
||||
char ident_[50];
|
||||
LogType type_;
|
||||
Tag tag_;
|
||||
Conditional conditional_;
|
||||
std::vector<log_sink_ptr> logSinks;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct LogSinkFormat : public LogSink
|
||||
{
|
||||
LogSinkFormat(LogPriority priority, Type type, const std::string& format = "%Y-%m-%d %H-%M-%S [#prio] (#tag)") : // #logline") :
|
||||
LogSink(priority, type),
|
||||
format_(format)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void set_format(const std::string& format)
|
||||
{
|
||||
format_ = format;
|
||||
}
|
||||
|
||||
virtual void log(const time_point_sys_clock& timestamp, LogPriority priority, LogType type, const Tag& tag, const std::string& message) const = 0;
|
||||
|
||||
|
||||
protected:
|
||||
/// strftime format + proprietary "#ms" for milliseconds
|
||||
virtual void do_log(std::ostream& stream, const time_point_sys_clock& timestamp, LogPriority priority, LogType type, const Tag& tag, const std::string& message) const
|
||||
{
|
||||
std::time_t now_c = std::chrono::system_clock::to_time_t(timestamp);
|
||||
struct::tm now_tm = *std::localtime(&now_c);
|
||||
|
||||
char buffer[256];
|
||||
strftime(buffer, sizeof buffer, format_.c_str(), &now_tm);
|
||||
std::string result = buffer;
|
||||
size_t pos = result.find("#ms");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
int ms_part = std::chrono::time_point_cast<std::chrono::milliseconds>(timestamp).time_since_epoch().count() % 1000;
|
||||
char ms_str[4];
|
||||
sprintf(ms_str, "%03d", ms_part);
|
||||
result.replace(pos, 3, ms_str);
|
||||
}
|
||||
|
||||
pos = result.find("#prio");
|
||||
if (pos != std::string::npos)
|
||||
result.replace(pos, 5, Log::toString(priority));
|
||||
|
||||
|
||||
pos = result.find("#tag");
|
||||
if (pos != std::string::npos)
|
||||
result.replace(pos, 4, tag?tag.tag:"log");
|
||||
|
||||
pos = result.find("#logline");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
result.replace(pos, 8, message);
|
||||
stream << result << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (result.empty() || (result.back() == ' '))
|
||||
stream << message << std::endl;
|
||||
else
|
||||
stream << result << " " << message << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::string format_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct LogSinkCout : public LogSinkFormat
|
||||
{
|
||||
LogSinkCout(LogPriority priority, Type type, const std::string& format = "%Y-%m-%d %H-%M-%S.#ms [#prio] (#tag)") : // #logline") :
|
||||
LogSinkFormat(priority, type, format)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void log(const time_point_sys_clock& timestamp, LogPriority priority, LogType type, const Tag& tag, const std::string& message) const
|
||||
{
|
||||
if (priority <= this->priority)
|
||||
do_log(std::cout, timestamp, priority, type, tag, message);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct LogSinkCerr : public LogSinkFormat
|
||||
{
|
||||
LogSinkCerr(LogPriority priority, Type type, const std::string& format = "%Y-%m-%d %H-%M-%S.#ms [#prio] (#tag)") : // #logline") :
|
||||
LogSinkFormat(priority, type, format)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void log(const time_point_sys_clock& timestamp, LogPriority priority, LogType type, const Tag& tag, const std::string& message) const
|
||||
{
|
||||
if (priority <= this->priority)
|
||||
do_log(std::cerr, timestamp, priority, type, tag, message);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Not tested due to unavailability of Windows
|
||||
struct LogSinkOutputDebugString : LogSink
|
||||
{
|
||||
LogSinkOutputDebugString(LogPriority priority, Type type = Type::all, const std::string& default_tag = "") : LogSink(priority, type)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void log(const time_point_sys_clock& timestamp, LogPriority priority, LogType type, const Tag& tag, const std::string& message) const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
OutputDebugString(message.c_str());
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct LogSinkUnifiedLogging : LogSink
|
||||
{
|
||||
LogSinkUnifiedLogging(LogPriority priority, Type type = Type::all) : LogSink(priority, type)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
os_log_type_t get_os_log_type(LogPriority priority) const
|
||||
{
|
||||
switch (priority)
|
||||
{
|
||||
case LogPriority::emerg:
|
||||
case LogPriority::alert:
|
||||
case LogPriority::critical:
|
||||
return OS_LOG_TYPE_FAULT;
|
||||
case LogPriority::error:
|
||||
return OS_LOG_TYPE_ERROR;
|
||||
case LogPriority::warning:
|
||||
case LogPriority::notice:
|
||||
return OS_LOG_TYPE_DEFAULT;
|
||||
case LogPriority::info:
|
||||
return OS_LOG_TYPE_INFO;
|
||||
case LogPriority::debug:
|
||||
return OS_LOG_TYPE_DEBUG;
|
||||
default:
|
||||
return OS_LOG_TYPE_DEFAULT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void log(const time_point_sys_clock& timestamp, LogPriority priority, LogType type, const Tag& tag, const std::string& message) const
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
os_log_with_type(OS_LOG_DEFAULT, get_os_log_type(priority), "%{public}s", message.c_str());
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct LogSinkSyslog : public LogSink
|
||||
{
|
||||
LogSinkSyslog(const char* ident, LogPriority priority, Type type) : LogSink(priority, type)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
openlog(ident, LOG_PID, LOG_USER);
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual ~LogSinkSyslog()
|
||||
{
|
||||
closelog();
|
||||
}
|
||||
|
||||
virtual void log(const time_point_sys_clock& timestamp, LogPriority priority, LogType type, const Tag& tag, const std::string& message) const
|
||||
{
|
||||
#ifndef _WIN32
|
||||
syslog((int)priority, "%s", message.c_str());
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct LogSinkAndroid : public LogSink
|
||||
{
|
||||
LogSinkAndroid(const std::string& ident, LogPriority priority, Type type = Type::all) : LogSink(priority, type), ident_(ident)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
android_LogPriority get_android_prio(LogPriority priority) const
|
||||
{
|
||||
switch (priority)
|
||||
{
|
||||
case LogPriority::emerg:
|
||||
case LogPriority::alert:
|
||||
case LogPriority::critical:
|
||||
return ANDROID_LOG_FATAL;
|
||||
case LogPriority::error:
|
||||
return ANDROID_LOG_ERROR;
|
||||
case LogPriority::warning:
|
||||
return ANDROID_LOG_WARN;
|
||||
case LogPriority::notice:
|
||||
return ANDROID_LOG_DEFAULT;
|
||||
case LogPriority::info:
|
||||
return ANDROID_LOG_INFO;
|
||||
case LogPriority::debug:
|
||||
return ANDROID_LOG_DEBUG;
|
||||
default:
|
||||
return ANDROID_LOG_UNKNOWN;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void log(const time_point_sys_clock& timestamp, LogPriority priority, LogType type, const Tag& tag, const std::string& message) const
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
std::string log_tag;// = default_tag_;
|
||||
if (tag)
|
||||
{
|
||||
if (!ident_.empty())
|
||||
log_tag = ident_ + "." + tag.tag;
|
||||
else
|
||||
log_tag = tag.tag;
|
||||
}
|
||||
else
|
||||
log_tag = ident_;
|
||||
|
||||
__android_log_write(get_android_prio(priority), log_tag.c_str(), message.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string ident_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Not tested due to unavailability of Windows
|
||||
struct LogSinkEventLog : public LogSink
|
||||
{
|
||||
LogSinkEventLog(const std::string& ident, LogPriority priority, Type type = Type::all) : LogSink(priority, type)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
event_log = RegisterEventSource(NULL, ident.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
WORD get_type(LogPriority priority) const
|
||||
{
|
||||
switch (priority)
|
||||
{
|
||||
case LogPriority::emerg:
|
||||
case LogPriority::alert:
|
||||
case LogPriority::critical:
|
||||
case LogPriority::error:
|
||||
return EVENTLOG_ERROR_TYPE;
|
||||
case LogPriority::warning:
|
||||
return EVENTLOG_WARNING_TYPE;
|
||||
case LogPriority::notice:
|
||||
return EVENTLOG_SUCCESS;
|
||||
case LogPriority::info:
|
||||
case LogPriority::debug:
|
||||
return EVENTLOG_INFORMATION_TYPE;
|
||||
default:
|
||||
return EVENTLOG_INFORMATION_TYPE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void log(const time_point_sys_clock& timestamp, LogPriority priority, LogType type, const Tag& tag, const std::string& message) const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
ReportEvent(event_log, get_type(priority), 0, 0, NULL, 1, 0, &message.c_str(), NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
#ifdef _WIN32
|
||||
HANDLE event_log;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct LogSinkNative : public LogSink
|
||||
{
|
||||
LogSinkNative(const std::string& ident, LogPriority priority, Type type = Type::all) :
|
||||
LogSink(priority, type),
|
||||
log_sink_(nullptr),
|
||||
ident_(ident)
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
log_sink_ = std::make_shared<LogSinkAndroid>(ident_, priority, type);
|
||||
#elif __APPLE__
|
||||
log_sink_ = std::make_shared<LogSinkUnifiedLogging>(priority, type);
|
||||
#elif _WIN32
|
||||
log_sink_ = std::make_shared<LogSinkEventLog>(priority, type);
|
||||
#else
|
||||
log_sink_ = std::make_shared<LogSinkSyslog>(ident_.c_str(), priority, type);
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void log(const time_point_sys_clock& timestamp, LogPriority priority, LogType type, const Tag& tag, const std::string& message) const
|
||||
{
|
||||
if (log_sink_)
|
||||
log_sink_->log(timestamp, priority, type, tag, message);
|
||||
}
|
||||
|
||||
protected:
|
||||
log_sink_ptr log_sink_;
|
||||
std::string ident_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct LogSinkCallback : public LogSink
|
||||
{
|
||||
typedef std::function<void(const time_point_sys_clock& timestamp, LogPriority priority, LogType type, const Tag& tag, const std::string& message)> callback_fun;
|
||||
|
||||
LogSinkCallback(LogPriority priority, Type type, callback_fun callback) : LogSink(priority, type), callback(callback)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void log(const time_point_sys_clock& timestamp, LogPriority priority, LogType type, const Tag& tag, const std::string& message) const
|
||||
{
|
||||
if (callback && (priority <= this->priority))
|
||||
callback(timestamp, priority, type, tag, message);
|
||||
}
|
||||
|
||||
private:
|
||||
callback_fun callback;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static std::ostream& operator<< (std::ostream& os, const LogPriority& log_priority)
|
||||
{
|
||||
Log* log = dynamic_cast<Log*>(os.rdbuf());
|
||||
if (log && (log->priority_ != log_priority))
|
||||
{
|
||||
log->sync();
|
||||
log->priority_ = log_priority;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static std::ostream& operator<< (std::ostream& os, const LogType& log_type)
|
||||
{
|
||||
Log* log = dynamic_cast<Log*>(os.rdbuf());
|
||||
if (log)
|
||||
log->type_ = log_type;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static std::ostream& operator<< (std::ostream& os, const Tag& tag)
|
||||
{
|
||||
Log* log = dynamic_cast<Log*>(os.rdbuf());
|
||||
if (log)
|
||||
log->tag_ = tag;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static std::ostream& operator<< (std::ostream& os, const Conditional& conditional)
|
||||
{
|
||||
Log* log = dynamic_cast<Log*>(os.rdbuf());
|
||||
if (log)
|
||||
log->conditional_.set(conditional.is_true());
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static std::ostream& operator<< (std::ostream& os, const LogColor& log_color)
|
||||
{
|
||||
os << "\033[";
|
||||
if ((log_color.foreground == Color::none) && (log_color.background == Color::none))
|
||||
os << "0"; // reset colors if no params
|
||||
|
||||
if (log_color.foreground != Color::none)
|
||||
{
|
||||
os << 29 + (int)log_color.foreground;
|
||||
if (log_color.background != Color::none)
|
||||
os << ";";
|
||||
}
|
||||
if (log_color.background != Color::none)
|
||||
os << 39 + (int)log_color.background;
|
||||
os << "m";
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static std::ostream& operator<< (std::ostream& os, const Color& color)
|
||||
{
|
||||
os << LogColor(color);
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /// AIX_LOG_HPP
|
||||
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ void SampleFormat::setFormat(uint32_t rate, uint16_t bits, uint16_t channels)
|
|||
if (bits == 24)
|
||||
sampleSize = 4;
|
||||
frameSize = channels*sampleSize;
|
||||
// logD << "SampleFormat: " << rate << ":" << bits << ":" << channels << "\n";
|
||||
// LOG(DEBUG) << "SampleFormat: " << rate << ":" << bits << ":" << channels << "\n";
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue