mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 08:40:50 +00:00
Convert system.errors.stack_trace from String into Array(UInt64)
This should decrease overhead for the errors collecting.
This commit is contained in:
parent
912144307d
commit
7c07b43597
@ -9,7 +9,7 @@ Columns:
|
||||
- `value` ([UInt64](../../sql-reference/data-types/int-uint.md)) — the number of times this error has been happened.
|
||||
- `last_error_time` ([DateTime](../../sql-reference/data-types/datetime.md)) — time when the last error happened.
|
||||
- `last_error_message` ([String](../../sql-reference/data-types/string.md)) — message for the last error.
|
||||
- `last_error_stacktrace` ([String](../../sql-reference/data-types/string.md)) — stacktrace for the last error.
|
||||
- `last_error_trace` ([Array(UInt64)](../../sql-reference/data-types/array.md)) — A [stack trace](https://en.wikipedia.org/wiki/Stack_trace) which represents a list of physical addresses where the called methods are stored.
|
||||
- `remote` ([UInt8](../../sql-reference/data-types/int-uint.md)) — remote exception (i.e. received during one of the distributed query).
|
||||
|
||||
**Example**
|
||||
@ -25,3 +25,12 @@ LIMIT 1
|
||||
│ CANNOT_OPEN_FILE │ 76 │ 1 │
|
||||
└──────────────────┴──────┴───────┘
|
||||
```
|
||||
|
||||
``` sql
|
||||
WITH arrayMap(x -> demangle(addressToSymbol(x)), last_error_trace) AS all
|
||||
SELECT name, arrayStringConcat(all, '\n') AS res
|
||||
FROM system.errors
|
||||
LIMIT 1
|
||||
SETTINGS allow_introspection_functions=1\G
|
||||
```
|
||||
|
||||
|
@ -587,7 +587,7 @@ namespace ErrorCodes
|
||||
|
||||
ErrorCode end() { return END + 1; }
|
||||
|
||||
void increment(ErrorCode error_code, bool remote, const std::string & message, const std::string & stacktrace)
|
||||
void increment(ErrorCode error_code, bool remote, const std::string & message, const FramePointers & trace)
|
||||
{
|
||||
if (error_code >= end())
|
||||
{
|
||||
@ -596,10 +596,10 @@ namespace ErrorCodes
|
||||
error_code = end() - 1;
|
||||
}
|
||||
|
||||
values[error_code].increment(remote, message, stacktrace);
|
||||
values[error_code].increment(remote, message, trace);
|
||||
}
|
||||
|
||||
void ErrorPairHolder::increment(bool remote, const std::string & message, const std::string & stacktrace)
|
||||
void ErrorPairHolder::increment(bool remote, const std::string & message, const FramePointers & trace)
|
||||
{
|
||||
const auto now = std::chrono::system_clock::now();
|
||||
|
||||
@ -609,7 +609,7 @@ namespace ErrorCodes
|
||||
|
||||
++error.count;
|
||||
error.message = message;
|
||||
error.stacktrace = stacktrace;
|
||||
error.trace = trace;
|
||||
error.error_time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
|
||||
}
|
||||
ErrorPair ErrorPairHolder::get()
|
||||
|
@ -1,11 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
#include <mutex>
|
||||
#include <common/types.h>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <common/types.h>
|
||||
|
||||
/** Allows to count number of simultaneously happening error codes.
|
||||
* See also Exception.cpp for incrementing part.
|
||||
@ -19,6 +20,7 @@ namespace ErrorCodes
|
||||
/// ErrorCode identifier (index in array).
|
||||
using ErrorCode = int;
|
||||
using Value = size_t;
|
||||
using FramePointers = std::vector<void *>;
|
||||
|
||||
/// Get name of error_code by identifier.
|
||||
/// Returns statically allocated string.
|
||||
@ -33,7 +35,7 @@ namespace ErrorCodes
|
||||
/// Message for the last error.
|
||||
std::string message;
|
||||
/// Stacktrace for the last error.
|
||||
std::string stacktrace;
|
||||
FramePointers trace;
|
||||
};
|
||||
struct ErrorPair
|
||||
{
|
||||
@ -46,7 +48,7 @@ namespace ErrorCodes
|
||||
{
|
||||
public:
|
||||
ErrorPair get();
|
||||
void increment(bool remote, const std::string & message, const std::string & stacktrace);
|
||||
void increment(bool remote, const std::string & message, const FramePointers & trace);
|
||||
|
||||
private:
|
||||
ErrorPair value;
|
||||
@ -60,7 +62,7 @@ namespace ErrorCodes
|
||||
ErrorCode end();
|
||||
|
||||
/// Add value for specified error_code.
|
||||
void increment(ErrorCode error_code, bool remote, const std::string & message, const std::string & stacktrace);
|
||||
void increment(ErrorCode error_code, bool remote, const std::string & message, const FramePointers & trace);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ namespace ErrorCodes
|
||||
|
||||
/// - Aborts the process if error code is LOGICAL_ERROR.
|
||||
/// - Increments error codes statistics.
|
||||
void handle_error_code([[maybe_unused]] const std::string & msg, const std::string & stacktrace, int code, bool remote)
|
||||
void handle_error_code([[maybe_unused]] const std::string & msg, int code, bool remote, const Exception::FramePointers & trace)
|
||||
{
|
||||
// In debug builds and builds with sanitizers, treat LOGICAL_ERROR as an assertion failure.
|
||||
// Log the message before we fail.
|
||||
@ -47,20 +47,21 @@ void handle_error_code([[maybe_unused]] const std::string & msg, const std::stri
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
ErrorCodes::increment(code, remote, msg, stacktrace);
|
||||
|
||||
ErrorCodes::increment(code, remote, msg, trace);
|
||||
}
|
||||
|
||||
Exception::Exception(const std::string & msg, int code, bool remote_)
|
||||
: Poco::Exception(msg, code)
|
||||
, remote(remote_)
|
||||
{
|
||||
handle_error_code(msg, getStackTraceString(), code, remote);
|
||||
handle_error_code(msg, code, remote, getStackFramePointers());
|
||||
}
|
||||
|
||||
Exception::Exception(const std::string & msg, const Exception & nested, int code)
|
||||
: Poco::Exception(msg, nested, code)
|
||||
{
|
||||
handle_error_code(msg, getStackTraceString(), code, remote);
|
||||
handle_error_code(msg, code, remote, getStackFramePointers());
|
||||
}
|
||||
|
||||
Exception::Exception(CreateFromPocoTag, const Poco::Exception & exc)
|
||||
@ -101,6 +102,31 @@ std::string Exception::getStackTraceString() const
|
||||
#endif
|
||||
}
|
||||
|
||||
Exception::FramePointers Exception::getStackFramePointers() const
|
||||
{
|
||||
FramePointers trace;
|
||||
#ifdef STD_EXCEPTION_HAS_STACK_TRACE
|
||||
{
|
||||
trace.resize(get_stack_trace_size());
|
||||
for (size_t i = 0; i < trace.size(); ++i)
|
||||
{
|
||||
trace[i] = get_stack_trace_frames()[i];
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
size_t stack_trace_size = trace.getSize();
|
||||
size_t stack_trace_offset = trace.getOffset();
|
||||
trace.resize(stack_trace_size - stack_trace_offset);
|
||||
for (size_t i = stack_trace_offset; i < stack_trace_size; ++i)
|
||||
{
|
||||
trace[i] = trace.getFramePointers()[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return trace;
|
||||
}
|
||||
|
||||
|
||||
void throwFromErrno(const std::string & s, int code, int the_errno)
|
||||
{
|
||||
|
@ -24,6 +24,8 @@ namespace DB
|
||||
class Exception : public Poco::Exception
|
||||
{
|
||||
public:
|
||||
using FramePointers = std::vector<void *>;
|
||||
|
||||
Exception() = default;
|
||||
Exception(const std::string & msg, int code, bool remote_ = false);
|
||||
Exception(const std::string & msg, const Exception & nested, int code);
|
||||
@ -66,6 +68,8 @@ public:
|
||||
bool isRemoteException() const { return remote; }
|
||||
|
||||
std::string getStackTraceString() const;
|
||||
/// Used for system.errors
|
||||
FramePointers getStackFramePointers() const;
|
||||
|
||||
private:
|
||||
#ifndef STD_EXCEPTION_HAS_STACK_TRACE
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <DataTypes/DataTypeString.h>
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <DataTypes/DataTypeDateTime.h>
|
||||
#include <DataTypes/DataTypeArray.h>
|
||||
#include <Storages/System/StorageSystemErrors.h>
|
||||
#include <Common/ErrorCodes.h>
|
||||
#include <Interpreters/Context.h>
|
||||
@ -16,7 +17,7 @@ NamesAndTypesList StorageSystemErrors::getNamesAndTypes()
|
||||
{ "value", std::make_shared<DataTypeUInt64>() },
|
||||
{ "last_error_time", std::make_shared<DataTypeDateTime>() },
|
||||
{ "last_error_message", std::make_shared<DataTypeString>() },
|
||||
{ "last_error_stacktrace", std::make_shared<DataTypeString>() },
|
||||
{ "last_error_trace", std::make_shared<DataTypeArray>(std::make_shared<DataTypeUInt64>()) },
|
||||
{ "remote", std::make_shared<DataTypeUInt8>() },
|
||||
};
|
||||
}
|
||||
@ -34,7 +35,14 @@ void StorageSystemErrors::fillData(MutableColumns & res_columns, const Context &
|
||||
res_columns[col_num++]->insert(error.count);
|
||||
res_columns[col_num++]->insert(error.error_time_ms / 1000);
|
||||
res_columns[col_num++]->insert(error.message);
|
||||
res_columns[col_num++]->insert(error.stacktrace);
|
||||
{
|
||||
Array trace_array;
|
||||
trace_array.reserve(error.trace.size());
|
||||
for (size_t i = 0; i < error.trace.size(); ++i)
|
||||
trace_array.emplace_back(reinterpret_cast<intptr_t>(error.trace[i]));
|
||||
|
||||
res_columns[col_num++]->insert(trace_array);
|
||||
}
|
||||
res_columns[col_num++]->insert(remote);
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user