2162 lines
64 KiB
C
2162 lines
64 KiB
C
#include "ob_full_link_trace.h"
|
|
|
|
#include <time.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#if defined(_WIN32)
|
|
#include <windows.h>
|
|
#include <wincrypt.h>
|
|
#else
|
|
#include <sys/time.h>
|
|
#endif
|
|
|
|
#include "ob_rwlock.h"
|
|
#include "ma_global.h"
|
|
#include "mariadb_com.h"
|
|
#include "ob_protocol20.h"
|
|
#include "ob_serialize.h"
|
|
#include "ob_utils.h"
|
|
|
|
#define TYPE_LENGTH 2
|
|
#define LEN_LENGTH 4
|
|
#define FLT_SIZE sizeof(float)
|
|
#define DBL_SIZE sizeof(double)
|
|
|
|
#define UUID_PATTERN "%8.8lx-%4.4lx-%4.4lx-%4.4lx-%12.12lx"
|
|
#define TRACE_PATTERN "{\"trace_id\":\""UUID_PATTERN"\",\"name\":\"%s\",\"id\":\""UUID_PATTERN"\",\"start_ts\":%ld,\"end_ts\":%ld,\"parent_id\":\""UUID_PATTERN"\",\"is_follow\":%s"
|
|
#define UUID_TOSTRING(uuid) \
|
|
((uuid).high_ >> 32), ((uuid).high_ >> 16 & 0xffff), ((uuid).high_ & 0xffff), \
|
|
((uuid).low_ >> 48), ((uuid).low_ & 0xffffffffffff)
|
|
#define INIT_SPAN(trace, span) \
|
|
if (OB_NOT_NULL(span) && 0 == span->span_id_.high_) { \
|
|
span->span_id_.low_ = xorshift128plus(trace->uuid_random_seed); \
|
|
span->span_id_.high_ = span->start_ts_; \
|
|
}
|
|
|
|
#define sint1korr(A) (*((int8_t*)(A)))
|
|
|
|
#define FLT_EXTRA_INFO_DEF(id, type) (id2type[id] = type)
|
|
#define FLT_EXTRA_INFO_INIT() \
|
|
do \
|
|
{ \
|
|
/* FLT_DRIVER_SPAN_INFO */ \
|
|
FLT_EXTRA_INFO_DEF(FLT_DRIVER_SPAN , MYSQL_TYPE_VAR_STRING); \
|
|
/* APP_INFO */ \
|
|
FLT_EXTRA_INFO_DEF(FLT_CLIENT_IDENTIFIER, MYSQL_TYPE_VAR_STRING); \
|
|
FLT_EXTRA_INFO_DEF(FLT_MODULE, MYSQL_TYPE_VAR_STRING); \
|
|
FLT_EXTRA_INFO_DEF(FLT_ACTION, MYSQL_TYPE_VAR_STRING); \
|
|
FLT_EXTRA_INFO_DEF(FLT_CLIENT_INFO, MYSQL_TYPE_VAR_STRING); \
|
|
/* QUERY_INFO */ \
|
|
FLT_EXTRA_INFO_DEF(FLT_QUERY_START_TIMESTAMP, MYSQL_TYPE_LONGLONG); \
|
|
FLT_EXTRA_INFO_DEF(FLT_QUERY_END_TIMESTAMP, MYSQL_TYPE_LONGLONG); \
|
|
/* CONTROL_INFO */ \
|
|
FLT_EXTRA_INFO_DEF(FLT_LEVEL, MYSQL_TYPE_TINY); \
|
|
FLT_EXTRA_INFO_DEF(FLT_SAMPLE_PERCENTAGE, MYSQL_TYPE_DOUBLE); \
|
|
FLT_EXTRA_INFO_DEF(FLT_RECORD_POLICY, MYSQL_TYPE_TINY); \
|
|
FLT_EXTRA_INFO_DEF(FLT_PRINT_SAMPLE_PCT, MYSQL_TYPE_DOUBLE); \
|
|
FLT_EXTRA_INFO_DEF(FLT_SLOW_QUERY_THRES, MYSQL_TYPE_LONGLONG); \
|
|
/* SPAN_INFO */ \
|
|
FLT_EXTRA_INFO_DEF(FLT_TRACE_ENABLE, MYSQL_TYPE_TINY); \
|
|
FLT_EXTRA_INFO_DEF(FLT_FORCE_PRINT, MYSQL_TYPE_TINY); \
|
|
FLT_EXTRA_INFO_DEF(FLT_TRACE_ID, MYSQL_TYPE_VAR_STRING); \
|
|
FLT_EXTRA_INFO_DEF(FLT_REF_TYPE, MYSQL_TYPE_TINY); \
|
|
FLT_EXTRA_INFO_DEF(FLT_SPAN_ID, MYSQL_TYPE_VAR_STRING); \
|
|
/* SHOW_TRACE_SPAN */ \
|
|
FLT_EXTRA_INFO_DEF(FLT_DRV_SHOW_TRACE_SPAN, MYSQL_TYPE_VAR_STRING); \
|
|
FLT_EXTRA_INFO_DEF(FLT_PROXY_SHOW_TRACE_SPAN, MYSQL_TYPE_VAR_STRING); \
|
|
FLT_EXTRA_INFO_DEF(FLT_EXTRA_INFO_ID_END, MAX_NO_FIELD_TYPES); \
|
|
} while (0);
|
|
#define FLT_SERIALIZE_FUNC_SET(id, funcname) (flt_funcs[id] = (FLTFunc)FLT_SERIALIZE_FUNC(funcname))
|
|
#define FLT_SERIALIZE_FUNC_INIT() \
|
|
do \
|
|
{ \
|
|
/* FLT_DRIVER_SPAN_INFO */ \
|
|
FLT_SERIALIZE_FUNC_SET(FLT_DRIVER_SPAN_INFO, driverspaninfo); \
|
|
/* APP_INFO */ \
|
|
FLT_SERIALIZE_FUNC_SET(FLT_APP_INFO, appinfo); \
|
|
/* QUERY_INFO */ \
|
|
FLT_SERIALIZE_FUNC_SET(FLT_QUERY_INFO, queryinfo); \
|
|
/* CONTROL_INFO */ \
|
|
FLT_SERIALIZE_FUNC_SET(FLT_CONTROL_INFO, controlinfo); \
|
|
/* SPAN_INFO */ \
|
|
FLT_SERIALIZE_FUNC_SET(FLT_SPAN_INFO, spaninfo); \
|
|
/* SHOW_TRACE_SPAN */ \
|
|
FLT_SERIALIZE_FUNC_SET(FLT_TYPE_SHOW_TRACE_SPAN, showtracespan); \
|
|
} while (0);
|
|
|
|
const char *tag_str[FLT_TAG_MAX_TYPE] =
|
|
{
|
|
"command_name",
|
|
"client_host"
|
|
};
|
|
|
|
static ob_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
static int init_flag = 0;
|
|
static enum_field_types id2type[FLT_EXTRA_INFO_ID_END + 1];
|
|
static FLTFunc flt_funcs[FLT_EXTRA_INFO_TYPE_END + 1];
|
|
|
|
static uint64_t xorshift128plus(uint64_t *s);
|
|
|
|
inline void flt_set_send_trans_flag(FLTInfo *flt, my_bool flag)
|
|
{
|
|
if (OB_NOT_NULL(flt)) {
|
|
flt->in_trans_ = flag;
|
|
}
|
|
}
|
|
|
|
static inline double flt_get_pct(uint64_t *seed)
|
|
{
|
|
uint64_t rand64;
|
|
/* Use the method of generating random numbers in uuid to get random numbers */
|
|
rand64 = xorshift128plus(seed);
|
|
|
|
return (double)rand64 / UINT64_MAX;
|
|
}
|
|
|
|
int flt_init(FLTInfo *flt)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
|
|
if (OB_NOT_NULL(flt)) {
|
|
if (!init_flag) {
|
|
ob_mutex_lock(&init_mutex);
|
|
if (!init_flag) {
|
|
FLT_EXTRA_INFO_INIT(); // init id2type
|
|
FLT_SERIALIZE_FUNC_INIT(); // init flt_funcs
|
|
init_flag = 1;
|
|
}
|
|
ob_mutex_unlock(&init_mutex);
|
|
}
|
|
|
|
memset(flt, 0, sizeof(*flt));
|
|
|
|
flt->show_trace_span_.type_ = FLT_TYPE_SHOW_TRACE_SPAN;
|
|
flt->client_span_.type_ = FLT_DRIVER_SPAN_INFO;
|
|
flt->app_info_.type_ = FLT_APP_INFO;
|
|
flt->query_info_.type_ = FLT_QUERY_INFO;
|
|
flt->span_info_.type_ = FLT_SPAN_INFO;
|
|
flt->control_info_.type_ = FLT_CONTROL_INFO;
|
|
flt->in_trans_ = FALSE;
|
|
|
|
// init control info
|
|
flt->control_info_.level_ = -1;
|
|
flt->control_info_.sample_pct_ = -1;
|
|
flt->control_info_.rp_ = MAX_RECORD_POLICY;
|
|
flt->control_info_.print_sample_pct_ = -1;
|
|
flt->control_info_.slow_query_threshold_ = -1;
|
|
flt->control_info_.flt_show_trace_enable_ = 0;
|
|
|
|
if (OB_FAIL(trace_init(flt))) {
|
|
// trace init error;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void flt_end(FLTInfo *flt)
|
|
{
|
|
trace_end(flt);
|
|
}
|
|
|
|
my_bool flt_is_vaild(FLTInfo *flt)
|
|
{
|
|
my_bool ret = FALSE;
|
|
if (OB_ISNULL(flt)) {
|
|
// do nothing
|
|
} else {
|
|
FLTControlInfo *control = &flt->control_info_;
|
|
if (control->level_ > 0 && (control->sample_pct_ >= 0 && control->sample_pct_ <= 1) && control->rp_ < MAX_RECORD_POLICY &&
|
|
(control->print_sample_pct_ >= 0 && control->print_sample_pct_ <= 1)) {
|
|
ret = TRUE;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_build_request(MYSQL *mysql, FLTInfo *flt)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObTrace *trace = OBTRACE(flt);
|
|
ObSpanCtx *span;
|
|
|
|
if (OB_ISNULL(trace) || OB_ISNULL(flt)) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// build request
|
|
int32_t serialize_size = 0;
|
|
int32_t span_info_serialize_size = 0;
|
|
int32_t client_log_serialize_size = 0;
|
|
int32_t app_info_serialize_size = 0;
|
|
int32_t show_trace_serialize_size = 0;
|
|
int64_t tmp_trace_id_pos = 0;
|
|
int64_t tmp_span_id_pos = 0;
|
|
|
|
span = trace->last_active_span_;
|
|
|
|
if (TRUE == trace->trace_enable_ && NULL != span) {
|
|
INIT_SPAN(trace, span);
|
|
// When trace enable is true, span info needs to be sent
|
|
if (OB_FAIL(serialize_UUID(flt->trace_id_, UUID4_SERIALIZE_LEN, &tmp_trace_id_pos, &trace->trace_id_))) {
|
|
// error
|
|
} else if (OB_FAIL(serialize_UUID(flt->span_id_, UUID4_SERIALIZE_LEN, &tmp_span_id_pos, &span->span_id_))) {
|
|
// error
|
|
} else {
|
|
flt->span_info_.trace_id_ = flt->trace_id_;
|
|
flt->span_info_.span_id_ = flt->span_id_;
|
|
flt->span_info_.type_ = FLT_SPAN_INFO;
|
|
flt->span_info_.trace_enable_ = trace->trace_enable_;
|
|
flt->span_info_.force_print_ = trace->force_print_;
|
|
if (trace->force_print_) {
|
|
FLUSH_TRACE(flt);
|
|
}
|
|
}
|
|
} else {
|
|
flt->span_info_.trace_enable_ = FALSE;
|
|
}
|
|
|
|
if (OB_SUCC(ret)) {
|
|
if (0 != trace->log_buf_offset_) {
|
|
flt->client_span_.client_span_ = trace->log_buf_;
|
|
} else {
|
|
flt->client_span_.client_span_ = NULL;
|
|
}
|
|
|
|
if (1 < trace->show_trace_buf_offset_ && trace->show_trace_enable_) {
|
|
flt->show_trace_span_.client_span_json_ = trace->show_trace_buf_;
|
|
// Change the final comma to a parenthesis
|
|
trace->show_trace_buf_[trace->show_trace_buf_offset_ - 1] = ']';
|
|
} else {
|
|
flt->show_trace_span_.client_span_json_ = NULL;
|
|
}
|
|
|
|
if (OB_FAIL(flt_get_serialize_size_extra_info(&app_info_serialize_size, &flt->app_info_))) {
|
|
// error
|
|
} else if (OB_FAIL(flt_get_serialize_size_extra_info(&client_log_serialize_size, &flt->client_span_))) {
|
|
// error
|
|
} else if (OB_FAIL(flt_get_serialize_size_extra_info(&span_info_serialize_size, &flt->span_info_))) {
|
|
// error
|
|
} else if (OB_FAIL(flt_get_serialize_size_extra_info(&show_trace_serialize_size, &flt->show_trace_span_))) {
|
|
// error
|
|
} else {
|
|
serialize_size += app_info_serialize_size;
|
|
serialize_size += client_log_serialize_size;
|
|
serialize_size += span_info_serialize_size;
|
|
serialize_size += show_trace_serialize_size;
|
|
#ifdef DEBUG_OB20
|
|
printf("spaninfo ssize:%d, log ssize:%d, appinfo ssize:%d, show trace ssize:%d\n", span_info_serialize_size,
|
|
client_log_serialize_size, app_info_serialize_size, show_trace_serialize_size);
|
|
if (0 != client_log_serialize_size) {
|
|
printf("log:%s\n", flt->client_span_.client_span_);
|
|
}
|
|
if (0 != show_trace_serialize_size) {
|
|
printf("log:%s\n", flt->show_trace_span_.client_span_json_);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if (OB_SUCC(ret) && 0 != serialize_size) {
|
|
if (MAX_FLT_SERIALIZE_SIZE < serialize_size) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
int64_t pos = 0;
|
|
|
|
flt->flt_value_data_.length = serialize_size;
|
|
flt->flt_value_data_.value_data_ = trace->flt_serialize_buf_;
|
|
|
|
if (OB_FAIL(flt_serialize_extra_info(flt->flt_value_data_.value_data_, serialize_size, &pos, &flt->span_info_))) {
|
|
// error
|
|
} else if (pos != span_info_serialize_size) {
|
|
ret = OB_ERROR;
|
|
} else if (0 != client_log_serialize_size && OB_FAIL(flt_serialize_extra_info(flt->flt_value_data_.value_data_, serialize_size, &pos, &flt->client_span_))) {
|
|
// error
|
|
} else if (pos != span_info_serialize_size + client_log_serialize_size) {
|
|
ret = OB_ERROR;
|
|
} else if (0 != show_trace_serialize_size && OB_FAIL(flt_serialize_extra_info(flt->flt_value_data_.value_data_, serialize_size, &pos, &flt->show_trace_span_))) {
|
|
// error
|
|
} else if (pos != span_info_serialize_size + client_log_serialize_size + show_trace_serialize_size) {
|
|
ret = OB_ERROR;
|
|
} else if (0 != app_info_serialize_size && OB_FAIL(flt_serialize_extra_info(flt->flt_value_data_.value_data_, serialize_size, &pos, &flt->app_info_))) {
|
|
// error
|
|
} else if (pos != serialize_size) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
if (0 != app_info_serialize_size) {
|
|
// clear app info
|
|
memset(&flt->app_info_, 0, sizeof(flt->app_info_));
|
|
flt->app_info_.type_ = FLT_APP_INFO;
|
|
}
|
|
// reset the log buf offset
|
|
trace->log_buf_offset_ = 0;
|
|
flt->client_span_.client_span_ = NULL;
|
|
// reset show trace log buffer
|
|
trace->show_trace_buf_[0] = '[';
|
|
trace->show_trace_buf_offset_ = 1;
|
|
flt->show_trace_span_.client_span_json_ = NULL;
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
if (OB_FAIL(ob20_set_extra_info(mysql, FULL_TRC, &flt->flt_value_data_))) {
|
|
// error
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int flt_deserialize_extra_info(const char *buf, const int64_t len, int64_t *pos, FullLinkTraceExtraInfoType type, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
while (OB_SUCC(ret) && *pos < len) {
|
|
int32_t val_len = 0;
|
|
int16_t extra_id;
|
|
if (OB_FAIL(flt_resolve_type_and_len(buf, len, pos, &extra_id, &val_len))) {
|
|
ret = OB_ERROR;
|
|
} else if (OB_FAIL(flt_funcs[type].deserialize_field_func((FullLinkTraceExtraInfoId)(extra_id), val_len, buf, len, pos, flt_info))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_serialize_extra_info(char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
FullLinkTraceExtraInfoType type = ((FLTInfoBase *)flt_info)->type_;
|
|
|
|
ret = flt_funcs[type].serialize_func(buf, len, pos, flt_info);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int flt_get_serialize_size_extra_info(int32_t *size, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
FullLinkTraceExtraInfoType type = ((FLTInfoBase *)flt_info)->type_;
|
|
|
|
ret = flt_funcs[type].get_serialize_size_func(size, flt_info);
|
|
|
|
return ret;
|
|
}
|
|
|
|
// for control info
|
|
int flt_get_serialize_size_controlinfo(int32_t *size, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int32_t local_size = 0;
|
|
UNUSED(flt_info);
|
|
|
|
local_size += TYPE_LENGTH + LEN_LENGTH;
|
|
local_size += flt_get_store_int1_size(); // type_
|
|
local_size += flt_get_store_double_size(); // sample_pct_
|
|
local_size += flt_get_store_int1_size(); // rp_
|
|
local_size += flt_get_store_double_size(); // print_sample_pct_
|
|
local_size += flt_get_store_int8_size(); // slow_query_threshold_
|
|
local_size += flt_get_store_int8_size(); // flt_show_trace_enable_
|
|
|
|
*size = local_size;
|
|
return ret;
|
|
}
|
|
|
|
int flt_serialize_controlinfo(char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t org_pos = *pos;
|
|
FLTControlInfo *control_info = (FLTControlInfo *)flt_info;
|
|
// resrver for type and len
|
|
if (*pos + 6 > len) {
|
|
ret = OB_SIZE_OVERFLOW;
|
|
} else {
|
|
*pos += 6;
|
|
}
|
|
if (OB_FAIL(ret)) {
|
|
// do nothing
|
|
} else if (OB_FAIL(flt_store_int1(buf, len, pos, control_info->level_, FLT_LEVEL))) {
|
|
ret = OB_ERROR;
|
|
} else if (OB_FAIL(flt_store_double(buf, len, pos, control_info->sample_pct_, FLT_SAMPLE_PERCENTAGE))) {
|
|
ret = OB_ERROR;
|
|
} else if (OB_FAIL(flt_store_int1(buf, len, pos, control_info->rp_, FLT_RECORD_POLICY))) {
|
|
ret = OB_ERROR;
|
|
} else if (OB_FAIL(flt_store_double(buf, len, pos, control_info->print_sample_pct_, FLT_PRINT_SAMPLE_PCT))) {
|
|
ret = OB_ERROR;
|
|
} else if (OB_FAIL(flt_store_int8(buf, len, pos, control_info->slow_query_threshold_, FLT_SLOW_QUERY_THRES))) {
|
|
ret = OB_ERROR;
|
|
} else if (OB_FAIL(flt_store_int8(buf, len, pos, control_info->flt_show_trace_enable_, FLT_SHOW_TRACE_ENABLE))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// fill type and len in the head
|
|
int32_t total_len = *pos - org_pos - 6;
|
|
if (OB_FAIL(flt_store_type_and_len(buf, len, &org_pos, control_info->type_, total_len))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_deserialize_field_controlinfo(FullLinkTraceExtraInfoId extra_id, const int64_t v_len,
|
|
const char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
FLTControlInfo *flt_control_info = (FLTControlInfo *)flt_info;
|
|
switch(extra_id) {
|
|
case FLT_LEVEL: {
|
|
if (OB_FAIL(flt_get_int1(buf, len, pos, v_len, &flt_control_info->level_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
#ifdef DEBUG_OB20
|
|
printf("level is %hhd\n", flt_control_info->level_);
|
|
#endif
|
|
}
|
|
break;
|
|
}
|
|
case FLT_SAMPLE_PERCENTAGE: {
|
|
if (OB_FAIL(flt_get_double(buf, len, pos, v_len, &flt_control_info->sample_pct_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
#ifdef DEBUG_OB20
|
|
printf("sample_pct is %f\n", flt_control_info->sample_pct_);
|
|
#endif
|
|
}
|
|
break;
|
|
}
|
|
case FLT_RECORD_POLICY: {
|
|
int8_t v = 0;
|
|
if (OB_FAIL(flt_get_int1(buf, len, pos, v_len, &v))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
flt_control_info->rp_ = v;
|
|
#ifdef DEBUG_OB20
|
|
printf("rp is %d\n", flt_control_info->rp_);
|
|
#endif
|
|
}
|
|
break;
|
|
}
|
|
case FLT_PRINT_SAMPLE_PCT: {
|
|
if (OB_FAIL(flt_get_double(buf, len, pos, v_len, &flt_control_info->print_sample_pct_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
#ifdef DEBUG_OB20
|
|
printf("print_sample_pct is %f\n", flt_control_info->print_sample_pct_);
|
|
#endif
|
|
}
|
|
break;
|
|
}
|
|
case FLT_SLOW_QUERY_THRES: {
|
|
if (OB_FAIL(flt_get_int8(buf, len, pos, v_len, &flt_control_info->slow_query_threshold_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
#ifdef DEBUG_OB20
|
|
printf("slow_query_threshold is %ld\n", flt_control_info->slow_query_threshold_);
|
|
#endif
|
|
}
|
|
break;
|
|
}
|
|
case FLT_SHOW_TRACE_ENABLE: {
|
|
if (OB_FAIL(flt_get_int1(buf, len, pos, v_len, &flt_control_info->flt_show_trace_enable_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
#ifdef DEBUG_OB20
|
|
printf("show_trace_enable is %hhd\n", flt_control_info->flt_show_trace_enable_);
|
|
#endif
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
// 这里碰到不能识别的key直接跳过
|
|
*pos += *pos + v_len;
|
|
break;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
// for control info
|
|
|
|
// for app info
|
|
int flt_get_serialize_size_appinfo(int32_t *size, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int32_t local_size = 0;
|
|
FLTAppInfo *app_info = (FLTAppInfo *)flt_info;
|
|
|
|
if (OB_NOT_NULL(app_info->identifier_)) {
|
|
local_size += flt_get_store_str_size(strlen(app_info->identifier_));
|
|
}
|
|
if (OB_NOT_NULL(app_info->module_)) {
|
|
local_size += flt_get_store_str_size(strlen(app_info->module_));
|
|
}
|
|
if (OB_NOT_NULL(app_info->action_)) {
|
|
local_size += flt_get_store_str_size(strlen(app_info->action_));
|
|
}
|
|
if (OB_NOT_NULL(app_info->client_info_)) {
|
|
local_size += flt_get_store_str_size(strlen(app_info->client_info_));
|
|
}
|
|
if (0 != local_size) {
|
|
local_size += TYPE_LENGTH + LEN_LENGTH;
|
|
}
|
|
|
|
*size = local_size;
|
|
return ret;
|
|
}
|
|
|
|
int flt_serialize_appinfo(char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t org_pos = *pos;
|
|
FLTAppInfo *app_info = (FLTAppInfo *)flt_info;
|
|
// resrver for type and len
|
|
if (*pos + 6 > len) {
|
|
ret = OB_SIZE_OVERFLOW;
|
|
} else {
|
|
*pos += 6;
|
|
}
|
|
if (OB_FAIL(ret)) {
|
|
// do nothing
|
|
} else if (OB_NOT_NULL(app_info->identifier_) && OB_FAIL(flt_store_str(buf, len, pos, app_info->identifier_, strlen(app_info->identifier_), FLT_CLIENT_IDENTIFIER))) {
|
|
ret = OB_ERROR;
|
|
} else if (OB_NOT_NULL(app_info->module_) && OB_FAIL(flt_store_str(buf, len, pos, app_info->module_, strlen(app_info->module_), FLT_MODULE))) {
|
|
ret = OB_ERROR;
|
|
} else if (OB_NOT_NULL(app_info->action_) && OB_FAIL(flt_store_str(buf, len, pos, app_info->action_, strlen(app_info->action_), FLT_ACTION))) {
|
|
ret = OB_ERROR;
|
|
} else if (OB_NOT_NULL(app_info->client_info_) && OB_FAIL(flt_store_str(buf, len, pos, app_info->client_info_, strlen(app_info->client_info_), FLT_CLIENT_INFO))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// fill type and len in the head
|
|
int32_t total_len = *pos - org_pos - 6;
|
|
if (OB_FAIL(flt_store_type_and_len(buf, len, &org_pos, app_info->type_, total_len))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_deserialize_field_appinfo(FullLinkTraceExtraInfoId extra_id, const int64_t v_len,
|
|
const char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
FLTAppInfo *app_info = (FLTAppInfo *)flt_info;
|
|
switch(extra_id) {
|
|
case FLT_CLIENT_IDENTIFIER: {
|
|
if (OB_FAIL(flt_get_str(buf, len, pos, v_len, (char **)&app_info->identifier_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
break;
|
|
}
|
|
case FLT_MODULE: {
|
|
if (OB_FAIL(flt_get_str(buf, len, pos, v_len, (char **)&app_info->module_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
break;
|
|
}
|
|
case FLT_ACTION: {
|
|
if (OB_FAIL(flt_get_str(buf, len, pos, v_len, (char **)&app_info->action_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
break;
|
|
}
|
|
case FLT_CLIENT_INFO: {
|
|
if (OB_FAIL(flt_get_str(buf, len, pos, v_len, (char **)&app_info->client_info_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
// get an unrecognized key here, skip it directly
|
|
*pos += *pos + v_len;
|
|
break;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
// for app info
|
|
|
|
// for queryinfo
|
|
int flt_get_serialize_size_queryinfo(int32_t *size, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int32_t local_size = 0;
|
|
UNUSED(flt_info);
|
|
|
|
local_size += TYPE_LENGTH + LEN_LENGTH;
|
|
local_size += flt_get_store_int8_size();
|
|
local_size += flt_get_store_int8_size();
|
|
|
|
*size = local_size;
|
|
return ret;
|
|
}
|
|
|
|
int flt_serialize_queryinfo(char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t org_pos = *pos;
|
|
FLTQueryInfo *query_info = (FLTQueryInfo *)flt_info;
|
|
// resrver for type and len
|
|
if (*pos + 6 > len) {
|
|
ret = OB_SIZE_OVERFLOW;
|
|
} else {
|
|
*pos += 6;
|
|
}
|
|
if (OB_FAIL(ret)) {
|
|
// do nothing
|
|
} else if (OB_FAIL(flt_store_int8(buf, len, pos, query_info->query_start_timestamp_, FLT_QUERY_START_TIMESTAMP))) {
|
|
ret = OB_ERROR;
|
|
} else if (OB_FAIL(flt_store_int8(buf, len, pos, query_info->query_end_timestamp_, FLT_QUERY_END_TIMESTAMP))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// fill type and len in the head
|
|
int32_t total_len = *pos - org_pos - 6;
|
|
if (OB_FAIL(flt_store_type_and_len(buf, len, &org_pos, query_info->type_, total_len))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
int flt_deserialize_field_queryinfo(FullLinkTraceExtraInfoId extra_id, const int64_t v_len,
|
|
const char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
FLTQueryInfo *query_info = (FLTQueryInfo *)flt_info;
|
|
switch(extra_id) {
|
|
case FLT_QUERY_START_TIMESTAMP: {
|
|
if (OB_FAIL(flt_get_int8(buf, len, pos, v_len, &query_info->query_start_timestamp_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
break;
|
|
}
|
|
case FLT_QUERY_END_TIMESTAMP: {
|
|
if (OB_FAIL(flt_get_int8(buf, len, pos, v_len, &query_info->query_end_timestamp_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
// get an unrecognized key here, skip it directly
|
|
*pos += *pos + v_len;
|
|
break;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
// for queryinfo
|
|
|
|
// for spaninfo
|
|
int flt_get_serialize_size_spaninfo(int32_t *size, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int32_t local_size = 0;
|
|
FLTSpanInfo *span_info = (FLTSpanInfo *)flt_info;
|
|
// FLTSpanInfo *span_info = (FLTSpanInfo *)flt_info;
|
|
|
|
// If trace is enabled, other fields need to be sent
|
|
if (TRUE == span_info->trace_enable_) {
|
|
local_size += TYPE_LENGTH + LEN_LENGTH;
|
|
local_size += flt_get_store_int1_size();
|
|
local_size += flt_get_store_int1_size();
|
|
local_size += flt_get_store_str_size(UUID4_SERIALIZE_LEN);
|
|
local_size += flt_get_store_int1_size();
|
|
local_size += flt_get_store_str_size(UUID4_SERIALIZE_LEN);
|
|
}
|
|
|
|
*size = local_size;
|
|
return ret;
|
|
}
|
|
|
|
int flt_serialize_spaninfo(char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t org_pos = *pos;
|
|
FLTSpanInfo *span_info = (FLTSpanInfo *)flt_info;
|
|
// resrver for type and len
|
|
if (TRUE == span_info->trace_enable_) {
|
|
if (*pos + 6 > len) {
|
|
ret = OB_SIZE_OVERFLOW;
|
|
} else {
|
|
*pos += 6;
|
|
}
|
|
if (OB_FAIL(ret)) {
|
|
// do nothing
|
|
} else if (OB_FAIL(flt_store_int1(buf, len, pos, span_info->trace_enable_, FLT_TRACE_ENABLE))) {
|
|
ret = OB_ERROR;
|
|
} else if (OB_FAIL(flt_store_int1(buf, len, pos, span_info->force_print_, FLT_FORCE_PRINT))) {
|
|
ret = OB_ERROR;
|
|
} else if (OB_FAIL(flt_store_str(buf, len, pos, span_info->trace_id_, UUID4_SERIALIZE_LEN, FLT_TRACE_ID))) {
|
|
ret = OB_ERROR;
|
|
} else if (OB_FAIL(flt_store_int1(buf, len, pos, span_info->ref_type_, FLT_REF_TYPE))) {
|
|
ret = OB_ERROR;
|
|
} else if (OB_FAIL(flt_store_str(buf, len, pos, span_info->span_id_, UUID4_SERIALIZE_LEN, FLT_SPAN_ID))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// success
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
// fill type and len in the head
|
|
int32_t total_len = *pos - org_pos - 6;
|
|
if (OB_FAIL(flt_store_type_and_len(buf, len, &org_pos, span_info->type_, total_len))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_deserialize_field_spaninfo(FullLinkTraceExtraInfoId extra_id, const int64_t v_len,
|
|
const char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
FLTSpanInfo *span_info = (FLTSpanInfo *)flt_info;
|
|
switch(extra_id) {
|
|
case FLT_TRACE_ENABLE: {
|
|
if (OB_FAIL(flt_get_int1(buf, len, pos, v_len, &span_info->trace_enable_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
break;
|
|
}
|
|
case FLT_FORCE_PRINT: {
|
|
if (OB_FAIL(flt_get_int1(buf, len, pos, v_len, &span_info->force_print_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
break;
|
|
}
|
|
case FLT_TRACE_ID: {
|
|
if (OB_FAIL(flt_get_str(buf, len, pos, v_len, (char **)&span_info->trace_id_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
break;
|
|
}
|
|
case FLT_REF_TYPE: {
|
|
if (OB_FAIL(flt_get_int1(buf, len, pos, v_len, &span_info->ref_type_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
break;
|
|
}
|
|
case FLT_SPAN_ID: {
|
|
if (OB_FAIL(flt_get_str(buf, len, pos, v_len, (char **)&span_info->span_id_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
*pos += *pos + v_len;
|
|
break;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
// for spaninfo
|
|
|
|
// for driverspaninfo info
|
|
int flt_get_serialize_size_driverspaninfo(int32_t *size, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int32_t local_size = 0;
|
|
FLTDriverSpanInfo *client_info = (FLTDriverSpanInfo *)flt_info;
|
|
|
|
if (NULL != client_info->client_span_) {
|
|
local_size += TYPE_LENGTH + LEN_LENGTH;
|
|
local_size += flt_get_store_str_size(strlen(client_info->client_span_) + 1);
|
|
}
|
|
|
|
*size = local_size;
|
|
return ret;
|
|
}
|
|
|
|
int flt_serialize_driverspaninfo(char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t org_pos = *pos;
|
|
FLTDriverSpanInfo *client_info = (FLTDriverSpanInfo *)flt_info;
|
|
// resrver for type and len
|
|
if (*pos + 6 > len) {
|
|
ret = OB_SIZE_OVERFLOW;
|
|
} else {
|
|
*pos += 6;
|
|
}
|
|
if (OB_FAIL(ret)) {
|
|
// do nothing
|
|
} else if (OB_FAIL(flt_store_str(buf, len, pos, client_info->client_span_, strlen(client_info->client_span_) + 1, FLT_DRIVER_SPAN))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// fill type and len in the head
|
|
int32_t total_len = *pos - org_pos - 6;
|
|
if (OB_FAIL(flt_store_type_and_len(buf, len, &org_pos, client_info->type_, total_len))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_deserialize_field_driverspaninfo(FullLinkTraceExtraInfoId extra_id, const int64_t v_len,
|
|
const char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
FLTDriverSpanInfo *client_info = (FLTDriverSpanInfo *)flt_info;
|
|
switch(extra_id) {
|
|
case FLT_CLIENT_IDENTIFIER: {
|
|
if (OB_FAIL(flt_get_str(buf, len, pos, v_len, (char **)&client_info->client_span_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
*pos += *pos + v_len;
|
|
break;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
// for driverspaninfo info
|
|
|
|
// for show trace span
|
|
int flt_get_serialize_size_showtracespan(int32_t *size, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int32_t local_size = 0;
|
|
FLTShowTraceSpan *show_trace_span = (FLTShowTraceSpan *)flt_info;
|
|
|
|
if (NULL != show_trace_span->client_span_json_) {
|
|
local_size += TYPE_LENGTH + LEN_LENGTH;
|
|
local_size += flt_get_store_str_size(strlen(show_trace_span->client_span_json_) + 1);
|
|
}
|
|
|
|
*size = local_size;
|
|
return ret;
|
|
}
|
|
|
|
int flt_serialize_showtracespan(char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t org_pos = *pos;
|
|
FLTShowTraceSpan *show_trace_span = (FLTShowTraceSpan *)flt_info;
|
|
// resrver for type and len
|
|
if (*pos + 6 > len) {
|
|
ret = OB_SIZE_OVERFLOW;
|
|
} else {
|
|
*pos += 6;
|
|
}
|
|
if (OB_FAIL(ret)) {
|
|
// do nothing
|
|
} else if (OB_FAIL(flt_store_str(buf, len, pos, show_trace_span->client_span_json_, strlen(show_trace_span->client_span_json_) + 1, FLT_DRV_SHOW_TRACE_SPAN))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// fill type and len in the head
|
|
int32_t total_len = *pos - org_pos - 6;
|
|
if (OB_FAIL(flt_store_type_and_len(buf, len, &org_pos, show_trace_span->type_, total_len))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_deserialize_field_showtracespan(FullLinkTraceExtraInfoId extra_id, const int64_t v_len,
|
|
const char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
FLTShowTraceSpan *show_trace_span = (FLTShowTraceSpan *)flt_info;
|
|
switch(extra_id) {
|
|
case FLT_CLIENT_IDENTIFIER: {
|
|
if (OB_FAIL(flt_get_str(buf, len, pos, v_len, (char **)&show_trace_span->client_span_json_))) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
*pos += *pos + v_len;
|
|
break;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
// for driverspaninfo info
|
|
|
|
// for no support
|
|
int flt_deserialize_field_nosupport(FullLinkTraceExtraInfoId extra_id, const int64_t v_len,
|
|
const char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
|
{
|
|
UNUSED(extra_id);
|
|
UNUSED(v_len);
|
|
UNUSED(buf);
|
|
UNUSED(len);
|
|
UNUSED(pos);
|
|
UNUSED(flt_info);
|
|
return OB_ERROR;
|
|
}
|
|
int flt_serialize_nosupport(char *buf, const int64_t len, int64_t *pos, void *flt_info)
|
|
{
|
|
UNUSED(buf);
|
|
UNUSED(len);
|
|
UNUSED(pos);
|
|
UNUSED(flt_info);
|
|
return OB_ERROR;
|
|
}
|
|
int flt_get_serialize_size_nosupport(int32_t *size, void *flt_info)
|
|
{
|
|
UNUSED(size);
|
|
UNUSED(flt_info);
|
|
return OB_ERROR;
|
|
}
|
|
|
|
// for encode
|
|
static int flt_store_int(char *buf, int64_t len, int64_t *ppos, int64_t v, int16_t type, int64_t v_len)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t pos = *ppos;
|
|
|
|
if (OB_ISNULL(buf)) {
|
|
ret = OB_ERROR;
|
|
} else if (len < pos + TYPE_LENGTH + LEN_LENGTH + v_len) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
int2store(buf + pos, type);
|
|
pos += 2;
|
|
int4store(buf + pos, v_len);
|
|
pos += 4;
|
|
|
|
if (1 == v_len) {
|
|
int1store(buf + pos, v);
|
|
} else if (2 == v_len) {
|
|
int2store(buf + pos, v);
|
|
} else if (3 == v_len) {
|
|
int3store(buf + pos, v);
|
|
} else if (4 == v_len) {
|
|
int4store(buf + pos, v);
|
|
} else if (5 == v_len) {
|
|
int5store(buf + pos, v);
|
|
} else if (6 == v_len) {
|
|
int6store(buf + pos, v);
|
|
} else if (8 == v_len) {
|
|
int8store(buf + pos, v);
|
|
}
|
|
pos += v_len;
|
|
|
|
*ppos = pos;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
int flt_store_type_and_len(char *buf, int64_t len, int64_t *ppos, int16_t type, int32_t v_len)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t pos = *ppos;
|
|
|
|
if (OB_ISNULL(buf)) {
|
|
ret = OB_ERROR;
|
|
} else if (len < pos + TYPE_LENGTH + LEN_LENGTH) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
int2store(buf + pos, type);
|
|
pos += 2;
|
|
int4store(buf + pos, v_len);
|
|
pos += 4;
|
|
|
|
*ppos = pos;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int flt_store_str(char *buf, int64_t len, int64_t *ppos, const char *str, const uint64_t str_len, int16_t type)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t pos = *ppos;
|
|
|
|
if (OB_ISNULL(buf)) {
|
|
ret = OB_ERROR;
|
|
} else if (len < pos + TYPE_LENGTH + LEN_LENGTH + (int64_t)str_len) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
int2store(buf + pos, type);
|
|
pos += 2;
|
|
int4store(buf + pos, str_len);
|
|
pos += 4;
|
|
|
|
memcpy(buf + pos, str, str_len);
|
|
pos += str_len;
|
|
|
|
*ppos = pos;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int flt_store_int1(char *buf, int64_t len, int64_t *pos, int8_t v, int16_t type)
|
|
{
|
|
return flt_store_int(buf, len, pos, v, type, 1);
|
|
}
|
|
int flt_store_int2(char *buf, int64_t len, int64_t *pos, int16_t v, int16_t type)
|
|
{
|
|
return flt_store_int(buf, len, pos, v, type, 2);
|
|
}
|
|
int flt_store_int3(char *buf, int64_t len, int64_t *pos, int32_t v, int16_t type)
|
|
{
|
|
return flt_store_int(buf, len, pos, v, type, 3);
|
|
}
|
|
int flt_store_int4(char *buf, int64_t len, int64_t *pos, int32_t v, int16_t type)
|
|
{
|
|
return flt_store_int(buf, len, pos, v, type, 4);
|
|
}
|
|
int flt_store_int5(char *buf, int64_t len, int64_t *pos, int64_t v, int16_t type)
|
|
{
|
|
return flt_store_int(buf, len, pos, v, type, 5);
|
|
}
|
|
int flt_store_int6(char *buf, int64_t len, int64_t *pos, int64_t v, int16_t type)
|
|
{
|
|
return flt_store_int(buf, len, pos, v, type, 6);
|
|
}
|
|
int flt_store_int8(char *buf, int64_t len, int64_t *pos, int64_t v, int16_t type)
|
|
{
|
|
return flt_store_int(buf, len, pos, v, type, 7);
|
|
}
|
|
|
|
int flt_store_double(char *buf, const int64_t len, int64_t *ppos, double val, int16_t type)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int v_len = DBL_SIZE;
|
|
int64_t pos = *ppos;
|
|
|
|
if (OB_ISNULL(buf)) {
|
|
ret = OB_ERROR;
|
|
} else if ((uint64_t)len < pos + DBL_SIZE + TYPE_LENGTH + LEN_LENGTH) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
int2store(buf + pos, type);
|
|
pos += 2;
|
|
int4store(buf + pos, v_len);
|
|
pos += 4;
|
|
|
|
memcpy(buf + pos, &val, DBL_SIZE);
|
|
pos += DBL_SIZE;
|
|
|
|
*ppos = pos;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_store_float(char *buf, const int64_t len, int64_t *ppos, float val, int16_t type)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int v_len = FLT_SIZE;
|
|
int64_t pos = *ppos;
|
|
|
|
if (OB_ISNULL(buf)) {
|
|
ret = OB_ERROR;
|
|
} else if ((uint64_t)len < pos + FLT_SIZE + TYPE_LENGTH + LEN_LENGTH) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
int2store(buf + pos, type);
|
|
pos += 2;
|
|
int4store(buf + pos, v_len);
|
|
pos += 4;
|
|
|
|
memcpy(buf + pos, &val, FLT_SIZE);
|
|
pos += FLT_SIZE;
|
|
|
|
*ppos = pos;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
inline int flt_get_store_str_size(const uint64_t str_len)
|
|
{
|
|
return TYPE_LENGTH + LEN_LENGTH + str_len;
|
|
}
|
|
int flt_get_store_int1_size()
|
|
{
|
|
return TYPE_LENGTH + LEN_LENGTH + 1;
|
|
}
|
|
int flt_get_store_int2_size()
|
|
{
|
|
return TYPE_LENGTH + LEN_LENGTH + 2;
|
|
}
|
|
int flt_get_store_int3_size()
|
|
{
|
|
return TYPE_LENGTH + LEN_LENGTH + 3;
|
|
}
|
|
int flt_get_store_int4_size()
|
|
{
|
|
return TYPE_LENGTH + LEN_LENGTH + 4;
|
|
}
|
|
int flt_get_store_int5_size()
|
|
{
|
|
return TYPE_LENGTH + LEN_LENGTH + 5;
|
|
}
|
|
int flt_get_store_int6_size()
|
|
{
|
|
return TYPE_LENGTH + LEN_LENGTH + 6;
|
|
}
|
|
int flt_get_store_int8_size()
|
|
{
|
|
return TYPE_LENGTH + LEN_LENGTH + 8;
|
|
}
|
|
int flt_get_store_double_size()
|
|
{
|
|
return TYPE_LENGTH + LEN_LENGTH + DBL_SIZE;
|
|
}
|
|
int flt_get_store_float_size()
|
|
{
|
|
return TYPE_LENGTH + LEN_LENGTH + FLT_SIZE;
|
|
}
|
|
|
|
static int flt_get_int(const char *buf, int64_t len, int64_t *ppos, int64_t v_len, void *val)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t pos = *ppos;
|
|
|
|
if (OB_ISNULL(buf)) {
|
|
ret = OB_ERROR;
|
|
} else if (pos + v_len > len) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
if (1 == v_len) {
|
|
*(int8_t *)val = sint1korr(buf + pos);
|
|
} else if (2 == v_len) {
|
|
*(int16_t *)val = sint2korr(buf + pos);
|
|
} else if (3 == v_len) {
|
|
*(int32_t *)val = sint3korr(buf + pos);
|
|
} else if (4 == v_len) {
|
|
*(int32_t *)val = sint4korr(buf + pos);
|
|
} else if (8 == v_len) {
|
|
*(int64_t *)val = sint8korr(buf + pos);
|
|
}
|
|
|
|
pos += v_len;
|
|
*ppos = pos;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int flt_resolve_type_and_len(const char *buf, int64_t len, int64_t *ppos, int16_t *type, int32_t *v_len)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t pos = *ppos;
|
|
|
|
if (OB_ISNULL(buf)) {
|
|
ret = OB_ERROR;
|
|
} else if (pos + TYPE_LENGTH + LEN_LENGTH > len) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
*type = sint2korr(buf + pos);
|
|
pos += 2;
|
|
*v_len = sint4korr(buf + pos);
|
|
pos += 4;
|
|
|
|
*ppos = pos;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_get_str(const char *buf, int64_t len, int64_t *ppos, int64_t str_len, char **str)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t pos = *ppos;
|
|
|
|
if (OB_ISNULL(buf)) {
|
|
ret = OB_ERROR;
|
|
} else if (pos + str_len > len) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
*str = (char *)buf;
|
|
|
|
pos += str_len;
|
|
*ppos = pos;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
//@{ Signed integer in reverse sequence, write the result to v, and update pos
|
|
int flt_get_int1(const char *buf, int64_t len, int64_t *pos, int64_t v_len, int8_t *val)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
|
|
if (1 != v_len) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
ret = flt_get_int(buf, len, pos, v_len, val);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
int flt_get_int2(const char *buf, int64_t len, int64_t *pos, int64_t v_len, int16_t *val)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
|
|
if (2 != v_len) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
ret = flt_get_int(buf, len, pos, v_len, val);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
int flt_get_int3(const char *buf, int64_t len, int64_t *pos, int64_t v_len, int32_t *val)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
|
|
if (3 != v_len) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
ret = flt_get_int(buf, len, pos, v_len, val);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
int flt_get_int4(const char *buf, int64_t len, int64_t *pos, int64_t v_len, int32_t *val)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
|
|
if (4 != v_len) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
ret = flt_get_int(buf, len, pos, v_len, val);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
int flt_get_int8(const char *buf, int64_t len, int64_t *pos, int64_t v_len, int64_t *val)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
|
|
if (8 != v_len) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
ret = flt_get_int(buf, len, pos, v_len, val);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int flt_get_double(const char *buf, int64_t len, int64_t *ppos, int64_t v_len, double *val)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t pos = *ppos;
|
|
|
|
if (OB_ISNULL(buf)) {
|
|
ret = OB_ERROR;
|
|
} else if (pos + v_len > len || sizeof(double) != v_len) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
*val = (*((double *)(buf + pos)));
|
|
|
|
pos += v_len;
|
|
*ppos = pos;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_get_float(const char *buf, int64_t len, int64_t *ppos, int64_t v_len, float *val)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t pos = *ppos;
|
|
|
|
if (OB_ISNULL(buf)) {
|
|
ret = OB_ERROR;
|
|
} else if (pos + v_len > len || sizeof(float) != v_len) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
*val = (*((float *)(buf + pos)));
|
|
|
|
pos += v_len;
|
|
*ppos = pos;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static uint64_t xorshift128plus(uint64_t *s) {
|
|
uint64_t s1 = s[0];
|
|
const uint64_t s0 = s[1];
|
|
s[0] = s0;
|
|
s1 ^= s1 << 23;
|
|
s[1] = s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5);
|
|
return s[1] + s0;
|
|
}
|
|
|
|
int uuid4_init(uint64_t *seed, size_t seed_size) {
|
|
#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
|
|
size_t res;
|
|
FILE *fp = fopen("/dev/urandom", "rb");
|
|
if (!fp) {
|
|
return OB_ERROR;
|
|
}
|
|
res = fread(seed, 1, seed_size, fp);
|
|
fclose(fp);
|
|
if ( res != seed_size ) {
|
|
return OB_ERROR;
|
|
}
|
|
|
|
#elif defined(_WIN32)
|
|
int res;
|
|
HCRYPTPROV hCryptProv;
|
|
res = CryptAcquireContext(
|
|
&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
|
|
if (!res) {
|
|
return OB_ERROR;
|
|
}
|
|
res = CryptGenRandom(hCryptProv, (DWORD) seed_size, (PBYTE) seed);
|
|
CryptReleaseContext(hCryptProv, 0);
|
|
if (!res) {
|
|
return OB_ERROR;
|
|
}
|
|
|
|
#else
|
|
#error "unsupported platform"
|
|
#endif
|
|
return OB_SUCCESS;
|
|
}
|
|
|
|
|
|
OBCLIENT_UUID uuid4_generate(uint64_t *seed) {
|
|
uint64_t word;
|
|
OBCLIENT_UUID ret;
|
|
/* get random */
|
|
word = xorshift128plus(seed);
|
|
// word[1] = xorshift128plus(seed);
|
|
|
|
ret.high_ = get_current_time_us();
|
|
ret.low_ = word;
|
|
return ret;
|
|
}
|
|
|
|
ObTrace *get_trace_instance(FLTInfo *flt)
|
|
{
|
|
return flt->trace_;
|
|
}
|
|
|
|
int trace_init(FLTInfo *flt)
|
|
{
|
|
int index;
|
|
int ret = OB_SUCCESS;
|
|
if (OB_ISNULL(flt)) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
ObTrace *trace = (ObTrace *)malloc(OBTRACE_DEFAULT_BUFFER_SIZE);
|
|
if (OB_ISNULL(trace)) {
|
|
// malloc error
|
|
ret = OB_ERROR;
|
|
} else {
|
|
memset(trace, 0, sizeof(*trace));
|
|
trace->buffer_size_ = OBTRACE_DEFAULT_BUFFER_SIZE - sizeof(*trace);
|
|
trace->log_buf_ = trace->data_; // size is MAX_TRACE_LOG_SIZE
|
|
trace->show_trace_buf_ = trace->data_ + MAX_TRACE_LOG_SIZE; // size is MAX_TRACE_LOG_SIZE
|
|
trace->flt_serialize_buf_ = trace->data_ + (2 * MAX_TRACE_LOG_SIZE); // size is MAX_FLT_SERIALIZE_SIZE
|
|
trace->offset_ = INIT_OFFSET;
|
|
trace->auto_flush_ = 1;
|
|
trace->trace_enable_ = FALSE;
|
|
trace->show_trace_enable_ = FALSE;
|
|
trace->force_print_ = FALSE;
|
|
trace->slow_query_print_ = FALSE;
|
|
trace->root_span_id_.low_ = 0;
|
|
trace->root_span_id_.high_ = 0;
|
|
trace->flt = flt;
|
|
flt->trace_ = trace;
|
|
// set the starting parentheses
|
|
trace->show_trace_buf_[0] = '[';
|
|
trace->show_trace_buf_offset_ = 1;
|
|
trace->free_tag_list_.data_ = NULL;
|
|
trace->free_tag_list_.next_ = NULL;
|
|
trace->free_tag_list_.tag_type_ = 0;
|
|
for (index = 0; index < TAG_CACHE_COUNT; ++index) {
|
|
ObTagCtx *tag = (ObTagCtx *)(trace->data_ + TAG_BUFFER_BEGIN + (index * sizeof(ObTagCtx)));
|
|
tag->next_ = trace->free_tag_list_.next_;
|
|
trace->free_tag_list_.next_ = tag;
|
|
}
|
|
for (index = 0; index < SPAN_CACHE_COUNT; ++index) {
|
|
char *begin_addr = trace->data_ + SPAN_BUFFER_BEGIN + (index * (sizeof(LIST) + sizeof(ObSpanCtx)));
|
|
LIST *list = (LIST *)begin_addr;
|
|
list->data = (ObSpanCtx *)(begin_addr + sizeof(LIST));
|
|
trace->free_span_list_ = list_add(trace->free_span_list_, list);
|
|
}
|
|
if (OB_FAIL(uuid4_init(trace->uuid_random_seed, sizeof(trace->uuid_random_seed)))) {
|
|
// init uuid seed error
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void trace_end(FLTInfo *flt)
|
|
{
|
|
if (OB_NOT_NULL(flt)) {
|
|
free(flt->trace_);
|
|
flt->trace_ = NULL;
|
|
}
|
|
return;
|
|
}
|
|
|
|
void begin_trace(ObTrace *trace)
|
|
{
|
|
if (OB_NOT_NULL(trace)) {
|
|
FLTInfo *flt = trace->flt;
|
|
|
|
if (OB_ISNULL(flt)) {
|
|
// error, do not entable trace
|
|
trace->trace_enable_ = FALSE;
|
|
trace->show_trace_enable_ = FALSE;
|
|
} else if (FALSE == flt_is_vaild(flt)) {
|
|
// error, invalid trace
|
|
trace->trace_enable_ = FALSE;
|
|
trace->show_trace_enable_ = FALSE;
|
|
} else if (TRUE == flt->control_info_.flt_show_trace_enable_) {
|
|
// for show trace , always true
|
|
trace->trace_enable_ = TRUE;
|
|
trace->show_trace_enable_ = TRUE;
|
|
} else {
|
|
double trace_pct = flt_get_pct(trace->uuid_random_seed);
|
|
trace->show_trace_enable_ = FALSE;
|
|
|
|
if (trace_pct <= flt->control_info_.sample_pct_) {
|
|
// trace enable
|
|
trace->trace_enable_ = TRUE;
|
|
} else {
|
|
trace->trace_enable_ = FALSE;
|
|
}
|
|
}
|
|
|
|
if (TRUE == trace->trace_enable_) {
|
|
// todo : add interface to set trace id
|
|
trace->trace_id_ = uuid4_generate(trace->uuid_random_seed);
|
|
trace->level_ = flt->control_info_.level_;
|
|
// If the trace hits, the subsequent calculation and printing strategy
|
|
|
|
if (TRUE == flt->control_info_.flt_show_trace_enable_) {
|
|
// for show trace , always true
|
|
trace->force_print_ = TRUE;
|
|
} else if (RP_ALL == flt->control_info_.rp_) {
|
|
trace->force_print_ = TRUE;
|
|
} else if (RP_SAMPLE_AND_SLOW_QUERY == flt->control_info_.rp_) {
|
|
// Hit print samples need to print
|
|
double print_pct = flt_get_pct(trace->uuid_random_seed);
|
|
if (print_pct <= flt->control_info_.print_sample_pct_) {
|
|
trace->force_print_ = TRUE;
|
|
} else {
|
|
trace->force_print_ = FALSE;
|
|
}
|
|
} else if (RP_ONLY_SLOW_QUERY == flt->control_info_.rp_) {
|
|
trace->force_print_ = FALSE;
|
|
} else {
|
|
trace->force_print_ = FALSE;
|
|
}
|
|
} else {
|
|
// Set the trace level to 0, subsequent spans will not be processed
|
|
trace->level_ = 0;
|
|
trace->force_print_ = FALSE;
|
|
trace->trace_id_.low_ = 0;
|
|
trace->trace_id_.high_ = 0;
|
|
}
|
|
|
|
#ifdef DEBUG_OB20
|
|
printf("trace enable is %d, force print is %d\n", trace->trace_enable_, trace->force_print_);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void end_trace(ObTrace *trace)
|
|
{
|
|
if (OB_NOT_NULL(trace)) {
|
|
LIST *span_elem;
|
|
ObSpanCtx *span;
|
|
while(OB_NOT_NULL(trace->current_span_list_)) {
|
|
span_elem = trace->current_span_list_;
|
|
span = (ObSpanCtx *)span_elem->data;
|
|
if (0 == span->end_ts_) {
|
|
span->end_ts_ = get_current_time_us();
|
|
}
|
|
// add all elem to free span list
|
|
trace->current_span_list_ = list_delete(trace->current_span_list_, span_elem);
|
|
trace->free_span_list_ = list_add(trace->free_span_list_, span_elem);
|
|
}
|
|
trace->offset_ = INIT_OFFSET;
|
|
trace->policy_ = 0;
|
|
trace->last_active_span_ = NULL;
|
|
}
|
|
}
|
|
|
|
// used by slow query
|
|
void flush_first_span(ObTrace *trace)
|
|
{
|
|
LIST *span_list;
|
|
ObSpanCtx *span;
|
|
int64_t pos = 0;
|
|
int ret = OB_SUCCESS;
|
|
|
|
if (OB_ISNULL(trace) || (0 == trace->trace_id_.low_ && 0 == trace->trace_id_.high_)) {
|
|
// do nothing
|
|
} else if (OB_ISNULL(span_list = trace->current_span_list_)) {
|
|
// do nothing
|
|
} else if (OB_ISNULL(span = (ObSpanCtx *)span_list->data)) {
|
|
// do nothing
|
|
} else {
|
|
ObTagCtx *tag = span->tags_;
|
|
my_bool first = TRUE;
|
|
char buf[MAX_TRACE_LOG_SIZE];
|
|
pos = 0;
|
|
INIT_SPAN(trace, span);
|
|
while (OB_SUCC(ret) && OB_NOT_NULL(tag)) {
|
|
if (pos + 10 >= MAX_TRACE_LOG_SIZE) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
buf[pos++] = ',';
|
|
if (first) {
|
|
strcpy(buf + pos, "\"tags\":[");
|
|
pos += 8;
|
|
first = FALSE;
|
|
}
|
|
ret = tostring_ObTagCtx(buf, MAX_TRACE_LOG_SIZE, &pos, tag);
|
|
tag = tag->next_;
|
|
}
|
|
}
|
|
if (0 != pos) {
|
|
if (pos + 1 < MAX_TRACE_LOG_SIZE) {
|
|
buf[pos++] = ']';
|
|
buf[pos++] = 0;
|
|
} else {
|
|
buf[MAX_TRACE_LOG_SIZE - 2] = ']';
|
|
buf[MAX_TRACE_LOG_SIZE - 1] = 0;
|
|
}
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
INIT_SPAN(trace, span->source_span_);
|
|
ret = snprintf(trace->log_buf_ + trace->log_buf_offset_,
|
|
MAX_TRACE_LOG_SIZE - trace->log_buf_offset_,
|
|
TRACE_PATTERN "%s}",
|
|
UUID_TOSTRING(trace->trace_id_),
|
|
"obclient",
|
|
UUID_TOSTRING(span->span_id_),
|
|
span->start_ts_,
|
|
span->end_ts_,
|
|
UUID_TOSTRING(OB_ISNULL(span->source_span_) ? trace->root_span_id_ : span->source_span_->span_id_),
|
|
span->is_follow_ ? "true" : "false",
|
|
buf);
|
|
if (ret < 0 || trace->log_buf_offset_ + ret >= MAX_TRACE_LOG_SIZE) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
trace->log_buf_offset_ += ret;
|
|
ret = OB_SUCCESS;
|
|
}
|
|
}
|
|
if (OB_SUCC(ret) && 0 != span->end_ts_) {
|
|
// clear span and reset tag
|
|
ObTagCtx *tag = span->tags_;
|
|
while(OB_NOT_NULL(tag)) {
|
|
ObTagCtx *free_tag = tag;
|
|
tag = tag->next_;
|
|
reset_tag(trace, span, free_tag);
|
|
}
|
|
span->tags_ = NULL;
|
|
trace->current_span_list_ = list_delete(trace->current_span_list_, span_list);
|
|
trace->free_span_list_ = list_add(trace->free_span_list_, span_list);
|
|
}
|
|
}
|
|
}
|
|
|
|
void flush_trace(ObTrace *trace)
|
|
{
|
|
LIST *span_elem;
|
|
ObSpanCtx *span;
|
|
int64_t pos = 0;
|
|
int ret = OB_SUCCESS;
|
|
int log_buf_len = 0;
|
|
int show_trace_buf_len = 0;
|
|
|
|
if (OB_ISNULL(trace) || (0 == trace->trace_id_.low_ && 0 == trace->trace_id_.high_)) {
|
|
// do nothing
|
|
} else if (OB_ISNULL(trace->current_span_list_)) {
|
|
// do nothing
|
|
} else {
|
|
while (OB_NOT_NULL(trace->current_span_list_) && OB_SUCC(ret)) {
|
|
span_elem = trace->current_span_list_;
|
|
span = (ObSpanCtx *)span_elem->data;
|
|
if (OB_NOT_NULL(span)) {
|
|
ObTagCtx *tag = span->tags_;
|
|
my_bool first = TRUE;
|
|
char buf[MAX_TRACE_LOG_SIZE] = {0};
|
|
pos = 0;
|
|
INIT_SPAN(trace, span);
|
|
while (OB_SUCC(ret) && OB_NOT_NULL(tag)) {
|
|
if (pos + 10 >= MAX_TRACE_LOG_SIZE) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
buf[pos++] = ',';
|
|
if (first) {
|
|
strcpy(buf + pos, "\"tags\":[");
|
|
pos += 8;
|
|
first = FALSE;
|
|
}
|
|
ret = tostring_ObTagCtx(buf, MAX_TRACE_LOG_SIZE, &pos, tag);
|
|
tag = tag->next_;
|
|
}
|
|
}
|
|
if (0 != pos) {
|
|
if (pos + 1 < MAX_TRACE_LOG_SIZE) {
|
|
buf[pos++] = ']';
|
|
buf[pos++] = 0;
|
|
} else {
|
|
buf[MAX_TRACE_LOG_SIZE - 2] = ']';
|
|
buf[MAX_TRACE_LOG_SIZE - 1] = 0;
|
|
}
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
INIT_SPAN(trace, span->source_span_);
|
|
log_buf_len = snprintf(trace->log_buf_ + trace->log_buf_offset_,
|
|
MAX_TRACE_LOG_SIZE - trace->log_buf_offset_,
|
|
TRACE_PATTERN "%s}",
|
|
UUID_TOSTRING(trace->trace_id_),
|
|
"obclient",
|
|
UUID_TOSTRING(span->span_id_),
|
|
span->start_ts_,
|
|
span->end_ts_,
|
|
UUID_TOSTRING(OB_ISNULL(span->source_span_) ? trace->root_span_id_ : span->source_span_->span_id_),
|
|
span->is_follow_ ? "true" : "false",
|
|
buf);
|
|
if (log_buf_len < 0 || trace->log_buf_offset_ + log_buf_len >= MAX_TRACE_LOG_SIZE) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
trace->log_buf_offset_ += log_buf_len;
|
|
if (0 != span->end_ts_) {
|
|
// The span that has ended needs to be put into the show trace buffer and sent to the backend next time
|
|
show_trace_buf_len = snprintf(trace->show_trace_buf_ + trace->show_trace_buf_offset_,
|
|
MAX_TRACE_LOG_SIZE - trace->show_trace_buf_offset_,
|
|
"%.*s,",
|
|
log_buf_len,
|
|
trace->log_buf_ + trace->log_buf_offset_ - log_buf_len);
|
|
if (show_trace_buf_len < 0 || trace->show_trace_buf_offset_ + show_trace_buf_len >= MAX_TRACE_LOG_SIZE) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
trace->show_trace_buf_offset_ += show_trace_buf_len;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (OB_SUCC(ret) && 0 != span->end_ts_) {
|
|
|
|
// clear span and reset tag
|
|
ObTagCtx *tag = span->tags_;
|
|
while(OB_NOT_NULL(tag)) {
|
|
ObTagCtx *free_tag = tag;
|
|
tag = tag->next_;
|
|
reset_tag(trace, span, free_tag);
|
|
}
|
|
span->tags_ = 0;
|
|
trace->current_span_list_ = list_delete(trace->current_span_list_, span_elem);
|
|
trace->free_span_list_ = list_add(trace->free_span_list_, span_elem);
|
|
}
|
|
}
|
|
}
|
|
trace->offset_ = INIT_OFFSET;
|
|
}
|
|
}
|
|
|
|
ObSpanCtx* begin_span(ObTrace *trace, uint32_t span_type, uint8_t level, my_bool is_follow)
|
|
{
|
|
ObSpanCtx *new_span = NULL;
|
|
#ifdef DEBUG_OB20
|
|
printf("//////////////////////call begin_span ////////////////////////////////\n");
|
|
#endif
|
|
if (OB_ISNULL(trace)) {
|
|
// do nothing
|
|
} else if (trace->trace_id_.low_ == 0 && trace->trace_id_.high_ == 0) {
|
|
// trace is not enable
|
|
} else if (level > trace->level_) {
|
|
// do nothing
|
|
} else {
|
|
if (OB_ISNULL(trace->free_span_list_)) {
|
|
FLUSH_TRACE(trace->flt);
|
|
}
|
|
if (OB_NOT_NULL(trace->free_span_list_)) {
|
|
LIST *span_elem = trace->free_span_list_;
|
|
if (OB_NOT_NULL(span_elem)) {
|
|
new_span = (ObSpanCtx *)span_elem->data;
|
|
new_span->span_type_ = span_type;
|
|
new_span->span_id_.high_ = 0;
|
|
new_span->span_id_.low_ = ++trace->seq_;
|
|
new_span->source_span_ = trace->last_active_span_;
|
|
new_span->is_follow_ = is_follow;
|
|
new_span->start_ts_ = get_current_time_us();
|
|
new_span->end_ts_ = 0;
|
|
new_span->tags_ = NULL;
|
|
trace->last_active_span_ = new_span;
|
|
trace->free_span_list_ = list_delete(trace->free_span_list_, span_elem);
|
|
trace->current_span_list_ = list_add(trace->current_span_list_, span_elem);
|
|
}
|
|
}
|
|
}
|
|
return new_span;
|
|
}
|
|
|
|
void end_span(ObTrace *trace, ObSpanCtx *span)
|
|
{
|
|
#ifdef DEBUG_OB20
|
|
printf("//////////////////////call end_span ////////////////////////////////\n");
|
|
#endif
|
|
if (OB_ISNULL(trace) || OB_ISNULL(trace->flt) || OB_ISNULL(span)) {
|
|
// error
|
|
} else if ((trace->trace_id_.low_ == 0 && trace->trace_id_.high_ == 0)
|
|
|| (span->span_id_.low_ == 0 && span->span_id_.high_ == 0)) {
|
|
// trace id or span id is not inited
|
|
} else {
|
|
FLTInfo *flt = trace->flt;
|
|
int64_t slow_query_threshold = flt->control_info_.slow_query_threshold_;
|
|
int64_t use_time;
|
|
RecordPolicy rp = flt->control_info_.rp_;
|
|
|
|
span->end_ts_ = get_current_time_us();
|
|
use_time = span->end_ts_ - span->start_ts_;
|
|
trace->last_active_span_ = span->source_span_;
|
|
// The current driver has only one span, so directly calculate the end time of this span and then calculate the slow query
|
|
// todo: Check the type of the span, only interactive spans need to record slow queries
|
|
if (RP_ONLY_SLOW_QUERY == rp || RP_SAMPLE_AND_SLOW_QUERY == rp) {
|
|
if (slow_query_threshold != -1 && slow_query_threshold <= use_time) {
|
|
// If you find slow queries, you only need to enable log printing, and send the span log to the server for printing.
|
|
#ifdef DEBUG_OB20
|
|
printf("get slow query, use_time is %ld, slow_query_threshold is %ld\n", use_time, slow_query_threshold);
|
|
#endif
|
|
trace->slow_query_print_ = TRUE;
|
|
}
|
|
}
|
|
#ifdef DEBUG_OB20
|
|
printf("end span spanid:[%lu:%lu]\n", span->span_id_.high_, span->span_id_.low_);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void reset_span(ObTrace *trace)
|
|
{
|
|
if (OB_ISNULL(trace) || OB_ISNULL(trace->flt)) {
|
|
// error
|
|
} else if (trace->trace_id_.low_ == 0 && trace->trace_id_.high_ == 0) {
|
|
// trace is not inited
|
|
} else {
|
|
ObSpanCtx *span;
|
|
LIST *span_elem;
|
|
while(OB_NOT_NULL(trace->current_span_list_)) {
|
|
span_elem = trace->current_span_list_;
|
|
span = (ObSpanCtx *)span_elem->data;
|
|
// All spans are recycled after a statement in the transaction ends
|
|
trace->current_span_list_ = list_delete(trace->current_span_list_, span_elem);
|
|
trace->free_span_list_ = list_add(trace->free_span_list_, span_elem);
|
|
span->tags_ = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
void append_tag(ObTrace *trace, ObSpanCtx *span, uint16_t tag_type, const char *str)
|
|
{
|
|
if (OB_ISNULL(trace)) {
|
|
// do nothing
|
|
} else if (OB_ISNULL(str)) {
|
|
// do nothing
|
|
} else if (OB_ISNULL(trace->free_tag_list_.next_)) {
|
|
// do nothing
|
|
} else {
|
|
// get tag from free tag list
|
|
ObTagCtx *tag = (ObTagCtx *)(trace->free_tag_list_.next_);
|
|
trace->free_tag_list_.next_ = tag->next_;
|
|
// append tag into span
|
|
tag->next_ = span->tags_;
|
|
span->tags_ = tag;
|
|
tag->tag_type_ = tag_type;
|
|
tag->data_ = str;
|
|
}
|
|
}
|
|
|
|
void reset_tag(ObTrace *trace, ObSpanCtx *span, ObTagCtx *tag)
|
|
{
|
|
UNUSED(span);
|
|
if (OB_ISNULL(trace)) {
|
|
// do nothing
|
|
} else if (OB_ISNULL(tag)) {
|
|
// do nothing
|
|
} else {
|
|
tag->next_ = trace->free_tag_list_.next_;
|
|
trace->free_tag_list_.next_ = tag;
|
|
}
|
|
}
|
|
|
|
int serialize_UUID(char *buf, const int64_t buf_len, int64_t *pos, OBCLIENT_UUID *uuid)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(encode_i64(buf, buf_len, pos, uuid->high_))) {
|
|
// LOG_WARN("deserialize failed", K(ret), K(buf), K(buf_len), K(pos));
|
|
} else if (OB_FAIL(encode_i64(buf, buf_len, pos, uuid->low_))) {
|
|
// LOG_WARN("deserialize failed", K(ret), K(buf), K(buf_len), K(pos));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int deserialize_UUID(const char *buf, const int64_t buf_len, int64_t *pos, OBCLIENT_UUID *uuid)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(decode_i64(buf, buf_len, pos, (int64_t *)(&uuid->high_)))) {
|
|
// LOG_WARN("deserialize failed", K(ret), K(buf), K(buf_len), K(pos));
|
|
} else if (OB_FAIL(decode_i64(buf, buf_len, pos, (int64_t *)(&uuid->low_)))) {
|
|
// LOG_WARN("deserialize failed", K(ret), K(buf), K(buf_len), K(pos));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
DEFINE_TO_STRING_FUNC_FOR(OBCLIENT_UUID)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t tmp_pos = *pos;
|
|
const char *transfer = "0123456789abcdef";
|
|
if (tmp_pos + 37 > buf_len) {
|
|
ret = OB_ERROR;
|
|
} else {
|
|
buf[tmp_pos++] = transfer[src->high_ >> 60 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->high_ >> 56 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->high_ >> 52 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->high_ >> 48 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->high_ >> 44 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->high_ >> 40 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->high_ >> 36 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->high_ >> 32 & 0xf];
|
|
buf[tmp_pos++] = '-';
|
|
buf[tmp_pos++] = transfer[src->high_ >> 28 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->high_ >> 24 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->high_ >> 20 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->high_ >> 16 & 0xf];
|
|
buf[tmp_pos++] = '-';
|
|
buf[tmp_pos++] = transfer[src->high_ >> 12 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->high_ >> 8 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->high_ >> 4 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->high_ >> 0 & 0xf];
|
|
buf[tmp_pos++] = '-';
|
|
buf[tmp_pos++] = transfer[src->low_ >> 60 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->low_ >> 56 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->low_ >> 52 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->low_ >> 48 & 0xf];
|
|
buf[tmp_pos++] = '-';
|
|
buf[tmp_pos++] = transfer[src->low_ >> 44 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->low_ >> 40 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->low_ >> 36 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->low_ >> 32 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->low_ >> 28 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->low_ >> 24 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->low_ >> 20 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->low_ >> 16 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->low_ >> 12 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->low_ >> 8 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->low_ >> 4 & 0xf];
|
|
buf[tmp_pos++] = transfer[src->low_ >> 0 & 0xf];
|
|
buf[tmp_pos ] = '\0';
|
|
}
|
|
|
|
*pos = tmp_pos;
|
|
return ret;
|
|
}
|
|
|
|
DEFINE_TO_STRING_FUNC_FOR(ObTagCtx)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
char from[] = "\"\n\r\\";
|
|
const char *to[] = { "\\\"", "\\n", "\\r", "\\\\"};
|
|
int l = strlen(tag_str[src->tag_type_]);
|
|
int64_t tmp_pos = *pos;
|
|
const char *c = src->data_;
|
|
const char *toc;
|
|
my_bool conv = FALSE;
|
|
int i;
|
|
if (tmp_pos + l + 7 >= buf_len) {
|
|
buf[buf_len - 1] = '\0';
|
|
ret = OB_ERROR;
|
|
} else {
|
|
buf[tmp_pos++] = '{';
|
|
buf[tmp_pos++] = '\"';
|
|
strcpy(buf + tmp_pos, tag_str[src->tag_type_]);
|
|
tmp_pos += l;
|
|
buf[tmp_pos++] = '\"';
|
|
buf[tmp_pos++] = ':';
|
|
buf[tmp_pos] = '\0';
|
|
for (; *c; ++c) {
|
|
if (c != src->data_ && *(c + 1)) {
|
|
// ignore the first one and the last one
|
|
for (i = 0; i < 4; ++i) {
|
|
if (from[i] == *c) {
|
|
for (toc = to[i]; *toc; ++toc) {
|
|
if (tmp_pos < buf_len) {
|
|
buf[tmp_pos++] = *toc;
|
|
} else {
|
|
ret = OB_ERROR;
|
|
}
|
|
}
|
|
conv = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!conv && tmp_pos < buf_len) {
|
|
buf[tmp_pos++] = *c;
|
|
}
|
|
}
|
|
}
|
|
if (OB_FAIL(ret) || tmp_pos + 1 >= buf_len) {
|
|
buf[buf_len - 1] = 0;
|
|
} else {
|
|
buf[tmp_pos++] = '}';
|
|
buf[tmp_pos] = 0;
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
*pos = tmp_pos;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// DEFINE_TO_STRING_FUNC_FOR(ObSpanCtx)
|
|
// {
|
|
// int ret = 0;
|
|
// char span_id[UUID4_LEN];
|
|
// char source_span_id[UUID4_LEN] = {0};
|
|
// int64_t span_id_pos = 0;
|
|
// int64_t source_span_id_pos = 0;
|
|
// if (OB_FAIL(tostring_UUID(span_id, UUID4_LEN, &span_id_pos, &src->span_id_))) {
|
|
// // error
|
|
// } else if (OB_NOT_NULL(src->source_span_id_) && (tostring_UUID(source_span_id, UUID4_LEN, &source_span_id_pos, src->source_span_id_))) {
|
|
// // error
|
|
// } else {
|
|
// ret = snprintf(buf + *pos, buf_len - *pos,
|
|
// "\"name\":\"%s\",\"id\":\"%s\",\"start_ts\":%ld,\"end_ts\":%ld,\"parent_id\":\"%s\",\"is_follow\":%s",
|
|
// "ObClient",
|
|
// span_id,
|
|
// src->start_ts_,
|
|
// src->end_ts_,
|
|
// source_span_id,
|
|
// src->is_follow_ ? "true" : "false");
|
|
// if (ret < 0 || *pos + ret >= buf_len) {
|
|
// ret = OB_ERROR;
|
|
// } else {
|
|
// ObTagCtx* tag = src->tags_;
|
|
// *pos = *pos + ret;
|
|
// ret = OB_SUCCESS;
|
|
// while (OB_SUCC(ret) && OB_NOT_NULL(tag)) {
|
|
// ret = snprintf(buf + *pos, buf_len - *pos, ",");
|
|
// if (ret < 0 || *pos + ret >= buf_len) {
|
|
// ret = OB_ERROR;
|
|
// } else {
|
|
// *pos = *pos + ret;
|
|
// ret = tostring_ObTagCtx(buf, buf_len, pos, tag);
|
|
// tag = tag->next_;
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// return ret;
|
|
// }
|
|
|
|
int flt_set_module(MYSQL *mysql, const char *module_name)
|
|
{
|
|
int ret = 0;
|
|
if (OB_ISNULL(mysql) || FALSE == get_use_full_link_trace(mysql)) {
|
|
// error
|
|
ret = 1;
|
|
} else if (OB_ISNULL(mysql->net.ob20protocol)) {
|
|
ret = 1;
|
|
} else {
|
|
FLTInfo *flt = mysql->net.ob20protocol->flt;
|
|
if (OB_ISNULL(flt)) {
|
|
ret = 1;
|
|
} else {
|
|
flt->app_info_.module_ = module_name;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_set_action(MYSQL *mysql, const char *action_name)
|
|
{
|
|
int ret = 0;
|
|
if (OB_ISNULL(mysql) || FALSE == get_use_full_link_trace(mysql)) {
|
|
// error
|
|
ret = 1;
|
|
} else if (OB_ISNULL(mysql->net.ob20protocol)) {
|
|
ret = 1;
|
|
} else {
|
|
FLTInfo *flt = mysql->net.ob20protocol->flt;
|
|
if (OB_ISNULL(flt)) {
|
|
ret = 1;
|
|
} else {
|
|
flt->app_info_.action_ = action_name;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_set_client_info(MYSQL *mysql, const char *client_info)
|
|
{
|
|
int ret = 0;
|
|
if (OB_ISNULL(mysql) || FALSE == get_use_full_link_trace(mysql)) {
|
|
// error
|
|
ret = 1;
|
|
} else if (OB_ISNULL(mysql->net.ob20protocol)) {
|
|
ret = 1;
|
|
} else {
|
|
FLTInfo *flt = mysql->net.ob20protocol->flt;
|
|
if (OB_ISNULL(flt)) {
|
|
ret = 1;
|
|
} else {
|
|
flt->app_info_.client_info_ = client_info;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_set_identifier(MYSQL *mysql, const char *identifier)
|
|
{
|
|
int ret = 0;
|
|
if (OB_ISNULL(mysql) || FALSE == get_use_full_link_trace(mysql)) {
|
|
// error
|
|
ret = 1;
|
|
} else if (OB_ISNULL(mysql->net.ob20protocol)) {
|
|
ret = 1;
|
|
} else {
|
|
FLTInfo *flt = mysql->net.ob20protocol->flt;
|
|
if (OB_ISNULL(flt)) {
|
|
ret = 1;
|
|
} else {
|
|
flt->app_info_.identifier_ = identifier;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_get_control_level(MYSQL *mysql, int *level)
|
|
{
|
|
int ret = 0;
|
|
if (OB_ISNULL(mysql) || FALSE == get_use_full_link_trace(mysql)) {
|
|
// error
|
|
ret = 1;
|
|
} else if (OB_ISNULL(mysql->net.ob20protocol)) {
|
|
ret = 1;
|
|
} else {
|
|
FLTInfo *flt = mysql->net.ob20protocol->flt;
|
|
if (OB_ISNULL(flt)) {
|
|
ret = 1;
|
|
} else {
|
|
*level = flt->control_info_.level_;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_get_control_sample_pct(MYSQL *mysql, double *sample_pct)
|
|
{
|
|
int ret = 0;
|
|
if (OB_ISNULL(mysql) || FALSE == get_use_full_link_trace(mysql)) {
|
|
// error
|
|
ret = 1;
|
|
} else if (OB_ISNULL(mysql->net.ob20protocol)) {
|
|
ret = 1;
|
|
} else {
|
|
FLTInfo *flt = mysql->net.ob20protocol->flt;
|
|
if (OB_ISNULL(flt)) {
|
|
ret = 1;
|
|
} else {
|
|
*sample_pct = flt->control_info_.sample_pct_;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_get_control_record_policy(MYSQL *mysql, int *rp)
|
|
{
|
|
int ret = 0;
|
|
if (OB_ISNULL(mysql) || FALSE == get_use_full_link_trace(mysql)) {
|
|
// error
|
|
ret = 1;
|
|
} else if (OB_ISNULL(mysql->net.ob20protocol)) {
|
|
ret = 1;
|
|
} else {
|
|
FLTInfo *flt = mysql->net.ob20protocol->flt;
|
|
if (OB_ISNULL(flt)) {
|
|
ret = 1;
|
|
} else {
|
|
*rp = flt->control_info_.rp_;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_get_control_print_spct(MYSQL *mysql, double *sample_pct)
|
|
{
|
|
int ret = 0;
|
|
if (OB_ISNULL(mysql) || FALSE == get_use_full_link_trace(mysql)) {
|
|
// error
|
|
ret = 1;
|
|
} else if (OB_ISNULL(mysql->net.ob20protocol)) {
|
|
ret = 1;
|
|
} else {
|
|
FLTInfo *flt = mysql->net.ob20protocol->flt;
|
|
if (OB_ISNULL(flt)) {
|
|
ret = 1;
|
|
} else {
|
|
*sample_pct = flt->control_info_.print_sample_pct_;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int flt_get_control_slow_threshold(MYSQL *mysql, long int *slow_threshold)
|
|
{
|
|
int ret = 0;
|
|
if (OB_ISNULL(mysql) || FALSE == get_use_full_link_trace(mysql)) {
|
|
// error
|
|
ret = 1;
|
|
} else if (OB_ISNULL(mysql->net.ob20protocol)) {
|
|
ret = 1;
|
|
} else {
|
|
FLTInfo *flt = mysql->net.ob20protocol->flt;
|
|
if (OB_ISNULL(flt)) {
|
|
ret = 1;
|
|
} else {
|
|
*slow_threshold = flt->control_info_.slow_query_threshold_;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|