1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-15 04:42:04 +00:00
srs/trunk/src/app/srs_app_statistic.cpp

777 lines
21 KiB
C++
Raw Normal View History

2017-03-25 09:21:39 +00:00
/**
* The MIT License (MIT)
*
2019-12-30 02:10:35 +00:00
* Copyright (c) 2013-2020 Winlin
2017-03-25 09:21:39 +00:00
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
2015-01-04 14:47:12 +00:00
#include <srs_app_statistic.hpp>
#include <unistd.h>
2015-01-05 04:57:48 +00:00
#include <sstream>
using namespace std;
2015-06-13 08:04:59 +00:00
#include <srs_rtmp_stack.hpp>
2015-08-21 08:20:19 +00:00
#include <srs_protocol_json.hpp>
2015-05-23 01:58:00 +00:00
#include <srs_protocol_kbps.hpp>
#include <srs_app_conn.hpp>
2015-04-02 07:05:09 +00:00
#include <srs_app_config.hpp>
#include <srs_kernel_utility.hpp>
2015-09-22 01:05:21 +00:00
#include <srs_protocol_amf0.hpp>
2015-01-04 14:47:12 +00:00
2018-08-26 06:29:45 +00:00
int64_t srs_gvid = 0;
int64_t srs_generate_id()
{
2018-08-26 06:29:45 +00:00
if (srs_gvid == 0) {
srs_gvid = getpid() * 3;
}
return srs_gvid++;
}
SrsStatisticVhost::SrsStatisticVhost()
{
id = srs_generate_id();
2018-12-23 12:47:17 +00:00
clk = new SrsWallClock();
kbps = new SrsKbps(clk);
kbps->set_io(NULL, NULL);
nb_clients = 0;
2015-08-22 14:51:59 +00:00
nb_streams = 0;
}
SrsStatisticVhost::~SrsStatisticVhost()
{
srs_freep(kbps);
2018-12-23 12:47:17 +00:00
srs_freep(clk);
}
2018-01-01 13:20:57 +00:00
srs_error_t SrsStatisticVhost::dumps(SrsJsonObject* obj)
{
2018-01-01 13:20:57 +00:00
srs_error_t err = srs_success;
// dumps the config of vhost.
bool hls_enabled = _srs_config->get_hls_enabled(vhost);
2015-08-21 09:00:52 +00:00
bool enabled = _srs_config->get_vhost_enabled(vhost);
2020-06-18 03:45:43 +00:00
obj->set("id", SrsJsonAny::str(id.c_str()));
2015-09-19 04:27:31 +00:00
obj->set("name", SrsJsonAny::str(vhost.c_str()));
obj->set("enabled", SrsJsonAny::boolean(enabled));
obj->set("clients", SrsJsonAny::integer(nb_clients));
obj->set("streams", SrsJsonAny::integer(nb_streams));
obj->set("send_bytes", SrsJsonAny::integer(kbps->get_send_bytes()));
obj->set("recv_bytes", SrsJsonAny::integer(kbps->get_recv_bytes()));
2015-09-19 04:27:31 +00:00
SrsJsonObject* okbps = SrsJsonAny::object();
obj->set("kbps", okbps);
okbps->set("recv_30s", SrsJsonAny::integer(kbps->get_recv_kbps_30s()));
okbps->set("send_30s", SrsJsonAny::integer(kbps->get_send_kbps_30s()));
2015-09-19 04:27:31 +00:00
SrsJsonObject* hls = SrsJsonAny::object();
obj->set("hls", hls);
2015-09-19 04:27:31 +00:00
hls->set("enabled", SrsJsonAny::boolean(hls_enabled));
if (hls_enabled) {
2019-04-16 00:14:12 +00:00
hls->set("fragment", SrsJsonAny::number(srsu2msi(_srs_config->get_hls_fragment(vhost))/1000.0));
}
2018-01-01 13:20:57 +00:00
return err;
}
SrsStatisticStream::SrsStatisticStream()
{
id = srs_generate_id();
vhost = NULL;
active = false;
2015-03-08 07:33:08 +00:00
has_video = false;
2017-02-12 12:38:39 +00:00
vcodec = SrsVideoCodecIdReserved;
avc_profile = SrsAvcProfileReserved;
avc_level = SrsAvcLevelReserved;
2015-03-08 07:33:08 +00:00
has_audio = false;
2017-02-12 12:38:39 +00:00
acodec = SrsAudioCodecIdReserved1;
asample_rate = SrsAudioSampleRateReserved;
asound_type = SrsAudioChannelsReserved;
aac_object = SrsAacObjectTypeReserved;
width = 0;
height = 0;
2018-12-23 12:47:17 +00:00
clk = new SrsWallClock();
kbps = new SrsKbps(clk);
kbps->set_io(NULL, NULL);
nb_clients = 0;
nb_frames = 0;
}
SrsStatisticStream::~SrsStatisticStream()
{
srs_freep(kbps);
2018-12-23 12:47:17 +00:00
srs_freep(clk);
}
2018-01-01 13:20:57 +00:00
srs_error_t SrsStatisticStream::dumps(SrsJsonObject* obj)
{
2018-01-01 13:20:57 +00:00
srs_error_t err = srs_success;
2020-06-18 03:45:43 +00:00
obj->set("id", SrsJsonAny::str(id.c_str()));
2015-09-19 04:27:31 +00:00
obj->set("name", SrsJsonAny::str(stream.c_str()));
2020-06-18 03:45:43 +00:00
obj->set("vhost", SrsJsonAny::str(vhost->id.c_str()));
2015-09-19 04:27:31 +00:00
obj->set("app", SrsJsonAny::str(app.c_str()));
obj->set("live_ms", SrsJsonAny::integer(srsu2ms(srs_get_system_time())));
obj->set("clients", SrsJsonAny::integer(nb_clients));
2017-04-23 13:00:06 +00:00
obj->set("frames", SrsJsonAny::integer(nb_frames));
obj->set("send_bytes", SrsJsonAny::integer(kbps->get_send_bytes()));
obj->set("recv_bytes", SrsJsonAny::integer(kbps->get_recv_bytes()));
2015-09-19 04:27:31 +00:00
SrsJsonObject* okbps = SrsJsonAny::object();
obj->set("kbps", okbps);
okbps->set("recv_30s", SrsJsonAny::integer(kbps->get_recv_kbps_30s()));
okbps->set("send_30s", SrsJsonAny::integer(kbps->get_send_kbps_30s()));
2015-09-19 04:27:31 +00:00
SrsJsonObject* publish = SrsJsonAny::object();
obj->set("publish", publish);
2015-09-19 04:27:31 +00:00
publish->set("active", SrsJsonAny::boolean(active));
2020-06-18 03:45:43 +00:00
publish->set("cid", SrsJsonAny::str(connection_cid.c_str()));
if (!has_video) {
2015-09-19 04:27:31 +00:00
obj->set("video", SrsJsonAny::null());
} else {
2015-09-19 04:27:31 +00:00
SrsJsonObject* video = SrsJsonAny::object();
obj->set("video", video);
2017-02-12 12:38:39 +00:00
video->set("codec", SrsJsonAny::str(srs_video_codec_id2str(vcodec).c_str()));
video->set("profile", SrsJsonAny::str(srs_avc_profile2str(avc_profile).c_str()));
video->set("level", SrsJsonAny::str(srs_avc_level2str(avc_level).c_str()));
video->set("width", SrsJsonAny::integer(width));
video->set("height", SrsJsonAny::integer(height));
}
if (!has_audio) {
2015-09-19 04:27:31 +00:00
obj->set("audio", SrsJsonAny::null());
} else {
2015-09-19 04:27:31 +00:00
SrsJsonObject* audio = SrsJsonAny::object();
obj->set("audio", audio);
2017-02-12 12:38:39 +00:00
audio->set("codec", SrsJsonAny::str(srs_audio_codec_id2str(acodec).c_str()));
audio->set("sample_rate", SrsJsonAny::integer(srs_flv_srates[asample_rate]));
audio->set("channel", SrsJsonAny::integer(asound_type + 1));
2017-02-12 12:38:39 +00:00
audio->set("profile", SrsJsonAny::str(srs_aac_object2str(aac_object).c_str()));
}
2018-01-01 13:20:57 +00:00
return err;
}
void SrsStatisticStream::publish(SrsContextId cid)
2015-05-08 08:45:25 +00:00
{
connection_cid = cid;
active = true;
2015-08-22 14:51:59 +00:00
vhost->nb_streams++;
2015-05-08 08:45:25 +00:00
}
2015-03-08 07:33:08 +00:00
void SrsStatisticStream::close()
{
has_video = false;
has_audio = false;
active = false;
2015-08-22 14:51:59 +00:00
vhost->nb_streams--;
2015-03-08 07:33:08 +00:00
}
2015-08-21 09:00:52 +00:00
SrsStatisticClient::SrsStatisticClient()
{
2020-06-18 03:45:43 +00:00
id = "";
stream = NULL;
conn = NULL;
req = NULL;
type = SrsRtmpConnUnknown;
create = srs_get_system_time();
2015-08-21 09:00:52 +00:00
}
SrsStatisticClient::~SrsStatisticClient()
{
}
2018-01-01 13:20:57 +00:00
srs_error_t SrsStatisticClient::dumps(SrsJsonObject* obj)
2015-08-21 09:00:52 +00:00
{
2018-01-01 13:20:57 +00:00
srs_error_t err = srs_success;
2015-08-21 09:00:52 +00:00
2020-06-18 03:45:43 +00:00
obj->set("id", SrsJsonAny::str(id.c_str()));
obj->set("vhost", SrsJsonAny::str(stream->vhost->id.c_str()));
obj->set("stream", SrsJsonAny::str(stream->id.c_str()));
2015-09-19 04:27:31 +00:00
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
obj->set("pageUrl", SrsJsonAny::str(req->pageUrl.c_str()));
obj->set("swfUrl", SrsJsonAny::str(req->swfUrl.c_str()));
obj->set("tcUrl", SrsJsonAny::str(req->tcUrl.c_str()));
obj->set("url", SrsJsonAny::str(req->get_stream_url().c_str()));
obj->set("type", SrsJsonAny::str(srs_client_type_string(type).c_str()));
obj->set("publish", SrsJsonAny::boolean(srs_client_type_is_publish(type)));
obj->set("alive", SrsJsonAny::number(srsu2ms(srs_get_system_time() - create) / 1000.0));
2015-08-21 09:00:52 +00:00
2018-01-01 13:20:57 +00:00
return err;
2015-08-21 09:00:52 +00:00
}
2020-03-27 05:37:39 +00:00
SrsStatisticCategory::SrsStatisticCategory()
{
2020-04-14 23:10:41 +00:00
nn = 0;
2020-03-27 05:37:39 +00:00
a = 0;
b = 0;
c = 0;
d = 0;
e = 0;
f = 0;
g = 0;
h = 0;
i = 0;
j = 0;
}
SrsStatisticCategory::~SrsStatisticCategory()
{
}
2018-08-26 06:29:45 +00:00
SrsStatistic* SrsStatistic::_instance = NULL;
2015-01-04 14:47:12 +00:00
SrsStatistic::SrsStatistic()
{
_server_id = srs_generate_id();
2018-12-23 12:47:17 +00:00
clk = new SrsWallClock();
kbps = new SrsKbps(clk);
kbps->set_io(NULL, NULL);
2020-03-27 05:37:39 +00:00
perf_iovs = new SrsStatisticCategory();
perf_msgs = new SrsStatisticCategory();
2020-04-14 13:49:49 +00:00
perf_rtp = new SrsStatisticCategory();
perf_rtc = new SrsStatisticCategory();
2020-04-16 02:05:17 +00:00
perf_bytes = new SrsStatisticCategory();
2015-01-04 14:47:12 +00:00
}
SrsStatistic::~SrsStatistic()
{
srs_freep(kbps);
2018-12-23 12:47:17 +00:00
srs_freep(clk);
2015-01-05 04:40:38 +00:00
if (true) {
2020-06-18 03:45:43 +00:00
std::map<std::string, SrsStatisticVhost*>::iterator it;
2015-01-05 04:40:38 +00:00
for (it = vhosts.begin(); it != vhosts.end(); it++) {
SrsStatisticVhost* vhost = it->second;
srs_freep(vhost);
}
}
if (true) {
2020-06-18 03:45:43 +00:00
std::map<std::string, SrsStatisticStream*>::iterator it;
2015-01-05 04:40:38 +00:00
for (it = streams.begin(); it != streams.end(); it++) {
SrsStatisticStream* stream = it->second;
srs_freep(stream);
}
}
if (true) {
2020-06-18 03:45:43 +00:00
std::map<std::string, SrsStatisticClient*>::iterator it;
2015-01-05 04:40:38 +00:00
for (it = clients.begin(); it != clients.end(); it++) {
SrsStatisticClient* client = it->second;
srs_freep(client);
}
}
2015-08-21 09:00:52 +00:00
vhosts.clear();
rvhosts.clear();
streams.clear();
rstreams.clear();
2020-03-27 05:37:39 +00:00
srs_freep(perf_iovs);
srs_freep(perf_msgs);
2020-04-14 13:49:49 +00:00
srs_freep(perf_rtp);
srs_freep(perf_rtc);
2020-04-16 02:05:17 +00:00
srs_freep(perf_bytes);
}
SrsStatistic* SrsStatistic::instance()
{
2018-08-26 06:29:45 +00:00
if (_instance == NULL) {
_instance = new SrsStatistic();
}
return _instance;
2015-01-04 14:47:12 +00:00
}
2020-06-18 03:45:43 +00:00
SrsStatisticVhost* SrsStatistic::find_vhost(string vid)
2015-08-21 09:00:52 +00:00
{
2020-06-18 03:45:43 +00:00
std::map<std::string, SrsStatisticVhost*>::iterator it;
2015-08-21 09:00:52 +00:00
if ((it = vhosts.find(vid)) != vhosts.end()) {
return it->second;
}
return NULL;
}
2020-06-18 03:45:43 +00:00
SrsStatisticStream* SrsStatistic::find_stream(string sid)
{
2020-06-18 03:45:43 +00:00
std::map<std::string, SrsStatisticStream*>::iterator it;
2015-08-21 09:00:52 +00:00
if ((it = streams.find(sid)) != streams.end()) {
return it->second;
}
return NULL;
}
SrsStatisticClient* SrsStatistic::find_client(string client_id)
2015-08-11 07:23:46 +00:00
{
2020-06-18 03:45:43 +00:00
std::map<std::string, SrsStatisticClient*>::iterator it;
if ((it = clients.find(client_id)) != clients.end()) {
2015-08-21 09:00:52 +00:00
return it->second;
2015-08-11 07:23:46 +00:00
}
return NULL;
}
2018-01-01 13:20:57 +00:00
srs_error_t SrsStatistic::on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, SrsAvcProfile avc_profile, SrsAvcLevel avc_level, int width, int height)
2017-03-25 09:21:39 +00:00
{
2018-01-01 13:20:57 +00:00
srs_error_t err = srs_success;
2015-01-05 04:57:48 +00:00
2015-03-08 07:33:08 +00:00
SrsStatisticVhost* vhost = create_vhost(req);
SrsStatisticStream* stream = create_stream(vhost, req);
2017-03-25 09:21:39 +00:00
2015-03-08 07:33:08 +00:00
stream->has_video = true;
stream->vcodec = vcodec;
stream->avc_profile = avc_profile;
stream->avc_level = avc_level;
2015-01-05 04:57:48 +00:00
stream->width = width;
stream->height = height;
2018-01-01 13:20:57 +00:00
return err;
2015-03-08 07:33:08 +00:00
}
2018-01-01 13:20:57 +00:00
srs_error_t SrsStatistic::on_audio_info(SrsRequest* req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, SrsAudioChannels asound_type, SrsAacObjectType aac_object)
2017-03-25 09:21:39 +00:00
{
2018-01-01 13:20:57 +00:00
srs_error_t err = srs_success;
2015-01-05 04:57:48 +00:00
2015-03-08 07:33:08 +00:00
SrsStatisticVhost* vhost = create_vhost(req);
SrsStatisticStream* stream = create_stream(vhost, req);
2017-03-25 09:21:39 +00:00
2015-03-08 07:33:08 +00:00
stream->has_audio = true;
stream->acodec = acodec;
stream->asample_rate = asample_rate;
stream->asound_type = asound_type;
stream->aac_object = aac_object;
2015-03-08 07:33:08 +00:00
2018-01-01 13:20:57 +00:00
return err;
2015-03-08 07:33:08 +00:00
}
2018-01-01 13:20:57 +00:00
srs_error_t SrsStatistic::on_video_frames(SrsRequest* req, int nb_frames)
{
2018-01-01 13:20:57 +00:00
srs_error_t err = srs_success;
SrsStatisticVhost* vhost = create_vhost(req);
SrsStatisticStream* stream = create_stream(vhost, req);
stream->nb_frames += nb_frames;
2018-01-01 13:20:57 +00:00
return err;
}
void SrsStatistic::on_stream_publish(SrsRequest* req, SrsContextId cid)
2015-05-08 08:45:25 +00:00
{
SrsStatisticVhost* vhost = create_vhost(req);
SrsStatisticStream* stream = create_stream(vhost, req);
2017-03-25 09:21:39 +00:00
stream->publish(cid);
2015-05-08 08:45:25 +00:00
}
2015-03-08 07:33:08 +00:00
void SrsStatistic::on_stream_close(SrsRequest* req)
{
SrsStatisticVhost* vhost = create_vhost(req);
SrsStatisticStream* stream = create_stream(vhost, req);
stream->close();
2017-03-11 08:28:18 +00:00
// TODO: FIXME: Should fix https://github.com/ossrs/srs/issues/803
if (true) {
2020-06-18 03:45:43 +00:00
std::map<std::string, SrsStatisticStream*>::iterator it;
2017-03-11 08:28:18 +00:00
if ((it=streams.find(stream->id)) != streams.end()) {
streams.erase(it);
}
}
// TODO: FIXME: Should fix https://github.com/ossrs/srs/issues/803
if (true) {
std::map<std::string, SrsStatisticStream*>::iterator it;
if ((it=rstreams.find(stream->url)) != rstreams.end()) {
rstreams.erase(it);
}
}
2015-03-08 07:33:08 +00:00
}
srs_error_t SrsStatistic::on_client(SrsContextId cid, SrsRequest* req, SrsConnection* conn, SrsRtmpConnType type)
2015-03-08 07:33:08 +00:00
{
2018-01-01 13:20:57 +00:00
srs_error_t err = srs_success;
// TODO: FIXME: We should use UUID for client ID.
std::string id = cid.c_str();
2015-03-08 07:33:08 +00:00
SrsStatisticVhost* vhost = create_vhost(req);
SrsStatisticStream* stream = create_stream(vhost, req);
2017-03-25 09:21:39 +00:00
2015-01-06 14:20:31 +00:00
// create client if not exists
SrsStatisticClient* client = NULL;
if (clients.find(id) == clients.end()) {
client = new SrsStatisticClient();
client->id = id;
2015-01-06 14:20:31 +00:00
client->stream = stream;
clients[id] = client;
} else {
client = clients[id];
}
// got client.
2015-08-22 05:36:15 +00:00
client->conn = conn;
client->req = req;
client->type = type;
stream->nb_clients++;
vhost->nb_clients++;
2017-03-25 09:21:39 +00:00
2018-01-01 13:20:57 +00:00
return err;
2015-01-06 14:20:31 +00:00
}
void SrsStatistic::on_disconnect(SrsContextId cid)
2015-01-06 14:20:31 +00:00
{
// TODO: FIXME: We should use UUID for client ID.
std::string id = cid.c_str();
2020-06-18 03:45:43 +00:00
std::map<std::string, SrsStatisticClient*>::iterator it;
if ((it = clients.find(id)) == clients.end()) {
return;
2015-01-06 14:20:31 +00:00
}
2017-03-25 09:21:39 +00:00
SrsStatisticClient* client = it->second;
SrsStatisticStream* stream = client->stream;
SrsStatisticVhost* vhost = stream->vhost;
srs_freep(client);
clients.erase(it);
stream->nb_clients--;
vhost->nb_clients--;
2015-01-06 14:20:31 +00:00
}
void SrsStatistic::kbps_add_delta(SrsConnection* conn)
{
// TODO: FIXME: Should not use context id as connection id.
std::string id = conn->srs_id().c_str();
if (clients.find(id) == clients.end()) {
return;
}
SrsStatisticClient* client = clients[id];
// resample the kbps to collect the delta.
2019-01-01 09:36:27 +00:00
int64_t in, out;
conn->remark(&in, &out);
// add delta of connection to kbps.
// for next sample() of server kbps can get the stat.
2019-01-01 09:36:27 +00:00
kbps->add_delta(in, out);
client->stream->kbps->add_delta(in, out);
client->stream->vhost->kbps->add_delta(in, out);
}
SrsKbps* SrsStatistic::kbps_sample()
{
kbps->sample();
if (true) {
2020-06-18 03:45:43 +00:00
std::map<std::string, SrsStatisticVhost*>::iterator it;
for (it = vhosts.begin(); it != vhosts.end(); it++) {
SrsStatisticVhost* vhost = it->second;
vhost->kbps->sample();
}
}
if (true) {
2020-06-18 03:45:43 +00:00
std::map<std::string, SrsStatisticStream*>::iterator it;
for (it = streams.begin(); it != streams.end(); it++) {
SrsStatisticStream* stream = it->second;
stream->kbps->sample();
}
}
return kbps;
}
int64_t SrsStatistic::server_id()
{
return _server_id;
}
2018-01-01 13:20:57 +00:00
srs_error_t SrsStatistic::dumps_vhosts(SrsJsonArray* arr)
2015-01-04 14:47:12 +00:00
{
2018-01-01 13:20:57 +00:00
srs_error_t err = srs_success;
2017-03-25 09:21:39 +00:00
2020-06-18 03:45:43 +00:00
std::map<std::string, SrsStatisticVhost*>::iterator it;
2015-01-05 04:57:48 +00:00
for (it = vhosts.begin(); it != vhosts.end(); it++) {
SrsStatisticVhost* vhost = it->second;
2015-09-19 04:27:31 +00:00
SrsJsonObject* obj = SrsJsonAny::object();
arr->append(obj);
2015-04-02 07:05:09 +00:00
2018-01-01 13:20:57 +00:00
if ((err = vhost->dumps(obj)) != srs_success) {
return srs_error_wrap(err, "dump vhost");
}
2015-01-05 04:57:48 +00:00
}
2017-03-25 09:21:39 +00:00
2018-01-01 13:20:57 +00:00
return err;
2015-01-04 14:47:12 +00:00
}
2018-01-01 13:20:57 +00:00
srs_error_t SrsStatistic::dumps_streams(SrsJsonArray* arr)
2015-01-04 14:47:12 +00:00
{
2018-01-01 13:20:57 +00:00
srs_error_t err = srs_success;
2015-01-05 04:57:48 +00:00
2020-06-18 03:45:43 +00:00
std::map<std::string, SrsStatisticStream*>::iterator it;
2015-01-05 04:57:48 +00:00
for (it = streams.begin(); it != streams.end(); it++) {
SrsStatisticStream* stream = it->second;
2015-09-19 04:27:31 +00:00
SrsJsonObject* obj = SrsJsonAny::object();
arr->append(obj);
2017-03-25 09:21:39 +00:00
2018-01-01 13:20:57 +00:00
if ((err = stream->dumps(obj)) != srs_success) {
return srs_error_wrap(err, "dump stream");
}
2015-01-05 04:57:48 +00:00
}
2018-01-01 13:20:57 +00:00
return err;
2015-01-05 04:40:38 +00:00
}
2015-03-08 07:33:08 +00:00
2018-01-01 13:20:57 +00:00
srs_error_t SrsStatistic::dumps_clients(SrsJsonArray* arr, int start, int count)
2015-08-21 09:00:52 +00:00
{
2018-01-01 13:20:57 +00:00
srs_error_t err = srs_success;
2015-08-21 09:00:52 +00:00
2020-06-18 03:45:43 +00:00
std::map<std::string, SrsStatisticClient*>::iterator it = clients.begin();
for (int i = 0; i < start + count && it != clients.end(); it++, i++) {
2015-08-21 09:00:52 +00:00
if (i < start) {
continue;
}
SrsStatisticClient* client = it->second;
2015-09-19 04:27:31 +00:00
SrsJsonObject* obj = SrsJsonAny::object();
arr->append(obj);
2015-08-21 09:00:52 +00:00
2018-01-01 13:20:57 +00:00
if ((err = client->dumps(obj)) != srs_success) {
return srs_error_wrap(err, "dump client");
2015-08-21 09:00:52 +00:00
}
}
2018-01-01 13:20:57 +00:00
return err;
2015-08-21 09:00:52 +00:00
}
2020-04-14 13:49:49 +00:00
void SrsStatistic::perf_on_msgs(int nb_msgs)
{
perf_on_packets(perf_msgs, nb_msgs);
}
2020-03-27 05:37:39 +00:00
2020-04-14 13:49:49 +00:00
srs_error_t SrsStatistic::dumps_perf_msgs(SrsJsonObject* obj)
{
return dumps_perf(perf_msgs, obj);
2020-03-27 05:37:39 +00:00
}
2020-04-14 13:49:49 +00:00
void SrsStatistic::perf_on_rtc_packets(int nb_packets)
2020-03-27 05:37:39 +00:00
{
2020-04-14 13:49:49 +00:00
perf_on_packets(perf_rtc, nb_packets);
}
2020-03-27 05:37:39 +00:00
2020-04-14 13:49:49 +00:00
srs_error_t SrsStatistic::dumps_perf_rtc_packets(SrsJsonObject* obj)
{
return dumps_perf(perf_rtc, obj);
}
2020-03-27 05:37:39 +00:00
2020-04-14 13:49:49 +00:00
void SrsStatistic::perf_on_rtp_packets(int nb_packets)
{
perf_on_packets(perf_rtp, nb_packets);
}
2020-03-27 05:37:39 +00:00
2020-04-14 13:49:49 +00:00
srs_error_t SrsStatistic::dumps_perf_rtp_packets(SrsJsonObject* obj)
{
return dumps_perf(perf_rtp, obj);
2020-03-27 05:37:39 +00:00
}
2020-04-14 13:49:49 +00:00
void SrsStatistic::perf_on_writev_iovs(int nb_iovs)
{
perf_on_packets(perf_iovs, nb_iovs);
}
2020-04-05 16:24:14 +00:00
2020-04-14 13:49:49 +00:00
srs_error_t SrsStatistic::dumps_perf_writev_iovs(SrsJsonObject* obj)
{
return dumps_perf(perf_iovs, obj);
}
2020-04-17 08:36:56 +00:00
void SrsStatistic::perf_on_rtc_bytes(int nn_bytes, int nn_rtp_bytes, int nn_padding)
2020-04-16 02:05:17 +00:00
{
2020-04-17 08:36:56 +00:00
// a: AVFrame bytes.
// b: RTC bytes.
// c: RTC paddings.
2020-04-16 02:05:17 +00:00
perf_bytes->a += nn_bytes;
2020-04-17 08:36:56 +00:00
perf_bytes->b += nn_rtp_bytes;
perf_bytes->c += nn_padding;
2020-04-16 02:05:17 +00:00
2020-04-17 08:36:56 +00:00
perf_bytes->nn += nn_rtp_bytes;
2020-04-16 02:05:17 +00:00
}
srs_error_t SrsStatistic::dumps_perf_bytes(SrsJsonObject* obj)
{
2020-04-17 08:36:56 +00:00
obj->set("avframe_bytes", SrsJsonAny::integer(perf_bytes->a));
obj->set("rtc_bytes", SrsJsonAny::integer(perf_bytes->b));
obj->set("rtc_padding", SrsJsonAny::integer(perf_bytes->c));
2020-04-16 02:05:17 +00:00
obj->set("nn", SrsJsonAny::integer(perf_bytes->nn));
return srs_success;
}
2020-04-15 02:50:56 +00:00
void SrsStatistic::reset_perf()
{
srs_freep(perf_iovs);
srs_freep(perf_msgs);
srs_freep(perf_rtp);
srs_freep(perf_rtc);
2020-04-16 02:05:17 +00:00
srs_freep(perf_bytes);
2020-04-15 02:50:56 +00:00
perf_iovs = new SrsStatisticCategory();
perf_msgs = new SrsStatisticCategory();
perf_rtp = new SrsStatisticCategory();
perf_rtc = new SrsStatisticCategory();
2020-04-16 02:05:17 +00:00
perf_bytes = new SrsStatisticCategory();
2020-04-15 02:50:56 +00:00
}
2020-04-14 13:49:49 +00:00
void SrsStatistic::perf_on_packets(SrsStatisticCategory* p, int nb_msgs)
{
2020-04-14 13:49:49 +00:00
// The range for stat:
// 2, 3, 5, 9, 16, 32, 64, 128, 256
// that is:
// a: <2
// b: <3
2020-04-14 13:49:49 +00:00
// c: <5
// d: <9
// e: <16
// f: <32
// g: <64
// h: <128
2020-04-14 13:49:49 +00:00
// i: <256
// j: >=256
if (nb_msgs < 2) {
p->a++;
} else if (nb_msgs < 3) {
2020-04-14 13:49:49 +00:00
p->b++;
} else if (nb_msgs < 5) {
p->c++;
} else if (nb_msgs < 9) {
2020-04-14 13:49:49 +00:00
p->d++;
} else if (nb_msgs < 16) {
2020-04-14 13:49:49 +00:00
p->e++;
} else if (nb_msgs < 32) {
2020-04-14 13:49:49 +00:00
p->f++;
} else if (nb_msgs < 64) {
2020-04-14 13:49:49 +00:00
p->g++;
} else if (nb_msgs < 128) {
2020-04-14 13:49:49 +00:00
p->h++;
} else if (nb_msgs < 256) {
p->i++;
} else {
2020-04-14 13:49:49 +00:00
p->j++;
}
2020-04-14 23:10:41 +00:00
p->nn += nb_msgs;
}
2020-04-14 13:49:49 +00:00
srs_error_t SrsStatistic::dumps_perf(SrsStatisticCategory* p, SrsJsonObject* obj)
{
srs_error_t err = srs_success;
2020-04-14 13:49:49 +00:00
// The range for stat:
// 2, 3, 5, 9, 16, 32, 64, 128, 256
// that is:
// a: <2
// b: <3
// c: <5
// d: <9
// e: <16
// f: <32
// g: <64
// h: <128
// i: <256
// j: >=256
if (p->a) obj->set("lt_2", SrsJsonAny::integer(p->a));
if (p->b) obj->set("lt_3", SrsJsonAny::integer(p->b));
if (p->c) obj->set("lt_5", SrsJsonAny::integer(p->c));
if (p->d) obj->set("lt_9", SrsJsonAny::integer(p->d));
if (p->e) obj->set("lt_16", SrsJsonAny::integer(p->e));
if (p->f) obj->set("lt_32", SrsJsonAny::integer(p->f));
if (p->g) obj->set("lt_64", SrsJsonAny::integer(p->g));
if (p->h) obj->set("lt_128", SrsJsonAny::integer(p->h));
if (p->i) obj->set("lt_256", SrsJsonAny::integer(p->i));
if (p->j) obj->set("gt_256", SrsJsonAny::integer(p->j));
2020-04-14 23:10:41 +00:00
obj->set("nn", SrsJsonAny::integer(p->nn));
return err;
}
2015-03-08 07:33:08 +00:00
SrsStatisticVhost* SrsStatistic::create_vhost(SrsRequest* req)
{
SrsStatisticVhost* vhost = NULL;
// create vhost if not exists.
2015-08-21 09:00:52 +00:00
if (rvhosts.find(req->vhost) == rvhosts.end()) {
2015-03-08 07:33:08 +00:00
vhost = new SrsStatisticVhost();
vhost->vhost = req->vhost;
2015-08-21 09:00:52 +00:00
rvhosts[req->vhost] = vhost;
vhosts[vhost->id] = vhost;
2015-03-08 07:33:08 +00:00
return vhost;
}
2017-03-25 09:21:39 +00:00
2015-08-21 09:00:52 +00:00
vhost = rvhosts[req->vhost];
2015-03-08 07:33:08 +00:00
return vhost;
}
SrsStatisticStream* SrsStatistic::create_stream(SrsStatisticVhost* vhost, SrsRequest* req)
{
std::string url = req->get_stream_url();
SrsStatisticStream* stream = NULL;
// create stream if not exists.
2015-08-21 09:00:52 +00:00
if (rstreams.find(url) == rstreams.end()) {
2015-03-08 07:33:08 +00:00
stream = new SrsStatisticStream();
stream->vhost = vhost;
stream->stream = req->stream;
2015-04-02 07:05:09 +00:00
stream->app = req->app;
2015-03-08 07:33:08 +00:00
stream->url = url;
2015-08-21 09:00:52 +00:00
rstreams[url] = stream;
streams[stream->id] = stream;
2015-03-08 07:33:08 +00:00
return stream;
}
2015-08-21 09:00:52 +00:00
stream = rstreams[url];
2015-03-08 07:33:08 +00:00
return stream;
}