From 7a927c5bae8b397c8975b1d6c6ab24c70645f077 Mon Sep 17 00:00:00 2001 From: Winlin Date: Thu, 28 Aug 2025 10:37:57 -0400 Subject: [PATCH] AI: Remove cloud CLS and APM. v7.0.66 (#4456) Co-authored-by: chundonglinlin Co-authored-by: OSSRS-AI --- trunk/auto/auto_headers.sh | 6 +- trunk/auto/options.sh | 16 +- trunk/conf/full.conf | 82 - trunk/configure | 4 +- trunk/doc/CHANGELOG.md | 1 + trunk/src/app/srs_app_config.cpp | 342 ---- trunk/src/app/srs_app_config.hpp | 21 +- trunk/src/app/srs_app_edge.cpp | 38 +- trunk/src/app/srs_app_edge.hpp | 10 +- trunk/src/app/srs_app_hybrid.cpp | 32 +- trunk/src/app/srs_app_latest_version.cpp | 10 +- trunk/src/app/srs_app_rtmp_conn.cpp | 55 +- trunk/src/app/srs_app_rtmp_conn.hpp | 6 +- trunk/src/app/srs_app_statistic.cpp | 2 +- trunk/src/app/srs_app_tencentcloud.cpp | 2317 ---------------------- trunk/src/app/srs_app_tencentcloud.hpp | 609 ------ trunk/src/core/srs_core_version7.hpp | 2 +- trunk/src/main/srs_main_server.cpp | 7 - trunk/src/utest/srs_utest_config.cpp | 72 - 19 files changed, 24 insertions(+), 3608 deletions(-) delete mode 100644 trunk/src/app/srs_app_tencentcloud.cpp delete mode 100644 trunk/src/app/srs_app_tencentcloud.hpp diff --git a/trunk/auto/auto_headers.sh b/trunk/auto/auto_headers.sh index 2494e555d..ab045f74f 100755 --- a/trunk/auto/auto_headers.sh +++ b/trunk/auto/auto_headers.sh @@ -115,11 +115,7 @@ else srs_undefine_macro "SRS_GB28181" $SRS_AUTO_HEADERS_H fi -if [[ $SRS_APM == YES ]]; then - srs_define_macro "SRS_APM" $SRS_AUTO_HEADERS_H -else - srs_undefine_macro "SRS_APM" $SRS_AUTO_HEADERS_H -fi + if [[ $SRS_UTEST == YES ]]; then srs_define_macro "SRS_UTEST" $SRS_AUTO_HEADERS_H diff --git a/trunk/auto/options.sh b/trunk/auto/options.sh index 34245e638..0bd95557c 100755 --- a/trunk/auto/options.sh +++ b/trunk/auto/options.sh @@ -64,6 +64,7 @@ SRS_SHARED_SRTP=RESERVED SRS_GCOV=NO # Whether enable cloud logging and APM(Application Performance Monitor). SRS_APM=NO + # whether enable the log verbose/info/trace level. # always enable the warn/error level. SRS_LOG_VERBOSE=NO @@ -185,7 +186,6 @@ Features: --gb28181=on|off Whether build the GB28181. Default: $(value2switch $SRS_GB28181) --ffmpeg-fit=on|off Whether enable the FFmpeg fit(source code). Default: $(value2switch $SRS_FFMPEG_FIT) --ffmpeg-opus=on|off Whether enable the FFmpeg native opus codec. Default: $(value2switch $SRS_FFMPEG_OPUS) - --apm=on|off Whether enable cloud logging and APM(Application Performance Monitor). Default: $(value2switch $SRS_APM) --prefix= The absolute installation path. Default: $SRS_PREFIX --jobs[=N] Allow N jobs at once; infinite jobs with no arg. Default: $SRS_JOBS @@ -265,6 +265,7 @@ Removed: --cygwin64 No support cygwin64 anymore. --cxx11=off Always disable C++11, force C++98 compatibility. Default: $(value2switch $SRS_CXX11) --cxx14=off Always disable C++14, force C++98 compatibility. Default: $(value2switch $SRS_CXX14) + --apm=off No support APM(Application Performance Monitor) anymore. For example: ./configure @@ -504,7 +505,6 @@ fi # Apply auto options ##################################################################################### function apply_auto_options() { - if [[ $SRS_CROSS_BUILD == YES ]]; then if [[ $SRS_CROSS_BUILD_PREFIX != "" && $SRS_CROSS_BUILD_HOST == "" ]]; then SRS_CROSS_BUILD_HOST=$(echo $SRS_CROSS_BUILD_PREFIX| sed 's/-$//g') @@ -580,8 +580,6 @@ function apply_auto_options() { SRS_SRTP_ASM=NO fi - - # Force single thread mode always - multi-threading support has been removed if [[ $SRS_SINGLE_THREAD != YES ]]; then echo "Warning: Multi-threading support has been removed. Forcing single thread mode." @@ -601,8 +599,9 @@ function apply_auto_options() { fi # parse the jobs for make - if [[ ! -z SRS_JOBS ]]; then + if [[ ! -z $SRS_JOBS ]]; then export SRS_JOBS="--jobs=${SRS_JOBS}" + echo "Export SRS_JOBS=$SRS_JOBS" fi # H.265/HEVC is always enabled, see https://github.com/ossrs/srs/issues/4349 @@ -610,6 +609,11 @@ function apply_auto_options() { echo "Warning: --h265 option is deprecated. H.265/HEVC support is always enabled." SRS_H265=ON fi + + if [[ $SRS_APM == YES ]]; then + echo "Warning: APM(Application Performance Monitor) is no longer supported." + SRS_APM=NO + fi } apply_auto_options @@ -693,7 +697,7 @@ function regenerate_options() { SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --log-trace=$(value2switch $SRS_LOG_TRACE)" SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --log-level_v2=$(value2switch $SRS_LOG_LEVEL_V2)" SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --gcov=$(value2switch $SRS_GCOV)" - SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --apm=$(value2switch $SRS_APM)" + SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --debug=$(value2switch $SRS_DEBUG)" SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --debug-stats=$(value2switch $SRS_DEBUG_STATS)" SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --debug-nack-drop=$(value2switch $SRS_DEBUG_NACK_DROP)" diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index d725c2fd3..e45d823e7 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -2159,88 +2159,6 @@ vhost cluster.srs.com { } } -############################################################################################# -# Tencent Cloud sections -############################################################################################# -# TencentCloud CLS(Cloud Log Service) config, logging to cloud. -# See https://cloud.tencent.com/document/product/614/11254 -tencentcloud_cls { - # Whether CLS is enabled. - # Overwrite by env SRS_TENCENTCLOUD_CLS_ENABLED - # default: off - enabled off; - # The logging label to category the cluster servers. - # Overwrite by env SRS_TENCENTCLOUD_CLS_LABEL - label cn-beijing; - # The logging tag to category the cluster servers. - # Overwrite by env SRS_TENCENTCLOUD_CLS_TAG - tag cn-edge; - # The SecretId to access CLS service, see https://console.cloud.tencent.com/cam/capi - # Overwrite by env SRS_TENCENTCLOUD_CLS_SECRET_ID - secret_id AKIDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; - # The SecretKey to access CLS service, see https://console.cloud.tencent.com/cam/capi - # Overwrite by env SRS_TENCENTCLOUD_CLS_SECRET_KEY - secret_key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; - # The endpoint of CLS, format as .cls.tencentcs.com. For example: - # ap-guangzhou.cls.tencentcs.com - # Note that tencentyun.com is for internal network, while tencentcs.com is for public internet. - # See https://cloud.tencent.com/document/product/614/18940 - # Overwrite by env SRS_TENCENTCLOUD_CLS_ENDPOINT - endpoint ap-guangzhou.cls.tencentcs.com; - # The topic ID of CLS, see https://cloud.tencent.com/document/product/614/41035 - # Overwrite by env SRS_TENCENTCLOUD_CLS_TOPIC_ID - topic_id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx; - # Whether enable logging for each log sending. - # Overwrite by env SRS_TENCENTCLOUD_CLS_DEBUG_LOGGING - # Default: off - debug_logging off; - # Whether enable the heartbeat stat every (5 * heartbeat_ratio)s. - # Overwrite by env SRS_TENCENTCLOUD_CLS_STAT_HEARTBEAT - # Default: on - stat_heartbeat on; - # Setup the heartbeat interval ratio, 1 means 5s, 2 means 10s, etc. - # Overwrite by env SRS_TENCENTCLOUD_CLS_HEARTBEAT_RATIO - # Default: 1 - heartbeat_ratio 1; - # Whether enable the streams stat every (5 * streams_ratio)s. - # Overwrite by env SRS_TENCENTCLOUD_CLS_STAT_STREAMS - # Default: on - stat_streams on; - # Setup the streams interval ratio, 1 means 5s, 2 means 10s, etc. - # Overwrite by env SRS_TENCENTCLOUD_CLS_STREAMS_RATIO - # Default: 1 - streams_ratio 1; -} - -# TencentCloud APM(Application Performance Management) config. -# See https://cloud.tencent.com/document/product/1463/57462 -tencentcloud_apm { - # Whether APM is enabled. - # Overwrite by env SRS_TENCENTCLOUD_APM_ENABLED - # default: off - enabled on; - # The APM team or business system ID, to which spans belongs to. For example, the team is apm-FsOsPOIMl (just an - # example, not available), please get your team from https://console.cloud.tencent.com/apm/monitor/team - # Overwrite by env SRS_TENCENTCLOUD_APM_TEAM - team apm-xxxxxxxxx; - # The APM token for authentication. For example, the token is xzddEaegsxGadEpGEDFx (just an example, not available), - # please get your token from https://console.cloud.tencent.com/apm/monitor/access - # Overwrite by env SRS_TENCENTCLOUD_APM_TOKEN - token xxxxxxxx; - # The APM endpoint. See https://github.com/open-telemetry/opentelemetry-go/tree/main/exporters/otlp/otlptrace - # Please note that 4317 is for GRPC/HTTP2, while SRS only support HTTP and the port shoule be 55681. - # Overwrite by env SRS_TENCENTCLOUD_APM_ENDPOINT - endpoint ap-guangzhou.apm.tencentcs.com:55681; - # The service.name of resource. - # Overwrite by env SRS_TENCENTCLOUD_APM_SERVICE_NAME - # Default: srs-server - service_name srs-server; - # Whether enable logging for each log sending. - # Overwrite by env SRS_TENCENTCLOUD_APM_DEBUG_LOGGING - # Default: off - debug_logging off; -} - ############################################################################################# # heartbeat/stats sections ############################################################################################# diff --git a/trunk/configure b/trunk/configure index d0231b2fb..874fc4145 100755 --- a/trunk/configure +++ b/trunk/configure @@ -329,9 +329,7 @@ MODULE_FILES+=("srs_app_rtc_conn" "srs_app_rtc_dtls" "srs_app_rtc_sdp" "srs_app_ if [[ $SRS_RTSP == YES ]]; then MODULE_FILES+=("srs_app_rtsp_source" "srs_app_rtsp_conn") fi -if [[ $SRS_APM == YES ]]; then - MODULE_FILES+=("srs_app_tencentcloud") -fi + if [[ $SRS_FFMPEG_FIT == YES ]]; then MODULE_FILES+=("srs_app_rtc_codec") fi diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index 6db811e9f..5d919bf42 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -7,6 +7,7 @@ The changelog for SRS. ## SRS 7.0 Changelog +* v7.0, 2025-08-28, Merge [#4456](https://github.com/ossrs/srs/pull/4456): AI: Remove cloud CLS and APM. v7.0.66 (#4456) * v7.0, 2025-08-27, Merge [#4455](https://github.com/ossrs/srs/pull/4455): Gather utility functions to kernel or protocol. v7.0.65 (#4455) * v7.0, 2025-08-27, Merge [#4454](https://github.com/ossrs/srs/pull/4454): AI: Config: Move RTMP configs to rtmp{} section. v7.0.64 (#4454) * v7.0, 2025-08-26, Merge [#4451](https://github.com/ossrs/srs/pull/4451): RTC: Fix null pointer crash in RTC2RTMP when start packet is missing. v7.0.63 (#4451) diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 3981decc9..67750cd90 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -3437,348 +3437,6 @@ int SrsConfig::get_dying_pulse() return ::atoi(conf->arg0().c_str()); } -bool SrsConfig::get_tencentcloud_cls_enabled() -{ - SRS_OVERWRITE_BY_ENV_BOOL("srs.tencentcloud_cls.enabled"); // SRS_TENCENTCLOUD_CLS_ENABLED - - static bool DEFAULT = false; - - SrsConfDirective *conf = root->get("tencentcloud_cls"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("enabled"); - if (!conf) { - return DEFAULT; - } - - return SRS_CONF_PREFER_FALSE(conf->arg0()); -} - -bool SrsConfig::get_tencentcloud_cls_stat_heartbeat() -{ - SRS_OVERWRITE_BY_ENV_BOOL2("srs.tencentcloud_cls.stat_heartbeat"); // SRS_TENCENTCLOUD_CLS_STAT_HEARTBEAT - - static bool DEFAULT = true; - - SrsConfDirective *conf = root->get("tencentcloud_cls"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("stat_heartbeat"); - if (!conf) { - return DEFAULT; - } - - return SRS_CONF_PREFER_TRUE(conf->arg0()); -} - -bool SrsConfig::get_tencentcloud_cls_stat_streams() -{ - SRS_OVERWRITE_BY_ENV_BOOL2("srs.tencentcloud_cls.stat_streams"); // SRS_TENCENTCLOUD_CLS_STAT_STREAMS - - static bool DEFAULT = true; - - SrsConfDirective *conf = root->get("tencentcloud_cls"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("stat_streams"); - if (!conf) { - return DEFAULT; - } - - return SRS_CONF_PREFER_TRUE(conf->arg0()); -} - -bool SrsConfig::get_tencentcloud_cls_debug_logging() -{ - SRS_OVERWRITE_BY_ENV_BOOL("srs.tencentcloud_cls.debug_logging"); // SRS_TENCENTCLOUD_CLS_DEBUG_LOGGING - - static bool DEFAULT = false; - - SrsConfDirective *conf = root->get("tencentcloud_cls"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("debug_logging"); - if (!conf) { - return DEFAULT; - } - - return SRS_CONF_PREFER_FALSE(conf->arg0()); -} - -int SrsConfig::get_tencentcloud_cls_heartbeat_ratio() -{ - SRS_OVERWRITE_BY_ENV_INT("srs.tencentcloud_cls.heartbeat_ratio"); // SRS_TENCENTCLOUD_CLS_HEARTBEAT_RATIO - - static int DEFAULT = 1; - - SrsConfDirective *conf = root->get("tencentcloud_cls"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("heartbeat_ratio"); - if (!conf) { - return DEFAULT; - } - - return ::atoi(conf->arg0().c_str()); -} - -int SrsConfig::get_tencentcloud_cls_streams_ratio() -{ - SRS_OVERWRITE_BY_ENV_INT("srs.tencentcloud_cls.streams_ratio"); // SRS_TENCENTCLOUD_CLS_STREAMS_RATIO - - static int DEFAULT = 1; - - SrsConfDirective *conf = root->get("tencentcloud_cls"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("streams_ratio"); - if (!conf) { - return DEFAULT; - } - - return ::atoi(conf->arg0().c_str()); -} - -string SrsConfig::get_tencentcloud_cls_label() -{ - SRS_OVERWRITE_BY_ENV_STRING("srs.tencentcloud_cls.label"); // SRS_TENCENTCLOUD_CLS_LABEL - - static string DEFAULT = ""; - - SrsConfDirective *conf = root->get("tencentcloud_cls"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("label"); - if (!conf) { - return DEFAULT; - } - - return conf->arg0(); -} - -string SrsConfig::get_tencentcloud_cls_tag() -{ - SRS_OVERWRITE_BY_ENV_STRING("srs.tencentcloud_cls.tag"); // SRS_TENCENTCLOUD_CLS_TAG - - static string DEFAULT = ""; - - SrsConfDirective *conf = root->get("tencentcloud_cls"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("tag"); - if (!conf) { - return DEFAULT; - } - - return conf->arg0(); -} - -string SrsConfig::get_tencentcloud_cls_secret_id() -{ - SRS_OVERWRITE_BY_ENV_STRING("srs.tencentcloud_cls.secret_id"); // SRS_TENCENTCLOUD_CLS_SECRET_ID - - static string DEFAULT = ""; - - SrsConfDirective *conf = root->get("tencentcloud_cls"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("secret_id"); - if (!conf) { - return DEFAULT; - } - - return conf->arg0(); -} - -string SrsConfig::get_tencentcloud_cls_secret_key() -{ - SRS_OVERWRITE_BY_ENV_STRING("srs.tencentcloud_cls.secret_key"); // SRS_TENCENTCLOUD_CLS_SECRET_KEY - - static string DEFAULT = ""; - - SrsConfDirective *conf = root->get("tencentcloud_cls"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("secret_key"); - if (!conf) { - return DEFAULT; - } - - return conf->arg0(); -} - -string SrsConfig::get_tencentcloud_cls_endpoint() -{ - SRS_OVERWRITE_BY_ENV_STRING("srs.tencentcloud_cls.endpoint"); // SRS_TENCENTCLOUD_CLS_ENDPOINT - - static string DEFAULT = ""; - - SrsConfDirective *conf = root->get("tencentcloud_cls"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("endpoint"); - if (!conf) { - return DEFAULT; - } - - return conf->arg0(); -} - -string SrsConfig::get_tencentcloud_cls_topic_id() -{ - SRS_OVERWRITE_BY_ENV_STRING("srs.tencentcloud_cls.topic_id"); // SRS_TENCENTCLOUD_CLS_TOPIC_ID - - static string DEFAULT = ""; - - SrsConfDirective *conf = root->get("tencentcloud_cls"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("topic_id"); - if (!conf) { - return DEFAULT; - } - - return conf->arg0(); -} - -bool SrsConfig::get_tencentcloud_apm_enabled() -{ - SRS_OVERWRITE_BY_ENV_BOOL("srs.tencentcloud_apm.enabled"); // SRS_TENCENTCLOUD_APM_ENABLED - - static bool DEFAULT = false; - - SrsConfDirective *conf = root->get("tencentcloud_apm"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("enabled"); - if (!conf) { - return DEFAULT; - } - - return SRS_CONF_PREFER_FALSE(conf->arg0()); -} - -string SrsConfig::get_tencentcloud_apm_team() -{ - SRS_OVERWRITE_BY_ENV_STRING("srs.tencentcloud_apm.team"); // SRS_TENCENTCLOUD_APM_TEAM - - static string DEFAULT = ""; - - SrsConfDirective *conf = root->get("tencentcloud_apm"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("team"); - if (!conf) { - return DEFAULT; - } - - return conf->arg0(); -} - -string SrsConfig::get_tencentcloud_apm_token() -{ - SRS_OVERWRITE_BY_ENV_STRING("srs.tencentcloud_apm.token"); // SRS_TENCENTCLOUD_APM_TOKEN - - static string DEFAULT = ""; - - SrsConfDirective *conf = root->get("tencentcloud_apm"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("token"); - if (!conf) { - return DEFAULT; - } - - return conf->arg0(); -} - -string SrsConfig::get_tencentcloud_apm_endpoint() -{ - SRS_OVERWRITE_BY_ENV_STRING("srs.tencentcloud_apm.endpoint"); // SRS_TENCENTCLOUD_APM_ENDPOINT - - static string DEFAULT = ""; - - SrsConfDirective *conf = root->get("tencentcloud_apm"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("endpoint"); - if (!conf) { - return DEFAULT; - } - - return conf->arg0(); -} - -string SrsConfig::get_tencentcloud_apm_service_name() -{ - SRS_OVERWRITE_BY_ENV_STRING("srs.tencentcloud_apm.service_name"); // SRS_TENCENTCLOUD_APM_SERVICE_NAME - - static string DEFAULT = "srs-server"; - - SrsConfDirective *conf = root->get("tencentcloud_apm"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("service_name"); - if (!conf) { - return DEFAULT; - } - - return conf->arg0(); -} - -bool SrsConfig::get_tencentcloud_apm_debug_logging() -{ - SRS_OVERWRITE_BY_ENV_BOOL("srs.tencentcloud_apm.debug_logging"); // SRS_TENCENTCLOUD_APM_DEBUG_LOGGING - - static bool DEFAULT = false; - - SrsConfDirective *conf = root->get("tencentcloud_apm"); - if (!conf) { - return DEFAULT; - } - - conf = conf->get("debug_logging"); - if (!conf) { - return DEFAULT; - } - - return SRS_CONF_PREFER_FALSE(conf->arg0()); -} - bool SrsConfig::get_exporter_enabled() { SRS_OVERWRITE_BY_ENV_BOOL("srs.exporter.enabled"); // SRS_EXPORTER_ENABLED diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index 659d677a3..5c8a0c4a1 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -486,26 +486,7 @@ public: virtual int get_critical_pulse(); virtual int get_dying_threshold(); virtual int get_dying_pulse(); - // TencentCloud service section. -public: - virtual bool get_tencentcloud_cls_enabled(); - virtual bool get_tencentcloud_cls_stat_heartbeat(); - virtual bool get_tencentcloud_cls_stat_streams(); - virtual bool get_tencentcloud_cls_debug_logging(); - virtual int get_tencentcloud_cls_heartbeat_ratio(); - virtual int get_tencentcloud_cls_streams_ratio(); - virtual std::string get_tencentcloud_cls_label(); - virtual std::string get_tencentcloud_cls_tag(); - virtual std::string get_tencentcloud_cls_secret_id(); - virtual std::string get_tencentcloud_cls_secret_key(); - virtual std::string get_tencentcloud_cls_endpoint(); - virtual std::string get_tencentcloud_cls_topic_id(); - virtual bool get_tencentcloud_apm_enabled(); - virtual std::string get_tencentcloud_apm_team(); - virtual std::string get_tencentcloud_apm_token(); - virtual std::string get_tencentcloud_apm_endpoint(); - virtual std::string get_tencentcloud_apm_service_name(); - virtual bool get_tencentcloud_apm_debug_logging(); + // stream_caster section public: // Get all stream_caster in config file. diff --git a/trunk/src/app/srs_app_edge.cpp b/trunk/src/app/srs_app_edge.cpp index f910621b1..e7ece8ece 100644 --- a/trunk/src/app/srs_app_edge.cpp +++ b/trunk/src/app/srs_app_edge.cpp @@ -20,7 +20,7 @@ using namespace std; #include #include #include -#include + #include #include #include @@ -109,11 +109,6 @@ srs_error_t SrsEdgeRtmpUpstream::connect(ISrsRequest *r, SrsLbRoundRobin *lb) srs_utime_t sto = SRS_CONSTS_RTMP_PULSE; sdk = new SrsSimpleRtmpClient(url, cto, sto); -#ifdef SRS_APM - // Create a client span and store it to an AMF0 propagator. - SrsUniquePtr span_client(_srs_apm->inject(_srs_apm->span("edge-pull")->set_kind(SrsApmKindClient)->as_child(_srs_apm->load()), sdk->extra_args())); -#endif - if ((err = sdk->connect()) != srs_success) { return srs_error_wrap(err, "edge pull %s failed, cto=%dms, sto=%dms.", url.c_str(), srsu2msi(cto), srsu2msi(sto)); } @@ -431,13 +426,6 @@ srs_error_t SrsEdgeIngester::initialize(SrsSharedPtr s, SrsPlayEd edge = e; req = r; -#ifdef SRS_APM - // We create a dedicate span for edge ingester, and all players will link to this one. - // Note that we use a producer span and end it immediately. - srs_assert(!span_main_); - span_main_ = _srs_apm->span("edge")->set_kind(SrsApmKindProducer)->end(); -#endif - return srs_success; } @@ -490,13 +478,6 @@ srs_error_t SrsEdgeIngester::cycle() { srs_error_t err = srs_success; -#ifdef SRS_APM - // Save span from parent coroutine to current coroutine context, so that we can load if in this coroutine, for - // example to use it in SrsEdgeRtmpUpstream which use RTMP or FLV client to connect to upstream server. - _srs_apm->store(span_main_); - srs_assert(span_main_); -#endif - while (true) { // We always check status first. // @see https://github.com/ossrs/srs/issues/1634#issuecomment-597571561 @@ -807,12 +788,6 @@ srs_error_t SrsEdgeForwarder::start() srs_utime_t sto = SRS_CONSTS_RTMP_TIMEOUT; sdk = new SrsSimpleRtmpClient(url, cto, sto); -#ifdef SRS_APM - // Create a client span and store it to an AMF0 propagator. - // Note that we are able to load the span from coroutine context because in the same coroutine. - SrsUniquePtr span_client(_srs_apm->inject(_srs_apm->span("edge-push")->set_kind(SrsApmKindClient)->as_child(_srs_apm->load()), sdk->extra_args())); -#endif - if ((err = sdk->connect()) != srs_success) { return srs_error_wrap(err, "sdk connect %s failed, cto=%dms, sto=%dms.", url.c_str(), srsu2msi(cto), srsu2msi(sto)); } @@ -1006,17 +981,6 @@ srs_error_t SrsPlayEdge::on_client_play() return srs_error_new(ERROR_RTMP_EDGE_PLAY_STATE, "state is stopping"); } -#ifdef SRS_APM - // APM bind client span to edge span, which fetch stream from upstream server. - // We create a new span to link the two span, because these two spans might be ended. - if (ingester->span() && _srs_apm->load()) { - ISrsApmSpan *from = _srs_apm->span("play-link")->as_child(_srs_apm->load()); - ISrsApmSpan *to = _srs_apm->span("edge-link")->as_child(ingester->span())->link(from); - srs_freep(from); - srs_freep(to); - } -#endif - return err; } diff --git a/trunk/src/app/srs_app_edge.hpp b/trunk/src/app/srs_app_edge.hpp index 2f733f4b6..e823aa654 100644 --- a/trunk/src/app/srs_app_edge.hpp +++ b/trunk/src/app/srs_app_edge.hpp @@ -33,7 +33,6 @@ class SrsHttpClient; class ISrsHttpMessage; class SrsHttpFileReader; class SrsFlvDecoder; -class ISrsApmSpan; // The state of edge, auto machine enum SrsEdgeState { @@ -158,9 +157,7 @@ private: SrsCoroutine *trd; SrsLbRoundRobin *lb; SrsEdgeUpstream *upstream; -#ifdef SRS_APM - ISrsApmSpan *span_main_; -#endif + public: SrsEdgeIngester(); virtual ~SrsEdgeIngester(); @@ -170,10 +167,7 @@ public: virtual srs_error_t start(); virtual void stop(); virtual std::string get_curr_origin(); -#ifdef SRS_APM - // Get the current main span. Note that it might be NULL. - ISrsApmSpan *span(); -#endif + // Interface ISrsReusableThread2Handler public: virtual srs_error_t cycle(); diff --git a/trunk/src/app/srs_app_hybrid.cpp b/trunk/src/app/srs_app_hybrid.cpp index 5820abbb7..04f281e73 100644 --- a/trunk/src/app/srs_app_hybrid.cpp +++ b/trunk/src/app/srs_app_hybrid.cpp @@ -21,7 +21,7 @@ #include #include #include -#include + #include #include #include @@ -347,16 +347,6 @@ srs_error_t SrsHybridServer::initialize() return srs_error_wrap(err, "dvr async"); } -#ifdef SRS_APM - // Initialize TencentCloud CLS object. - if ((err = _srs_cls->initialize()) != srs_success) { - return srs_error_wrap(err, "cls client"); - } - if ((err = _srs_apm->initialize()) != srs_success) { - return srs_error_wrap(err, "apm client"); - } -#endif - // Register some timers. timer20ms_->subscribe(clock_monitor_); timer5s_->subscribe(this); @@ -585,20 +575,6 @@ srs_error_t SrsHybridServer::on_timer(srs_utime_t interval) epoll_desc.c_str(), sched_desc.c_str(), clock_desc.c_str(), thread_desc.c_str(), free_desc.c_str(), objs_desc.c_str()); -#ifdef SRS_APM - // Report logs to CLS if enabled. - if ((err = _srs_cls->report()) != srs_success) { - srs_warn("ignore cls err %s", srs_error_desc(err).c_str()); - srs_freep(err); - } - - // Report logs to APM if enabled. - if ((err = _srs_apm->report()) != srs_success) { - srs_warn("ignore apm err %s", srs_error_desc(err).c_str()); - srs_freep(err); - } -#endif - return err; } @@ -811,12 +787,6 @@ srs_error_t srs_global_initialize() // Create global async worker for DVR. _srs_dvr_async = new SrsAsyncCallWorker(); -#ifdef SRS_APM - // Initialize global TencentCloud CLS object. - _srs_cls = new SrsClsClient(); - _srs_apm = new SrsApmClient(); -#endif - _srs_reload_err = srs_success; _srs_reload_state = SrsReloadStateInit; _srs_reload_id = srs_rand_gen_str(7); diff --git a/trunk/src/app/srs_app_latest_version.cpp b/trunk/src/app/srs_app_latest_version.cpp index 372954109..9ae885f65 100644 --- a/trunk/src/app/srs_app_latest_version.cpp +++ b/trunk/src/app/srs_app_latest_version.cpp @@ -10,7 +10,7 @@ #include #include #include -#include + #include #include #include @@ -172,14 +172,6 @@ void srs_build_features(stringstream &ss) SRS_CHECK_FEATURE(transcode, ss); SRS_CHECK_FEATURE(security, ss); SRS_CHECK_FEATURE2(_srs_config_by_env, "env", ss); - -#ifdef SRS_APM - SRS_CHECK_FEATURE2(_srs_cls->enabled(), "cls", ss); - SRS_CHECK_FEATURE3(_srs_cls->nn_logs(), "logs", _srs_cls->nn_logs(), ss); - - SRS_CHECK_FEATURE2(_srs_apm->enabled(), "apm", ss); - SRS_CHECK_FEATURE3(_srs_apm->nn_spans(), "spans", _srs_apm->nn_spans(), ss); -#endif } SrsLatestVersion::SrsLatestVersion() diff --git a/trunk/src/app/srs_app_rtmp_conn.cpp b/trunk/src/app/srs_app_rtmp_conn.cpp index a69647728..91725f3fa 100644 --- a/trunk/src/app/srs_app_rtmp_conn.cpp +++ b/trunk/src/app/srs_app_rtmp_conn.cpp @@ -29,7 +29,7 @@ using namespace std; #include #include #include -#include + #include #include #include @@ -188,11 +188,7 @@ SrsRtmpConn::SrsRtmpConn(SrsServer *svr, SrsRtmpTransport *transport, string cip ip = cip; port = cport; create_time = srsu2ms(srs_time_now_cached()); -#ifdef SRS_APM - span_main_ = _srs_apm->dummy(); - span_connect_ = _srs_apm->dummy(); - span_client_ = _srs_apm->dummy(); -#endif + trd = new SrsSTCoroutine("rtmp", this, _srs_context->get_id()); kbps = new SrsNetworkKbps(); @@ -260,14 +256,6 @@ srs_error_t SrsRtmpConn::do_cycle() { srs_error_t err = srs_success; -#ifdef SRS_APM - // We should keep the root span to alive util connection closed. - // Note that we use producer and consumer span because RTMP connection is long polling connection. - // Note that we also store this span in coroutine context, so that edge could load it. - srs_freep(span_main_); - span_main_ = _srs_apm->span("rtmp")->set_kind(SrsApmKindServer)->attr("cip", ip)->attr("cid", _srs_context->get_id().c_str()); -#endif - #ifdef SRS_APM srs_trace("RTMP client transport=%s, ip=%s:%d, fd=%d, trace=%s, span=%s", transport_->transport_type(), ip.c_str(), port, srs_netfd_fileno(transport_->fd()), span_main_->format_trace_id(), span_main_->format_span_id()); @@ -292,15 +280,6 @@ srs_error_t SrsRtmpConn::do_cycle() srs_trace("RTMP proxy real client ip=%s", rips.c_str()); } -#ifdef SRS_APM - // Update the real IP of client, also set the HTTP fields. - span_main_->attr("rip", rip ? rips : ip)->attr("http.client_ip", rip ? rips : ip); - - // The span for RTMP connecting to application. - srs_freep(span_connect_); - span_connect_ = _srs_apm->span("connect")->as_child(span_main_); -#endif - ISrsRequest *req = info->req; if ((err = rtmp->connect_app(req)) != srs_success) { return srs_error_wrap(err, "rtmp connect tcUrl"); @@ -339,12 +318,6 @@ srs_error_t SrsRtmpConn::do_cycle() srs_trace("edge-srs ip=%s, version=%s, pid=%d, id=%d", srs_server_ip.c_str(), srs_version.c_str(), srs_pid, srs_id); } - -#ifdef SRS_APM - // Load the span from the AMF0 object propagator. - // Note that we will update the trace id, so please make sure no spans are ended before this. - _srs_apm->extract(span_main_, req->args); -#endif } if ((err = service_cycle()) != srs_success) { @@ -598,22 +571,11 @@ srs_error_t SrsRtmpConn::stream_service_cycle() srs_trace("client identified, type=%s, vhost=%s, app=%s, stream=%s, param=%s, duration=%dms", srs_client_type_string(info->type).c_str(), req->vhost.c_str(), req->app.c_str(), req->stream.c_str(), req->param.c_str(), srsu2msi(req->duration)); -#ifdef SRS_APM - // Start APM only when client is identified, because it might republish. - srs_freep(span_client_); - span_client_ = _srs_apm->span("client")->as_child(span_connect_)->attr("type", srs_client_type_string(info->type))->attr("url", req->get_stream_url())->attr("http.url", req->get_stream_url()); - // We store the span to coroutine context, for edge to load it. - _srs_apm->store(span_client_); -#endif - // discovery vhost, resolve the vhost from config SrsConfDirective *parsed_vhost = _srs_config->get_vhost(req->vhost); if (parsed_vhost) { req->vhost = parsed_vhost->arg0(); } -#ifdef SRS_APM - span_client_->attr("vhost", req->vhost)->attr("http.host", req->host)->attr("http.server_name", req->vhost)->attr("http.target", srs_fmt_sprintf("/%s/%s", req->app.c_str(), req->stream.c_str())); -#endif if (req->schema.empty() || req->vhost.empty() || req->port == 0 || req->app.empty()) { return srs_error_new(ERROR_RTMP_REQ_TCURL, "discovery tcUrl failed, tcUrl=%s, schema=%s, vhost=%s, port=%d, app=%s", @@ -912,10 +874,6 @@ srs_error_t SrsRtmpConn::do_playing(SrsSharedPtr source, SrsLiveC srs_trace("start play smi=%dms, mw_sleep=%d, mw_msgs=%d, realtime=%d, tcp_nodelay=%d", srsu2msi(send_min_interval), srsu2msi(mw_sleep), mw_msgs, realtime, tcp_nodelay); -#ifdef SRS_APM - SrsUniquePtr span(_srs_apm->span("play-cycle")->set_kind(SrsApmKindProducer)->as_child(span_client_)->attr("realtime", srs_fmt_sprintf("%d", realtime))->end()); -#endif - while (true) { // when source is set to expired, disconnect it. if ((err = trd->pull()) != srs_success) { @@ -1711,15 +1669,6 @@ srs_error_t SrsRtmpConn::cycle() // Serve the client. err = do_cycle(); -#ifdef SRS_APM - // Final APM span, parent is the last span, not the root span. Note that only client or server kind will be filtered - // for error or exception report. - SrsUniquePtr span_final(_srs_apm->span("final")->set_kind(SrsApmKindServer)->as_child(span_client_)); - if (srs_error_code(err) != 0) { - span_final->record_error(err)->set_status(SrsApmStatusError, srs_fmt_sprintf("fail code=%d", srs_error_code(err))); - } -#endif - // Update statistic when done. SrsStatistic *stat = SrsStatistic::instance(); stat->kbps_add_delta(get_id().c_str(), delta_); diff --git a/trunk/src/app/srs_app_rtmp_conn.hpp b/trunk/src/app/srs_app_rtmp_conn.hpp index 70822e5f1..9ed3d7574 100644 --- a/trunk/src/app/srs_app_rtmp_conn.hpp +++ b/trunk/src/app/srs_app_rtmp_conn.hpp @@ -39,7 +39,7 @@ class ISrsWakable; class SrsCommonMessage; class SrsPacket; class SrsNetworkDelta; -class ISrsApmSpan; + class SrsSslConnection; // The simple rtmp client for SRS. @@ -169,10 +169,6 @@ private: // The create time in milliseconds. // for current connection to log self create time and calculate the living time. int64_t create_time; - // The span for tracing connection establishment. - ISrsApmSpan *span_main_; - ISrsApmSpan *span_connect_; - ISrsApmSpan *span_client_; public: SrsRtmpConn(SrsServer *svr, SrsRtmpTransport *transport, std::string cip, int port); diff --git a/trunk/src/app/srs_app_statistic.cpp b/trunk/src/app/srs_app_statistic.cpp index 65096f211..b447bb44b 100644 --- a/trunk/src/app/srs_app_statistic.cpp +++ b/trunk/src/app/srs_app_statistic.cpp @@ -12,7 +12,7 @@ using namespace std; #include #include -#include + #include #include #include diff --git a/trunk/src/app/srs_app_tencentcloud.cpp b/trunk/src/app/srs_app_tencentcloud.cpp deleted file mode 100644 index fc5a4ca5c..000000000 --- a/trunk/src/app/srs_app_tencentcloud.cpp +++ /dev/null @@ -1,2317 +0,0 @@ -// -// Copyright (c) 2013-2025 The SRS Authors -// -// SPDX-License-Identifier: MIT -// - -#include -#ifdef SRS_APM - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - -// See https://cloud.tencent.com/document/product/614/12445 -namespace tencentcloud_api_sign -{ -std::string sha1(const void *data, size_t len) -{ - unsigned char digest[SHA_DIGEST_LENGTH]; - SHA_CTX ctx; - SHA1_Init(&ctx); - SHA1_Update(&ctx, data, len); - SHA1_Final(digest, &ctx); - char c_sha1[SHA_DIGEST_LENGTH * 2 + 1]; - for (unsigned i = 0; i < SHA_DIGEST_LENGTH; ++i) { - snprintf(&c_sha1[i * 2], 3, "%02x", (unsigned int)digest[i]); - } - return c_sha1; -} - -std::string hmac_sha1(const char *key, const void *data, size_t len) -{ - unsigned char digest[EVP_MAX_MD_SIZE]; - unsigned digest_len; - char c_hmacsha1[EVP_MAX_MD_SIZE * 2 + 1]; -#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L - HMAC_CTX ctx; - HMAC_CTX_init(&ctx); - HMAC_Init_ex(&ctx, key, strlen(key), EVP_sha1(), NULL); - HMAC_Update(&ctx, (unsigned char *)data, len); - HMAC_Final(&ctx, digest, &digest_len); - HMAC_CTX_cleanup(&ctx); -#else - HMAC_CTX *ctx = HMAC_CTX_new(); - HMAC_CTX_reset(ctx); - HMAC_Init_ex(ctx, key, strlen(key), EVP_sha1(), NULL); - HMAC_Update(ctx, (unsigned char *)data, len); - HMAC_Final(ctx, digest, &digest_len); - HMAC_CTX_free(ctx); -#endif - for (unsigned i = 0; i != digest_len; ++i) { - snprintf(&c_hmacsha1[i * 2], 3, "%02x", (unsigned int)digest[i]); - } - return c_hmacsha1; -} - -std::string urlencode(const char *s) -{ - static unsigned char hexchars[] = "0123456789ABCDEF"; - size_t length = strlen(s), pos = 0; - unsigned char c_url[length * 3 + 1]; - const unsigned char *p = (const unsigned char *)s; - for (; *p; ++p) { - if (isalnum((unsigned char)*p) || (*p == '-') || - (*p == '_') || (*p == '.') || (*p == '~')) { - c_url[pos++] = *p; - } else { - c_url[pos++] = '%'; - c_url[pos++] = hexchars[(*p) >> 4]; - c_url[pos++] = hexchars[(*p) & 15U]; - } - } - c_url[pos] = 0; - return (char *)c_url; -} - -std::string signature(const std::string &secret_id, - const std::string &secret_key, - std::string method, - const std::string &path, - const std::map ¶ms, - const std::map &headers, - long expire) -{ - - const size_t SIGNLEN = 1024; - std::string http_request_info, uri_parm_list, - header_list, str_to_sign, sign_key; - transform(method.begin(), method.end(), method.begin(), ::tolower); - http_request_info.reserve(SIGNLEN); - http_request_info.append(method).append("\n").append(path).append("\n"); - uri_parm_list.reserve(SIGNLEN); - std::map::const_iterator iter; - for (iter = params.begin(); - iter != params.end();) { - uri_parm_list.append(iter->first); - http_request_info.append(iter->first).append("=").append(urlencode(iter->second.c_str())); - if (++iter != params.end()) { - uri_parm_list.append(";"); - http_request_info.append("&"); - } - } - http_request_info.append("\n"); - header_list.reserve(SIGNLEN); - for (iter = headers.begin(); - iter != headers.end(); ++iter) { - sign_key = iter->first; - transform(sign_key.begin(), sign_key.end(), sign_key.begin(), ::tolower); - if (sign_key == "content-type" || sign_key == "content-md5" || sign_key == "host" || sign_key[0] == 'x') { - header_list.append(sign_key); - http_request_info.append(sign_key).append("=").append(urlencode(iter->second.c_str())); - header_list.append(";"); - http_request_info.append("&"); - } - } - if (!header_list.empty()) { - header_list[header_list.size() - 1] = 0; - http_request_info[http_request_info.size() - 1] = '\n'; - } - // printf("%s\nEOF\n", http_request_info.c_str()); - char signed_time[SIGNLEN] = {0}; - int signed_time_len = snprintf(signed_time, SIGNLEN, - "%lu;%lu", time(0) - 60, time(0) + expire); - // snprintf(signed_time, SIGNLEN, "1510109254;1510109314"); - std::string signkey = hmac_sha1(secret_key.c_str(), - signed_time, signed_time_len); - str_to_sign.reserve(SIGNLEN); - str_to_sign.append("sha1").append("\n").append(signed_time).append("\n").append(sha1(http_request_info.c_str(), http_request_info.size())).append("\n"); - // printf("%s\nEOF\n", str_to_sign.c_str()); - std::stringstream c_signature; - c_signature << "q-sign-algorithm=sha1&q-ak=" << secret_id.c_str() - << "&q-sign-time=" << signed_time - << "&q-key-time=" << signed_time - << "&q-header-list=" << header_list.c_str() - << "&q-url-param-list=" << uri_parm_list.c_str() - << "&q-signature=" << hmac_sha1(signkey.c_str(), str_to_sign.c_str(), str_to_sign.size()).c_str(); - return c_signature.str(); -} -} // namespace tencentcloud_api_sign - -// See https://cloud.tencent.com/document/api/614/16873 -class SrsClsLogContent : public ISrsEncoder -{ -private: - // required string key = 1; - std::string key_; - // required string value = 2; - std::string value_; - -public: - SrsClsLogContent(); - virtual ~SrsClsLogContent(); - -public: - SrsClsLogContent *set_key(std::string v); - SrsClsLogContent *set_value(std::string v); - -public: - virtual uint64_t nb_bytes(); - srs_error_t encode(SrsBuffer *b); -}; - -// See https://cloud.tencent.com/document/api/614/16873 -class SrsClsLog : public ISrsEncoder -{ -private: - // required int64 time = 1; - int64_t time_; - // repeated Content contents= 2; - std::vector contents_; - -public: - SrsClsLog(); - virtual ~SrsClsLog(); - -public: - SrsClsLogContent *add_content(); - SrsClsLog *set_time(int64_t v); - -public: - virtual uint64_t nb_bytes(); - srs_error_t encode(SrsBuffer *b); -}; - -// See https://cloud.tencent.com/document/api/614/16873 -class SrsClsLogGroup : public ISrsEncoder -{ -private: - // repeated Log logs= 1; - std::vector logs_; - // optional string source = 4; - std::string source_; - -public: - SrsClsLogGroup(); - virtual ~SrsClsLogGroup(); - -public: - SrsClsLogGroup *set_source(std::string v); - SrsClsLog *add_log(); - -public: - virtual uint64_t nb_bytes(); - srs_error_t encode(SrsBuffer *b); -}; - -// See https://cloud.tencent.com/document/api/614/16873 -class SrsClsLogGroupList -{ -private: - // repeated LogGroup logGroupList = 1; - std::vector groups_; - -public: - SrsClsLogGroupList(); - virtual ~SrsClsLogGroupList(); - -public: - bool empty(); - SrsClsLogGroup *add_log_group(); - -public: - virtual uint64_t nb_bytes(); - srs_error_t encode(SrsBuffer *b); -}; - -SrsClsLogContent::SrsClsLogContent() -{ -} - -SrsClsLogContent::~SrsClsLogContent() -{ -} - -SrsClsLogContent *SrsClsLogContent::set_key(std::string v) -{ - key_ = v; - return this; -} - -SrsClsLogContent *SrsClsLogContent::set_value(std::string v) -{ - value_ = v; - return this; -} - -uint64_t SrsClsLogContent::nb_bytes() -{ - uint64_t nn = SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(key_); - nn += SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(value_); - return nn; -} - -srs_error_t SrsClsLogContent::encode(SrsBuffer *b) -{ - srs_error_t err = srs_success; - - // Encode the key. - if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufFieldString)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufString::encode(b, key_)) != srs_success) { - return srs_error_wrap(err, "encode key=%s", key_.c_str()); - } - - // Encode the value. - if ((err = SrsProtobufKey::encode(b, 2, SrsProtobufFieldString)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufString::encode(b, value_)) != srs_success) { - return srs_error_wrap(err, "encode value=%s", value_.c_str()); - } - - return err; -} - -SrsClsLog::SrsClsLog() -{ -} - -SrsClsLog::~SrsClsLog() -{ - for (std::vector::iterator it = contents_.begin(); it != contents_.end(); ++it) { - SrsClsLogContent *content = *it; - srs_freep(content); - } -} - -SrsClsLogContent *SrsClsLog::add_content() -{ - SrsClsLogContent *content = new SrsClsLogContent(); - contents_.push_back(content); - return content; -} - -SrsClsLog *SrsClsLog::set_time(int64_t v) -{ - time_ = v; - return this; -} - -uint64_t SrsClsLog::nb_bytes() -{ - uint64_t nn = SrsProtobufKey::sizeof_key() + SrsProtobufVarints::sizeof_varint(time_); - - for (std::vector::iterator it = contents_.begin(); it != contents_.end(); ++it) { - SrsClsLogContent *content = *it; - nn += SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(content); - } - - return nn; -} - -srs_error_t SrsClsLog::encode(SrsBuffer *b) -{ - srs_error_t err = srs_success; - - // Encode the time. - if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufFieldVarint)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufVarints::encode(b, time_)) != srs_success) { - return srs_error_wrap(err, "encode time"); - } - - // Encode each content. - for (std::vector::iterator it = contents_.begin(); it != contents_.end(); ++it) { - SrsClsLogContent *content = *it; - - if ((err = SrsProtobufKey::encode(b, 2, SrsProtobufFieldObject)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufObject::encode(b, content)) != srs_success) { - return srs_error_wrap(err, "encode content"); - } - } - - return err; -} - -SrsClsLogGroup::SrsClsLogGroup() -{ -} - -SrsClsLogGroup::~SrsClsLogGroup() -{ - for (std::vector::iterator it = logs_.begin(); it != logs_.end(); ++it) { - SrsClsLog *log = *it; - srs_freep(log); - } -} - -SrsClsLogGroup *SrsClsLogGroup::set_source(std::string v) -{ - source_ = v; - return this; -} - -SrsClsLog *SrsClsLogGroup::add_log() -{ - SrsClsLog *log = new SrsClsLog(); - logs_.push_back(log); - return log; -} - -uint64_t SrsClsLogGroup::nb_bytes() -{ - uint64_t nn = 0; - for (std::vector::iterator it = logs_.begin(); it != logs_.end(); ++it) { - SrsClsLog *log = *it; - nn += SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(log); - } - - nn += SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(source_); - return nn; -} - -srs_error_t SrsClsLogGroup::encode(SrsBuffer *b) -{ - srs_error_t err = srs_success; - - // Encode each log. - for (std::vector::iterator it = logs_.begin(); it != logs_.end(); ++it) { - SrsClsLog *log = *it; - - if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufFieldObject)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufObject::encode(b, log)) != srs_success) { - return srs_error_wrap(err, "encode log"); - } - } - - // Encode the optional source. - if ((err = SrsProtobufKey::encode(b, 4, SrsProtobufFieldString)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufString::encode(b, source_)) != srs_success) { - return srs_error_wrap(err, "encode source=%s", source_.c_str()); - } - - return err; -} - -SrsClsLogGroupList::SrsClsLogGroupList() -{ -} - -SrsClsLogGroupList::~SrsClsLogGroupList() -{ - for (std::vector::iterator it = groups_.begin(); it != groups_.end(); ++it) { - SrsClsLogGroup *group = *it; - srs_freep(group); - } -} - -bool SrsClsLogGroupList::empty() -{ - return groups_.empty(); -} - -SrsClsLogGroup *SrsClsLogGroupList::add_log_group() -{ - SrsClsLogGroup *group = new SrsClsLogGroup(); - groups_.push_back(group); - return group; -} - -uint64_t SrsClsLogGroupList::nb_bytes() -{ - uint64_t nn = 0; - for (std::vector::iterator it = groups_.begin(); it != groups_.end(); ++it) { - SrsClsLogGroup *group = *it; - nn += SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(group); - } - return nn; -} - -srs_error_t SrsClsLogGroupList::encode(SrsBuffer *b) -{ - srs_error_t err = srs_success; - - // Encode each group. - for (std::vector::iterator it = groups_.begin(); it != groups_.end(); ++it) { - SrsClsLogGroup *group = *it; - - if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufFieldObject)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufObject::encode(b, group)) != srs_success) { - return srs_error_wrap(err, "encode group"); - } - } - - return err; -} - -SrsClsSugar::SrsClsSugar() -{ - log_groups_ = new SrsClsLogGroupList(); - log_group_ = log_groups_->add_log_group(); - log_ = log_group_->add_log(); - - log_group_->set_source(srs_get_public_internet_address(true)); - log_->set_time(srs_time_now_cached() / SRS_UTIME_MILLISECONDS); - kv("agent", RTMP_SIG_SRS_SERVER); - - string label = _srs_cls->label(); - if (!label.empty()) { - kv("label", label); - } - - string tag = _srs_cls->tag(); - if (!tag.empty()) { - kv("tag", tag); - } - - string server_id = SrsStatistic::instance()->server_id(); - if (!server_id.empty()) { - kv("id", server_id); - } -} - -SrsClsSugar::~SrsClsSugar() -{ - srs_freep(log_groups_); -} - -uint64_t SrsClsSugar::nb_bytes() -{ - return log_groups_->nb_bytes(); -} - -srs_error_t SrsClsSugar::encode(SrsBuffer *b) -{ - return log_groups_->encode(b); -} - -bool SrsClsSugar::empty() -{ - return log_groups_->empty(); -} - -SrsClsSugar *SrsClsSugar::kv(std::string k, std::string v) -{ - log_->add_content()->set_key(k)->set_value(v); - return this; -} - -SrsClsSugars::SrsClsSugars() -{ -} - -SrsClsSugars::~SrsClsSugars() -{ - for (vector::iterator it = sugars.begin(); it != sugars.end(); ++it) { - SrsClsSugar *sugar = *it; - srs_freep(sugar); - } -} - -uint64_t SrsClsSugars::nb_bytes() -{ - uint64_t size = 0; - for (vector::iterator it = sugars.begin(); it != sugars.end(); ++it) { - SrsClsSugar *sugar = *it; - size += sugar->nb_bytes(); - } - return size; -} - -srs_error_t SrsClsSugars::encode(SrsBuffer *b) -{ - srs_error_t err = srs_success; - - for (vector::iterator it = sugars.begin(); it != sugars.end(); ++it) { - SrsClsSugar *sugar = *it; - if ((err = sugar->encode(b)) != srs_success) { - return srs_error_wrap(err, "encode %d sugars", (int)sugars.size()); - } - } - - return err; -} - -SrsClsSugar *SrsClsSugars::create() -{ - SrsClsSugar *sugar = new SrsClsSugar(); - sugars.push_back(sugar); - return sugar; -} - -SrsClsSugars *SrsClsSugars::slice(int max_size) -{ - SrsClsSugars *v = new SrsClsSugars(); - - uint64_t v_size = 0; - for (vector::iterator it = sugars.begin(); it != sugars.end();) { - SrsClsSugar *sugar = *it; - - // Always consume it. - it = sugars.erase(it); - - // If empty, ignore it. - if (sugar->empty()) { - srs_freep(sugar); - continue; - } - - // Not empty, append it, to make sure at least one elem. - v->sugars.push_back(sugar); - - // Util exceed the max size. - v_size += sugar->nb_bytes(); - if ((int)v_size > max_size) { - break; - } - } - - return v; -} - -bool SrsClsSugars::empty() -{ - return sugars.empty(); -} - -int SrsClsSugars::size() -{ - return (int)sugars.size(); -} - -SrsClsClient *_srs_cls = NULL; - -SrsClsClient::SrsClsClient() -{ - enabled_ = false; - stat_heartbeat_ = false; - stat_streams_ = false; - debug_logging_ = false; - heartbeat_ratio_ = 0; - streams_ratio_ = 0; - nn_logs_ = 0; - sugars_ = new SrsClsSugars(); -} - -SrsClsClient::~SrsClsClient() -{ - srs_freep(sugars_); -} - -bool SrsClsClient::enabled() -{ - return enabled_; -} - -string SrsClsClient::label() -{ - return label_; -} - -string SrsClsClient::tag() -{ - return tag_; -} - -uint64_t SrsClsClient::nn_logs() -{ - return nn_logs_; -} - -srs_error_t SrsClsClient::initialize() -{ - srs_error_t err = srs_success; - - enabled_ = _srs_config->get_tencentcloud_cls_enabled(); - if (!enabled_) { - srs_trace("TencentCloud CLS is disabled"); - return err; - } - - label_ = _srs_config->get_tencentcloud_cls_label(); - tag_ = _srs_config->get_tencentcloud_cls_tag(); - stat_heartbeat_ = _srs_config->get_tencentcloud_cls_stat_heartbeat(); - stat_streams_ = _srs_config->get_tencentcloud_cls_stat_streams(); - debug_logging_ = _srs_config->get_tencentcloud_cls_debug_logging(); - heartbeat_ratio_ = srs_max(1, _srs_config->get_tencentcloud_cls_heartbeat_ratio()); - streams_ratio_ = srs_max(1, _srs_config->get_tencentcloud_cls_streams_ratio()); - - secret_id_ = _srs_config->get_tencentcloud_cls_secret_id(); - if (secret_id_.empty()) { - return srs_error_new(ERROR_CLS_INVALID_CONFIG, "CLS no config for secret_id"); - } - - string secret_key = _srs_config->get_tencentcloud_cls_secret_key(); - if (secret_key.empty()) { - return srs_error_new(ERROR_CLS_INVALID_CONFIG, "CLS no config for secret_key"); - } - - endpoint_ = _srs_config->get_tencentcloud_cls_endpoint(); - if (endpoint_.empty()) { - return srs_error_new(ERROR_CLS_INVALID_CONFIG, "CLS no config for endpoint"); - } - - topic_ = _srs_config->get_tencentcloud_cls_topic_id(); - if (topic_.empty()) { - return srs_error_new(ERROR_CLS_INVALID_CONFIG, "CLS no config for topic_id"); - } - - srs_trace("Initialize TencentCloud CLS label=%s, tag=%s, secret_id=%dB, secret_key=%dB, endpoint=%s, topic=%s, heartbeat=%d/%d, streams=%d/%d debug_logging=%d", - label_.c_str(), tag_.c_str(), secret_id_.length(), secret_key.length(), endpoint_.c_str(), topic_.c_str(), stat_heartbeat_, heartbeat_ratio_, stat_streams_, streams_ratio_, debug_logging_); - - return err; -} - -srs_error_t SrsClsClient::report() -{ - srs_error_t err = srs_success; - - if ((err = dump_summaries(sugars_)) != srs_success) { - return srs_error_wrap(err, "dump summary"); - } - - if ((err = dump_streams(sugars_)) != srs_success) { - return srs_error_wrap(err, "dump streams"); - } - - if (sugars_->empty()) { - return err; - } - - SrsUniquePtr sugars(sugars_); - sugars_ = new SrsClsSugars(); - - if ((err = send_logs(sugars.get())) != srs_success) { - return srs_error_wrap(err, "cls"); - } - - return err; -} - -srs_error_t SrsClsClient::do_send_logs(ISrsEncoder *sugar, int count, int total) -{ - srs_error_t err = srs_success; - - uint64_t size = sugar->nb_bytes(); - // Max size is 5MB, error is 403:LogSizeExceed, see https://cloud.tencent.com/document/api/614/12402 - if (size >= 5 * 1024 * 1024) { - return srs_error_new(ERROR_CLS_EXCEED_SIZE, "exceed 5MB actual %d", size); - } - - SrsUniquePtr buf(new char[size]); - - memset(buf.get(), 0, size); - SrsBuffer b(buf.get(), size); - if ((err = sugar->encode(&b)) != srs_success) { - return srs_error_wrap(err, "encode log"); - } - - string body(buf.get(), size); - - // Write a CLS log to service specified by url. - string url = "http://" + endpoint_ + ":80/structuredlog?topic_id=" + topic_; - - SrsHttpUri uri; - if ((err = uri.initialize(url)) != srs_success) { - return srs_error_wrap(err, "http: post failed. url=%s", url.c_str()); - } - - SrsHttpClient http; - if ((err = http.initialize(uri.get_schema(), uri.get_host(), uri.get_port())) != srs_success) { - return srs_error_wrap(err, "http: init client"); - } - - // Sign the request, see https://cloud.tencent.com/document/product/614/56475 - if (true) { - map params; - params["topic_id"] = topic_; - - map headers; - headers["Host"] = uri.get_host(); - headers["Content-Type"] = "application/x-protobuf"; - http.set_header("Content-Type", "application/x-protobuf"); - - string method = "POST"; - string secret_key = _srs_config->get_tencentcloud_cls_secret_key(); - std::string signature = tencentcloud_api_sign::signature( - secret_id_, secret_key, method, uri.get_path(), params, headers, 300 // Expire in seconds - ); - headers["Authorization"] = signature; - http.set_header("Authorization", signature); - } - - string path = uri.get_path(); - if (!uri.get_query().empty()) { - path += "?" + uri.get_query(); - } - - // Start request and parse response. - ISrsHttpMessage *msg_raw = NULL; - if ((err = http.post(path, body, &msg_raw)) != srs_success) { - return srs_error_wrap(err, "http: client post"); - } - SrsUniquePtr msg(msg_raw); - - string res; - uint16_t code = msg->status_code(); - if ((err = msg->body_read_all(res)) != srs_success) { - return srs_error_wrap(err, "http: body read"); - } - - // ensure the http status is ok. - if (code != SRS_CONSTS_HTTP_OK && code != SRS_CONSTS_HTTP_Created) { - return srs_error_new(ERROR_HTTP_STATUS_INVALID, "http: status %d, body is %s", code, res.c_str()); - } - - string request_id = msg->header()->get("X-Cls-Requestid"); - if (request_id.empty() && !debug_logging_) { - srs_warn("no CLS requestId for log %dB", body.length()); - } - - if (debug_logging_) { - string server_id = SrsStatistic::instance()->server_id(); - srs_trace("CLS write logs=%d/%d, size=%dB, server_id=%s, request_id=%s", count, total, body.length(), server_id.c_str(), request_id.c_str()); - } - - return err; -} - -// For each upload, never exceed 2MB, to avoid burst of CPU or network usage. -#define SRS_CLS_BATCH_MAX_LOG_SIZE 2 * 1024 * 1024 - -srs_error_t SrsClsClient::send_logs(SrsClsSugars *sugars) -{ - srs_error_t err = srs_success; - - // Record the total logs sent out. - int total = sugars->size(); - nn_logs_ += total; - - // Never do infinite loop, limit to a max loop and drop logs if exceed. - for (int i = 0; i < 128 && !sugars->empty(); ++i) { - SrsUniquePtr v(sugars->slice(SRS_CLS_BATCH_MAX_LOG_SIZE)); - - if ((err = do_send_logs((ISrsEncoder *)v.get(), v->size(), total)) != srs_success) { - return srs_error_wrap(err, "send %d/%d/%d logs", v->size(), i, total); - } - } - - return err; -} - -srs_error_t SrsClsClient::dump_summaries(SrsClsSugars *sugars) -{ - srs_error_t err = srs_success; - - // Ignore if disabled. - if (!enabled_ || !stat_heartbeat_) { - return err; - } - - // Whether it's time to report heartbeat. - static int nn_heartbeat = -1; - bool interval_ok = nn_heartbeat == -1 || ++nn_heartbeat >= heartbeat_ratio_; - if (interval_ok) { - nn_heartbeat = 0; - } - if (!interval_ok) { - return err; - } - - SrsClsSugar *sugar = sugars->create(); - sugar->kv("hint", "summary"); - sugar->kv("version", RTMP_SIG_SRS_VERSION); - sugar->kv("pid", srs_fmt_sprintf("%d", getpid())); - - // Server ID to identify logs from a set of servers' logs. - SrsStatistic::instance()->dumps_cls_summaries(sugar); - - SrsProcSelfStat *u = srs_get_self_proc_stat(); - if (u->ok) { - // The cpu usage of SRS, 1 means 1/1000 - if (u->percent > 0) { - sugar->kv("cpu", srs_fmt_sprintf("%d", (int)(u->percent * 1000))); - } - } - - SrsPlatformInfo *p = srs_get_platform_info(); - if (p->ok) { - // The uptime of SRS, in seconds. - if (p->srs_startup_time > 0) { - sugar->kv("uptime", srs_fmt_sprintf("%d", (int)((srs_time_now_cached() - p->srs_startup_time) / SRS_UTIME_SECONDS))); - } - // The load of system, load every 1 minute, 1 means 1/1000. - if (p->load_one_minutes > 0) { - sugar->kv("load", srs_fmt_sprintf("%d", (int)(p->load_one_minutes * 1000))); - } - } - - SrsRusage *r = srs_get_system_rusage(); - SrsMemInfo *m = srs_get_meminfo(); - if (r->ok && m->ok) { - float self_mem_percent = 0; - if (m->MemTotal > 0) { - self_mem_percent = (float)(r->r.ru_maxrss / (double)m->MemTotal); - } - - // The memory of SRS, 1 means 1/1000 - if (self_mem_percent > 0) { - sugar->kv("mem", srs_fmt_sprintf("%d", (int)(self_mem_percent * 1000))); - } - } - - SrsProcSystemStat *s = srs_get_system_proc_stat(); - if (s->ok) { - // The cpu usage of system, 1 means 1/1000 - if (s->percent > 0) { - sugar->kv("cpu2", srs_fmt_sprintf("%d", (int)(s->percent * 1000))); - } - } - - SrsNetworkRtmpServer *nrs = srs_get_network_rtmp_server(); - if (nrs->ok) { - // The number of connections of SRS. - if (nrs->nb_conn_srs > 0) { - sugar->kv("conn", srs_fmt_sprintf("%d", nrs->nb_conn_srs)); - } - // The number of connections of system. - if (nrs->nb_conn_sys > 0) { - sugar->kv("conn2", srs_fmt_sprintf("%d", nrs->nb_conn_sys)); - } - // The received kbps in 30s of SRS. - if (nrs->rkbps_30s > 0) { - sugar->kv("recv", srs_fmt_sprintf("%d", nrs->rkbps_30s)); - } - // The sending out kbps in 30s of SRS. - if (nrs->skbps_30s > 0) { - sugar->kv("send", srs_fmt_sprintf("%d", nrs->skbps_30s)); - } - } - - return err; -} - -srs_error_t SrsClsClient::dump_streams(SrsClsSugars *sugars) -{ - srs_error_t err = srs_success; - - // Ignore if disabled. - if (!enabled_ || !stat_streams_) { - return err; - } - - // Whether it's time to report streams. - static int nn_streams = -1; - bool interval_ok = nn_streams == -1 || ++nn_streams >= streams_ratio_; - if (interval_ok) { - nn_streams = 0; - } - if (!interval_ok) { - return err; - } - - // Dumps all streams as sugars. - SrsStatistic::instance()->dumps_cls_streams(sugars); - - return err; -} - -SrsOtelExportTraceServiceRequest::SrsOtelExportTraceServiceRequest() -{ -} - -SrsOtelExportTraceServiceRequest::~SrsOtelExportTraceServiceRequest() -{ - for (vector::iterator it = spans_.begin(); it != spans_.end(); ++it) { - SrsOtelResourceSpans *span = *it; - srs_freep(span); - } -} - -SrsOtelResourceSpans *SrsOtelExportTraceServiceRequest::append() -{ - SrsOtelResourceSpans *v = new SrsOtelResourceSpans(); - spans_.push_back(v); - return v; -} - -uint64_t SrsOtelExportTraceServiceRequest::nb_bytes() -{ - uint64_t nn = 0; - for (vector::iterator it = spans_.begin(); it != spans_.end(); ++it) { - SrsOtelResourceSpans *span = *it; - nn += SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(span); - } - return nn; -} - -srs_error_t SrsOtelExportTraceServiceRequest::encode(SrsBuffer *b) -{ - srs_error_t err = srs_success; - - // Encode each span. - for (vector::iterator it = spans_.begin(); it != spans_.end(); ++it) { - SrsOtelResourceSpans *span = *it; - - if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufFieldObject)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufObject::encode(b, span)) != srs_success) { - return srs_error_wrap(err, "encode span"); - } - } - - return err; -} - -SrsOtelResourceSpans::SrsOtelResourceSpans() -{ - resource_ = new SrsOtelResource(); -} - -SrsOtelResourceSpans::~SrsOtelResourceSpans() -{ - srs_freep(resource_); - - for (std::vector::iterator it = spans_.begin(); it != spans_.end(); ++it) { - SrsOtelScopeSpans *span = *it; - srs_freep(span); - } -} - -SrsOtelResource *SrsOtelResourceSpans::resource() -{ - return resource_; -} - -SrsOtelScopeSpans *SrsOtelResourceSpans::append() -{ - SrsOtelScopeSpans *v = new SrsOtelScopeSpans(); - spans_.push_back(v); - return v; -} - -uint64_t SrsOtelResourceSpans::nb_bytes() -{ - uint64_t nn = SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(resource_); - for (std::vector::iterator it = spans_.begin(); it != spans_.end(); ++it) { - SrsOtelScopeSpans *span = *it; - nn += SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(span); - } - return nn; -} - -srs_error_t SrsOtelResourceSpans::encode(SrsBuffer *b) -{ - srs_error_t err = srs_success; - - // Encode the resource. - if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufFieldObject)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufObject::encode(b, resource_)) != srs_success) { - return srs_error_wrap(err, "encode resource"); - } - - // Encode scope spans. - - // Encode each group. - for (std::vector::iterator it = spans_.begin(); it != spans_.end(); ++it) { - SrsOtelScopeSpans *span = *it; - - if ((err = SrsProtobufKey::encode(b, 2, SrsProtobufFieldObject)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufObject::encode(b, span)) != srs_success) { - return srs_error_wrap(err, "encode span"); - } - } - - return err; -} - -SrsOtelResource::SrsOtelResource() -{ -} - -SrsOtelResource::~SrsOtelResource() -{ - for (vector::iterator it = attributes_.begin(); it != attributes_.end(); ++it) { - SrsOtelAttribute *attribute = *it; - srs_freep(attribute); - } -} - -SrsOtelResource *SrsOtelResource::add_addr(SrsOtelAttribute *v) -{ - attributes_.push_back(v); - return this; -} - -uint64_t SrsOtelResource::nb_bytes() -{ - uint64_t nn = 0; - for (vector::iterator it = attributes_.begin(); it != attributes_.end(); ++it) { - SrsOtelAttribute *attribute = *it; - nn += SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(attribute); - } - return nn; -} - -srs_error_t SrsOtelResource::encode(SrsBuffer *b) -{ - srs_error_t err = srs_success; - - // Encode attributes. - for (vector::iterator it = attributes_.begin(); it != attributes_.end(); ++it) { - SrsOtelAttribute *attribute = *it; - - if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufFieldObject)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufObject::encode(b, attribute)) != srs_success) { - return srs_error_wrap(err, "encode attribute"); - } - } - - return err; -} - -SrsOtelAttribute::SrsOtelAttribute() -{ - value_ = new SrsOtelAnyValue(); -} - -SrsOtelAttribute::~SrsOtelAttribute() -{ - srs_freep(value_); -} - -const std::string &SrsOtelAttribute::key() -{ - return key_; -} - -SrsOtelAttribute *SrsOtelAttribute::kv(std::string k, std::string v) -{ - SrsOtelAttribute *attr = new SrsOtelAttribute(); - attr->key_ = k; - attr->value_->set_string(v); - return attr; -} - -SrsOtelAttribute *SrsOtelAttribute::kvi(std::string k, int64_t v) -{ - SrsOtelAttribute *attr = new SrsOtelAttribute(); - attr->key_ = k; - attr->value_->set_int(v); - return attr; -} - -uint64_t SrsOtelAttribute::nb_bytes() -{ - uint64_t nn = SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(key_); - nn += SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(value_); - return nn; -} - -srs_error_t SrsOtelAttribute::encode(SrsBuffer *b) -{ - srs_error_t err = srs_success; - - // Encode the key. - if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufFieldString)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufString::encode(b, key_)) != srs_success) { - return srs_error_wrap(err, "encode key=%s", key_.c_str()); - } - - // Encode the value. - if ((err = SrsProtobufKey::encode(b, 2, SrsProtobufFieldObject)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufObject::encode(b, value_)) != srs_success) { - return srs_error_wrap(err, "encode value"); - } - - return err; -} - -SrsOtelAnyValue::SrsOtelAnyValue() -{ - used_field_id_ = 1; - int_value_ = 0; -} - -SrsOtelAnyValue::~SrsOtelAnyValue() -{ -} - -SrsOtelAnyValue *SrsOtelAnyValue::set_string(const std::string &v) -{ - string_value_ = v; - used_field_id_ = 1; - return this; -} - -SrsOtelAnyValue *SrsOtelAnyValue::set_int(int64_t v) -{ - int_value_ = v; - used_field_id_ = 3; - return this; -} - -uint64_t SrsOtelAnyValue::nb_bytes() -{ - uint64_t nn = 0; - if (used_field_id_ == 1) - nn = SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(string_value_); - if (used_field_id_ == 3) - nn = SrsProtobufKey::sizeof_key() + SrsProtobufVarints::sizeof_varint(int_value_); - return nn; -} - -srs_error_t SrsOtelAnyValue::encode(SrsBuffer *b) -{ - srs_error_t err = srs_success; - - if (used_field_id_ == 1) { - // Encode the string value. - if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufFieldString)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufString::encode(b, string_value_)) != srs_success) { - return srs_error_wrap(err, "encode value=%s", string_value_.c_str()); - } - } else if (used_field_id_ == 3) { - // Encode the int value. - if ((err = SrsProtobufKey::encode(b, 3, SrsProtobufFieldVarint)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufVarints::encode(b, int_value_)) != srs_success) { - return srs_error_wrap(err, "encode value=%" PRId64, int_value_); - } - } - - return err; -} - -SrsOtelScopeSpans::SrsOtelScopeSpans() -{ - scope_ = new SrsOtelScope(); -} - -SrsOtelScopeSpans::~SrsOtelScopeSpans() -{ - srs_freep(scope_); - for (std::vector::iterator it = spans_.begin(); it != spans_.end(); ++it) { - SrsOtelSpan *span = *it; - srs_freep(span); - } -} - -SrsOtelScope *SrsOtelScopeSpans::scope() -{ - return scope_; -} - -SrsOtelScopeSpans *SrsOtelScopeSpans::swap(std::vector &spans) -{ - spans_.swap(spans); - return this; -} - -int SrsOtelScopeSpans::size() -{ - return (int)spans_.size(); -} - -uint64_t SrsOtelScopeSpans::nb_bytes() -{ - uint64_t nn = SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(scope_); - for (std::vector::iterator it = spans_.begin(); it != spans_.end(); ++it) { - SrsOtelSpan *span = *it; - nn += SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(span); - } - return nn; -} - -srs_error_t SrsOtelScopeSpans::encode(SrsBuffer *b) -{ - srs_error_t err = srs_success; - - // Encode the scope. - if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufFieldObject)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufObject::encode(b, scope_)) != srs_success) { - return srs_error_wrap(err, "encode scope"); - } - - // Encode each span. - for (std::vector::iterator it = spans_.begin(); it != spans_.end(); ++it) { - SrsOtelSpan *span = *it; - - if ((err = SrsProtobufKey::encode(b, 2, SrsProtobufFieldObject)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufObject::encode(b, span)) != srs_success) { - return srs_error_wrap(err, "encode span"); - } - } - return err; -} - -SrsOtelScope::SrsOtelScope() -{ -} - -SrsOtelScope::~SrsOtelScope() -{ -} - -uint64_t SrsOtelScope::nb_bytes() -{ - uint64_t nn = 0; - nn = SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(name_); - return nn; -} - -srs_error_t SrsOtelScope::encode(SrsBuffer *b) -{ - srs_error_t err = srs_success; - - // Encode the name. - if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufFieldString)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufString::encode(b, name_)) != srs_success) { - return srs_error_wrap(err, "encode name=%s", name_.c_str()); - } - - return err; -} - -SrsOtelSpan::SrsOtelSpan() -{ - start_time_unix_nano_ = 0; - end_time_unix_nano_ = 0; - status_ = new SrsOtelStatus(); -} - -SrsOtelSpan::~SrsOtelSpan() -{ - for (vector::iterator it = attributes_.begin(); it != attributes_.end(); ++it) { - SrsOtelAttribute *attribute = *it; - srs_freep(attribute); - } - - for (vector::iterator it = events_.begin(); it != events_.end(); ++it) { - SrsOtelEvent *event = *it; - srs_freep(event); - } - - for (vector::iterator it = links_.begin(); it != links_.end(); ++it) { - SrsOtelLink *link = *it; - srs_freep(link); - } - - srs_freep(status_); -} - -SrsOtelAttribute *SrsOtelSpan::attr(const std::string k) -{ - for (vector::iterator it = attributes_.begin(); it != attributes_.end(); ++it) { - SrsOtelAttribute *attribute = *it; - if (attribute->key() == k) { - return attribute; - } - } - return NULL; -} - -uint64_t SrsOtelSpan::nb_bytes() -{ - uint64_t nn = 0; - - nn += SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(trace_id_); - nn += SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(span_id_); - if (!parent_span_id_.empty()) { - nn += SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(parent_span_id_); - } - nn += SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(name_); - nn += SrsProtobufKey::sizeof_key() + SrsProtobufVarints::sizeof_varint(kind_); - nn += SrsProtobufKey::sizeof_key() + SrsProtobufFixed64::sizeof_int(start_time_unix_nano_); - nn += SrsProtobufKey::sizeof_key() + SrsProtobufFixed64::sizeof_int(end_time_unix_nano_); - - for (vector::iterator it = attributes_.begin(); it != attributes_.end(); ++it) { - SrsOtelAttribute *attribute = *it; - nn += SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(attribute); - } - - for (vector::iterator it = events_.begin(); it != events_.end(); ++it) { - SrsOtelEvent *event = *it; - nn += SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(event); - } - - for (vector::iterator it = links_.begin(); it != links_.end(); ++it) { - SrsOtelLink *link = *it; - nn += SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(link); - } - - nn += SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(status_); - - return nn; -} - -srs_error_t SrsOtelSpan::encode(SrsBuffer *b) -{ - srs_error_t err = srs_success; - - // Encode the trace id. - if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufFieldString)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufString::encode(b, trace_id_)) != srs_success) { - return srs_error_wrap(err, "encode trace_id=%s", trace_id_.c_str()); - } - - // Encode the span id. - if ((err = SrsProtobufKey::encode(b, 2, SrsProtobufFieldString)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufString::encode(b, span_id_)) != srs_success) { - return srs_error_wrap(err, "encode span_id=%s", span_id_.c_str()); - } - - // Encode the parent span id. - if (!parent_span_id_.empty()) { - if ((err = SrsProtobufKey::encode(b, 4, SrsProtobufFieldString)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufString::encode(b, parent_span_id_)) != srs_success) { - return srs_error_wrap(err, "encode parent_span_id=%s", parent_span_id_.c_str()); - } - } - - // Encode the name. - if ((err = SrsProtobufKey::encode(b, 5, SrsProtobufFieldString)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufString::encode(b, name_)) != srs_success) { - return srs_error_wrap(err, "encode name=%s", name_.c_str()); - } - - // Encode the kind. - if ((err = SrsProtobufKey::encode(b, 6, SrsProtobufFieldEnum)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufVarints::encode(b, kind_)) != srs_success) { - return srs_error_wrap(err, "encode kind=%d", (int)kind_); - } - - // Encode the start time. - if ((err = SrsProtobufKey::encode(b, 7, SrsProtobufField64bit)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufFixed64::encode(b, start_time_unix_nano_)) != srs_success) { - return srs_error_wrap(err, "encode start_time=%" PRId64, start_time_unix_nano_); - } - - // Encode the end time. - if ((err = SrsProtobufKey::encode(b, 8, SrsProtobufField64bit)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufFixed64::encode(b, end_time_unix_nano_)) != srs_success) { - return srs_error_wrap(err, "encode end_time=%" PRId64, end_time_unix_nano_); - } - - // Encode attribute if not empty. - for (vector::iterator it = attributes_.begin(); it != attributes_.end(); ++it) { - SrsOtelAttribute *attribute = *it; - - if ((err = SrsProtobufKey::encode(b, 9, SrsProtobufFieldObject)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufObject::encode(b, attribute)) != srs_success) { - return srs_error_wrap(err, "encode attribute"); - } - } - - // Encode the events if not empty. - for (vector::iterator it = events_.begin(); it != events_.end(); ++it) { - SrsOtelEvent *event = *it; - - if ((err = SrsProtobufKey::encode(b, 11, SrsProtobufFieldObject)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufObject::encode(b, event)) != srs_success) { - return srs_error_wrap(err, "encode event"); - } - } - - // Encode the links if not empty. - for (vector::iterator it = links_.begin(); it != links_.end(); ++it) { - SrsOtelLink *link = *it; - - if ((err = SrsProtobufKey::encode(b, 13, SrsProtobufFieldObject)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufObject::encode(b, link)) != srs_success) { - return srs_error_wrap(err, "encode link"); - } - } - - // Encode the status. - if ((err = SrsProtobufKey::encode(b, 15, SrsProtobufFieldObject)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufObject::encode(b, status_)) != srs_success) { - return srs_error_wrap(err, "encode status"); - } - - return err; -} - -SrsOtelEvent::SrsOtelEvent() -{ - time_ = srs_time_now_realtime(); -} - -SrsOtelEvent::~SrsOtelEvent() -{ - for (vector::iterator it = attributes_.begin(); it != attributes_.end(); ++it) { - SrsOtelAttribute *attribute = *it; - srs_freep(attribute); - } -} - -SrsOtelEvent *SrsOtelEvent::create(std::string v) -{ - SrsOtelEvent *e = new SrsOtelEvent(); - e->name_ = v; - return e; -} - -SrsOtelEvent *SrsOtelEvent::add_attr(SrsOtelAttribute *v) -{ - attributes_.push_back(v); - return this; -} - -uint64_t SrsOtelEvent::nb_bytes() -{ - uint64_t nn = 0; - nn += SrsProtobufKey::sizeof_key() + SrsProtobufFixed64::sizeof_int(time_); - nn += SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(name_); - for (vector::iterator it = attributes_.begin(); it != attributes_.end(); ++it) { - SrsOtelAttribute *attribute = *it; - nn += SrsProtobufKey::sizeof_key() + SrsProtobufObject::sizeof_object(attribute); - } - return nn; -} - -srs_error_t SrsOtelEvent::encode(SrsBuffer *b) -{ - srs_error_t err = srs_success; - - // Encode the time. - if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufField64bit)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufFixed64::encode(b, time_)) != srs_success) { - return srs_error_wrap(err, "encode time=%" PRId64, time_); - } - - // Encode the name. - if ((err = SrsProtobufKey::encode(b, 2, SrsProtobufFieldString)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufString::encode(b, name_)) != srs_success) { - return srs_error_wrap(err, "encode key=%s", name_.c_str()); - } - - // Encode attributes. - for (vector::iterator it = attributes_.begin(); it != attributes_.end(); ++it) { - SrsOtelAttribute *attribute = *it; - - if ((err = SrsProtobufKey::encode(b, 3, SrsProtobufFieldObject)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufObject::encode(b, attribute)) != srs_success) { - return srs_error_wrap(err, "encode attribute"); - } - } - - return err; -} - -SrsOtelLink::SrsOtelLink() -{ -} - -SrsOtelLink::~SrsOtelLink() -{ -} - -SrsOtelLink *SrsOtelLink::create() -{ - return new SrsOtelLink(); -} - -SrsOtelLink *SrsOtelLink::set_id(const std::string &trace_id, const std::string &span_id) -{ - trace_id_ = trace_id; - span_id_ = span_id; - return this; -} - -uint64_t SrsOtelLink::nb_bytes() -{ - uint64_t nn = 0; - nn += SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(trace_id_); - nn += SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(span_id_); - return nn; -} - -srs_error_t SrsOtelLink::encode(SrsBuffer *b) -{ - srs_error_t err = srs_success; - - // Encode the trace id. - if ((err = SrsProtobufKey::encode(b, 1, SrsProtobufFieldString)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufString::encode(b, trace_id_)) != srs_success) { - return srs_error_wrap(err, "encode trace_id=%s", trace_id_.c_str()); - } - - // Encode the span id. - if ((err = SrsProtobufKey::encode(b, 2, SrsProtobufFieldString)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufString::encode(b, span_id_)) != srs_success) { - return srs_error_wrap(err, "encode span_id=%s", span_id_.c_str()); - } - - return err; -} - -SrsOtelStatus::SrsOtelStatus() -{ - code_ = SrsApmStatusUnset; -} - -SrsOtelStatus::~SrsOtelStatus() -{ -} - -uint64_t SrsOtelStatus::nb_bytes() -{ - uint64_t nn = 0; - if (!message_.empty()) { - nn += SrsProtobufKey::sizeof_key() + SrsProtobufString::sizeof_string(message_); - } - if (code_ != SrsApmStatusUnset) { - nn += SrsProtobufKey::sizeof_key() + SrsProtobufVarints::sizeof_varint(code_); - } - return nn; -} - -srs_error_t SrsOtelStatus::encode(SrsBuffer *b) -{ - srs_error_t err = srs_success; - - // Encode the message. - if (!message_.empty()) { - if ((err = SrsProtobufKey::encode(b, 2, SrsProtobufFieldString)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufString::encode(b, message_)) != srs_success) { - return srs_error_wrap(err, "encode message=%s", message_.c_str()); - } - } - - // Encode the status. - if (code_ != SrsApmStatusUnset) { - if ((err = SrsProtobufKey::encode(b, 3, SrsProtobufFieldEnum)) != srs_success) { - return srs_error_wrap(err, "key"); - } - - if ((err = SrsProtobufVarints::encode(b, code_)) != srs_success) { - return srs_error_wrap(err, "encode kind=%d", (int)code_); - } - } - - return err; -} - -SrsApmClient *_srs_apm = NULL; - -SrsApmContext::SrsApmContext(const std::string &name) -{ - name_ = name; - kind_ = SrsApmKindUnspecified; - - set_trace_id(srs_rand_gen_str(16)); - set_span_id(srs_rand_gen_str(8)); - // We must not use time cache, or span render might fail. - start_time_ = srs_time_now_realtime(); - ended_ = false; - status_ = SrsApmStatusUnset; - err_ = srs_success; - - span_ = NULL; - parent_ = NULL; -} - -SrsApmContext::~SrsApmContext() -{ - srs_freep(err_); - - // Span is not created by context, so should never free it here. - if (span_) { - span_->ctx_ = NULL; - span_ = NULL; - } - - // Free all child context. - for (vector::iterator it = childs_.begin(); it != childs_.end(); ++it) { - SrsApmContext *ctx = *it; - srs_freep(ctx); - } - - for (vector::iterator it = attributes_.begin(); it != attributes_.end(); ++it) { - SrsOtelAttribute *attribute = *it; - srs_freep(attribute); - } - - for (vector::iterator it = links_.begin(); it != links_.end(); ++it) { - SrsOtelLink *link = *it; - srs_freep(link); - } -} - -void SrsApmContext::set_trace_id(std::string v) -{ - trace_id_ = v; - str_trace_id_ = srs_strings_dumps_hex(trace_id_.data(), trace_id_.length(), INT_MAX, 0, INT_MAX, 0); -} - -void SrsApmContext::set_span_id(std::string v) -{ - span_id_ = v; - str_span_id_ = srs_strings_dumps_hex(span_id_.data(), span_id_.length(), INT_MAX, 0, INT_MAX, 0); -} - -const char *SrsApmContext::format_trace_id() -{ - return str_trace_id_.c_str(); -} - -const char *SrsApmContext::format_span_id() -{ - return str_span_id_.c_str(); -} - -SrsApmContext *SrsApmContext::root() -{ - // Root is node that has no parent. - if (!parent_) - return this; - - // Use cached root or parent root, literally they should be the same. - return parent_->root(); -} - -void SrsApmContext::set_parent(SrsApmContext *parent) -{ - if (ended_) - return; - - parent_ = parent; - if (parent) { - set_trace_id(parent->trace_id_); - parent_span_id_ = parent->span_id_; - parent->childs_.push_back(this); - } -} - -void SrsApmContext::set_status(SrsApmStatus status, const std::string &description) -{ - if (ended_) - return; - - status_ = status; - if (status == SrsApmStatusError) { - description_ = description; - } -} - -bool SrsApmContext::all_ended() -{ - if (!ended_) - return false; - - for (vector::iterator it = childs_.begin(); it != childs_.end(); ++it) { - SrsApmContext *ctx = *it; - if (!ctx->all_ended()) - return false; - } - - return true; -} - -int SrsApmContext::count_spans() -{ - int nn = span_ ? 1 : 0; - - for (vector::iterator it = childs_.begin(); it != childs_.end(); ++it) { - SrsApmContext *ctx = *it; - nn += ctx->count_spans(); - } - - return nn; -} - -void SrsApmContext::update_trace_id(std::string v) -{ - if (ended_) - return; - - set_trace_id(v); - - for (vector::iterator it = childs_.begin(); it != childs_.end(); ++it) { - SrsApmContext *ctx = *it; - ctx->set_trace_id(v); - } -} - -void SrsApmContext::link(SrsApmContext *to) -{ - if (ended_) - return; - - links_.push_back(SrsOtelLink::create()->set_id(to->trace_id_, to->span_id_)); - attributes_.push_back(SrsOtelAttribute::kv("link_trace", to->str_trace_id_)); - attributes_.push_back(SrsOtelAttribute::kv("link_span", to->str_span_id_)); - - to->links_.push_back(SrsOtelLink::create()->set_id(trace_id_, span_id_)); - to->attributes_.push_back(SrsOtelAttribute::kv("link_trace", str_trace_id_)); - to->attributes_.push_back(SrsOtelAttribute::kv("link_span", str_span_id_)); - - srs_trace("APM: Link span %s(trace=%s, span=%s) with %s(trace=%s, span=%s)", - name_.c_str(), str_trace_id_.c_str(), str_span_id_.c_str(), to->name_.c_str(), - to->str_trace_id_.c_str(), to->str_span_id_.c_str()); -} - -void SrsApmContext::end() -{ - if (ended_) - return; - ended_ = true; - - SrsOtelSpan *otel = new SrsOtelSpan(); - - otel->name_ = name_; - otel->trace_id_ = trace_id_; - otel->span_id_ = span_id_; - otel->parent_span_id_ = parent_span_id_; - otel->kind_ = kind_; - otel->start_time_unix_nano_ = start_time_ * 1000; - // We must not use time cache, or span render might fail. - otel->end_time_unix_nano_ = srs_time_now_realtime() * 1000; - - otel->status_->code_ = status_; - otel->status_->message_ = description_; - - otel->attributes_.swap(attributes_); - otel->links_.swap(links_); - - // Insert server ip if not exists. - if (!otel->attr("ip")) { - otel->attributes_.push_back(SrsOtelAttribute::kv("ip", srs_get_public_internet_address())); - } - if (!otel->attr("component")) { - otel->attributes_.push_back(SrsOtelAttribute::kv("component", "srs")); - } - - // See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md - if (err_ != srs_success) { - // Set the events for detail about the error. - otel->events_.push_back(SrsOtelEvent::create("exception") - ->add_attr(SrsOtelAttribute::kv("exception.type", srs_fmt_sprintf("code_%d_%s", srs_error_code(err_), srs_error_code_str(err_).c_str()))) - ->add_attr(SrsOtelAttribute::kv("exception.message", srs_error_summary(err_))) - ->add_attr(SrsOtelAttribute::kv("exception.stacktrace", srs_error_desc(err_)))); - - // We also use HTTP status code for APM to class the error. Note that it also works for non standard HTTP status - // code, for example, SRS error codes. - otel->attributes_.push_back(SrsOtelAttribute::kv("http.status_code", srs_fmt_sprintf("%d", srs_error_code(err_)))); - } - - _srs_apm->snapshot(otel); - srs_info("APM: Snapshot name=%s, trace=%s, span=%s", name_.c_str(), trace_id_.c_str(), span_id_.c_str()); -} - -SrsApmSpan::SrsApmSpan(const std::string &name) -{ - child_ = false; - - // Create the context for this span. - ctx_ = new SrsApmContext(name); - ctx_->span_ = this; - - // Default to internal span. - ctx_->kind_ = SrsApmKindInternal; -} - -SrsApmSpan::~SrsApmSpan() -{ - end(); - - // Context might be freed by other span. - if (!ctx_) - return; - - // Span is not available. - ctx_->span_ = NULL; - - // Dispose the context tree when all spans are ended. - SrsApmContext *root = ctx_->root(); - - // Only free the tree when free the last span, because we might create new span even all spans are ended only if the - // root span has not been freed, for example, when RTMP client cycle done, we create a final span. - if (root->count_spans() == 0 && root->all_ended()) { - srs_freep(root); - } -} - -const char *SrsApmSpan::format_trace_id() -{ - return ctx_ ? ctx_->format_trace_id() : ""; -} - -const char *SrsApmSpan::format_span_id() -{ - return ctx_ ? ctx_->format_span_id() : ""; -} - -ISrsApmSpan *SrsApmSpan::set_name(const std::string &name) -{ - if (ctx_) - ctx_->name_ = name; - return this; -} - -ISrsApmSpan *SrsApmSpan::set_kind(SrsApmKind kind) -{ - if (ctx_) - ctx_->kind_ = kind; - return this; -} - -ISrsApmSpan *SrsApmSpan::as_child(ISrsApmSpan *parent) -{ - // Should not be child of multiple parent spans. - if (child_) - return this; - - // For child, always load parent from context. - SrsApmSpan *span = dynamic_cast(parent); - if (span) { - ctx_->set_parent(span->ctx_); - child_ = true; - } - - return this; -} - -ISrsApmSpan *SrsApmSpan::set_status(SrsApmStatus status, const std::string &description) -{ - if (ctx_) - ctx_->set_status(status, description); - return this; -} - -ISrsApmSpan *SrsApmSpan::record_error(srs_error_t err) -{ - if (ctx_) - ctx_->err_ = srs_error_copy(err); - return this; -} - -ISrsApmSpan *SrsApmSpan::attr(const std::string &k, const std::string &v) -{ - if (ctx_) - ctx_->attributes_.push_back(SrsOtelAttribute::kv(k, v)); - return this; -} - -ISrsApmSpan *SrsApmSpan::link(ISrsApmSpan *span) -{ - SrsApmSpan *to = dynamic_cast(span); - if (ctx_ && span) - ctx_->link(to->ctx_); - return this; -} - -ISrsApmSpan *SrsApmSpan::end() -{ - if (ctx_) - ctx_->end(); - return this; -} - -ISrsApmSpan *SrsApmSpan::extract(SrsAmf0Object *h) -{ - if (!ctx_) - return this; - - SrsAmf0Any *prop = h->ensure_property_string("Traceparent"); - if (!prop) - return this; - - std::string trace_parent = prop->to_str(); - vector vs = srs_strings_split(trace_parent, "-"); - if (vs.size() != 4) - return this; - - // Update trace id for span and all its child spans. - ctx_->update_trace_id(vs[1]); - - // Update the parent span id of span, note that the parent is NULL. - ctx_->parent_span_id_ = vs[2]; - - return this; -} - -ISrsApmSpan *SrsApmSpan::inject(SrsAmf0Object *h) -{ - if (!ctx_) - return this; - - string v = text_propagator(); - if (!v.empty()) - h->set("Traceparent", SrsAmf0Any::str(v.c_str())); - - return this; -} - -std::string SrsApmSpan::text_propagator() -{ - // FlagsSampled is a bitmask with the sampled bit set. A SpanContext - // with the sampling bit set means the span is sampled. - const uint8_t FlagsSampled = 0x01; - const uint8_t supportedVersion = 0; - static char buf[256]; - - // For text based propagation, for example, HTTP header "Traceparent: 00-bb8dedf16c53ab4b6ceb1f4ca6d985bb-29247096662468ab-01" - // About the "%.2x", please see https://www.quora.com/What-does-2x-do-in-C-code for detail. - int nn = snprintf(buf, sizeof(buf), "%.2x-%s-%s-%.2x", supportedVersion, ctx_->trace_id_.c_str(), ctx_->span_id_.c_str(), FlagsSampled); - if (nn > 0 && nn < (int)sizeof(buf)) { - return string(buf, nn); - } - - return ""; -} - -static int _srs_apm_key = -1; -void _srs_apm_destructor(void *arg) -{ - // We don't free the span, because it's not created by us. - // Note that it's safe because keys will be reset when coroutine is terminated. - // SrsApmSpan* span = (SrsApmSpan*)arg; -} - -ISrsApmSpan *SrsApmSpan::store() -{ - ISrsApmSpan *span = _srs_apm->load(); - if (span == this) - return this; - - int r0 = srs_thread_setspecific(_srs_apm_key, this); - srs_assert(r0 == 0); - return this; -} - -ISrsApmSpan *SrsApmSpan::load() -{ - if (_srs_apm_key < 0) { - int r0 = srs_key_create(&_srs_apm_key, _srs_apm_destructor); - srs_assert(r0 == 0); - } - - void *span = srs_thread_getspecific(_srs_apm_key); - return (ISrsApmSpan *)span; -} - -SrsApmClient::SrsApmClient() -{ - enabled_ = false; - nn_spans_ = 0; -} - -SrsApmClient::~SrsApmClient() -{ - for (vector::iterator it = spans_.begin(); it != spans_.end(); ++it) { - SrsOtelSpan *span = *it; - srs_freep(span); - } -} - -srs_error_t SrsApmClient::initialize() -{ - srs_error_t err = srs_success; - - enabled_ = _srs_config->get_tencentcloud_apm_enabled(); - if (!enabled_) { - srs_trace("TencentCloud APM is disabled"); - return err; - } - - team_ = _srs_config->get_tencentcloud_apm_team(); - token_ = _srs_config->get_tencentcloud_apm_token(); - endpoint_ = _srs_config->get_tencentcloud_apm_endpoint(); - service_name_ = _srs_config->get_tencentcloud_apm_service_name(); - debug_logging_ = _srs_config->get_tencentcloud_apm_debug_logging(); - srs_trace("Initialize TencentCloud APM, team=%s, token=%dB, endpoint=%s, service_name=%s, debug_logging=%d", team_.c_str(), token_.length(), endpoint_.c_str(), service_name_.c_str(), debug_logging_); - - // Check authentication, the team or token. - if (team_.empty()) { - return srs_error_new(ERROR_APM_AUTH, "No authentication team for APM"); - } - if (token_.empty()) { - return srs_error_new(ERROR_APM_AUTH, "No authentication token for APM"); - } - - // Please note that 4317 is for GRPC/HTTP2, while SRS only support HTTP and the port shoule be 55681. - if (srs_strings_contains(endpoint_, ":4317")) { - return srs_error_new(ERROR_APM_ENDPOINT, "Port 4317 is for GRPC over HTTP2 for APM"); - } - - return err; -} - -srs_error_t SrsApmClient::report() -{ - srs_error_t err = do_report(); - if (err != srs_success) { - return srs_error_wrap(err, "team=%s, token=%dB", team_.c_str(), token_.length()); - } - - return err; -} - -srs_error_t SrsApmClient::do_report() -{ - srs_error_t err = srs_success; - - if (spans_.empty()) - return err; - - // Update statistaic for APM. - nn_spans_ += spans_.size(); - - SrsUniquePtr sugar(new SrsOtelExportTraceServiceRequest()); - - SrsOtelResourceSpans *rs = sugar->append(); - // See https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/resource/semantic_conventions - rs->resource()->add_addr(SrsOtelAttribute::kv("service.name", service_name_)); - // For Tencent Cloud APM authentication, see https://console.cloud.tencent.com/apm/monitor/access - rs->resource()->add_addr(SrsOtelAttribute::kv("token", token_)); - // For Tencent Cloud APM debugging, see https://console.cloud.tencent.com/apm/monitor/team - rs->resource()->add_addr(SrsOtelAttribute::kv("tapm.team", team_)); - - SrsOtelScopeSpans *spans = rs->append(); - spans->scope()->name_ = "srs"; - spans->swap(spans_); - - // Send out over HTTP1. - uint64_t size = sugar->nb_bytes(); - if (size >= 5 * 1024 * 1024) { - return srs_error_new(ERROR_APM_EXCEED_SIZE, "exceed 5MB actual %d", size); - } - - SrsUniquePtr buf(new char[size]); - - memset(buf.get(), 0, size); - SrsBuffer b(buf.get(), size); - if ((err = sugar->encode(&b)) != srs_success) { - return srs_error_wrap(err, "encode log"); - } - - string body(buf.get(), size); - - // Write a CLS log to service specified by url. - string url = "http://" + endpoint_ + "/v1/traces"; - - SrsHttpUri uri; - if ((err = uri.initialize(url)) != srs_success) { - return srs_error_wrap(err, "http: post failed. url=%s", url.c_str()); - } - - SrsHttpClient http; - if ((err = http.initialize(uri.get_schema(), uri.get_host(), uri.get_port())) != srs_success) { - return srs_error_wrap(err, "http: init client"); - } - - // Setup the request. - if (true) { - http.set_header("Content-Type", "application/x-protobuf"); - } - - string path = uri.get_path(); - if (!uri.get_query().empty()) { - path += "?" + uri.get_query(); - } - - // Start request and parse response. - ISrsHttpMessage *msg_raw = NULL; - if ((err = http.post(path, body, &msg_raw)) != srs_success) { - return srs_error_wrap(err, "http: client post"); - } - SrsUniquePtr msg(msg_raw); - - string res; - uint16_t code = msg->status_code(); - if ((err = msg->body_read_all(res)) != srs_success) { - return srs_error_wrap(err, "http: body read"); - } - - // ensure the http status is ok. - if (code != SRS_CONSTS_HTTP_OK && code != SRS_CONSTS_HTTP_Created) { - return srs_error_new(ERROR_HTTP_STATUS_INVALID, "http: status %d, body is %s", code, res.c_str()); - } - - if (debug_logging_) { - string server_id = SrsStatistic::instance()->server_id(); - srs_trace("APM write team=%s, token=%dB, logs=%d, size=%dB, server_id=%s", team_.c_str(), token_.length(), spans->size(), body.length(), server_id.c_str()); - } - - return err; -} - -bool SrsApmClient::enabled() -{ - return enabled_; -} - -uint64_t SrsApmClient::nn_spans() -{ - return nn_spans_; -} - -ISrsApmSpan *SrsApmClient::span(const std::string &name) -{ - if (!enabled_) - return new ISrsApmSpan(); - return new SrsApmSpan(name); -} - -ISrsApmSpan *SrsApmClient::dummy() -{ - return new ISrsApmSpan(); -} - -ISrsApmSpan *SrsApmClient::extract(ISrsApmSpan *v, SrsAmf0Object *h) -{ - SrsApmSpan *span = dynamic_cast(v); - if (span) - span->extract(h); - return v; -} - -ISrsApmSpan *SrsApmClient::inject(ISrsApmSpan *v, SrsAmf0Object *h) -{ - SrsApmSpan *span = dynamic_cast(v); - if (span) - span->inject(h); - return v; -} - -void SrsApmClient::store(ISrsApmSpan *v) -{ - SrsApmSpan *span = dynamic_cast(v); - if (span) - span->store(); -} - -ISrsApmSpan *SrsApmClient::load() -{ - static ISrsApmSpan *dummy = new ISrsApmSpan(); - ISrsApmSpan *span = SrsApmSpan::load(); - return span ? span : dummy; -} - -void SrsApmClient::snapshot(SrsOtelSpan *span) -{ - spans_.push_back(span); -} -#endif diff --git a/trunk/src/app/srs_app_tencentcloud.hpp b/trunk/src/app/srs_app_tencentcloud.hpp deleted file mode 100644 index 193b516f9..000000000 --- a/trunk/src/app/srs_app_tencentcloud.hpp +++ /dev/null @@ -1,609 +0,0 @@ -// -// Copyright (c) 2013-2025 The SRS Authors -// -// SPDX-License-Identifier: MIT -// - -#ifndef SRS_APP_TENCENTCLOUD_HPP -#define SRS_APP_TENCENTCLOUD_HPP - -#include -#ifdef SRS_APM - -#include - -#include -#include - -class SrsBuffer; -class SrsClsLogGroupList; -class SrsClsLogGroup; -class SrsClsLog; -class SrsOtelSpan; -class SrsApmContext; -class SrsAmf0Object; -class SrsApmSpan; -class SrsOtelResourceSpans; -class SrsOtelResource; -class SrsOtelScopeSpans; -class SrsOtelAttribute; -class SrsOtelAnyValue; -class SrsOtelScope; -class SrsOtelStatus; -class SrsOtelEvent; -class SrsOtelLink; - -class SrsClsSugar : public ISrsEncoder -{ -private: - SrsClsLog *log_; - SrsClsLogGroup *log_group_; - SrsClsLogGroupList *log_groups_; - -public: - SrsClsSugar(); - virtual ~SrsClsSugar(); - -public: - virtual uint64_t nb_bytes(); - srs_error_t encode(SrsBuffer *b); - -public: - bool empty(); - SrsClsSugar *kv(std::string k, std::string v); -}; - -class SrsClsSugars : public ISrsEncoder -{ -private: - std::vector sugars; - -public: - SrsClsSugars(); - virtual ~SrsClsSugars(); - -public: - virtual uint64_t nb_bytes(); - srs_error_t encode(SrsBuffer *b); - -public: - SrsClsSugar *create(); - SrsClsSugars *slice(int max_size); - bool empty(); - int size(); -}; - -class SrsClsClient -{ -private: - bool enabled_; - bool stat_heartbeat_; - bool stat_streams_; - bool debug_logging_; - int heartbeat_ratio_; - int streams_ratio_; - std::string label_; - std::string tag_; - -private: - std::string secret_id_; - std::string endpoint_; - std::string topic_; - -private: - SrsClsSugars *sugars_; - uint64_t nn_logs_; - -public: - SrsClsClient(); - virtual ~SrsClsClient(); - -public: - bool enabled(); - std::string label(); - std::string tag(); - uint64_t nn_logs(); - -public: - srs_error_t initialize(); - srs_error_t report(); - -private: - srs_error_t do_send_logs(ISrsEncoder *sugar, int count, int total); - srs_error_t send_logs(SrsClsSugars *sugars); - srs_error_t dump_summaries(SrsClsSugars *sugars); - srs_error_t dump_streams(SrsClsSugars *sugars); -}; - -extern SrsClsClient *_srs_cls; - -enum SrsApmKind { - SrsApmKindUnspecified = 0, - SrsApmKindInternal = 1, - SrsApmKindServer = 2, - SrsApmKindClient = 3, - SrsApmKindProducer = 4, - SrsApmKindConsumer = 5, -}; - -enum SrsApmStatus { - SrsApmStatusUnset = 0, - SrsApmStatusOk = 1, - SrsApmStatusError = 2, -}; - -class SrsOtelExportTraceServiceRequest : public ISrsEncoder -{ -private: - // repeated opentelemetry.proto.trace.v1.ResourceSpans resource_spans = 1; - std::vector spans_; - -public: - SrsOtelExportTraceServiceRequest(); - virtual ~SrsOtelExportTraceServiceRequest(); - -public: - SrsOtelResourceSpans *append(); - -public: - virtual uint64_t nb_bytes(); - srs_error_t encode(SrsBuffer *b); -}; - -class SrsOtelResourceSpans : public ISrsEncoder -{ -private: - // opentelemetry.proto.resource.v1.Resource resource = 1; - SrsOtelResource *resource_; - // repeated ScopeSpans scope_spans = 2; - std::vector spans_; - -public: - SrsOtelResourceSpans(); - virtual ~SrsOtelResourceSpans(); - -public: - SrsOtelResource *resource(); - SrsOtelScopeSpans *append(); - -public: - virtual uint64_t nb_bytes(); - srs_error_t encode(SrsBuffer *b); -}; - -class SrsOtelResource : public ISrsEncoder -{ -private: - // repeated opentelemetry.proto.common.v1.KeyValue attributes = 1; - std::vector attributes_; - -public: - SrsOtelResource(); - virtual ~SrsOtelResource(); - -public: - SrsOtelResource *add_addr(SrsOtelAttribute *v); - -public: - virtual uint64_t nb_bytes(); - srs_error_t encode(SrsBuffer *b); -}; - -class SrsOtelAttribute : public ISrsEncoder -{ -private: - // string key = 1; - std::string key_; - // AnyValue value = 2; - SrsOtelAnyValue *value_; - -private: - SrsOtelAttribute(); - -public: - virtual ~SrsOtelAttribute(); - -public: - const std::string &key(); - -public: - static SrsOtelAttribute *kv(std::string k, std::string v); - static SrsOtelAttribute *kvi(std::string k, int64_t v); - -public: - virtual uint64_t nb_bytes(); - srs_error_t encode(SrsBuffer *b); -}; - -class SrsOtelAnyValue : public ISrsEncoder -{ -private: - // Default to string(1). Please change it if use other value, such as int(3). - uint8_t used_field_id_; - -private: - // string string_value = 1; - std::string string_value_; - // bool bool_value = 2; - // int64 int_value = 3; - int64_t int_value_; - // double double_value = 4; - // ArrayValue array_value = 5; - // KeyValueList kvlist_value = 6; - // bytes bytes_value = 7; -public: - SrsOtelAnyValue(); - virtual ~SrsOtelAnyValue(); - -public: - SrsOtelAnyValue *set_string(const std::string &v); - SrsOtelAnyValue *set_int(int64_t v); - -public: - virtual uint64_t nb_bytes(); - srs_error_t encode(SrsBuffer *b); -}; - -class SrsOtelScopeSpans : public ISrsEncoder -{ -private: - // opentelemetry.proto.common.v1.InstrumentationScope scope = 1; - SrsOtelScope *scope_; - // repeated Span spans = 2; - std::vector spans_; - -public: - SrsOtelScopeSpans(); - virtual ~SrsOtelScopeSpans(); - -public: - SrsOtelScope *scope(); - SrsOtelScopeSpans *swap(std::vector &spans); - int size(); - -public: - virtual uint64_t nb_bytes(); - srs_error_t encode(SrsBuffer *b); -}; - -class SrsOtelScope : public ISrsEncoder -{ -public: - // string name = 1; - std::string name_; - // string version = 2; - // repeated KeyValue attributes = 3; - // uint32 dropped_attributes_count = 4; -public: - SrsOtelScope(); - virtual ~SrsOtelScope(); - -public: - virtual uint64_t nb_bytes(); - srs_error_t encode(SrsBuffer *b); -}; - -class SrsOtelSpan : public ISrsEncoder -{ -public: - // bytes trace_id = 1; // This field is required. - std::string trace_id_; - // bytes span_id = 2; // This field is required. - std::string span_id_; - // string trace_state = 3; - // bytes parent_span_id = 4; - std::string parent_span_id_; - // string name = 5; // This field is required. - std::string name_; - // SpanKind kind = 6; - SrsApmKind kind_; - // fixed64 start_time_unix_nano = 7; - int64_t start_time_unix_nano_; - // fixed64 end_time_unix_nano = 8; - int64_t end_time_unix_nano_; - // repeated opentelemetry.proto.common.v1.KeyValue attributes = 9; - std::vector attributes_; - // uint32 dropped_attributes_count = 10; - // repeated Event events = 11; - std::vector events_; - // uint32 dropped_events_count = 12; - // repeated Link links = 13; - std::vector links_; - // uint32 dropped_links_count = 14; - // Status status = 15; - SrsOtelStatus *status_; - -public: - SrsOtelSpan(); - virtual ~SrsOtelSpan(); - -public: - SrsOtelAttribute *attr(const std::string k); - -public: - virtual uint64_t nb_bytes(); - srs_error_t encode(SrsBuffer *b); -}; - -class SrsOtelEvent : public ISrsEncoder -{ -public: - // fixed64 time_unix_nano = 1; - int64_t time_; - // string name = 2; - std::string name_; - // repeated opentelemetry.proto.common.v1.KeyValue attributes = 3; - std::vector attributes_; - // uint32 dropped_attributes_count = 4; -public: - SrsOtelEvent(); - virtual ~SrsOtelEvent(); - -public: - static SrsOtelEvent *create(std::string v); - SrsOtelEvent *add_attr(SrsOtelAttribute *v); - -public: - virtual uint64_t nb_bytes(); - srs_error_t encode(SrsBuffer *b); -}; - -class SrsOtelLink : public ISrsEncoder -{ -private: - // bytes trace_id = 1; - std::string trace_id_; - // bytes span_id = 2; - std::string span_id_; - // string trace_state = 3; - // repeated opentelemetry.proto.common.v1.KeyValue attributes = 4; - // uint32 dropped_attributes_count = 5; -private: - SrsOtelLink(); - -public: - virtual ~SrsOtelLink(); - -public: - static SrsOtelLink *create(); - SrsOtelLink *set_id(const std::string &trace_id, const std::string &span_id); - -public: - virtual uint64_t nb_bytes(); - srs_error_t encode(SrsBuffer *b); -}; - -class SrsOtelStatus : public ISrsEncoder -{ -public: - // string message = 2; - std::string message_; - // StatusCode code = 3; - SrsApmStatus code_; - -public: - SrsOtelStatus(); - virtual ~SrsOtelStatus(); - -public: - virtual uint64_t nb_bytes(); - srs_error_t encode(SrsBuffer *b); -}; - -class SrsApmContext -{ -private: - friend class SrsApmSpan; - -private: - SrsApmSpan *span_; - SrsApmContext *parent_; - std::vector childs_; - // Encode the id in hex string. - std::string str_trace_id_; - std::string str_span_id_; - -private: - std::string name_; - SrsApmKind kind_; - std::string trace_id_; - std::string span_id_; - // Note that parent span id might not be empty, while parent might be NULL, when extract span from propagator. - std::string parent_span_id_; - srs_utime_t start_time_; - SrsApmStatus status_; - std::string description_; - srs_error_t err_; - std::vector attributes_; - std::vector links_; - -private: - bool ended_; - -private: - SrsApmContext(const std::string &name); - -public: - virtual ~SrsApmContext(); - -private: - // Update the trace id and format it as hex string id. - void set_trace_id(std::string v); - // Update the span id and format it as hex string id. - void set_span_id(std::string v); - -public: - const char *format_trace_id(); - const char *format_span_id(); - SrsApmContext *root(); - void set_parent(SrsApmContext *parent); - void set_status(SrsApmStatus status, const std::string &description); - bool all_ended(); - int count_spans(); - void update_trace_id(std::string v); - void link(SrsApmContext *to); - void end(); -}; - -class ISrsApmSpan -{ -private: - friend class SrsApmClient; - -public: - ISrsApmSpan() - { - } - virtual ~ISrsApmSpan() - { - } - -public: - // Get the formatted trace ID in hex string. - virtual const char *format_trace_id() - { - return ""; - } - // Get the formatted span ID in hex string. - virtual const char *format_span_id() - { - return ""; - } - -public: - // Set the name of span. - virtual ISrsApmSpan *set_name(const std::string &name) - { - return this; - } - // Set the kind of span. - virtual ISrsApmSpan *set_kind(SrsApmKind kind) - { - return this; - } - // Set span as child span of parent span. - virtual ISrsApmSpan *as_child(ISrsApmSpan *parent) - { - return this; - } - // Set the status of span, and error description by fmt. - // Note that ignore description except for error status. - virtual ISrsApmSpan *set_status(SrsApmStatus status, const std::string &description) - { - return this; - } - // RecordError will record err as an exception span event for this span. An - // additional call to SetStatus is required if the Status of the Span should - // be set to Error, as this method does not change the Span status. If this - // span is not being recorded or err is nil then this method does nothing. - virtual ISrsApmSpan *record_error(srs_error_t err) - { - return this; - } - // Add an attribute with all string kv to span. - virtual ISrsApmSpan *attr(const std::string &k, const std::string &v) - { - return this; - } - // Link with another span. - virtual ISrsApmSpan *link(ISrsApmSpan *span) - { - return this; - } - // End the span, snapshot and upload(in a while) a otel span to APM server. - virtual ISrsApmSpan *end() - { - return this; - } -}; - -class SrsApmSpan : public ISrsApmSpan -{ -private: - friend class SrsApmContext; - friend class SrsApmClient; - -private: - bool child_; - SrsApmContext *ctx_; - -private: - SrsApmSpan(const std::string &name); - -public: - virtual ~SrsApmSpan(); - // Span operations. -public: - const char *format_trace_id(); - const char *format_span_id(); - ISrsApmSpan *set_name(const std::string &name); - ISrsApmSpan *set_kind(SrsApmKind kind); - ISrsApmSpan *as_child(ISrsApmSpan *parent); - ISrsApmSpan *set_status(SrsApmStatus status, const std::string &description); - ISrsApmSpan *record_error(srs_error_t err); - ISrsApmSpan *attr(const std::string &k, const std::string &v); - ISrsApmSpan *link(ISrsApmSpan *span); - ISrsApmSpan *end(); - // Inject or extract for propagator. -private: - ISrsApmSpan *extract(SrsAmf0Object *h); - ISrsApmSpan *inject(SrsAmf0Object *h); - std::string text_propagator(); - // Store or load with coroutine context. -private: - ISrsApmSpan *store(); - static ISrsApmSpan *load(); -}; - -class SrsApmClient -{ -private: - bool enabled_; - uint64_t nn_spans_; - std::string team_; - std::string token_; - std::string endpoint_; - std::string service_name_; - bool debug_logging_; - std::vector spans_; - -public: - SrsApmClient(); - virtual ~SrsApmClient(); - -public: - srs_error_t initialize(); - srs_error_t report(); - -private: - srs_error_t do_report(); - -public: - bool enabled(); - uint64_t nn_spans(); - -public: - // Create a span with specified name. - ISrsApmSpan *span(const std::string &name); - // Create dummy span for default. - ISrsApmSpan *dummy(); - -public: - // Extract and inject for propagator. - ISrsApmSpan *extract(ISrsApmSpan *v, SrsAmf0Object *h); - ISrsApmSpan *inject(ISrsApmSpan *v, SrsAmf0Object *h); - // Store the span to coroutine context. - void store(ISrsApmSpan *span); - // Get or load span from coroutine context. - // Note that a dummy span will be returned if no span in coroutine context. - // Note that user should never free the returned span. - ISrsApmSpan *load(); - // Internal APIs. -public: - void snapshot(SrsOtelSpan *span); -}; - -extern SrsApmClient *_srs_apm; - -#endif -#endif diff --git a/trunk/src/core/srs_core_version7.hpp b/trunk/src/core/srs_core_version7.hpp index d4b15fd68..238874436 100644 --- a/trunk/src/core/srs_core_version7.hpp +++ b/trunk/src/core/srs_core_version7.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 7 #define VERSION_MINOR 0 -#define VERSION_REVISION 65 +#define VERSION_REVISION 66 #endif \ No newline at end of file diff --git a/trunk/src/main/srs_main_server.cpp b/trunk/src/main/srs_main_server.cpp index 36b374421..ae0c0caad 100644 --- a/trunk/src/main/srs_main_server.cpp +++ b/trunk/src/main/srs_main_server.cpp @@ -453,7 +453,6 @@ srs_error_t run_directly_or_daemon() return err; } -#include srs_error_t run_hybrid_server() { srs_error_t err = srs_success; @@ -477,12 +476,6 @@ srs_error_t run_hybrid_server() return srs_error_wrap(err, "init circuit breaker"); } -#ifdef SRS_APM - // When startup, create a span for server information. - ISrsApmSpan *span = _srs_apm->span("main")->set_kind(SrsApmKindServer); - srs_freep(span); -#endif - // Should run util hybrid servers all done. if ((err = _srs_hybrid->run()) != srs_success) { return srs_error_wrap(err, "hybrid run"); diff --git a/trunk/src/utest/srs_utest_config.cpp b/trunk/src/utest/srs_utest_config.cpp index d4a300882..cbbf1eae4 100644 --- a/trunk/src/utest/srs_utest_config.cpp +++ b/trunk/src/utest/srs_utest_config.cpp @@ -4792,78 +4792,6 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesCircuitBreaker) } } -VOID TEST(ConfigEnvTest, CheckEnvValuesTencentcloudCls) -{ - if (true) { - MockSrsConfig conf; - - SrsSetEnvConfig(conf, tencentcloud_cls_enabled, "SRS_TENCENTCLOUD_CLS_ENABLED", "on"); - EXPECT_TRUE(conf.get_tencentcloud_cls_enabled()); - - SrsSetEnvConfig(conf, tencentcloud_cls_label, "SRS_TENCENTCLOUD_CLS_LABEL", "xxx"); - EXPECT_STREQ("xxx", conf.get_tencentcloud_cls_label().c_str()); - - SrsSetEnvConfig(conf, tencentcloud_cls_tag, "SRS_TENCENTCLOUD_CLS_TAG", "xxx2"); - EXPECT_STREQ("xxx2", conf.get_tencentcloud_cls_tag().c_str()); - - SrsSetEnvConfig(conf, tencentcloud_cls_secret_id, "SRS_TENCENTCLOUD_CLS_SECRET_ID", "xxx3"); - EXPECT_STREQ("xxx3", conf.get_tencentcloud_cls_secret_id().c_str()); - - SrsSetEnvConfig(conf, tencentcloud_cls_secret_key, "SRS_TENCENTCLOUD_CLS_SECRET_KEY", "xxx4"); - EXPECT_STREQ("xxx4", conf.get_tencentcloud_cls_secret_key().c_str()); - - SrsSetEnvConfig(conf, tencentcloud_cls_endpoint, "SRS_TENCENTCLOUD_CLS_ENDPOINT", "yyy"); - EXPECT_STREQ("yyy", conf.get_tencentcloud_cls_endpoint().c_str()); - - SrsSetEnvConfig(conf, tencentcloud_cls_topic_id, "SRS_TENCENTCLOUD_CLS_TOPIC_ID", "yyy2"); - EXPECT_STREQ("yyy2", conf.get_tencentcloud_cls_topic_id().c_str()); - } - - if (true) { - MockSrsConfig conf; - - SrsSetEnvConfig(conf, tencentcloud_cls_debug_logging, "SRS_TENCENTCLOUD_CLS_DEBUG_LOGGING", "on"); - EXPECT_TRUE(conf.get_tencentcloud_cls_debug_logging()); - - SrsSetEnvConfig(conf, tencentcloud_cls_stat_heartbeat, "SRS_TENCENTCLOUD_CLS_STAT_HEARTBEAT", "off"); - EXPECT_FALSE(conf.get_tencentcloud_cls_stat_heartbeat()); - - SrsSetEnvConfig(conf, tencentcloud_cls_heartbeat_ratio, "SRS_TENCENTCLOUD_CLS_HEARTBEAT_RATIO", "2"); - EXPECT_EQ(2, conf.get_tencentcloud_cls_heartbeat_ratio()); - - SrsSetEnvConfig(conf, tencentcloud_cls_stat_streams, "SRS_TENCENTCLOUD_CLS_STAT_STREAMS", "off"); - EXPECT_FALSE(conf.get_tencentcloud_cls_stat_streams()); - - SrsSetEnvConfig(conf, tencentcloud_cls_streams_ratio, "SRS_TENCENTCLOUD_CLS_STREAMS_RATIO", "2"); - EXPECT_EQ(2, conf.get_tencentcloud_cls_streams_ratio()); - } -} - -VOID TEST(ConfigEnvTest, CheckEnvValuesTencentcloudApm) -{ - if (true) { - MockSrsConfig conf; - - SrsSetEnvConfig(conf, tencentcloud_apm_enabled, "SRS_TENCENTCLOUD_APM_ENABLED", "on"); - EXPECT_TRUE(conf.get_tencentcloud_apm_enabled()); - - SrsSetEnvConfig(conf, tencentcloud_apm_team, "SRS_TENCENTCLOUD_APM_TEAM", "xxx"); - EXPECT_STREQ("xxx", conf.get_tencentcloud_apm_team().c_str()); - - SrsSetEnvConfig(conf, tencentcloud_apm_token, "SRS_TENCENTCLOUD_APM_TOKEN", "xxx2"); - EXPECT_STREQ("xxx2", conf.get_tencentcloud_apm_token().c_str()); - - SrsSetEnvConfig(conf, tencentcloud_apm_endpoint, "SRS_TENCENTCLOUD_APM_ENDPOINT", "xxx3"); - EXPECT_STREQ("xxx3", conf.get_tencentcloud_apm_endpoint().c_str()); - - SrsSetEnvConfig(conf, tencentcloud_apm_service_name, "SRS_TENCENTCLOUD_APM_SERVICE_NAME", "srs"); - EXPECT_STREQ("srs", conf.get_tencentcloud_apm_service_name().c_str()); - - SrsSetEnvConfig(conf, tencentcloud_apm_debug_logging, "SRS_TENCENTCLOUD_APM_DEBUG_LOGGING", "on"); - EXPECT_TRUE(conf.get_tencentcloud_apm_debug_logging()); - } -} - VOID TEST(ConfigEnvTest, CheckEnvValuesExporter) { if (true) {