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

Generated by: LCOV version 1.14