Example #1
0
File: log.cpp Project: ronj/invent
      void saveMessage(const char* entry, const char* file, int line, const char* function, const LEVELS& level,
              const char* boolean_expression, int fatal_signal, const char* stack_trace) {
         LEVELS msgLevel{level};
         LogMessagePtr message{std2::make_unique<LogMessage>(file, line, function, msgLevel)};
         message.get()->write().append(entry);
         message.get()->setExpression(boolean_expression);

         if (internal::wasFatal(level)) {
            message.get()->write().append(stack_trace);
            FatalMessagePtr fatal_message{std2::make_unique<FatalMessage>(*(message._move_only.get()), fatal_signal)};
            // At destruction, flushes fatal message to g2LogWorker
            // 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);
         }
      }
Example #2
0
      /** explicits copy of all input. This is makes it possibly to use g3log across dynamically loaded libraries
      * i.e. (dlopen + dlsym)  */
      void saveMessage(const char *entry, const char *file, int line, const char *function, const LEVELS &level,
                       const char *boolean_expression, int fatal_signal, const char *stack_trace) {
         LEVELS msgLevel {level};
         LogMessagePtr message {std2::make_unique<LogMessage>(file, line, function, msgLevel)};
         message.get()->write().append(entry);
         message.get()->setExpression(boolean_expression);


         if (internal::wasFatal(level)) {
            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 { std2::make_unique<FatalMessage>(*(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);
         }
      }