mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-28 02:21:59 +00:00
Send LOGICAL_ERRORs to sentry
This is like an assert() in the code, so it is useful to know about them as well. Signed-off-by: Azat Khuzhin <a.khuzhin@semrush.com>
This commit is contained in:
parent
53cef82acd
commit
f4ad005249
@ -5,6 +5,7 @@
|
||||
#include <IO/WriteHelpers.h>
|
||||
#include <base/demangle.h>
|
||||
#include <Common/AtomicLogger.h>
|
||||
#include <Daemon/SentryWriter.h>
|
||||
#include <Common/ErrorCodes.h>
|
||||
#include <Common/Exception.h>
|
||||
#include <Common/LockMemoryExceptionInThread.h>
|
||||
@ -52,14 +53,20 @@ thread_local bool update_error_statistics = true;
|
||||
/// - Increments error codes statistics.
|
||||
void handle_error_code([[maybe_unused]] const std::string & msg, int code, bool remote, const Exception::FramePointers & trace)
|
||||
{
|
||||
if (code == ErrorCodes::LOGICAL_ERROR)
|
||||
{
|
||||
// In debug builds and builds with sanitizers, treat LOGICAL_ERROR as an assertion failure.
|
||||
// Log the message before we fail.
|
||||
#ifdef ABORT_ON_LOGICAL_ERROR
|
||||
if (code == ErrorCodes::LOGICAL_ERROR)
|
||||
{
|
||||
abortOnFailedAssertion(msg);
|
||||
}
|
||||
#else
|
||||
/// In release builds send it to sentry (if it is configured)
|
||||
SentryWriter::FramePointers frame_pointers;
|
||||
for (size_t i = 0; i < trace.size(); ++i)
|
||||
frame_pointers[i] = trace[i];
|
||||
SentryWriter::onFault(-code, msg, frame_pointers, /* offset= */ 0, trace.size());
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!update_error_statistics) [[unlikely]]
|
||||
return;
|
||||
|
@ -497,7 +497,7 @@ private:
|
||||
/// Send crash report to developers (if configured)
|
||||
if (sig != SanitizerTrap)
|
||||
{
|
||||
SentryWriter::onFault(sig, error_message, stack_trace);
|
||||
SentryWriter::onFault(sig, error_message, stack_trace.getFramePointers(), stack_trace.getOffset(), stack_trace.getSize());
|
||||
|
||||
/// Advice the user to send it manually.
|
||||
if (std::string_view(VERSION_OFFICIAL).contains("official build"))
|
||||
|
@ -139,14 +139,25 @@ void SentryWriter::shutdown()
|
||||
sentry_shutdown();
|
||||
}
|
||||
|
||||
void SentryWriter::onFault(int sig, const std::string & error_message, const StackTrace & stack_trace)
|
||||
void SentryWriter::onFault(int sig_or_error, const std::string & error_message, const FramePointers & frame_pointers, size_t offset, size_t size)
|
||||
{
|
||||
auto logger = getLogger("SentryWriter");
|
||||
if (initialized)
|
||||
{
|
||||
sentry_value_t event = sentry_value_new_message_event(SENTRY_LEVEL_FATAL, "fault", error_message.c_str());
|
||||
if (sig_or_error > 0)
|
||||
{
|
||||
int sig = sig_or_error;
|
||||
sentry_set_tag("signal", strsignal(sig)); // NOLINT(concurrency-mt-unsafe) // not thread-safe but ok in this context
|
||||
sentry_set_extra("signal_number", sentry_value_new_int32(sig));
|
||||
}
|
||||
else
|
||||
{
|
||||
/// Can be only LOGICAL_ERROR, but just in case.
|
||||
int code = -sig_or_error;
|
||||
sentry_set_tag("exception", DB::ErrorCodes::getName(code).data());
|
||||
sentry_set_extra("exception_code", sentry_value_new_int32(code));
|
||||
}
|
||||
|
||||
#if defined(__ELF__) && !defined(OS_FREEBSD)
|
||||
const String & build_id_hex = DB::SymbolIndex::instance().getBuildIDHex();
|
||||
@ -157,11 +168,8 @@ void SentryWriter::onFault(int sig, const std::string & error_message, const Sta
|
||||
|
||||
/// Prepare data for https://develop.sentry.dev/sdk/event-payloads/stacktrace/
|
||||
sentry_value_t sentry_frames = sentry_value_new_list();
|
||||
size_t stack_size = stack_trace.getSize();
|
||||
if (stack_size > 0)
|
||||
if (size > 0)
|
||||
{
|
||||
ssize_t offset = stack_trace.getOffset();
|
||||
|
||||
char instruction_addr[19]
|
||||
{
|
||||
'0', 'x',
|
||||
@ -191,7 +199,7 @@ void SentryWriter::onFault(int sig, const std::string & error_message, const Sta
|
||||
sentry_value_append(sentry_frames, sentry_frame);
|
||||
};
|
||||
|
||||
StackTrace::forEachFrame(stack_trace.getFramePointers(), offset, stack_size, sentry_add_stack_trace, /* fatal= */ true);
|
||||
StackTrace::forEachFrame(frame_pointers, offset, size, sentry_add_stack_trace, /* fatal= */ true);
|
||||
}
|
||||
|
||||
/// Prepare data for https://develop.sentry.dev/sdk/event-payloads/threads/
|
||||
@ -212,7 +220,7 @@ void SentryWriter::onFault(int sig, const std::string & error_message, const Sta
|
||||
|
||||
LOG_INFO(logger, "Sending crash report");
|
||||
sentry_capture_event(event);
|
||||
shutdown();
|
||||
/* shutdown(); */
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <Common/StackTrace.h>
|
||||
|
||||
|
||||
namespace Poco { namespace Util { class LayeredConfiguration; }}
|
||||
@ -19,9 +20,14 @@ namespace SentryWriter
|
||||
void initialize(Poco::Util::LayeredConfiguration & config);
|
||||
void shutdown();
|
||||
|
||||
using FramePointers = StackTrace::FramePointers;
|
||||
|
||||
/// Not signal safe and can't be called from a signal handler
|
||||
/// @param sig_or_error - signal if >= 0, otherwise exception code
|
||||
void onFault(
|
||||
int sig,
|
||||
int sig_or_error,
|
||||
const std::string & error_message,
|
||||
const StackTrace & stack_trace);
|
||||
const FramePointers & frame_pointers,
|
||||
size_t offset,
|
||||
size_t size);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user