// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // 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/. #include #include #include #include #include #ifdef ANDROID #include #ifdef ALOGE #undef ALOGE #endif #define ALOGE(LOG_TAG, ...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) #ifndef LOGE #define LOGE ALOGE #endif #ifdef ALOGW #undef ALOGW #endif #define ALOGW(LOG_TAG, ...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) #ifndef LOGE #define LOGW ALOGW #endif #ifdef ALOGI #undef ALOGI #endif #define ALOGI(LOG_TAG, ...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) #ifndef LOGE #define LOGI ALOGI #endif #ifdef ALOGD #undef ALOGD #endif #define ALOGD(LOG_TAG, ...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) #ifndef LOGE #define LOGD ALOGD #endif #ifdef ALOGV #undef ALOGV #endif #define ALOGV(LOG_TAG, ...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) #ifndef LOGE #define LOGV ALOGV #endif #endif #include #include #include "../include/logger_impl.hpp" #include "../../configuration/include/configuration.hpp" namespace vsomeip_v3 { namespace logger { std::mutex message::mutex__; message::message(level_e _level) : std::ostream(&buffer_), level_(_level) { when_ = std::chrono::system_clock::now(); } message::~message() try { std::lock_guard its_lock(mutex__); auto its_logger = logger_impl::get(); auto its_configuration = its_logger->get_configuration(); if (!its_configuration) return; if (level_ > its_configuration->get_loglevel()) return; if (its_configuration->has_console_log() || its_configuration->has_file_log()) { // Prepare log level const char *its_level; switch (level_) { case level_e::LL_FATAL: its_level = "fatal"; break; case level_e::LL_ERROR: its_level = "error"; break; case level_e::LL_WARNING: its_level = "warning"; break; case level_e::LL_INFO: its_level = "info"; break; case level_e::LL_DEBUG: its_level = "debug"; break; case level_e::LL_VERBOSE: its_level = "verbose"; break; default: its_level = "none"; }; // Prepare time stamp auto its_time_t = std::chrono::system_clock::to_time_t(when_); struct tm its_time; localtime_r(&its_time_t, &its_time); auto its_ms = (when_.time_since_epoch().count() / 100) % 1000000; if (its_configuration->has_console_log()) { #ifndef ANDROID std::cout << std::dec << std::setw(4) << its_time.tm_year + 1900 << "-" << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_mon + 1 << "-" << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_mday << " " << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_hour << ":" << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_min << ":" << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_sec << "." << std::dec << std::setw(6) << std::setfill('0') << its_ms << " [" << its_level << "] " << buffer_.data_.str() << std::endl; #else std::string app = runtime::get_property("LogApplication"); switch (level_) { case level_e::LL_FATAL: ALOGE(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; case level_e::LL_ERROR: ALOGE(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; case level_e::LL_WARNING: ALOGW(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; case level_e::LL_INFO: ALOGI(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; case level_e::LL_DEBUG: ALOGD(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; case level_e::LL_VERBOSE: ALOGV(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; default: ALOGI(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); }; #endif // !ANDROID } if (its_configuration->has_file_log()) { std::ofstream its_logfile( its_configuration->get_logfile(), std::ios_base::app); if (its_logfile.is_open()) { its_logfile << std::dec << std::setw(4) << its_time.tm_year + 1900 << "-" << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_mon + 1 << "-" << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_mday << " " << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_hour << ":" << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_min << ":" << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_sec << "." << std::dec << std::setw(6) << std::setfill('0') << its_ms << " [" << its_level << "] " << buffer_.data_.str() << std::endl; } } } if (its_configuration->has_dlt_log()) { #ifdef USE_DLT #ifndef ANDROID its_logger->log(level_, buffer_.data_.str().c_str()); #endif #endif // USE_DLT } } catch (const std::exception& e) { std::cout << "\nVSIP: Error destroying message class: " << e.what() << '\n'; } std::streambuf::int_type message::buffer::overflow(std::streambuf::int_type c) { if (c != EOF) { data_ << (char)c; } return (c); } std::streamsize message::buffer::xsputn(const char *s, std::streamsize n) { data_.write(s, n); return (n); } } // namespace logger } // namespace vsomeip_v3