From 823d9ec49be4a095980577bccb0a1f9501a2a394 Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Thu, 22 Aug 2024 17:41:52 -0500 Subject: [PATCH 01/14] Update badges to point to gz-utils3 branch (#138) Signed-off-by: Addisu Z. Taddese --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7b3acb9..e083c15 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,10 @@ Build | Status -- | -- -Test coverage | [![codecov](https://codecov.io/gh/gazebosim/gz-utils/branch/main/graph/badge.svg)](https://codecov.io/gh/gazebosim/gz-utils) -Ubuntu Noble | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_utils-ci-main-noble-amd64)](https://build.osrfoundation.org/job/gz_utils-ci-main-noble-amd64) -Homebrew | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_utils-ci-main-homebrew-amd64)](https://build.osrfoundation.org/job/gz_utils-ci-main-homebrew-amd64) -Windows | [![Build Status](https://build.osrfoundation.org/job/gz_utils-main-win/badge/icon)](https://build.osrfoundation.org/job/ign_utils-ci-win/) +Test coverage | [![codecov](https://codecov.io/gh/gazebosim/gz-utils/branch/gz-utils3/graph/badge.svg)](https://app.codecov.io/gh/gazebosim/gz-utils/tree/gz-utils3) +Ubuntu Noble | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_utils-ci-gz-utils3-noble-amd64)](https://build.osrfoundation.org/job/gz_utils-ci-gz-utils3-noble-amd64) +Homebrew | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_utils-ci-gz-utils3-homebrew-amd64)](https://build.osrfoundation.org/job/gz_utils-ci-gz-utils3-homebrew-amd64) +Windows | [![Build Status](https://build.osrfoundation.org/job/gz_utils-3-win/badge/icon)](https://build.osrfoundation.org/job/gz_utils-3-win/) Gazebo Utils, a component of [Gazebo](https://gazebosim.org), provides general purpose classes and functions designed for robotic applications. @@ -53,7 +53,7 @@ See the [installation tutorial](https://gazebosim.org/api/utils/2/install.html). # Usage -Please refer to the [examples directory](https://github.com/gazebosim/gz-utils/blob/main/examples/). +Please refer to the [examples directory](https://github.com/gazebosim/gz-utils/blob/gz-utils3/examples/). # Documentation From 108a052f23d701284be8024084c975f734e0e3fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Ag=C3=BCero?= Date: Tue, 27 Aug 2024 23:23:00 +0200 Subject: [PATCH 02/14] Logger updates (#139) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * No EOL, no flush, no register in Loggers Signed-off-by: Carlos Agüero --- log/src/Logger.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/log/src/Logger.cc b/log/src/Logger.cc index 340693a..e28ec39 100644 --- a/log/src/Logger.cc +++ b/log/src/Logger.cc @@ -61,8 +61,10 @@ Logger::Logger(const std::string &_loggerName) this->dataPtr->logger->set_level(spdlog::level::err); this->dataPtr->logger->flush_on(spdlog::level::err); - spdlog::flush_every(std::chrono::seconds(5)); - spdlog::register_logger(this->dataPtr->logger); + // Disable eol. + auto f = std::make_unique( + "%+", spdlog::pattern_time_type::local, std::string("")); + this->dataPtr->logger->set_formatter(std::move(f)); } ///////////////////////////////////////////////// From 2a10be09978e5acdf2b86035c9df18e29a8333b4 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Tue, 27 Aug 2024 14:41:58 -0700 Subject: [PATCH 03/14] Prepare for 3.0.0pre2 release (#140) Signed-off-by: Ian Chen --- CMakeLists.txt | 2 +- Changelog.md | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a375316..513f3d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ find_package(gz-cmake4 REQUIRED) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -gz_configure_project(VERSION_SUFFIX pre1) +gz_configure_project(VERSION_SUFFIX pre2) #============================================================================ # Set project-specific options diff --git a/Changelog.md b/Changelog.md index 8c33e33..2621b43 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,18 @@ ## Gazebo Utils 3.0.0 (20XX-XX-XX) +1. **Baseline:** this includes all changes from 2.2.0 and earlier. + +1. Logger updates + * [Pull request #139](https://github.com/gazebosim/gz-utils/pull/139) + +1. Update badges to point to gz-utils3 branch + * [Pull request #137](https://github.com/gazebosim/gz-utils/pull/137) + * [Pull request #138](https://github.com/gazebosim/gz-utils/pull/138) + +1. Update changelog and add prepare for prereleases + * [Pull request #136](https://github.com/gazebosim/gz-utils/pull/136) + 1. Move spdlog::logger to gz-utils * [Pull request #134](https://github.com/gazebosim/gz-utils/pull/134) From f5eabdf0ff35c366b0ef740dba1d7a7a1e896233 Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Wed, 28 Aug 2024 14:34:09 -0500 Subject: [PATCH 04/14] Use common formatter for console and file sinks (#141) The severity level of the file sink is now set to trace so that it logs to file regardless of the severity level of the console. This patch also adds an API to set the severity level of just the console sink. Signed-off-by: Addisu Z. Taddese --- log/include/gz/utils/log/Logger.hh | 4 ++++ log/src/Logger.cc | 29 ++++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/log/include/gz/utils/log/Logger.hh b/log/include/gz/utils/log/Logger.hh index 3e3a491..d2cdd9a 100644 --- a/log/include/gz/utils/log/Logger.hh +++ b/log/include/gz/utils/log/Logger.hh @@ -57,6 +57,10 @@ class GZ_UTILS_LOG_VISIBLE Logger /// \return The spdlog logger. public: [[nodiscard]] std::shared_ptr RawLoggerPtr() const; + /// \brief Set the severity level of the Console sink + /// \param [in] _level Severity level + public: void SetConsoleSinkLevel(spdlog::level::level_enum _level); + /// \brief Implementation Pointer. GZ_UTILS_UNIQUE_IMPL_PTR(dataPtr) }; diff --git a/log/src/Logger.cc b/log/src/Logger.cc index e28ec39..8866c26 100644 --- a/log/src/Logger.cc +++ b/log/src/Logger.cc @@ -25,6 +25,11 @@ namespace gz::utils::log { +namespace { + /// \brief Default log format + /// Example output + constexpr std::string_view kDefaultLogFormat{"%^(%Y-%m-%d %T.%e) [%l] %v%$"}; +} /// \brief Private data for the Logger class. class Logger::Implementation { @@ -33,6 +38,9 @@ class Logger::Implementation public: explicit Implementation(const std::string &_loggerName) : consoleSink(std::make_shared()), sinks(std::make_shared()), + formatter(std::make_unique( + kDefaultLogFormat.data(), + spdlog::pattern_time_type::local, std::string(""))), logger(std::make_shared(_loggerName, sinks)) { } @@ -46,6 +54,9 @@ class Logger::Implementation /// \brief A sink distribution storing multiple sinks. std::shared_ptr sinks {nullptr}; + /// \brief Common formatter for both all sinks + std::unique_ptr formatter; + /// \brief The underlying spdlog logger. std::shared_ptr logger {nullptr}; }; @@ -58,13 +69,10 @@ Logger::Logger(const std::string &_loggerName) this->dataPtr->sinks->add_sink(this->dataPtr->consoleSink); // Configure the logger. - this->dataPtr->logger->set_level(spdlog::level::err); + this->dataPtr->consoleSink->set_level(spdlog::level::err); this->dataPtr->logger->flush_on(spdlog::level::err); - // Disable eol. - auto f = std::make_unique( - "%+", spdlog::pattern_time_type::local, std::string("")); - this->dataPtr->logger->set_formatter(std::move(f)); + this->dataPtr->logger->set_formatter(this->dataPtr->formatter->clone()); } ///////////////////////////////////////////////// @@ -77,6 +85,8 @@ void Logger::SetLogDestination(const std::string &_filename) { this->dataPtr->fileSink = std::make_shared(_filename, true); + this->dataPtr->fileSink->set_formatter(this->dataPtr->formatter->clone()); + this->dataPtr->fileSink->set_level(spdlog::level::trace); this->dataPtr->sinks->add_sink(this->dataPtr->fileSink); } } @@ -103,4 +113,13 @@ std::shared_ptr Logger::RawLoggerPtr() const return this->dataPtr->logger; } +///////////////////////////////////////////////// +void Logger::SetConsoleSinkLevel(spdlog::level::level_enum _level) +{ + if (this->dataPtr->consoleSink) + { + this->dataPtr->consoleSink->set_level(_level); + } +} + } // namespace gz::utils::log From 2b53ca8a3c145481c6b90245f67e9b6c06701a4b Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Wed, 28 Aug 2024 17:37:39 -0500 Subject: [PATCH 05/14] Update logger level and flush_on values (#142) The logger level change is needed because the file sink's level is `trace` and apparently `spdlog` will use the lower severity level of the logger and the sink. The `flush_on` change is needed to cause spdlog to write to file more frequently. Signed-off-by: Addisu Z. Taddese --- log/src/Logger.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/log/src/Logger.cc b/log/src/Logger.cc index 8866c26..0eccc61 100644 --- a/log/src/Logger.cc +++ b/log/src/Logger.cc @@ -69,8 +69,9 @@ Logger::Logger(const std::string &_loggerName) this->dataPtr->sinks->add_sink(this->dataPtr->consoleSink); // Configure the logger. + this->dataPtr->logger->set_level(spdlog::level::trace); this->dataPtr->consoleSink->set_level(spdlog::level::err); - this->dataPtr->logger->flush_on(spdlog::level::err); + this->dataPtr->logger->flush_on(spdlog::level::debug); this->dataPtr->logger->set_formatter(this->dataPtr->formatter->clone()); } From daa3d654f1b2360bb497eaf15ab05b1df4bc27a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Ag=C3=BCero?= Date: Thu, 29 Aug 2024 00:50:20 +0200 Subject: [PATCH 06/14] Prepare for 3.0.0pre3 (#143) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Carlos Agüero --- CMakeLists.txt | 2 +- Changelog.md | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 513f3d8..87262db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ find_package(gz-cmake4 REQUIRED) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -gz_configure_project(VERSION_SUFFIX pre2) +gz_configure_project(VERSION_SUFFIX pre3) #============================================================================ # Set project-specific options diff --git a/Changelog.md b/Changelog.md index 2621b43..fa9b43d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,12 @@ 1. **Baseline:** this includes all changes from 2.2.0 and earlier. +1. Update logger level and flush_on values + * [Pull request #142](https://github.com/gazebosim/gz-utils/pull/142) + +1. Use common formatter for console and file sinks + * [Pull request #141](https://github.com/gazebosim/gz-utils/pull/141) + 1. Logger updates * [Pull request #139](https://github.com/gazebosim/gz-utils/pull/139) From d6c602d8e897964223e6900baac67615b6679d81 Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Tue, 3 Sep 2024 12:45:46 -0500 Subject: [PATCH 07/14] Include file name in log format (#144) Signed-off-by: Addisu Z. Taddese --- log/src/Logger.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/log/src/Logger.cc b/log/src/Logger.cc index 0eccc61..e0d1824 100644 --- a/log/src/Logger.cc +++ b/log/src/Logger.cc @@ -28,7 +28,8 @@ namespace gz::utils::log namespace { /// \brief Default log format /// Example output - constexpr std::string_view kDefaultLogFormat{"%^(%Y-%m-%d %T.%e) [%l] %v%$"}; +constexpr std::string_view kDefaultLogFormat{ + "%^(%Y-%m-%d %T.%e) [%l] [%s:%#] %v%$"}; } /// \brief Private data for the Logger class. class Logger::Implementation From aae0d8c3e920eaf5b0e04664d4087bc1b2ca6f12 Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Wed, 4 Sep 2024 12:10:22 -0500 Subject: [PATCH 08/14] Catch spdlog exception thrown when creating file (#145) Signed-off-by: Addisu Z. Taddese --- log/src/Logger.cc | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/log/src/Logger.cc b/log/src/Logger.cc index e0d1824..7346f99 100644 --- a/log/src/Logger.cc +++ b/log/src/Logger.cc @@ -14,6 +14,8 @@ * limitations under the License. * */ +#include +#include #include #include @@ -85,11 +87,18 @@ void Logger::SetLogDestination(const std::string &_filename) if (!_filename.empty()) { - this->dataPtr->fileSink = - std::make_shared(_filename, true); - this->dataPtr->fileSink->set_formatter(this->dataPtr->formatter->clone()); - this->dataPtr->fileSink->set_level(spdlog::level::trace); - this->dataPtr->sinks->add_sink(this->dataPtr->fileSink); + try + { + this->dataPtr->fileSink = + std::make_shared(_filename, true); + this->dataPtr->fileSink->set_formatter(this->dataPtr->formatter->clone()); + this->dataPtr->fileSink->set_level(spdlog::level::trace); + this->dataPtr->sinks->add_sink(this->dataPtr->fileSink); + } + catch (const std::exception &_e) + { + std::cerr << "Error creating log file: " << _e.what() << std::endl; + } } } From fb1cc8111a4ab13be5ce9aa894bdaf62b4691aca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Ag=C3=BCero?= Date: Wed, 25 Sep 2024 22:38:59 +0200 Subject: [PATCH 09/14] Add EoL and use SetConsoleSinkLevel (#148) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Carlos Agüero --- examples/log/main.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/log/main.cc b/examples/log/main.cc index 1ad207d..51cd09d 100644 --- a/examples/log/main.cc +++ b/examples/log/main.cc @@ -22,16 +22,16 @@ int main(int argc, char** argv) { gz::utils::log::Logger logger("my_logger"); - logger.RawLogger().set_level(spdlog::level::trace); + logger.SetConsoleSinkLevel(spdlog::level::info); std::filesystem::path logDir = std::filesystem::temp_directory_path(); std::filesystem::path logFile = "my_log.txt"; std::filesystem::path logPath = logDir / logFile; logger.SetLogDestination(logPath); - logger.RawLogger().trace("trace"); - logger.RawLogger().info("info"); - logger.RawLogger().warn("warn"); - logger.RawLogger().error("error"); - logger.RawLogger().critical("critical"); + logger.RawLogger().trace("trace\n"); + logger.RawLogger().info("info\n"); + logger.RawLogger().warn("warn\n"); + logger.RawLogger().error("error\n"); + logger.RawLogger().critical("critical\n"); } From 24a37ce443d0e594bcf276a78aa677d9291a3df9 Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Wed, 25 Sep 2024 15:41:08 -0500 Subject: [PATCH 10/14] Prepare for 3.0.0 Signed-off-by: Addisu Z. Taddese --- CMakeLists.txt | 2 +- Changelog.md | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 87262db..74fee08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ find_package(gz-cmake4 REQUIRED) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -gz_configure_project(VERSION_SUFFIX pre3) +gz_configure_project(VERSION_SUFFIX) #============================================================================ # Set project-specific options diff --git a/Changelog.md b/Changelog.md index fa9b43d..361212d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,9 +1,18 @@ ## Gazebo Utils 3.x -## Gazebo Utils 3.0.0 (20XX-XX-XX) +## Gazebo Utils 3.0.0 (2024-09-25) 1. **Baseline:** this includes all changes from 2.2.0 and earlier. +1. Add EoL and use SetConsoleSinkLevel in example + * [Pull request #148](https://github.com/gazebosim/gz-utils/pull/148) + +1. Catch spdlog exception thrown when creating file + * [Pull request #145](https://github.com/gazebosim/gz-utils/pull/145) + +1. Include file name in log format + * [Pull request #144](https://github.com/gazebosim/gz-utils/pull/144) + 1. Update logger level and flush_on values * [Pull request #142](https://github.com/gazebosim/gz-utils/pull/142) From 6b37112ba4e53a26a0d96644812521972b3dde6d Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Sat, 5 Oct 2024 00:24:18 +0000 Subject: [PATCH 11/14] update readme badge Signed-off-by: Ian Chen --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e083c15..d16ee44 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,10 @@ Build | Status -- | -- -Test coverage | [![codecov](https://codecov.io/gh/gazebosim/gz-utils/branch/gz-utils3/graph/badge.svg)](https://app.codecov.io/gh/gazebosim/gz-utils/tree/gz-utils3) -Ubuntu Noble | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_utils-ci-gz-utils3-noble-amd64)](https://build.osrfoundation.org/job/gz_utils-ci-gz-utils3-noble-amd64) -Homebrew | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_utils-ci-gz-utils3-homebrew-amd64)](https://build.osrfoundation.org/job/gz_utils-ci-gz-utils3-homebrew-amd64) -Windows | [![Build Status](https://build.osrfoundation.org/job/gz_utils-3-win/badge/icon)](https://build.osrfoundation.org/job/gz_utils-3-win/) +Test coverage | [![codecov](https://codecov.io/gh/gazebosim/gz-utils/branch/main/graph/badge.svg)](https://app.codecov.io/gh/gazebosim/gz-utils/tree/main) +Ubuntu Noble | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_utils-ci-main-noble-amd64)](https://build.osrfoundation.org/job/gz_utils-ci-main-noble-amd64) +Homebrew | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_utils-ci-main-homebrew-amd64)](https://build.osrfoundation.org/job/gz_utils-ci-main-homebrew-amd64) +Windows | [![Build Status](https://build.osrfoundation.org/job/gz_utils-main-win/badge/icon)](https://build.osrfoundation.org/job/gz_utils-main-win/) Gazebo Utils, a component of [Gazebo](https://gazebosim.org), provides general purpose classes and functions designed for robotic applications. @@ -53,7 +53,7 @@ See the [installation tutorial](https://gazebosim.org/api/utils/2/install.html). # Usage -Please refer to the [examples directory](https://github.com/gazebosim/gz-utils/blob/gz-utils3/examples/). +Please refer to the [examples directory](https://github.com/gazebosim/gz-utils/blob/main/examples/). # Documentation From c547c9bc51d987e2cca3850843477006d2a92c6f Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Tue, 8 Oct 2024 09:48:38 -0500 Subject: [PATCH 12/14] Build gz-utils with bzlmod (#128) Signed-off-by: Michael Carroll --- .bazelrc | 12 +++ .bazelversion | 1 + .gitignore | 6 ++ BUILD.bazel | 168 ++++++++++++++++++++-------------- MODULE.bazel | 12 +++ WORKSPACE | 0 cli/BUILD.bazel | 49 ++++++---- include/gz/utils/config.hh.in | 14 +-- log/BUILD.bazel | 65 +++++++++++++ 9 files changed, 233 insertions(+), 94 deletions(-) create mode 100644 .bazelrc create mode 100644 .bazelversion create mode 100644 MODULE.bazel create mode 100644 WORKSPACE create mode 100644 log/BUILD.bazel diff --git a/.bazelrc b/.bazelrc new file mode 100644 index 0000000..f2d0613 --- /dev/null +++ b/.bazelrc @@ -0,0 +1,12 @@ +common --enable_bzlmod +common --lockfile_mode=off + +# Add C++17 compiler flags. +build --cxxopt=-std=c++17 +build --host_cxxopt=-std=c++17 + +build --force_pic +build --strip=never +build --strict_system_includes +build --fission=dbg +build --features=per_object_debug_info diff --git a/.bazelversion b/.bazelversion new file mode 100644 index 0000000..643916c --- /dev/null +++ b/.bazelversion @@ -0,0 +1 @@ +7.3.1 diff --git a/.gitignore b/.gitignore index 62b9898..39555d6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,9 @@ build_* # OS generated files .DS_Store *.swp + +# Bazel generated files +bazel-bin/ +bazel-out/ +bazel-testlogs/ +bazel-* diff --git a/BUILD.bazel b/BUILD.bazel index 435829a..395826f 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -1,18 +1,11 @@ -load( - "@gz//bazel/skylark:build_defs.bzl", - "GZ_FEATURES", - "GZ_ROOT", - "GZ_VISIBILITY", - "gz_configure_header", - "gz_export_header", - "gz_include_header", -) +load("@buildifier_prebuilt//:rules.bzl", "buildifier", "buildifier_test") +load("@rules_gazebo//gazebo:headers.bzl", "gz_configure_header", "gz_export_header") load("@rules_license//rules:license.bzl", "license") package( - default_applicable_licenses = [GZ_ROOT + "utils:license"], - default_visibility = GZ_VISIBILITY, - features = GZ_FEATURES, + default_applicable_licenses = [":license"], + default_visibility = ["__subpackages__"], + features = ["layering_check"], ) license( @@ -20,51 +13,87 @@ license( package_name = "gz-utils", ) -licenses(["notice"]) +exports_files([ + "LICENSE", + "MODULE.bazel", +]) -exports_files(["LICENSE"]) +gz_export_header( + name = "Export", + out = "include/gz/utils/Export.hh", + export_base = "GZ_UTILS", + lib_name = "gz-utils", +) gz_configure_header( - name = "config", + name = "Config", src = "include/gz/utils/config.hh.in", - cmakelists = ["CMakeLists.txt"], - package = "utils", + package_xml = "package.xml", ) -gz_export_header( - name = "include/gz/utils/Export.hh", - export_base = "GZ_UTILS", - lib_name = "gz-utils", - visibility = ["//visibility:private"], +cc_library( + name = "Environment", + srcs = ["src/Environment.cc"], + hdrs = ["include/gz/utils/Environment.hh"], + includes = ["include"], + deps = [ + ":Config", + ":Export", + ], ) -public_headers_no_gen = glob([ - "include/gz/utils/*.hh", - "include/gz/utils/detail/*.hh", - "include/gz/utils/detail/*.h", -]) - -gz_include_header( - name = "utilshh_genrule", - out = "include/gz/utils.hh", - hdrs = public_headers_no_gen + [ - "include/gz/utils/Export.hh", - "include/gz/utils/config.hh", +cc_library( + name = "ImplPtr", + hdrs = [ + "include/gz/utils/ImplPtr.hh", + "include/gz/utils/detail/DefaultOps.hh", + "include/gz/utils/detail/ImplPtr.hh", + ], + includes = ["include"], + visibility = ["//visibility:public"], + deps = [ + ":Export", + ":SuppressWarning", ], ) -public_headers = public_headers_no_gen + [ - "include/gz/utils/config.hh", - "include/gz/utils/Export.hh", - "include/gz/utils.hh", -] +cc_library( + name = "NeverDestroyed", + hdrs = ["include/gz/utils/NeverDestroyed.hh"], + includes = ["include"], + visibility = ["//visibility:public"], +) cc_library( - name = "utils", - srcs = ["src/Environment.cc"], - hdrs = public_headers, - copts = ["-fexceptions"], + name = "SuppressWarning", + hdrs = [ + "include/gz/utils/SuppressWarning.hh", + "include/gz/utils/detail/SuppressWarning.hh", + ], + includes = ["include"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "Subprocess", + hdrs = [ + "include/gz/utils/Subprocess.hh", + "include/gz/utils/detail/subprocess.h", + ], includes = ["include"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "gz-utils", + visibility = ["//visibility:public"], + deps = [ + ":Environment", + ":ImplPtr", + ":NeverDestroyed", + ":Subprocess", + ":SuppressWarning", + ], ) # Tests @@ -77,7 +106,7 @@ cc_library( "test/integration/implptr/implptr_test_classes.hh", ], includes = ["test/integration/implptr"], - deps = [":utils"], + deps = [":ImplPtr"], ) cc_test( @@ -86,8 +115,7 @@ cc_test( srcs = ["test/integration/implptr/ImplPtr_TEST.cc"], deps = [ ":implptr_test_classes", - "@gtest", - "@gtest//:gtest_main", + "@googletest//:gtest_main", ], ) @@ -95,39 +123,43 @@ cc_test( name = "Environment_TEST", srcs = ["src/Environment_TEST.cc"], deps = [ - ":utils", - "@gtest", - "@gtest//:gtest_main", + ":Environment", + "@googletest//:gtest_main", ], ) -cc_test( - name = "NeverDestroyed_TEST", - srcs = ["src/NeverDestroyed_TEST.cc"], - copts = ["-fexceptions"], +cc_binary( + name = "subprocess_main", + srcs = ["test/integration/subprocess/subprocess_main.cc"], deps = [ - ":utils", - "@gtest", - "@gtest//:gtest_main", + ":Environment", + "//cli", ], ) -cc_binary( - name = "subprocess_main", - srcs = ["test/integration/subprocess/subprocess_main.cc"], - deps = [ - GZ_ROOT + "utils/cli", - ] -) - cc_test( name = "subprocess_TEST", srcs = ["test/integration/subprocess_TEST.cc"], + local_defines = ['SUBPROCESS_EXECUTABLE_PATH=\\"subprocess_main\\"'], deps = [ - ":utils", + ":gz-utils", ":subprocess_main", - "@gtest", - "@gtest//:gtest_main", + "@googletest//:gtest_main", ], - local_defines = ['SUBPROCESS_EXECUTABLE_PATH=\\"utils/subprocess_main\\"'], +) + +buildifier( + name = "buildifier.fix", + exclude_patterns = ["./.git/*"], + lint_mode = "fix", + mode = "fix", +) + +buildifier_test( + name = "buildifier.test", + exclude_patterns = ["./.git/*"], + lint_mode = "warn", + mode = "diff", + no_sandbox = True, + workspace = "//:MODULE.bazel", ) diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 0000000..6a8b2ce --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,12 @@ +"gz-utils" + +module( + name = "gz-utils", + repo_name = "org_gazebosim_gz-utils", +) + +bazel_dep(name = "buildifier_prebuilt", version = "7.3.1") +bazel_dep(name = "googletest", version = "1.14.0") +bazel_dep(name = "rules_gazebo", version = "0.0.2") +bazel_dep(name = "rules_license", version = "1.0.0") +bazel_dep(name = "spdlog", version = "1.14.1") diff --git a/WORKSPACE b/WORKSPACE new file mode 100644 index 0000000..e69de29 diff --git a/cli/BUILD.bazel b/cli/BUILD.bazel index b97bc2d..f1d18fa 100644 --- a/cli/BUILD.bazel +++ b/cli/BUILD.bazel @@ -1,12 +1,7 @@ -load( - "@gz//bazel/skylark:build_defs.bzl", - "GZ_ROOT", - "GZ_VISIBILITY", -) load("@rules_license//rules:license.bzl", "license") package( - default_applicable_licenses = [GZ_ROOT + "utils/cli:license"], + default_applicable_licenses = ["//:license"], ) license( @@ -14,23 +9,39 @@ license( package_name = "gz-utils-cli", ) -public_headers = [ - "include/gz/utils/cli/GzFormatter.hpp", -] + glob([ - "include/external-cli/gz/utils/cli/*.hpp", -]) +cc_library( + name = "cli11", + hdrs = glob([ + "include/vendored-cli/gz/utils/cli/*.hpp", + ]), + includes = ["include/vendored-cli"], +) + +cc_library( + name = "GzFormatter", + hdrs = [ + "include/gz/utils/cli/GzFormatter.hpp", + ], + includes = ["include"], + deps = [ + "//:Export", + ], +) cc_library( name = "cli", - hdrs = public_headers, - copts = ["-fexceptions"], - includes = [ - "include", - "include/external-cli", + visibility = ["//visibility:public"], + deps = [ + ":GzFormatter", + ":cli11", ], - visibility = GZ_VISIBILITY, +) + +cc_test( + name = "cli_TEST", + srcs = ["src/cli_TEST.cc"], deps = [ - GZ_ROOT + "utils:utils", - "@cli11" + ":cli", + "@googletest//:gtest_main", ], ) diff --git a/include/gz/utils/config.hh.in b/include/gz/utils/config.hh.in index 60984a8..4c05ce3 100644 --- a/include/gz/utils/config.hh.in +++ b/include/gz/utils/config.hh.in @@ -21,15 +21,15 @@ #define GZ_UTILS_CONFIG_HH_ /* Version number */ -#define GZ_UTILS_MAJOR_VERSION ${PROJECT_VERSION_MAJOR} -#define GZ_UTILS_MINOR_VERSION ${PROJECT_VERSION_MINOR} -#define GZ_UTILS_PATCH_VERSION ${PROJECT_VERSION_PATCH} +#define GZ_UTILS_MAJOR_VERSION @PROJECT_VERSION_MAJOR@ +#define GZ_UTILS_MINOR_VERSION @PROJECT_VERSION_MINOR@ +#define GZ_UTILS_PATCH_VERSION @PROJECT_VERSION_PATCH@ -#define GZ_UTILS_VERSION "${PROJECT_VERSION}" -#define GZ_UTILS_VERSION_FULL "${PROJECT_VERSION_FULL}" +#define GZ_UTILS_VERSION "@PROJECT_VERSION@" +#define GZ_UTILS_VERSION_FULL "@PROJECT_VERSION_FULL@" -#define GZ_UTILS_VERSION_NAMESPACE v${PROJECT_VERSION_MAJOR} +#define GZ_UTILS_VERSION_NAMESPACE v@PROJECT_VERSION_MAJOR@ -#define GZ_UTILS_VERSION_HEADER "Gazebo Utils, version ${PROJECT_VERSION_FULL}\nCopyright (C) 2020 Open Source Robotics Foundation.\nReleased under the Apache 2.0 License.\n\n" +#define GZ_UTILS_VERSION_HEADER "Gazebo Utils, version @PROJECT_VERSION_FULL@\nCopyright (C) 2020 Open Source Robotics Foundation.\nReleased under the Apache 2.0 License.\n\n" #endif diff --git a/log/BUILD.bazel b/log/BUILD.bazel new file mode 100644 index 0000000..6e314c7 --- /dev/null +++ b/log/BUILD.bazel @@ -0,0 +1,65 @@ +load("@rules_gazebo//gazebo:headers.bzl", "gz_export_header") +load("@rules_license//rules:license.bzl", "license") + +package( + default_applicable_licenses = ["//:license"], +) + +license( + name = "license", + package_name = "gz-utils-log", +) + +gz_export_header( + name = "Export", + out = "include/gz/utils/log/Export.hh", + export_base = "GZ_UTILS_LOG", + lib_name = "gz-utils-log", +) + +cc_library( + name = "SplitSink", + srcs = [ + "src/SplitSink.cc", + ], + hdrs = [ + "include/gz/utils/log/SplitSink.hh", + ], + includes = ["include"], + deps = [ + ":Export", + "//:Config", + "//:ImplPtr", + "@spdlog", + ], +) + +cc_library( + name = "Logger", + srcs = [ + "src/Logger.cc", + ], + hdrs = [ + "include/gz/utils/log/Logger.hh", + ], + includes = ["include"], + deps = [":SplitSink"], +) + +cc_library( + name = "log", + visibility = ["//visibility:public"], + deps = [ + ":Logger", + ":SplitSink", + ], +) + +cc_test( + name = "SplitSink_TEST", + srcs = ["src/SplitSink_TEST.cc"], + deps = [ + ":log", + "@googletest//:gtest_main", + ], +) From 8614daae6ca42aa793c349353fc564ee49e1c0a1 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Tue, 8 Oct 2024 09:48:54 -0500 Subject: [PATCH 13/14] Add Bazel CI (#153) Signed-off-by: Michael Carroll --- .github/workflows/bazel.yml | 24 ++++++++++++++++++++++++ .github/workflows/ci.bazelrc | 15 +++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 .github/workflows/bazel.yml create mode 100644 .github/workflows/ci.bazelrc diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml new file mode 100644 index 0000000..8dcf7f8 --- /dev/null +++ b/.github/workflows/bazel.yml @@ -0,0 +1,24 @@ +name: Bazel CI +on: + push: + branches: [gz-utils3, main] + pull_request: + branches: [gz-utils3, main] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + test: + uses: bazel-contrib/.github/.github/workflows/bazel.yaml@v6 + with: + folders: | + [ + ".", + ] + exclude: | + [ + {"bazelversion": "6.4.0"} + {"bazelversion": "5.4.0"}, + ] diff --git a/.github/workflows/ci.bazelrc b/.github/workflows/ci.bazelrc new file mode 100644 index 0000000..3b4aad2 --- /dev/null +++ b/.github/workflows/ci.bazelrc @@ -0,0 +1,15 @@ +# This file contains Bazel settings to apply on CI only. +# It is referenced with a --bazelrc option in the call to bazel in ci.yaml + +# Debug where options came from +build --announce_rc +# This directory is configured in GitHub actions to be persisted between runs. +# We do not enable the repository cache to cache downloaded external artifacts +# as these are generally faster to download again than to fetch them from the +# GitHub actions cache. +build --disk_cache=~/.cache/bazel +# Don't rely on test logs being easily accessible from the test runner, +# though it makes the log noisier. +test --test_output=errors +# Allows tests to run bazelisk-in-bazel, since this is the cache folder used +test --test_env=XDG_CACHE_HOME From 2aa20d7147a838a795eadd8d8a2d7e02ec9eeeb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Ag=C3=BCero?= Date: Tue, 8 Oct 2024 20:12:47 +0200 Subject: [PATCH 14/14] Fix logging source location (#150) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Make the log example show file source location --------- Signed-off-by: Carlos Agüero Signed-off-by: Ian Chen Co-authored-by: Ian Chen --- examples/log/main.cc | 12 ++- log/include/gz/utils/log/Logger.hh | 4 + log/src/Logger_TEST.cc | 160 +++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+), 5 deletions(-) create mode 100644 log/src/Logger_TEST.cc diff --git a/examples/log/main.cc b/examples/log/main.cc index 51cd09d..7aee2df 100644 --- a/examples/log/main.cc +++ b/examples/log/main.cc @@ -29,9 +29,11 @@ int main(int argc, char** argv) std::filesystem::path logPath = logDir / logFile; logger.SetLogDestination(logPath); - logger.RawLogger().trace("trace\n"); - logger.RawLogger().info("info\n"); - logger.RawLogger().warn("warn\n"); - logger.RawLogger().error("error\n"); - logger.RawLogger().critical("critical\n"); + + SPDLOG_LOGGER_TRACE(logger.RawLoggerPtr(), "trace\n"); + SPDLOG_LOGGER_DEBUG(logger.RawLoggerPtr(), "debug\n"); + SPDLOG_LOGGER_INFO(logger.RawLoggerPtr(), "info\n"); + SPDLOG_LOGGER_WARN(logger.RawLoggerPtr(), "warn\n"); + SPDLOG_LOGGER_ERROR(logger.RawLoggerPtr(), "error\n"); + SPDLOG_LOGGER_CRITICAL(logger.RawLoggerPtr(), "critical\n"); } diff --git a/log/include/gz/utils/log/Logger.hh b/log/include/gz/utils/log/Logger.hh index d2cdd9a..d9d94f7 100644 --- a/log/include/gz/utils/log/Logger.hh +++ b/log/include/gz/utils/log/Logger.hh @@ -17,6 +17,10 @@ #ifndef GZ_UTILS_LOG_LOGGER_HH_ #define GZ_UTILS_LOG_LOGGER_HH_ +#if !defined(SPDLOG_ACTIVE_LEVEL) + #define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE +#endif + #include #include #include diff --git a/log/src/Logger_TEST.cc b/log/src/Logger_TEST.cc new file mode 100644 index 0000000..8e12061 --- /dev/null +++ b/log/src/Logger_TEST.cc @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2024 Open Source Robotics Foundation + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include + +///////////////////////////////////////////////// +std::string getLogContent(const std::string &_filename) +{ + // Open the log file, and read back the string + std::ifstream ifs(_filename.c_str(), std::ios::in); + std::string loggedString; + + while (!ifs.eof()) + { + std::string line; + std::getline(ifs, line); + loggedString += line; + } + + return loggedString; +} + +///////////////////////////////////////////////// +TEST(Logger, defaults) +{ + gz::utils::log::Logger logger("my_logger"); + + // Logger defaults. + EXPECT_TRUE(logger.RawLogger().should_log(spdlog::level::trace)); + EXPECT_EQ(spdlog::level::debug, logger.RawLogger().flush_level()); + EXPECT_EQ(spdlog::level::debug, logger.RawLoggerPtr()->flush_level()); + + // Sink defaults. + EXPECT_EQ(1u, logger.RawLogger().sinks().size()); + auto sink = logger.RawLogger().sinks().front(); + ASSERT_NE(nullptr, sink); +} + +///////////////////////////////////////////////// +TEST(Logger, basicLogging) +{ + gz::utils::log::Logger logger("my_logger"); + + testing::internal::CaptureStdout(); + testing::internal::CaptureStderr(); + + SPDLOG_LOGGER_TRACE(logger.RawLoggerPtr(), "trace\n"); + SPDLOG_LOGGER_DEBUG(logger.RawLoggerPtr(), "debug\n"); + SPDLOG_LOGGER_INFO(logger.RawLoggerPtr(), "info\n"); + SPDLOG_LOGGER_WARN(logger.RawLoggerPtr(), "warn\n"); + SPDLOG_LOGGER_ERROR(logger.RawLoggerPtr(), "error\n"); + SPDLOG_LOGGER_CRITICAL(logger.RawLoggerPtr(), "critical\n"); + + std::string stdOut = testing::internal::GetCapturedStdout(); + std::string stdErr = testing::internal::GetCapturedStderr(); + + for (auto word : {"trace", "debug", "info"}) + EXPECT_FALSE(stdOut.find(word) != std::string::npos); + + for (auto word : {"warn"}) + EXPECT_FALSE(stdErr.find(word) != std::string::npos); + + for (auto word : {"error", "critical"}) + EXPECT_TRUE(stdErr.find(word) != std::string::npos); +} + +///////////////////////////////////////////////// +TEST(Logger, consoleSinkLevel) +{ + gz::utils::log::Logger logger("my_logger"); + logger.SetConsoleSinkLevel(spdlog::level::critical); + + testing::internal::CaptureStdout(); + testing::internal::CaptureStderr(); + + SPDLOG_LOGGER_TRACE(logger.RawLoggerPtr(), "trace\n"); + SPDLOG_LOGGER_DEBUG(logger.RawLoggerPtr(), "debug\n"); + SPDLOG_LOGGER_INFO(logger.RawLoggerPtr(), "info\n"); + SPDLOG_LOGGER_WARN(logger.RawLoggerPtr(), "warn\n"); + SPDLOG_LOGGER_ERROR(logger.RawLoggerPtr(), "error\n"); + SPDLOG_LOGGER_CRITICAL(logger.RawLoggerPtr(), "critical\n"); + + std::string stdOut = testing::internal::GetCapturedStdout(); + std::string stdErr = testing::internal::GetCapturedStderr(); + + for (auto word : {"trace", "debug", "info"}) + EXPECT_FALSE(stdOut.find(word) != std::string::npos); + + for (auto word : {"warn", "error"}) + EXPECT_FALSE(stdErr.find(word) != std::string::npos); + + for (auto word : {"critical"}) + EXPECT_TRUE(stdErr.find(word) != std::string::npos); +} + +///////////////////////////////////////////////// +TEST(Logger, fileLocation) +{ + gz::utils::log::Logger logger("my_logger"); + + testing::internal::CaptureStdout(); + testing::internal::CaptureStderr(); + + SPDLOG_LOGGER_ERROR(logger.RawLoggerPtr(), "error\n"); + SPDLOG_LOGGER_CRITICAL(logger.RawLoggerPtr(), "critical\n"); + + std::string stdOut = testing::internal::GetCapturedStdout(); + std::string stdErr = testing::internal::GetCapturedStderr(); + + for (auto word : {"error", "critical"}) + { + EXPECT_TRUE(stdErr.find(word) != std::string::npos); + EXPECT_TRUE(stdErr.find("Logger_TEST.cc:") != std::string::npos); + } +} + +///////////////////////////////////////////////// +TEST(Logger, fileLogging) +{ + gz::utils::log::Logger logger("my_logger"); + + std::filesystem::path logDir = std::filesystem::temp_directory_path(); + std::filesystem::path logFile = "my_log.txt"; + std::filesystem::path logPath = logDir / logFile; + + EXPECT_TRUE(logger.LogDestination().empty()); + logger.SetLogDestination(logPath.string()); + EXPECT_EQ(logPath.string(), logger.LogDestination()); + + logger.RawLogger().trace("trace\n"); + logger.RawLogger().debug("debug\n"); + logger.RawLogger().info("info\n"); + logger.RawLogger().warn("warn\n"); + logger.RawLogger().error("error\n"); + logger.RawLogger().critical("critical\n"); + + // Expect to find the string in the log file + std::string logContent = getLogContent(logPath.string()); + for (auto word : {"trace", "debug", "info", "warn", "error", "critical"}) + EXPECT_TRUE(logContent.find(word) != std::string::npos); +}