From 06bbfdafdef58891799c70d115c82a670488b09b Mon Sep 17 00:00:00 2001 From: Martin Koch Date: Tue, 7 Jan 2020 11:22:30 +0100 Subject: AM-Utils: Introduce new logging architecture, providing separate classes for each logging channel (DLT, file or stdout) and a channel-independent wrapper class. (first preparation step of AM for build without strong dependency to DLT library) Signed-off-by: Martin Koch --- AudioManagerUtilities/CMakeLists.txt | 7 + AudioManagerUtilities/include/CAmLogWrapper.h | 128 +++++++++ AudioManagerUtilities/include/CAmLoggerDlt.h | 90 +++++++ AudioManagerUtilities/include/CAmLoggerFile.h | 105 ++++++++ AudioManagerUtilities/include/CAmLoggerStdOut.h | 113 ++++++++ AudioManagerUtilities/include/CAmTimeUtility.h | 45 ++++ AudioManagerUtilities/include/IAmLogger.h | 342 ++++++++++++++++++++++++ AudioManagerUtilities/src/CAmLogWrapper.cpp | 125 +++++++++ AudioManagerUtilities/src/CAmLoggerDlt.cpp | 223 +++++++++++++++ AudioManagerUtilities/src/CAmLoggerFile.cpp | 252 +++++++++++++++++ AudioManagerUtilities/src/CAmLoggerStdOut.cpp | 264 ++++++++++++++++++ Foo/uncrustify_files.cfg | 10 + 12 files changed, 1704 insertions(+) create mode 100755 AudioManagerUtilities/include/CAmLogWrapper.h create mode 100755 AudioManagerUtilities/include/CAmLoggerDlt.h create mode 100755 AudioManagerUtilities/include/CAmLoggerFile.h create mode 100755 AudioManagerUtilities/include/CAmLoggerStdOut.h create mode 100755 AudioManagerUtilities/include/CAmTimeUtility.h create mode 100755 AudioManagerUtilities/include/IAmLogger.h create mode 100755 AudioManagerUtilities/src/CAmLogWrapper.cpp create mode 100755 AudioManagerUtilities/src/CAmLoggerDlt.cpp create mode 100755 AudioManagerUtilities/src/CAmLoggerFile.cpp create mode 100755 AudioManagerUtilities/src/CAmLoggerStdOut.cpp diff --git a/AudioManagerUtilities/CMakeLists.txt b/AudioManagerUtilities/CMakeLists.txt index 7c502c5..51b5d74 100644 --- a/AudioManagerUtilities/CMakeLists.txt +++ b/AudioManagerUtilities/CMakeLists.txt @@ -40,6 +40,9 @@ ENDIF (WITH_SHARED_UTILITIES) SET(AUDIO_MANAGER_UTILITIES_SRCS_CXX src/CAmCommandLineSingleton.cpp src/CAmDltWrapper.cpp + src/CAmLogWrapper.cpp + src/CAmLoggerFile.cpp + src/CAmLoggerStdOut.cpp src/CAmSocketHandler.cpp) if(WITH_SYSTEMD_WATCHDOG) @@ -109,6 +112,10 @@ ENDIF (WITH_CAPI_WRAPPER) IF (WITH_DLT) pkg_check_modules(DLT REQUIRED "automotive-dlt >= 2.2.0") + SET(AUDIO_MANAGER_UTILITIES_SRCS_CXX + ${AUDIO_MANAGER_UTILITIES_SRCS_CXX} + src/CAmLoggerDlt.cpp) + add_definitions(${DLT_CFLAGS_OTHER}) set(AUDIO_MANAGER_UTILITIES_LIBS diff --git a/AudioManagerUtilities/include/CAmLogWrapper.h b/AudioManagerUtilities/include/CAmLogWrapper.h new file mode 100755 index 0000000..224c3ac --- /dev/null +++ b/AudioManagerUtilities/include/CAmLogWrapper.h @@ -0,0 +1,128 @@ +/** + * SPDX license identifier: MPL-2.0 + * + * Copyright (C) 2017, ADIT GmbH + * + * \author Mattia Guerra, mguerra@de.adit-jv.com ADIT 2017 + * \author Jens Lorenz, jlorenz@de.adit-jv.com ADIT 2017 + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \file CAmLogWrapper.h + * For further information see http://www.genivi.org/. + */ + +#ifndef LOGWRAPPER_H_ +#define LOGWRAPPER_H_ + +#include +#include "pthread.h" +#include "IAmLogger.h" +#include "audiomanagertypes.h" + +namespace am +{ +/** + * This class is instantiated as a singleton and offers logging to a default context (maincontext). + * Logging under the default context can simply be done with the logDebug/logInfo/logError/logWarning/logVerbose + * templates. For logging with a different context, you need to register a context with registerContext, + * method provided by backends implementing the IAmLogger interface. registerContext returns a logging context. + * To import this context into other classes use importContext, method provided by backends implementing the IAmLogger + * interface. To access the IAmLogger interface, simply ask CAmLogWrapper::instance(). + */ +class CAmLogWrapper +{ +public: + static IAmLogger *instantiateOnce(const char *appid, const char *description, + const am_LogStatus_e logStatus = LS_ON, const am_LogService_e logService = DEFAULT_LOG_SERVICE, + const std::string Filename = "", bool onlyError = false); + static IAmLogger *instance(const am_LogService_e logservice = DEFAULT_LOG_SERVICE); + + inline static am_LogService_e getLogService() + { + return mLogService; + } + + virtual ~CAmLogWrapper(); + +private: + CAmLogWrapper(void); //!< is private because of singleton pattern + static IAmLogger *mpLogger; //!< pointer to the logger instance + static std::string mAppId; + static std::string mDescription; + static am_LogStatus_e mLogStatus; + static am_LogService_e mLogService; + static std::string mFilename; + static bool mOnlyError; +}; + +/** + * returns the instance of instantiated IAmLogger + * @return + */ +inline IAmLogger *getLogger() +{ + return (CAmLogWrapper::instance(CAmLogWrapper::getLogService())); +} + +/** + * logs given values with debuglevel with the default context + * @param value + * @param ... + */ +template +void logDebug(const T &value, const TArgs & ... args) +{ + getLogger()->logToDefaultContext(LL_DEBUG, value, args...); +} + +/** + * logs given values with infolevel with the default context + * @param value + * @param ... + */ +template +void logInfo(const T &value, const TArgs & ... args) +{ + getLogger()->logToDefaultContext(LL_INFO, value, args...); +} + +/** + * logs given values with errorlevel with the default context + * @param value + * @param ... + */ +template +void logError(const T &value, const TArgs & ... args) +{ + getLogger()->logToDefaultContext(LL_ERROR, value, args...); +} + +/** + * logs given values with warninglevel with the default context + * @param value + * @param ... + */ +template +void logWarning(const T &value, const TArgs & ... args) +{ + getLogger()->logToDefaultContext(LL_WARN, value, args...); +} + +/** + * logs given values with verboselevel with the default context + * @param value + * @param ... + */ +template +void logVerbose(const T &value, const TArgs & ... args) +{ + getLogger()->logToDefaultContext(LL_VERBOSE, value, args...); +} + +} + +#endif /* LOGWRAPPER_H_ */ diff --git a/AudioManagerUtilities/include/CAmLoggerDlt.h b/AudioManagerUtilities/include/CAmLoggerDlt.h new file mode 100755 index 0000000..5af0aad --- /dev/null +++ b/AudioManagerUtilities/include/CAmLoggerDlt.h @@ -0,0 +1,90 @@ +/** + * SPDX license identifier: MPL-2.0 + * + * Copyright (C) 2017, ADIT GmbH + * + * This file is part of GENIVI Project AudioManager. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \file CAmLoggerDlt.h + * For further information see http://www.genivi.org/. + */ + +#ifndef LOGGERDLT_H_ +#define LOGGERDLT_H_ + +#include "IAmLogger.h" +#include +#include +#include +#include +#include + +namespace am +{ + +class CAmLogContextDlt : public IAmLogContext +{ +public: + CAmLogContextDlt(const char *id); + virtual ~CAmLogContextDlt() {} + DltContext *getHandle(); + +private: + /* IAmLogContext */ + bool configure(const am_LogLevel_e loglevel) override; + void send() override; + void append(const int8_t value) override; + void append(const uint8_t value) override; + void append(const int16_t value) override; + void append(const uint16_t value) override; + void append(const int32_t value) override; + void append(const uint32_t value) override; + void append(const uint64_t value) override; + void append(const int64_t value) override; + void append(const bool value) override; + void append(const std::vector &data) override; + void append(const char *value) override; + + template + void append(T value); + + bool checkLogLevel(const am_LogLevel_e logLevel) override; + +private: + const char *mId; + DltContext mDltContext; + DltContextData mDltContextData; +}; + +class CAmLoggerDlt : public IAmLogger +{ +public: + ~CAmLoggerDlt(); + + /* IAmLogger */ + void registerApp(const char *appid, const char *description) override; + void unregisterApp() override; + IAmLogContext ®isterContext(const char *contextid, const char *description) override; + IAmLogContext ®isterContext(const char *contextid, const char *description, + const am_LogLevel_e level, const am_LogStatus_e status) override; + IAmLogContext &importContext(const char *contextid = NULL) override; + void unregisterContext(const char *contextid) override; + +private: + CAmLogContextDlt &createContext(const char *contextid); + +private: + std::map mCtxTable; +}; + +} + +#endif /* LOGGERDLT_H_ */ diff --git a/AudioManagerUtilities/include/CAmLoggerFile.h b/AudioManagerUtilities/include/CAmLoggerFile.h new file mode 100755 index 0000000..de09a63 --- /dev/null +++ b/AudioManagerUtilities/include/CAmLoggerFile.h @@ -0,0 +1,105 @@ +/** + * SPDX license identifier: MPL-2.0 + * + * Copyright (C) 2017, ADIT GmbH + * + * This file is part of GENIVI Project AudioManager. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \file CAmLoggerFile.h + * For further information see http://www.genivi.org/. + */ + +#ifndef LOGGERFILE_H_ +#define LOGGERFILE_H_ + +#include "IAmLogger.h" +#include +#include +#include +#include + +namespace am +{ + +class CFileHeader +{ +public: + CFileHeader(const char *ctx = "LOG") + : mCtx(ctx) {} + friend std ::ostream &operator <<(std::ostream &out, const CFileHeader &h); + + const char *mCtx; +}; + +class CAmLogContextFile : public IAmLogContext +{ +public: + CAmLogContextFile(const char *id, const am_LogLevel_e level, const am_LogStatus_e status, std::ofstream &filestream); + virtual ~CAmLogContextFile() {} + + /* IAmLogContext */ + bool checkLogLevel(const am_LogLevel_e logLevel) override; + +private: + /* IAmLogContext */ + bool configure(const am_LogLevel_e loglevel) override; + void send() override; + void append(const int8_t value) override; + void append(const uint8_t value) override; + void append(const int16_t value) override; + void append(const uint16_t value) override; + void append(const int32_t value) override; + void append(const uint32_t value) override; + void append(const uint64_t value) override; + void append(const int64_t value) override; + void append(const bool value) override; + void append(const std::vector &data) override; + void append(const char *value) override; + + template + void appendFile(T value); + +private: + CFileHeader mHeader; + am_LogLevel_e mLogLevel; + am_LogStatus_e mLogStatus; + std::ofstream &mFilestream; +}; + +class CAmLoggerFile : public IAmLogger +{ +public: + CAmLoggerFile(const am_LogStatus_e status, const bool onlyError = false, const std::string &filename = ""); + ~CAmLoggerFile(); + + /* IAmLogger */ + void registerApp(const char *appid, const char *description) override; + void unregisterApp() override; + IAmLogContext ®isterContext(const char *contextid, const char *description) override; + IAmLogContext ®isterContext(const char *contextid, const char *description, + const am_LogLevel_e level, const am_LogStatus_e status) override; + IAmLogContext &importContext(const char *contextid = NULL) override; + void unregisterContext(const char *contextid) override; + +private: + void print(std::string str); + +private: + CFileHeader mHeader; + const am_LogStatus_e mLogStatus; + const am_LogLevel_e mStandardLogLevel; + std::ofstream mFilestream; + std::map mCtxTable; +}; + +} + +#endif /* LOGGERFILE_H_ */ diff --git a/AudioManagerUtilities/include/CAmLoggerStdOut.h b/AudioManagerUtilities/include/CAmLoggerStdOut.h new file mode 100755 index 0000000..3821aba --- /dev/null +++ b/AudioManagerUtilities/include/CAmLoggerStdOut.h @@ -0,0 +1,113 @@ +/** + * SPDX license identifier: MPL-2.0 + * + * Copyright (C) 2015, ADIT GmbH + * + * This file is part of GENIVI Project AudioManager. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \file CAmLoggerStdOut.h + * For further information see http://www.genivi.org/. + */ + +#ifndef LOGGERSTDOUT_H_ +#define LOGGERSTDOUT_H_ + +#include "IAmLogger.h" +#include +#include +#include + +namespace am +{ + +static const std::string CC_BLACK = "\x1b[0;30m"; +static const std::string CC_RED = "\x1b[0;31m"; +static const std::string CC_GREEN = "\x1b[0;32m"; +static const std::string CC_YELLOW = "\x1b[0;33m"; +static const std::string CC_BLUE = "\x1b[0;34m"; +static const std::string CC_MAGENTA = "\x1b[0;35m"; +static const std::string CC_CYAN = "\x1b[0;36m"; +static const std::string CC_WHITE = "\x1b[0;37m"; +static const std::string CC_RESET = "\x1b[0;39m"; + +class CStdOutHeader +{ +public: + CStdOutHeader(const char *ctx = "LOG", const std::string &color = CC_BLUE) + : mCtx(ctx) + , mCc(color) {} + friend std ::ofstream &operator <<(std::ofstream &out, const CStdOutHeader &h); + + const char *mCtx; + const std::string &mCc; +}; + +class CAmLogContextStdOut : public IAmLogContext +{ +public: + CAmLogContextStdOut(const char *id, const am_LogLevel_e level, const am_LogStatus_e status); + virtual ~CAmLogContextStdOut() {} + + void changeLogLS(const am_LogLevel_e level, const am_LogStatus_e status); + + /* IAmLogContext */ + bool checkLogLevel(const am_LogLevel_e logLevel) override; + +private: + /* IAmLogContext */ + bool configure(const am_LogLevel_e loglevel) override; + void send() override; + void append(const int8_t value) override; + void append(const uint8_t value) override; + void append(const int16_t value) override; + void append(const uint16_t value) override; + void append(const int32_t value) override; + void append(const uint32_t value) override; + void append(const uint64_t value) override; + void append(const int64_t value) override; + void append(const bool value) override; + void append(const std::vector &data) override; + void append(const char *value) override; + + template + void appendStdOut(T value); + +private: + CStdOutHeader mHeader; + am_LogLevel_e mLogLevel; + am_LogStatus_e mLogStatus; +}; + +class CAmLoggerStdOut : public IAmLogger +{ +public: + CAmLoggerStdOut(const am_LogStatus_e status, const bool onlyError = false); + ~CAmLoggerStdOut(); + + /* IAmLogger */ + void registerApp(const char *appid, const char *description) override; + void unregisterApp() override; + IAmLogContext ®isterContext(const char *contextid, const char *description) override; + IAmLogContext ®isterContext(const char *contextid, const char *description, + const am_LogLevel_e level, const am_LogStatus_e status) override; + IAmLogContext &importContext(const char *contextid = NULL) override; + void unregisterContext(const char *contextid) override; + +private: + CStdOutHeader mHeader; + const am_LogStatus_e mLogStatus; + const am_LogLevel_e mStandardLogLevel; + std::map mCtxTable; +}; + +} + +#endif /* LOGGERSTDOUT_H_ */ diff --git a/AudioManagerUtilities/include/CAmTimeUtility.h b/AudioManagerUtilities/include/CAmTimeUtility.h new file mode 100755 index 0000000..2f0a29d --- /dev/null +++ b/AudioManagerUtilities/include/CAmTimeUtility.h @@ -0,0 +1,45 @@ +/** + * SPDX license identifier: MPL-2.0 + * + * Copyright (C) 2016, ADIT GmbH + * + * This file is part of GENIVI Project AudioManager. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \file CAmTimeUtility.h + * For further information see http://www.genivi.org/. + */ + +#ifndef TIMEUTILITY_H_ +#define TIMEUTILITY_H_ + +#include + +namespace am +{ + +class CAmTimeUtility +{ +public: + static inline std::string now() + { + time_t t(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now())); + struct tm *timeinfo(localtime(&t)); + char buffer[80]; + strftime(buffer, 80, "%D %T ", timeinfo); + return (std::string(buffer)); + } + + virtual ~CAmTimeUtility(); +}; + +} + +#endif /* TIMEUTILITY_H_ */ diff --git a/AudioManagerUtilities/include/IAmLogger.h b/AudioManagerUtilities/include/IAmLogger.h new file mode 100755 index 0000000..95af6b9 --- /dev/null +++ b/AudioManagerUtilities/include/IAmLogger.h @@ -0,0 +1,342 @@ +/** + * SPDX license identifier: MPL-2.0 + * + * Copyright (C) 2015, ADIT GmbH + * + * \author Jens Lorenz, jlorenz@de.adit-jv.com ADIT 2015 + * + * This file is part of GENIVI Project AudioManager. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \file IAmLogger.h + * For further information see http://www.genivi.org/. + */ + +#ifndef LOGGER_H_ +#define LOGGER_H_ + +#include +#include +#include +#include +#include +#include "audiomanagertypes.h" + + +namespace am +{ + +#define DEFAULT_CONTEXT "DEF" +#define DEFAULT_DESCRIPTION "default Context registered by DLT Logger Class" + +#define DEFAULT_LOG_SERVICE static_cast(0) + +enum am_LogService_e +{ + LOG_SERVICE_DLT, + LOG_SERVICE_STDOUT, + LOG_SERVICE_FILE, + LOG_SERVICE_OFF +}; + +enum am_LogLevel_e +{ + LL_OFF = 0x00, /**< Log level off */ + LL_FATAL = 0x01, /**< fatal system error */ + LL_ERROR = 0x02, /**< error with impact to correct functionality */ + LL_WARN = 0x03, /**< warning, correct behavior could not be ensured */ + LL_INFO = 0x04, /**< informational */ + LL_DEBUG = 0x05, /**< debug */ + LL_VERBOSE = 0x06 /**< highest grade of information */ +}; + +enum am_LogStatus_e +{ + LS_OFF = 0x00, + LS_ON = 0x01 +}; + +class IAmLogContext +{ +public: + virtual ~IAmLogContext() {} + + /** + * logs given loglevel and given values + * @param loglevel + * @param ... + */ + template + void off(const TArgs & ... args) + { + this->log(LL_OFF, args...); + } + + template + void fatal(const TArgs & ... args) + { + this->log(LL_FATAL, args...); + } + + template + void error(const TArgs & ... args) + { + this->log(LL_ERROR, args...); + } + + template + void warn(const TArgs & ... args) + { + this->log(LL_WARN, args...); + } + + template + void info(const TArgs & ... args) + { + this->log(LL_INFO, args...); + } + + template + void debug(const TArgs & ... args) + { + this->log(LL_DEBUG, args...); + } + + template + void verbose(const TArgs & ... args) + { + this->log(LL_VERBOSE, args...); + } + + template + void log(const am_LogLevel_e loglevel, const TArgs & ... args) + { + if (!this->configure(loglevel)) + { + return; + } + + this->append(args...); + this->send(); + } + + virtual bool checkLogLevel(const am_LogLevel_e logLevel) = 0; + + virtual bool configure(const am_LogLevel_e loglevel) = 0; + +private: + virtual void send() = 0; + + virtual void append(const int8_t value) = 0; + virtual void append(const uint8_t value) = 0; + virtual void append(const int16_t value) = 0; + virtual void append(const uint16_t value) = 0; + virtual void append(const int32_t value) = 0; + virtual void append(const uint32_t value) = 0; + virtual void append(const uint64_t value) = 0; + virtual void append(const int64_t value) = 0; + virtual void append(const bool value) = 0; + virtual void append(const std::vector &data) = 0; + virtual void append(const char *value) = 0; + + template + void append(const std::string &value) + { + this->append(value.c_str()); + } + + template + void append_enum(const T &value, const T &tmax, const std::vector &text) + { + assert(tmax == text.size()); + try + { + this->append(text.at(value)); + } + catch (const std::out_of_range &) + { + this->append(__PRETTY_FUNCTION__); + this->append(static_cast(value)); + this->append("out of range!"); + } + } + + template + void append(const am_Error_e value) + { + this->append_enum(value, E_MAX, std::vector { + "E_OK", + "E_UNKNOWN", + "E_OUT_OF_RANGE", + "E_NOT_USED", + "E_DATABASE_ERROR", + "E_ALREADY_EXISTS", + "E_NO_CHANGE", + "E_NOT_POSSIBLE", + "E_NON_EXISTENT", + "E_ABORTED", + "E_WRONG_FORMAT", + "E_COMMUNICATION" + } + ); + } + + template + void append(const am_SourceState_e value) + { + this->append_enum(value, SS_MAX, std::vector { + "SS_UNKNNOWN", + "SS_ON", + "SS_OFF", + "SS_PAUSED" + } + ); + } + + template + void append(const am_MuteState_e value) + { + this->append_enum(value, MS_MAX, std::vector { + "MS_UNKNOWN", + "MS_MUTED", + "MS_UNMUTED" + } + ); + } + + template + void append(const am_DomainState_e value) + { + this->append_enum(value, DS_MAX, std::vector { + "DS_UNKNOWN", + "DS_CONTROLLED", + "DS_INDEPENDENT_STARTUP", + "DS_INDEPENDENT_RUNDOWN" + } + ); + } + + template + void append(const am_ConnectionState_e value) + { + this->append_enum(value, CS_MAX, std::vector { + "CS_UNKNOWN", + "CS_CONNECTING", + "CS_CONNECTED", + "CS_DISCONNECTING", + "CS_DISCONNECTED", + "CS_SUSPENDED" + } + ); + } + + template + void append(const am_Availability_e value) + { + this->append_enum(value, A_MAX, std::vector { + "A_UNKNOWN", + "A_AVAILABLE", + "A_UNAVAILABLE" + } + ); + } + + template + void append(const am_InterruptState_e value) + { + this->append_enum(value, IS_MAX, std::vector { + "IS_UNKNOWN", + "IS_OFF", + "IS_INTERRUPTED" + } + ); + } + + template + void append(const am_Handle_e value) + { + this->append_enum(value, H_MAX, std::vector { + "H_UNKNOWN", + "H_CONNECT", + "H_DISCONNECT", + "H_SETSOURCESTATE", + "H_SETSINKVOLUME", + "H_SETSOURCEVOLUME", + "H_SETSINKSOUNDPROPERTY", + "H_SETSOURCESOUNDPROPERTY", + "H_SETSINKSOUNDPROPERTIES", + "H_SETSOURCESOUNDPROPERTIES", + "H_CROSSFADE", + "H_SETVOLUMES", + "H_SETSINKNOTIFICATION", + "H_SETSOURCENOTIFICATION" + } + ); + } + + template + void append(const am_Handle_s value) + { + this->append(value.handle); + this->append(value.handleType); + } + + // Template to print unknown pointer types with their address + template + void append(T *value) + { + std::ostringstream ss; + ss << "0x" << std::hex << (uint64_t)value; + this->append(ss.str().c_str()); + } + + // Template to print unknown types + template + void append(T value) + { + std::ostringstream ss; + ss << std::dec << value; + this->append(ss.str().c_str()); + } + + // Template parameter pack to generate recursive code + void append(void) {} + template + void append(const T &value, const TArgs & ... args) + { + this->append(value); + this->append(args...); + } + +}; + +class IAmLogger +{ +public: + virtual ~IAmLogger() {} + virtual void registerApp(const char *appid, const char *description) = 0; + virtual void unregisterApp() = 0; + virtual IAmLogContext ®isterContext(const char *contextid, const char *description) = 0; + virtual IAmLogContext ®isterContext(const char *contextid, const char *description, + const am_LogLevel_e level, const am_LogStatus_e status) = 0; + virtual IAmLogContext &importContext(const char *contextid = NULL) = 0; + virtual void unregisterContext(const char *contextid) = 0; + + template + void logToDefaultContext(const am_LogLevel_e loglevel, const T &value, const TArgs & ... args) + { + this->importContext().log(loglevel, value, args...); + } + +}; + +} + +#endif // LOGGER_H_ diff --git a/AudioManagerUtilities/src/CAmLogWrapper.cpp b/AudioManagerUtilities/src/CAmLogWrapper.cpp new file mode 100755 index 0000000..8bd6b0a --- /dev/null +++ b/AudioManagerUtilities/src/CAmLogWrapper.cpp @@ -0,0 +1,125 @@ +/** + * SPDX license identifier: MPL-2.0 + * + * Copyright (C) 2017, ADIT GmbH + * + * This file is part of GENIVI Project AudioManager. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * + * \author Mattia Guerra, mguerra@de.adit-jv.com ADIT 2017 + * \author Jens Lorenz, jlorenz@de.adit-jv.com ADIT 2017 + * + * \file CAmLogWrapper.cpp + * For further information see http://www.genivi.org/. + * + */ + +#include +#include +#include "CAmLogWrapper.h" +#include "CAmLoggerStdOut.h" +#include "CAmLoggerFile.h" +#ifdef WITH_DLT +# include "CAmLoggerDlt.h" +#endif + + +using namespace std; + +namespace am +{ + +IAmLogger *CAmLogWrapper::mpLogger = NULL; +string CAmLogWrapper::mAppId = ""; +string CAmLogWrapper::mDescription = ""; +am_LogStatus_e CAmLogWrapper::mLogStatus = LS_ON; +am_LogService_e CAmLogWrapper::mLogService = DEFAULT_LOG_SERVICE; +string CAmLogWrapper::mFilename = ""; +bool CAmLogWrapper::mOnlyError = false; + +CAmLogWrapper::CAmLogWrapper(void) +{ +} + +IAmLogger *CAmLogWrapper::instantiateOnce(const char *appid, const char *description, + const am_LogStatus_e logStatus, const am_LogService_e logService, + const string fileName, bool onlyError) +{ + if (mpLogger) + { + return mpLogger; + } + + mAppId = string(appid); + mDescription = string(description); + mLogStatus = logStatus; + mLogService = logService; + mFilename = fileName; + mOnlyError = onlyError; + return instance(mLogService); +} + +IAmLogger *CAmLogWrapper::instance(const am_LogService_e service) +{ + if (mpLogger) + { + return mpLogger; + } + + switch (service) + { + case LOG_SERVICE_DLT: +#ifdef WITH_DLT + mpLogger = new CAmLoggerDlt(); +#else + std::cerr << "Option WITH_DLT not enabled for CAmLogWrapper! " + << "Redirecting log output to stdout ..." << std::endl; + mLogService = LOG_SERVICE_STDOUT; + mpLogger = new CAmLoggerStdOut(mLogStatus, mOnlyError); +#endif + break; + case LOG_SERVICE_STDOUT: + mpLogger = new CAmLoggerStdOut(mLogStatus, mOnlyError); + break; + case LOG_SERVICE_FILE: + mpLogger = new CAmLoggerFile(mLogStatus, mOnlyError, mFilename); + break; + default: + mpLogger = new CAmLoggerStdOut(LS_OFF); + break; + } + + // an application seems not to use our CAmLogWrapper class properly therefore create default context + if ((mLogStatus == LS_ON) && mAppId.empty() && mDescription.empty()) + { + mAppId = "AMDL"; + std::ostringstream description; + description << "PID=" << getpid() << " _=" << getenv("_"); + mDescription = description.str().c_str(); + std::cerr << "Application doesn't call CAmLogWrapper::instantiateOnce!!!" << std::endl; + std::cerr << "-> CAmLogWrapper::instance registers DLT application [ AMDL | " << description.str() << " ]" << std::endl; + } + + mpLogger->registerApp(mAppId.c_str(), mDescription.c_str()); + + return mpLogger; +} + +CAmLogWrapper::~CAmLogWrapper() +{ + if (mpLogger) + { + mpLogger->unregisterApp(); + delete mpLogger; + } +} + +} diff --git a/AudioManagerUtilities/src/CAmLoggerDlt.cpp b/AudioManagerUtilities/src/CAmLoggerDlt.cpp new file mode 100755 index 0000000..8840916 --- /dev/null +++ b/AudioManagerUtilities/src/CAmLoggerDlt.cpp @@ -0,0 +1,223 @@ +/** + * SPDX license identifier: MPL-2.0 + * + * Copyright (C) 2015, ADIT GmbH + * + * This file is part of GENIVI Project AudioManager. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * + * \author Jens Lorenz, jlorenz@de.adit-jv.com ADIT 2017 + * \author Mattia Guerra, mguerra@de.adit-jv.com ADIT 2017 + * \author Martin Koch, mkoch@de.adit-jv.com ADIT 2020 + * + * \file CAmLoggerDlt.cpp + * For further information see http://www.genivi.org/. + * + */ + +#include "CAmLogWrapper.h" +#include "CAmLoggerDlt.h" + +namespace am +{ + +pthread_mutex_t gDltMtx = PTHREAD_MUTEX_INITIALIZER; + +CAmLogContextDlt::CAmLogContextDlt(const char *id) + : mId(id) +{ +} + +DltContext *CAmLogContextDlt::getHandle() +{ + return &mDltContext; +} + +void CAmLogContextDlt::append(const int8_t value) +{ + dlt_user_log_write_int8(&mDltContextData, value); +} + +void CAmLogContextDlt::append(const uint8_t value) +{ + dlt_user_log_write_uint8(&mDltContextData, value); +} + +void CAmLogContextDlt::append(const int16_t value) +{ + dlt_user_log_write_int16(&mDltContextData, value); +} + +void CAmLogContextDlt::append(const uint16_t value) +{ + dlt_user_log_write_uint16(&mDltContextData, value); +} + +void CAmLogContextDlt::append(const int32_t value) +{ + dlt_user_log_write_int32(&mDltContextData, value); +} + +void CAmLogContextDlt::append(const uint32_t value) +{ + dlt_user_log_write_uint32(&mDltContextData, value); +} + +void CAmLogContextDlt::append(const bool value) +{ + dlt_user_log_write_bool(&mDltContextData, static_cast(value)); +} + +void CAmLogContextDlt::append(const int64_t value) +{ + dlt_user_log_write_int64(&mDltContextData, value); +} + +void CAmLogContextDlt::append(const uint64_t value) +{ + dlt_user_log_write_uint64(&mDltContextData, value); +} + +void CAmLogContextDlt::append(const std::vector &data) +{ + dlt_user_log_write_raw(&mDltContextData, (void *)data.data(), data.size()); +} + +void CAmLogContextDlt::append(const char *value) +{ + dlt_user_log_write_string(&mDltContextData, value); +} + +bool CAmLogContextDlt::checkLogLevel(const am_LogLevel_e logLevel) +{ +#ifdef DLT_IS_LOG_LEVEL_ENABLED + return (dlt_user_is_logLevel_enabled(&mDltContext, static_cast(logLevel)) == DLT_RETURN_TRUE); +#else + (void)logLevel; + return true; +#endif +} + +bool CAmLogContextDlt::configure(const am_LogLevel_e loglevel) +{ + pthread_mutex_lock(&gDltMtx); + + /* leave in case we are allowed to send messages */ + if (dlt_user_log_write_start(&mDltContext, &mDltContextData, static_cast(loglevel)) > 0) + { + return true; + } + + pthread_mutex_unlock(&gDltMtx); + return false; +} + +void CAmLogContextDlt::send() +{ + dlt_user_log_write_finish(&mDltContextData); + pthread_mutex_unlock(&gDltMtx); +} + +CAmLoggerDlt::~CAmLoggerDlt() +{ + unregisterApp(); +} + +void CAmLoggerDlt::registerApp(const char *appid, const char *description) +{ + dlt_register_app(appid, description); + registerContext(DEFAULT_CONTEXT, DEFAULT_DESCRIPTION); +} + +void CAmLoggerDlt::unregisterApp() +{ + for (auto &&context : mCtxTable) + { + dlt_unregister_context(context.second->getHandle()); + delete context.second; + delete context.first; + } + mCtxTable.clear(); + + dlt_unregister_app(); +} + +IAmLogContext &CAmLoggerDlt::registerContext(const char *contextid, const char *description) +{ + auto &&context = createContext(contextid); + dlt_register_context(context.getHandle(), contextid, description); + return context; +} + +IAmLogContext &CAmLoggerDlt::registerContext(const char *contextid, const char *description, const am_LogLevel_e level, const am_LogStatus_e status) +{ + auto &&context = createContext(contextid); + dlt_register_context_ll_ts(context.getHandle(), contextid, description, static_cast(level), static_cast(status)); + return context; +} + +IAmLogContext &CAmLoggerDlt::importContext(const char *contextid) +{ + // check, if we have this context + contextid = (contextid ? contextid : DEFAULT_CONTEXT); + for (auto &ctx : mCtxTable) + { + if (contextid && strncmp(ctx.first, contextid, DLT_ID_SIZE) == 0) + { + return *ctx.second; + } + } + + // no match. Fall back to default context + return importContext(DEFAULT_CONTEXT); +} + +void CAmLoggerDlt::unregisterContext(const char *contextid) +{ + for (auto it = mCtxTable.begin(); it != mCtxTable.end(); ++it) + { + if (contextid && strncmp(contextid, it->first, DLT_ID_SIZE) == 0) + { + dlt_unregister_context(it->second->getHandle()); + delete it->second; + + const char *pKey = it->first; + mCtxTable.erase(it); + delete pKey; + + return; + } + } +} + +CAmLogContextDlt &CAmLoggerDlt::createContext(const char *contextid) +{ + // check, if we already have this context + for (auto &ctx : mCtxTable) + { + if (contextid && strncmp(contextid, ctx.first, DLT_ID_SIZE) == 0) + { + return *ctx.second; + } + } + + // Not in list. Create new + size_t len = (contextid ? strlen(contextid) : 0); + char *pKey = new char[1 + len]; + strncpy(pKey, contextid, len); + pKey[len] = '\0'; + auto *pContext = new CAmLogContextDlt(contextid); + mCtxTable[pKey] = pContext; + + return *pContext; +} + +} diff --git a/AudioManagerUtilities/src/CAmLoggerFile.cpp b/AudioManagerUtilities/src/CAmLoggerFile.cpp new file mode 100755 index 0000000..e3b4dbf --- /dev/null +++ b/AudioManagerUtilities/src/CAmLoggerFile.cpp @@ -0,0 +1,252 @@ +/** + * SPDX license identifier: MPL-2.0 + * + * Copyright (C) 2017, ADIT GmbH + * + * This file is part of GENIVI Project AudioManager. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \author Jens Lorenz, jlorenz@de.adit-jv.com ADIT 2017 + * \author Mattia Guerra, mguerra@de.adit-jv.com ADIT 2017 + * \author Martin Koch, mkoch@de.adit-jv.com ADIT 2020 + * + * \file CAmLoggerFile.cpp + * For further information see http://www.genivi.org/. + * + */ + +#include +#include +#include +#include +#include +#include "CAmLogWrapper.h" +#include "CAmLoggerFile.h" +#include "CAmTimeUtility.h" + +using namespace std; + +namespace am +{ + +#define PADDING_WIDTH 4 + +pthread_mutex_t gFileMtx = PTHREAD_MUTEX_INITIALIZER; + +ostream &operator <<(ostream &out, const class CFileHeader &h) +{ + out << CAmTimeUtility::now() << "[" << setw(PADDING_WIDTH) << left << string(h.mCtx, 0, PADDING_WIDTH) << "] "; + return out; +} + +CAmLogContextFile::CAmLogContextFile(const char *id, const am_LogLevel_e level, const am_LogStatus_e status, ofstream &filestream) + : mHeader(id) + , mLogLevel(level) + , mLogStatus(status) + , mFilestream(filestream) +{ +} + +void CAmLogContextFile::append(const int8_t value) +{ + appendFile(value); +} + +void CAmLogContextFile::append(const uint8_t value) +{ + appendFile(value); +} + +void CAmLogContextFile::append(const int16_t value) +{ + appendFile(value); +} + +void CAmLogContextFile::append(const uint16_t value) +{ + appendFile(value); +} + +void CAmLogContextFile::append(const int32_t value) +{ + appendFile(value); +} + +void CAmLogContextFile::append(const uint32_t value) +{ + appendFile(value); +} + +void CAmLogContextFile::append(const uint64_t value) +{ + appendFile(value); +} + +void CAmLogContextFile::append(const int64_t value) +{ + appendFile(value); +} + +void CAmLogContextFile::append(const bool value) +{ + appendFile(value); +} + +void CAmLogContextFile::append(const char *value) +{ + appendFile(value); +} + +void CAmLogContextFile::append(const vector &data) +{ + mFilestream << data.data() << " "; +} + +template +void CAmLogContextFile::appendFile(T value) +{ + mFilestream << value << " "; +} + +bool CAmLogContextFile::configure(const am_LogLevel_e loglevel) +{ + if (LS_OFF || loglevel > mLogLevel) + { + return false; + } + + pthread_mutex_lock(&gFileMtx); + mFilestream << mHeader; + + return true; +} + +bool CAmLogContextFile::checkLogLevel(const am_LogLevel_e logLevel) +{ + return logLevel <= mLogLevel; +} + +void CAmLogContextFile::send() +{ + mFilestream << endl; + pthread_mutex_unlock(&gFileMtx); +} + +CAmLoggerFile::CAmLoggerFile(const am_LogStatus_e status, const bool onlyError, const string &filename) + : mLogStatus(status) + , mStandardLogLevel(onlyError ? LL_ERROR : LL_INFO) +{ + if (mLogStatus == LS_OFF) + { + cout << "Running without Logging support" << endl; + return; + } + + mFilestream.open(filename.c_str(), ofstream::out | ofstream::trunc); + if (!mFilestream.is_open()) + { + throw runtime_error("Cannot open log file: " + filename); + } +} + +CAmLoggerFile::~CAmLoggerFile() +{ + mFilestream.close(); + unregisterApp(); +} + +void CAmLoggerFile::unregisterApp() +{ + for (auto &&context : mCtxTable) + { + unregisterContext(context.first); + } +} + +void CAmLoggerFile::registerApp(const char *appid, const char *description) +{ + if (mLogStatus == LS_ON) + { + mFilestream << mHeader << "Register Application " << string(appid, PADDING_WIDTH) << ", " << description << endl; + } + + registerContext(DEFAULT_CONTEXT, DEFAULT_DESCRIPTION); +} + +IAmLogContext &CAmLoggerFile::registerContext(const char *contextid, const char *description) +{ + return registerContext(contextid, description, mStandardLogLevel, mLogStatus); +} + +IAmLogContext &CAmLoggerFile::registerContext(const char *contextid, const char *description, + const am_LogLevel_e level, const am_LogStatus_e status) +{ + // check, if we already have this context + for (auto &ctx : mCtxTable) + { + if (contextid && strncmp(contextid, ctx.first, PADDING_WIDTH) == 0) + { + return *ctx.second; + } + } + + // Not in list. Create new + if (mLogStatus == LS_ON) + { + mFilestream << mHeader << "Registering Context " << string(contextid, PADDING_WIDTH) << ", " << description << endl; + } + size_t len = (contextid ? strlen(contextid) : 0); + char *pKey = new char[1 + len]; + strncpy(pKey, contextid, len); + pKey[len] = '\0'; + auto *pContext = new CAmLogContextFile(contextid, level, status, mFilestream); + mCtxTable[pKey] = pContext; + + return *pContext; +} + +IAmLogContext &CAmLoggerFile::importContext(const char *contextid) +{ + // check, if we have this context + contextid = (contextid ? contextid : DEFAULT_CONTEXT); + for (auto &ctx : mCtxTable) + { + if (contextid && strncmp(ctx.first, contextid, PADDING_WIDTH) == 0) + { + return *ctx.second; + } + } + + // no match. Fall back to default context + return importContext(DEFAULT_CONTEXT); +} + +void CAmLoggerFile::unregisterContext(const char *contextid) +{ + for (auto it = mCtxTable.begin(); it != mCtxTable.end(); ++it) + { + if (contextid && strncmp(contextid, it->first, PADDING_WIDTH) == 0) + { + delete it->second; + const char *key = it->first; + mCtxTable.erase(it); + delete key; + + if (mLogStatus == LS_ON) + { + mFilestream << mHeader << "Context " << string(contextid, PADDING_WIDTH) << "unregistered" << endl; + } + + return; + } + } +} + +} diff --git a/AudioManagerUtilities/src/CAmLoggerStdOut.cpp b/AudioManagerUtilities/src/CAmLoggerStdOut.cpp new file mode 100755 index 0000000..0e3e4dd --- /dev/null +++ b/AudioManagerUtilities/src/CAmLoggerStdOut.cpp @@ -0,0 +1,264 @@ +/** + * SPDX license identifier: MPL-2.0 + * + * Copyright (C) 2017, ADIT GmbH + * + * This file is part of GENIVI Project AudioManager. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * \author Jens Lorenz, jlorenz@de.adit-jv.com ADIT 2017 + * \author Mattia Guerra, mguerra@de.adit-jv.com ADIT 2017 + * \author Martin Koch, mkoch@de.adit-jv.com ADIT 2020 + * + * \file CAmLoggerStdOut.cpp + * For further information see http://www.genivi.org/. + * + */ + +#include +#include +#include +#include +#include +#include "CAmLogWrapper.h" +#include "CAmLoggerStdOut.h" +#include "CAmTimeUtility.h" + +using namespace std; + +namespace am +{ + +#define PADDING_WIDTH 4 + +pthread_mutex_t gStdOutMtx = PTHREAD_MUTEX_INITIALIZER; + +ostream &operator <<(ostream &out, const class CStdOutHeader &h) +{ + out << CAmTimeUtility::now() << h.mCc << "[" << setw(PADDING_WIDTH) << left << string(h.mCtx, 0, PADDING_WIDTH) << "] " << CC_RESET; + return out; +} + +CAmLogContextStdOut::CAmLogContextStdOut(const char *id, const am_LogLevel_e level, const am_LogStatus_e status) + : mHeader(id, CC_GREEN) + , mLogLevel(level) + , mLogStatus(status) +{ +} + +void CAmLogContextStdOut::changeLogLS(const am_LogLevel_e level, const am_LogStatus_e status) +{ + mLogLevel = level; + mLogStatus = status; +} + +void CAmLogContextStdOut::append(const int8_t value) +{ + appendStdOut(value); +} + +void CAmLogContextStdOut::append(const uint8_t value) +{ + appendStdOut(value); +} + +void CAmLogContextStdOut::append(const int16_t value) +{ + appendStdOut(value); +} + +void CAmLogContextStdOut::append(const uint16_t value) +{ + appendStdOut(value); +} + +void CAmLogContextStdOut::append(const int32_t value) +{ + appendStdOut(value); +} + +void CAmLogContextStdOut::append(const uint32_t value) +{ + appendStdOut(value); +} + +void CAmLogContextStdOut::append(const uint64_t value) +{ + appendStdOut(value); +} + +void CAmLogContextStdOut::append(const int64_t value) +{ + appendStdOut(value); +} + +void CAmLogContextStdOut::append(const bool value) +{ + appendStdOut(value); +} + +void CAmLogContextStdOut::append(const char *value) +{ + appendStdOut(value); +} + +void CAmLogContextStdOut::append(const vector &data) +{ + cout << data.data() << " "; +} + +template +void CAmLogContextStdOut::appendStdOut(T value) +{ + cout << value << " "; +} + +bool CAmLogContextStdOut::configure(const am_LogLevel_e loglevel) +{ + if ((mLogStatus == LS_OFF) || (loglevel > mLogLevel)) + { + return false; + } + + pthread_mutex_lock(&gStdOutMtx); + + switch (loglevel) + { + case LL_ERROR: + cout << mHeader << CC_RED; + break; + case LL_WARN: + cout << mHeader << CC_YELLOW; + break; + default: + cout << mHeader << CC_RESET; + break; + } + + return true; +} + +bool CAmLogContextStdOut::checkLogLevel(const am_LogLevel_e logLevel) +{ + return ((mLogStatus == LS_ON) && (logLevel <= mLogLevel)); +} + +void CAmLogContextStdOut::send() +{ + // NOTE: The color is set in the configure function + cout << CC_RESET << endl; + pthread_mutex_unlock(&gStdOutMtx); +} + +CAmLoggerStdOut::CAmLoggerStdOut(const am_LogStatus_e status, const bool onlyError) + : mLogStatus(status) + , mStandardLogLevel(onlyError ? LL_ERROR : LL_INFO) +{ + if (mLogStatus == LS_OFF) + { + cout << mHeader << "Running without Logging support" << endl; + } +} + +CAmLoggerStdOut::~CAmLoggerStdOut() +{ + unregisterApp(); +} + +void CAmLoggerStdOut::unregisterApp() +{ + for (auto &&context : mCtxTable) + { + unregisterContext(context.first); + } +} + +void CAmLoggerStdOut::registerApp(const char *appid, const char *description) +{ + if (mLogStatus == LS_ON) + { + cout << mHeader << "Register Application " << string(appid, PADDING_WIDTH) << ", " << description << endl; + } + + registerContext(DEFAULT_CONTEXT, DEFAULT_DESCRIPTION); +} + +IAmLogContext &CAmLoggerStdOut::registerContext(const char *contextid, const char *description) +{ + return registerContext(contextid, description, mStandardLogLevel, mLogStatus); +} + +IAmLogContext &CAmLoggerStdOut::registerContext(const char *contextid, const char *description, + const am_LogLevel_e level, const am_LogStatus_e status) +{ + // check, if we already have this context + for (auto &ctx : mCtxTable) + { + if (contextid && strncmp(contextid, ctx.first, PADDING_WIDTH) == 0) + { + ctx.second->changeLogLS(level, status); + return *ctx.second; + } + } + + // Not in list. Create new + if (mLogStatus == LS_ON) + { + cout << mHeader << "Registering Context " << string(contextid, PADDING_WIDTH) << ", " << description << endl; + } + size_t len = (contextid ? strlen(contextid) : 0); + char *pKey = new char[1 + len]; + strncpy(pKey, contextid, len); + pKey[len] = '\0'; + auto *pContext = new CAmLogContextStdOut(contextid, level, status); + pContext->changeLogLS(level, status); + mCtxTable[pKey] = pContext; + + return *pContext; +} + +IAmLogContext &CAmLoggerStdOut::importContext(const char *contextid) +{ + // check, if we have this context + contextid = (contextid ? contextid : DEFAULT_CONTEXT); + for (auto &ctx : mCtxTable) + { + if (contextid && strncmp(ctx.first, contextid, PADDING_WIDTH) == 0) + { + return *ctx.second; + } + } + + // no match. Fall back to default context + return importContext(DEFAULT_CONTEXT); +} + +void CAmLoggerStdOut::unregisterContext(const char *contextid) +{ + for (auto it = mCtxTable.begin(); it != mCtxTable.end(); ++it) + { + if (contextid && strncmp(contextid, it->first, PADDING_WIDTH) == 0) + { + delete it->second; + const char *key = it->first; + mCtxTable.erase(it); + delete key; + + if (mLogStatus == LS_ON) + { + cout << mHeader << string(contextid, PADDING_WIDTH) << " unregistered" << endl; + } + + return; + } + } +} + +} diff --git a/Foo/uncrustify_files.cfg b/Foo/uncrustify_files.cfg index c422173..b0ca445 100644 --- a/Foo/uncrustify_files.cfg +++ b/Foo/uncrustify_files.cfg @@ -1,5 +1,9 @@ ./AudioManagerUtilities/src/CAmCommonAPIWrapper.cpp ./AudioManagerUtilities/src/CAmDltWrapper.cpp +./AudioManagerUtilities/src/CAmLogWrapper.cpp +./AudioManagerUtilities/src/CAmLoggerDlt.cpp +./AudioManagerUtilities/src/CAmLoggerFile.cpp +./AudioManagerUtilities/src/CAmLoggerStdOut.cpp ./AudioManagerUtilities/src/CAmSocketHandler.cpp ./AudioManagerUtilities/src/CAmDbusWrapper.cpp ./AudioManagerUtilities/src/CAmCommandLineSingleton.cpp @@ -18,6 +22,12 @@ ./AudioManagerUtilities/include/CAmDbusWrapper.h ./AudioManagerUtilities/include/CAmSerializer.h ./AudioManagerUtilities/include/CAmDltWrapper.h +./AudioManagerUtilities/include/IAmLogger.h +./AudioManagerUtilities/include/CAmLogWrapper.h +./AudioManagerUtilities/include/CAmTimeUtility.h +./AudioManagerUtilities/include/CAmLoggerDlt.h +./AudioManagerUtilities/include/CAmLoggerFile.h +./AudioManagerUtilities/include/CAmLoggerStdOut.h ./AudioManagerUtilities/include/CAmWatchdog.h ./AudioManagerUtilities/include/TAmPluginTemplate.h ./AudioManagerUtilities/include/CAmCommandLineSingleton.h -- cgit v1.2.1