From 332ac26e45cf3a1a9b5c7a7dd8e23bf9c67a98e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjell=20Hedstr=C3=B6m?= <331742+KjellKod@users.noreply.github.com> Date: Mon, 27 Nov 2023 14:09:21 -0700 Subject: [PATCH 01/14] trying out codespaces --- .devcontainer/Dockerfile | 19 ++++++++++ .devcontainer/reinstall_cmake.sh | 60 ++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/reinstall_cmake.sh diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..2c928bde --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,19 @@ +# Latest Debian +FROM mcr.microsoft.com/devcontainers/cpp:debian + +ARG REINSTALL_CMAKE_VERSION_FROM_SOURCE="none" + +# Optionally install the cmake for vcpkg +COPY ./reinstall-cmake.sh /tmp/ + +RUN if [ "${REINSTALL_CMAKE_VERSION_FROM_SOURCE}" != "none" ]; then \ + chmod +x /tmp/reinstall-cmake.sh && /tmp/reinstall-cmake.sh ${REINSTALL_CMAKE_VERSION_FROM_SOURCE}; \ + fi \ + && rm -f /tmp/reinstall-cmake.sh + +# [Optional] Uncomment this section to install additional vcpkg ports. +# RUN su vscode -c "${VCPKG_ROOT}/vcpkg install " + +# [Optional] Uncomment this section to install additional packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends \ No newline at end of file diff --git a/.devcontainer/reinstall_cmake.sh b/.devcontainer/reinstall_cmake.sh new file mode 100644 index 00000000..92ff7272 --- /dev/null +++ b/.devcontainer/reinstall_cmake.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +#------------------------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. +#------------------------------------------------------------------------------------------------------------- +# +# testing, unsure if it's needed. following steps from example: https://github.com/microsoft/vscode-remote-try-cpp/tree/main/.devcontainer + +set -e + +CMAKE_VERSION=${1:-"none"} + +if [ "${CMAKE_VERSION}" = "none" ]; then + echo "No CMake version specified, skipping CMake reinstallation" + exit 0 +fi + +# Cleanup temporary directory and associated files when exiting the script. +cleanup() { + EXIT_CODE=$? + set +e + if [[ -n "${TMP_DIR}" ]]; then + echo "Executing cleanup of tmp files" + rm -Rf "${TMP_DIR}" + fi + exit $EXIT_CODE +} +trap cleanup EXIT + + +echo "Installing CMake..." +apt-get -y purge --auto-remove cmake +mkdir -p /opt/cmake + +architecture=$(dpkg --print-architecture) +case "${architecture}" in + arm64) + ARCH=aarch64 ;; + amd64) + ARCH=x86_64 ;; + *) + echo "Unsupported architecture ${architecture}." + exit 1 + ;; +esac + +CMAKE_BINARY_NAME="cmake-${CMAKE_VERSION}-linux-${ARCH}.sh" +CMAKE_CHECKSUM_NAME="cmake-${CMAKE_VERSION}-SHA-256.txt" +TMP_DIR=$(mktemp -d -t cmake-XXXXXXXXXX) + +echo "${TMP_DIR}" +cd "${TMP_DIR}" + +curl -sSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_BINARY_NAME}" -O +curl -sSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_CHECKSUM_NAME}" -O + +sha256sum -c --ignore-missing "${CMAKE_CHECKSUM_NAME}" +sh "${TMP_DIR}/${CMAKE_BINARY_NAME}" --prefix=/opt/cmake --skip-license + +ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake \ No newline at end of file From e93c3074d444680febcffa11d13373819b40934e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjell=20Hedstr=C3=B6m?= <331742+KjellKod@users.noreply.github.com> Date: Mon, 27 Nov 2023 14:13:06 -0700 Subject: [PATCH 02/14] trying out codespaces --- .devcontainer/devcontainer.json | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..fd8a0e89 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,31 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/cpp +{ + "name": "C++", + "build": { + "dockerfile": "Dockerfile" + }, + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Configure tool-specific properties. + "customizations": { + // Configure properties specific to VS Code. + "vscode": { + "settings": {}, + "extensions": [ + "streetsidesoftware.code-spell-checker" + ] + } + } + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "gcc -v", + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} \ No newline at end of file From 51dd8871004daa4bb3748af90a365c2fc0808d49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjell=20Hedstr=C3=B6m?= <331742+KjellKod@users.noreply.github.com> Date: Mon, 27 Nov 2023 18:50:05 -0700 Subject: [PATCH 03/14] trying out codespaces --- docs/codespaces.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 docs/codespaces.md diff --git a/docs/codespaces.md b/docs/codespaces.md new file mode 100644 index 00000000..0fc7ef74 --- /dev/null +++ b/docs/codespaces.md @@ -0,0 +1,43 @@ +# Codespaces + +You can experiment with codespaces and g3log. + +## Learn about Github Codespaces +For an introduction to codespaces you can check out [example c++ codespace](https://github.com/microsoft/vscode-remote-try-cpp/tree/main) and [using-github-codespaces-with-github-cli](https://docs.github.com/en/codespaces/developing-in-a-codespace/using-github-codespaces-with-github-cli) + + +# Commandline codespaces Quick Reference + +1. List all your codespaces `gh codespace list` +2. Create a new codespace `gh codespace create -r OWNER/REPO_NAME [-b BRANCH]`. Ref [docs/github: Creating a codespace for a repository](https://docs.github.com/en/codespaces/developing-in-a-codespace/creating-a-codespace-for-a-repository) +3. View codebase details `gh codespace view` +4. Stop `gh codespace stop -c CODESPACE-NAME` +5. Delete `gh codespace delete -c CODESPACE-NAME` +6. Rebuild `gh codespace rebuild` +7. Rename `gh codespace edit -c CODESPACE-NAME -d DISPLAY-NAME` +8. SSH into REMOTE codespace `gh codespace ssh -c CODESPACE-NAME` +9. Open a remote codespace in CVisual Studio `gh codespace code -c CODESPACE-NAME` (ref: [github:doc cs studio](https://docs.github.com/en/codespaces/developing-in-a-codespace/using-github-codespaces-in-visual-studio-code)) +10. Copy local file to/from codespace `gh codespace cp [-r] SOURCE(S) DESTINATION`. Example: Copy a file from the local machine to the $HOME directory of a codespace: `gh codespace cp myfile.txt remote:`. Example Copy a file from a codespace to the current directory on the local machine: `gh codespace cp remote:myfile.txt .` (more information available [here](https://cli.github.com/manual/gh_codespace_cp)) + + +# Try g3log in a local dev container. + +Please note that this will build g3log as if it's on a Debian Linux platform. + +1. Clone this repository to your local filesystem. +2. Start Visual Studio Code. Press F1 and select the `Dev Containers: Open Folder in Container...` command. +3. Select the cloned copy of this g3log folder, wait for the container to start, and try things out! You should have debian C++ environment at hand. + +### Example cmake configuration and build +``` +Open a terminal in Visual Studio Code +mkdir debianbuild +cd debianbuild +cmake -DADD_G3LOG_UNIT_TEST=ON -DADD_G3LOG_BENCH_PERFORMANCE=ON .. +make -j +``` + +### Example runs +1. performance test in the container `./g3log-performance-threaded_mean 4` +2. unit tests `ctest -v` +3. Try a fatal example with dumped stack trace `./g3log-FATAL-contract` \ No newline at end of file From efe99d584a477ab7b1876e84143606a1b18b0832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjell=20Hedstr=C3=B6m?= <331742+KjellKod@users.noreply.github.com> Date: Mon, 27 Nov 2023 18:55:18 -0700 Subject: [PATCH 04/14] trying out codespaces --- .devcontainer/Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 2c928bde..62232404 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -4,16 +4,16 @@ FROM mcr.microsoft.com/devcontainers/cpp:debian ARG REINSTALL_CMAKE_VERSION_FROM_SOURCE="none" # Optionally install the cmake for vcpkg -COPY ./reinstall-cmake.sh /tmp/ +COPY ./reinstall_cmake.sh /tmp/ RUN if [ "${REINSTALL_CMAKE_VERSION_FROM_SOURCE}" != "none" ]; then \ - chmod +x /tmp/reinstall-cmake.sh && /tmp/reinstall-cmake.sh ${REINSTALL_CMAKE_VERSION_FROM_SOURCE}; \ + chmod +x /tmp/reinstall_cmake.sh && /tmp/reinstall_cmake.sh ${REINSTALL_CMAKE_VERSION_FROM_SOURCE}; \ fi \ - && rm -f /tmp/reinstall-cmake.sh + && rm -f /tmp/reinstall_cmake.sh # [Optional] Uncomment this section to install additional vcpkg ports. # RUN su vscode -c "${VCPKG_ROOT}/vcpkg install " # [Optional] Uncomment this section to install additional packages. # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ -# && apt-get -y install --no-install-recommends \ No newline at end of file +# && apt-get -y install --no-install-recommends From c7d301b2147f346add83b571dc028bb360d5e9db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjell=20Hedstr=C3=B6m?= <331742+KjellKod@users.noreply.github.com> Date: Mon, 27 Nov 2023 18:55:41 -0700 Subject: [PATCH 05/14] trying out codespaces --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 939cda38..6a61b5cf 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,10 @@ The super quick introduction to g3log can be seen in the steps 1 - 9 below. For more in-depth information please see the full usage description in [g3log.md](docs/g3log.md). The internal API for more advanced integration with g3log can be accessed in [API.md](docs/API.md) +## Experiment and try-out g3log in Github Codespaces +ref: [CodeSpsces.md](docs/codespaces.md) + + ## 1. Easy usage in files Avoid deep dependency injection complexity and instead get access to the logger as easy as ``` From b1f38dc4771d3cc65ad4fe5e942790eb0c530db0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjell=20Hedstr=C3=B6m?= <331742+KjellKod@users.noreply.github.com> Date: Mon, 27 Nov 2023 19:40:46 -0700 Subject: [PATCH 06/14] trying out codespaces --- docs/codespaces.md | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/docs/codespaces.md b/docs/codespaces.md index 0fc7ef74..966c2a71 100644 --- a/docs/codespaces.md +++ b/docs/codespaces.md @@ -40,4 +40,46 @@ make -j ### Example runs 1. performance test in the container `./g3log-performance-threaded_mean 4` 2. unit tests `ctest -v` -3. Try a fatal example with dumped stack trace `./g3log-FATAL-contract` \ No newline at end of file +3. Try a fatal example with dumped stack trace `./g3log-FATAL-contract` + + +### Example with Debugging. +Without any need to set up environment on your local machine you can also use Codespaces to debug examples, unit tests etc of g3log. +The pesky thing with VSCode, especially with cmake is to set up the launh.json. +It's a little bit easier if you open a VSCode terminal and do the cmake configuration and build there. Then the `launch.json` only needs to +contain information about the pecific executable. + +Here we try out the `g3log-FATAL-contract` after cmake configure with `-DCMAKE_BUILD_TYPE=Debug` +``` +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + // Remember to build the specific part of cmake with + // "cmake -DCMAKE_BUILD_TYPE=Debug" if you want to be able to debug it. + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Start", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/g3log-FATAL-contract", + "MIMode": "gdb", + "cwd": "${workspaceFolder}/build" + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + } + + ] +} +``` \ No newline at end of file From 17b8e407f996a15d4f5d3268b02def665fdee379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjell=20Hedstr=C3=B6m?= <331742+KjellKod@users.noreply.github.com> Date: Thu, 30 Nov 2023 12:30:19 -0700 Subject: [PATCH 07/14] test --- docs/codespaces.md | 4 +- src/g3log.cpp | 129 ++++++++++++++++++++++++-------------------- src/g3log/g3log.hpp | 2 + 3 files changed, 75 insertions(+), 60 deletions(-) diff --git a/docs/codespaces.md b/docs/codespaces.md index 966c2a71..4b60d4f7 100644 --- a/docs/codespaces.md +++ b/docs/codespaces.md @@ -11,8 +11,8 @@ For an introduction to codespaces you can check out [example c++ codespace](http 1. List all your codespaces `gh codespace list` 2. Create a new codespace `gh codespace create -r OWNER/REPO_NAME [-b BRANCH]`. Ref [docs/github: Creating a codespace for a repository](https://docs.github.com/en/codespaces/developing-in-a-codespace/creating-a-codespace-for-a-repository) 3. View codebase details `gh codespace view` -4. Stop `gh codespace stop -c CODESPACE-NAME` -5. Delete `gh codespace delete -c CODESPACE-NAME` +4. Stop `gh codespace stop` +5. Delete `gh codespace delete` 6. Rebuild `gh codespace rebuild` 7. Rename `gh codespace edit -c CODESPACE-NAME -d DISPLAY-NAME` 8. SSH into REMOTE codespace `gh codespace ssh -c CODESPACE-NAME` diff --git a/src/g3log.cpp b/src/g3log.cpp index f93bb710..f9636d59 100644 --- a/src/g3log.cpp +++ b/src/g3log.cpp @@ -32,6 +32,7 @@ #include #include #include +#include "g3log.hpp" namespace { std::once_flag g_initialize_flag; @@ -162,8 +163,16 @@ namespace g3 { message.get()->write().append(entry); message.get()->setExpression(boolean_expression); + if (internal::wasFatal(level)) + { + saveFatalMessage(level, stack_trace, message, fatal_signal); + } else { + pushMessageToLogger(message); + } + } - if (internal::wasFatal(level)) { + void saveFatalMessage(const LEVELS &level, const char *stack_trace, g3::LogMessagePtr &message, int &fatal_signal) + { auto fatalhook = g_fatal_pre_logging_hook; // In case the fatal_pre logging actually will cause a crash in its turn // let's not do recursive crashing! @@ -176,79 +185,83 @@ namespace g3 { fatalhook(); message.get()->write().append(stack_trace); - if (g_fatal_hook_recursive_counter.load() > 1) { - message.get()->write() - .append("\n\n\nWARNING\n" - "A recursive crash detected. It is likely the hook set with 'setFatalPreLoggingHook(...)' is responsible\n\n") - .append("---First crash stacktrace: ").append(first_stack_trace).append("\n---End of first stacktrace\n"); + if (g_fatal_hook_recursive_counter.load() > 1) + { + message.get()->write().append("\n\n\nWARNING\n" + "A recursive crash detected. It is likely the hook set with 'setFatalPreLoggingHook(...)' is responsible\n\n") + .append("---First crash stacktrace: ") + .append(first_stack_trace) + .append("\n---End of first stacktrace\n"); } - FatalMessagePtr fatal_message { std::make_unique(*(message._move_only.get()), fatal_signal) }; + FatalMessagePtr fatal_message{std::make_unique(*(message._move_only.get()), fatal_signal)}; // At destruction, flushes fatal message to g3LogWorker // either we will stay here until the background worker has received the fatal // message, flushed the crash message to the sinks and exits with the same fatal signal //..... OR it's in unit-test mode then we throw a std::runtime_error (and never hit sleep) fatalCall(fatal_message); - } else { - pushMessageToLogger(message); - } } - - /** - * save the message to the logger. In case of called before the logger is instantiated - * the first message will be saved. Any following subsequent uninitialized log calls - * will be ignored. - * - * The first initialized log entry will also save the first uninitialized log message, if any - * @param log_entry to save to logger - */ - void pushMessageToLogger(LogMessagePtr incoming) { // todo rename to Push SavedMessage To Worker - // Uninitialized messages are ignored but does not CHECK/crash the logger - if (!internal::isLoggingInitialized()) { - std::call_once(g_set_first_uninitialized_flag, [&] { + /** + * save the message to the logger. In case of called before the logger is instantiated + * the first message will be saved. Any following subsequent uninitialized log calls + * will be ignored. + * + * The first initialized log entry will also save the first uninitialized log message, if any + * @param log_entry to save to logger + */ + void pushMessageToLogger(LogMessagePtr incoming) + { // todo rename to Push SavedMessage To Worker + // Uninitialized messages are ignored but does not CHECK/crash the logger + if (!internal::isLoggingInitialized()) + { + std::call_once(g_set_first_uninitialized_flag, [&] + { g_first_uninitialized_msg = incoming.release(); std::string err = {"LOGGER NOT INITIALIZED:\n\t\t"}; err.append(g_first_uninitialized_msg->message()); std::string& str = g_first_uninitialized_msg->write(); str.clear(); str.append(err); // replace content - std::cerr << str << std::endl; - }); - return; - } - - // logger is initialized - g_logger_instance->save(incoming); - } + std::cerr << str << std::endl; }); + return; + } - /** Fatal call saved to logger. This will trigger SIGABRT or other fatal signal - * to exit the program. After saving the fatal message the calling thread - * will sleep forever (i.e. until the background thread catches up, saves the fatal - * message and kills the software with the fatal signal. - */ - void pushFatalMessageToLogger(FatalMessagePtr message) { - if (!isLoggingInitialized()) { - std::ostringstream error; - error << "FATAL CALL but logger is NOT initialized\n" - << "CAUSE: " << message.get()->reason() - << "\nMessage: \n" << message.get()->toString() << std::flush; - std::cerr << error.str() << std::flush; - internal::exitWithDefaultSignalHandler(message.get()->_level, message.get()->_signal_id); + // logger is initialized + g_logger_instance->save(incoming); } - g_logger_instance->fatal(message); - while (shouldBlockForFatalHandling()) { - std::this_thread::sleep_for(std::chrono::seconds(1)); - } - } - /** The default, initial, handling to send a 'fatal' event to g3logworker - * the caller will stay here, eternally, until the software is aborted - * ... in the case of unit testing it is the given "Mock" fatalCall that will - * define the behaviour. - */ - void fatalCall(FatalMessagePtr message) { - g_fatal_to_g3logworker_function_ptr(FatalMessagePtr {std::move(message)}); - } + /** Fatal call saved to logger. This will trigger SIGABRT or other fatal signal + * to exit the program. After saving the fatal message the calling thread + * will sleep forever (i.e. until the background thread catches up, saves the fatal + * message and kills the software with the fatal signal. + */ + void pushFatalMessageToLogger(FatalMessagePtr message) + { + if (!isLoggingInitialized()) + { + std::ostringstream error; + error << "FATAL CALL but logger is NOT initialized\n" + << "CAUSE: " << message.get()->reason() + << "\nMessage: \n" + << message.get()->toString() << std::flush; + std::cerr << error.str() << std::flush; + internal::exitWithDefaultSignalHandler(message.get()->_level, message.get()->_signal_id); + } + g_logger_instance->fatal(message); + while (shouldBlockForFatalHandling()) + { + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + } + /** The default, initial, handling to send a 'fatal' event to g3logworker + * the caller will stay here, eternally, until the software is aborted + * ... in the case of unit testing it is the given "Mock" fatalCall that will + * define the behaviour. + */ + void fatalCall(FatalMessagePtr message) + { + g_fatal_to_g3logworker_function_ptr(FatalMessagePtr{std::move(message)}); + } - } // internal + } // internal } // g3 diff --git a/src/g3log/g3log.hpp b/src/g3log/g3log.hpp index 1a2dc81b..e5715d0a 100644 --- a/src/g3log/g3log.hpp +++ b/src/g3log/g3log.hpp @@ -110,6 +110,8 @@ namespace g3 { void saveMessage(const char *message, const char *file, int line, const char *function, const LEVELS &level, const char *boolean_expression, int fatal_signal, const char *stack_trace); +void saveFatalMessage(const LEVELS & level, const char * stack_trace, g3::LogMessagePtr &message, int &fatal_signal); + // forwards the message to all sinks void pushMessageToLogger(LogMessagePtr log_entry); From 6745a4a002b098d2b357b8a5c33e00214d9fca32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjell=20Hedstr=C3=B6m?= <331742+KjellKod@users.noreply.github.com> Date: Tue, 5 Dec 2023 20:08:33 -0700 Subject: [PATCH 08/14] merg fix --- .DS_Store | Bin 0 -> 8196 bytes docs/.DS_Store | Bin 0 -> 6148 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 .DS_Store create mode 100644 docs/.DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..83fa468f4831eb3282c575a2ecd56bb572662927 GIT binary patch literal 8196 zcmeHM&2G~`5T0#Q;t*N_0;xzKS#YgNN-3h^lBNwPQcIyp;Q%N&iCe5Xc9fr{s4B`G zo`F~3%!}|C+&RHFyKZE=ap6)_sk_nc?Ar6q?tVM7_Buo)iv8vS(JT=e$SiYN6k`(K z=X@ef1XpfD3gC%$$e~@Dr;pS+p{*}y1~dbj0nLDBKr?V27{D`|lacV;S9f)(8PE(| zNCtR+Fp*gn0y$JtZXGD(5dboU%QB&kbAZH{fh+`asHB9#raC={04jnbhEQH z?U5ZreU71KXce|?=z18li(fMKR}4Fq)XT(fOp|-rP~)L>%%)2{TN*{bci zEzf6ykVNo&qG{D0m0wUBO?WK4K>1K6kN1Hk{i= z$XReWTRLI`EgueG%OLjPL_K5<>Mk6F!_CIRCIt~fFVaT_h)t@Tg1~$uh?xNKFChzu zh+xxjp)wq*1ox{@DLQ|4i-`7R@U(aALKq=`Y>aO@%-N?9XVaKXJH$vL6NFHUAZOv` z+Zf+Ef@}*Te2G>GqpYG`MQsE3*Re)iPYAn+y^OT7f|c4xKrpl6v8S5m0hZ+1CVlWp%w59Lu$W5Qo9>y244exFL~5V;FU1VJ1v$l!+ z9+?yC4V9D-6!JI@DUaijqdyE$H=)XyLLi4q;tJCL{}8}$MEd#9?~VHTFJ16L7JmR# CA2&w; literal 0 HcmV?d00001 diff --git a/docs/.DS_Store b/docs/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..82b4dda05d9969f3fc310ab2dd39fa001ea869e8 GIT binary patch literal 6148 zcmeHKOG*Pl5Uq|uf83Hk*`QdVQF1&-_){Weo}#_31Y=-P1&5TFb#XQH_WyP{#5engZebtT`z;OBHA&#vKhhlepiT z#J${TH7Enhz+Yp4zujGG(iL^6LFw<87ln6d<5NURue-4k^=V0ST2KtHh;D&1^t!Mt zXiQTY6~=33;#H}KIAfa7V6&Gw%XsZ0dkl{uD!50^zVr&}H_sW*L-CxV#u@T)?r*9! z9~ti>BX3n*X@rO`Uc>`LxL8-kPq+&U&n@?Eh_C-{ROAWrQ+X^JFYl6{tG3Rw zRju+ge1DX#@&g92XR}mz4Ny@AlmTVHXMop-0LmCTOf1UMfkuu1z%tAt=<{y_`veX{ zhlxepff(xww64Y-F^qMGJ#gbfhlxe&PR1QRjLU4?3B^cu#1CXRnb4xP%78MEW?;u& z)_DKF+F`!uhl=1{ Xz#U-dFtG>=M1KT?25ppqUuED6J8;4P literal 0 HcmV?d00001 From dd00f608b0e5a5a72d436a5817cadb2dbe6aa107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjell=20Hedstr=C3=B6m?= <331742+KjellKod@users.noreply.github.com> Date: Mon, 27 Nov 2023 18:50:05 -0700 Subject: [PATCH 09/14] trying out codespaces --- docs/codespaces.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codespaces.md b/docs/codespaces.md index 966c2a71..1bdac716 100644 --- a/docs/codespaces.md +++ b/docs/codespaces.md @@ -82,4 +82,4 @@ Here we try out the `g3log-FATAL-contract` after cmake configure with `-DCMAKE_B ] } -``` \ No newline at end of file +``` From 074a81aad08abc2ce6173f21002bfb193ed344cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjell=20Hedstr=C3=B6m?= <331742+KjellKod@users.noreply.github.com> Date: Thu, 30 Nov 2023 12:30:19 -0700 Subject: [PATCH 10/14] test --- docs/codespaces.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/codespaces.md b/docs/codespaces.md index 1bdac716..26cff522 100644 --- a/docs/codespaces.md +++ b/docs/codespaces.md @@ -11,8 +11,8 @@ For an introduction to codespaces you can check out [example c++ codespace](http 1. List all your codespaces `gh codespace list` 2. Create a new codespace `gh codespace create -r OWNER/REPO_NAME [-b BRANCH]`. Ref [docs/github: Creating a codespace for a repository](https://docs.github.com/en/codespaces/developing-in-a-codespace/creating-a-codespace-for-a-repository) 3. View codebase details `gh codespace view` -4. Stop `gh codespace stop -c CODESPACE-NAME` -5. Delete `gh codespace delete -c CODESPACE-NAME` +4. Stop `gh codespace stop` +5. Delete `gh codespace delete` 6. Rebuild `gh codespace rebuild` 7. Rename `gh codespace edit -c CODESPACE-NAME -d DISPLAY-NAME` 8. SSH into REMOTE codespace `gh codespace ssh -c CODESPACE-NAME` From a4214d95c98c160667d1fe90203d1ce9fda53ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjell=20Hedstr=C3=B6m?= <331742+KjellKod@users.noreply.github.com> Date: Tue, 5 Dec 2023 20:12:48 -0700 Subject: [PATCH 11/14] fixed formatting --- src/g3log.cpp | 76 +++++++++++++++++++++++---------------------- src/g3log/g3log.hpp | 2 +- 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/src/g3log.cpp b/src/g3log.cpp index 6fe5df81..9b4386d4 100644 --- a/src/g3log.cpp +++ b/src/g3log.cpp @@ -147,42 +147,40 @@ namespace g3 { message.get()->write().append(entry); message.get()->setExpression(boolean_expression); - if (internal::wasFatal(level)) - { + if (internal::wasFatal(level)) { saveFatalMessage(level, stack_trace, message, fatal_signal); } else { pushMessageToLogger(message); } } - void saveFatalMessage(const LEVELS &level, const char *stack_trace, g3::LogMessagePtr &message, int &fatal_signal) - { - auto fatalhook = g_fatal_pre_logging_hook; - // In case the fatal_pre logging actually will cause a crash in its turn - // let's not do recursive crashing! - setFatalPreLoggingHook(g_pre_fatal_hook_that_does_nothing); - ++g_fatal_hook_recursive_counter; // thread safe counter - // "benign" race here. If two threads crashes, with recursive crashes - // then it's possible that the "other" fatal stack trace will be shown - // that's OK since it was anyhow the first crash detected - static const std::string first_stack_trace = stack_trace; - fatalhook(); - message.get()->write().append(stack_trace); - - if (g_fatal_hook_recursive_counter.load() > 1) - { - message.get()->write().append("\n\n\nWARNING\n" - "A recursive crash detected. It is likely the hook set with 'setFatalPreLoggingHook(...)' is responsible\n\n") - .append("---First crash stacktrace: ") - .append(first_stack_trace) - .append("\n---End of first stacktrace\n"); - } - FatalMessagePtr fatal_message{std::make_unique(*(message._move_only.get()), fatal_signal)}; - // At destruction, flushes fatal message to g3LogWorker - // either we will stay here until the background worker has received the fatal - // message, flushed the crash message to the sinks and exits with the same fatal signal - //..... OR it's in unit-test mode then we throw a std::runtime_error (and never hit sleep) - fatalCall(fatal_message); + void saveFatalMessage(const LEVELS& level, const char* stack_trace, g3::LogMessagePtr& message, int& fatal_signal) { + auto fatalhook = g_fatal_pre_logging_hook; + // In case the fatal_pre logging actually will cause a crash in its turn + // let's not do recursive crashing! + setFatalPreLoggingHook(g_pre_fatal_hook_that_does_nothing); + ++g_fatal_hook_recursive_counter; // thread safe counter + // "benign" race here. If two threads crashes, with recursive crashes + // then it's possible that the "other" fatal stack trace will be shown + // that's OK since it was anyhow the first crash detected + static const std::string first_stack_trace = stack_trace; + fatalhook(); + message.get()->write().append(stack_trace); + + if (g_fatal_hook_recursive_counter.load() > 1) { + message.get()->write().append( + "\n\n\nWARNING\n" + "A recursive crash detected. It is likely the hook set with 'setFatalPreLoggingHook(...)' is responsible\n\n") + .append("---First crash stacktrace: ") + .append(first_stack_trace) + .append("\n---End of first stacktrace\n"); + } + FatalMessagePtr fatal_message{std::make_unique(*(message._move_only.get()), fatal_signal)}; + // At destruction, flushes fatal message to g3LogWorker + // either we will stay here until the background worker has received the fatal + // message, flushed the crash message to the sinks and exits with the same fatal signal + //..... OR it's in unit-test mode then we throw a std::runtime_error (and never hit sleep) + fatalCall(fatal_message); } /** * save the message to the logger. In case of called before the logger is instantiated @@ -236,16 +234,20 @@ namespace g3 { std::this_thread::sleep_for(std::chrono::seconds(1)); } } + g_logger_instance->fatal(message); + while (shouldBlockForFatalHandling()) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + } - /** The default, initial, handling to send a 'fatal' event to g3logworker + /** The default, initial, handling to send a 'fatal' event to g3logworker * the caller will stay here, eternally, until the software is aborted * ... in the case of unit testing it is the given "Mock" fatalCall that will * define the behaviour. */ - void fatalCall(FatalMessagePtr message) - { - g_fatal_to_g3logworker_function_ptr(FatalMessagePtr{std::move(message)}); - } + void fatalCall(FatalMessagePtr message) { + g_fatal_to_g3logworker_function_ptr(FatalMessagePtr{std::move(message)}); + } - } // internal -} // g3 + } // namespace internal +} // namespace g3 diff --git a/src/g3log/g3log.hpp b/src/g3log/g3log.hpp index f8ae3151..37c54506 100644 --- a/src/g3log/g3log.hpp +++ b/src/g3log/g3log.hpp @@ -106,7 +106,7 @@ namespace g3 { void saveMessage(const char* message, const char* file, int line, const char* function, const LEVELS& level, const char* boolean_expression, int fatal_signal, const char* stack_trace); -void saveFatalMessage(const LEVELS & level, const char * stack_trace, g3::LogMessagePtr &message, int &fatal_signal); + void saveFatalMessage(const LEVELS& level, const char* stack_trace, g3::LogMessagePtr& message, int& fatal_signal); // forwards the message to all sinks void pushMessageToLogger(LogMessagePtr log_entry); From 8b64c08fbe96813bd589a3afe3c272d4c486701f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjell=20Hedstr=C3=B6m?= <331742+KjellKod@users.noreply.github.com> Date: Wed, 6 Dec 2023 03:30:34 +0000 Subject: [PATCH 12/14] replaced readme with master --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 03727696..e9f2301c 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ For more in-depth information please see the full usage description in [g3log.md ## Experiment and try-out g3log in Github Codespaces -ref: [CodeSpsces.md](docs/codespaces.md) +ref: [codespaces.md](docs/codespaces.md) ## 1. Easy usage in files From 25af3058113b97c4bdfc735a7e209dbf25781028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjell=20Hedstr=C3=B6m?= <331742+KjellKod@users.noreply.github.com> Date: Wed, 6 Dec 2023 03:32:09 +0000 Subject: [PATCH 13/14] replaced readme with master --- docs/codespaces.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/codespaces.md b/docs/codespaces.md index 26cff522..966c2a71 100644 --- a/docs/codespaces.md +++ b/docs/codespaces.md @@ -11,8 +11,8 @@ For an introduction to codespaces you can check out [example c++ codespace](http 1. List all your codespaces `gh codespace list` 2. Create a new codespace `gh codespace create -r OWNER/REPO_NAME [-b BRANCH]`. Ref [docs/github: Creating a codespace for a repository](https://docs.github.com/en/codespaces/developing-in-a-codespace/creating-a-codespace-for-a-repository) 3. View codebase details `gh codespace view` -4. Stop `gh codespace stop` -5. Delete `gh codespace delete` +4. Stop `gh codespace stop -c CODESPACE-NAME` +5. Delete `gh codespace delete -c CODESPACE-NAME` 6. Rebuild `gh codespace rebuild` 7. Rename `gh codespace edit -c CODESPACE-NAME -d DISPLAY-NAME` 8. SSH into REMOTE codespace `gh codespace ssh -c CODESPACE-NAME` @@ -82,4 +82,4 @@ Here we try out the `g3log-FATAL-contract` after cmake configure with `-DCMAKE_B ] } -``` +``` \ No newline at end of file From a77b28c5e10ccb0994299dcb92a7c7edcd6bc4ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjell=20Hedstr=C3=B6m?= <331742+KjellKod@users.noreply.github.com> Date: Tue, 5 Dec 2023 20:37:15 -0700 Subject: [PATCH 14/14] fixed format --- src/g3log.cpp | 51 ++++++++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/src/g3log.cpp b/src/g3log.cpp index 9b4386d4..fa35e41c 100644 --- a/src/g3log.cpp +++ b/src/g3log.cpp @@ -182,7 +182,7 @@ namespace g3 { //..... OR it's in unit-test mode then we throw a std::runtime_error (and never hit sleep) fatalCall(fatal_message); } - /** + /** * save the message to the logger. In case of called before the logger is instantiated * the first message will be saved. Any following subsequent uninitialized log calls * will be ignored. @@ -190,13 +190,10 @@ namespace g3 { * The first initialized log entry will also save the first uninitialized log message, if any * @param log_entry to save to logger */ - void pushMessageToLogger(LogMessagePtr incoming) - { // todo rename to Push SavedMessage To Worker - // Uninitialized messages are ignored but does not CHECK/crash the logger - if (!internal::isLoggingInitialized()) - { - std::call_once(g_set_first_uninitialized_flag, [&] - { + void pushMessageToLogger(LogMessagePtr incoming) { // todo rename to Push SavedMessage To Worker + // Uninitialized messages are ignored but does not CHECK/crash the logger + if (!internal::isLoggingInitialized()) { + std::call_once(g_set_first_uninitialized_flag, [&] { g_first_uninitialized_msg = incoming.release(); std::string err = {"LOGGER NOT INITIALIZED:\n\t\t"}; err.append(g_first_uninitialized_msg->message()); @@ -204,35 +201,27 @@ namespace g3 { str.clear(); str.append(err); // replace content std::cerr << str << std::endl; }); - return; - } - - // logger is initialized - g_logger_instance->save(incoming); + return; } - /** Fatal call saved to logger. This will trigger SIGABRT or other fatal signal + // logger is initialized + g_logger_instance->save(incoming); + } + + /** Fatal call saved to logger. This will trigger SIGABRT or other fatal signal * to exit the program. After saving the fatal message the calling thread * will sleep forever (i.e. until the background thread catches up, saves the fatal * message and kills the software with the fatal signal. */ - void pushFatalMessageToLogger(FatalMessagePtr message) - { - if (!isLoggingInitialized()) - { - std::ostringstream error; - error << "FATAL CALL but logger is NOT initialized\n" - << "CAUSE: " << message.get()->reason() - << "\nMessage: \n" - << message.get()->toString() << std::flush; - std::cerr << error.str() << std::flush; - internal::exitWithDefaultSignalHandler(message.get()->_level, message.get()->_signal_id); - } - g_logger_instance->fatal(message); - while (shouldBlockForFatalHandling()) - { - std::this_thread::sleep_for(std::chrono::seconds(1)); - } + void pushFatalMessageToLogger(FatalMessagePtr message) { + if (!isLoggingInitialized()) { + std::ostringstream error; + error << "FATAL CALL but logger is NOT initialized\n" + << "CAUSE: " << message.get()->reason() + << "\nMessage: \n" + << message.get()->toString() << std::flush; + std::cerr << error.str() << std::flush; + internal::exitWithDefaultSignalHandler(message.get()->_level, message.get()->_signal_id); } g_logger_instance->fatal(message); while (shouldBlockForFatalHandling()) {