diff --git a/client/Makefile b/client/Makefile index bc84bdaa..0516f3d9 100644 --- a/client/Makefile +++ b/client/Makefile @@ -42,7 +42,7 @@ ifeq ($(TARGET), ANDROID) CXX = $(PROGRAM_PREFIX)clang++ STRIP = $(PROGRAM_PREFIX)strip CXXFLAGS += -pthread -DANDROID -DNO_CPP11_STRING -fPIC -DHAS_TREMOR -DHAS_OPENSL -I$(NDK_DIR)/include -LDFLAGS = -L$(NDK_DIR)/lib -pie -lvorbisidec -logg -lFLAC -lOpenSLES -latomic +LDFLAGS = -L$(NDK_DIR)/lib -pie -lvorbisidec -logg -lFLAC -lOpenSLES -latomic -llog OBJ += player/openslPlayer.o else ifeq ($(TARGET), OPENWRT) diff --git a/client/snapClient.cpp b/client/snapClient.cpp index d4e47e2f..602275af 100644 --- a/client/snapClient.cpp +++ b/client/snapClient.cpp @@ -117,7 +117,7 @@ int main (int argc, char **argv) } catch (const std::invalid_argument& e) { - SLOG(LOG_ERR) << "Exception: " << e.what() << std::endl; + cerr << "Exception: " << e.what() << std::endl; cout << "\n" << op << "\n"; exit(EXIT_FAILURE); } @@ -155,10 +155,10 @@ int main (int argc, char **argv) if (instance <= 0) std::invalid_argument("instance id must be >= 1"); - Log::init( + AixLog::Log::init( { - make_shared(debugSwitch.isSet()?(LogSeverity::trace):(LogSeverity::info), LogSink::Type::all, debugSwitch.isSet()?"%Y-%m-%d %H-%M-%S.#ms [#prio] (#tag)":"%Y-%m-%d %H-%M-%S [#prio]"), - make_shared("snapclient", LogSeverity::trace, LogSink::Type::special) + make_shared(debugSwitch.isSet()?(AixLog::Severity::trace):(AixLog::Severity::info), AixLog::Type::all, debugSwitch.isSet()?"%Y-%m-%d %H-%M-%S.#ms [#severity] (#tag)":"%Y-%m-%d %H-%M-%S [#severity]"), + make_shared("snapclient", AixLog::Severity::trace, AixLog::Type::special) } ); diff --git a/common/log.h b/common/log.h index 8f07bda8..075a3c94 100644 --- a/common/log.h +++ b/common/log.h @@ -3,37 +3,26 @@ / _\ ( )( \/ )( ) / \ / __) / \ )( ) ( / (_/\( O )( (_ \ \_/\_/(__)(_/\_)\____/ \__/ \___/ - version 0.7.0 + version 0.13.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 - 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 . + + This software may be modified and distributed under the terms + of the MIT license. See the LICENSE file for details. ***/ /// inspired by "eater": /// https://stackoverflow.com/questions/2638654/redirect-c-stdclog-to-syslog-on-unix -/// TODO: add global log level #ifndef AIX_LOG_HPP #define AIX_LOG_HPP #ifndef _WIN32 -#define _HAS_SYSLOG_ +#define _HAS_SYSLOG_ 1 #endif #include @@ -59,33 +48,28 @@ /// Internal helper defines -#define LOG_WO_TAG(P) std::clog << (LogSeverity)P << Tag(__func__) << LogType::normal -#define SLOG_WO_TAG(P) std::clog << (LogSeverity)P << Tag(__func__) << LogType::special +#define LOG_WO_TAG(P) std::clog << (AixLog::Severity)P +#define LOG_TAG(P, T) std::clog << (AixLog::Severity)P << TAG(T) -#define LOG_TAG(P, T) std::clog << (LogSeverity)P << Tag(T) << LogType::normal -#define SLOG_TAG(P, T) std::clog << (LogSeverity)P << Tag(T) << LogType::special +#define ONE_COLOR(FG) AixLog::Color::FG +#define TWO_COLOR(FG, BG) AixLog::TextColor(AixLog::Color::FG, AixLog::Color::BG) -#define LOG_X(x,P,T,FUNC, ...) FUNC -#define SLOG_X(x,P,T,FUNC, ...) FUNC +#define VAR_PARM(x,P,T,FUN, ...) FUN /// 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 LOG(...) VAR_PARM(,##__VA_ARGS__, LOG_TAG(__VA_ARGS__), LOG_WO_TAG(__VA_ARGS__)) << TIMESTAMP << FUNC +#define SLOG(...) VAR_PARM(,##__VA_ARGS__, LOG_TAG(__VA_ARGS__), LOG_WO_TAG(__VA_ARGS__)) << TIMESTAMP << SPECIAL << FUNC +#define COLOR(...) VAR_PARM(,##__VA_ARGS__, TWO_COLOR(__VA_ARGS__), ONE_COLOR(__VA_ARGS__)) -#define FUNC __func__ -#define TAG Tag -#define COND Conditional +#define FUNC AixLog::Function(__func__, __FILE__, __LINE__) +#define TAG AixLog::Tag +#define COND AixLog::Conditional +#define SPECIAL AixLog::Type::special +#define TIMESTAMP AixLog::Timestamp(std::chrono::system_clock::now()) -enum class LogType -{ - normal, - special -}; - - -enum Severity +enum SEVERITY { // https://chromium.googlesource.com/chromium/mini_chromium/+/master/base/logging.cc @@ -113,7 +97,20 @@ enum Severity }; -enum class LogSeverity : std::int8_t + +namespace AixLog +{ + +enum class Type +{ + normal, + special, + all +}; + + + +enum class Severity : std::int8_t { trace = TRACE, debug = DEBUG, @@ -141,9 +138,9 @@ enum class Color -struct LogColor +struct TextColor { - LogColor(Color foreground = Color::none, Color background = Color::none) : + TextColor(Color foreground = Color::none, Color background = Color::none) : foreground(foreground), background(background) { @@ -181,9 +178,58 @@ private: +struct Timestamp +{ + typedef std::chrono::time_point time_point_sys_clock; + + Timestamp(std::nullptr_t) : is_null_(true) + { + } + + Timestamp() : Timestamp(nullptr) + { + } + + Timestamp(const time_point_sys_clock& time_point) : time_point(time_point), is_null_(false) + { + } + + virtual explicit operator bool() const + { + return !is_null_; + } + + /// strftime format + proprietary "#ms" for milliseconds + std::string to_string(const std::string& format = "%Y-%m-%d %H-%M-%S.#ms") const + { + std::time_t now_c = std::chrono::system_clock::to_time_t(time_point); + 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(time_point).time_since_epoch().count() % 1000; + char ms_str[4]; + sprintf(ms_str, "%03d", ms_part); + result.replace(pos, 3, ms_str); + } + return result; + } + + time_point_sys_clock time_point; + +private: + bool is_null_; +}; + + + struct Tag { - Tag(std::nullptr_t) : tag(""), is_null(true) + Tag(std::nullptr_t) : text(""), is_null_(true) { } @@ -191,54 +237,92 @@ struct Tag { } - Tag(const std::string& tag) : tag(tag), is_null(false) + Tag(const std::string& text) : text(text), is_null_(false) { } virtual explicit operator bool() const { - return !is_null; + return !is_null_; } - std::string tag; + std::string text; private: - bool is_null; + bool is_null_; }; -typedef std::chrono::time_point time_point_sys_clock; -struct LogSink +struct Function { - enum class Type - { - normal, - special, - all - }; - - LogSink(LogSeverity severity, Type type) : severity(severity), sink_type_(type) + Function(const std::string& name, const std::string& file, size_t line) : + name(name), file(file), line(line), is_null_(false) { } - virtual ~LogSink() + Function(std::nullptr_t) : name(""), file(""), line(0), is_null_(true) { } - virtual void log(const time_point_sys_clock& timestamp, LogSeverity severity, LogType type, const Tag& tag, const std::string& message) const = 0; + Function() : Function(nullptr) + { + } + + virtual explicit operator bool() const + { + return !is_null_; + } + + std::string name; + std::string file; + size_t line; + +private: + bool is_null_; +}; + + + +struct Metadata +{ + Metadata() : + severity(Severity::trace), tag(nullptr), type(Type::normal), function(nullptr), timestamp(nullptr) + { + } + + Severity severity; + Tag tag; + Type type; + Function function; + Timestamp timestamp; +}; + + + +struct Sink +{ + Sink(Severity severity, Type type) : severity(severity), sink_type_(type) + { + } + + virtual ~Sink() + { + } + + virtual void log(const Metadata& metadata, const std::string& message) const = 0; virtual Type get_type() const { return sink_type_; } - virtual LogSink& set_type(Type sink_type) + virtual Sink& set_type(Type sink_type) { sink_type_ = sink_type; return *this; } - LogSeverity severity; + Severity severity; protected: Type sink_type_; @@ -246,12 +330,14 @@ protected: -static std::ostream& operator<< (std::ostream& os, const LogSeverity& log_severity); -static std::ostream& operator<< (std::ostream& os, const LogType& log_type); +static std::ostream& operator<< (std::ostream& os, const Severity& log_severity); +static std::ostream& operator<< (std::ostream& os, const Type& log_type); +static std::ostream& operator<< (std::ostream& os, const Timestamp& timestamp); static std::ostream& operator<< (std::ostream& os, const Tag& tag); +static std::ostream& operator<< (std::ostream& os, const Function& function); static std::ostream& operator<< (std::ostream& os, const Conditional& conditional); -typedef std::shared_ptr log_sink_ptr; +typedef std::shared_ptr log_sink_ptr; class Log : public std::basic_streambuf > @@ -266,6 +352,8 @@ public: /// Without "init" every LOG(X) will simply go to clog static void init(const std::vector log_sinks = {}) { + Log::instance().log_sinks_.clear(); + for (auto sink: log_sinks) Log::instance().add_logsink(sink); @@ -274,31 +362,31 @@ public: void add_logsink(log_sink_ptr sink) { - logSinks.push_back(sink); + log_sinks_.push_back(sink); } void remove_logsink(log_sink_ptr sink) { - logSinks.erase(std::remove(logSinks.begin(), logSinks.end(), sink), logSinks.end()); + log_sinks_.erase(std::remove(log_sinks_.begin(), log_sinks_.end(), sink), log_sinks_.end()); } - static std::string toString(LogSeverity logSeverity) + static std::string to_string(Severity logSeverity) { switch (logSeverity) { - case LogSeverity::trace: + case Severity::trace: return "Trace"; - case LogSeverity::debug: + case Severity::debug: return "Debug"; - case LogSeverity::info: + case Severity::info: return "Info"; - case LogSeverity::notice: + case Severity::notice: return "Notice"; - case LogSeverity::warning: + case Severity::warning: return "Warn"; - case LogSeverity::error: + case Severity::error: return "Err"; - case LogSeverity::fatal: + case Severity::fatal: return "Fatal"; default: std::stringstream ss; @@ -309,7 +397,7 @@ public: protected: - Log() : type_(LogType::normal) + Log() { } @@ -317,25 +405,27 @@ protected: { if (!buffer_.str().empty()) { - auto now = std::chrono::system_clock::now(); if (conditional_.is_true()) { - for (const auto sink: logSinks) + for (const auto sink: log_sinks_) { 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)) + (metadata_.type == Type::all) || + (sink->get_type() == Type::all) || + ((metadata_.type == Type::special) && (sink->get_type() == Type::special)) || + ((metadata_.type == Type::normal) && (sink->get_type() == Type::normal)) ) - if (severity_ >= sink->severity) - sink->log(now, severity_, type_, tag_, buffer_.str()); + if (metadata_.severity >= sink->severity) + sink->log(metadata_, buffer_.str()); } } buffer_.str(""); buffer_.clear(); - //severity_ = debug; // default to debug for each message - //type_ = kNormal; - tag_ = nullptr; + metadata_.severity = Severity::trace; + metadata_.type = Type::normal; + metadata_.timestamp = nullptr; + metadata_.tag = nullptr; + metadata_.function = nullptr; conditional_.set(true); } return 0; @@ -357,7 +447,6 @@ protected: } else { - std::cout << "EOF\n"; sync(); } return c; @@ -365,25 +454,25 @@ protected: private: - friend std::ostream& operator<< (std::ostream& os, const LogSeverity& log_severity); - friend std::ostream& operator<< (std::ostream& os, const LogType& log_type); + friend std::ostream& operator<< (std::ostream& os, const Severity& log_severity); + friend std::ostream& operator<< (std::ostream& os, const Type& log_type); + friend std::ostream& operator<< (std::ostream& os, const Timestamp& timestamp); friend std::ostream& operator<< (std::ostream& os, const Tag& tag); + friend std::ostream& operator<< (std::ostream& os, const Function& function); friend std::ostream& operator<< (std::ostream& os, const Conditional& conditional); std::stringstream buffer_; - LogSeverity severity_; - LogType type_; - Tag tag_; + Metadata metadata_; Conditional conditional_; - std::vector logSinks; + std::vector log_sinks_; }; -struct LogSinkFormat : public LogSink +struct SinkFormat : public Sink { - LogSinkFormat(LogSeverity severity, Type type, const std::string& format = "%Y-%m-%d %H-%M-%S [#prio] (#tag)") : // #logline") : - LogSink(severity, type), + SinkFormat(Severity severity, Type type, const std::string& format = "%Y-%m-%d %H-%M-%S [#severity] (#tag)") : + Sink(severity, type), format_(format) { } @@ -393,38 +482,29 @@ struct LogSinkFormat : public LogSink format_ = format; } - virtual void log(const time_point_sys_clock& timestamp, LogSeverity severity, LogType type, const Tag& tag, const std::string& message) const = 0; + virtual void log(const Metadata& metadata, 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, LogSeverity severity, LogType type, const Tag& tag, const std::string& message) const + virtual void do_log(std::ostream& stream, const Metadata& metadata, 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); + std::string result = format_; + if (metadata.timestamp) + result = metadata.timestamp.to_string(result); - char buffer[256]; - strftime(buffer, sizeof buffer, format_.c_str(), &now_tm); - std::string result = buffer; - size_t pos = result.find("#ms"); + size_t pos = result.find("#severity"); if (pos != std::string::npos) - { - int ms_part = std::chrono::time_point_cast(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(severity)); - + result.replace(pos, 9, Log::to_string(metadata.severity)); pos = result.find("#tag"); if (pos != std::string::npos) - result.replace(pos, 4, tag?tag.tag:"log"); + result.replace(pos, 4, metadata.tag?metadata.tag.text:(metadata.function?metadata.function.name:"log")); - pos = result.find("#logline"); + pos = result.find("#function"); + if (pos != std::string::npos) + result.replace(pos, 9, metadata.function?metadata.function.name:""); + + pos = result.find("#message"); if (pos != std::string::npos) { result.replace(pos, 8, message); @@ -444,46 +524,46 @@ protected: -struct LogSinkCout : public LogSinkFormat +struct SinkCout : public SinkFormat { - LogSinkCout(LogSeverity severity, Type type, const std::string& format = "%Y-%m-%d %H-%M-%S.#ms [#prio] (#tag)") : // #logline") : - LogSinkFormat(severity, type, format) + SinkCout(Severity severity, Type type, const std::string& format = "%Y-%m-%d %H-%M-%S.#ms [#severity] (#tag)") : + SinkFormat(severity, type, format) { } - virtual void log(const time_point_sys_clock& timestamp, LogSeverity severity, LogType type, const Tag& tag, const std::string& message) const + virtual void log(const Metadata& metadata, const std::string& message) const { if (severity >= this->severity) - do_log(std::cout, timestamp, severity, type, tag, message); + do_log(std::cout, metadata, message); } }; -struct LogSinkCerr : public LogSinkFormat +struct SinkCerr : public SinkFormat { - LogSinkCerr(LogSeverity severity, Type type, const std::string& format = "%Y-%m-%d %H-%M-%S.#ms [#prio] (#tag)") : // #logline") : - LogSinkFormat(severity, type, format) + SinkCerr(Severity severity, Type type, const std::string& format = "%Y-%m-%d %H-%M-%S.#ms [#severity] (#tag)") : + SinkFormat(severity, type, format) { } - virtual void log(const time_point_sys_clock& timestamp, LogSeverity severity, LogType type, const Tag& tag, const std::string& message) const + virtual void log(const Metadata& metadata, const std::string& message) const { if (severity >= this->severity) - do_log(std::cerr, timestamp, severity, type, tag, message); + do_log(std::cerr, metadata, message); } }; /// Not tested due to unavailability of Windows -struct LogSinkOutputDebugString : LogSink +struct SinkOutputDebugString : Sink { - LogSinkOutputDebugString(LogSeverity severity, Type type = Type::all, const std::string& default_tag = "") : LogSink(severity, type) + SinkOutputDebugString(Severity severity, Type type = Type::all, const std::string& default_tag = "") : Sink(severity, type) { } - virtual void log(const time_point_sys_clock& timestamp, LogSeverity severity, LogType type, const Tag& tag, const std::string& message) const + virtual void log(const Metadata& metadata, const std::string& message) const { #ifdef _WIN32 OutputDebugString(message.c_str()); @@ -493,29 +573,29 @@ struct LogSinkOutputDebugString : LogSink -struct LogSinkUnifiedLogging : LogSink +struct SinkUnifiedLogging : Sink { - LogSinkUnifiedLogging(LogSeverity severity, Type type = Type::all) : LogSink(severity, type) + SinkUnifiedLogging(Severity severity, Type type = Type::all) : Sink(severity, type) { } #ifdef __APPLE__ - os_log_type_t get_os_log_type(LogSeverity severity) const + os_log_type_t get_os_log_type(Severity severity) const { // https://developer.apple.com/documentation/os/os_log_type_t?language=objc switch (severity) { - case LogSeverity::trace: - case LogSeverity::debug: + case Severity::trace: + case Severity::debug: return OS_LOG_TYPE_DEBUG; - case LogSeverity::info: - case LogSeverity::notice: + case Severity::info: + case Severity::notice: return OS_LOG_TYPE_INFO; - case LogSeverity::warning: + case Severity::warning: return OS_LOG_TYPE_DEFAULT; - case LogSeverity::error: + case Severity::error: return OS_LOG_TYPE_ERROR; - case LogSeverity::fatal: + case Severity::fatal: return OS_LOG_TYPE_FAULT; default: return OS_LOG_TYPE_DEFAULT; @@ -523,48 +603,50 @@ struct LogSinkUnifiedLogging : LogSink } #endif - virtual void log(const time_point_sys_clock& timestamp, LogSeverity severity, LogType type, const Tag& tag, const std::string& message) const + virtual void log(const Metadata& metadata, const std::string& message) const { #ifdef __APPLE__ - os_log_with_type(OS_LOG_DEFAULT, get_os_log_type(severity), "%{public}s", message.c_str()); + os_log_with_type(OS_LOG_DEFAULT, get_os_log_type(metadata.severity), "%{public}s", message.c_str()); #endif } }; -struct LogSinkSyslog : public LogSink +struct SinkSyslog : public Sink { - LogSinkSyslog(const char* ident, LogSeverity severity, Type type) : LogSink(severity, type) + SinkSyslog(const char* ident, Severity severity, Type type) : Sink(severity, type) { #ifdef _HAS_SYSLOG_ openlog(ident, LOG_PID, LOG_USER); #endif } - virtual ~LogSinkSyslog() + virtual ~SinkSyslog() { +#ifdef _HAS_SYSLOG_ closelog(); +#endif } #ifdef _HAS_SYSLOG_ - int get_syslog_priority(LogSeverity severity) const + int get_syslog_priority(Severity severity) const { // http://unix.superglobalmegacorp.com/Net2/newsrc/sys/syslog.h.html switch (severity) { - case LogSeverity::trace: - case LogSeverity::debug: + case Severity::trace: + case Severity::debug: return LOG_DEBUG; - case LogSeverity::info: + case Severity::info: return LOG_INFO; - case LogSeverity::notice: + case Severity::notice: return LOG_NOTICE; - case LogSeverity::warning: + case Severity::warning: return LOG_WARNING; - case LogSeverity::error: + case Severity::error: return LOG_ERR; - case LogSeverity::fatal: + case Severity::fatal: return LOG_CRIT; default: return LOG_INFO; @@ -573,40 +655,40 @@ struct LogSinkSyslog : public LogSink #endif - virtual void log(const time_point_sys_clock& timestamp, LogSeverity severity, LogType type, const Tag& tag, const std::string& message) const + virtual void log(const Metadata& metadata, const std::string& message) const { #ifdef _HAS_SYSLOG_ - syslog(get_syslog_priority(severity), "%s", message.c_str()); + syslog(get_syslog_priority(metadata.severity), "%s", message.c_str()); #endif } }; -struct LogSinkAndroid : public LogSink +struct SinkAndroid : public Sink { - LogSinkAndroid(const std::string& ident, LogSeverity severity, Type type = Type::all) : LogSink(severity, type), ident_(ident) + SinkAndroid(const std::string& ident, Severity severity, Type type = Type::all) : Sink(severity, type), ident_(ident) { } #ifdef __ANDROID__ - android_LogSeverity get_android_prio(LogSeverity severity) const + android_LogPriority get_android_prio(Severity severity) const { // https://developer.android.com/ndk/reference/log_8h.html switch (severity) { - case LogSeverity::trace: + case Severity::trace: return ANDROID_LOG_VERBOSE; - case LogSeverity::debug: + case Severity::debug: return ANDROID_LOG_DEBUG; - case LogSeverity::info: - case LogSeverity::notice: + case Severity::info: + case Severity::notice: return ANDROID_LOG_INFO; - case LogSeverity::warning: + case Severity::warning: return ANDROID_LOG_WARN; - case LogSeverity::error: + case Severity::error: return ANDROID_LOG_ERROR; - case LogSeverity::fatal: + case Severity::fatal: return ANDROID_LOG_FATAL; default: return ANDROID_LOG_UNKNOWN; @@ -614,21 +696,21 @@ struct LogSinkAndroid : public LogSink } #endif - virtual void log(const time_point_sys_clock& timestamp, LogSeverity severity, LogType type, const Tag& tag, const std::string& message) const + virtual void log(const Metadata& metadata, 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 + std::string tag = metadata.tag?metadata.tag.text:(metadata.function?metadata.function.name:""); + std::string log_tag; + if (!ident_.empty() && !tag.empty()) + log_tag = ident_ + "." + tag; + else if (!ident_.empty()) log_tag = ident_; - - __android_log_write(get_android_prio(severity), log_tag.c_str(), message.c_str()); + else if (!tag.empty()) + log_tag = tag; + else + log_tag = "log"; + + __android_log_write(get_android_prio(metadata.severity), log_tag.c_str(), message.c_str()); #endif } @@ -639,9 +721,9 @@ protected: /// Not tested due to unavailability of Windows -struct LogSinkEventLog : public LogSink +struct SinkEventLog : public Sink { - LogSinkEventLog(const std::string& ident, LogSeverity severity, Type type = Type::all) : LogSink(severity, type) + SinkEventLog(const std::string& ident, Severity severity, Type type = Type::all) : Sink(severity, type) { #ifdef _WIN32 event_log = RegisterEventSource(NULL, ident.c_str()); @@ -649,21 +731,21 @@ struct LogSinkEventLog : public LogSink } #ifdef _WIN32 - WORD get_type(LogSeverity severity) const + WORD get_type(Severity severity) const { // https://msdn.microsoft.com/de-de/library/windows/desktop/aa363679(v=vs.85).aspx switch (severity) { - case LogSeverity::trace: - case LogSeverity::debug: + case Severity::trace: + case Severity::debug: return EVENTLOG_INFORMATION_TYPE; - case LogSeverity::info: - case LogSeverity::notice: + case Severity::info: + case Severity::notice: return EVENTLOG_SUCCESS; - case LogSeverity::warning: + case Severity::warning: return EVENTLOG_WARNING_TYPE; - case LogSeverity::error: - case LogSeverity::fatal: + case Severity::error: + case Severity::fatal: return EVENTLOG_ERROR_TYPE; default: return EVENTLOG_INFORMATION_TYPE; @@ -671,10 +753,10 @@ struct LogSinkEventLog : public LogSink } #endif - virtual void log(const time_point_sys_clock& timestamp, LogSeverity severity, LogType type, const Tag& tag, const std::string& message) const + virtual void log(const Metadata& metadata, const std::string& message) const { #ifdef _WIN32 - ReportEvent(event_log, get_type(severity), 0, 0, NULL, 1, 0, &message.c_str(), NULL); + ReportEvent(event_log, get_type(metadata.severity), 0, 0, NULL, 1, 0, &message.c_str(), NULL); #endif } @@ -686,28 +768,36 @@ protected: -struct LogSinkNative : public LogSink +struct SinkNative : public Sink { - LogSinkNative(const std::string& ident, LogSeverity severity, Type type = Type::all) : - LogSink(severity, type), + SinkNative(const std::string& ident, Severity severity, Type type = Type::all) : + Sink(severity, type), log_sink_(nullptr), ident_(ident) { #ifdef __ANDROID__ - log_sink_ = std::make_shared(ident_, severity, type); + log_sink_ = std::make_shared(ident_, severity, type); #elif __APPLE__ - log_sink_ = std::make_shared(severity, type); + log_sink_ = std::make_shared(severity, type); #elif _WIN32 - log_sink_ = std::make_shared(severity, type); + log_sink_ = std::make_shared(severity, type); +#elif _HAS_SYSLOG_ + log_sink_ = std::make_shared(ident_.c_str(), severity, type); #else - log_sink_ = std::make_shared(ident_.c_str(), severity, type); + /// will not throw or something. Use "get_logger()" to check for success + log_sink_ = nullptr; #endif } - virtual void log(const time_point_sys_clock& timestamp, LogSeverity severity, LogType type, const Tag& tag, const std::string& message) const + virtual log_sink_ptr get_logger() + { + return log_sink_; + } + + virtual void log(const Metadata& metadata, const std::string& message) const { if (log_sink_) - log_sink_->log(timestamp, severity, type, tag, message); + log_sink_->log(metadata, message); } protected: @@ -717,44 +807,54 @@ protected: -struct LogSinkCallback : public LogSink +struct SinkCallback : public Sink { - typedef std::function callback_fun; + typedef std::function callback_fun; - LogSinkCallback(LogSeverity severity, Type type, callback_fun callback) : LogSink(severity, type), callback(callback) + SinkCallback(Severity severity, Type type, callback_fun callback) : Sink(severity, type), callback_(callback) { } - virtual void log(const time_point_sys_clock& timestamp, LogSeverity severity, LogType type, const Tag& tag, const std::string& message) const + virtual void log(const Metadata& metadata, const std::string& message) const { - if (callback && (severity >= this->severity)) - callback(timestamp, severity, type, tag, message); + if (callback_ && (severity >= this->severity)) + callback_(metadata, message); } private: - callback_fun callback; + callback_fun callback_; }; -static std::ostream& operator<< (std::ostream& os, const LogSeverity& log_severity) +static std::ostream& operator<< (std::ostream& os, const Severity& log_severity) { Log* log = dynamic_cast(os.rdbuf()); - if (log && (log->severity_ != log_severity)) + if (log && (log->metadata_.severity != log_severity)) { log->sync(); - log->severity_ = log_severity; + log->metadata_.severity = log_severity; } return os; } -static std::ostream& operator<< (std::ostream& os, const LogType& log_type) +static std::ostream& operator<< (std::ostream& os, const Type& log_type) { Log* log = dynamic_cast(os.rdbuf()); if (log) - log->type_ = log_type; + log->metadata_.type = log_type; + return os; +} + + + +static std::ostream& operator<< (std::ostream& os, const Timestamp& timestamp) +{ + Log* log = dynamic_cast(os.rdbuf()); + if (log) + log->metadata_.timestamp = timestamp; return os; } @@ -764,7 +864,17 @@ static std::ostream& operator<< (std::ostream& os, const Tag& tag) { Log* log = dynamic_cast(os.rdbuf()); if (log) - log->tag_ = tag; + log->metadata_.tag = tag; + return os; +} + + + +static std::ostream& operator<< (std::ostream& os, const Function& function) +{ + Log* log = dynamic_cast(os.rdbuf()); + if (log) + log->metadata_.function = function; return os; } @@ -780,7 +890,7 @@ static std::ostream& operator<< (std::ostream& os, const Conditional& conditiona -static std::ostream& operator<< (std::ostream& os, const LogColor& log_color) +static std::ostream& operator<< (std::ostream& os, const TextColor& log_color) { os << "\033["; if ((log_color.foreground == Color::none) && (log_color.background == Color::none)) @@ -803,11 +913,13 @@ static std::ostream& operator<< (std::ostream& os, const LogColor& log_color) static std::ostream& operator<< (std::ostream& os, const Color& color) { - os << LogColor(color); + os << TextColor(color); return os; } +} + #endif /// AIX_LOG_HPP diff --git a/server/Makefile b/server/Makefile index 1d349138..af82596f 100644 --- a/server/Makefile +++ b/server/Makefile @@ -43,7 +43,7 @@ ifeq ($(TARGET), ANDROID) CXX = $(NDK_DIR)/bin/arm-linux-androideabi-g++ STRIP = $(NDK_DIR)/bin/arm-linux-androideabi-strip CXXFLAGS += -pthread -DANDROID -DNO_CPP11_STRING -fPIC -I$(NDK_DIR)/include -LDFLAGS += -L$(NDK_DIR)/lib -pie +LDFLAGS += -L$(NDK_DIR)/lib -pie -llog else ifeq ($(TARGET), OPENWRT) diff --git a/server/snapServer.cpp b/server/snapServer.cpp index b23d9f79..172ee27f 100644 --- a/server/snapServer.cpp +++ b/server/snapServer.cpp @@ -143,10 +143,10 @@ int main(int argc, char* argv[]) return 1; } - Log::init( + AixLog::Log::init( { - make_shared(debugSwitch.isSet()?(LogSeverity::trace):(LogSeverity::info), LogSink::Type::all, debugSwitch.isSet()?"%Y-%m-%d %H-%M-%S.#ms [#prio] (#tag)":"%Y-%m-%d %H-%M-%S [#prio]"), - make_shared("snapserver", LogSeverity::trace, LogSink::Type::special) + make_shared(debugSwitch.isSet()?(AixLog::Severity::trace):(AixLog::Severity::info), AixLog::Type::all, debugSwitch.isSet()?"%Y-%m-%d %H-%M-%S.#ms [#severity] (#tag)":"%Y-%m-%d %H-%M-%S [#severity]"), + make_shared("snapserver", AixLog::Severity::trace, AixLog::Type::special) } );