diff options
author | Lutz Bichler <Lutz.Bichler@bmw.de> | 2015-04-08 07:44:06 +0200 |
---|---|---|
committer | Lutz Bichler <Lutz.Bichler@bmw.de> | 2015-04-08 07:44:06 +0200 |
commit | 0c1019e6f347e41c371fbd0996b41b73e78d08ff (patch) | |
tree | e8bdea9bdd9080701bcb4d9ad806a89e89a69165 | |
parent | 8d2271465d28702dd7ca95bb39f30a771b0f8f1a (diff) | |
parent | 4148db77ef54a6ad33307b8474f5dfa44d82b0ac (diff) | |
download | genivi-common-api-runtime-0c1019e6f347e41c371fbd0996b41b73e78d08ff.tar.gz |
Merge branch 'pu/logging' into maintain/3.0
-rw-r--r-- | include/CommonAPI/Logger.hpp | 87 | ||||
-rw-r--r-- | include/CommonAPI/Utils.hpp | 191 | ||||
-rw-r--r-- | src/CommonAPI/IniFileReader.cpp | 35 | ||||
-rw-r--r-- | src/CommonAPI/Runtime.cpp | 18 | ||||
-rw-r--r-- | src/CommonAPI/Utils.cpp | 164 |
5 files changed, 125 insertions, 370 deletions
diff --git a/include/CommonAPI/Logger.hpp b/include/CommonAPI/Logger.hpp index 95117dd..4c34b62 100644 --- a/include/CommonAPI/Logger.hpp +++ b/include/CommonAPI/Logger.hpp @@ -7,17 +7,75 @@ #ifndef COMMONAPI_LOGGER_HPP_ #define COMMONAPI_LOGGER_HPP_ +#include <cstdint> #include <iostream> #include <memory> +#define COMMONAPI_LOGLEVEL_FATAL 0 +#define COMMONAPI_LOGLEVEL_ERROR 1 +#define COMMONAPI_LOGLEVEL_WARNING 2 +#define COMMONAPI_LOGLEVEL_INFO 3 +#define COMMONAPI_LOGLEVEL_DEBUG 4 +#define COMMONAPI_LOGLEVEL_VERBOSE 5 + +#ifndef COMMONAPI_LOGLEVEL +#define COMMONAPI_LOGLEVEL COMMONAPI_LOGLEVEL_INFO +#endif + +#define COMMONAPI_FATAL(params...) \ + do { Logger::log(Logger::Level::FATAL, params); } while (false); + +#if COMMONAPI_LOGLEVEL >= COMMONAPI_LOGLEVEL_ERROR + #define COMMONAPI_ERROR(params...) \ + do { Logger::log(Logger::Level::ERROR, params); } while (false); +#else + #define COMMONAPI_ERROR(params...) +#endif + +#if COMMONAPI_LOGLEVEL >= COMMONAPI_LOGLEVEL_WARNING + #define COMMONAPI_WARNING(params...) \ + do { Logger::log(Logger::Level::WARNING, params); } while (false); +#else + #define COMMONAPI_WARNING(params...) +#endif + +#if COMMONAPI_LOGLEVEL >= COMMONAPI_LOGLEVEL_INFO + #define COMMONAPI_INFO(params...) \ + do { Logger::log(Logger::Level::INFO, params); } while (false); +#else + #define COMMONAPI_INFO(params...) +#endif + +#if COMMONAPI_LOGLEVEL >= COMMONAPI_LOGLEVEL_DEBUG + #define COMMONAPI_DEBUG(params...) \ + do { Logger::log(Logger::Level::DEBUG, params); } while (false); +#else + #define COMMONAPI_DEBUG(params...) +#endif + +#if COMMONAPI_LOGLEVEL >= COMMONAPI_LOGLEVEL_VERBOSE + #define COMMONAPI_VERBOSE(params...) \ + do { Logger::log(Logger::Level::VERBOSE, params); } while (false); +#else + #define COMMONAPI_VERBOSE(params...) +#endif + namespace CommonAPI { class Logger { public: + enum class Level : uint8_t { + FATAL = 0, ERROR = 1, WARNING = 2, INFO = 3, DEBUG = 4, VERBOSE = 5 + }; + + Logger(); + template<typename... _LogEntries> - static void log(_LogEntries... _entries) { - std::cout << "[CAPI] "; - Logger::get()->log_intern(_entries...); + static void log(Level _level, _LogEntries... _entries) { + if (Logger::get()->useConsole_) { + std::cout << "[CAPI " << Logger::get()->level_as_string(_level) << "] "; + Logger::get()->log_intern(_entries...); + } } private: @@ -36,6 +94,29 @@ private: log_intern(_moreEntries...); } + std::string level_as_string(Level _level) { + switch (_level) { + case Level::FATAL: + return "FATAL"; + case Level::ERROR: + return "ERROR"; + case Level::WARNING: + return "WARNING"; + case Level::INFO: + return "INFO"; + case Level::DEBUG: + return "DEBUG"; + case Level::VERBOSE: + return "VERBOSE"; + default: + return ""; + } + } + + bool useConsole_; + bool useFile_; + bool useDlt_; + Level maximumLogLevel_; }; } // namespace CommonAPI diff --git a/include/CommonAPI/Utils.hpp b/include/CommonAPI/Utils.hpp index b8f38b0..efdbca6 100644 --- a/include/CommonAPI/Utils.hpp +++ b/include/CommonAPI/Utils.hpp @@ -36,198 +36,9 @@ namespace CommonAPI { - -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) -# define COMMONAPI_DEPRECATED __attribute__ ((__deprecated__)) -#elif defined(_MSC_VER) && (_MSC_VER >= 1300) -# define COMMONAPI_DEPRECATED __declspec(deprecated) -#else -# define COMMONAPI_DEPRECATED -#endif - - -/** - * \brief Returns the fully qualified name of the binary. - * - * @return The name of the currently executing binary. - */ -std::string getCurrentBinaryFileFQN(); - -/** - * \brief Splits a std::string according to the given delim-char. - * - * The string will be splitted at each position the delim char is encountered. The delim itself - * will be removed from the result. - * - * @param s: The string that is to be splitted - * @param delim: The character that separates the resulting string tokens in the original string - * @param elems: Reference to the vector that shall be filled with the splitted string elements. - * - * @return A reference to the vector you passed in (elems) - */ -std::vector<std::string>& split(const std::string& s, char delim, std::vector<std::string>& elems); - -/** - * \brief Splits a std::string according to the given delim-char. - * - * The string will be splitted at each position the delim char is encountered. The delim itself - * will be removed from the result. - * - * @param s: The string that is to be splitted - * @param delim: The character that separates the resulting string tokens in the original string - * - * @return A vector containing the splitted string elements. - */ std::vector<std::string> split(const std::string& s, char delim); - -inline bool isspace(char c) { - return std::isspace(c, std::locale()); -} - -/** - * \brief Trims whitespaces from beginning and end of a std::string. - * - * @param toTrim: The string that is to be trimmed. - */ -void trim(std::string& toTrim); - -bool notIsdigit(char c); - -/** - * \brief Checks whether the given string contains nothing but digits. - * - * @param toCheck: The string that is to be checked on the presence of anything but digits. - * - * @return true if toCheck contains nothing but digits, false otherwise. - */ -bool containsOnlyDigits(const std::string& toCheck); - -bool notIsalnum(char c); - -/** - * \brief Checks whether the given string contains nothing but alphanumeric characters. - * - * @param toCheck: The string that is to be checked on the presence of anything but alphanumeric characters. - * - * @return true if toCheck contains nothing but alphanumeric characters, false otherwise. - */ -bool containsOnlyAlphanumericCharacters(const std::string& toCheck); - -/** - * \brief Checks whether the given std::string is a valid CommonAPI domain name. - * - * @param domainName: The std::string that is to be checked. - * - * @return true if domainName is a valid CommonAPI domainName, false otherwise. - */ -bool isValidDomainName(const std::string& domainName); - -/** - * \brief Checks whether the given std::string is a valid CommonAPI service name. - * - * @param serviceName: The std::string that is to be checked. - * - * @return true if serviceName is a valid CommonAPI serviceName, false otherwise. - */ -bool isValidServiceName(const std::string& serviceName); - -/** - * \brief Checks whether the given std::string is a valid CommonAPI instance ID. - * - * @param instanceId: The std::string that is to be checked. - * - * @return true if instanceId is a valid CommonAPI instance ID, false otherwise. - */ -bool isValidInstanceId(const std::string& instanceId); - -/** - * \brief Checks whether the given std::string is a valid CommonAPI address. - * - * @param commonApiAddressName: The std::string that is to be checked. - * - * @return true if commonApiAddress is a valid CommonAPI address, false otherwise. - */ -bool isValidCommonApiAddress(const std::string& commonApiAddress); - -#ifndef WIN32 -/** - * \brief Loads a specific generic library at runtime. - * - * The library will be loaded using dlopen(3) with the flags (RTLD_NOW | RTLD_GLOBAL), if all pre-checks are - * successful. Pre-checks include the verification that the given parameters actually point to a library and - * optionally if the library matches the standard name pattern for CommonAPI generic libraries. The standard - * name pattern is "lib<wellKnownMiddlewareName>Gen-<arbitraryName>.so[.major[.minor.revision]]". - * - * @param wellKnownMiddlewareName: The name of the middleware that requests the loading of the library. - * @param libraryName: The name of the library that shall be loaded. - * @param path: The path at which the library is to be found. path + library name together make up the fully - * qualified name of the library. - * @param checkStandardNamePattern: If set to true, it will be ensured the library matches the CommonAPI - * standard name pattern for generic libraries. This is meant as a safety measure - * to prevent the loading of unnecessary or the wrong libraries. Set to false if - * you are sure about what you are doing. - * @return true if the library could be loaded successfully, false otherwise. - * - * @note The well known middleware name is included as a parameter because the additional libraries normally are needed - * only by specific middlewares. This name however will only be taken into consideration during name checking - * if the checkStandardNamePattern flag is set to true. - */ -bool loadGenericLibrary(const std::string& wellKnownMiddlewareName, const std::string& libraryName, const std::string& path, bool checkStandardNamePattern = true); - -/** - * \brief Loads a specific generic library at runtime. - * - * The library will be loaded using dlopen(3) with the flags (RTLD_NOW | RTLD_GLOBAL), if all pre-checks are - * successful. Pre-checks include the verification that the given parameters actually point to a library and - * optionally if the library matches the standard name pattern for CommonAPI generic libraries. The standard - * name pattern is "lib<wellKnownMiddlewareName>Gen-<arbitraryName>.so[.major[.minor.revision]]". - * - * @param wellKnownMiddlewareName: The name of the middleware that requests the loading of the library. - * @param fqnOfLibrary: The fully qualified name of the library. - * @param checkStandardNamePattern: If set to true, it will be ensured the library matches the CommonAPI - * standard name pattern for generic libraries. This is meant as a safety measure - * to prevent the loading of unnecessary or the wrong libraries. Set to false if - * you are sure about what you are doing. - * @return true if the library could be loaded successfully, false otherwise. - * - * @note The well known middleware name is included as a parameter because the additional libraries normally are needed - * only by specific middlewares. This name however will only be taken into consideration during name checking - * if the checkStandardNamePattern flag is set to true. - */ -bool loadGenericLibrary(const std::string& wellKnownMiddlewareName, - const std::string& fqnOfLibrary, - bool checkStandardNamePattern = true); - -/** - * \brief Searches the given path for additional generic CommonAPI libraries and loads them. - * - * All libraries for which the pre-checks are successful will be loaded using dlopen(3) with the flags - * (RTLD_NOW | RTLD_GLOBAL). Pre-checks include the verification that the given parameters actually point - * to a library and if the library matches the standard name pattern for CommonAPI generic libraries. - * The standard name pattern is "lib<wellKnownMiddlewareName>Gen-<arbitraryName>.so[.major[.minor.revision]]". - * - * @param wellKnownMiddlewareName: The name of the middleware that requests the loading of the library. Will - * be used to perform the name check. - * @param singleSearchPath: The directory that is to be searched for libraries. - */ -void findAndLoadGenericLibraries(const std::string& requestedMiddlewareName, const std::string& singleSearchPath); - -/** - * \brief Searches the given paths for additional generic CommonAPI libraries and loads them. - * - * All libraries for which the pre-checks are successful will be loaded using dlopen(3) with the flags - * (RTLD_NOW | RTLD_GLOBAL). Pre-checks include the verification that the given parameters actually point - * to a library and if the library matches the standard name pattern for CommonAPI generic libraries. - * The standard name pattern is "lib<wellKnownMiddlewareName>Gen-<arbitraryName>.so[.major[.minor.revision]]". - * - * @param wellKnownMiddlewareName: The name of the middleware that requests the loading of the library. Will - * be used to perform the name check. - * @param searchPaths: The directories that are to be searched for libraries. - */ -void findAndLoadGenericLibraries(const std::string& requestedMiddlewareName, const std::vector<std::string>& searchPaths); -#endif +void trim(std::string &_s); } //namespace CommonAPI - #endif /* COMMONAPI_UTILS_HPP_ */ diff --git a/src/CommonAPI/IniFileReader.cpp b/src/CommonAPI/IniFileReader.cpp index d61e3e5..ab9ab62 100644 --- a/src/CommonAPI/IniFileReader.cpp +++ b/src/CommonAPI/IniFileReader.cpp @@ -31,7 +31,7 @@ bool IniFileReader::load(const std::string &_path) { std::ifstream configStream(_path); if (configStream.is_open()) { - Logger::log("Loading ini file from ", _path); + COMMONAPI_INFO("Loading ini file from ", _path); int lineCounter(0); std::string currentSectionName; @@ -55,17 +55,16 @@ IniFileReader::load(const std::string &_path) { sections_[currentSectionName] = currentSection; } } else { - Logger::log("Double definition of section \'", - currentSectionName, - "\' ignoring definition (line ", - lineCounter, - ")"); + COMMONAPI_ERROR("Double definition of section \'", + currentSectionName, + "\' ignoring definition (line ", + lineCounter, + ")"); currentSection = nullptr; } } else { - // TODO: use error instead of log - Logger::log("Missing \']\' in section definition (line ", - lineCounter, ")"); + COMMONAPI_ERROR("Missing \']\' in section definition (line ", + lineCounter, ")"); } } else if (currentSection) { std::size_t pos = line.find('='); @@ -74,21 +73,21 @@ IniFileReader::load(const std::string &_path) { trim(key); if (currentSection->mappings_.end() != currentSection->mappings_.find(key)) { - Logger::log("Double definition for key \'", - key, - "'\' in section \'", - currentSectionName, - "\' (line ", - lineCounter, - ")"); + COMMONAPI_ERROR("Double definition for key \'", + key, + "'\' in section \'", + currentSectionName, + "\' (line ", + lineCounter, + ")"); } else { std::string value = line.substr(pos+1); trim(value); currentSection->mappings_[key] = value; } } else if (line.size() > 0) { - Logger::log("Missing \'=\' in key=value definition (line ", - lineCounter, ")"); + COMMONAPI_ERROR("Missing \'=\' in key=value definition (line ", + lineCounter, ")"); } } } diff --git a/src/CommonAPI/Runtime.cpp b/src/CommonAPI/Runtime.cpp index 3532353..fdd108f 100644 --- a/src/CommonAPI/Runtime.cpp +++ b/src/CommonAPI/Runtime.cpp @@ -44,7 +44,7 @@ Runtime::~Runtime() { bool Runtime::registerFactory(const std::string &_binding, std::shared_ptr<Factory> _factory) { - Logger::log("Registering factory for binding=", _binding); + COMMONAPI_DEBUG("Registering factory for binding=", _binding); bool isRegistered(false); std::lock_guard<std::mutex> itsLock(factoriesMutex_); auto foundFactory = factories_.find(_binding); @@ -87,9 +87,9 @@ void Runtime::init() { defaultFolder_ = folder; // Log settings - Logger::log("Using default binding \'", defaultBinding_, "\'"); - Logger::log("Using default shared library folder \'", defaultFolder_, "\'"); - Logger::log("Using default configuration file \'", defaultConfig_, "\'"); + COMMONAPI_INFO("Using default binding \'", defaultBinding_, "\'"); + COMMONAPI_INFO("Using default shared library folder \'", defaultFolder_, "\'"); + COMMONAPI_INFO("Using default configuration file \'", defaultConfig_, "\'"); } bool @@ -131,7 +131,7 @@ Runtime::readConfiguration() { section = reader.getSection("proxy"); if (section) { for (auto m : section->getMappings()) { - Logger::log("Adding proxy mapping: ", m.first, " --> ", m.second); + COMMONAPI_DEBUG("Adding proxy mapping: ", m.first, " --> ", m.second); libraries_[m.first][true] = m.second; } } @@ -139,7 +139,7 @@ Runtime::readConfiguration() { section = reader.getSection("stub"); if (section) { for (auto m : section->getMappings()) { - Logger::log("Adding stub mapping: ", m.first, " --> ", m.second); + COMMONAPI_DEBUG("Adding stub mapping: ", m.first, " --> ", m.second); libraries_[m.first][false] = m.second; } } @@ -269,7 +269,7 @@ Runtime::getLibrary( std::string address = _domain + ":" + _interface + ":" + _instance; - Logger::log("Loading proxy library for ", address); + COMMONAPI_DEBUG("Loading proxy library for ", address); auto libraryIterator = libraries_.find(address); if (libraryIterator != libraries_.end()) { @@ -310,10 +310,10 @@ Runtime::loadLibrary(const std::string &_library) { #else if (dlopen(itsLibrary.c_str(), RTLD_LAZY | RTLD_GLOBAL) != 0) { loadedLibraries_.insert(itsLibrary); - Logger::log("Loading interface library \"", itsLibrary, "\" succeeded."); + COMMONAPI_DEBUG("Loading interface library \"", itsLibrary, "\" succeeded."); } else { - Logger::log("Loading interface library \"", itsLibrary, "\" failed (", dlerror(), ")"); + COMMONAPI_ERROR("Loading interface library \"", itsLibrary, "\" failed (", dlerror(), ")"); isLoaded = false; } #endif diff --git a/src/CommonAPI/Utils.cpp b/src/CommonAPI/Utils.cpp index 6f2aeba..26de71c 100644 --- a/src/CommonAPI/Utils.cpp +++ b/src/CommonAPI/Utils.cpp @@ -8,27 +8,6 @@ #include <CommonAPI/Utils.hpp> namespace CommonAPI { -std::string getCurrentBinaryFileFQN() { - #ifdef WIN32 - TCHAR result[MAX_PATH]; - std::basic_string<TCHAR> resultString(result, GetModuleFileName(NULL, result, MAX_PATH)); - return std::string(resultString.begin(), resultString.end()); - #else - char fqnOfBinary[FILENAME_MAX]; - char pathToProcessImage[FILENAME_MAX]; - - sprintf(pathToProcessImage, "/proc/%d/exe", getpid()); - const ssize_t lengthOfFqn = readlink(pathToProcessImage, fqnOfBinary, sizeof(fqnOfBinary) - 1); - - if (lengthOfFqn != -1) { - fqnOfBinary[lengthOfFqn] = '\0'; - return std::string(std::move(fqnOfBinary)); - } - else { - return std::string(""); - } - #endif - } std::vector<std::string>& split(const std::string& s, char delim, std::vector<std::string>& elems) { std::istringstream ss(s); @@ -46,136 +25,21 @@ std::vector<std::string> split(const std::string& s, char delim) { void trim(std::string& toTrim) { toTrim.erase( - toTrim.begin(), - std::find_if(toTrim.begin(), - toTrim.end(), - std::not1(std::ptr_fun(isspace))) - ); - toTrim.erase( - std::find_if(toTrim.rbegin(), - toTrim.rend(), - std::not1(std::ptr_fun(isspace))).base(), - toTrim.end() - ); -} - -bool notIsdigit(char c) { - return !std::isdigit(c, std::locale()); -} - -bool containsOnlyDigits(const std::string& toCheck) { - auto firstNonDigitIt = std::find_if( - toCheck.begin(), - toCheck.end(), - notIsdigit); - - return firstNonDigitIt == toCheck.end(); -} - -bool notIsalnum(char c) { - return !std::isalnum(c, std::locale()); -} - -bool containsOnlyAlphanumericCharacters(const std::string& toCheck) { - auto firstNonAlphanumericCharacterIt = std::find_if( - toCheck.begin(), - toCheck.end(), - notIsalnum); - - return firstNonAlphanumericCharacterIt == toCheck.end(); -} - -bool isValidDomainName(const std::string& domainName) { - return containsOnlyAlphanumericCharacters(domainName); -} - -bool isValidServiceName(const std::string& serviceName) { - bool isValid = serviceName[0] != '.' && serviceName[serviceName.size() - 1] != '.'; - - if (isValid) { - std::vector<std::string> splittedServiceName = split(serviceName, '.'); - - for (auto serviceNameElementIt = splittedServiceName.begin(); - serviceNameElementIt != splittedServiceName.end() && isValid; - ++serviceNameElementIt) { - isValid &= containsOnlyAlphanumericCharacters(*serviceNameElementIt); - } - } - - return isValid; -} + toTrim.begin(), + std::find_if( + toTrim.begin(), + toTrim.end(), + std::not1(std::ptr_fun(isspace)) + ) + ); -bool isValidInstanceId(const std::string& instanceId) { - //Validation rules for ServiceName and InstanceID are equivalent - return isValidServiceName(instanceId); -} - -bool isValidCommonApiAddress(const std::string& commonApiAddress) { - std::vector<std::string> splittedAddress = split(commonApiAddress, ':'); - if (splittedAddress.size() != 3) { - return false; - } - return isValidDomainName(splittedAddress[0]) && isValidServiceName(splittedAddress[1]) && isValidInstanceId(splittedAddress[2]); -} - -#ifndef WIN32 -bool loadGenericLibrary(const std::string& wellKnownMiddlewareName, const std::string& libraryName, const std::string& path, bool checkStandardNamePattern) { - std::string fqnOfLibrary = path + libraryName; - struct stat filestat; - if (stat(fqnOfLibrary.c_str(), &filestat)) { - return false; - } - if (S_ISDIR(filestat.st_mode)) { - return false; - } - - if (checkStandardNamePattern) { - const std::string generatedLibPrefix = "lib" + wellKnownMiddlewareName + "Gen-"; - if (strncmp(generatedLibPrefix.c_str(), libraryName.c_str(), generatedLibPrefix.length()) != 0) { - return false; - } - - const char* fileNamePtr = libraryName.c_str(); - while ((fileNamePtr = strchr(fileNamePtr + 1, '.'))) { - if (strncmp(".so\0", fileNamePtr, 4) == 0 || strncmp(".so.", fileNamePtr, 4) == 0) { - break; - } - } - - if (!fileNamePtr) { - return false; - } - } - - dlopen(fqnOfLibrary.c_str(), RTLD_NOW | RTLD_GLOBAL); - return true; -} - -bool loadGenericLibrary(const std::string& wellKnownMiddlewareName, - const std::string& fqnOfLibrary, - bool checkStandardNamePattern) { - uint32_t position = fqnOfLibrary.find_last_of("/\\"); - std::string path = fqnOfLibrary.substr(0, position + 1); - std::string file = fqnOfLibrary.substr(position + 1); - return loadGenericLibrary(wellKnownMiddlewareName, file, path, checkStandardNamePattern); -} - -void findAndLoadGenericLibraries(const std::string& requestedMiddlewareName, const std::string& singleSearchPath) { - DIR *directory = opendir(singleSearchPath.c_str()); - - if (directory != NULL) { - struct dirent* entry; - - while ((entry = readdir(directory))) { - loadGenericLibrary(requestedMiddlewareName, entry->d_name, singleSearchPath, true); - } - } + toTrim.erase( + std::find_if( + toTrim.rbegin(), + toTrim.rend(), + std::not1(std::ptr_fun(isspace))).base(), + toTrim.end() + ); } -void findAndLoadGenericLibraries(const std::string& requestedMiddlewareName, const std::vector<std::string>& searchPaths) { - for (const std::string& singleSearchPath : searchPaths) { - findAndLoadGenericLibraries(requestedMiddlewareName, singleSearchPath.c_str()); - } -} -#endif }//namespace CommonAPI |