Merge "[Filesystem] Remove special case for zero in readBytes/writeBytes" into tizen_4.0
[platform/core/api/webapi-plugins.git] / src / common / logger.h
1 // Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef COMMON_LOGGER_H_
6 #define COMMON_LOGGER_H_
7
8 #include <dlog.h>
9
10 // Tizen 3.0 uses different debug flag (DLOG_DEBUG_ENABLE) which is always
11 // enabled, following code allows to disable logs with DLOG_DEBUG priority if
12 // TIZEN_DEBUG_ENABLE is not set.
13 // This code should be removed when DLOG_DEBUG_ENABLE flag is no longer set
14 // by default in dlog.h file.
15 #undef LOG_
16 #ifdef TIZEN_DEBUG_ENABLE
17 #define LOG_(id, prio, tag, fmt, arg...)                                                       \
18   ({                                                                                           \
19     do {                                                                                       \
20       __dlog_print(id, prio, tag, "%s: %s(%d) > " fmt, __MODULE__, __func__, __LINE__, ##arg); \
21     } while (0);                                                                               \
22   })
23 #else  // TIZEN_DEBUG_ENABLE
24 #define LOG_(id, prio, tag, fmt, arg...)                                                         \
25   ({                                                                                             \
26     do {                                                                                         \
27       if ((int)prio != DLOG_DEBUG) {                                                             \
28         __dlog_print(id, prio, tag, "%s: %s(%d) > " fmt, __MODULE__, __func__, __LINE__, ##arg); \
29       }                                                                                          \
30     } while (0);                                                                                 \
31   })
32 #endif  // TIZEN_DEBUG_ENABLE
33
34 #undef SECURE_LOG_
35 #ifdef TIZEN_DEBUG_ENABLE
36 #define SECURE_LOG_(id, prio, tag, fmt, arg...)                                           \
37   ({                                                                                      \
38     do {                                                                                  \
39       __dlog_print(id, prio, tag, "%s: %s(%d) > [SECURE_LOG] " fmt, __MODULE__, __func__, \
40                    __LINE__, ##arg);                                                      \
41     } while (0);                                                                          \
42   })
43 #else  // TIZEN_DEBUG_ENABLE
44 #define SECURE_LOG_(id, prio, tag, fmt, arg...) NOP(fmt, ##arg)
45 #endif  // TIZEN_DEBUG_ENABLE
46
47 #include <cstring>
48 #include <sstream>
49 #include <string>
50
51 #include "common/utils.h"
52
53 #undef LOGGER_TAG
54 #define LOGGER_TAG "WEBAPI_PLUGINS"
55
56 #define _LOGGER_LOG(prio, fmt, args...) LOG_(LOG_ID_MAIN, prio, LOGGER_TAG, fmt, ##args)
57
58 #define _LOGGER_SLOG(prio, fmt, args...) SECURE_LOG_(LOG_ID_MAIN, prio, LOGGER_TAG, fmt, ##args)
59
60 #define LoggerD(fmt, args...) _LOGGER_LOG(DLOG_DEBUG, fmt, ##args)
61 #define LoggerI(fmt, args...) _LOGGER_LOG(DLOG_INFO, fmt, ##args)
62 #define LoggerW(fmt, args...) _LOGGER_LOG(DLOG_WARN, fmt, ##args)
63 #define LoggerE(fmt, args...) _LOGGER_LOG(DLOG_ERROR, fmt, ##args)
64
65 #define SLoggerD(fmt, args...) _LOGGER_SLOG(DLOG_DEBUG, fmt, ##args)
66 #define SLoggerI(fmt, args...) _LOGGER_SLOG(DLOG_INFO, fmt, ##args)
67 #define SLoggerW(fmt, args...) _LOGGER_SLOG(DLOG_WARN, fmt, ##args)
68 #define SLoggerE(fmt, args...) _LOGGER_SLOG(DLOG_ERROR, fmt, ##args)
69
70 // A few definitions of macros that don't generate much code. These are used
71 // by LOGGER() and LOGGER_IF, etc. Since these are used all over our code, it's
72 // better to have compact code for these operations.
73 #ifdef TIZEN_DEBUG_ENABLE
74 #define COMPACT_LOG_DEBUG LogMessage(__MODULE__, __func__, __LINE__, DLOG_DEBUG).stream()
75 #else
76 #define COMPACT_LOG_DEBUG true ? (void)0 : LogMessageVoidify() & (std::ostringstream())
77 #endif
78
79 #define COMPACT_LOG_INFO LogMessage(__MODULE__, __func__, __LINE__, DLOG_INFO).stream()
80 #define COMPACT_LOG_WARN LogMessage(__MODULE__, __func__, __LINE__, DLOG_WARN).stream()
81 #define COMPACT_LOG_ERROR LogMessage(__MODULE__, __func__, __LINE__, DLOG_ERROR).stream()
82
83 #define LOGGER(priority) COMPACT_LOG_##priority
84 #define LOGGER_IF(priority, condition) \
85   !(condition) ? (void)0 : LogMessageVoidify() & (LOGGER(priority))
86
87 // This class more or less represents a particular log message.
88 // You create an instance of LogMessage and then stream stuff to it.
89 // When you finish streaming to it, ~LogMessage is called and the
90 // full message gets streamed to dlog.
91 //
92 // You shouldn't actually use LogMessage's constructor to log things,
93 // though. You should use the LOGGER() macro (and variants thereof) above.
94 class LogMessage {
95  public:
96   LogMessage(const char* file, const char* function, int line, log_priority priority);
97   ~LogMessage();
98
99   std::ostream& stream() {
100     return stream_;
101   }
102
103  private:
104   const char* file_;
105   const char* function_;
106   const int line_;
107   log_priority priority_;
108
109   std::ostringstream stream_;
110
111   DISALLOW_COPY_AND_ASSIGN(LogMessage);
112 };
113
114 // This class is used to explicitly ignore values in the conditional
115 // logging macros. This avoids compiler warnings like "value computed
116 // is not used" and "statement has no effect".
117 class LogMessageVoidify {
118  public:
119   LogMessageVoidify() {
120   }
121
122   // This has to be an operator with a precedence lower than << but
123   // higher than ?:
124   void operator&(std::ostream&) {
125   }
126 };
127
128 // internal macros
129 #define LogAndReportError_2(error, object) \
130   do {                                     \
131     LoggerE("Reporting error.");           \
132     ReportError(error, object);            \
133   } while (false)
134
135 #define LogAndReportError_3(error, object, log) \
136   do {                                          \
137     LoggerE log;                                \
138     ReportError(error, object);                 \
139   } while (false)
140
141 #define LogAndReportError_X(_0, _1, _2, _3, FUNC, ...) FUNC
142
143 // usage:
144 // LogAndCreateResult(const common::PlatformResult& result, picojson::object* obj, [(const char*
145 // log, ...)])
146 //  LogAndReportError(result, &out);
147 //  LogAndReportError(result, &out, ("Failed to open archive."));
148 //  LogAndReportError(result, &out, ("Failed to open archive: %d.", 11));
149
150 #define LogAndReportError(...)                                           \
151   LogAndReportError_X(, ##__VA_ARGS__, LogAndReportError_3(__VA_ARGS__), \
152                       LogAndReportError_2(__VA_ARGS__))
153
154 // internal macros
155 #define LogAndCreateResult_1(error_code) \
156   (LoggerE("Creating PlatformResult with error"), common::PlatformResult(error_code))
157
158 #define LogAndCreateResult_2(error_code, msg) \
159   (LoggerE("Creating PlatformResult with error"), common::PlatformResult(error_code, msg))
160
161 #define LogAndCreateResult_3(error_code, msg, log) \
162   (LoggerE log, common::PlatformResult(error_code, msg))
163
164 #define LogAndCreateResult_X(_0, _1, _2, _3, FUNC, ...) FUNC
165
166 // LogAndCreateResult(common::ErrorCode code, [const char* error_message, (const char* log, ...)])
167 // usage:
168 //  auto pr1 = LogAndCreateResult(ErrorCode::IO_ERR);
169 //  PlatformResult pr2 = LogAndCreateResult(ErrorCode::IO_ERR);
170 //  return LogAndCreateResult(ErrorCode::IO_ERR);
171 //
172 //  auto pr3 = LogAndCreateResult(ErrorCode::IO_ERR, "Not a directory.");
173 //  PlatformResult pr4 = LogAndCreateResult(ErrorCode::IO_ERR, "Not a directory.");
174 //  return LogAndCreateResult(ErrorCode::IO_ERR, "Not a directory.");
175 //
176 //  auto pr5 = LogAndCreateResult(ErrorCode::IO_ERR, "Not a directory.", ("Not a directory:
177 //  reporting IO error"));
178 //  PlatformResult pr6 = LogAndCreateResult(ErrorCode::IO_ERR, "Not a directory.", ("Not a
179 //  directory: reporting IO error"));
180 //  return LogAndCreateResult(ErrorCode::IO_ERR, "Not a directory.", ("Not a directory: reporting IO
181 //  error"));
182 //
183 //  auto pr7 = LogAndCreateResult(ErrorCode::IO_ERR, "Not a directory.", ("Not a directory:
184 //  reporting IO error: %d", 33));
185 //  PlatformResult pr8 = LogAndCreateResult(ErrorCode::IO_ERR, "Not a directory.", ("Not a
186 //  directory: reporting IO error: %d", 33));
187 //  return LogAndCreateResult(ErrorCode::IO_ERR, "Not a directory.", ("Not a directory: reporting IO
188 //  error: %d", 33));
189
190 #define LogAndCreateResult(...)                                            \
191   LogAndCreateResult_X(, ##__VA_ARGS__, LogAndCreateResult_3(__VA_ARGS__), \
192                        LogAndCreateResult_2(__VA_ARGS__), LogAndCreateResult_1(__VA_ARGS__))
193
194 // internal macros
195 #define LogAndCreateTizenError_1(error_name) (LoggerE("Creating TizenError"), common::error_name())
196
197 #define LogAndCreateTizenError_2(error_name, msg) \
198   (LoggerE("Creating TizenError"), common::error_name(msg))
199
200 #define LogAndCreateTizenError_3(error_name, msg, log) (LoggerE log, common::error_name(msg))
201
202 #define LogAndCreateTizenError_X(_0, _1, _2, _3, FUNC, ...) FUNC
203
204 #define LogAndCreateTizenError(...)                                                \
205   LogAndCreateTizenError_X(, ##__VA_ARGS__, LogAndCreateTizenError_3(__VA_ARGS__), \
206                            LogAndCreateTizenError_2(__VA_ARGS__),                  \
207                            LogAndCreateTizenError_1(__VA_ARGS__))
208
209 // internal macros
210 #define LogAndReturnTizenError_1(error) \
211   do {                                  \
212     LoggerE("Reporting error.");        \
213     return error;                       \
214   } while (false)
215
216 #define LogAndReturnTizenError_2(error, log) \
217   do {                                       \
218     LoggerE log;                             \
219     return error;                            \
220   } while (false)
221
222 #define LogAndReturnTizenError_X(_0, _1, _2, FUNC, ...) FUNC
223
224 #define LogAndReturnTizenError(...)                                                \
225   LogAndReturnTizenError_X(, ##__VA_ARGS__, LogAndReturnTizenError_2(__VA_ARGS__), \
226                            LogAndReturnTizenError_1(__VA_ARGS__))
227
228 namespace common {
229
230 // defined here, so LoggerD() depends on TIZEN_DEBUG_ENABLE flag on per-module
231 // basis
232 class ScopeLogger {
233  public:
234   ScopeLogger(const std::string& f, const std::string& m) : file_(f), method_(m) {
235   }
236
237   ~ScopeLogger() {
238     LoggerD("%s: %s > Exit", file_.c_str(), method_.c_str());
239   }
240
241  private:
242   std::string file_;
243   std::string method_;
244 };
245
246 }  // common
247
248 #ifdef TIZEN_DEBUG_ENABLE
249 #define ScopeLogger(EX, args...)                                                                 \
250   __dlog_print(LOG_ID_MAIN, DLOG_DEBUG, LOGGER_TAG,                                              \
251                "logger.h: ScopeLogger > %s: %s(%d) > Enter " EX, __MODULE__, __func__, __LINE__, \
252                ##args);                                                                          \
253   const common::ScopeLogger __sl__{__MODULE__, __func__};
254
255 #else
256 #define ScopeLogger(EX, args...)
257 #endif
258
259 #endif  // COMMON_LOGGER_H_