mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-28 14:16:32 +08:00
feat: Add on_mk_get_statistic_cb c api to obtain performance statistics data (#3549)
This commit is contained in:
parent
65c2abb0b5
commit
0935da60a3
@ -128,6 +128,15 @@ API_EXPORT char *API_CALL mk_ini_dump_string(mk_ini ini);
|
||||
* @param file 配置文件路径
|
||||
*/
|
||||
API_EXPORT void API_CALL mk_ini_dump_file(mk_ini ini, const char *file);
|
||||
///////////////////////////////////////////统计/////////////////////////////////////////////
|
||||
|
||||
typedef void(API_CALL *on_mk_get_statistic_cb)(void *user_data, mk_ini ini);
|
||||
|
||||
/**
|
||||
* 获取内存数据统计
|
||||
* @param ini 存放统计结果
|
||||
*/
|
||||
API_EXPORT void API_CALL mk_get_statistic(on_mk_get_statistic_cb cb, void *user_data, on_user_data_free free_cb);
|
||||
|
||||
///////////////////////////////////////////日志/////////////////////////////////////////////
|
||||
|
||||
|
@ -15,6 +15,9 @@
|
||||
#include "Util/util.h"
|
||||
#include "Util/mini.h"
|
||||
#include "Util/logger.h"
|
||||
#include "Util/TimeTicker.h"
|
||||
#include "Poller/EventPoller.h"
|
||||
#include "Thread/WorkThreadPool.h"
|
||||
#include "Common/config.h"
|
||||
|
||||
using namespace std;
|
||||
@ -132,6 +135,129 @@ API_EXPORT void API_CALL mk_ini_dump_file(mk_ini ini, const char *file) {
|
||||
ptr->dumpFile(file);
|
||||
}
|
||||
|
||||
extern uint64_t getTotalMemUsage();
|
||||
extern uint64_t getTotalMemBlock();
|
||||
extern uint64_t getThisThreadMemUsage();
|
||||
extern uint64_t getThisThreadMemBlock();
|
||||
extern std::vector<size_t> getBlockTypeSize();
|
||||
extern uint64_t getTotalMemBlockByType(int type);
|
||||
extern uint64_t getThisThreadMemBlockByType(int type);
|
||||
|
||||
namespace mediakit {
|
||||
class MediaSource;
|
||||
class MultiMediaSourceMuxer;
|
||||
class FrameImp;
|
||||
class Frame;
|
||||
class RtpPacket;
|
||||
class RtmpPacket;
|
||||
} // namespace mediakit
|
||||
|
||||
namespace toolkit {
|
||||
class TcpServer;
|
||||
class TcpSession;
|
||||
class UdpServer;
|
||||
class UdpSession;
|
||||
class TcpClient;
|
||||
class Socket;
|
||||
class Buffer;
|
||||
class BufferRaw;
|
||||
class BufferLikeString;
|
||||
class BufferList;
|
||||
} // namespace toolkit
|
||||
|
||||
API_EXPORT void API_CALL mk_get_statistic(on_mk_get_statistic_cb func, void *user_data, on_user_data_free free_cb) {
|
||||
assert(func);
|
||||
std::shared_ptr<void> data(user_data, free_cb);
|
||||
auto cb = [func, data](const toolkit::mINI &ini) { func(data.get(), (mk_ini)&ini); };
|
||||
auto obj = std::make_shared<toolkit::mINI>();
|
||||
auto &val = *obj;
|
||||
|
||||
val["object.MediaSource"] = ObjectStatistic<MediaSource>::count();
|
||||
val["object.MultiMediaSourceMuxer"] = ObjectStatistic<MultiMediaSourceMuxer>::count();
|
||||
|
||||
val["object.TcpServer"] = ObjectStatistic<TcpServer>::count();
|
||||
val["object.TcpSession"] = ObjectStatistic<TcpSession>::count();
|
||||
val["object.UdpServer"] = ObjectStatistic<UdpServer>::count();
|
||||
val["object.UdpSession"] = ObjectStatistic<UdpSession>::count();
|
||||
val["object.TcpClient"] = ObjectStatistic<TcpClient>::count();
|
||||
val["object.Socket"] = ObjectStatistic<Socket>::count();
|
||||
|
||||
val["object.FrameImp"] = ObjectStatistic<FrameImp>::count();
|
||||
val["object.Frame"] = ObjectStatistic<Frame>::count();
|
||||
|
||||
val["object.Buffer"] = ObjectStatistic<Buffer>::count();
|
||||
val["object.BufferRaw"] = ObjectStatistic<BufferRaw>::count();
|
||||
val["object.BufferLikeString"] = ObjectStatistic<BufferLikeString>::count();
|
||||
val["object.BufferList"] = ObjectStatistic<BufferList>::count();
|
||||
|
||||
val["object.RtpPacket"] = ObjectStatistic<RtpPacket>::count();
|
||||
val["object.RtmpPacket"] = ObjectStatistic<RtmpPacket>::count();
|
||||
#ifdef ENABLE_MEM_DEBUG
|
||||
auto bytes = getTotalMemUsage();
|
||||
val["memory.memUsage"] = bytes;
|
||||
val["memory.memUsageMB"] = (int)(bytes / 1024 / 1024);
|
||||
val["memory.memBlock"] = getTotalMemBlock();
|
||||
static auto block_type_size = getBlockTypeSize();
|
||||
{
|
||||
int i = 0;
|
||||
string str;
|
||||
size_t last = 0;
|
||||
for (auto sz : block_type_size) {
|
||||
str.append(to_string(last) + "~" + to_string(sz) + ":" + to_string(getTotalMemBlockByType(i++)) + ";");
|
||||
last = sz;
|
||||
}
|
||||
str.pop_back();
|
||||
val["memory.memBlockTypeCount"] = str;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto thread_size = EventPollerPool::Instance().getExecutorSize() + WorkThreadPool::Instance().getExecutorSize();
|
||||
std::shared_ptr<vector<toolkit::mINI>> thread_mem_info = std::make_shared<vector<toolkit::mINI>>(thread_size);
|
||||
|
||||
shared_ptr<void> finished(nullptr, [thread_mem_info, cb, obj](void *) {
|
||||
for (auto &val : *thread_mem_info) {
|
||||
auto thread_name = val["name"];
|
||||
replace(thread_name, "...", "~~~");
|
||||
auto prefix = "thread-" + thread_name + ".";
|
||||
for (auto &pr : val) {
|
||||
(*obj).emplace(prefix + pr.first, std::move(pr.second));
|
||||
}
|
||||
}
|
||||
// 触发回调
|
||||
cb(*obj);
|
||||
});
|
||||
|
||||
auto pos = 0;
|
||||
auto lambda = [&](const TaskExecutor::Ptr &executor) {
|
||||
auto &val = (*thread_mem_info)[pos++];
|
||||
val["load"] = executor->load();
|
||||
Ticker ticker;
|
||||
executor->async([finished, &val, ticker]() {
|
||||
val["name"] = getThreadName();
|
||||
val["delay"] = ticker.elapsedTime();
|
||||
#ifdef ENABLE_MEM_DEBUG
|
||||
auto bytes = getThisThreadMemUsage();
|
||||
val["memUsage"] = bytes;
|
||||
val["memUsageMB"] = bytes / 1024 / 1024;
|
||||
val["memBlock"] = getThisThreadMemBlock();
|
||||
{
|
||||
int i = 0;
|
||||
string str;
|
||||
size_t last = 0;
|
||||
for (auto sz : block_type_size) {
|
||||
str.append(to_string(last) + "~" + to_string(sz) + ":" + to_string(getThisThreadMemBlockByType(i++)) + ";");
|
||||
last = sz;
|
||||
}
|
||||
str.pop_back();
|
||||
val["memBlockTypeCount"] = str;
|
||||
}
|
||||
#endif
|
||||
});
|
||||
};
|
||||
EventPollerPool::Instance().for_each(lambda);
|
||||
WorkThreadPool::Instance().for_each(lambda);
|
||||
}
|
||||
|
||||
API_EXPORT void API_CALL mk_log_printf(int level, const char *file, const char *function, int line, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
@ -189,6 +189,14 @@ static void on_mk_webrtc_get_answer_sdp_func(void *user_data, const char *answer
|
||||
free((void *)answer);
|
||||
}
|
||||
}
|
||||
|
||||
void API_CALL on_get_statistic_cb(void *user_data, mk_ini ini) {
|
||||
const char *response_header[] = { NULL };
|
||||
char *str = mk_ini_dump_string(ini);
|
||||
mk_http_response_invoker_do_string(user_data, 200, response_header, str);
|
||||
mk_free(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 收到http api请求广播(包括GET/POST)
|
||||
* @param parser http请求内容对象
|
||||
@ -247,6 +255,9 @@ void API_CALL on_mk_http_request(const mk_parser parser,
|
||||
|
||||
mk_webrtc_get_answer_sdp(mk_http_response_invoker_clone(invoker), on_mk_webrtc_get_answer_sdp_func,
|
||||
mk_parser_get_url_param(parser, "type"), mk_parser_get_content(parser, NULL), rtc_url);
|
||||
} else if (strcmp(url, "/index/api/getStatistic") == 0) {
|
||||
//拦截api: /index/api/webrtc
|
||||
mk_get_statistic(on_get_statistic_cb, mk_http_response_invoker_clone(invoker), (on_user_data_free) mk_http_response_invoker_clone_release);
|
||||
} else {
|
||||
*consumed = 0;
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user