From aea0215de2cda5095f24790388105fa8f5bc53b5 Mon Sep 17 00:00:00 2001 From: jparisu Date: Wed, 16 Nov 2022 14:27:11 +0100 Subject: [PATCH 1/4] Implement Custom LogConsumer for filter by kind and category in our way Signed-off-by: jparisu --- .../logging/CustomStdLogConsumer.hpp | 69 +++++++++++++++ .../cpp_utils/macros/custom_enumeration.hpp | 5 +- .../src/cpp/logging/CustomStdLogConsumer.cpp | 87 +++++++++++++++++++ 3 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 cpp_utils/include/cpp_utils/logging/CustomStdLogConsumer.hpp create mode 100644 cpp_utils/src/cpp/logging/CustomStdLogConsumer.cpp diff --git a/cpp_utils/include/cpp_utils/logging/CustomStdLogConsumer.hpp b/cpp_utils/include/cpp_utils/logging/CustomStdLogConsumer.hpp new file mode 100644 index 00000000..a4b091ec --- /dev/null +++ b/cpp_utils/include/cpp_utils/logging/CustomStdLogConsumer.hpp @@ -0,0 +1,69 @@ +// Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file CustomStdLogConsumer.hpp + */ + +#pragma once + +#include + +#include +#include + +namespace eprosima { +namespace utils { + +/** + * TODO + */ +class CustomStdLogConsumer : public utils::LogConsumer +{ +public: + + CPP_UTILS_DllAPI CustomStdLogConsumer( + const std::string& log_filter, + const eprosima::fastdds::dds::Log::Kind& log_verbosity); + + //! Default destructor + CPP_UTILS_DllAPI ~CustomStdLogConsumer() noexcept = default; + + /** + * @brief Implements \c LogConsumer \c Consume method. + * + * Each entry is filtered by a regex done by \c filter_ and must be equal or higher the + * verbosity level \c verbosity_ . + * This method will print the \c entry in std::cout with info verbosity and in std:cerr otherwise. + * + * @param entry entry to consume + */ + CPP_UTILS_DllAPI void Consume( + const Log::Entry& entry) override; + +protected: + + CPP_UTILS_DllAPI virtual bool accept_entry_( + const Log::Entry& entry); + + CPP_UTILS_DllAPI virtual std::ostream& get_stream_( + const Log::Entry& entry); + + std::regex filter_; + + eprosima::fastdds::dds::Log::Kind verbosity_; +}; + +} /* namespace utils */ +} /* namespace eprosima */ diff --git a/cpp_utils/include/cpp_utils/macros/custom_enumeration.hpp b/cpp_utils/include/cpp_utils/macros/custom_enumeration.hpp index fd3fe160..8bf23a8b 100644 --- a/cpp_utils/include/cpp_utils/macros/custom_enumeration.hpp +++ b/cpp_utils/include/cpp_utils/macros/custom_enumeration.hpp @@ -69,6 +69,9 @@ namespace utils { /* To string method */ \ inline const std::string& to_string(const enumeration_name& e) \ { return names_ ## enumeration_name[static_cast(e)]; } \ + \ + inline std::vector string_vector_ ## enumeration_name() \ + { return std::vector (names_ ## enumeration_name.begin(), names_ ## enumeration_name.end()); } \ \ /* From string */ \ inline enumeration_name from_string_ ## enumeration_name(const std::string& s) \ @@ -89,5 +92,3 @@ namespace utils { } /* namespace utils */ } /* namespace eprosima */ - - diff --git a/cpp_utils/src/cpp/logging/CustomStdLogConsumer.cpp b/cpp_utils/src/cpp/logging/CustomStdLogConsumer.cpp new file mode 100644 index 00000000..d4abe8ea --- /dev/null +++ b/cpp_utils/src/cpp/logging/CustomStdLogConsumer.cpp @@ -0,0 +1,87 @@ +// Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file CustomStdLogConsumer.cpp + * + */ + +#include + +namespace eprosima { +namespace utils { + +CustomStdLogConsumer::CustomStdLogConsumer( + const std::string& log_filter, + const eprosima::fastdds::dds::Log::Kind& log_verbosity) + : filter_(log_filter) + , verbosity_(log_verbosity) +{ + // Do nothing +} + +void CustomStdLogConsumer::Consume( + const utils::Log::Entry& entry) +{ + if (accept_entry_(entry)) + { + std::ostream& stream = get_stream_(entry); + print_timestamp(stream, entry, true); + print_header(stream, entry, true); + print_message(stream, entry, true); + print_context(stream, entry, true); + print_new_line(stream, true); + stream.flush(); + } +} + +bool CustomStdLogConsumer::accept_entry_( + const Log::Entry& entry) +{ + // Filter by kind + if (entry.kind > verbosity_) + { + return false; + } + else if (entry.kind == eprosima::fastdds::dds::Log::Kind::Error && + entry.kind < verbosity_) + { + // In case it is an error message and verbosity is not error, filter does not care + return true; + } + + // Filter by regex + if (!std::regex_search(entry.context.category, filter_)) + { + return false; + } + + return true; +} + +std::ostream& CustomStdLogConsumer::get_stream_( + const Log::Entry& entry) +{ + if (entry.kind < eprosima::fastdds::dds::Log::Kind::Warning) + { + return std::cout; + } + else + { + return std::cerr; + } +} + +} /* namespace utils */ +} /* namespace eprosima */ From 3f7a6d8ea288b931505029a48b66ec933aaed4be Mon Sep 17 00:00:00 2001 From: jparisu Date: Wed, 16 Nov 2022 14:34:25 +0100 Subject: [PATCH 2/4] Add documentation Signed-off-by: jparisu --- .../logging/CustomStdLogConsumer.hpp | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/cpp_utils/include/cpp_utils/logging/CustomStdLogConsumer.hpp b/cpp_utils/include/cpp_utils/logging/CustomStdLogConsumer.hpp index a4b091ec..e7de1e6c 100644 --- a/cpp_utils/include/cpp_utils/logging/CustomStdLogConsumer.hpp +++ b/cpp_utils/include/cpp_utils/logging/CustomStdLogConsumer.hpp @@ -27,12 +27,20 @@ namespace eprosima { namespace utils { /** - * TODO + * Custom Log Consumer with Standard (logical) behaviour. + * + * Registering this consumer in Fast DDS Log prints every log entry that has a more important kind that the threshold + * given. In case messages are not of Error kind, they are filtered by category to match a regex. + * Info messages are printed in std::cout while others are sent to std::cerr . + * + * @attention This consumer filters the entries that receives, but some other entries could be filtered beforehand + * by Fast DDS Log. To avoid these, set Log verbosity to Info and do not use Category Filter. */ class CustomStdLogConsumer : public utils::LogConsumer { public: + //! Create new CustomStdLogConsumer with regex filter generated from a string and with maximum verbosity kind. CPP_UTILS_DllAPI CustomStdLogConsumer( const std::string& log_filter, const eprosima::fastdds::dds::Log::Kind& log_verbosity); @@ -43,9 +51,11 @@ class CustomStdLogConsumer : public utils::LogConsumer /** * @brief Implements \c LogConsumer \c Consume method. * - * Each entry is filtered by a regex done by \c filter_ and must be equal or higher the - * verbosity level \c verbosity_ . - * This method will print the \c entry in std::cout with info verbosity and in std:cerr otherwise. + * Each entry must be equal or higher the verbosity level \c verbosity_ . + * Each entry category must match with regex stored in \c filter_ , except + * those entries that are Error will be always printed if \c verbosity_ is not Error. + * + * This method will print the \c entry in \c std::cout with info verbosity and in \c std:cerr otherwise. * * @param entry entry to consume */ @@ -54,14 +64,24 @@ class CustomStdLogConsumer : public utils::LogConsumer protected: + //! Whether the entry must be accepted depending on kind and category CPP_UTILS_DllAPI virtual bool accept_entry_( const Log::Entry& entry); + /** + * @brief Get which stream must be used depending on the entry + * + * @param entry to decide the output stream + * + * @return \c std::out if entry is Info, \c std::cerr otherwise. + */ CPP_UTILS_DllAPI virtual std::ostream& get_stream_( const Log::Entry& entry); + //! Regex filter for entry category std::regex filter_; + //! Maximum Log Kind that will be printed. eprosima::fastdds::dds::Log::Kind verbosity_; }; From bed26a531864ff1719d4231eb72554cfb4598fe4 Mon Sep 17 00:00:00 2001 From: jparisu Date: Fri, 18 Nov 2022 09:41:37 +0100 Subject: [PATCH 3/4] apply suggestions Signed-off-by: jparisu --- cpp_utils/include/cpp_utils/logging/CustomStdLogConsumer.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp_utils/include/cpp_utils/logging/CustomStdLogConsumer.hpp b/cpp_utils/include/cpp_utils/logging/CustomStdLogConsumer.hpp index e7de1e6c..aeea83ea 100644 --- a/cpp_utils/include/cpp_utils/logging/CustomStdLogConsumer.hpp +++ b/cpp_utils/include/cpp_utils/logging/CustomStdLogConsumer.hpp @@ -29,7 +29,7 @@ namespace utils { /** * Custom Log Consumer with Standard (logical) behaviour. * - * Registering this consumer in Fast DDS Log prints every log entry that has a more important kind that the threshold + * Registering this consumer in Fast DDS Log prints every log entry that has a higher kind than the threshold * given. In case messages are not of Error kind, they are filtered by category to match a regex. * Info messages are printed in std::cout while others are sent to std::cerr . * From c25f57e3ee048a0dcc57907df951b830779fafc2 Mon Sep 17 00:00:00 2001 From: jparisu Date: Fri, 18 Nov 2022 09:41:41 +0100 Subject: [PATCH 4/4] uncrustify Signed-off-by: jparisu --- cpp_utils/src/cpp/logging/CustomStdLogConsumer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp_utils/src/cpp/logging/CustomStdLogConsumer.cpp b/cpp_utils/src/cpp/logging/CustomStdLogConsumer.cpp index d4abe8ea..2b02bdbb 100644 --- a/cpp_utils/src/cpp/logging/CustomStdLogConsumer.cpp +++ b/cpp_utils/src/cpp/logging/CustomStdLogConsumer.cpp @@ -55,7 +55,7 @@ bool CustomStdLogConsumer::accept_entry_( return false; } else if (entry.kind == eprosima::fastdds::dds::Log::Kind::Error && - entry.kind < verbosity_) + entry.kind < verbosity_) { // In case it is an error message and verbosity is not error, filter does not care return true;