LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-common/sandesh/library/cpp - sandesh.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 380 563 67.5 %
Date: 2026-11-09 02:10:49 Functions: 59 73 80.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : //
       7             : // sandesh.cc
       8             : //
       9             : // Sandesh Implementation
      10             : //
      11             : 
      12             : #include <boost/filesystem.hpp>
      13             : #include <boost/bind/bind.hpp>
      14             : #include <boost/foreach.hpp>
      15             : #include <boost/format.hpp>
      16             : #include <boost/algorithm/string/predicate.hpp>
      17             : 
      18             : #include <base/logging.h>
      19             : #include <base/parse_object.h>
      20             : #include <base/queue_task.h>
      21             : #include <base/address_util.h>
      22             : #include <http/http_session.h>
      23             : #include <io/tcp_session.h>
      24             : 
      25             : #include <sandesh/transport/TBufferTransports.h>
      26             : #include <sandesh/transport/TSimpleFileTransport.h>
      27             : #include <sandesh/protocol/TBinaryProtocol.h>
      28             : #include <sandesh/protocol/TProtocol.h>
      29             : 
      30             : #include <sandesh/sandesh_types.h>
      31             : #include <sandesh/sandesh.h>
      32             : #include <sandesh/sandesh_trace.h>
      33             : #include <sandesh/sandesh_uve_types.h>
      34             : #include "sandesh_statistics.h"
      35             : #include "sandesh_uve.h"
      36             : #include "sandesh_session.h"
      37             : #include "sandesh_http.h"
      38             : #include "sandesh_client.h"
      39             : #include "sandesh_connection.h"
      40             : #include "sandesh_state_machine.h"
      41             : 
      42             : #include <log4cplus/helpers/pointer.h>
      43             : #include <log4cplus/configurator.h>
      44             : #include <log4cplus/fileappender.h>
      45             : #include <log4cplus/syslogappender.h>
      46             : 
      47             : using boost::asio::ip::tcp;
      48             : using boost::asio::ip::address;
      49             : 
      50             : using namespace contrail::sandesh::protocol;
      51             : using namespace contrail::sandesh::transport;
      52             : using namespace log4cplus;
      53             : using namespace boost::placeholders;
      54             : 
      55             : // Statics
      56             : Sandesh::SandeshRole::type Sandesh::role_ = SandeshRole::Invalid;
      57             : bool Sandesh::enable_local_log_ = false;
      58             : bool Sandesh::enable_flow_log_ = false;
      59             : bool Sandesh::enable_session_syslog_ = false;
      60             : int Sandesh::http_port_ = 0;
      61             : bool Sandesh::enable_trace_print_ = false;
      62             : bool Sandesh::send_queue_enabled_ = true;
      63             : bool Sandesh::connect_to_collector_ = false;
      64             : bool Sandesh::disable_flow_collection_ = false;
      65             : bool Sandesh::disable_sending_all_ = false;
      66             : bool Sandesh::disable_sending_object_logs_ = false;
      67             : bool Sandesh::disable_sending_flows_ = false;
      68             : bool Sandesh::slo_to_collector_ = false;
      69             : bool Sandesh::sampled_to_collector_ = false;
      70             : bool Sandesh::slo_to_logger_ = false;
      71             : bool Sandesh::sampled_to_logger_ = false;
      72             : SandeshClient *Sandesh::client_ = NULL;
      73             : SandeshConfig Sandesh::config_;
      74             : std::unique_ptr<Sandesh::SandeshRxQueue> Sandesh::recv_queue_;
      75             : std::string Sandesh::module_;
      76             : std::string Sandesh::source_;
      77             : std::string Sandesh::node_type_;
      78             : std::string Sandesh::instance_id_;
      79             : int Sandesh::recv_task_id_ = -1;
      80             : SandeshContext* Sandesh::client_context_ = NULL;
      81             : Sandesh::SandeshCallback Sandesh::response_callback_ = 0;
      82             : SandeshLevel::type Sandesh::logging_level_ = SandeshLevel::INVALID;
      83             : SandeshLevel::type Sandesh::logging_ut_level_ =
      84             :     getenv("SANDSH_UT_DEBUG") ? SandeshLevel::SYS_DEBUG : SandeshLevel::UT_DEBUG;
      85             : std::string Sandesh::logging_category_;
      86             : EventManager* Sandesh::event_manager_ = NULL;
      87             : SandeshMessageStatistics Sandesh::msg_stats_;
      88             : std::mutex Sandesh::stats_mutex_;
      89             : log4cplus::Logger Sandesh::logger_ =
      90             :     log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("SANDESH"));
      91             : log4cplus::Logger Sandesh::slo_logger_ =
      92             :     log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("SLO_SESSION"));
      93             : log4cplus::Logger Sandesh::sampled_logger_ =
      94             :     log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("SAMPLED_SESSION"));
      95             : 
      96             : Sandesh::ModuleContextMap Sandesh::module_context_;
      97             : std::atomic<uint32_t> Sandesh::sandesh_send_ratelimit_;
      98             : 
      99             : const char *loggingPattern = "%D{%Y-%m-%d %a %H:%M:%S:%Q %Z} "
     100             :                              " %h [Thread %t, Pid %i]: %m%n";
     101             : 
     102          85 : const char * Sandesh::SandeshRoleToString(SandeshRole::type role) {
     103          85 :     switch (role) {
     104          83 :     case SandeshRole::Generator:
     105          83 :         return "Generator";
     106           0 :     case SandeshRole::Collector:
     107           0 :         return "Collector";
     108           2 :     case SandeshRole::Test:
     109           2 :         return "Test";
     110           0 :     case SandeshRole::Invalid:
     111           0 :         return "Invalid";
     112           0 :     default:
     113           0 :         return "Unknown";
     114             :     }
     115             : }
     116             : 
     117          86 : void Sandesh::InitReceive(int recv_task_inst) {
     118          86 :     assert(recv_task_id_ == -1);
     119          86 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     120          86 :     recv_task_id_ = scheduler->GetTaskId("sandesh::RecvQueue");
     121         172 :     recv_queue_.reset(new SandeshRxQueue(recv_task_id_, recv_task_inst,
     122          86 :             &Sandesh::ProcessRecv));
     123          86 : }
     124             : 
     125          37 : void Sandesh::InitClient(EventManager *evm, Endpoint server,
     126             :                          const SandeshConfig &config, bool periodicuve) {
     127          37 :     connect_to_collector_ = true;
     128          37 :     SANDESH_LOG(INFO, "SANDESH: CONNECT TO COLLECTOR: " <<
     129             :         connect_to_collector_);
     130             :     // Create and initialize the client
     131          37 :     assert(client_ == NULL);
     132          37 :     std::vector<Endpoint> collector_endpoints = boost::assign::list_of(server);
     133          37 :     client_ = new SandeshClient(evm, collector_endpoints, config,
     134          37 :                                 periodicuve);
     135          37 :     client_->Initiate();
     136          37 : }
     137             : 
     138          10 : static int32_t SandeshHttpCallback(SandeshRequest *rsnh) {
     139          10 :     return rsnh->Enqueue(Sandesh::recv_queue());
     140             : }
     141             : 
     142             : extern int PullSandeshGenStatsReq;
     143             : extern int PullSandeshUVE;
     144             : extern int PullSandeshTraceReq;
     145             : 
     146          88 : bool Sandesh::Initialize(SandeshRole::type role,
     147             :                          const std::string &module,
     148             :                          const std::string &source,
     149             :                          const std::string &node_type,
     150             :                          const std::string &instance_id,
     151             :                          EventManager *evm,
     152             :                          unsigned short http_port,
     153             :                          SandeshContext *client_context,
     154             :                          const SandeshConfig &config) {
     155          88 :     PullSandeshGenStatsReq = 1;
     156          88 :     PullSandeshUVE = 1;
     157          88 :     PullSandeshTraceReq = 1;
     158             : 
     159          88 :     if (role_ != SandeshRole::Invalid || role == SandeshRole::Invalid) {
     160           2 :         return true;
     161             :     }
     162             : 
     163          86 :     SANDESH_LOG(INFO, "SANDESH: ROLE             : " << SandeshRoleToString(role));
     164          86 :     SANDESH_LOG(INFO, "SANDESH: MODULE           : " << module);
     165          86 :     SANDESH_LOG(INFO, "SANDESH: SOURCE           : " << source);
     166          86 :     SANDESH_LOG(INFO, "SANDESH: NODE TYPE        : " << node_type);
     167          86 :     SANDESH_LOG(INFO, "SANDESH: INSTANCE ID      : " << instance_id);
     168          86 :     SANDESH_LOG(INFO, "SANDESH: HTTP SERVER PORT : " << http_port);
     169             : 
     170          86 :     role_           = role;
     171          86 :     module_         = module;
     172          86 :     source_         = source;
     173          86 :     node_type_      = node_type;
     174          86 :     instance_id_    = instance_id;
     175          86 :     client_context_ = client_context;
     176          86 :     config_         = config;
     177          86 :     event_manager_  = evm;
     178             : 
     179          86 :     set_send_rate_limit(config.system_logs_rate_limit);
     180          86 :     DisableSendingObjectLogs(config.disable_object_logs);
     181          86 :     InitReceive(Task::kTaskInstanceAny);
     182          86 :     bool success(SandeshHttp::Init(evm, module, http_port,
     183             :         &SandeshHttpCallback, &http_port_, config_));
     184          86 :     if (!success) {
     185           0 :         SANDESH_LOG(ERROR, "SANDESH: HTTP INIT FAILED (PORT " <<
     186             :             http_port << ")");
     187           0 :         return false;
     188             :     }
     189          86 :     RecordPort("http", module_, http_port_);
     190          86 :     return true;
     191             : }
     192             : 
     193          86 : void Sandesh::RecordPort(const std::string& name, const std::string& module, unsigned short port) {
     194             :     int fd;
     195          86 :     std::ostringstream myfifoss;
     196          86 :     myfifoss << "/tmp/" << module << "." << getppid() << "." << name << "_port";
     197          86 :     std::string myfifo = myfifoss.str();
     198          86 :     std::ostringstream hss;
     199          86 :     hss << port << "\n";
     200          86 :     std::string hstr = hss.str();
     201             : 
     202          86 :     fd = open(myfifo.c_str(), O_WRONLY | O_NONBLOCK);
     203          86 :     if (fd != -1) {
     204          44 :         SANDESH_LOG(INFO, "SANDESH: Write " << name << "_port " << port <<
     205             :                           "TO : " << myfifo);
     206          44 :         write(fd, hstr.c_str(), hstr.length());
     207          44 :         close(fd);
     208             :     } else {
     209          42 :         SANDESH_LOG(INFO, "SANDESH: NOT Writing " << name << "_port " << port <<
     210             :                           "TO : " << myfifo);
     211             :     }
     212          86 : }
     213             : 
     214          37 : bool Sandesh::ConnectToCollector(const std::string &collector_ip,
     215             :                                  int collector_port, bool periodicuve) {
     216          37 :     boost::system::error_code ec;
     217          37 :     address collector_addr = AddressFromString(collector_ip, &ec);
     218          37 :     if (ec) {
     219           0 :         SANDESH_LOG(ERROR, __func__ << ": Invalid collector address: " <<
     220             :                 collector_ip << " Error: " << ec);
     221           0 :         return false;
     222             :     }
     223             : 
     224          37 :     SANDESH_LOG(INFO, "SANDESH: COLLECTOR : " << collector_ip);
     225          37 :     SANDESH_LOG(INFO, "SANDESH: COLLECTOR PORT : " << collector_port);
     226             : 
     227          37 :     tcp::endpoint collector(collector_addr, collector_port);
     228          37 :     InitClient(event_manager_, collector, Sandesh::config(), periodicuve);
     229          37 :     return true;
     230             : }
     231             : 
     232           0 : void Sandesh::ReConfigCollectors(const std::vector<std::string>& collector_list) {
     233           0 :     if (client_) {
     234           0 :         client_->ReConfigCollectors(collector_list);
     235             :     }
     236           0 : }
     237             : 
     238          46 : bool Sandesh::InitClient(EventManager *evm,
     239             :                          const std::vector<std::string> &collectors,
     240             :                          const SandeshConfig &config) {
     241          46 :     connect_to_collector_ = true;
     242          46 :     SANDESH_LOG(INFO, "SANDESH: CONNECT TO COLLECTOR: " <<
     243             :         connect_to_collector_);
     244          46 :     std::vector<Endpoint> collector_endpoints;
     245         152 :     BOOST_FOREACH(const std::string &collector, collectors) {
     246          53 :         Endpoint ep;
     247          53 :         if (!MakeEndpoint(&ep, collector)) {
     248           0 :             SANDESH_LOG(ERROR, __func__ << ": Invalid collector address: " <<
     249             :                         collector);
     250           0 :             return false;
     251             :         }
     252          53 :         collector_endpoints.push_back(ep);
     253             :     }
     254          46 :     client_ = new SandeshClient(evm, collector_endpoints, config, true);
     255          46 :     client_->Initiate();
     256          46 :     return true;
     257          46 : }
     258             : 
     259          40 : bool Sandesh::InitGenerator(const std::string &module,
     260             :                             const std::string &source,
     261             :                             const std::string &node_type,
     262             :                             const std::string &instance_id,
     263             :                             EventManager *evm,
     264             :                             unsigned short http_port,
     265             :                             SandeshContext *client_context,
     266             :                             DerivedStats ds,
     267             :                             const SandeshConfig &config) {
     268          40 :     assert(SandeshUVETypeMaps::InitDerivedStats(ds));
     269          40 :     return Initialize(SandeshRole::Generator, module, source, node_type,
     270          40 :                       instance_id, evm, http_port, client_context, config);
     271             : }
     272             : 
     273          46 : bool Sandesh::InitGenerator(const std::string &module,
     274             :                             const std::string &source,
     275             :                             const std::string &node_type,
     276             :                             const std::string &instance_id,
     277             :                             EventManager *evm,
     278             :                             unsigned short http_port,
     279             :                             const std::vector<std::string> &collectors,
     280             :                             SandeshContext *client_context,
     281             :                             DerivedStats ds,
     282             :                             const SandeshConfig &config) {
     283          46 :     assert(SandeshUVETypeMaps::InitDerivedStats(ds));
     284          46 :     bool success(Initialize(SandeshRole::Generator, module, source, node_type,
     285             :                             instance_id, evm, http_port, client_context,
     286             :                             config));
     287          46 :     if (!success) {
     288           0 :         return false;
     289             :     }
     290          46 :     return InitClient(evm, collectors, config);
     291             : }
     292             : 
     293             : // Collector
     294           0 : bool Sandesh::InitCollector(const std::string &module,
     295             :                             const std::string &source,
     296             :                             const std::string &node_type,
     297             :                             const std::string &instance_id,
     298             :                             EventManager *evm,
     299             :                             const std::string &collector_ip, int collector_port,
     300             :                             unsigned short http_port,
     301             :                             SandeshContext *client_context,
     302             :                             const SandeshConfig &config) {
     303           0 :     bool success(Initialize(SandeshRole::Collector, module, source, node_type,
     304             :                             instance_id, evm, http_port, client_context,
     305             :                             config));
     306           0 :     if (!success) {
     307           0 :         return false;
     308             :     }
     309           0 :     return ConnectToCollector(collector_ip, collector_port, true);
     310             : }
     311             : 
     312           2 : bool Sandesh::InitGeneratorTest(const std::string &module,
     313             :                                 const std::string &source,
     314             :                                 const std::string &node_type,
     315             :                                 const std::string &instance_id,
     316             :                                 EventManager *evm,
     317             :                                 unsigned short http_port,
     318             :                                 SandeshContext *client_context,
     319             :                                 const SandeshConfig &config) {
     320           2 :     return Initialize(SandeshRole::Test, module, source, node_type,
     321           2 :                       instance_id, evm, http_port, client_context, config);
     322             : }
     323             : 
     324          83 : static void WaitForIdle() {
     325             :     static const int kTimeout = 15;
     326          83 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     327             : 
     328         167 :     for (int i = 0; i < (kTimeout * 1000); i++) {
     329         167 :         if (scheduler->IsEmpty()) {
     330          83 :             break;
     331             :         }
     332          84 :         usleep(1000);
     333             :     }
     334          83 : }
     335             : 
     336           9 : void Sandesh::SetDscpValue(uint8_t value) {
     337           9 :     SandeshClient *client = Sandesh::client();
     338           9 :     if (client) {
     339           0 :         client->SetDscpValue(value);
     340             :     }
     341           9 : }
     342             : 
     343          86 : void Sandesh::Uninit() {
     344             : 
     345             :     // Wait until all pending http session based tasks are cleaned up.
     346          86 :     long count = 60000;
     347          86 :     while (count--) {
     348          86 :         if (HttpSession::GetPendingTaskCount() == 0) break;
     349           0 :         usleep(1000);
     350             :     }
     351          86 :     SandeshHttp::Uninit();
     352          86 :     role_ = SandeshRole::Invalid;
     353          86 :     if (recv_queue_.get() != NULL) {
     354          86 :         recv_queue_->Shutdown();
     355          86 :         recv_queue_.reset(NULL);
     356          86 :         assert(recv_task_id_ != -1);
     357          86 :         recv_task_id_ = -1;
     358             :     } else {
     359           0 :         assert(recv_task_id_ == -1);
     360             :     }
     361          86 :     if (client_ != NULL) {
     362          83 :         client_->Shutdown();
     363         170 :         while (client()->IsSession()) usleep(100);
     364          83 :         WaitForIdle();
     365          83 :         client_->ClearSessions();
     366          83 :         TcpServerManager::DeleteServer(client_);
     367          83 :         client_ = NULL;
     368             :     }
     369          86 : }
     370             : 
     371          60 : void Sandesh::SetLoggingParams(bool enable_local_log, std::string category,
     372             :         std::string level, bool enable_trace_print, bool enable_flow_log,
     373             :         bool enable_session_syslog) {
     374          60 :     SetLocalLogging(enable_local_log);
     375          60 :     SetLoggingCategory(category);
     376          60 :     SetLoggingLevel(level);
     377          60 :     SetTracePrint(enable_trace_print);
     378          60 :     SetFlowLogging(enable_flow_log);
     379          60 :     SetSessionSyslogging(enable_session_syslog);
     380          60 : }
     381             : 
     382         273 : void Sandesh::SetLoggingParams(bool enable_local_log, std::string category,
     383             :         SandeshLevel::type level, bool enable_trace_print,
     384             :         bool enable_flow_log) {
     385         273 :     SetLocalLogging(enable_local_log);
     386         273 :     SetLoggingCategory(category);
     387         273 :     SetLoggingLevel(level);
     388         273 :     SetTracePrint(enable_trace_print);
     389         273 :     SetFlowLogging(enable_flow_log);
     390         273 : }
     391             : 
     392          60 : void Sandesh::SetLoggingLevel(std::string level) {
     393          60 :     SandeshLevel::type nlevel = StringToLevel(level);
     394          60 :     SetLoggingLevel(nlevel);
     395          60 : }
     396             : 
     397    12362651 : log4cplus::LogLevel SandeshLevelTolog4Level(
     398             :     SandeshLevel::type slevel) {
     399    12362651 :     switch (slevel) {
     400          24 :       case SandeshLevel::SYS_EMERG:
     401             :       case SandeshLevel::SYS_ALERT:
     402             :       case SandeshLevel::SYS_CRIT:
     403          24 :           return log4cplus::FATAL_LOG_LEVEL;
     404        5264 :       case SandeshLevel::SYS_ERR:
     405        5264 :           return log4cplus::ERROR_LOG_LEVEL;
     406       17480 :       case SandeshLevel::SYS_WARN:
     407             :       case SandeshLevel::SYS_NOTICE:
     408       17480 :           return log4cplus::WARN_LOG_LEVEL;
     409      795260 :       case SandeshLevel::SYS_INFO:
     410      795260 :           return log4cplus::INFO_LOG_LEVEL;
     411     4875652 :       case SandeshLevel::SYS_DEBUG:
     412     4875652 :           return log4cplus::DEBUG_LOG_LEVEL;
     413     6668971 :       default:
     414             :       case SandeshLevel::INVALID:
     415     6668971 :           return log4cplus::ALL_LOG_LEVEL;
     416             :     }
     417             : }
     418             : 
     419         334 : void Sandesh::SetLoggingLevel(SandeshLevel::type level) {
     420         334 :     log4cplus::LogLevel log4_new_level(SandeshLevelTolog4Level(level));
     421         334 :     log4cplus::LogLevel log4_old_level(logger_.getLogLevel());
     422         334 :     if (logging_level_ != level ||
     423             :         log4_old_level != log4_new_level) {
     424             :         const log4cplus::LogLevelManager &log4level_manager(
     425         240 :             log4cplus::getLogLevelManager());
     426         240 :         SANDESH_LOG(INFO, "SANDESH: Logging: LEVEL: " << "[ " <<
     427             :                 LevelToString(logging_level_) << " ] -> [ " <<
     428             :                 LevelToString(level) << " ] log4level: [ " <<
     429             :                 log4level_manager.toString(log4_old_level) <<
     430             :                 " ] -> [ " <<
     431             :                 log4level_manager.toString(log4_new_level) <<
     432             :                 " ]");
     433         240 :         logging_level_ = level;
     434         240 :         logger_.setLogLevel(log4_new_level);
     435             :         // Set the LogLevel on rootLogger
     436         240 :         ::SetLoggingLevel(log4_new_level);
     437             :     }
     438         334 : }
     439             : 
     440         333 : void Sandesh::SetLoggingCategory(std::string category) {
     441         333 :     if (logging_category_ != category) {
     442           0 :         SANDESH_LOG(INFO, "SANDESH: Logging: CATEGORY: " <<
     443             :                 (logging_category_.empty() ? "*" : logging_category_) << " -> " <<
     444             :                 (category.empty() ? "*" : category));
     445           0 :         logging_category_ = category;
     446             :     }
     447         333 : }
     448             : 
     449         340 : void Sandesh::SetLocalLogging(bool enable_local_log) {
     450         340 :     if (enable_local_log_ != enable_local_log) {
     451         206 :         SANDESH_LOG(INFO, "SANDESH: Logging: " <<
     452             :                 (enable_local_log_ ? "ENABLED" : "DISABLED") << " -> " <<
     453             :                 (enable_local_log ? "ENABLED" : "DISABLED"));
     454         206 :         enable_local_log_ = enable_local_log;
     455             :     }
     456         340 : }
     457             : 
     458         333 : void Sandesh::SetTracePrint(bool enable_trace_print) {
     459         333 :     if (enable_trace_print_ != enable_trace_print) {
     460           0 :         SANDESH_LOG(INFO, "SANDESH: Trace: PRINT: " <<
     461             :                 (enable_trace_print_ ? "ENABLED" : "DISABLED") << " -> " <<
     462             :                 (enable_trace_print ? "ENABLED" : "DISABLED"));
     463           0 :         enable_trace_print_ = enable_trace_print;
     464             :     }
     465         333 : }
     466             : 
     467         333 : void Sandesh::SetFlowLogging(bool enable_flow_log) {
     468         333 :     if (enable_flow_log_ != enable_flow_log) {
     469           0 :         SANDESH_LOG(INFO, "SANDESH: Flow Logging: " <<
     470             :             (enable_flow_log_ ? "ENABLED" : "DISABLED") << " -> " <<
     471             :             (enable_flow_log ? "ENABLED" : "DISABLED"));
     472           0 :         enable_flow_log_ = enable_flow_log;
     473             :     }
     474         333 : }
     475             : 
     476          60 : void Sandesh::SetSessionSyslogging(bool enable_session_syslog) {
     477          60 :      if (enable_session_syslog_ != enable_session_syslog) {
     478           0 :         SANDESH_LOG(INFO, "SANDESH: Flow Logging: " <<
     479             :             (enable_session_syslog_ ? "ENABLED" : "DISABLED") << " -> " <<
     480             :             (enable_session_syslog ? "ENABLED" : "DISABLED"));
     481           0 :         enable_session_syslog_ = enable_session_syslog;
     482             :     }
     483             : 
     484          60 : }
     485             : 
     486           0 : void Sandesh::DisableFlowCollection(bool disable) {
     487           0 :     if (disable_flow_collection_ != disable) {
     488           0 :         SANDESH_LOG(INFO, "SANDESH: Disable Flow Collection: " <<
     489             :             disable_flow_collection_ << " -> " << disable);
     490           0 :         disable_flow_collection_ = disable;
     491             :     }
     492           0 : }
     493             : 
     494           0 : void Sandesh::DisableSendingAllMessages(bool disable) {
     495           0 :     if (disable_sending_all_ != disable) {
     496           0 :         SANDESH_LOG(INFO, "SANDESH: Disable Sending ALL Messages: " <<
     497             :             disable_sending_all_ << " -> " << disable);
     498           0 :         disable_sending_all_ = disable;
     499             :     }
     500           0 : }
     501             : 
     502      198774 : bool Sandesh::IsSendingAllMessagesDisabled() {
     503      198774 :     return disable_sending_all_;
     504             : }
     505             : 
     506          86 : void Sandesh::DisableSendingObjectLogs(bool disable) {
     507          86 :     if (disable_sending_object_logs_ != disable) {
     508           0 :         SANDESH_LOG(INFO, "SANDESH: Disable Sending Object Logs: " <<
     509             :             disable_sending_object_logs_ << " -> " << disable);
     510           0 :         disable_sending_object_logs_ = disable;
     511             :     }
     512          86 : }
     513             : 
     514        9595 : bool Sandesh::IsSendingObjectLogsDisabled() {
     515        9595 :     return disable_sending_object_logs_;
     516             : }
     517             : 
     518           0 : void Sandesh::DisableSendingFlows(bool disable) {
     519           0 :     if (disable_sending_flows_ != disable) {
     520           0 :         SANDESH_LOG(INFO, "SANDESH: Disable Sending Flows: " <<
     521             :             disable_sending_flows_ << " -> " << disable);
     522           0 :         disable_sending_flows_ = disable;
     523             :     }
     524           0 : }
     525             : 
     526           0 : bool Sandesh::IsSendingFlowsDisabled() {
     527           0 :     return disable_sending_flows_;
     528             : }
     529             : 
     530      184573 : bool Sandesh::IsSendingSystemLogsDisabled() {
     531      184573 :     return sandesh_send_ratelimit_ == 0;
     532             : }
     533             : 
     534          86 : void Sandesh::set_send_rate_limit(int rate_limit) {
     535          86 :     if (rate_limit >= 0) {
     536          86 :         SANDESH_LOG(INFO, "SANDESH: System Log Send Rate Limit: " <<
     537             :             sandesh_send_ratelimit_ << " -> " << rate_limit);
     538          86 :         sandesh_send_ratelimit_ = rate_limit;
     539             :     }
     540          86 : }
     541             : 
     542       29565 : uint32_t Sandesh::get_send_rate_limit() {
     543       29565 :     return sandesh_send_ratelimit_;
     544             : }
     545             : 
     546       12936 : bool Sandesh::Enqueue(SandeshQueue *queue) {
     547       12936 :     if (!queue) {
     548           0 :         if (IsLoggingDroppedAllowed(type())) {
     549           0 :             SANDESH_LOG(ERROR, __func__ << ": SandeshQueue NULL : Dropping Message: "
     550             :                 << ToString());
     551             :         }
     552           0 :         UpdateTxMsgFailStats(name_, 0, SandeshTxDropReason::NoQueue);
     553           0 :         Release();
     554           0 :         return false;
     555             :     }
     556             :     //Frame an elemet object and enqueue it
     557       12936 :     SandeshElement elem(this);
     558       12936 :     if (!queue->Enqueue(elem)) {
     559             :         // XXX Change when WorkQueue implements bounded queues
     560           0 :         return true;
     561             :     }
     562       12936 :     return true;
     563             : }
     564             : 
     565          10 : bool Sandesh::ProcessRecv(SandeshRequest *rsnh) {
     566          10 :     rsnh->HandleRequest();
     567          10 :     rsnh->Release();
     568          10 :     return true;
     569             : }
     570             : 
     571        2280 : void SandeshRequest::Release() { self_.reset(); }
     572             : 
     573       22880 : int32_t Sandesh::WriteBinary(u_int8_t *buf, u_int32_t buf_len,
     574             :         int *error) {
     575             :     int32_t xfer;
     576             :     boost::shared_ptr<TMemoryBuffer> btrans =
     577             :             boost::shared_ptr<TMemoryBuffer>(
     578       22880 :                     new TMemoryBuffer(buf, buf_len));
     579       22871 :     btrans->setWriteBuffer(buf, buf_len);
     580             :     boost::shared_ptr<TBinaryProtocol> prot =
     581       22867 :             boost::shared_ptr<TBinaryProtocol>(new TBinaryProtocol(btrans));
     582       22868 :     xfer = Write(prot);
     583       22868 :     if (xfer < 0) {
     584           2 :         SANDESH_LOG(DEBUG, __func__ << "Write sandesh to " << buf_len <<
     585             :                 " bytes FAILED" << std::endl);
     586           0 :         *error = EINVAL;
     587           0 :         return xfer;
     588             :     }
     589       22866 :     return xfer;
     590       22866 : }
     591             : 
     592           0 : int32_t Sandesh::ReadBinary(u_int8_t *buf, u_int32_t buf_len,
     593             :         int *error) {
     594           0 :     int32_t xfer = 0;
     595             :     boost::shared_ptr<TMemoryBuffer> btrans =
     596             :             boost::shared_ptr<TMemoryBuffer>(
     597           0 :                     new TMemoryBuffer(buf, buf_len));
     598             :     boost::shared_ptr<TBinaryProtocol> prot =
     599           0 :             boost::shared_ptr<TBinaryProtocol>(new TBinaryProtocol(btrans));
     600           0 :     xfer = Read(prot);
     601           0 :     if (xfer < 0) {
     602           0 :         SANDESH_LOG(DEBUG, __func__ << "Read sandesh from " << buf_len <<
     603             :                 " bytes FAILED" << std::endl);
     604           0 :         *error = EINVAL;
     605           0 :         return xfer;
     606             :     }
     607           0 :     return xfer;
     608           0 : }
     609             : 
     610           0 : int32_t Sandesh::WriteBinaryToFile(const std::string& path, int *error) {
     611             :     int32_t xfer;
     612             :     boost::shared_ptr<TSimpleFileTransport> btrans =
     613             :             boost::shared_ptr<TSimpleFileTransport>(
     614           0 :                     new TSimpleFileTransport(path, false, true));
     615             :     boost::shared_ptr<TBinaryProtocol> prot =
     616           0 :             boost::shared_ptr<TBinaryProtocol>(new TBinaryProtocol(btrans));
     617           0 :     xfer = Write(prot);
     618           0 :     if (xfer < 0) {
     619           0 :         SANDESH_LOG(DEBUG, __func__ << "Write sandesh to file FAILED"
     620             :                 << std::endl);
     621           0 :         *error = EINVAL;
     622           0 :         return xfer;
     623             :     }
     624           0 :     return xfer;
     625           0 : }
     626             : 
     627           0 : int32_t Sandesh::ReadBinaryFromFile(const std::string& path, int *error) {
     628             :     int32_t xfer;
     629             :     boost::shared_ptr<TSimpleFileTransport> btrans =
     630             :             boost::shared_ptr<TSimpleFileTransport>(
     631           0 :                     new TSimpleFileTransport(path));
     632             :     boost::shared_ptr<TBinaryProtocol> prot =
     633           0 :             boost::shared_ptr<TBinaryProtocol>(new TBinaryProtocol(btrans));
     634           0 :     xfer = Read(prot);
     635           0 :     if (xfer < 0) {
     636           0 :         SANDESH_LOG(DEBUG, __func__ << "Read sandesh from file FAILED"
     637             :                 << std::endl);
     638           0 :         *error = EINVAL;
     639           0 :         return xfer;
     640             :     }
     641           0 :     return xfer;
     642           0 : }
     643             : 
     644       22882 : int32_t Sandesh::ReceiveBinaryMsgOne(u_int8_t *buf, u_int32_t buf_len,
     645             :         int *error, SandeshContext *client_context) {
     646             :     int32_t xfer;
     647       22882 :     std::string sandesh_name;
     648             :     boost::shared_ptr<TMemoryBuffer> btrans =
     649             :             boost::shared_ptr<TMemoryBuffer>(
     650       22882 :                     new TMemoryBuffer(buf, buf_len));
     651             :     boost::shared_ptr<TBinaryProtocol> prot =
     652       22881 :             boost::shared_ptr<TBinaryProtocol>(new TBinaryProtocol(btrans));
     653             :     // Extract sandesh name
     654       22881 :     xfer = prot->readSandeshBegin(sandesh_name);
     655       22879 :     if (xfer < 0) {
     656           0 :         SANDESH_LOG(DEBUG, __func__ << "Read sandesh begin from " << buf_len <<
     657             :                 " bytes FAILED" << std::endl);
     658           0 :         *error = EINVAL;
     659           0 :         return xfer;
     660             :     }
     661             :     // Create and process the sandesh
     662       22879 :     Sandesh *sandesh = SandeshBaseFactory::CreateInstance(sandesh_name);
     663       22879 :     if (sandesh == NULL) {
     664           0 :         SANDESH_LOG(DEBUG, __func__ << " Unknown sandesh:" <<
     665             :                 sandesh_name << std::endl);
     666           0 :         *error = EINVAL;
     667           0 :         return -1;
     668             :     }
     669             :     // Reinitialize buffer and protocol
     670       45760 :     btrans = boost::shared_ptr<TMemoryBuffer>(
     671       45756 :                     new TMemoryBuffer(buf, buf_len));
     672       22880 :     prot = boost::shared_ptr<TBinaryProtocol>(new TBinaryProtocol(btrans));
     673       22880 :     xfer = sandesh->Read(prot);
     674       22881 :     if (xfer < 0) {
     675           0 :         SANDESH_LOG(DEBUG, __func__ << " Decoding " << sandesh_name << " FAILED" <<
     676             :                 std::endl);
     677           0 :         *error = EINVAL;
     678           0 :         return xfer;
     679             :     }
     680       22881 :     SandeshBuffer * bsnh = dynamic_cast<SandeshBuffer *>(sandesh);
     681       22881 :     if (bsnh) bsnh->Process(client_context);
     682       22882 :     sandesh->Release();
     683       22882 :     return xfer;
     684       22882 : }
     685             : 
     686           0 : int32_t Sandesh::ReceiveBinaryMsg(u_int8_t *buf, u_int32_t buf_len,
     687             :         int *error, SandeshContext *client_context) {
     688           0 :     u_int32_t xfer = 0;
     689             :     int ret;
     690           0 :     while (xfer < buf_len) {
     691           0 :         ret = ReceiveBinaryMsgOne(buf + xfer, buf_len - xfer, error,
     692             :                                   client_context);
     693           0 :         if (ret < 0) {
     694           0 :             SANDESH_LOG(DEBUG, __func__ << "Read sandesh from " << buf_len <<
     695             :                     " bytes at offset " << xfer << " FAILED (" <<
     696             :                     error << ")");
     697           0 :             return ret;
     698             :         }
     699           0 :         xfer += ret;
     700             :     }
     701           0 :     return xfer;
     702             : }
     703             : 
     704       11621 : bool Sandesh::SendEnqueue() {
     705       11621 :     if (!client_) {
     706        2236 :         if (IsLoggingDroppedAllowed(type())) {
     707        2236 :             if (IsConnectToCollectorEnabled()) {
     708           0 :                 SANDESH_LOG(ERROR, "SANDESH: No client: " << ToString());
     709             :             } else {
     710        2236 :                 Log();
     711             :             }
     712             :         }
     713        2236 :         UpdateTxMsgFailStats(name_, 0, SandeshTxDropReason::NoClient);
     714        2236 :         Release();
     715        2236 :         return false;
     716             :     }
     717        9385 :     if (!client_->SendSandesh(this)) {
     718           0 :         if (IsLoggingDroppedAllowed(type())) {
     719           0 :             SANDESH_LOG(ERROR, "SANDESH: Send FAILED: " << ToString());
     720             :         }
     721           0 :         UpdateTxMsgFailStats(name_, 0,
     722             :             SandeshTxDropReason::ClientSendFailed);
     723           0 :         Release();
     724           0 :         return false;
     725             :     }
     726        9386 :     return true;
     727             : }
     728             : 
     729       11658 : bool Sandesh::Dispatch(SandeshConnection * sconn) {
     730             :     // Sandesh client does not have a connection
     731       11658 :     if (sconn) {
     732          37 :         return sconn->SendSandesh(this);
     733             :     } else {
     734       11621 :         return SendEnqueue();
     735             :     }
     736             : }
     737             : 
     738        1940 : bool SandeshResponse::Dispatch(SandeshConnection * sconn) {
     739        1940 :     assert(sconn == NULL);
     740        5810 :     if ((context().find("http%") == 0) ||
     741        3870 :         (context().find("https%") == 0)) {
     742          10 :         SandeshHttp::Response(this, context());
     743          10 :         return true;
     744             :     }
     745        1930 :     if (response_callback_) {
     746        1930 :         response_callback_(this);
     747             :     }
     748        1930 :     return Sandesh::Dispatch(sconn);
     749             : }
     750             : 
     751           0 : bool SandeshTrace::Dispatch(SandeshConnection * sconn) {
     752           0 :     assert(sconn == NULL);
     753           0 :     if ((0 == context().find("http%")) ||
     754           0 :         (0 == context().find("https%"))) {
     755           0 :         SandeshHttp::Response(this, context());
     756           0 :         return true;
     757             :     }
     758           0 :     return Sandesh::Dispatch();
     759             : }
     760             : 
     761      184324 : bool SandeshUVE::Dispatch(SandeshConnection * sconn) {
     762      184324 :     assert(sconn == NULL);
     763      552984 :     if ((0 == context().find("http%")) ||
     764      368664 :         (0 == context().find("https%"))) {
     765           0 :         SandeshHttp::Response(this, context());
     766           0 :         return true;
     767             :     }
     768      184336 :     if (client_) {
     769        4610 :         if (IsSendingAllMessagesDisabled()) {
     770           0 :             Log();
     771           0 :             UpdateTxMsgFailStats(Name(), 0,
     772             :                 SandeshTxDropReason::SendingDisabled);
     773           0 :             Release();
     774           0 :             return false;
     775             :         }
     776             :         // SandeshUVE has an implicit send level of SandeshLevel::SYS_UVE
     777             :         // which is irrespective of the level set by the user in the Send.
     778             :         // This is needed so that the send queue does not grow unbounded.
     779             :         // Once the send queue's sending level reaches SandeshLevel::SYS_UVE
     780             :         // we will reset the connection to the collector to initiate resync
     781             :         // of the UVE cache
     782        4610 :         if (SandeshLevel::SYS_UVE >= SendingLevel()) {
     783           0 :             client_->CloseSMSession();
     784             :         }
     785        4610 :         if (!client_->SendSandeshUVE(this)) {
     786           0 :             SANDESH_LOG(ERROR, "SandeshUVE : Send FAILED: " << ToString());
     787           0 :             UpdateTxMsgFailStats(Name(), 0,
     788             :                 SandeshTxDropReason::ClientSendFailed);
     789           0 :             Release();
     790           0 :             return false;
     791             :         }
     792        4610 :         return true;
     793             :     }
     794      179726 :     if (IsConnectToCollectorEnabled()) {
     795          83 :         SANDESH_LOG(ERROR, "SANDESH: No Client: " << ToString());
     796             :     } else {
     797      179646 :         Log();
     798             :     }
     799      179708 :     UpdateTxMsgFailStats(Name(), 0, SandeshTxDropReason::NoClient);
     800      179805 :     Release();
     801      179804 :     return false;
     802             : }
     803             : 
     804          10 : bool SandeshRequest::Enqueue(SandeshRxQueue *queue) {
     805          10 :     if (!queue) {
     806           0 :         SANDESH_LOG(ERROR, "SandeshRequest: No RxQueue: " << ToString());
     807           0 :         UpdateRxMsgFailStats(Name(), 0, SandeshRxDropReason::NoQueue);
     808           0 :         Release();
     809           0 :         return false;
     810             :     }
     811          10 :     if (!queue->Enqueue(this)) {
     812             :         // XXX Change when WorkQueue implements bounded queues
     813           0 :         return true;
     814             :     }
     815          10 :     return true;
     816             : }
     817             : 
     818      236178 : bool Sandesh::IsLevelUT(SandeshLevel::type level) {
     819      236178 :     return level >= SandeshLevel::UT_START &&
     820      236178 :             level <= SandeshLevel::UT_END;
     821             : }
     822             : 
     823    20788195 : bool Sandesh::IsLevelCategoryLoggingAllowed(SandeshType::type type,
     824             :                                             SandeshLevel::type level,
     825             :                                             const std::string& category) {
     826             :     // Do not log UVEs unless explicitly configured via setting log_level
     827             :     // to INVALID. This is to avoid flooding the log files with UVEs
     828    20788195 :     if (type == SandeshType::UVE) {
     829      183239 :         level = SandeshLevel::INVALID;
     830             :     }
     831    20788195 :     bool level_allowed = logging_level_ >= level;
     832    20788195 :     bool category_allowed = !logging_category_.empty() ?
     833         199 :             logging_category_ == category : true;
     834    20788795 :     return level_allowed && category_allowed;
     835             : }
     836             : 
     837       12973 : bool Sandesh::IsLoggingAllowed() const {
     838       12973 :     if (type_ == SandeshType::FLOW || type_ == SandeshType::SESSION) {
     839           0 :         return enable_flow_log_;
     840             :     } else {
     841       25897 :         return IsLocalLoggingEnabled() &&
     842       25897 :                 IsLevelCategoryLoggingAllowed(type_, level_, category_);
     843             :     }
     844             : }
     845             : 
     846        3296 : bool Sandesh::IsLoggingDroppedAllowed(SandeshType::type type) {
     847        3296 :     if (type == SandeshType::FLOW || type == SandeshType::SESSION) {
     848           0 :         return enable_flow_log_;
     849             :     } else {
     850        3296 :         return true;
     851             :     }
     852             : }
     853             : 
     854    12133711 : const char * Sandesh::LevelToString(SandeshLevel::type level) {
     855    12133711 :     std::map<int, const char*>::const_iterator it = _SandeshLevel_VALUES_TO_NAMES.find(level);
     856    12132380 :     if (it != _SandeshLevel_VALUES_TO_NAMES.end()) {
     857    12132245 :         return it->second;
     858             :     } else {
     859           0 :         return "UNKNOWN";
     860             :     }
     861             : }
     862             : 
     863         106 : SandeshLevel::type Sandesh::StringToLevel(std::string level) {
     864         106 :     std::map<int, const char*>::const_iterator it = _SandeshLevel_VALUES_TO_NAMES.begin();
     865         907 :     while (it != _SandeshLevel_VALUES_TO_NAMES.end()) {
     866         907 :         if (strncmp(level.c_str(), it->second, strlen(it->second)) == 0) {
     867         106 :             return static_cast<SandeshLevel::type>(it->first);
     868             :         }
     869         801 :         it++;
     870             :     }
     871           0 :     return SandeshLevel::INVALID;
     872             : }
     873             : 
     874          86 : void Sandesh::UpdateRxMsgStats(const std::string &msg_name,
     875             :                                uint64_t bytes) {
     876          86 :     std::scoped_lock lock(stats_mutex_);
     877          86 :     msg_stats_.UpdateRecv(msg_name, bytes);
     878          86 : }
     879             : 
     880           0 : void Sandesh::UpdateRxMsgFailStats(const std::string &msg_name,
     881             :     uint64_t bytes, SandeshRxDropReason::type dreason) {
     882           0 :     std::scoped_lock lock(stats_mutex_);
     883           0 :     msg_stats_.UpdateRecvFailed(msg_name, bytes, dreason);
     884           0 : }
     885             : 
     886       12973 : void Sandesh::UpdateTxMsgStats(const std::string &msg_name,
     887             :                                uint64_t bytes) {
     888       12973 :     std::scoped_lock lock(stats_mutex_);
     889       12973 :     msg_stats_.UpdateSend(msg_name, bytes);
     890       12973 : }
     891             : 
     892      367551 : void Sandesh::UpdateTxMsgFailStats(const std::string &msg_name,
     893             :     uint64_t bytes, SandeshTxDropReason::type dreason) {
     894      367551 :     std::scoped_lock lock(stats_mutex_);
     895      367681 :     msg_stats_.UpdateSendFailed(msg_name, bytes, dreason);
     896      367681 : }
     897             : 
     898         659 : void Sandesh::GetMsgStats(
     899             :     std::vector<SandeshMessageTypeStats> *mtype_stats,
     900             :     SandeshMessageStats *magg_stats) {
     901         659 :     std::scoped_lock lock(stats_mutex_);
     902         659 :     msg_stats_.Get(mtype_stats, magg_stats);
     903         659 : }
     904             : 
     905           0 : void Sandesh::GetMsgStats(
     906             :     boost::ptr_map<std::string, SandeshMessageTypeStats> *mtype_stats,
     907             :     SandeshMessageStats *magg_stats) {
     908           0 :     std::scoped_lock lock(stats_mutex_);
     909           0 :     msg_stats_.Get(mtype_stats, magg_stats);
     910           0 : }
     911             : 
     912           0 : void Sandesh::SetSendQueue(bool enable) {
     913           0 :     if (send_queue_enabled_ != enable) {
     914           0 :         SANDESH_LOG(INFO, "SANDESH: CLIENT: SEND QUEUE: " <<
     915             :             (send_queue_enabled_ ? "ENABLED" : "DISABLED") << " -> " <<
     916             :             (enable ? "ENABLED" : "DISABLED"));
     917           0 :         send_queue_enabled_ = enable;
     918           0 :         if (enable) {
     919           0 :             if (client_ && client_->IsSession()) {
     920           0 :                 client_->session()->send_queue()->MayBeStartRunner();
     921             :             }
     922             :         }
     923             :     }
     924           0 : }
     925             : 
     926             : // In sandesh state machine on collector, we can only drop systemlog,
     927             : // objectlog, and flow. UVEs can only be dropped after being dequeued from
     928             : // the state machine and published on redis/kafka
     929       12449 : bool DoDropSandeshMessage(const SandeshHeader &header,
     930             :     const SandeshLevel::type drop_level) {
     931       12449 :     SandeshType::type stype(header.get_Type());
     932       12449 :     if (stype == SandeshType::SYSTEM ||
     933        3395 :         stype == SandeshType::OBJECT ||
     934        3395 :         stype == SandeshType::FLOW ||
     935             :         stype == SandeshType::SESSION) {
     936             :         // Is level above drop level?
     937             :         SandeshLevel::type slevel(
     938        9054 :             static_cast<SandeshLevel::type>(header.get_Level()));
     939        9054 :         if (slevel >= drop_level) {
     940           0 :             return true;
     941             :         }
     942             :     }
     943             :     // Drop flow message if flow collection is disabled
     944       12449 :     if (Sandesh::IsFlowCollectionDisabled() &&
     945           0 :            (stype == SandeshType::FLOW || stype == SandeshType::SESSION)) {
     946           0 :         return true;
     947             :     }
     948       12449 :     return false;
     949             : }
     950             : 
     951         359 : SandeshContext *Sandesh::module_context(const std::string &module_name) {
     952         359 :     ModuleContextMap::const_iterator loc = module_context_.find(module_name);
     953         359 :     if (loc != module_context_.end()) {
     954         359 :         return loc->second;
     955             :     }
     956           0 :     return NULL;
     957             : }
     958             : 
     959         217 : void Sandesh::set_module_context(const std::string &module_name,
     960             :                                  SandeshContext *context) {
     961             :     std::pair<ModuleContextMap::iterator, bool> result =
     962         217 :             module_context_.insert(std::make_pair(module_name, context));
     963         217 :     if (!result.second) {
     964         203 :         result.first->second = context;
     965             :     }
     966         217 : }
     967             : 
     968    12135077 : bool Sandesh::HandleTest(SandeshLevel::type level,
     969             :                          const std::string& category) {
     970             :     // Handle unit test scenario
     971    12135077 :     if (IsUnitTest() || IsLevelUT(level)) {
     972    11941134 :         return true;
     973             :     }
     974      194185 :     return false;
     975             : }
     976             : 
     977       14205 : SandeshLevel::type Sandesh::SendingLevel() {
     978       14205 :     if (client_) {
     979       13889 :         SandeshSession *sess = client_->session();
     980       13889 :         if (sess) {
     981       13449 :             return sess->SendingLevel();
     982             :         }
     983             :     }
     984         756 :     return SandeshLevel::INVALID;
     985             : }
     986             : 
     987             : template<>
     988       12973 : size_t Sandesh::SandeshQueue::AtomicIncrementQueueCount(
     989             :     SandeshElement *element)
     990             :  {
     991       12973 :         size_t sandesh_size = element->GetSize();
     992       25946 :         return count_.fetch_add(sandesh_size) + sandesh_size;
     993             : }
     994             : 
     995             : template<>
     996       12973 : size_t Sandesh::SandeshQueue::AtomicDecrementQueueCount(
     997             :     SandeshElement *element) {
     998       12973 :         size_t sandesh_size = element->GetSize();
     999       25946 :         return count_.fetch_sub(sandesh_size) - sandesh_size;
    1000             : }
    1001             : 
    1002             : /*
    1003             :  * Add the configured appenders for the sample logger
    1004             :  */
    1005           4 : void Sandesh::set_logger_appender(const std::string &file_name, long max_file_size,
    1006             :                              int max_backup_index,
    1007             :                              const std::string &syslog_facility,
    1008             :                              const std::vector<std::string> &destn,
    1009             :                              const std::string &ident,
    1010             :                              bool is_sampled_logger) {
    1011           4 :     log4cplus::Logger logger;
    1012           4 :     if (is_sampled_logger) {
    1013           2 :         logger = Sandesh::sampled_logger();
    1014             :     } else {
    1015           2 :         logger = Sandesh::slo_logger();
    1016             :     }
    1017           4 :     logger.setAdditivity(false);
    1018             :     // Session messages log level is
    1019           4 :     logger.setLogLevel(SandeshLevel::SYS_NOTICE);
    1020             :     // Local logging for SLO logger
    1021           4 :     if (std::find(destn.begin(), destn.end(), "file") !=
    1022           8 :             destn.end()) {
    1023             :         // Append file appender to SLO logger
    1024             :         SharedAppenderPtr fileappender(new RollingFileAppender(file_name,
    1025           0 :                                            max_file_size, max_backup_index));
    1026           0 :         logger.addAppender(fileappender);
    1027           0 :         if (is_sampled_logger) {
    1028           0 :             Sandesh::sampled_to_logger_ = true;
    1029             :         } else {
    1030           0 :             Sandesh::slo_to_logger_ = true;
    1031             :         }
    1032           0 :     }
    1033             :     // SYSLOG appender for SLO logger
    1034           4 :     if (std::find(destn.begin(), destn.end(), "syslog") !=
    1035           8 :             destn.end()) {
    1036           0 :         helpers::Properties props;
    1037             :         std::string syslogident = boost::str(
    1038           0 :             boost::format("%1%[%2%]") % ident % getpid());
    1039           0 :         props.setProperty(LOG4CPLUS_TEXT("facility"),
    1040           0 :                           boost::starts_with(syslog_facility, "LOG_")
    1041           0 :                         ? syslog_facility.substr(4)
    1042             :                         : syslog_facility);
    1043           0 :         props.setProperty(LOG4CPLUS_TEXT("ident"), syslogident);
    1044           0 :         props.setProperty(LOG4CPLUS_TEXT("additivity"), "false");
    1045           0 :         SharedAppenderPtr syslogappender(new SysLogAppender(props));
    1046             :         std::unique_ptr<Layout> syslog_layout_ptr(new PatternLayout(
    1047           0 :                                                     loggingPattern));
    1048           0 :         syslogappender->setLayout(std::move(syslog_layout_ptr));
    1049           0 :         logger.addAppender(syslogappender);
    1050           0 :         if (is_sampled_logger) {
    1051           0 :             Sandesh::sampled_to_logger_ = true;
    1052             :         } else {
    1053           0 :             Sandesh::slo_to_logger_ = true;
    1054             :         }
    1055           0 :     }
    1056           4 : }
    1057             : 
    1058           2 : void Sandesh::set_send_to_collector_flags(
    1059             :     const std::vector<std::string> &sampled_destn,
    1060             :     const std::vector<std::string> &slo_destn) {
    1061           2 :     if (std::find(slo_destn.begin(), slo_destn.end(), "collector") !=
    1062           4 :             slo_destn.end()) {
    1063           2 :         Sandesh::slo_to_collector_ = true;
    1064             :     }
    1065           2 :     if (std::find(sampled_destn.begin(), sampled_destn.end(), "collector") !=
    1066           4 :             sampled_destn.end()) {
    1067           2 :         Sandesh::sampled_to_collector_ = true;
    1068             :     }
    1069           2 : }

Generated by: LCOV version 1.14