LCOV - code coverage report
Current view: top level - src/extension - discovery_reporter.cc (source / functions) Hit Total Coverage
Test: vlink Lines: 125 137 91.2 %
Date: 2026-09-30 18:30:16 Functions: 19 22 86.4 %
Branches: 111 224 49.6 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2026 by Thun Lu. All rights reserved.
       3                 :            :  * Author: Thun Lu <thun.lu@zohomail.cn>
       4                 :            :  * Repo:   https://github.com/thun-res/vlink
       5                 :            :  *  _    __   __      _           __
       6                 :            :  * | |  / /  / /     (_) ____    / /__
       7                 :            :  * | | / /  / /     / / / __ \  / //_/
       8                 :            :  * | |/ /  / /___  / / / / / / / ,<
       9                 :            :  * |___/  /_____/ /_/ /_/ /_/ /_/|_|
      10                 :            :  *
      11                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
      12                 :            :  * you may not use this file except in compliance with the License.
      13                 :            :  * You may obtain a copy of the License at
      14                 :            :  *
      15                 :            :  *     http://www.apache.org/licenses/LICENSE-2.0
      16                 :            :  *
      17                 :            :  * Unless required by applicable law or agreed to in writing, software
      18                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      19                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      20                 :            :  * See the License for the specific language governing permissions and
      21                 :            :  * limitations under the License.
      22                 :            :  */
      23                 :            : 
      24                 :            : #include "./extension/discovery_reporter.h"
      25                 :            : 
      26                 :            : #include <cstring>
      27                 :            : #include <map>
      28                 :            : #include <memory>
      29                 :            : #include <mutex>
      30                 :            : #include <string>
      31                 :            : #include <tuple>
      32                 :            : #include <unordered_set>
      33                 :            : #include <utility>
      34                 :            : #include <vector>
      35                 :            : 
      36                 :            : #include "./base/cpu_profiler.h"
      37                 :            : #include "./base/helpers.h"
      38                 :            : #include "./base/logger.h"
      39                 :            : #include "./base/utils.h"
      40                 :            : #include "./extension/discovery_viewer.h"
      41                 :            : #include "./impl/node_impl.h"
      42                 :            : #include "./impl/types.h"
      43                 :            : #include "./version.h"
      44                 :            : 
      45                 :            : #if __has_include(<unistd.h>)
      46                 :            : #include <unistd.h>
      47                 :            : #endif
      48                 :            : 
      49                 :            : #ifdef _WIN32
      50                 :            : #include <Winsock2.h>
      51                 :            : #include <ws2tcpip.h>
      52                 :            : #else
      53                 :            : #include <arpa/inet.h>
      54                 :            : #include <netinet/in.h>
      55                 :            : #include <sys/socket.h>
      56                 :            : #endif
      57                 :            : 
      58                 :            : #define VLINK_DISCOVERY_MULTICAST 1
      59                 :            : #define VLINK_DISCOVERY_OFFLINE 0
      60                 :            : 
      61                 :            : namespace vlink {
      62                 :            : 
      63                 :            : #ifdef _WIN32
      64                 :            : using SocketHandle = SOCKET;
      65                 :            : static constexpr SocketHandle kInvalidSocket = INVALID_SOCKET;
      66                 :            : #else
      67                 :            : using SocketHandle = int;
      68                 :            : static constexpr SocketHandle kInvalidSocket = -1;
      69                 :            : #endif
      70                 :            : 
      71                 :            : [[maybe_unused]] static constexpr int kReportFirstInterval = 100;
      72                 :            : [[maybe_unused]] static constexpr int kReportInterval = 500;
      73                 :            : [[maybe_unused]] static constexpr size_t kMaxTaskSize = 10000U;
      74                 :            : [[maybe_unused]] static constexpr uint32_t kMaxElapsedTime = 1000;
      75                 :            : [[maybe_unused]] static constexpr int kInterfaceWarnInterval = 60000;
      76                 :            : [[maybe_unused]] static constexpr int kSendTTL = 3;
      77                 :            : [[maybe_unused]] static constexpr int kMaxMtuSize = 1450;
      78                 :            : 
      79                 :            : #if VLINK_DISCOVERY_MULTICAST
      80                 :            : [[maybe_unused]] static constexpr const char* kBroadcastAddress = "239.255.0.100";
      81                 :            : #else
      82                 :            : [[maybe_unused]] static constexpr const char* kBroadcastAddress = "255.255.255.255";
      83                 :            : #endif
      84                 :            : 
      85                 :            : template <typename T>
      86                 :       1119 : [[maybe_unused]] static std::string_view convert_type(const T& t) {
      87   [ +  +  +  +  :       1119 :   switch (t) {
                +  +  - ]
      88                 :         54 :     case kServer:
      89                 :         54 :       return "Ser";
      90                 :        147 :     case kClient:
      91                 :        147 :       return "Cli";
      92                 :        102 :     case kPublisher:
      93                 :        102 :       return "Pub";
      94                 :        628 :     case kSubscriber:
      95                 :        628 :       return "Sub";
      96                 :         60 :     case kSetter:
      97                 :         60 :       return "Set";
      98                 :        128 :     case kGetter:
      99                 :        128 :       return "Get";
     100                 :            :     default:         // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     101                 :            :       return "Unk";  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     102                 :            :   }
     103                 :            : }
     104                 :            : 
     105                 :        165 : static void send_message_list(SocketHandle sock, const sockaddr_in& address, const std::vector<std::string>& list) {
     106         [ +  + ]:        312 :   for (const auto& message : list) {
     107   [ +  -  -  + ]:        147 :     if VUNLIKELY (::sendto(sock, message.c_str(), message.length(), 0,
     108                 :            :                            reinterpret_cast<const struct sockaddr*>(&address), sizeof(address)) < 0) {
     109                 :            :       Utils::yield_cpu();  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     110                 :            :       continue;            // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     111                 :            :     }
     112                 :            :   }
     113                 :        165 : }
     114                 :            : 
     115                 :          0 : [[maybe_unused]] static void send_multicast_list(SocketHandle sock, const sockaddr_in& address,
     116                 :            :                                                  const std::vector<std::string>& ip_list,
     117                 :            :                                                  const std::vector<std::string>& message_list) {
     118         [ #  # ]:          0 :   for (const auto& ip : ip_list) {
     119                 :            :     in_addr interface_addr;
     120                 :          0 :     interface_addr.s_addr = inet_addr(ip.c_str());
     121                 :            : 
     122         [ #  # ]:          0 :     if VUNLIKELY (::setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, reinterpret_cast<const char*>(&interface_addr),
     123                 :            :                                sizeof(interface_addr)) < 0) {
     124   [ #  #  #  #  :          0 :       VLOG_W_EVERY_MS(kInterfaceWarnInterval, "DiscoveryReporter: Failed to set multicast interface [", ip, "].");
                   #  # ]
     125                 :          0 :       continue;
     126                 :          0 :     }
     127                 :            : 
     128         [ #  # ]:          0 :     send_message_list(sock, address, message_list);
     129                 :            :   }
     130                 :          0 : }
     131                 :            : 
     132                 :            : // DiscoveryReporter::Impl
     133                 :            : struct DiscoveryReporter::Impl final {
     134                 :            :   std::unordered_set<NodeImpl*> info_set;
     135                 :            :   std::mutex mtx;
     136                 :            :   std::vector<std::string> message_list;
     137                 :            :   Timer timer;
     138                 :            :   std::string runtime_version;
     139                 :            :   std::string local_message;
     140                 :            :   bool is_profiler_enabled{false};
     141                 :            :   int64_t seq{0};
     142                 :            : 
     143                 :            :   SocketHandle sock{kInvalidSocket};
     144                 :            :   sockaddr_in address;
     145                 :            :   std::vector<std::string> ip_list;
     146                 :            : #ifdef _WIN32
     147                 :            :   bool winsock_initialized{false};
     148                 :            : #endif
     149                 :            : };
     150                 :            : 
     151         [ +  - ]:         40 : DiscoveryReporter::DiscoveryReporter() : impl_(std::make_unique<Impl>()) {
     152   [ +  -  +  - ]:         40 :   set_name("DiscoveryReporter");
     153                 :            : 
     154   [ +  -  +  - ]:         80 :   const std::string native_discovery = Utils::get_env("VLINK_DISCOVER_NATIVE");
     155                 :            : 
     156         [ -  + ]:         40 :   if (native_discovery == "1") {
     157         [ #  # ]:          0 :     impl_->ip_list.emplace_back("127.0.0.1");
     158                 :            :   } else {
     159   [ +  -  +  - ]:         40 :     impl_->ip_list = Helpers::split_any(Utils::get_env("VLINK_DISCOVER_IP"));
     160                 :            :   }
     161                 :            : 
     162                 :         40 :   impl_->runtime_version = Version{VLINK_VERSION_MAJOR, VLINK_VERSION_MINOR, VLINK_VERSION_PATCH}.to_string();
     163                 :            : 
     164                 :         40 :   impl_->local_message =
     165   [ +  -  +  -  :         80 :       Helpers::escape_field(get_host_name()) + ":" + Utils::get_pid_str() + ":" + Helpers::escape_field(get_app_name());
          +  -  +  -  +  
                -  +  - ]
     166                 :            : 
     167                 :         40 :   impl_->is_profiler_enabled = CpuProfiler::is_global_enabled();
     168                 :            : 
     169                 :            : #ifdef _WIN32
     170                 :            :   ::WSADATA wsa_data;
     171                 :            : 
     172                 :            :   if VUNLIKELY (::WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0) {
     173                 :            :     VLOG_F("DiscoveryReporter: Failed to initialize winsock.");
     174                 :            :     return;
     175                 :            :   }
     176                 :            : 
     177                 :            :   impl_->winsock_initialized = true;
     178                 :            : #endif
     179                 :         40 :   impl_->sock = ::socket(AF_INET, SOCK_DGRAM, 0);
     180                 :            : 
     181         [ -  + ]:         40 :   if VUNLIKELY (impl_->sock == kInvalidSocket) {
     182                 :            :     VLOG_F("DiscoveryReporter: Failed to create socket.");  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     183                 :            :     return;                                                 // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     184                 :            :   }
     185                 :            : 
     186                 :            : #ifdef IP_TTL
     187                 :            : 
     188         [ -  + ]:         40 :   if VUNLIKELY (::setsockopt(impl_->sock, IPPROTO_IP, IP_TTL, reinterpret_cast<const char*>(&kSendTTL),
     189                 :            :                              sizeof(kSendTTL)) < 0) {
     190                 :            :     VLOG_F("DiscoveryReporter: Failed to set TTL option.");  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     191                 :            :     return;                                                  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     192                 :            :   }
     193                 :            : #endif
     194                 :            : 
     195                 :            : #if !VLINK_DISCOVERY_MULTICAST
     196                 :            :   int enable_broadcast = 1;
     197                 :            : 
     198                 :            :   if VUNLIKELY (::setsockopt(impl_->sock, SOL_SOCKET, SO_BROADCAST, reinterpret_cast<const char*>(&enable_broadcast),
     199                 :            :                              sizeof(enable_broadcast)) < 0) {
     200                 :            :     VLOG_F("DiscoveryReporter: Failed to enable broadcast.");
     201                 :            :     return;
     202                 :            :   }
     203                 :            : #endif
     204                 :            : 
     205         [ +  - ]:         40 :   DiscoveryViewer::warn_listen_domain();
     206                 :            : 
     207                 :         40 :   std::memset(&impl_->address, 0, sizeof(impl_->address));
     208                 :            : 
     209                 :         40 :   impl_->address.sin_family = AF_INET;
     210                 :         40 :   impl_->address.sin_addr.s_addr = inet_addr(kBroadcastAddress);
     211         [ +  - ]:         40 :   impl_->address.sin_port = htons(DiscoveryViewer::get_listen_port());
     212                 :            : 
     213         [ +  - ]:         40 :   impl_->timer.set_interval(kReportFirstInterval);
     214         [ +  - ]:         40 :   impl_->timer.set_loop_count(Timer::kInfinite);
     215         [ +  - ]:         40 :   impl_->timer.attach(this);
     216   [ +  -  +  - ]:         40 :   impl_->timer.start([this]() {
     217                 :        126 :     send_report();
     218                 :            : 
     219                 :        126 :     impl_->timer.set_interval(kReportInterval);
     220                 :        126 :   });
     221                 :            : 
     222   [ +  -  +  - ]:         79 :   post_task([this]() { send_report(); });
     223         [ +  - ]:         40 : }
     224                 :            : 
     225                 :         79 : DiscoveryReporter::~DiscoveryReporter() {
     226                 :            : #ifdef _WIN32
     227                 :            :   if (Utils::is_terminating()) {
     228                 :            :     (void)impl_.release();
     229                 :            :     return;
     230                 :            :   }
     231                 :            : #endif
     232                 :            : 
     233                 :         40 :   impl_->timer.stop();
     234                 :            : 
     235                 :         40 :   quit(true);
     236                 :            : 
     237                 :         40 :   wait_for_quit();
     238                 :            : 
     239                 :            : #if VLINK_DISCOVERY_OFFLINE
     240                 :            :   send_offline();
     241                 :            : #endif
     242                 :            : 
     243         [ +  - ]:         40 :   if VLIKELY (impl_->sock != kInvalidSocket) {
     244                 :            : #ifdef _WIN32
     245                 :            :     ::closesocket(impl_->sock);
     246                 :            : #else
     247                 :         40 :     ::close(impl_->sock);
     248                 :            : #endif
     249                 :            : 
     250                 :         40 :     impl_->sock = kInvalidSocket;
     251                 :            :   }
     252                 :            : 
     253                 :            : #ifdef _WIN32
     254                 :            :   if VLIKELY (impl_->winsock_initialized) {
     255                 :            :     ::WSACleanup();
     256                 :            :     impl_->winsock_initialized = false;
     257                 :            :   }
     258                 :            : #endif
     259                 :         79 : }
     260                 :            : 
     261                 :        507 : void DiscoveryReporter::add(NodeImpl* node) {
     262         [ +  - ]:        507 :   std::lock_guard lock(impl_->mtx);
     263         [ +  - ]:        507 :   impl_->info_set.emplace(node);
     264                 :            : 
     265         [ +  - ]:        507 :   if (!impl_->is_profiler_enabled) {
     266         [ +  - ]:        507 :     rebuild_message();
     267                 :            :   }
     268                 :        507 : }
     269                 :            : 
     270                 :        507 : void DiscoveryReporter::remove(NodeImpl* node) {
     271         [ +  - ]:        507 :   std::lock_guard lock(impl_->mtx);
     272         [ +  - ]:        507 :   impl_->info_set.erase(node);
     273                 :            : 
     274         [ +  - ]:        507 :   if (!impl_->is_profiler_enabled) {
     275         [ +  - ]:        507 :     rebuild_message();
     276                 :            :   }
     277                 :        507 : }
     278                 :            : 
     279                 :        166 : size_t DiscoveryReporter::get_max_task_count() const { return kMaxTaskSize; }
     280                 :            : 
     281                 :        496 : uint32_t DiscoveryReporter::get_max_elapsed_time() const { return kMaxElapsedTime; }
     282                 :            : 
     283                 :         39 : void DiscoveryReporter::on_begin() { MessageLoop::on_begin(); }
     284                 :            : 
     285                 :         39 : void DiscoveryReporter::on_end() { MessageLoop::on_end(); }
     286                 :            : 
     287                 :       1014 : void DiscoveryReporter::rebuild_message() {
     288                 :       1014 :   impl_->message_list.clear();
     289                 :            : 
     290                 :       1014 :   std::string message_pack;
     291         [ +  - ]:       1014 :   message_pack.reserve(kMaxMtuSize);
     292                 :            : 
     293                 :       1014 :   std::map<std::tuple<int, std::string, std::string, SchemaType, bool>, std::pair<bool, double>> profiler_value_map;
     294                 :            : 
     295         [ -  + ]:       1014 :   if (impl_->is_profiler_enabled) {
     296                 :            :     // LCOV_EXCL_START GCOVR_EXCL_START
     297                 :            :     for (auto* node : impl_->info_set) {
     298                 :            :       const std::string& trim_url = Helpers::trim_string(node->url);
     299                 :            :       const std::string& trim_ser_type = Helpers::trim_string(node->ser_type);
     300                 :            : 
     301                 :            :       auto& value = profiler_value_map[std::make_tuple(
     302                 :            :                                            node->impl_type, trim_url, trim_ser_type, node->schema_type,
     303                 :            :                                            node->impl_type == kPublisher && node->get_property("proxy.bridge") == "1")]
     304                 :            :                         .second;
     305                 :            : 
     306                 :            :       if (node->profiler) {
     307                 :            :         value += node->profiler->restart();
     308                 :            :       }
     309                 :            :     }
     310                 :            :     // LCOV_EXCL_STOP GCOVR_EXCL_STOP
     311                 :            :   }
     312                 :            : 
     313         [ +  + ]:       2133 :   for (auto* node : impl_->info_set) {
     314                 :       1119 :     const std::string& trim_url = Helpers::trim_string(node->url);
     315                 :       1119 :     const std::string& trim_ser_type = Helpers::trim_string(node->ser_type);
     316                 :            : 
     317         [ -  + ]:       1119 :     if VUNLIKELY (trim_url.empty()) {
     318                 :            :       continue;  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     319                 :            :     }
     320                 :            : 
     321         [ -  + ]:       1119 :     if VUNLIKELY (trim_url.size() > 300) {
     322                 :            :       VLOG_F("DiscoveryReporter: Url is too long [", trim_url, "].");  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     323                 :            :       return;                                                          // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     324                 :            :     }
     325                 :            : 
     326         [ -  + ]:       1119 :     if VUNLIKELY (trim_ser_type.size() > 300) {
     327                 :            :       VLOG_F("DiscoveryReporter: Ser type is too long [", trim_ser_type, "].");  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     328                 :            :       return;                                                                    // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     329                 :            :     }
     330                 :            : 
     331                 :       1119 :     std::string message;
     332   [ +  -  +  - ]:       1119 :     message.append(convert_type(node->impl_type)).append(" ");
     333                 :            : 
     334   [ +  +  +  -  :       1119 :     const bool bridge = node->impl_type == kPublisher && node->get_property("proxy.bridge") == "1";
          +  -  -  +  +  
          +  +  +  +  +  
          -  -  -  -  -  
                      - ]
     335                 :            :     auto& profiler_result =
     336   [ +  -  +  - ]:       1119 :         profiler_value_map[std::make_tuple(node->impl_type, trim_url, trim_ser_type, node->schema_type, bridge)];
     337                 :            : 
     338         [ +  + ]:       1119 :     if (profiler_result.first) {
     339                 :        228 :       continue;
     340                 :            :     } else {
     341                 :        891 :       profiler_result.first = true;
     342                 :            : 
     343                 :        891 :       const std::string escaped_url = Helpers::escape_field(trim_url);
     344   [ +  +  +  -  :        891 :       const std::string escaped_ser_type = trim_ser_type.empty() ? "{}" : Helpers::escape_field(trim_ser_type);
             +  +  -  - ]
     345                 :            : 
     346   [ +  -  +  - ]:        891 :       message.append(escaped_url).append(" ");
     347   [ +  -  +  - ]:        891 :       message.append(escaped_ser_type).append(" ");
     348   [ +  -  +  -  :        891 :       message.append(std::to_string(static_cast<uint32_t>(node->schema_type))).append(" ");
                   +  - ]
     349         [ +  - ]:        891 :       message.append(impl_->local_message);
     350                 :            : 
     351         [ -  + ]:        891 :       if (impl_->is_profiler_enabled) {
     352                 :            :         message.append(":" + Helpers::double_to_string(profiler_result.second, 4));  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     353                 :            :       }
     354                 :            : 
     355         [ -  + ]:        891 :       if (bridge) {
     356         [ #  # ]:          0 :         message.append(" bridge=1");
     357                 :            :       }
     358                 :            : 
     359         [ +  - ]:        891 :       message.append("\n");
     360                 :        891 :     }
     361                 :            : 
     362         [ -  + ]:        891 :     if VUNLIKELY (message.size() > kMaxMtuSize) {
     363                 :            :       VLOG_F("DiscoveryReporter: Discovery message is too long [", trim_url, "].");  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     364                 :            :       return;                                                                        // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     365                 :            :     }
     366                 :            : 
     367         [ -  + ]:        891 :     if VUNLIKELY (message_pack.size() + message.size() > kMaxMtuSize) {
     368                 :            :       if VLIKELY (!message_pack.empty()) {               // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     369                 :            :         impl_->message_list.emplace_back(message_pack);  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     370                 :            :       }
     371                 :            : 
     372                 :            :       message_pack.clear();  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     373                 :            :     }
     374                 :            : 
     375         [ +  - ]:        891 :     message_pack.append(message);
     376   [ +  +  -  +  :       1575 :   }
             +  -  +  +  
                      - ]
     377                 :            : 
     378         [ +  + ]:       1014 :   if (!message_pack.empty()) {
     379         [ +  - ]:        617 :     impl_->message_list.emplace_back(std::move(message_pack));
     380                 :            :   }
     381   [ +  -  +  - ]:       1014 : }
     382                 :            : 
     383                 :        165 : void DiscoveryReporter::send_report() {
     384         [ +  - ]:        165 :   std::lock_guard lock(impl_->mtx);
     385                 :            : 
     386         [ -  + ]:        165 :   if (impl_->is_profiler_enabled) {
     387                 :            :     rebuild_message();  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     388                 :            :   }
     389                 :            : 
     390                 :            : #if VLINK_DISCOVERY_MULTICAST
     391         [ +  - ]:        165 :   if (impl_->ip_list.empty()) {
     392         [ +  - ]:        165 :     send_message_list(impl_->sock, impl_->address, impl_->message_list);
     393                 :            :   } else {
     394         [ #  # ]:          0 :     send_multicast_list(impl_->sock, impl_->address, impl_->ip_list, impl_->message_list);
     395                 :            :   }
     396                 :            : #else
     397                 :            :   send_message_list(impl_->sock, impl_->address, impl_->message_list);
     398                 :            : #endif
     399                 :            : 
     400                 :        165 :   ++impl_->seq;
     401                 :        165 : }
     402                 :            : 
     403                 :            : // LCOV_EXCL_START GCOVR_EXCL_START
     404                 :            : void DiscoveryReporter::send_offline() {
     405                 :            :   std::lock_guard lock(impl_->mtx);
     406                 :            : 
     407                 :            :   const std::vector<std::string> offline_list{"offline\n" + impl_->local_message};
     408                 :            : 
     409                 :            : #if VLINK_DISCOVERY_MULTICAST
     410                 :            :   if (impl_->ip_list.empty()) {
     411                 :            :     send_message_list(impl_->sock, impl_->address, offline_list);
     412                 :            :   } else {
     413                 :            :     send_multicast_list(impl_->sock, impl_->address, impl_->ip_list, offline_list);
     414                 :            :   }
     415                 :            : #else
     416                 :            :   send_message_list(impl_->sock, impl_->address, offline_list);
     417                 :            : #endif
     418                 :            : }
     419                 :            : // LCOV_EXCL_STOP GCOVR_EXCL_STOP
     420                 :            : 
     421                 :         40 : const std::string& DiscoveryReporter::get_host_name() {
     422                 :         40 :   static std::string host_name = [] {
     423                 :         40 :     std::string name = Utils::get_host_name();
     424                 :            : 
     425         [ -  + ]:         40 :     if (name.size() > 50) {
     426                 :            :       name.resize(50);  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     427                 :            :     }
     428                 :            : 
     429                 :         40 :     return name;
     430   [ +  -  +  -  :         40 :   }();
             +  -  -  - ]
     431                 :            : 
     432                 :         40 :   return host_name;
     433                 :            : }
     434                 :            : 
     435                 :         40 : const std::string& DiscoveryReporter::get_app_name() {
     436                 :         40 :   static std::string app_name = [] {
     437                 :         40 :     std::string name = Utils::get_app_name();
     438                 :            : 
     439         [ -  + ]:         40 :     if (name.size() > 50) {
     440                 :            :       name.resize(50);  // LCOV_EXCL_LINE GCOVR_EXCL_LINE
     441                 :            :     }
     442                 :            : 
     443                 :         40 :     return name;
     444   [ +  -  +  -  :         40 :   }();
             +  -  -  - ]
     445                 :            : 
     446                 :         40 :   return app_name;
     447                 :            : }
     448                 :            : 
     449                 :            : }  // namespace vlink

Generated by: LCOV version 1.14