AlexaClientSDK  3.0.0
A cross-platform, modular SDK for interacting with the Alexa Voice Service
Logger.h
Go to the documentation of this file.
1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  * http://aws.amazon.com/apache2.0/
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 #ifndef ALEXA_CLIENT_SDK_AVSCOMMON_UTILS_INCLUDE_AVSCOMMON_UTILS_LOGGER_LOGGER_H_
17 #define ALEXA_CLIENT_SDK_AVSCOMMON_UTILS_INCLUDE_AVSCOMMON_UTILS_LOGGER_LOGGER_H_
18 
19 #include <atomic>
20 #include <chrono>
21 #include <mutex>
22 #include <sstream>
23 #include <vector>
24 
26 
31 
37 #define ACSDK_STRINGIFY_INNER(expression) #expression
38 
44 #define ACSDK_STRINGIFY(macro) ACSDK_STRINGIFY_INNER(macro)
45 
52 #define ACSDK_CONCATENATE_INNER(lhs, rhs) lhs##rhs
53 
60 #define ACSDK_CONCATENATE(lhs, rhs) ACSDK_CONCATENATE_INNER(lhs, rhs)
61 
62 namespace alexaClientSDK {
63 namespace avsCommon {
64 namespace utils {
65 namespace logger {
66 
147 class Logger {
148 public:
154  Logger(Level level);
155 
157  virtual ~Logger() = default;
158 
164  virtual void setLevel(Level level);
165 
172  inline bool shouldLog(Level level) const;
173 
180  void log(Level level, const LogEntry& entry);
181 
193  void logAtExit(Level level, const LogEntry& entry);
194 
205  virtual void emit(
206  Level level,
207  std::chrono::system_clock::time_point time,
208  const char* threadMoniker,
209  const char* text);
210 
217 
224 
225 protected:
231  void init(const configuration::ConfigurationNode configuration);
232 
234  std::atomic<Level> m_level;
235 
236 private:
243  bool initLogLevel(const configuration::ConfigurationNode configuration);
244 
248  void notifyObserversOnLogLevelChanged();
249 
251  std::vector<LogLevelObserverInterface*> m_observers;
252 
254  std::mutex m_observersMutex;
255 };
256 
257 bool Logger::shouldLog(Level level) const {
258  return level >= m_level;
259 }
260 
266 #define ACSDK_GET_LOGGER_FUNCTION_NAME(type) ACSDK_CONCATENATE(ACSDK_CONCATENATE(get, type), Logger)
267 
273 std::shared_ptr<Logger> getConsoleLogger();
274 
275 } // namespace logger
276 } // namespace utils
277 } // namespace avsCommon
278 } // namespace alexaClientSDK
279 
280 #ifndef ACSDK_LOG_MODULE
281 #define ACSDK_LOG_MODULE ConsoleLogger
282 #endif // ACSDK_LOG_MODULE
283 
285 
286 namespace alexaClientSDK {
287 namespace avsCommon {
288 namespace utils {
289 namespace logger {
290 
296 #define ACSDK_GET_LOGGER_FUNCTION ACSDK_GET_LOGGER_FUNCTION_NAME(ACSDK_LOG_MODULE)
297 
301 inline std::shared_ptr<Logger> ACSDK_GET_LOGGER_FUNCTION() {
302  static std::shared_ptr<ModuleLogger> moduleLogger =
303  std::make_shared<ModuleLogger>(ACSDK_STRINGIFY(ACSDK_LOG_MODULE));
304  return moduleLogger;
305 }
306 
307 } // namespace logger
308 } // namespace utils
309 } // namespace avsCommon
310 } // namespace alexaClientSDK
311 
321 #ifdef ACSDK_LOG_ENABLED
322 #define ACSDK_LOG(level, entry) \
323  do { \
324  auto loggerInstance = alexaClientSDK::avsCommon::utils::logger::ACSDK_GET_LOGGER_FUNCTION(); \
325  if (loggerInstance->shouldLog(level)) { \
326  loggerInstance->log(level, entry); \
327  } \
328  } while (false)
329 #else // ACSDK_LOG_ENABLED
330 #define ACSDK_LOG(level, entry) \
331  do { \
332  (void)sizeof(level); \
333  (void)sizeof(entry); \
334  } while (false)
335 #endif // ACSDK_LOG_ENABLED
336 
347 #ifdef ACSDK_DEBUG_LOG_ENABLED
348 #define ACSDK_DEBUG_LOG(level, entry) ACSDK_LOG((level), (entry))
349 #else // ACSDK_DEBUG_LOG_ENABLED
350 #define ACSDK_DEBUG_LOG(level, entry) \
351  do { \
352  (void)sizeof(level); \
353  (void)sizeof(entry); \
354  } while (false)
355 #endif // ACSDK_DEBUG_LOG_ENABLED
356 
364 #define ACSDK_DEBUG9(entry) ACSDK_DEBUG_LOG(alexaClientSDK::avsCommon::utils::logger::Level::DEBUG9, entry)
365 
373 #define ACSDK_DEBUG8(entry) ACSDK_DEBUG_LOG(alexaClientSDK::avsCommon::utils::logger::Level::DEBUG8, entry)
374 
382 #define ACSDK_DEBUG7(entry) ACSDK_DEBUG_LOG(alexaClientSDK::avsCommon::utils::logger::Level::DEBUG7, entry)
383 
391 #define ACSDK_DEBUG6(entry) ACSDK_DEBUG_LOG(alexaClientSDK::avsCommon::utils::logger::Level::DEBUG6, entry)
392 
400 #define ACSDK_DEBUG5(entry) ACSDK_DEBUG_LOG(alexaClientSDK::avsCommon::utils::logger::Level::DEBUG5, entry)
401 
409 #define ACSDK_DEBUG4(entry) ACSDK_DEBUG_LOG(alexaClientSDK::avsCommon::utils::logger::Level::DEBUG4, entry)
410 
418 #define ACSDK_DEBUG3(entry) ACSDK_DEBUG_LOG(alexaClientSDK::avsCommon::utils::logger::Level::DEBUG3, entry)
419 
427 #define ACSDK_DEBUG2(entry) ACSDK_DEBUG_LOG(alexaClientSDK::avsCommon::utils::logger::Level::DEBUG2, entry)
428 
436 #define ACSDK_DEBUG1(entry) ACSDK_DEBUG_LOG(alexaClientSDK::avsCommon::utils::logger::Level::DEBUG1, entry)
437 
445 #define ACSDK_DEBUG0(entry) ACSDK_DEBUG_LOG(alexaClientSDK::avsCommon::utils::logger::Level::DEBUG0, entry)
446 
454 #define ACSDK_DEBUG(entry) ACSDK_DEBUG_LOG(alexaClientSDK::avsCommon::utils::logger::Level::DEBUG0, entry)
455 
463 #define ACSDK_INFO(entry) ACSDK_LOG(alexaClientSDK::avsCommon::utils::logger::Level::INFO, entry)
464 
472 #define ACSDK_WARN(entry) ACSDK_LOG(alexaClientSDK::avsCommon::utils::logger::Level::WARN, entry)
473 
481 #define ACSDK_ERROR(entry) ACSDK_LOG(alexaClientSDK::avsCommon::utils::logger::Level::ERROR, entry)
482 
489 #define ACSDK_CRITICAL(entry) ACSDK_LOG(alexaClientSDK::avsCommon::utils::logger::Level::CRITICAL, entry)
490 
491 #ifndef ACSDK_LOGS_KEEP_FUNC_MACRO
492 // In older Android releases __func__ is redefined as __PRETTY_FUNCTION__ making log messages difficult to read and
493 // analyse. We undefine this macro if it is defined. See Logger.cmake for details on how to keep the macro intact.
494 #undef __func__
495 #endif // ACSDK_LOGS_KEEP_FUNC_MACRO
496 
497 #endif // ALEXA_CLIENT_SDK_AVSCOMMON_UTILS_INCLUDE_AVSCOMMON_UTILS_LOGGER_LOGGER_H_
#define ACSDK_STRINGIFY(macro)
Definition: Logger.h:44
bool shouldLog(Level level) const
Definition: Logger.h:257
void log(Level level, const LogEntry &entry)
virtual void emit(Level level, std::chrono::system_clock::time_point time, const char *threadMoniker, const char *text)
std::shared_ptr< Logger > getConsoleLogger()
void init(const configuration::ConfigurationNode configuration)
void logAtExit(Level level, const LogEntry &entry)
std::shared_ptr< Logger > ACSDK_GET_LOGGER_FUNCTION()
Definition: Logger.h:301
void addLogLevelObserver(LogLevelObserverInterface *observer)
void removeLogLevelObserver(LogLevelObserverInterface *observer)
Whether or not curl logs should be emitted.
Definition: AVSConnectionManager.h:36
std::atomic< Level > m_level
The lowest severity level of logs to be output by this Logger.
Definition: Logger.h:234
#define ACSDK_LOG_MODULE
Definition: Logger.h:281
LogEntry is used to compile the log entry text to log via Logger.
Definition: LogEntry.h:33

AlexaClientSDK 3.0.0 - Copyright 2016-2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. Licensed under the Apache License, Version 2.0