Files
oceanbase/src/sql/monitor/flt/ob_flt_span_mgr.cpp
2023-04-28 02:41:45 +00:00

226 lines
7.5 KiB
C++

// Copyright 2010-2016 Alibaba Inc. All Rights Reserved.
// Author:
//
// Normalizer:
//
// this file defines implementation of full link trace span manager
#define USING_LOG_PREFIX SERVER
#include "sql/monitor/flt/ob_flt_span_mgr.h"
#include "share/ob_define.h"
#include "lib/time/ob_time_utility.h"
#include "lib/allocator/ob_malloc.h"
#include "lib/allocator/ob_concurrent_fifo_allocator.h"
#include "lib/allocator/page_arena.h"
#include "lib/stat/ob_session_stat.h"
#include "lib/alloc/alloc_func.h"
#include "lib/thread/thread_mgr.h"
#include "lib/rc/ob_rc.h"
#include "share/rc/ob_context.h"
#include "observer/ob_server.h"
#include "sql/session/ob_basic_session_info.h"
#include "lib/trace/ob_trace.h"
namespace oceanbase
{
using namespace oceanbase::share::schema;
namespace sql
{
ObFLTSpanMgr* get_flt_span_manager() {
return MTL(ObFLTSpanMgr*);
}
int ObFLTSpanMgr::init(uint64_t tenant_id, const int64_t max_mem_size, const int64_t queue_size)
{
int ret = OB_SUCCESS;
if (inited_) {
ret = OB_INIT_TWICE;
} else if (OB_FAIL(queue_.init("SqlFltSpanRec", queue_size, tenant_id))) {
SERVER_LOG(WARN, "Failed to init ObMySQLRequestQueue", K(ret));
} else if (OB_FAIL(TG_CREATE_TENANT(lib::TGDefIDs::ReqMemEvict, tg_id_))) {
SERVER_LOG(WARN, "create failed", K(ret));
} else if (OB_FAIL(TG_START(tg_id_))) {
SERVER_LOG(WARN, "init timer fail", K(ret));
} else if (OB_FAIL(allocator_.init(FLT_SPAN_PAGE_SIZE,
"SqlFltSpanRec",
tenant_id,
INT64_MAX))) {
SERVER_LOG(WARN, "failed to init allocator", K(ret));
} else {
mem_limit_ = max_mem_size;
tenant_id_ = tenant_id;
inited_ = true;
destroyed_ = false;
}
if ((OB_FAIL(ret)) && (!inited_)) {
destroy();
}
return ret;
}
void ObFLTSpanMgr::destroy()
{
if (!destroyed_) {
TG_DESTROY(tg_id_);
clear_queue();
queue_.destroy();
allocator_.destroy();
inited_ = false;
destroyed_ = true;
}
}
int ObFLTSpanMgr::mtl_init(ObFLTSpanMgr* &span_mgr)
{
int ret = OB_SUCCESS;
span_mgr = OB_NEW(ObFLTSpanMgr, "SqlFltSpanRec");
if (nullptr == span_mgr) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("failed to alloc memory for ObMySQLRequestManager", K(ret));
} else {
uint64_t tenant_id = lib::current_resource_owner_id();
int64_t mem_limit = lib::get_tenant_memory_limit(tenant_id);
int64_t queue_size = MAX_QUEUE_SIZE;
if (OB_FAIL(span_mgr->init(tenant_id, mem_limit, queue_size))) {
LOG_WARN("failed to init request manager", K(ret));
} else {
// do nothing
}
}
if (OB_FAIL(ret) && span_mgr != nullptr) {
// cleanup
common::ob_delete(span_mgr);
span_mgr = nullptr;
}
return ret;
}
void ObFLTSpanMgr::mtl_destroy(ObFLTSpanMgr* &span_mgr)
{
common::ob_delete(span_mgr);
span_mgr = nullptr;
}
int ObFLTSpanMgr::record_span(ObFLTSpanData &span_data, bool is_formmated_json)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
} else {
ObFLTSpanRec *rec = NULL;
char *buf = NULL;
//alloc mem from allocator
int64_t pos = sizeof(ObFLTSpanRec);
int64_t total_sz = sizeof(ObFLTSpanRec)
+ min(span_data.trace_id_.length(), OB_MAX_SPAN_LENGTH)
+ min(span_data.span_id_.length(), OB_MAX_SPAN_LENGTH)
+ min(span_data.parent_span_id_.length(), OB_MAX_SPAN_LENGTH)
+ min(span_data.span_name_.length(), OB_MAX_SPAN_LENGTH)
+ min(span_data.tags_.length(), OB_MAX_SPAN_TAG_LENGTH)
+ min(span_data.logs_.length(), OB_MAX_SPAN_TAG_LENGTH)
+ (is_formmated_json ? 0:4);
if (NULL == (buf = (char*)allocator_.alloc(total_sz))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
if (REACH_TIME_INTERVAL(100 * 1000)) {
SERVER_LOG(WARN, "record concurrent fifoallocator alloc mem failed", K(sizeof(ObFLTSpanRec)), K(ret));
}
} else {
rec = new(buf)ObFLTSpanRec();
rec->allocator_ = &allocator_;
rec->data_ = span_data;
//deep copy trace id
if (!span_data.trace_id_.empty()) {
const int len = min(span_data.trace_id_.length(), OB_MAX_SPAN_LENGTH);
MEMCPY(buf + pos, span_data.trace_id_.ptr(), len);
rec->data_.trace_id_.assign_ptr(buf + pos, len);
pos += len;
}
//deep copy span id
if (!span_data.span_id_.empty()) {
const int len = min(span_data.span_id_.length(), OB_MAX_SPAN_LENGTH);
MEMCPY(buf + pos, span_data.span_id_.ptr(), len);
rec->data_.span_id_.assign_ptr(buf + pos, len);
pos += len;
}
//deep copy parent span id
if (!span_data.parent_span_id_.empty()) {
const int len = min(span_data.parent_span_id_.length(), OB_MAX_SPAN_LENGTH);
MEMCPY(buf + pos, span_data.parent_span_id_.ptr(), len);
rec->data_.parent_span_id_.assign_ptr(buf + pos, len);
pos += len;
}
//deep copy span name
if (!span_data.span_name_.empty()) {
const int len = min(span_data.span_name_.length(), OB_MAX_SPAN_LENGTH);
MEMCPY(buf + pos, span_data.span_name_.ptr(), len);
rec->data_.span_name_.assign_ptr(buf + pos, len);
pos += len;
}
//deep copy tags
if (!span_data.tags_.empty()) {
const int len = min(span_data.tags_.length(), OB_MAX_SPAN_TAG_LENGTH);
if (is_formmated_json) {
MEMCPY(buf + pos, span_data.tags_.ptr(), len);
rec->data_.tags_.assign_ptr(buf + pos, len);
pos += len;
} else {
buf[pos] = '[';
MEMCPY(buf + pos + 1, span_data.tags_.ptr(), len);
buf[pos + len + 1] = ']';
rec->data_.tags_.assign_ptr(buf + pos, len + 2);
pos += len + 2;
}
}
//deep copy logs_
if (!span_data.logs_.empty()) {
const int len = min(span_data.logs_.length(), OB_MAX_SPAN_TAG_LENGTH);
if (is_formmated_json) {
MEMCPY(buf + pos, span_data.logs_.ptr(), len);
rec->data_.logs_.assign_ptr(buf + pos, len);
pos += len;
} else {
buf[pos] = '[';
MEMCPY(buf + pos + 1, span_data.logs_.ptr(), len);
buf[pos + len + 1] = ']';
rec->data_.logs_.assign_ptr(buf + pos, len + 2);
pos += len + 2;
}
}
//push into queue
if (OB_SUCC(ret)) {
int64_t req_id = 0;
if (OB_FAIL(queue_.push(rec, req_id))) {
//sql audit槽位已满时会push失败, 依赖后台线程进行淘汰获得可用槽位
if (REACH_TIME_INTERVAL(2 * 1000 * 1000)) {
SERVER_LOG(WARN, "push into queue failed", K(ret));
}
allocator_.free(rec);
rec = NULL;
} else {
rec->data_.req_id_ = req_id;
}
} else {
allocator_.free(rec);
rec = NULL;
}
}
} // end
return ret;
}
// evict old span and release memory
int ObFLTSpanMgr::release_old(int64_t limit)
{
void * span = NULL;
int64_t count = 0;
while(count++ < limit && NULL != (span = queue_.pop())) {
free(span);
}
return common::OB_SUCCESS;
}
} // end of namespace obmysql
} // end of namespace oceanbase