1 // Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
11 #define PROJECT_TAG "PKGMGR_INFO"
26 #define __FILENAME__ \
27 (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
39 log_priority LogLevelToPriority(LogLevel level);
41 template<LogLevel> struct LogTag;
42 template<> struct LogTag<LogLevel::LOG_ERROR> {
43 static constexpr const char* value = "\033[1;31m| ERROR |\033[0m";
45 template<> struct LogTag<LogLevel::LOG_WARNING> {
46 static constexpr const char* value = "\033[1;33m| WARNING |\033[0m";
48 template<> struct LogTag<LogLevel::LOG_INFO> {
49 static constexpr const char* value = "\033[1;32m| INFO |\033[0m";
51 template<> struct LogTag<LogLevel::LOG_DEBUG> {
52 static constexpr const char* value = "\033[0m| DEBUG |\033[0m";
55 template <class charT, class traits = std::char_traits<charT>>
56 class StringStream : private std::basic_ostringstream<charT, traits> {
58 using std::basic_ostringstream<charT, traits>::str;
61 StringStream& operator<<(const T& value) {
62 static_cast<std::basic_ostringstream<charT, traits> &>(*this) << value;
69 LogCatcher(LogLevel level, const char* tag)
70 : level_(level), tag_(tag) { }
72 void operator&(const StringStream<char>& str) const {
73 dlog_print(LogLevelToPriority(level_), tag_.c_str(), "%s",
74 Escape(str.str()).c_str());
78 // Since LogCatcher passes input to dlog_print(), the input which contains
79 // format string(such as %d, %n) can cause unexpected result.
80 // This is simple function to escape '%'.
81 // NOTE: Is there any gorgeous way instead of this?
82 std::string Escape(const std::string& str) const {
83 std::string escaped = std::string(str);
85 std::string from = "%";
86 std::string to = "%%";
87 while ((start_pos = escaped.find(from, start_pos)) != std::string::npos) {
88 escaped.replace(start_pos, from.length(), to);
89 start_pos += to.length();
99 inline static const constexpr char* __tag_for_project() {
103 // Simple logging macro of following usage:
104 // LOG(LEVEL) << object_1 << object_2 << object_n;
106 // LEVEL = ERROR | WARNING | INFO | DEBUG
108 ::utils::LogCatcher( \
109 ::utils::LogLevel::LOG_ ## LEVEL, __tag_for_project()) \
110 & ::utils::StringStream<char>() \
111 << std::string(::utils::LogTag<::utils::LogLevel::LOG_ ## LEVEL>::value) \
112 << " : " << std::setw(36) \
113 << (std::string(__FILENAME__) + ":" + std::to_string(__LINE__)).c_str() \
114 << std::setw(0) << " : " \
116 #endif // LOGGING_HH_