obconnector-c/libmariadb/ob_full_link_trace.c
2024-06-03 16:47:46 +08:00

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;
}