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 <IO/WriteHelpers.h>
|
||||||
#include <base/demangle.h>
|
#include <base/demangle.h>
|
||||||
#include <Common/AtomicLogger.h>
|
#include <Common/AtomicLogger.h>
|
||||||
|
#include <Daemon/SentryWriter.h>
|
||||||
#include <Common/ErrorCodes.h>
|
#include <Common/ErrorCodes.h>
|
||||||
#include <Common/Exception.h>
|
#include <Common/Exception.h>
|
||||||
#include <Common/LockMemoryExceptionInThread.h>
|
#include <Common/LockMemoryExceptionInThread.h>
|
||||||
@ -52,14 +53,20 @@ thread_local bool update_error_statistics = true;
|
|||||||
/// - Increments error codes statistics.
|
/// - Increments error codes statistics.
|
||||||
void handle_error_code([[maybe_unused]] const std::string & msg, int code, bool remote, const Exception::FramePointers & trace)
|
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.
|
// In debug builds and builds with sanitizers, treat LOGICAL_ERROR as an assertion failure.
|
||||||
// Log the message before we fail.
|
// Log the message before we fail.
|
||||||
#ifdef ABORT_ON_LOGICAL_ERROR
|
#ifdef ABORT_ON_LOGICAL_ERROR
|
||||||
if (code == ErrorCodes::LOGICAL_ERROR)
|
|
||||||
{
|
|
||||||
abortOnFailedAssertion(msg);
|
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
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (!update_error_statistics) [[unlikely]]
|
if (!update_error_statistics) [[unlikely]]
|
||||||
return;
|
return;
|
||||||
|
@ -497,7 +497,7 @@ private:
|
|||||||
/// Send crash report to developers (if configured)
|
/// Send crash report to developers (if configured)
|
||||||
if (sig != SanitizerTrap)
|
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.
|
/// Advice the user to send it manually.
|
||||||
if (std::string_view(VERSION_OFFICIAL).contains("official build"))
|
if (std::string_view(VERSION_OFFICIAL).contains("official build"))
|
||||||
|
@ -139,14 +139,25 @@ void SentryWriter::shutdown()
|
|||||||
sentry_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");
|
auto logger = getLogger("SentryWriter");
|
||||||
if (initialized)
|
if (initialized)
|
||||||
{
|
{
|
||||||
sentry_value_t event = sentry_value_new_message_event(SENTRY_LEVEL_FATAL, "fault", error_message.c_str());
|
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_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));
|
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)
|
#if defined(__ELF__) && !defined(OS_FREEBSD)
|
||||||
const String & build_id_hex = DB::SymbolIndex::instance().getBuildIDHex();
|
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/
|
/// Prepare data for https://develop.sentry.dev/sdk/event-payloads/stacktrace/
|
||||||
sentry_value_t sentry_frames = sentry_value_new_list();
|
sentry_value_t sentry_frames = sentry_value_new_list();
|
||||||
size_t stack_size = stack_trace.getSize();
|
if (size > 0)
|
||||||
if (stack_size > 0)
|
|
||||||
{
|
{
|
||||||
ssize_t offset = stack_trace.getOffset();
|
|
||||||
|
|
||||||
char instruction_addr[19]
|
char instruction_addr[19]
|
||||||
{
|
{
|
||||||
'0', 'x',
|
'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);
|
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/
|
/// 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");
|
LOG_INFO(logger, "Sending crash report");
|
||||||
sentry_capture_event(event);
|
sentry_capture_event(event);
|
||||||
shutdown();
|
/* shutdown(); */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <Common/StackTrace.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco { namespace Util { class LayeredConfiguration; }}
|
namespace Poco { namespace Util { class LayeredConfiguration; }}
|
||||||
@ -19,9 +20,14 @@ namespace SentryWriter
|
|||||||
void initialize(Poco::Util::LayeredConfiguration & config);
|
void initialize(Poco::Util::LayeredConfiguration & config);
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
|
||||||
|
using FramePointers = StackTrace::FramePointers;
|
||||||
|
|
||||||
/// Not signal safe and can't be called from a signal handler
|
/// Not signal safe and can't be called from a signal handler
|
||||||
|
/// @param sig_or_error - signal if >= 0, otherwise exception code
|
||||||
void onFault(
|
void onFault(
|
||||||
int sig,
|
int sig_or_error,
|
||||||
const std::string & error_message,
|
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