LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-analytics/contrail-collector - structured_syslog_server.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 110 1396 7.9 %
Date: 2026-11-09 02:10:49 Functions: 2 66 3.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2017 Juniper Networks, Inc. All rights reserved.
       3             : // Copyright Contributors to the OpenSDN project
       4             : //
       5             : 
       6             : #include <utility>
       7             : #include <string>
       8             : #include <vector>
       9             : #include <boost/asio/buffer.hpp>
      10             : #include <boost/intrusive_ptr.hpp>
      11             : #include <boost/algorithm/string.hpp>
      12             : 
      13             : #include <sandesh/sandesh_message_builder.h>
      14             : 
      15             : #include <base/logging.h>
      16             : #include "base/address_util.h"
      17             : #include <io/io_types.h>
      18             : #include <io/tcp_server.h>
      19             : #include <io/tcp_session.h>
      20             : #include <io/udp_server.h>
      21             : 
      22             : #include <rapidjson/document.h>
      23             : #include <rapidjson/stringbuffer.h>
      24             : #include <rapidjson/writer.h>
      25             : 
      26             : #include "structured_syslog_server.h"
      27             : #include "structured_syslog_server_impl.h"
      28             : #include "generator.h"
      29             : #include <analytics/sdwan_uve_types.h>
      30             : #include "syslog_collector.h"
      31             : #include "structured_syslog_config.h"
      32             : 
      33             : 
      34             : using std::make_pair;
      35             : 
      36             : namespace structured_syslog {
      37             : 
      38             : namespace impl {
      39             : 
      40             : 
      41             : void StructuredSyslogDecorate(SyslogParser::syslog_m_t &v, StructuredSyslogConfig *config_obj,
      42             :                               boost::shared_ptr<std::string> msg, std::vector<std::string> int_fields);
      43             : void StructuredSyslogPush(SyslogParser::syslog_m_t v, StatWalker::StatTableInsertFn stat_db_callback,
      44             :     std::vector<std::string> tagged_fields);
      45             : void StructuredSyslogUVESummarize(SyslogParser::syslog_m_t v, bool summarize_user, StructuredSyslogConfig *config_obj);
      46             : boost::shared_ptr<std::string> StructuredSyslogJsonMessage(SyslogParser::syslog_m_t v);
      47             : 
      48           0 : size_t DecorateMsg(boost::shared_ptr<std::string> msg, const std::string &key, const std::string &val, size_t prev_pos) {
      49           0 :     if (msg == NULL) {
      50           0 :         return 0;
      51             :     }
      52           0 :     size_t pos = msg->find(']', prev_pos);
      53           0 :     if (pos == std::string::npos) {
      54           0 :         return 0;
      55             :     }
      56           0 :     std::string insert_str = " " + key + "=\"" + val + "\"";
      57           0 :     msg->insert(pos, insert_str);
      58           0 :     return pos;
      59           0 : }
      60             : 
      61           0 : bool ParseStructuredPart(SyslogParser::syslog_m_t *v, const std::string &structured_part,
      62             :                          const std::vector<std::string> &int_fields, boost::shared_ptr<std::string> fwd_msg){
      63           0 :     std::size_t start = 0, end = 0;
      64           0 :     size_t prev_pos = 0;
      65           0 :     while ((end = structured_part.find('=', start)) != std::string::npos) {
      66           0 :         const std::string key = structured_part.substr(start, end - start);
      67           0 :         start = end + 2;
      68           0 :         end = structured_part.find('"', start);
      69           0 :         if (end == std::string::npos) {
      70           0 :             LOG(ERROR, "BAD structured_syslog: " << structured_part);
      71           0 :             return false;
      72             :           }
      73           0 :         const std::string val = structured_part.substr(start, end - start);
      74           0 :         LOG(DEBUG, "structured_syslog - " << key << " : " << val);
      75           0 :         start = end + 2;
      76           0 :         if (std::find(int_fields.begin(), int_fields.end(),
      77           0 :                       key) != int_fields.end()) {
      78           0 :             LOG(DEBUG, "int field - " << key);
      79           0 :             int64_t ival = atol(val.c_str());
      80           0 :             v->insert(std::pair<std::string, SyslogParser::Holder>(key,
      81           0 :                   SyslogParser::Holder(key, ival)));
      82             :         } else {
      83           0 :             v->insert(std::pair<std::string, SyslogParser::Holder>(key,
      84           0 :                   SyslogParser::Holder(key, val)));
      85             :         }
      86           0 :         prev_pos = DecorateMsg(fwd_msg, key, val, prev_pos);
      87           0 :   }
      88           0 :   return true;
      89             : }
      90             : 
      91           0 : bool filter_msg(SyslogParser::syslog_m_t &v) {
      92           0 :   std::string tag  = SyslogParser::GetMapVals(v, "tag", "UNKNOWN");
      93           0 :   std::string reason = SyslogParser::GetMapVals(v, "reason", "UNKNOWN");
      94           0 :   if (tag == "APPQOE_BEST_PATH_SELECTED" && 
      95           0 :     ((reason == "session close") || reason == "app detected")) {
      96           0 :     return false;
      97             :   }
      98           0 :   if (tag == "SNMP_TRAP_LINK_UP" || tag == "SNMP_TRAP_LINK_DOWN") {
      99           0 :     if (SyslogParser::GetMapVals(v, "role", "UNKNOWN") == "HUB" && 
     100           0 :       SyslogParser::GetMapVals(v,"interface-name", "UNKNOWN").compare(0, 2, "st") != 0) {
     101           0 :       return false;
     102             :     }
     103             :   }
     104           0 :   return true;
     105           0 : }
     106             : 
     107             : //filter out session close syslog for incoming traffic i.e. syslog coming from destination site.
     108           0 : bool filter_session_close_msg(SyslogParser::syslog_m_t &v) {
     109           0 :   std::string routing_instance = SyslogParser::GetMapVals(v, "routing-instance", "UNKNOWN");
     110           0 :   if (routing_instance.size() > 3 && ( routing_instance.compare(0,4,"LAN-") == 0)) {
     111           0 :       return true;
     112             :   }
     113           0 :   return false;
     114           0 : }
     115             : 
     116             : //filter out vol update syslog for incoming traffic i.e. syslog coming from destination site.
     117           0 : bool filter_vol_update_msg(SyslogParser::syslog_m_t &v) {
     118           0 :   std::string department = SyslogParser::GetMapVals(v, "source-zone-name", "UNKNOWN");
     119           0 :   if ((department.compare(0,5,"trust") == 0) || (department.compare(0,7,"untrust") == 0)) {
     120           0 :       return true;
     121             :   }
     122           0 :   return false;
     123           0 : }
     124             : 
     125          31 : bool StructuredSyslogPostParsing (SyslogParser::syslog_m_t &v, StructuredSyslogConfig *config_obj,
     126             :                                   StatWalker::StatTableInsertFn stat_db_callback, const uint8_t *message,
     127             :                                   int message_len, boost::shared_ptr<StructuredSyslogForwarder> forwarder){
     128             :   /*
     129             :   syslog format: <14>1 2016-12-06T11:38:19.818+02:00 csp-ucpe-bglr51 RT_FLOW: APPTRACK_SESSION_CLOSE [junos@2636.1.1.1.2.26
     130             :   reason="TCP RST" source-address="4.0.0.3" source-port="13175" destination-address="5.0.0.7"
     131             :   destination-port="48334" service-name="None" application="HTTP" nested-application="Facebook"
     132             :   nat-source-address="10.110.110.10" nat-source-port="13175" destination-address="96.9.139.213"
     133             :   nat-destination-port="48334" src-nat-rule-name="None" dst-nat-rule-name="None" protocol-id="6"
     134             :   policy-name="dmz-out" source-zone-name="DMZ" destination-zone-name="Internet" session-id-32="44292"
     135             :   packets-from-client="7" bytes-from-client="1421" packets-from-server="6" bytes-from-server="1133"
     136             :   elapsed-time="4" username="Frank" roles="Engineering" encrypted="No" profile-name="pf1" rule-name="1"
     137             :   routing-instance="inst1" destination-interface-name="xe-1/2/0.0"]
     138             :   */
     139             : 
     140             :   /*
     141             :   Remove unnecessary fields so that we avoid writing them into DB
     142             :   */
     143          31 :   v.erase("msglen");
     144          31 :   v.erase("severity");
     145          31 :   v.erase("facility");
     146          31 :   v.erase("year");
     147          31 :   v.erase("month");
     148          31 :   v.erase("day");
     149          31 :   v.erase("hour");
     150          31 :   v.erase("min");
     151          31 :   v.erase("sec");
     152          31 :   v.erase("msec");
     153          31 :   if (SyslogParser::GetMapVal(v, "pid", -1) == -1)
     154          31 :     v.erase("pid");
     155             : 
     156          62 :   const std::string body(SyslogParser::GetMapVals(v, "body", ""));
     157          31 :   std::size_t start = 0, end = 0;
     158          31 :   v.erase("body");
     159          31 :   LOG(DEBUG, "BODY: " << body);
     160          31 :   end = body.find('[', start);
     161          31 :   size_t tag_end = end;
     162             : 
     163          31 :   if (end == std::string::npos) {
     164           0 :     LOG(ERROR, "BAD structured_syslog: " << body);
     165           0 :     return false;
     166             :   }
     167          31 :   end = body.find(']', end+1);
     168             : 
     169          31 :   if (end == std::string::npos) {
     170           1 :     LOG(ERROR, "BAD structured_syslog: " << body);
     171           1 :     return false;
     172             :   }
     173          30 :   end = body.find(' ', start);
     174             : 
     175          30 :   if (end == std::string::npos) {
     176           0 :     LOG(ERROR, "BAD structured_syslog: " << body);
     177           0 :     return false;
     178             :   }
     179          30 :   std::string tag_ = "UNKNOWN";
     180          30 :   std::string find_tag_str = body.substr(start,tag_end-1);
     181          30 :   std::size_t tag_index = find_tag_str.find_last_of(' ');
     182          30 :   if (tag_index !=  std::string::npos){
     183           2 :       tag_  = find_tag_str.substr(tag_index+1, end-tag_index);
     184             :   }
     185          28 :   else {tag_ = find_tag_str;}
     186          30 :   const std::string tag = tag_;
     187          30 :   LOG(DEBUG, "structured_syslog - tag: " << tag );
     188          30 :   boost::shared_ptr<MessageConfig> mc = config_obj->GetMessageConfig(tag);
     189          30 :   if (mc == NULL || ((mc->process_and_store() == false) && (mc->forward() == false)
     190           0 :      && (mc->process_and_summarize() == false))) {
     191          30 :     LOG(DEBUG, "structured_syslog - not processing message: " << tag );
     192          30 :     return false;
     193             :   }
     194           0 :   LOG(DEBUG, "structured_syslog - message_config: " << mc->name());
     195           0 :   boost::shared_ptr<std::string> msg;
     196           0 :   boost::shared_ptr<std::string> hostname;
     197           0 :   start = tag_end;
     198             : 
     199           0 :   v.insert(std::pair<std::string, SyslogParser::Holder>("tag",
     200           0 :         SyslogParser::Holder("tag", tag)));
     201             : 
     202           0 :   end = body.find(' ', start);
     203             : 
     204           0 :   if (end == std::string::npos) {
     205           0 :     LOG(ERROR, "BAD structured_syslog: " << body);
     206           0 :     return false;
     207             :   }
     208           0 :   const std::string hardware = body.substr(start+1, end-start-1);
     209             : 
     210           0 :   start = end + 1;
     211           0 :   LOG(DEBUG, "structured_syslog - hardware: " << hardware);
     212           0 :   v.insert(std::pair<std::string, SyslogParser::Holder>("hardware",
     213           0 :         SyslogParser::Holder("hardware", hardware)));
     214           0 :   end = body.find_last_of(']');
     215           0 :   std::string structured_part = body.substr(start, end-start);
     216           0 :   LOG(DEBUG, "structured_syslog - struct_data: " << structured_part);
     217             : 
     218           0 :   bool ret = ParseStructuredPart(&v, structured_part, mc->ints(), msg);
     219           0 :   if (ret == false){
     220           0 :     return ret;
     221             :   }
     222             :   // Do not process APPTRACK_SESSION_CLOSE syslogs for incoming traffic 
     223           0 :   if(tag == "APPTRACK_SESSION_CLOSE" && filter_session_close_msg(v)){
     224           0 :     return false;
     225             :   }
     226             :   
     227             :   // Do not process APPTRACK_SESSION_VOL_UPDATE syslogs for incoming traffic. 
     228           0 :   if(tag == "APPTRACK_SESSION_VOL_UPDATE" && filter_vol_update_msg(v)) {
     229           0 :     return false;
     230             :   }
     231             : 
     232           0 :   if (mc->process_and_store() == true || mc->process_before_forward() == true
     233           0 :       || mc->process_and_summarize() == true) {
     234           0 :       if (forwarder != NULL && mc->forward() == true) {
     235           0 :         msg.reset(new std::string (message, message + message_len));
     236           0 :         hostname.reset(new std::string (SyslogParser::GetMapVals(v, "hostname", "")));
     237             :       }
     238           0 :       StructuredSyslogDecorate(v, config_obj, msg, mc->ints());
     239           0 :       if (mc->process_and_summarize() == true) {
     240           0 :         bool syslog_summarize_user = mc->process_and_summarize_user();
     241           0 :         StructuredSyslogUVESummarize(v, syslog_summarize_user, config_obj);
     242             :       }
     243           0 :       if (forwarder != NULL && mc->forward() == true &&
     244           0 :           mc->process_before_forward() == true && filter_msg (v)) {
     245           0 :         std::stringstream msglength;
     246           0 :         msglength << msg->length();
     247           0 :         msg->insert(0, msglength.str() + " ");
     248           0 :         LOG(DEBUG, "forwarding after decoration - " << *msg);
     249           0 :         boost::shared_ptr<std::string> json_msg;
     250           0 :         if (forwarder->kafkaForwarder()) {
     251           0 :           json_msg = StructuredSyslogJsonMessage(v);
     252             :         }
     253           0 :         boost::shared_ptr<StructuredSyslogQueueEntry> ssqe(new StructuredSyslogQueueEntry(msg, msg->length(),
     254           0 :                                                                                           json_msg, hostname));
     255           0 :         forwarder->Forward(ssqe);
     256           0 :       }
     257           0 :       if (mc->process_and_store() == true) {
     258           0 :         StructuredSyslogPush(v, stat_db_callback, mc->tags());
     259             :       }
     260             :   }
     261           0 :   if (forwarder != NULL && mc->forward() == true && filter_msg(v) &&
     262           0 :       mc->process_before_forward() == false) {
     263           0 :     msg.reset(new std::string (message, message + message_len));
     264           0 :     hostname.reset(new std::string (SyslogParser::GetMapVals(v, "hostname", "")));
     265           0 :     std::stringstream msglength;
     266           0 :     msglength << msg->length();
     267           0 :     msg->insert(0, msglength.str() + " ");
     268           0 :     LOG(DEBUG, "forwarding without decoration - " << *msg);
     269           0 :     boost::shared_ptr<std::string> json_msg;
     270           0 :     if (forwarder->kafkaForwarder()) {
     271           0 :         json_msg = StructuredSyslogJsonMessage(v);
     272             :     }
     273           0 :     boost::shared_ptr<StructuredSyslogQueueEntry> ssqe(new StructuredSyslogQueueEntry(msg, msg->length(),
     274           0 :                                                                                       json_msg, hostname));
     275           0 :     forwarder->Forward(ssqe);
     276           0 :   }
     277           0 :   return true;
     278          31 : }
     279             : 
     280           0 : static inline void PushStructuredSyslogAttribsAndTags(DbHandler::AttribMap *attribs,
     281             :     StatWalker::TagMap *tags, bool is_tag, const std::string &name,
     282             :     DbHandler::Var value) {
     283             :     // Insert into the attribute map
     284           0 :     attribs->insert(make_pair(name, value));
     285           0 :     if (is_tag) {
     286             :         // Insert into the tag map
     287           0 :         StatWalker::TagVal tvalue;
     288           0 :         tvalue.val = value;
     289           0 :         tags->insert(make_pair(name, tvalue));
     290           0 :     }
     291           0 : }
     292             : 
     293           0 : void PushStructuredSyslogStats(SyslogParser::syslog_m_t v, const std::string &stat_attr_name,
     294             :                                StatWalker *stat_walker, std::vector<std::string> tagged_fields) {
     295             :     // At the top level the stat walker already has the tags so
     296             :     // we need to skip going through the elemental types and
     297             :     // creating the tag and attribute maps. At lower levels,
     298             :     // only strings are inserted into the tag map
     299           0 :     bool top_level(stat_attr_name.empty());
     300           0 :     DbHandler::AttribMap attribs;
     301           0 :     StatWalker::TagMap tags;
     302             : 
     303           0 :     if (!top_level) {
     304             : 
     305           0 :       int i = 0;
     306           0 :       while (!v.empty()) {
     307             :       /*
     308             :       All the key-value pairs in v will be iterated over and pushed into the stattable
     309             :       */
     310           0 :           SyslogParser::Holder d = v.begin()->second;
     311           0 :           const std::string &key(d.key);
     312           0 :           bool is_tag = false;
     313           0 :            if (std::find(tagged_fields.begin(), tagged_fields.end(), key) != tagged_fields.end()) {
     314           0 :             LOG(DEBUG, "tagged field - " << key);
     315           0 :             is_tag = true;
     316             :            }
     317             : 
     318           0 :           if (d.type == SyslogParser::str_type) {
     319           0 :             const std::string &sval(d.s_val);
     320           0 :             LOG(DEBUG, i++ << " - " << key << " : " << sval << " is_tag: " << is_tag);
     321           0 :             DbHandler::Var svalue(sval);
     322           0 :             PushStructuredSyslogAttribsAndTags(&attribs, &tags, is_tag, key, svalue);
     323           0 :           }
     324           0 :           else if (d.type == SyslogParser::int_type) {
     325           0 :             LOG(DEBUG, i++ << " - " << key << " : " << d.i_val << " is_tag: " << is_tag);
     326           0 :             if (d.i_val >= 0) { /* added this condition as having -ve values was resulting in a crash */
     327           0 :                 DbHandler::Var ivalue(static_cast<uint64_t>(d.i_val));
     328           0 :                 PushStructuredSyslogAttribsAndTags(&attribs, &tags, is_tag, key, ivalue);
     329           0 :             }
     330             :           }
     331             :           else {
     332           0 :             LOG(ERROR, i++ << "BAD Type: ");
     333             :           }
     334           0 :           v.erase(v.begin());
     335           0 :       }
     336             : 
     337             :       // Push the stats at this level
     338           0 :       stat_walker->Push(stat_attr_name, tags, attribs);
     339             : 
     340             :     }
     341             :     // Perform traversal of children
     342             :     else {
     343           0 :         PushStructuredSyslogStats(v, "data", stat_walker, tagged_fields);
     344             :     }
     345             : 
     346             :     // Pop the stats at this level
     347           0 :     if (!top_level) {
     348           0 :         stat_walker->Pop();
     349             :     }
     350           0 : }
     351             : 
     352           0 : void PushStructuredSyslogTopLevelTags(SyslogParser::syslog_m_t v, StatWalker::TagMap *top_tags) {
     353           0 :     StatWalker::TagVal tvalue;
     354           0 :     const std::string ip(SyslogParser::GetMapVals(v, "ip", ""));
     355           0 :     const std::string saddr(SyslogParser::GetMapVals(v, "hostname", ip));
     356           0 :     tvalue.val = saddr;
     357           0 :     top_tags->insert(make_pair("Source", tvalue));
     358           0 : }
     359             : 
     360           0 : void StructuredSyslogPush(SyslogParser::syslog_m_t v, StatWalker::StatTableInsertFn stat_db_callback,
     361             :     std::vector<std::string> tagged_fields) {
     362           0 :     StatWalker::TagMap top_tags;
     363           0 :     PushStructuredSyslogTopLevelTags(v, &top_tags);
     364           0 :     StatWalker stat_walker(stat_db_callback, (uint64_t)SyslogParser::GetMapVal (v, "timestamp", 0),
     365           0 :                            "JunosSyslog", top_tags);
     366           0 :     PushStructuredSyslogStats(v, std::string(), &stat_walker, tagged_fields);
     367           0 : }
     368             : 
     369             : boost::shared_ptr<std::string>
     370           0 : StructuredSyslogJsonMessage(SyslogParser::syslog_m_t v) {
     371           0 :     contrail_rapidjson::Document doc;
     372           0 :     doc.SetObject();
     373           0 :     for (std::map<std::string, SyslogParser::Holder>::iterator i=v.begin(); i!=v.end(); ++i) {
     374           0 :         SyslogParser::Holder val = i->second;
     375           0 :         const std::string &key(val.key);
     376           0 :         if (val.type == SyslogParser::str_type) {
     377           0 :             contrail_rapidjson::Value vk;
     378           0 :             contrail_rapidjson::Value value(contrail_rapidjson::kStringType);
     379           0 :             value.SetString(val.s_val.c_str(), doc.GetAllocator());
     380           0 :             doc.AddMember(vk.SetString(key.c_str(),
     381             :                                  doc.GetAllocator()), value, doc.GetAllocator());
     382           0 :         }
     383           0 :         else if (val.type == SyslogParser::int_type) {
     384           0 :             contrail_rapidjson::Value vk;
     385           0 :             contrail_rapidjson::Value value(contrail_rapidjson::kNumberType);
     386           0 :             value.SetUint64(val.i_val);
     387           0 :             doc.AddMember(vk.SetString(key.c_str(),
     388             :                                  doc.GetAllocator()), value, doc.GetAllocator());
     389           0 :         }
     390           0 :     }
     391           0 :     contrail_rapidjson::StringBuffer buffer;
     392           0 :     contrail_rapidjson::Writer<contrail_rapidjson::StringBuffer> writer(buffer);
     393           0 :     doc.Accept(writer);
     394           0 :     boost::shared_ptr<std::string> json_msg(new std::string(buffer.GetString()));
     395           0 :     return json_msg;
     396           0 : }
     397             : 
     398             : //Identify the prefix and return the VPN name if nothing matches then return routing_instance
     399           0 : const std::string get_VPNName(const std::string &routing_instance){
     400           0 :     if (routing_instance.size() > 16 && (routing_instance.compare(0, 16, "Default-reverse-") == 0)){
     401           0 :         if (routing_instance.size() > 20 && (routing_instance.compare(16, 4, "hub-") == 0)){
     402           0 :             return routing_instance.substr(20, (routing_instance.size() - 20));
     403             :         }
     404           0 :         return routing_instance.substr(16, (routing_instance.size() - 16));
     405             :     }
     406           0 :     if (routing_instance.size() > 8 && (routing_instance.compare(0, 8,"Default-") == 0)){
     407           0 :         if (routing_instance.size() > 12 && (routing_instance.compare(8, 4, "hub-") == 0)){
     408           0 :             return routing_instance.substr(12, (routing_instance.size() - 12));
     409             :         }
     410           0 :         return routing_instance.substr(8, (routing_instance.size() - 8));
     411             :    }
     412           0 :     if (routing_instance.size() > 5 && (routing_instance.compare(0, 5, "mpls-") == 0)){
     413           0 :         if (routing_instance.size() > 9 && (routing_instance.compare(5, 4, "hub-") == 0)){
     414           0 :             return routing_instance.substr(9, (routing_instance.size() - 9));
     415             :         }
     416           0 :         return routing_instance.substr(5, (routing_instance.size() - 5));
     417             :     }
     418           0 :     if (routing_instance.size() > 9 && ( routing_instance.compare(0, 9, "internet-") == 0)){
     419           0 :         if (routing_instance.size() > 13 && (routing_instance.compare(9, 4, "hub-") == 0)){
     420           0 :             return routing_instance.substr(13, (routing_instance.size() - 13));
     421             :         }
     422           0 :         return routing_instance.substr(9, (routing_instance.size() - 9));
     423             :     }
     424           0 :     return routing_instance;
     425             : }
     426             : 
     427             : //Identify the VPN name from department depending upon the case
     428             : // in which network segmentation is enabled or disabled.
     429           0 : const std::string get_VPNName(const std::string &department, 
     430             :                             const std::string &network_segmentation, 
     431             :                             const std::string &tenant_name) {
     432           0 :     std::string vpn_name = department;
     433           0 :     if (boost::iequals(network_segmentation, "Disabled") || boost::iequals(department, "Default")) {
     434           0 :             vpn_name = tenant_name + "_DefaultVPN";
     435             :     }
     436           0 :     return vpn_name;
     437           0 : }
     438             : 
     439             : 
     440           0 : void StructuredSyslogUVESummarizeData(SyslogParser::syslog_m_t v, bool summarize_user, StructuredSyslogConfig *config_obj) {
     441           0 :     SDWANMetricsRecord sdwanmetricrecord;
     442           0 :     SDWANTenantMetricsRecord sdwantenantmetricrecord;
     443           0 :     SDWANKPIMetricsRecord sdwankpimetricrecord_source;
     444             : 
     445           0 :     const std::string tag(SyslogParser::GetMapVals(v, "tag", "UNKNOWN"));
     446           0 :     const std::string process_vol_update(SyslogParser::GetMapVals(v, "process-vol-update", "False"));
     447             :     // process_vol_update as True enables diff calculation
     448             :     // from cumulative counters across sequence of traffic syslogs.
     449             :     // Note that VOL_UPDATE should be considered for counters with SLA-PROFILE
     450             :     // or TRAFFIC-TYPE because the VOL_UPDATE doesn't contain such information.
     451           0 :     LOG(DEBUG, "StructuredSyslogUVESummarizeData - process-vol-update : " << process_vol_update);
     452           0 :     bool is_close = boost::equals(tag, "APPTRACK_SESSION_CLOSE");
     453           0 :     bool is_vol_update = boost::equals(tag, "APPTRACK_SESSION_VOL_UPDATE");
     454             : 
     455           0 :     if (!boost::iequals(process_vol_update, "True")) {
     456             :         /*
     457             :         For certain sites VOL_UPDATE syslog may not supported.
     458             :         For such sites only SESSION_CLOSE syslog should be used.
     459             :         */
     460           0 :         if (is_vol_update) {
     461             :             // reject vol_update syslogs.
     462           0 :             LOG(DEBUG, "StructuredSyslogUVESummarizeData - VOL_UPDATE msg rejected.");
     463           0 :             return;
     464             :         }
     465             :     }
     466             :     
     467             : 
     468           0 :     const std::string location(SyslogParser::GetMapVals(v, "location", "UNKNOWN"));
     469           0 :     const std::string tenant(SyslogParser::GetMapVals(v, "tenant", "UNKNOWN"));
     470           0 :     std::string sla_profile(SyslogParser::GetMapVals(v, "sla-profile", "UNKNOWN"));
     471           0 :     const std::string app_category(SyslogParser::GetMapVals(v, "app-category", "UNKNOWN"));
     472           0 :     const std::string department(SyslogParser::GetMapVals(v, "source-zone-name", "UNKNOWN"));
     473           0 :     const std::string dest_zone(SyslogParser::GetMapVals(v, "destination-zone-name", "UNKNOWN"));
     474           0 :     const std::string device_id(SyslogParser::GetMapVals(v, "device", "UNKNOWN"));
     475           0 :     const std::string region(SyslogParser::GetMapVals(v, "region", "DEFAULT"));
     476           0 :     const std::string opco(SyslogParser::GetMapVals(v, "OPCO", "DEFAULT"));
     477           0 :     const std::string hubs_interfaces(SyslogParser::GetMapVals(v, "HUBS", "UNKNOWN"));
     478           0 :     const std::string uvename = tenant + "::" + location + "::" + device_id;
     479           0 :     const std::string tenantuvename = region + "::" + opco + "::" + tenant;
     480           0 :     const std::string kpi_uvename_source = location;
     481           0 :     std::string traffic_type(SyslogParser::GetMapVals(v, "active-probe-params", "UNKNOWN"));
     482           0 :     const std::string dscp_alias_code(SyslogParser::GetMapVals(v, "dscp-alias-code", "UNKNOWN"));
     483           0 :     const std::string dscp_value(SyslogParser::GetMapVals(v, "dscp-value", "UNKNOWN"));
     484           0 :     std::string nested_appname(SyslogParser::GetMapVals(v, "nested-application", "UNKNOWN"));
     485           0 :     std::string service_name(SyslogParser::GetMapVals(v, "service-name", "UNKNOWN"));
     486           0 :     std::string appname(SyslogParser::GetMapVals(v, "application", "UNKNOWN"));
     487           0 :     const std::string tenant_name(SyslogParser::GetMapVals(v, "tenantaddr", "UNKNOWN"));
     488           0 :     const std::string network_segmentation(SyslogParser::GetMapVals(v, "network-segmentation", "UNKNOWN"));
     489           0 :     bool is_site_traffic_destination = true;
     490             : 
     491             :     //counters for cumulative to differential value conversation
     492           0 :     int64_t prev_total_bytes=0, prev_bytes_from_client=0,
     493           0 :             prev_bytes_from_server=0, prev_packets_from_client=0,
     494           0 :             prev_packets_from_server=0;
     495           0 :     bool process_curr_counter = true;
     496             : 
     497           0 :     if (boost::iequals(process_vol_update, "True")) {
     498             :         // ToDo: Remove this once vol-update syslog provides sla-profile.
     499           0 :         sla_profile = "DEFAULT";
     500             :         // ToDo: Remove this once vol-update syslog provides traffic-type.
     501           0 :         traffic_type = "DEFAULT";
     502             :     }
     503             : 
     504             :     /*
     505             :     If VOL_UPDATE syslogs were processed, compute diff values
     506             :     from cumulative traffic counters for each session-id.
     507             :     Note that prev counters for the session has to be checked in all cases
     508             :     to handle shift from
     509             :     cumulative -> diff computation (in case of process vol-update)
     510             :     to just diff computation (in case of session-close only).
     511             :     */
     512           0 :     const std::string session_id_32(SyslogParser::GetMapVals(v, "session-id-32", "-1"));
     513           0 :     const std::string session_unique_key = uvename + "::" + session_id_32;
     514           0 :     std::map<std::string, uint64_t> session_prev_traffic_counters;
     515             :     bool found_session_prev_counters =
     516           0 :             config_obj->FetchSyslogSessionCounters(session_unique_key,
     517             :                                             session_prev_traffic_counters);
     518           0 :     if (found_session_prev_counters) {
     519             :         // read previous counters
     520           0 :         prev_total_bytes = session_prev_traffic_counters["total-bytes"];
     521           0 :         prev_bytes_from_client = session_prev_traffic_counters["bytes-from-client"];
     522           0 :         prev_bytes_from_server = session_prev_traffic_counters["bytes-from-server"];
     523           0 :         prev_packets_from_server = session_prev_traffic_counters["packets-from-server"];
     524           0 :         prev_packets_from_client = session_prev_traffic_counters["packets-from-client"];
     525             : 
     526             :         // update & process the counter which are new and greater than before.
     527           0 :         if ((prev_total_bytes > SyslogParser::GetMapVal(v, "total-bytes", 0)) ||
     528           0 :             (prev_packets_from_client > SyslogParser::GetMapVal(v, "packets-from-client", 0))) {
     529           0 :                 process_curr_counter = false;
     530           0 :                 LOG(ERROR, "Syslog Session Counter is OLD !. Discarding ...");
     531             :         }
     532             : 
     533           0 :         if (is_close) {
     534             :             // session is closed.
     535             :             // Remove session counters from syslog session counter map.
     536             :             int removed_sess_counter =
     537           0 :                 config_obj->RemoveSyslogSessionCounter(session_unique_key);
     538           0 :             if (removed_sess_counter == 0) {
     539           0 :                 LOG(ERROR, "Syslog Session Counter NOT removed for key " << session_unique_key);
     540             :             }
     541             :         }
     542             :     }
     543             : 
     544             :     // either this is a new session,
     545             :     // or this update has new cumulative counter count.
     546             :     // add/update counters to syslog session counter map if
     547             :     // processing vol update is enabled.
     548           0 :     if (!is_close && boost::iequals(process_vol_update, "True")) {
     549           0 :         if (process_curr_counter) {
     550           0 :             std::map<std::string, uint64_t> session_curr_traffic_counters;
     551           0 :             session_curr_traffic_counters["total-bytes"] = SyslogParser::GetMapVal(v, "total-bytes", 0);
     552           0 :             session_curr_traffic_counters["bytes-from-client"] = SyslogParser::GetMapVal(v, "bytes-from-client", 0);
     553           0 :             session_curr_traffic_counters["bytes-from-server"] = SyslogParser::GetMapVal(v, "bytes-from-server", 0);
     554           0 :             session_curr_traffic_counters["packets-from-server"] = SyslogParser::GetMapVal(v, "packets-from-server", 0);
     555           0 :             session_curr_traffic_counters["packets-from-client"] = SyslogParser::GetMapVal(v, "packets-from-client", 0);
     556           0 :             bool addSessionCounter = config_obj->AddSyslogSessionCounter(session_unique_key, session_curr_traffic_counters);
     557           0 :             if (!addSessionCounter) {
     558           0 :                 LOG(ERROR, "StructuredSyslogUVESummarizeData - Syslog message rejected.");
     559           0 :                 return;
     560             :             }
     561             : 
     562           0 :         }
     563             :     }
     564             : 
     565             : 
     566             :     // compute diff counters
     567             :     //LOG(DEBUG, "prev-total-bytes: " << prev_total_bytes);
     568           0 :     int64_t diff_total_bytes=0, diff_bytes_from_client=0,
     569           0 :             diff_bytes_from_server=0, diff_packets_from_server=0,
     570           0 :             diff_packets_from_client=0;
     571             : 
     572           0 :     if (process_curr_counter) {
     573           0 :         diff_total_bytes = SyslogParser::GetMapVal(v, "total-bytes", 0) - prev_total_bytes;
     574           0 :         diff_bytes_from_client = SyslogParser::GetMapVal(v, "bytes-from-client", 0) - prev_bytes_from_client;
     575           0 :         diff_bytes_from_server = SyslogParser::GetMapVal(v, "bytes-from-server", 0) - prev_bytes_from_server;
     576           0 :         diff_packets_from_server = SyslogParser::GetMapVal(v, "packets-from-server", 0) - prev_packets_from_server;
     577           0 :         diff_packets_from_client = SyslogParser::GetMapVal(v, "packets-from-client", 0) - prev_packets_from_client;
     578             :     }
     579           0 :     LOG(DEBUG, "Diff total-bytes: " << diff_total_bytes);
     580           0 :     LOG(DEBUG, "Diff bytes-from-client: " << diff_bytes_from_client);
     581           0 :     LOG(DEBUG, "Diff bytes-from-server: " << diff_bytes_from_server);
     582           0 :     LOG(DEBUG, "Diff packets-from-server: " << diff_packets_from_server);
     583           0 :     LOG(DEBUG, "Diff packets-from-client: " << diff_packets_from_client);
     584             : 
     585           0 :     LOG(DEBUG, "UVE: dscp-alias-code: " << dscp_alias_code);
     586           0 :     LOG(DEBUG, "UVE: dscp-value: " << dscp_value);
     587             : 
     588           0 :     if (boost::iequals(nested_appname, "UNKNOWN") && boost::iequals(appname, "UNKNOWN")) {
     589           0 :         if (!(boost::iequals(service_name, "UNKNOWN")) && !(boost::iequals(service_name, "None"))) {
     590           0 :             nested_appname =  service_name;
     591           0 :             appname = service_name;
     592             :         }
     593             :     }
     594             : 
     595             :     // nested_appname@UNKNOWN, nested_appname@dscp_alias_code nested_appname@DSCP-dscp_value
     596           0 :     std::string dscp_key = dscp_alias_code;
     597           0 :     if (dscp_value == "UNKNOWN") {
     598           0 :         dscp_key = "UNKNOWN";
     599             :     }
     600           0 :     else if (dscp_alias_code == "UNKNOWN") {
     601           0 :         dscp_key = "DSCP-" + dscp_value;
     602             :     }
     603             : 
     604           0 :     const std::string nested_appname_with_alias_code = nested_appname + "@" + dscp_key;
     605           0 :     const std::string tt_app_dept_info = traffic_type + "(" + nested_appname_with_alias_code + ":" + appname
     606           0 :                                          + "/" + app_category +  ")" + "::" + department + "::";
     607             :                                          
     608             :     //username => syslog.username or syslog.source-address
     609           0 :     std::string username(SyslogParser::GetMapVals(v, "username", "UNKNOWN"));
     610           0 :     if (boost::iequals(username, "unknown")) {
     611           0 :         username = SyslogParser::GetMapVals(v, "source-address", "UNKNOWN");
     612             :     }
     613             : 
     614           0 :     sdwanmetricrecord.set_name(uvename);
     615           0 :     sdwantenantmetricrecord.set_name(tenantuvename);
     616           0 :     sdwankpimetricrecord_source.set_name(kpi_uvename_source);
     617             : 
     618             :     //Update maps for SDWANKPI metrics record
     619           0 :     SDWANKPIMetrics_diff sdwankpimetricdiff;
     620           0 :     std::map<std::string, SDWANKPIMetrics_diff> sdwan_kpi_metrics_diff_source;
     621           0 :     if ((is_close || is_vol_update) && (boost::iequals(dest_zone, "trust"))) {
     622           0 :         const std::string routing_instance (SyslogParser::GetMapVals(v, "routing-instance", "UNKNOWN"));
     623           0 :         std::string vpn_name = "UNKNOWN";
     624           0 :         if (routing_instance != "UNKNOWN") {
     625           0 :             vpn_name = get_VPNName(routing_instance);
     626             :         }
     627             :         else {
     628             :             // this case will be true for vol_update syslogs.
     629             :             vpn_name = 
     630           0 :                 get_VPNName(department, network_segmentation, tenant_name);
     631             :         }
     632             : 
     633           0 :         const std::string destination_address (SyslogParser::GetMapVals(v, "destination-address", "UNKNOWN"));
     634           0 :         const std::string destination_interface_name (SyslogParser::GetMapVals(v, "destination-interface-name", "UNKNOWN"));
     635           0 :         if (is_close)
     636             :         {
     637           0 :             sdwankpimetricdiff.set_session_close_count(1);
     638             :         }
     639           0 :         else if (is_vol_update)
     640             :         {   
     641           0 :             sdwankpimetricdiff.set_bps(diff_total_bytes);
     642             :         }
     643             :         
     644           0 :         std::string destination_site;
     645             :         
     646             :         //Find Network only if valid VPN name is parsed from routing instance
     647           0 :         if (vpn_name != routing_instance){
     648           0 :             std::string network_key = tenant + "::" + vpn_name;
     649           0 :             destination_site = config_obj->FindNetwork(destination_address, network_key, location);
     650           0 :         }
     651             :         // if VPN name == routing instance, then VPN name is not valid and assign destination site to "UNKNOWN"
     652           0 :         if ((vpn_name == routing_instance) || destination_site.empty() ){
     653           0 :             destination_site = "UNKNOWN";
     654           0 :             is_site_traffic_destination = false;
     655             :         }
     656           0 :         LOG(DEBUG,"destination address "<< destination_address  <<" in VPN " << vpn_name <<
     657             :          " belongs to site : " << destination_site);
     658             : 
     659           0 :         std::string searchHubInterface = destination_interface_name + ",";
     660           0 :         std::size_t destination_interface_name_found = hubs_interfaces.find(searchHubInterface);
     661             : 
     662             :          // map key should be destination site for source UVE and source site for destination UVE
     663           0 :         std::string kpimetricdiff_key_source(destination_site);
     664           0 :         LOG(DEBUG,"UVE: KPI key destination : " << kpimetricdiff_key_source);
     665           0 :         sdwan_kpi_metrics_diff_source.insert(std::make_pair(kpimetricdiff_key_source, sdwankpimetricdiff));
     666             : 
     667             :         // If destination interface name belongs to hub_interfaces then traffic goes via HUB 
     668           0 :         if (destination_interface_name_found != std::string::npos){
     669           0 :             LOG(DEBUG,"destination_interface_name "<< destination_interface_name <<" found in hubs_interfaces" );
     670             : 
     671           0 :             sdwankpimetricrecord_source.set_kpi_metrics_greater_diff(sdwan_kpi_metrics_diff_source);
     672             :         }
     673             :         else {
     674           0 :             LOG(DEBUG,"destination_interface_name "<< destination_interface_name <<" NOT found in hubs_interfaces" );
     675             : 
     676           0 :             sdwankpimetricrecord_source.set_kpi_metrics_lesser_diff(sdwan_kpi_metrics_diff_source);
     677             :         }
     678           0 :     }//End of Update maps for SDWANKPI metrics record
     679           0 :     SDWANKPIMetrics::Send(sdwankpimetricrecord_source,"ObjectCPETable");
     680             : 
     681           0 :     std::string link1, link2, link1_info, link2_info, traffic_destination_link1, traffic_destination_link2, link_type_link1, link_type_link2;
     682           0 :     int64_t link1_bytes = SyslogParser::GetMapVal(v, "uplink-tx-bytes", -1);
     683           0 :     int64_t link2_bytes = SyslogParser::GetMapVal(v, "uplink-rx-bytes", -1);
     684             : 
     685             : 
     686           0 :     if (link1_bytes < 0 || (boost::iequals(process_vol_update, "True"))) {
     687           0 :         link1_bytes = diff_bytes_from_client;
     688             :     }
     689           0 :     if (link2_bytes < 0 || (boost::iequals(process_vol_update, "True"))) {
     690           0 :         link2_bytes = diff_bytes_from_server;
     691             :     }
     692             : 
     693           0 :     if (is_close || is_vol_update) {
     694             :         // Fetch Interfaces for VOL_UPDATE or SESSION_CLOSE syslogs.
     695             : 
     696           0 :         link1 = (SyslogParser::GetMapVals(v, "destination-interface-name", "UNKNOWN"));
     697             :         //vol-update syslogs does NOT contain uplink interfaces and counters.
     698           0 :         if (!(boost::iequals(process_vol_update, "True"))) {
     699           0 :             link2 = (SyslogParser::GetMapVals(v, "uplink-incoming-interface-name", "N/A"));
     700             :         }
     701           0 :         else {link2 = "N/A";}
     702             : 
     703           0 :         std::string underlay_link1 = (SyslogParser::GetMapVals(v, "underlay-destination-interface-name", "UNKNOWN"));
     704           0 :         link_type_link1 = (SyslogParser::GetMapVals(v, "link-type-destination-interface-name", "UNKNOWN"));
     705           0 :         traffic_destination_link1 = (SyslogParser::GetMapVals(v, "traffic-destination-destination-interface-name", "UNKNOWN"));
     706           0 :         std::string metadata_link1 = (SyslogParser::GetMapVals(v, "metadata-destination-interface-name", "UNKNOWN"));
     707             : 
     708           0 :         if ((traffic_destination_link1 == "HUB" || traffic_destination_link1 == "EHUB") 
     709           0 :             && (is_site_traffic_destination)) {
     710           0 :             traffic_destination_link1 = traffic_destination_link1 + "2S" ;
     711             :         }
     712           0 :         else if (traffic_destination_link1 == "HUB" || traffic_destination_link1 == "EHUB") {
     713           0 :             traffic_destination_link1 = traffic_destination_link1 + "2CBO" ;
     714             :         }
     715             : 
     716           0 :         link1_info = link1 + "@" + underlay_link1
     717           0 :             + "@" + link_type_link1 + "@" + traffic_destination_link1 + "@" + metadata_link1 ;
     718             : 
     719           0 :         if (boost::iequals(link2, "N/A")) {
     720           0 :             link2 = link1;
     721             :             //link1_bytes = SyslogParser::GetMapVal(v, "bytes-from-client", 0);
     722             :             //link2_bytes = SyslogParser::GetMapVal(v, "bytes-from-server", 0);
     723           0 :             link1_bytes = diff_bytes_from_client;
     724           0 :             link2_bytes = diff_bytes_from_server;
     725           0 :             link2_info = link1_info;
     726             :         }
     727             :         else {
     728           0 :             std::string underlay_link2 = (SyslogParser::GetMapVals(v, "underlay-uplink-incoming-interface-name", "UNKNOWN"));
     729           0 :             link_type_link2 = (SyslogParser::GetMapVals(v, "link-type-uplink-incoming-interface-name", "UNKNOWN"));
     730           0 :             traffic_destination_link2 = (SyslogParser::GetMapVals(v, "traffic-destination-uplink-incoming-interface-name", "UNKNOWN"));
     731           0 :             std::string metadata_link2 = (SyslogParser::GetMapVals(v, "metadata-uplink-incoming-interface-name", "UNKNOWN"));
     732           0 :             link2_info = link2 + "@" + underlay_link2
     733           0 :                 + "@" + link_type_link2 + "@" + traffic_destination_link2 + "@" + metadata_link2 ;
     734           0 :         }
     735             :         
     736           0 :         LOG(DEBUG,"UVE: link1_info :" << link1_info);
     737           0 :         LOG(DEBUG,"UVE: link2_info :" << link2_info);
     738           0 :     } else {
     739             :         // Fetch Interfaces for RT_FLOW_NEXTHOP_CHANGE syslog.
     740             : 
     741           0 :         if (!(boost::iequals(process_vol_update, "True"))) {
     742           0 :             link1 = (SyslogParser::GetMapVals(v, "last-destination-interface-name", "UNKNOWN"));
     743           0 :             link2 = (SyslogParser::GetMapVals(v, "last-incoming-interface-name", "UNKNOWN"));
     744             : 
     745           0 :             std::string underlay_link1 = (SyslogParser::GetMapVals(v, "underlay-last-destination-interface-name", "UNKNOWN"));
     746           0 :             link_type_link1 = (SyslogParser::GetMapVals(v, "link-type-last-destination-interface-name", "UNKNOWN"));
     747           0 :             traffic_destination_link1 = (SyslogParser::GetMapVals(v, "traffic-destination-last-destination-interface-name", "UNKNOWN"));
     748           0 :             std::string metadata_link1 = (SyslogParser::GetMapVals(v, "metadata-last-destination-interface-name", "UNKNOWN"));
     749             : 
     750           0 :             link1_info = link1 + "@" + underlay_link1
     751           0 :               + "@" + link_type_link1 + "@" + traffic_destination_link1 + "@" + metadata_link1 ;
     752             : 
     753           0 :             std::string underlay_link2 = (SyslogParser::GetMapVals(v, "underlay-last-incoming-interface-name", "UNKNOWN"));
     754           0 :             link_type_link2 = (SyslogParser::GetMapVals(v, "link-type-last-incoming-interface-name", "UNKNOWN"));
     755           0 :             traffic_destination_link2 = (SyslogParser::GetMapVals(v, "traffic-destination-last-incoming-interface-name", "UNKNOWN"));
     756           0 :             std::string metadata_link2 = (SyslogParser::GetMapVals(v, "metadata-last-incoming-interface-name", "UNKNOWN"));
     757             : 
     758           0 :             link2_info = link2 + "@" + underlay_link2
     759           0 :                 + "@" + link_type_link2 + "@" + traffic_destination_link2 + "@" + metadata_link2 ;
     760           0 :         }
     761             :         else {
     762           0 :             link1 = SyslogParser::GetMapVals(v, "destination-interface-name", "UNKNOWN");
     763           0 :             link2 = link1;
     764             : 
     765           0 :             std::string underlay_link1 = (SyslogParser::GetMapVals(v, "underlay-destination-interface-name", "UNKNOWN"));
     766           0 :             link_type_link1 = (SyslogParser::GetMapVals(v, "link-type-destination-interface-name", "UNKNOWN"));
     767           0 :             traffic_destination_link1 = (SyslogParser::GetMapVals(v, "traffic-destination-destination-interface-name", "UNKNOWN"));
     768           0 :             std::string metadata_link1 = (SyslogParser::GetMapVals(v, "metadata-destination-interface-name", "UNKNOWN"));
     769             : 
     770           0 :             link1_info = link1 + "@" + underlay_link1
     771           0 :               + "@" + link_type_link1 + "@" + traffic_destination_link1 + "@" + metadata_link1 ;
     772             :             
     773           0 :             link2_info = link1_info;
     774           0 :         }
     775             : 
     776           0 :         LOG(DEBUG,"UVE: link1_info :" << link1_info);
     777           0 :         LOG(DEBUG,"UVE: link2_info :" << link2_info);
     778             :     }
     779           0 :     SDWANMetrics_diff sdwanmetric;
     780           0 :     if (is_close || is_vol_update) {
     781             :         //int64_t output_pkts = SyslogParser::GetMapVal(v, "packets-from-client", 0);
     782             :         //int64_t input_pkts = SyslogParser::GetMapVal(v, "packets-from-server", 0);
     783           0 :         int64_t output_pkts = diff_packets_from_client;
     784           0 :         int64_t input_pkts = diff_packets_from_server;
     785           0 :         sdwanmetric.set_total_pkts(input_pkts + output_pkts);
     786           0 :         sdwanmetric.set_input_pkts(input_pkts);
     787           0 :         sdwanmetric.set_output_pkts(output_pkts);
     788           0 :         sdwanmetric.set_total_bytes(diff_total_bytes);
     789           0 :         sdwanmetric.set_output_bytes(diff_bytes_from_client);
     790           0 :         sdwanmetric.set_input_bytes(diff_bytes_from_server);
     791           0 :         if (is_close) {
     792           0 :             sdwanmetric.set_session_duration(SyslogParser::GetMapVal(v, "elapsed-time", 0));
     793           0 :             sdwanmetric.set_session_count(1);
     794             :         }
     795             :         
     796             :         // Map: app_metrics_diff_sla
     797           0 :         std::map<std::string, SDWANMetrics_diff> app_metrics_diff_sla;
     798           0 :         std::string slamap_key(tt_app_dept_info + sla_profile);
     799           0 :         LOG(DEBUG,"UVE: app_metrics_diff_sla key :" << slamap_key);
     800           0 :         app_metrics_diff_sla.insert(std::make_pair(slamap_key, sdwanmetric));
     801           0 :         sdwanmetricrecord.set_app_metrics_diff_sla(app_metrics_diff_sla);
     802             : 
     803             :         // Map: app_metrics_diff_user
     804           0 :         if (summarize_user == true) {
     805           0 :             std::map<std::string, SDWANMetrics_diff> app_metrics_diff_user;
     806           0 :             std::string usermap_key(tt_app_dept_info + username);
     807           0 :             LOG(DEBUG,"UVE: app_metrics_diff_user key :" << usermap_key);
     808           0 :             app_metrics_diff_user.insert(std::make_pair(usermap_key, sdwanmetric));
     809           0 :             sdwanmetricrecord.set_app_metrics_diff_user(app_metrics_diff_user);
     810           0 :         }
     811             :     //replaced the fuction to the outerloop for both session_close and rt_flow_next_hop_change syslog
     812             :     // // Map: tenant_metrics_diff_sla
     813             :     // std::map<std::string, SDWANMetrics_diff> tenant_metrics_diff_sla;
     814             :     // std::string tenantmetric_key(location + "::" + sla_profile + "::" + traffic_type + "@" + traffic_destination_link + "@" + link_type_link);
     815             :     // LOG(DEBUG,"UVE: tenant_metrics_diff_sla key :" << tenantmetric_key);
     816             :     // tenant_metrics_diff_sla.insert(std::make_pair(tenantmetric_key, sdwanmetric));
     817             :     // sdwantenantmetricrecord.set_tenant_metrics_diff_sla(tenant_metrics_diff_sla);
     818             :     // SDWANTenantMetrics::Send(sdwantenantmetricrecord, "ObjectCPETable");
     819           0 :     }
     820             :     // Map: app_metrics_diff_link
     821             :     // Map: link_metrics_diff_traffic_type
     822           0 :     SDWANMetrics_diff sdwanmetric1;
     823           0 :     SDWANMetrics_diff sdwanmetric2;
     824           0 :     std::map<std::string, SDWANMetrics_diff> app_metrics_diff_link;
     825           0 :     std::map<std::string, SDWANMetrics_diff> link_metrics_diff_traffic_type;
     826           0 :     if (boost::equals(link1, link2)) {
     827           0 :         sdwanmetric1.set_total_bytes(link1_bytes + link2_bytes);
     828           0 :         sdwanmetric1.set_input_bytes(link2_bytes);
     829           0 :         sdwanmetric1.set_output_bytes(link1_bytes);
     830           0 :         if (is_close) {
     831           0 :             sdwanmetric1.set_session_duration(SyslogParser::GetMapVal(v, "elapsed-time", 0));
     832           0 :             sdwanmetric1.set_session_count(1);
     833             :         }
     834           0 :         std::string linkmap_key(tt_app_dept_info + link1_info);
     835           0 :         std::string linkmetricmap_key(link1_info + "::" + sla_profile + "::" + traffic_type);
     836           0 :         LOG(DEBUG,"UVE: app_metrics_diff_link key :" << linkmap_key);
     837           0 :         app_metrics_diff_link.insert(std::make_pair(linkmap_key, sdwanmetric1));
     838           0 :         sdwanmetricrecord.set_app_metrics_diff_link(app_metrics_diff_link);
     839             : 
     840             :         // Map: tenant_metrics_diff_sla
     841           0 :         std::map<std::string, SDWANMetrics_diff> tenant_metrics_diff_sla;
     842           0 :         LOG(DEBUG,"UVE: link_metrics_*_traffic_type key :" << linkmetricmap_key);
     843           0 :         link_metrics_diff_traffic_type.insert(std::make_pair(linkmetricmap_key, sdwanmetric1));
     844           0 :         sdwanmetricrecord.set_link_metrics_diff_traffic_type(link_metrics_diff_traffic_type);
     845             : 
     846             :         // Update Map: tenant_metrics_diff_sla
     847           0 :         std::string tenantmetric_key(location + "::" + sla_profile +
     848           0 :                                     "::" + traffic_type +
     849           0 :                                     "@" + traffic_destination_link1 +
     850           0 :                                     "@" + link_type_link1);
     851             : 
     852           0 :         LOG(DEBUG,"UVE: tenant_metrics_diff_sla key :" << tenantmetric_key);
     853           0 :         tenant_metrics_diff_sla.insert(std::make_pair(tenantmetric_key, sdwanmetric1));
     854           0 :         sdwantenantmetricrecord.set_tenant_metrics_diff_sla(tenant_metrics_diff_sla);
     855             : 
     856             : 
     857             : 
     858             : 
     859             :         /*
     860             :         // Update maps for underlay links if needed
     861             :         if (!(boost::equals(link1, underlay_link1))) {
     862             :             std::string linkmap_key(tt_app_dept_info + underlay_link1);
     863             :             std::string linkmetricmap_key(underlay_link1 + "::" + sla_profile + "::" + traffic_type);
     864             :             LOG(DEBUG,"UVE: underlay app_metrics_diff_link key :" << linkmap_key);
     865             :             LOG(DEBUG,"UVE: underlay link_metrics_*_traffic_type key :" << linkmetricmap_key);
     866             :             app_metrics_diff_link.insert(std::make_pair(linkmap_key, sdwanmetric1));
     867             :             link_metrics_diff_traffic_type.insert(std::make_pair(linkmetricmap_key, sdwanmetric1));
     868             :             sdwanmetricrecord.set_app_metrics_diff_link(app_metrics_diff_link);
     869             :             sdwanmetricrecord.set_link_metrics_diff_traffic_type(link_metrics_diff_traffic_type);
     870             :         }
     871             :         */
     872           0 :     } else {
     873           0 :         sdwanmetric1.set_total_bytes(link1_bytes);
     874           0 :         sdwanmetric1.set_output_bytes(link1_bytes);
     875           0 :         sdwanmetric1.set_input_bytes(0);
     876           0 :         sdwanmetric2.set_total_bytes(link2_bytes);
     877           0 :         sdwanmetric2.set_output_bytes(0);
     878           0 :         sdwanmetric2.set_input_bytes(link2_bytes);
     879           0 :         if (is_close) {
     880           0 :             sdwanmetric1.set_session_duration(SyslogParser::GetMapVal(v, "elapsed-time", 0));
     881           0 :             sdwanmetric1.set_session_count(1);
     882           0 :             sdwanmetric2.set_session_duration(SyslogParser::GetMapVal(v, "elapsed-time", 0));
     883           0 :             sdwanmetric2.set_session_count(1);
     884             :         }
     885             : 
     886           0 :         std::string linkmap_key1(tt_app_dept_info + link1_info);
     887           0 :         std::string linkmap_key2(tt_app_dept_info + link2_info);
     888           0 :         LOG(DEBUG,"UVE: app_metrics_diff_link key1 :" << linkmap_key1);
     889           0 :         LOG(DEBUG,"UVE: app_metrics_diff_link key2 :" << linkmap_key2);
     890           0 :         app_metrics_diff_link.insert(std::make_pair(linkmap_key1, sdwanmetric1));
     891           0 :         app_metrics_diff_link.insert(std::make_pair(linkmap_key2, sdwanmetric2));
     892           0 :         sdwanmetricrecord.set_app_metrics_diff_link(app_metrics_diff_link);
     893             : 
     894           0 :         std::string linkmetricmap_key1(link1_info + "::" + sla_profile + "::" + traffic_type);
     895           0 :         std::string linkmetricmap_key2(link2_info + "::" + sla_profile + "::" + traffic_type);
     896           0 :         LOG(DEBUG,"UVE: link_metrics_*_traffic_type key1 :" << linkmetricmap_key1);
     897           0 :         LOG(DEBUG,"UVE: link_metrics_*_traffic_type key2 :" << linkmetricmap_key2);
     898           0 :         link_metrics_diff_traffic_type.insert(std::make_pair(linkmetricmap_key1, sdwanmetric1));
     899           0 :         link_metrics_diff_traffic_type.insert(std::make_pair(linkmetricmap_key2, sdwanmetric2));
     900           0 :         sdwanmetricrecord.set_link_metrics_diff_traffic_type(link_metrics_diff_traffic_type);
     901             : 
     902             :         // Map: tenant_metrics_diff_sla
     903           0 :         std::map<std::string, SDWANMetrics_diff> tenant_metrics_diff_sla;
     904           0 :         std::string tenantmetric_key1(location + "::" +
     905           0 :                                     sla_profile + "::" +
     906           0 :                                     traffic_type + "@" +
     907           0 :                                     traffic_destination_link1 + "@" +
     908           0 :                                     link_type_link1);
     909           0 :         std::string tenantmetric_key2(location + "::" +
     910           0 :                                     sla_profile + "::" +
     911           0 :                                     traffic_type + "@" +
     912           0 :                                     traffic_destination_link2 + "@" + 
     913           0 :                                     link_type_link2);
     914           0 :         LOG(DEBUG,"UVE: tenant_metrics_diff_sla key1 :" << tenantmetric_key1);
     915           0 :         LOG(DEBUG,"UVE: tenant_metrics_diff_sla key2 :" << tenantmetric_key2);
     916           0 :         tenant_metrics_diff_sla.insert(std::make_pair(tenantmetric_key1, sdwanmetric1));
     917           0 :         tenant_metrics_diff_sla.insert(std::make_pair(tenantmetric_key2, sdwanmetric2));
     918           0 :         sdwantenantmetricrecord.set_tenant_metrics_diff_sla(tenant_metrics_diff_sla);
     919             : 
     920             :         // Update maps for underlay links if needed
     921             :         /*
     922             :         if ((!(boost::equals(link1, underlay_link1))) ||
     923             :            (!(boost::equals(link2, underlay_link2)))) {
     924             :             if (!(boost::equals(link1, underlay_link1))) {
     925             :                 std::string linkmap_key1(tt_app_dept_info + underlay_link1);
     926             :                 std::string linkmetricmap_key1(underlay_link1 + "::" + sla_profile + "::" + traffic_type);
     927             :                 LOG(DEBUG,"UVE: underlay app_metrics_diff_link key1 :" << linkmap_key1);
     928             :                 LOG(DEBUG,"UVE: underlay link_metrics_*_traffic_type key1 :" << linkmetricmap_key1);
     929             :                 app_metrics_diff_link.insert(std::make_pair(linkmap_key1, sdwanmetric1));
     930             :                 link_metrics_diff_traffic_type.insert(std::make_pair(linkmetricmap_key1, sdwanmetric1));
     931             :             }
     932             :             if ((!(boost::equals(link2, underlay_link2))) &&
     933             :                (!(boost::equals(underlay_link1, underlay_link2)))) {
     934             :                 std::string linkmap_key2(tt_app_dept_info + underlay_link2);
     935             :                 std::string linkmetricmap_key2(underlay_link2 + "::" + sla_profile + "::" + traffic_type);
     936             :                 LOG(DEBUG,"UVE: underlay app_metrics_diff_link key2 :" << linkmap_key2);
     937             :                 LOG(DEBUG,"UVE: underlay link_metrics_*_traffic_type key2 :" << linkmetricmap_key2);
     938             :                 app_metrics_diff_link.insert(std::make_pair(linkmap_key2, sdwanmetric2));
     939             :                 link_metrics_diff_traffic_type.insert(std::make_pair(linkmetricmap_key2, sdwanmetric2));
     940             : 
     941             :             }
     942             :             sdwanmetricrecord.set_app_metrics_diff_link(app_metrics_diff_link);
     943             :             sdwanmetricrecord.set_link_metrics_diff_traffic_type(link_metrics_diff_traffic_type);
     944             :         }
     945             :         */
     946           0 :     }
     947             : 
     948           0 :     SDWANMetrics::Send(sdwanmetricrecord, "ObjectCPETable");
     949           0 :     SDWANTenantMetrics::Send(sdwantenantmetricrecord, "ObjectCPETable");
     950             : 
     951           0 :     return;
     952           0 : }
     953             : 
     954             : 
     955           0 : double calculate_link_score(int64_t latency, int64_t packet_loss, int64_t jitter,
     956             :                            int64_t effective_latency_threshold, int64_t latency_factor,
     957             :                            int64_t jitter_factor, int64_t packet_loss_factor) {
     958             : 
     959             :     double effective_latency, r_factor, mos, latency_ms, jitter_ms;
     960           0 :     latency_ms = latency/1000;  // latency in milli secs
     961           0 :     jitter_ms = jitter/1000;    // jitter in milli secs
     962             : 
     963             :     // Setting the default values for coefficients
     964           0 :     if (effective_latency_threshold == 0)
     965           0 :         effective_latency_threshold = 160;
     966           0 :     if (latency_factor == 0)
     967           0 :         latency_factor = 100;
     968           0 :     if (jitter_factor == 0)
     969           0 :         jitter_factor = 200;
     970           0 :     if (packet_loss_factor == 0)
     971           0 :         packet_loss_factor = 250;
     972             : 
     973           0 :     LOG(DEBUG, "Link score calculation coefficients, effective_latency_threshold : "
     974             :                                                    << effective_latency_threshold
     975             :                                                    << ", latency_factor : " << latency_factor
     976             :                                                    << ", jitter_factor : " << jitter_factor
     977             :                                                    << ", packet_loss_factor : " 
     978             :                                                    << packet_loss_factor);
     979             : 
     980             :     // Step-1: Calculate EffectiveLatency = (AvgLatency + 2*AvgPositiveJitter + 10)
     981           0 :     effective_latency =
     982           0 :     ((latency_ms * (latency_factor/100.0)) + ((jitter_factor/100.0)*jitter_ms) + 10);
     983             :     // Step-2: Calculate Intermediate R-Value
     984           0 :     if (effective_latency < effective_latency_threshold) {
     985           0 :         r_factor = 93.2 - (effective_latency/40);
     986             :     }
     987             :     else {
     988           0 :         r_factor = 93.2 - (effective_latency - 120)/10;
     989             :     }
     990             :     // Step-3: Adjust R-Value for PacketLoss
     991           0 :     r_factor =  r_factor - (packet_loss * packet_loss_factor/100.0);
     992             :     // Step-4: Calculate MeanOpinionScore
     993           0 :     if (r_factor < 0 ){
     994           0 :         mos = 1;
     995             :     }
     996           0 :     else if ((r_factor > 0) && (r_factor < 100)) {
     997           0 :         mos = 1 + (0.035) * r_factor + (0.000007) * r_factor * (r_factor - 60) * (100 - r_factor);
     998             :     }
     999             :     else {
    1000           0 :         mos = 4.5;
    1001             :     }
    1002           0 :     LOG(DEBUG, "Calculated Mean Opinion Score (link_score) for sla params is : " << mos);
    1003           0 :     return (mos * 20);
    1004             : }
    1005             : 
    1006             : 
    1007           0 : void StructuredSyslogUVESummarizeAppQoePSMR(SyslogParser::syslog_m_t v, bool summarize_user) {
    1008           0 :     SDWANMetricsRecord sdwanmetricrecord;
    1009           0 :     SDWANTenantMetricsRecord sdwantenantmetricrecord;
    1010           0 :     const std::string location(SyslogParser::GetMapVals(v, "location", "UNKNOWN"));
    1011           0 :     const std::string tenant(SyslogParser::GetMapVals(v, "tenant", "UNKNOWN"));
    1012           0 :     const std::string link(SyslogParser::GetMapVals(v, "destination-interface-name", "UNKNOWN"));
    1013           0 :     const std::string sla_profile(SyslogParser::GetMapVals(v, "sla-profile", "UNKNOWN"));
    1014           0 :     const std::string app_category(SyslogParser::GetMapVals(v, "app-category", "UNKNOWN"));
    1015           0 :     const std::string department(SyslogParser::GetMapVals(v, "source-zone-name", "UNKNOWN"));
    1016           0 :     const std::string device_id(SyslogParser::GetMapVals(v, "device", "UNKNOWN"));
    1017           0 :     const std::string region(SyslogParser::GetMapVals(v, "region", "DEFAULT"));
    1018           0 :     const std::string opco(SyslogParser::GetMapVals(v, "OPCO", "DEFAULT"));
    1019           0 :     const std::string uvename = tenant + "::" + location + "::" + device_id;
    1020           0 :     const std::string tenantuvename = region + "::" + opco + "::" + tenant;
    1021           0 :     const std::string traffic_type(SyslogParser::GetMapVals(v, "active-probe-params", "UNKNOWN"));
    1022           0 :     const std::string ip_dscp(SyslogParser::GetMapVals(v, "ip-dscp", "UNKNOWN"));
    1023           0 :     const std::string dscp_alias_code(SyslogParser::GetMapVals(v, "dscp-alias-code", "UNKNOWN"));
    1024           0 :     std::string nested_appname(SyslogParser::GetMapVals(v, "nested-application", "UNKNOWN"));
    1025           0 :     std::string service_name(SyslogParser::GetMapVals(v, "service-name", "UNKNOWN"));
    1026           0 :     std::string appname(SyslogParser::GetMapVals(v, "application", "UNKNOWN"));
    1027             : 
    1028           0 :     const std::string underlay_link = (SyslogParser::GetMapVals(v, "underlay-destination-interface-name", "UNKNOWN"));
    1029           0 :     const std::string link_type_link = (SyslogParser::GetMapVals(v, "link-type-destination-interface-name", "UNKNOWN"));
    1030           0 :     const std::string traffic_destination_link = (SyslogParser::GetMapVals(v, "traffic-destination-destination-interface-name", "UNKNOWN"));
    1031           0 :     const std::string metadata_link = (SyslogParser::GetMapVals(v, "metadata-destination-interface-name", "UNKNOWN"));
    1032           0 :     const std::string link_info = link + "@" + underlay_link
    1033           0 :         + "@" + link_type_link + "@" + traffic_destination_link + "@" + metadata_link ;
    1034             : 
    1035           0 :     LOG(DEBUG,"UVE: dscp-alias-code: " << dscp_alias_code);
    1036           0 :     LOG(DEBUG,"UVE: ip-dscp: " << ip_dscp);
    1037             : 
    1038           0 :     if (boost::iequals(nested_appname, "UNKNOWN") && boost::iequals(appname, "UNKNOWN")) {
    1039           0 :         if (!(boost::iequals(service_name, "UNKNOWN")) && !(boost::iequals(service_name, "None"))) {
    1040           0 :             nested_appname =  service_name;
    1041           0 :             appname = service_name;
    1042             :         }
    1043             :     }
    1044             : 
    1045             :     // nested_appname@UNKNOWN, nested_appname@dscp_alias_code nested_appname@DSCP-dscp_value
    1046           0 :     std::string dscp_key = "DSCP-" + dscp_alias_code;
    1047           0 :     if (ip_dscp == "UNKNOWN") {
    1048           0 :         dscp_key = "UNKNOWN";
    1049             :     }
    1050           0 :     else if (dscp_alias_code == "UNKNOWN") {
    1051           0 :         dscp_key = "DSCP-" + ip_dscp;
    1052             :     }
    1053             : 
    1054           0 :     const std::string nested_appname_with_alias_code = nested_appname + "@" + dscp_key;
    1055             : 
    1056           0 :     const std::string tt_app_dept_info = traffic_type + "(" + nested_appname_with_alias_code + ":" + appname
    1057           0 :                                          + "/" + app_category +  ")" + "::" + department + "::";
    1058             : 
    1059             :     //username => syslog.username or syslog.source-address
    1060           0 :     std::string username(SyslogParser::GetMapVals(v, "username", "UNKNOWN"));
    1061           0 :     if (boost::iequals(username, "unknown")) {
    1062           0 :         username = SyslogParser::GetMapVals(v, "source-address", "UNKNOWN");
    1063             :     }
    1064           0 :     sdwanmetricrecord.set_name(uvename);
    1065           0 :     sdwantenantmetricrecord.set_name(tenantuvename);
    1066           0 :     SDWANMetrics_dial sdwanmetric;
    1067           0 :     int64_t pkt_loss = SyslogParser::GetMapVal(v, "pkt-loss", -1);
    1068           0 :     int64_t rtt = SyslogParser::GetMapVal(v, "rtt", -1);
    1069           0 :     int64_t rtt_jitter = SyslogParser::GetMapVal(v, "rtt-jitter", -1);
    1070           0 :     int64_t egress_jitter = SyslogParser::GetMapVal(v, "egress-jitter", -1);
    1071           0 :     int64_t ingress_jitter = SyslogParser::GetMapVal(v, "ingress-jitter", -1);
    1072             : 
    1073             :      /*
    1074             :         Device sends high values for SLA parameters in syslog
    1075             :         when probe is not successfull or for some reason
    1076             :         device is not able to calculate SLA parameters.
    1077             :         High values for -
    1078             :         rtt -> 4294967295
    1079             :         rtt_jitter -> 4294967295
    1080             :         pkt_loss -> 255
    1081             :         These high values should NOT be used for calculation and
    1082             :         should be avoided.
    1083             :     */
    1084           0 :     if (rtt != -1 && rtt != 4294967295) {
    1085           0 :         sdwanmetric.set_rtt(rtt);
    1086             :     }
    1087           0 :     if (rtt_jitter != -1 && rtt_jitter != 4294967295) {
    1088           0 :         sdwanmetric.set_rtt_jitter(rtt_jitter);
    1089             :     }
    1090           0 :     if (egress_jitter != -1 && egress_jitter != 4294967295) {
    1091           0 :         sdwanmetric.set_egress_jitter(egress_jitter);
    1092             :     }
    1093           0 :     if (ingress_jitter != -1 && ingress_jitter != 4294967295) {
    1094           0 :         sdwanmetric.set_ingress_jitter(ingress_jitter);
    1095             :     }
    1096           0 :     if (pkt_loss != -1 && pkt_loss != 255) {
    1097             :         // this check is added to correct the cases in which device sends
    1098             :         // incorrect values containing loss% to be more than 100.
    1099           0 :         if (pkt_loss > 100) {
    1100           0 :             pkt_loss = 100;
    1101             :         }
    1102           0 :         sdwanmetric.set_pkt_loss(pkt_loss);
    1103             :     }
    1104           0 :     if ((rtt != -1) && (rtt != 4294967295) &&
    1105           0 :         (rtt_jitter != -1) && (rtt_jitter != 4294967295) &&
    1106           0 :         (pkt_loss != -1) && (pkt_loss != 255)) {
    1107           0 :         sdwanmetric.set_score((int64_t)calculate_link_score(rtt/2, pkt_loss, rtt_jitter,
    1108             :                              SyslogParser::GetMapVal(v, "effective-latency-threshold",0),
    1109             :                              SyslogParser::GetMapVal(v, "latency-factor",0),
    1110             :                              SyslogParser::GetMapVal(v, "jitter-factor",0),
    1111             :                              SyslogParser::GetMapVal(v, "packet-loss-factor",0) ));
    1112             :     }
    1113             : 
    1114             :     // Map:  app_metrics_dial_sla
    1115           0 :     std::map<std::string, SDWANMetrics_dial> app_metrics_dial_sla;
    1116           0 :     std::string slamap_key(tt_app_dept_info + sla_profile);
    1117           0 :     LOG(DEBUG,"UVE: app_metrics_dial_sla key :" << slamap_key);
    1118           0 :     app_metrics_dial_sla.insert(std::make_pair(slamap_key, sdwanmetric));
    1119           0 :     sdwanmetricrecord.set_app_metrics_dial_sla(app_metrics_dial_sla);
    1120             : 
    1121             :     // Map:  app_metrics_dial_user
    1122           0 :     if (summarize_user == true) {
    1123           0 :         std::map<std::string, SDWANMetrics_dial> app_metrics_dial_user;
    1124           0 :         std::string usermap_key(tt_app_dept_info + username);
    1125           0 :         LOG(DEBUG,"UVE: app_metrics_dial_user key :" << usermap_key);
    1126           0 :         app_metrics_dial_user.insert(std::make_pair(usermap_key, sdwanmetric));
    1127           0 :         sdwanmetricrecord.set_app_metrics_dial_user(app_metrics_dial_user);
    1128           0 :     }
    1129             :     // Map:  app_metrics_dial_link
    1130           0 :     std::map<std::string, SDWANMetrics_dial> app_metrics_dial_link;
    1131           0 :     std::string linkmap_key(tt_app_dept_info + link_info);
    1132           0 :     LOG(DEBUG,"UVE: app_metrics_dial_link key :" << linkmap_key);
    1133           0 :     app_metrics_dial_link.insert(std::make_pair(linkmap_key, sdwanmetric));
    1134           0 :     sdwanmetricrecord.set_app_metrics_dial_link(app_metrics_dial_link);
    1135             : 
    1136             :     // Map:  link_metrics_dial_traffic_type
    1137           0 :     std::map<std::string, SDWANMetrics_dial> link_metrics_dial_traffic_type;
    1138           0 :     std::string linkmetric_key(link_info + "::" + sla_profile + "::" + traffic_type);
    1139           0 :     LOG(DEBUG,"UVE: link_metrics_dial_traffic_type key :" << linkmetric_key);
    1140           0 :     link_metrics_dial_traffic_type.insert(std::make_pair(linkmetric_key, sdwanmetric));
    1141           0 :     sdwanmetricrecord.set_link_metrics_dial_traffic_type(link_metrics_dial_traffic_type);
    1142             : 
    1143             :     // Map: tenant_metrics_dial_sla
    1144           0 :     std::map<std::string, SDWANMetrics_dial> tenant_metrics_dial_sla;
    1145           0 :     std::string tenantmetric_key(location + "::" + sla_profile + "::" + traffic_type);
    1146           0 :     LOG(DEBUG,"UVE: tenant_metrics_dial_sla key :" << tenantmetric_key);
    1147           0 :     tenant_metrics_dial_sla.insert(std::make_pair(tenantmetric_key, sdwanmetric));
    1148           0 :     sdwantenantmetricrecord.set_tenant_metrics_dial_sla(tenant_metrics_dial_sla);
    1149             : 
    1150           0 :     SDWANTenantMetrics::Send(sdwantenantmetricrecord, "ObjectCPETable");
    1151           0 :     SDWANMetrics::Send(sdwanmetricrecord, "ObjectCPETable");
    1152           0 :     return;
    1153           0 : }
    1154             : 
    1155           0 : void StructuredSyslogUVESummarizeAppQoeBPS(SyslogParser::syslog_m_t v, bool summarize_user) {
    1156           0 :     SDWANMetricsRecord sdwanmetricrecord;
    1157           0 :     SDWANTenantMetricsRecord sdwantenantmetricrecord;
    1158           0 :     const std::string location(SyslogParser::GetMapVals(v, "location", "UNKNOWN"));
    1159           0 :     const std::string tenant(SyslogParser::GetMapVals(v, "tenant", "UNKNOWN"));
    1160           0 :     const std::string link(SyslogParser::GetMapVals(v, "previous-interface", "UNKNOWN"));
    1161           0 :     const std::string sla_profile(SyslogParser::GetMapVals(v, "sla-profile", "UNKNOWN"));
    1162           0 :     const std::string app_category(SyslogParser::GetMapVals(v, "app-category", "UNKNOWN"));
    1163           0 :     const std::string department(SyslogParser::GetMapVals(v, "source-zone-name", "UNKNOWN"));
    1164           0 :     const std::string device_id(SyslogParser::GetMapVals(v, "device", "UNKNOWN"));
    1165           0 :     const std::string region(SyslogParser::GetMapVals(v, "region", "DEFAULT"));
    1166           0 :     const std::string opco(SyslogParser::GetMapVals(v, "OPCO", "DEFAULT"));
    1167           0 :     const std::string uvename = tenant + "::" + location + "::" + device_id;
    1168           0 :     const std::string tenantuvename = region + "::" + opco + "::" + tenant;
    1169           0 :     const std::string traffic_type(SyslogParser::GetMapVals(v, "active-probe-params", "UNKNOWN"));
    1170           0 :     const std::string ip_dscp(SyslogParser::GetMapVals(v, "dscp-alias-code", "UNKNOWN"));
    1171           0 :     const std::string dscp_alias_code(SyslogParser::GetMapVals(v, "ip-dscp", "UNKNOWN"));
    1172           0 :     std::string nested_appname(SyslogParser::GetMapVals(v, "nested-application", "UNKNOWN"));
    1173           0 :     std::string service_name(SyslogParser::GetMapVals(v, "service-name", "UNKNOWN"));
    1174           0 :     std::string appname(SyslogParser::GetMapVals(v, "application", "UNKNOWN"));
    1175             : 
    1176           0 :     const std::string underlay_link = (SyslogParser::GetMapVals(v, "underlay-destination-interface-name", "UNKNOWN"));
    1177           0 :     const std::string link_type_link = (SyslogParser::GetMapVals(v, "link-type-destination-interface-name", "UNKNOWN"));
    1178           0 :     const std::string traffic_destination_link = (SyslogParser::GetMapVals(v, "traffic-destination-destination-interface-name", "UNKNOWN"));
    1179           0 :     const std::string metadata_link = (SyslogParser::GetMapVals(v, "metadata-destination-interface-name", "UNKNOWN"));
    1180           0 :     const std::string link_info = link + "@" + underlay_link
    1181           0 :         + "@" + link_type_link + "@" + traffic_destination_link + "@" + metadata_link ;
    1182             : 
    1183           0 :     LOG(DEBUG,"UVE: dscp-alias-code: " << dscp_alias_code);
    1184           0 :     LOG(DEBUG,"UVE: ip-dscp: " << ip_dscp);
    1185             : 
    1186           0 :     if (boost::iequals(nested_appname, "UNKNOWN") && boost::iequals(appname, "UNKNOWN")) {
    1187           0 :         if (!(boost::iequals(service_name, "UNKNOWN")) && !(boost::iequals(service_name, "None"))) {
    1188           0 :             nested_appname =  service_name;
    1189           0 :             appname = service_name;
    1190             :         }
    1191             :     }
    1192             : 
    1193             :     // nested_appname@UNKNOWN, nested_appname@dscp_alias_code nested_appname@DSCP-dscp_value
    1194           0 :     std::string dscp_key = "DSCP-" + dscp_alias_code;
    1195           0 :     if (ip_dscp == "UNKNOWN") {
    1196           0 :         dscp_key = "UNKNOWN";
    1197             :     }
    1198           0 :     else if (dscp_alias_code == "UNKNOWN") {
    1199           0 :         dscp_key = "DSCP-" + ip_dscp;
    1200             :     }
    1201             : 
    1202           0 :     const std::string nested_appname_with_alias_code = nested_appname + "@" + dscp_key;
    1203             : 
    1204           0 :     const std::string tt_app_dept_info = traffic_type + "(" + nested_appname_with_alias_code + ":" + appname
    1205           0 :                                          + "/" + app_category +  ")" + "::" + department + "::";
    1206           0 :     int64_t elapsed_time = SyslogParser::GetMapVal(v, "elapsed-time", 0);
    1207           0 :     const std::string reason = SyslogParser::GetMapVals(v, "reason", "UNKNOWN");
    1208             :     //username => syslog.username or syslog.source-address
    1209           0 :     std::string username(SyslogParser::GetMapVals(v, "username", "UNKNOWN"));
    1210           0 :     if (boost::iequals(username, "unknown")) {
    1211           0 :         username = SyslogParser::GetMapVals(v, "source-address", "UNKNOWN");
    1212             :     }
    1213           0 :     sdwanmetricrecord.set_name(uvename);
    1214           0 :     sdwantenantmetricrecord.set_name(tenantuvename);
    1215             : 
    1216           0 :     SDWANMetrics_diff sdwanmetric;
    1217           0 :     if ((elapsed_time > 2) && (!(boost::iequals(reason, "session close")))){
    1218           0 :         sdwanmetric.set_session_switch_count(1);
    1219             :     }
    1220             : 
    1221             :     // Map: app_metrics_diff_sla
    1222           0 :     std::map<std::string, SDWANMetrics_diff> app_metrics_diff_sla;
    1223           0 :     std::string slamap_key(tt_app_dept_info + sla_profile);
    1224           0 :     LOG(DEBUG,"UVE: app_metrics_diff_sla key :" << slamap_key);
    1225           0 :     app_metrics_diff_sla.insert(std::make_pair(slamap_key, sdwanmetric));
    1226           0 :     sdwanmetricrecord.set_app_metrics_diff_sla(app_metrics_diff_sla);
    1227             : 
    1228             :     // Map: app_metrics_diff_user
    1229           0 :     if (summarize_user == true) {
    1230           0 :         std::map<std::string, SDWANMetrics_diff> app_metrics_diff_user;
    1231           0 :         std::string usermap_key(tt_app_dept_info + username);
    1232           0 :         LOG(DEBUG,"UVE: app_metrics_diff_user key :" << usermap_key);
    1233           0 :         app_metrics_diff_user.insert(std::make_pair(usermap_key, sdwanmetric));
    1234           0 :         sdwanmetricrecord.set_app_metrics_diff_user(app_metrics_diff_user);
    1235           0 :     }
    1236             : 
    1237             :     // Map: app_metrics_diff_link
    1238           0 :     std::map<std::string, SDWANMetrics_diff> app_metrics_diff_link;
    1239           0 :     std::string linkmap_key(tt_app_dept_info + link_info);
    1240           0 :     LOG(DEBUG,"UVE: app_metrics_diff_link key :" << linkmap_key);
    1241           0 :     app_metrics_diff_link.insert(std::make_pair(linkmap_key, sdwanmetric));
    1242           0 :     sdwanmetricrecord.set_app_metrics_diff_link(app_metrics_diff_link);
    1243             : 
    1244             :     // Map: tenant_metrics_diff_sla
    1245           0 :     std::map<std::string, SDWANMetrics_diff> tenant_metrics_diff_sla;
    1246           0 :     std::string tenantmetric_key(location + "::" + sla_profile + "::" + traffic_type + "@" + traffic_destination_link + "@" + link_type_link);
    1247           0 :     LOG(DEBUG,"UVE: tenant_metrics_diff_sla key :" << tenantmetric_key);
    1248           0 :     tenant_metrics_diff_sla.insert(std::make_pair(tenantmetric_key, sdwanmetric));
    1249           0 :     sdwantenantmetricrecord.set_tenant_metrics_diff_sla(tenant_metrics_diff_sla);
    1250             : 
    1251             :     // Map: link_metrics_diff_traffic_type
    1252           0 :     std::map<std::string, SDWANMetrics_diff> link_metrics_diff_traffic_type;
    1253           0 :     std::string linkmetricmap_key(link_info + "::" + sla_profile + "::" + traffic_type);
    1254           0 :     LOG(DEBUG,"UVE: link_metrics_diff_traffic_type key :" << linkmetricmap_key);
    1255           0 :     link_metrics_diff_traffic_type.insert(std::make_pair(linkmetricmap_key, sdwanmetric));
    1256           0 :     sdwanmetricrecord.set_link_metrics_diff_traffic_type(link_metrics_diff_traffic_type);
    1257             : 
    1258           0 :     SDWANMetrics::Send(sdwanmetricrecord, "ObjectCPETable");
    1259           0 :     SDWANTenantMetrics::Send(sdwantenantmetricrecord, "ObjectCPETable");
    1260             : 
    1261           0 :     return;
    1262           0 : }
    1263             : 
    1264           0 : void StructuredSyslogUVESummarizeAppQoeSMV(SyslogParser::syslog_m_t v, bool summarize_user) {
    1265           0 :     SDWANMetricsRecord sdwanmetricrecord;
    1266           0 :     SDWANTenantMetricsRecord sdwantenantmetricrecord;
    1267           0 :     const std::string location(SyslogParser::GetMapVals(v, "location", "UNKNOWN"));
    1268           0 :     const std::string tenant(SyslogParser::GetMapVals(v, "tenant", "UNKNOWN"));
    1269           0 :     const std::string link(SyslogParser::GetMapVals(v, "destination-interface-name", "UNKNOWN"));
    1270           0 :     const std::string sla_profile(SyslogParser::GetMapVals(v, "sla-profile", "UNKNOWN"));
    1271           0 :     const std::string app_category(SyslogParser::GetMapVals(v, "app-category", "UNKNOWN"));
    1272           0 :     const std::string department(SyslogParser::GetMapVals(v, "source-zone-name", "UNKNOWN"));
    1273           0 :     const std::string device_id(SyslogParser::GetMapVals(v, "device", "UNKNOWN"));
    1274           0 :     const std::string region(SyslogParser::GetMapVals(v, "region", "DEFAULT"));
    1275           0 :     const std::string opco(SyslogParser::GetMapVals(v, "OPCO", "DEFAULT"));
    1276           0 :     const std::string uvename = tenant + "::" + location + "::" + device_id;
    1277           0 :     const std::string tenantuvename = region + "::" + opco + "::" + tenant;
    1278           0 :     const std::string traffic_type(SyslogParser::GetMapVals(v, "active-probe-params", "UNKNOWN"));
    1279           0 :     const std::string ip_dscp(SyslogParser::GetMapVals(v, "ip-dscp", "UNKNOWN"));
    1280           0 :     const std::string dscp_alias_code(SyslogParser::GetMapVals(v, "dscp-alias-code", "UNKNOWN"));
    1281           0 :     std::string nested_appname(SyslogParser::GetMapVals(v, "nested-application", "UNKNOWN"));
    1282           0 :     std::string appname(SyslogParser::GetMapVals(v, "application", "UNKNOWN"));
    1283           0 :     std::string service_name(SyslogParser::GetMapVals(v, "service-name", "UNKNOWN"));
    1284             : 
    1285           0 :     const std::string underlay_link = (SyslogParser::GetMapVals(v, "underlay-destination-interface-name", "UNKNOWN"));
    1286           0 :     const std::string link_type_link = (SyslogParser::GetMapVals(v, "link-type-destination-interface-name", "UNKNOWN"));
    1287           0 :     const std::string traffic_destination_link = (SyslogParser::GetMapVals(v, "traffic-destination-destination-interface-name", "UNKNOWN"));
    1288           0 :     const std::string metadata_link = (SyslogParser::GetMapVals(v, "metadata-destination-interface-name", "UNKNOWN"));
    1289           0 :     const std::string link_info = link + "@" + underlay_link
    1290           0 :         + "@" + link_type_link + "@" + traffic_destination_link + "@" + metadata_link ;
    1291             : 
    1292             : 
    1293           0 :     LOG(DEBUG,"UVE: dscp-alias-code: " << dscp_alias_code);
    1294           0 :     LOG(DEBUG,"UVE: ip-dscp: " << ip_dscp);
    1295             : 
    1296           0 :     if (boost::iequals(nested_appname, "UNKNOWN") && boost::iequals(appname, "UNKNOWN")) {
    1297           0 :         if (!(boost::iequals(service_name, "UNKNOWN")) && !(boost::iequals(service_name, "None"))) {
    1298           0 :             nested_appname =  service_name;
    1299           0 :             appname = service_name;
    1300             :         }
    1301             :     }
    1302             : 
    1303             :     // nested_appname@UNKNOWN, nested_appname@dscp_alias_code nested_appname@DSCP-dscp_value
    1304           0 :     std::string dscp_key = "DSCP-" + dscp_alias_code;
    1305           0 :     if (ip_dscp == "UNKNOWN") {
    1306           0 :         dscp_key = "UNKNOWN";
    1307             :     }
    1308           0 :     else if (dscp_alias_code == "UNKNOWN") {
    1309           0 :         dscp_key = "DSCP-" + ip_dscp;
    1310             :     }
    1311             : 
    1312           0 :     const std::string nested_appname_with_alias_code = nested_appname + "@" + dscp_key;
    1313           0 :     const std::string tt_app_dept_info = traffic_type + "(" + nested_appname_with_alias_code + ":" + appname
    1314           0 :                                          + "/" + app_category +  ")" + "::" + department + "::";
    1315             : 
    1316             :     //username => syslog.username or syslog.source-address
    1317           0 :     std::string username(SyslogParser::GetMapVals(v, "username", "UNKNOWN"));
    1318           0 :     if (boost::iequals(username, "unknown")) {
    1319           0 :         username = SyslogParser::GetMapVals(v, "source-address", "UNKNOWN");
    1320             :     }
    1321           0 :     sdwanmetricrecord.set_name(uvename);
    1322           0 :     sdwantenantmetricrecord.set_name(tenantuvename);
    1323             : 
    1324           0 :     SDWANMetrics_diff sdwanmetric;
    1325             :     //SDWANMetrics_dial sdwanmetric_dial;
    1326             :     //int64_t sampling_percentage = SyslogParser::GetMapVal(v, "sampling-percentage", -1);
    1327             :     //if (sampling_percentage != -1) {
    1328             :     //    sdwanmetric_dial.set_sampling_percentage(sampling_percentage);
    1329             :     //}
    1330           0 :     int64_t violation_reason = SyslogParser::GetMapVal(v, "violation-reason", -1);
    1331           0 :     if (violation_reason > 0) {
    1332           0 :         sdwanmetric.set_sla_violation_count(1);
    1333           0 :         if (SyslogParser::GetMapVal(v, "jitter-violation-count", 0) != 0) {
    1334           0 :             sdwanmetric.set_jitter_violation_count(1);
    1335             :         }
    1336           0 :         if (SyslogParser::GetMapVal(v, "rtt-violation-count", 0) != 0) {
    1337           0 :             sdwanmetric.set_rtt_violation_count(1);
    1338             :         }
    1339           0 :         if (SyslogParser::GetMapVal(v, "pkt-loss-violation-count", 0) != 0) {
    1340           0 :             sdwanmetric.set_pkt_loss_violation_count(1);
    1341             :         }
    1342             :     }
    1343           0 :     else if (violation_reason == 0) {
    1344           0 :         sdwanmetric.set_sla_violation_duration(SyslogParser::GetMapVal(v, "violation-duration", 0));
    1345             :     }
    1346             :     else {
    1347           0 :         return;
    1348             :     }
    1349             : 
    1350             :     // Map: app_metrics_*_sla
    1351           0 :     std::map<std::string, SDWANMetrics_diff> app_metrics_diff_sla;
    1352           0 :     std::map<std::string, SDWANMetrics_dial> app_metrics_dial_sla;
    1353           0 :     std::string slamap_key(tt_app_dept_info + sla_profile);
    1354           0 :     LOG(DEBUG,"UVE: app_metrics_*_sla key :" << slamap_key);
    1355           0 :     app_metrics_diff_sla.insert(std::make_pair(slamap_key, sdwanmetric));
    1356             :     //app_metrics_dial_sla.insert(std::make_pair(slamap_key, sdwanmetric_dial));
    1357           0 :     sdwanmetricrecord.set_app_metrics_diff_sla(app_metrics_diff_sla);
    1358             :     //sdwanmetricrecord.set_app_metrics_dial_sla(app_metrics_dial_sla);
    1359             : 
    1360             :     // Map: app_metrics_*_user
    1361           0 :     if (summarize_user == true) {
    1362           0 :         std::map<std::string, SDWANMetrics_diff> app_metrics_diff_user;
    1363           0 :         std::map<std::string, SDWANMetrics_dial> app_metrics_dial_user;
    1364           0 :         std::string usermap_key(tt_app_dept_info + username);
    1365           0 :         LOG(DEBUG,"UVE: app_metrics_*_user key :" << usermap_key);
    1366           0 :         app_metrics_diff_user.insert(std::make_pair(usermap_key, sdwanmetric));
    1367             :         //app_metrics_dial_user.insert(std::make_pair(usermap_key, sdwanmetric_dial));
    1368           0 :         sdwanmetricrecord.set_app_metrics_diff_user(app_metrics_diff_user);
    1369           0 :         sdwanmetricrecord.set_app_metrics_dial_user(app_metrics_dial_user);
    1370           0 :     }
    1371             :     // Map: app_metrics_*_link
    1372           0 :     std::map<std::string, SDWANMetrics_diff> app_metrics_diff_link;
    1373             :     //std::map<std::string, SDWANMetrics_dial> app_metrics_dial_link;
    1374           0 :     std::string linkmap_key(tt_app_dept_info + link_info);
    1375           0 :     LOG(DEBUG,"UVE: app_metrics_*_link key :" << linkmap_key);
    1376           0 :     app_metrics_diff_link.insert(std::make_pair(linkmap_key, sdwanmetric));
    1377             :     //app_metrics_dial_link.insert(std::make_pair(linkmap_key, sdwanmetric_dial));
    1378           0 :     sdwanmetricrecord.set_app_metrics_diff_link(app_metrics_diff_link);
    1379             :     //sdwanmetricrecord.set_app_metrics_dial_link(app_metrics_dial_link);
    1380             : 
    1381             :     // Map: tenant_metrics_*_sla
    1382           0 :     std::map<std::string, SDWANMetrics_diff> tenant_metrics_diff_sla;
    1383           0 :     std::map<std::string, SDWANMetrics_dial> tenant_metrics_dial_sla;
    1384           0 :     std::string tenantmetric_key(location + "::" + sla_profile + "::" + traffic_type + "@" + traffic_destination_link + "@" + link_type_link);
    1385           0 :     LOG(DEBUG,"UVE: tenant_metrics_*_sla key :" << tenantmetric_key);
    1386           0 :     tenant_metrics_diff_sla.insert(std::make_pair(tenantmetric_key, sdwanmetric));
    1387             :     //tenant_metrics_dial_sla.insert(std::make_pair(tenantmetric_key, sdwanmetric_dial));
    1388           0 :     sdwantenantmetricrecord.set_tenant_metrics_diff_sla(tenant_metrics_diff_sla);
    1389             :     //sdwantenantmetricrecord.set_tenant_metrics_dial_sla(tenant_metrics_dial_sla);
    1390             : 
    1391             :     // Map: link_metrics_*_traffic_type
    1392           0 :     std::map<std::string, SDWANMetrics_diff> link_metrics_diff_traffic_type;
    1393           0 :     std::map<std::string, SDWANMetrics_dial> link_metrics_dial_traffic_type;
    1394           0 :     std::string linkmetricmap_key(link_info + "::" + sla_profile + "::" + traffic_type);
    1395           0 :     LOG(DEBUG,"UVE: link_metrics_*_traffic_type key :" << linkmetricmap_key);
    1396           0 :     link_metrics_diff_traffic_type.insert(std::make_pair(linkmetricmap_key, sdwanmetric));
    1397             :     //link_metrics_dial_traffic_type.insert(std::make_pair(linkmetricmap_key, sdwanmetric_dial));
    1398           0 :     sdwanmetricrecord.set_link_metrics_diff_traffic_type(link_metrics_diff_traffic_type);
    1399             :     //sdwanmetricrecord.set_link_metrics_dial_traffic_type(link_metrics_dial_traffic_type);
    1400             : 
    1401           0 :     SDWANMetrics::Send(sdwanmetricrecord, "ObjectCPETable");
    1402           0 :     SDWANTenantMetrics::Send(sdwantenantmetricrecord, "ObjectCPETable");
    1403             : 
    1404           0 :     return;
    1405           0 : }
    1406             : 
    1407           0 : void StructuredSyslogUVESummarizeAppQoeASMR(SyslogParser::syslog_m_t v, bool summarize_user) {
    1408           0 :     SDWANMetricsRecord sdwanmetricrecord;
    1409           0 :     SDWANTenantMetricsRecord sdwantenantmetricrecord;
    1410           0 :     const std::string location(SyslogParser::GetMapVals(v, "location", "UNKNOWN"));
    1411           0 :     const std::string tenant(SyslogParser::GetMapVals(v, "tenant", "UNKNOWN"));
    1412           0 :     const std::string link(SyslogParser::GetMapVals(v, "destination-interface-name", "UNKNOWN"));
    1413           0 :     const std::string sla_profile(SyslogParser::GetMapVals(v, "sla-profile", "UNKNOWN"));
    1414           0 :     const std::string device_id(SyslogParser::GetMapVals(v, "device", "UNKNOWN"));
    1415           0 :     const std::string region(SyslogParser::GetMapVals(v, "region", "DEFAULT"));
    1416           0 :     const std::string opco(SyslogParser::GetMapVals(v, "OPCO", "DEFAULT"));
    1417           0 :     const std::string uvename = tenant + "::" + location + "::" + device_id;
    1418           0 :     const std::string tenantuvename = region + "::" + opco + "::" + tenant;
    1419           0 :     const std::string traffic_type(SyslogParser::GetMapVals(v, "active-probe-params", "UNKNOWN"));
    1420           0 :     const std::string underlay_link = (SyslogParser::GetMapVals(v, "underlay-destination-interface-name", "UNKNOWN"));
    1421           0 :     const std::string link_type_link = (SyslogParser::GetMapVals(v, "link-type-destination-interface-name", "UNKNOWN"));
    1422           0 :     const std::string traffic_destination_link = (SyslogParser::GetMapVals(v, "traffic-destination-destination-interface-name", "UNKNOWN"));
    1423           0 :     const std::string metadata_link = (SyslogParser::GetMapVals(v, "metadata-destination-interface-name", "UNKNOWN"));
    1424           0 :     const std::string link_info = link + "@" + underlay_link
    1425           0 :         + "@" + link_type_link + "@" + traffic_destination_link + "@" + metadata_link ;
    1426             : 
    1427             :     // DSCP value is not collected for ASMR syslog because we dont display on the basis of APP here.
    1428             : 
    1429           0 :     sdwanmetricrecord.set_name(uvename);
    1430           0 :     sdwantenantmetricrecord.set_name(tenantuvename);
    1431           0 :     SDWANMetrics_dial sdwanmetric;
    1432           0 :     int64_t pkt_loss = SyslogParser::GetMapVal(v, "pkt-loss", -1);
    1433           0 :     int64_t rtt = SyslogParser::GetMapVal(v, "rtt", -1);
    1434           0 :     int64_t rtt_jitter = SyslogParser::GetMapVal(v, "rtt-jitter", -1);
    1435           0 :     int64_t egress_jitter = SyslogParser::GetMapVal(v, "egress-jitter", -1);
    1436           0 :     int64_t ingress_jitter = SyslogParser::GetMapVal(v, "ingress-jitter", -1);
    1437             :     /*
    1438             :         Device sends high values for SLA parameters in syslog
    1439             :         when probe is not successfull or for some reason
    1440             :         device is not able to calculate SLA parameters.
    1441             :         High values for -
    1442             :         rtt -> 4294967295
    1443             :         rtt_jitter -> 4294967295
    1444             :         pkt_loss -> 255
    1445             :         These high values should NOT be used for calculation and
    1446             :         should be avoided.
    1447             :     */
    1448           0 :     if (rtt != -1 && rtt != 4294967295) {
    1449           0 :         sdwanmetric.set_rtt(rtt);
    1450             :     }
    1451           0 :     if (rtt_jitter != -1 && rtt_jitter != 4294967295) {
    1452           0 :         sdwanmetric.set_rtt_jitter(rtt_jitter);
    1453             :     }
    1454           0 :     if (egress_jitter != -1 && egress_jitter != 4294967295) {
    1455           0 :         sdwanmetric.set_egress_jitter(egress_jitter);
    1456             :     }
    1457           0 :     if (ingress_jitter != -1 && ingress_jitter != 4294967295) {
    1458           0 :         sdwanmetric.set_ingress_jitter(ingress_jitter);
    1459             :     }
    1460           0 :     if (pkt_loss != -1 && pkt_loss != 255) {
    1461             :         // this check is added to correct the cases in which device sends
    1462             :         // incorrect values containing loss% to be more than 100.
    1463           0 :         if (pkt_loss > 100) {
    1464           0 :             pkt_loss = 100;
    1465             :         }
    1466           0 :         sdwanmetric.set_pkt_loss(pkt_loss);
    1467             :     }
    1468           0 :     if ((rtt != -1) && (rtt != 4294967295) &&
    1469           0 :         (rtt_jitter != -1) && (rtt_jitter != 4294967295) &&
    1470           0 :         (pkt_loss != -1) && (pkt_loss != 255)) {
    1471           0 :         sdwanmetric.set_score((int64_t)calculate_link_score(rtt/2, pkt_loss, rtt_jitter,
    1472             :                              SyslogParser::GetMapVal(v, "effective-latency-threshold",0),
    1473             :                              SyslogParser::GetMapVal(v, "latency-factor",0),
    1474             :                              SyslogParser::GetMapVal(v, "jitter-factor",0),
    1475             :                              SyslogParser::GetMapVal(v, "packet-loss-factor",0) ));
    1476             :     }
    1477             :     // Map:  link_metrics_dial_traffic_type
    1478           0 :     std::map<std::string, SDWANMetrics_dial> link_metrics_dial_traffic_type;
    1479           0 :     std::string linkmap_key(link_info + "::" + sla_profile + "::" + traffic_type);
    1480           0 :     LOG(DEBUG,"UVE: link_metrics_dial_traffic_type key :" << linkmap_key);
    1481           0 :     link_metrics_dial_traffic_type.insert(std::make_pair(linkmap_key, sdwanmetric));
    1482           0 :     sdwanmetricrecord.set_link_metrics_dial_traffic_type(link_metrics_dial_traffic_type);
    1483             : 
    1484             :     // Map: tenant_metrics_dial_sla
    1485           0 :     std::map<std::string, SDWANMetrics_dial> tenant_metrics_dial_sla;
    1486           0 :     std::string tenantmetric_key(location + "::" + sla_profile + "::" + traffic_type);
    1487           0 :     LOG(DEBUG,"UVE: tenant_metrics_dial_sla key :" << tenantmetric_key);
    1488           0 :     tenant_metrics_dial_sla.insert(std::make_pair(tenantmetric_key, sdwanmetric));
    1489           0 :     sdwantenantmetricrecord.set_tenant_metrics_dial_sla(tenant_metrics_dial_sla);
    1490             : 
    1491           0 :     SDWANMetrics::Send(sdwanmetricrecord, "ObjectCPETable");
    1492           0 :     SDWANTenantMetrics::Send(sdwantenantmetricrecord, "ObjectCPETable");
    1493           0 :     return;
    1494           0 : }
    1495             : 
    1496           0 : void StructuredSyslogUVESummarize(SyslogParser::syslog_m_t v, bool summarize_user, StructuredSyslogConfig *config_obj) {
    1497           0 :     const std::string tag(SyslogParser::GetMapVals(v, "tag", "UNKNOWN"));
    1498           0 :     LOG(DEBUG,"UVE: Summarizing " << tag << " as UVE with flag summarize_user:" << summarize_user);
    1499           0 :     if (boost::equals(tag, "APPTRACK_SESSION_CLOSE")) {
    1500           0 :         StructuredSyslogUVESummarizeData(v, summarize_user, config_obj);
    1501             :     }
    1502           0 :     else if (boost::equals(tag, "APPTRACK_SESSION_VOL_UPDATE")) {
    1503           0 :         StructuredSyslogUVESummarizeData(v, summarize_user, config_obj);
    1504             :     }
    1505           0 :     else if (boost::equals(tag, "RT_FLOW_NEXTHOP_CHANGE")) {
    1506           0 :         StructuredSyslogUVESummarizeData(v, summarize_user, config_obj);
    1507             :     }
    1508           0 :     else if (boost::equals(tag, "APPQOE_BEST_PATH_SELECTED")) {
    1509           0 :         StructuredSyslogUVESummarizeAppQoeBPS(v, summarize_user);
    1510             :     }
    1511           0 :     else if (boost::equals(tag, "APPQOE_PASSIVE_SLA_METRIC_REPORT") ||
    1512           0 :              boost::equals(tag, "APPQOE_APP_PASSIVE_SLA_METRIC_REPORT")) {
    1513           0 :         StructuredSyslogUVESummarizeAppQoePSMR(v, summarize_user);
    1514             :     }
    1515           0 :     else if (boost::equals(tag, "APPQOE_ACTIVE_SLA_METRIC_REPORT")) {
    1516           0 :         StructuredSyslogUVESummarizeAppQoeASMR(v, summarize_user);
    1517             :     }
    1518           0 :     else if (boost::equals(tag, "APPQOE_SLA_METRIC_VIOLATION")) {
    1519           0 :         StructuredSyslogUVESummarizeAppQoeSMV(v, summarize_user);
    1520             :     }
    1521           0 : }
    1522             : 
    1523           0 : void StructuredSyslogDecorate (SyslogParser::syslog_m_t &v, StructuredSyslogConfig *config_obj,
    1524             :                                boost::shared_ptr<std::string> msg, std::vector<std::string> int_fields) {
    1525             : 
    1526           0 :     int64_t from_client = SyslogParser::GetMapVal(v, "bytes-from-client", 0);
    1527           0 :     int64_t from_server = SyslogParser::GetMapVal(v, "bytes-from-server", 0);
    1528           0 :     size_t prev_pos = 0;
    1529           0 :     v.insert(std::pair<std::string, SyslogParser::Holder>("total-bytes",
    1530           0 :     SyslogParser::Holder("total-bytes", (from_client + from_server))));
    1531           0 :     std::stringstream total_bytes;
    1532           0 :     total_bytes << (from_client + from_server);
    1533           0 :     prev_pos = DecorateMsg(msg, "total-bytes", total_bytes.str(), prev_pos);
    1534           0 :     v.insert(std::pair<std::string, SyslogParser::Holder>("tenant",
    1535           0 :     SyslogParser::Holder("tenant", "UNKNOWN")));
    1536           0 :     v.insert(std::pair<std::string, SyslogParser::Holder>("location",
    1537           0 :     SyslogParser::Holder("location", "UNKNOWN")));
    1538           0 :     v.insert(std::pair<std::string, SyslogParser::Holder>("device",
    1539           0 :     SyslogParser::Holder("device", "UNKNOWN")));
    1540             :     /* get sla-profile from rule-name or sla-rule */
    1541             :     /* rule-name="r_apbr_d_ENG_p_Intent-1_s_sla-profile1" */
    1542           0 :     std::string sla_profile = SyslogParser::GetMapVals(v, "sla-rule", "");
    1543           0 :     if (sla_profile.empty()) {
    1544           0 :         std::string rn = SyslogParser::GetMapVals(v, "rule-name", "");
    1545           0 :         if (!rn.empty()) {
    1546           0 :             size_t start = rn.find_last_of('_');
    1547           0 :             if (start != string::npos) {
    1548           0 :                 sla_profile = rn.substr(start+1);
    1549             :             }
    1550             :             else {
    1551           0 :                 sla_profile = "DEFAULT";
    1552             :             }
    1553             :         }
    1554             :         else {
    1555           0 :             sla_profile = "DEFAULT";
    1556             :         }
    1557           0 :     }
    1558           0 :     v.insert(std::pair<std::string, SyslogParser::Holder>("sla-profile",
    1559           0 :     SyslogParser::Holder("sla-profile", sla_profile)));
    1560           0 :     prev_pos = DecorateMsg(msg, "sla-profile", sla_profile, prev_pos);
    1561             : 
    1562           0 :     if (config_obj != NULL) {
    1563           0 :         std::string hn = SyslogParser::GetMapVals(v, "hostname", "");
    1564           0 :         boost::shared_ptr<HostnameRecord> hr = config_obj->GetHostnameRecord(hn);
    1565           0 :         if (hr != NULL) {
    1566           0 :             LOG(DEBUG, "StructuredSyslogDecorate hostname record: " << hn);
    1567           0 :             const std::string tenant = hr->tenant();
    1568           0 :             if (!tenant.empty()) {
    1569           0 :                 v.erase("tenant");
    1570           0 :                 v.insert(std::pair<std::string, SyslogParser::Holder>("tenant",
    1571           0 :                 SyslogParser::Holder("tenant", tenant)));
    1572           0 :                 prev_pos = DecorateMsg(msg, "tenant", tenant, prev_pos);
    1573             :             }
    1574           0 :             const std::string location = hr->location();
    1575           0 :             if (!location.empty()) {
    1576           0 :                 v.erase("location");
    1577           0 :                 v.insert(std::pair<std::string, SyslogParser::Holder>("location",
    1578           0 :                 SyslogParser::Holder("location", location)));
    1579           0 :                 prev_pos = DecorateMsg(msg, "location", location, prev_pos);
    1580             :             }
    1581           0 :             const std::string device = hr->device();
    1582           0 :             if (!device.empty()) {
    1583           0 :                 v.erase("device");
    1584           0 :                 v.insert(std::pair<std::string, SyslogParser::Holder>("device",
    1585           0 :                 SyslogParser::Holder("device", device)));
    1586           0 :                 prev_pos = DecorateMsg(msg, "device", device, prev_pos);
    1587             :             }
    1588           0 :             const std::string hostname_tags = hr->tags();
    1589           0 :             if (!hostname_tags.empty()) {
    1590           0 :                 ParseStructuredPart(&v, hostname_tags, int_fields, msg);
    1591             :             }
    1592           0 :             std::map< std::string, std::string > linkmap = hr->linkmap();
    1593             :             std::string links[4] = { "destination-interface-name", "last-incoming-interface-name",
    1594           0 :                                   "uplink-incoming-interface-name","last-destination-interface-name"};
    1595           0 :             for (int i = 0; i < 4; i++) {
    1596           0 :                 std::string overlay_link(SyslogParser::GetMapVals(v, links[i], ""));
    1597           0 :                 if (!overlay_link.empty() && !(boost::equals(overlay_link,"N/A"))) {
    1598           0 :                     std::map< std::string, std::string >::iterator it = linkmap.find(overlay_link);
    1599           0 :                     if (it  != linkmap.end()) {
    1600             :                         // linkmap value => underlay + "@" + link_type + "@" + traffic_destination + "@" + link_metadata ;
    1601           0 :                         std::vector<std::string> link_data;
    1602           0 :                         boost::split(link_data, it->second, boost::is_any_of("@"), boost::token_compress_on);
    1603           0 :                         LOG(DEBUG, "StructuredSyslogDecorate: linkmap for " << links[i] << " : "
    1604             :                             << overlay_link << " underlay " << link_data[0]);
    1605           0 :                         LOG(DEBUG, "StructuredSyslogDecorate: linkmap for " << links[i] << " : "
    1606             :                             << overlay_link << " link type " << link_data[1]);
    1607           0 :                         LOG(DEBUG, "StructuredSyslogDecorate: linkmap for " << links[i] << " : "
    1608             :                             << overlay_link << " traffic destination " << link_data[2]);
    1609           0 :                         LOG(DEBUG, "StructuredSyslogDecorate: linkmap for " << links[i] << " : "
    1610             :                             << overlay_link << " link metadata " << link_data[3]);
    1611             : 
    1612           0 :                         std::string underlay_link_name = "underlay-" + links[i];
    1613           0 :                         v.insert(std::pair<std::string, SyslogParser::Holder>(underlay_link_name,
    1614           0 :                               SyslogParser::Holder(underlay_link_name, link_data[0])));
    1615           0 :                         std::string link_type = "link-type-" + links[i];
    1616           0 :                         v.insert(std::pair<std::string, SyslogParser::Holder>(link_type,
    1617           0 :                               SyslogParser::Holder(link_type, link_data[1])));
    1618           0 :                         std::string traffic_destination = "traffic-destination-" + links[i];
    1619           0 :                         v.insert(std::pair<std::string, SyslogParser::Holder>(traffic_destination,
    1620           0 :                               SyslogParser::Holder(traffic_destination, link_data[2])));
    1621           0 :                         std::string link_metadata = "metadata-" + links[i];
    1622           0 :                         v.insert(std::pair<std::string, SyslogParser::Holder>(link_metadata,
    1623           0 :                               SyslogParser::Holder(link_metadata, link_data[3])));
    1624           0 :                     }
    1625             :                 }
    1626           0 :             }
    1627             : 
    1628             :             //const std::string tenant_record_default_tenant = "DEFAULT";
    1629           0 :             boost::shared_ptr<TenantRecord> tr = config_obj->GetTenantRecord(tenant);
    1630           0 :             LOG(DEBUG, "StructuredSyslogDecorate: Processing Tenant Record !!");
    1631             :             // if (tr == NULL) {
    1632             :             //     tr = config_obj->GetTenantRecord(tenant_record_default_tenant);
    1633             :             //     LOG(DEBUG, "StructuredSyslogDecorate: Tenant \"" << tenant << "\" not found. Reading \"DEFAULT\" Tenant Record !!");
    1634             :             // }
    1635           0 :             if (tr != NULL) {
    1636           0 :                 const std::string tenantaddr = tr->tenantaddr();
    1637           0 :                 if (!tenantaddr.empty()){
    1638           0 :                     v.insert(std::pair<std::string, SyslogParser::Holder>("tenantaddr",
    1639           0 :                         SyslogParser::Holder("tenantaddr", tenantaddr)));
    1640             :                 }
    1641             : 
    1642           0 :                 const std::string tenant_tags = tr->tags();
    1643           0 :                 if (!tenant_tags.empty()) {
    1644           0 :                     ParseStructuredPart(&v, tenant_tags, int_fields, msg);
    1645             :                 }
    1646             : 
    1647             :                 //check if the syslog contains dscp-value(or ip-dscp) then find the corresponding alias-code 
    1648           0 :                 std::string dscp_value = SyslogParser::GetMapVals(v, "dscp-value", "");
    1649           0 :                 std::string ip_dscp = SyslogParser::GetMapVals(v, "ip-dscp", "");
    1650           0 :                 if (dscp_value.empty()) {
    1651           0 :                     LOG(DEBUG, "StructuredSyslogDecorate: \"dscp-value\" field not found in syslog, reading \"ip-dscp\" instead ...");
    1652           0 :                     dscp_value = ip_dscp;
    1653             :                 }
    1654           0 :                 if (!dscp_value.empty()) {
    1655           0 :                     LOG(DEBUG, "StructuredSyslogDecorate: Finding alias-code for dscp-value " << dscp_value);
    1656             :                     //find the internet protocol (IP) version for destination-address
    1657           0 :                     const std::string destination_address (SyslogParser::GetMapVals(v, "destination-address", "UNKNOWN"));
    1658           0 :                     int ip_version = 4;
    1659           0 :                     if (destination_address != "UNKNOWN") {
    1660           0 :                         ip_version = config_obj->get_ip_version (destination_address);
    1661             :                     }
    1662           0 :                     LOG(DEBUG, "StructuredSyslogDecorate: IP version for destination-address " << destination_address << " found to be IPv" << ip_version);
    1663           0 :                     if (ip_version == 4) {
    1664           0 :                         std::map< std::string, std::string > dscpmap_ipv4 = tr->dscpmap_ipv4();  
    1665           0 :                         std::map< std::string, std::string >::iterator it = dscpmap_ipv4.find(dscp_value);
    1666           0 :                         if (it != dscpmap_ipv4.end()) {
    1667           0 :                             LOG(DEBUG, "StructuredSyslogDecorate: alias-code for dscp-value: " << dscp_value << " is "
    1668             :                                 << it->second );
    1669           0 :                             v.insert(std::pair<std::string, SyslogParser::Holder>("dscp-alias-code",
    1670           0 :                                   SyslogParser::Holder("dscp-alias-code", it->second)));
    1671             :                         }
    1672             :                         else {
    1673           0 :                             LOG(DEBUG, "StructuredSyslogDecorate: alias-code NOT found for dscp-value: " << dscp_value);
    1674             :                         }
    1675           0 :                     }
    1676           0 :                     else if (ip_version == 6) {
    1677           0 :                         std::map< std::string, std::string > dscpmap_ipv6 = tr->dscpmap_ipv6();  
    1678           0 :                         std::map< std::string, std::string >::iterator it = dscpmap_ipv6.find(dscp_value);
    1679           0 :                         if (it != dscpmap_ipv6.end()) {
    1680           0 :                             LOG(DEBUG, "StructuredSyslogDecorate: alias-code for dscp-value: " << dscp_value << " is "
    1681             :                                 << it->second );
    1682           0 :                             v.insert(std::pair<std::string, SyslogParser::Holder>("dscp-alias-code",
    1683           0 :                                   SyslogParser::Holder("dscp-alias-code", it->second)));
    1684             :                         }
    1685             :                         else {
    1686           0 :                             LOG(DEBUG, "StructuredSyslogDecorate: alias-code NOT found for dscp-value: " << dscp_value);
    1687             :                         }
    1688           0 :                     }
    1689             :                     else {
    1690           0 :                         LOG(ERROR, "StructuredSyslogDecorate: destination-address IP does not have any valid version. Skipping search for dscp-alias-code!");
    1691             :                     }
    1692           0 :                 }
    1693           0 :             }
    1694             :             else {
    1695           0 :                 LOG(DEBUG, "StructuredSyslogDecorate: Tenant Record not found for: " << tenant);
    1696             :             }
    1697             : 
    1698             : 
    1699             :             /*
    1700             :             std::string an = SyslogParser::GetMapVals(v, "nested-application", "unknown");
    1701             :             if (boost::iequals(an, "unknown")) {
    1702             :                 an = SyslogParser::GetMapVals(v, "application", "unknown");
    1703             :             }
    1704             :             size_t found = an.find_first_of(':');
    1705             :             while (found != string::npos) {
    1706             :                 an[found] = '/';
    1707             :                 found = an.find_first_of(':', found+1);
    1708             :             }
    1709             :             v.insert(std::pair<std::string, SyslogParser::Holder>("app-category",
    1710             :             SyslogParser::Holder("app-category", "UNKNOWN")));
    1711             :             v.insert(std::pair<std::string, SyslogParser::Holder>("app-subcategory",
    1712             :             SyslogParser::Holder("app-subcategory", "UNKNOWN")));
    1713             :             v.insert(std::pair<std::string, SyslogParser::Holder>("app-groups",
    1714             :             SyslogParser::Holder("app-groups", "UNKNOWN")));
    1715             :             v.insert(std::pair<std::string, SyslogParser::Holder>("app-risk",
    1716             :             SyslogParser::Holder("app-risk", "UNKNOWN")));
    1717             : 
    1718             :             boost::shared_ptr<ApplicationRecord> ar;
    1719             :             ar = config_obj->GetApplicationRecord(an);
    1720             :             if (ar == NULL) {
    1721             :                 ar = config_obj->GetApplicationRecord("*");
    1722             :             }
    1723             :             if (ar != NULL) {
    1724             :                 LOG(DEBUG, "StructuredSyslogDecorate application record: " << an);
    1725             :                 const std::string app_category = ar->app_category();
    1726             :                 if (!app_category.empty()) {
    1727             :                     v.erase("app-category");
    1728             :                     v.insert(std::pair<std::string, SyslogParser::Holder>("app-category",
    1729             :                     SyslogParser::Holder("app-category", app_category)));
    1730             :                     prev_pos = DecorateMsg(msg, "app-category", app_category, prev_pos);
    1731             :                 }
    1732             :                 const std::string app_subcategory = ar->app_subcategory();
    1733             :                 if (!app_subcategory.empty()) {
    1734             :                     v.erase("app-subcategory");
    1735             :                     v.insert(std::pair<std::string, SyslogParser::Holder>("app-subcategory",
    1736             :                     SyslogParser::Holder("app-subcategory", app_subcategory)));
    1737             :                     prev_pos = DecorateMsg(msg, "app-subcategory", app_subcategory, prev_pos);
    1738             :                 }
    1739             :                 const std::string app_groups = ar->app_groups();
    1740             :                 if (!app_groups.empty()) {
    1741             :                     v.erase("app-groups");
    1742             :                     v.insert(std::pair<std::string, SyslogParser::Holder>("app-groups",
    1743             :                     SyslogParser::Holder("app-groups", app_groups)));
    1744             :                     prev_pos = DecorateMsg(msg, "app-groups", app_groups, prev_pos);
    1745             :                 }
    1746             :                 const std::string app_risk = ar->app_risk();
    1747             :                 if (!app_risk.empty()) {
    1748             :                     v.erase("app-risk");
    1749             :                     v.insert(std::pair<std::string, SyslogParser::Holder>("app-risk",
    1750             :                     SyslogParser::Holder("app-risk", app_risk)));
    1751             :                     prev_pos = DecorateMsg(msg, "app-risk", app_risk, prev_pos);
    1752             :                 }
    1753             :                 const std::string app_service_tags = ar->app_service_tags();
    1754             :                 if (!app_service_tags.empty()) {
    1755             :                     ParseStructuredPart(&v, app_service_tags, int_fields, msg);
    1756             :                 }
    1757             :             } else {
    1758             :                 LOG(INFO, "StructuredSyslogDecorate: Application Record not found for: " << an);
    1759             :             }
    1760             :             */
    1761           0 :             std::string sla_rec_name = tenant + "/" + device + "/" + sla_profile;
    1762           0 :             boost::shared_ptr<SlaProfileRecord> sla_rec;
    1763           0 :             sla_rec = config_obj->GetSlaProfileRecord(sla_rec_name);
    1764           0 :             if (sla_rec != NULL) {
    1765           0 :                 LOG(DEBUG, "StructuredSyslogDecorate sla-profile record: " << sla_rec_name);
    1766           0 :                 const std::string sla_params = sla_rec->sla_params();
    1767           0 :                 if (!sla_params.empty()) {
    1768           0 :                     ParseStructuredPart(&v, sla_params, int_fields, msg);
    1769             :                 }
    1770           0 :             }
    1771           0 :         }
    1772             :         else {
    1773           0 :             LOG(DEBUG, "StructuredSyslogDecorate: Hostname Record not found for: " << hn);
    1774             :         }
    1775           0 :     }
    1776           0 : }
    1777             : 
    1778             : 
    1779             : /* -------Structured syslog parsing.
    1780             :    -------For newly received tcp message on port 3514(structured-syslog port),
    1781             : 
    1782             : 1. Check if there is old buffer from previous message (start ptr = 0)
    1783             :     a. If yes,
    1784             :     then append newly received tcp message to old buffer, and take forward
    1785             :     appended message for further processing, otherwise take forward just
    1786             :     the received message
    1787             : 
    1788             : 2. Identifying the start and end of the message, ( Len = received buffer length
    1789             :     or the appended buffer + received buffer length)
    1790             :     a. Find the first space (" ")
    1791             :     from the start, and take up the word from the start (pointer) to the space
    1792             :     for parsing prepended syslog message length.
    1793             :     b. If message length conversion doesn't turn up to be 0,
    1794             :         - then end pointer is pointed to message length + no. of
    1795             :           bytes after space and start pointer to first char after space.
    1796             :     c. But if message length conversion is 0, determination of start and end of
    1797             :     syslog message is done by parsing each byte/char of the message till either
    1798             :     the start and end are found or we run our of Len.
    1799             :         - The position of char '<' is taken as start pointer and
    1800             :           char ']' is taken as end pointer.
    1801             : 
    1802             : 3. If end char of structured syslog ']' is not found upon parsing the complete
    1803             : received message, the message from the start till the end of received message is
    1804             : put into session buffer anticipating the remaining part of structured syslog in
    1805             : next tcp buffer which will be appended to session buffer as pointedin step 1.
    1806             : The necessary condition here is that the end pointer index should be either
    1807             : greater than the received tcp buffer length (len, in this case we will directly
    1808             : put the message into buffer) or it should point to received tcp buffer length
    1809             : (len), in this case will check for last element to have end delimiter ']'. check
    1810             : for following condition below in code for step 3.  (((end > len) || ((end ==
    1811             : len) && (*(p + end - 1) != ']') )) && (sess_buf != NULL))
    1812             : 
    1813             : 4. If the above step (step 3) holds true, i.e. complete syslog message remains
    1814             : to be be received, the process follows again from step 1. Else next step (step
    1815             : 5) follows for parsing the identified structured  syslog message.
    1816             : 
    1817             : 5. The identified structured syslog message is first parsed for syslog part of
    1818             : message and then structured part of syslog.
    1819             : 
    1820             : 6. Upon parsing of syslog message in step 5, check for the remaining message in
    1821             : received tcp buffer (multiple syslog messages can be in single buffer) and shift
    1822             : start and end pointers as follows below.
    1823             :     a. Shift the start pointer to 1 + end pointer of previously parsed message,
    1824             :     if parsing the syslog in step 5 is unsuccessful.
    1825             :     b. Shift the start pointer to previous start pointer + message length of
    1826             :     previously parsed message, if parsing the syslog in step 5 is successful.
    1827             : 
    1828             : 7. Check if start pointer index is equal to received tcp buffer length (meaning
    1829             : the complete received tcp buffer is parsed), otherwise flow jumps to step 2 with
    1830             : new (shifted) start pointer till we parse complete received tcp buffer. */
    1831             : 
    1832             : 
    1833          15 : bool ProcessStructuredSyslog(const uint8_t *data, size_t len,
    1834             :     const boost::asio::ip::address remote_address,
    1835             :     StatWalker::StatTableInsertFn stat_db_callback, StructuredSyslogConfig *config_obj,
    1836             :     boost::shared_ptr<StructuredSyslogForwarder> forwarder, boost::shared_ptr<std::string> sess_buf) {
    1837          15 :   boost::system::error_code ec;
    1838          15 :   const std::string ip(remote_address.to_string(ec));
    1839             :   const uint8_t *p;
    1840          15 :   std::string full_log;
    1841             : 
    1842          15 :   size_t end, len_end, start = 0;
    1843             :   bool r;
    1844             : 
    1845          15 :   while (!*(data + len - 1))
    1846           0 :       --len;
    1847          15 :   LOG(DEBUG, "full structured_syslog: " << std::string(data + start, data + len) << " len: " << len);
    1848          15 :   if (sess_buf != NULL) {
    1849           9 :     full_log = *sess_buf + std::string(data + start, data + len);
    1850           9 :     p = reinterpret_cast<const uint8_t*>(full_log.data());
    1851           9 :     len += sess_buf->length();
    1852           9 :     LOG(DEBUG, "structured_syslog sess_buf + new buf: " << full_log << " len: " <<  len);
    1853           9 :     sess_buf->clear();
    1854             :   } else {
    1855           6 :     p = data;
    1856             :   }
    1857             :   
    1858             :   do {
    1859          36 :       SyslogParser::syslog_m_t v;
    1860          36 :       end = start + 1;
    1861          36 :       len_end = start + 1;
    1862         186 :       while ((*(p + len_end - 1) != ' ') && (len_end < len))
    1863         150 :         ++len_end;
    1864             : 
    1865             :       /* use prepended msg len to find the end of msg, if it exists */
    1866          36 :       if (len_end != len) {
    1867          33 :           bool is_msg_len = true;
    1868          33 :           int mlen_idx = start;
    1869          33 :           long int mlen = 0;
    1870         131 :           while (is_msg_len && ((p + mlen_idx) < (p + len_end - 1))) {
    1871          98 :               if (!(isdigit(*(p + mlen_idx)))) {is_msg_len = false;}
    1872          98 :               mlen_idx++;
    1873             :           }
    1874          33 :           if (is_msg_len) {
    1875          24 :               std::string mlenstr  = std::string(p + start, p + len_end);
    1876          24 :               mlen = strtol(mlenstr.c_str(), NULL, 10);
    1877          24 :           }
    1878          33 :           LOG (DEBUG, "prepended message length: " << mlen);
    1879          33 :           if (mlen != 0) {
    1880          24 :             len_end += mlen;
    1881             :           } else {
    1882        2307 :               while ((*(p + len_end - 1) != ']') && (len_end < len)){
    1883             :                 /* check for start of message if message length doesn't exist */
    1884        2298 :                 if (*(p + end - 1 ) == '<'){
    1885           7 :                   start = end - 1;
    1886             :                 }
    1887        2298 :                 ++end;
    1888        2298 :                 ++len_end;
    1889             :               }
    1890             :           }
    1891             :       }
    1892          36 :       end = len_end;
    1893             : 
    1894             :       // check if end of tcp buffer is reached and message delimiter ']' has arrived,
    1895             :       // if not, wait till it comes in next tcp buffer
    1896          36 :       if (((end > len) ||
    1897          72 :          ((end == len) && (*(p + end - 1) != ']') )) && (sess_buf != NULL)) {
    1898             :           /* limiting session buffer to 5KB */
    1899           4 :           if (len-start < 5120) {
    1900           4 :               sess_buf->append(std::string(p + start, p + len));
    1901           4 :               LOG(DEBUG, "structured_syslog next sess_buf: "
    1902             :                 << *sess_buf << " len: "<< len-start);
    1903           4 :               return true;
    1904             :           }
    1905             :           else {
    1906           0 :               LOG(ERROR, "next session buffer length too high, discarding buffer!!"
    1907             :                 "[log msg buf truncated to 2048 bytes] next sess_buf: "
    1908             :                 << std::string(p + start, p + 2048) << " length: "<< len-start);
    1909           0 :               return false;
    1910             :           }
    1911             :       }
    1912          32 :       r = SyslogParser::parse_syslog (p + start, p + end, v);
    1913          32 :       LOG(DEBUG, "structured_syslog: " << std::string(p + start, p + end) <<
    1914             :                  " start: " << start << " end: " << end << " parsed " << r);
    1915          32 :       if (r) {
    1916          31 :           v.insert(std::pair<std::string, SyslogParser::Holder>("ip",
    1917          62 :                 SyslogParser::Holder("ip", ip)));
    1918          31 :           std::stringstream lenss;
    1919          31 :           lenss << SyslogParser::GetMapVal(v, "msglen", 0);
    1920          31 :           std::string lenstr = lenss.str();
    1921          31 :           int message_len = SyslogParser::GetMapVal(v, "msglen", len);
    1922          31 :           if (message_len != (int)len) {
    1923          24 :             start += lenstr.length() + 1;
    1924             :           }
    1925          31 :           LOG(DEBUG, "structured_syslog message_len: " << message_len);
    1926          31 :           SyslogParser::PostParsing(v);
    1927          31 :           if (StructuredSyslogPostParsing(v, config_obj, stat_db_callback, p + start, end-start, forwarder) == false)
    1928             :           {
    1929          31 :             LOG(DEBUG, "structured_syslog not handled");
    1930             :           }
    1931          31 :           if (message_len == (int)len) {
    1932           7 :             start = end + 1;
    1933             :           } else {
    1934          24 :             start += message_len;
    1935             :           }
    1936          31 :       } else {
    1937           1 :           LOG(ERROR, "structured_syslog parse failed for: " << std::string(p + start, p + end));
    1938           1 :           start = end;
    1939             :       }
    1940         219 :       while (!v.empty()) {
    1941         187 :           v.erase(v.begin());
    1942             :       }
    1943          68 :   } while (start<len);
    1944          11 :   return r;
    1945          15 : }
    1946             : 
    1947             : }  // namespace impl
    1948             : 
    1949             : class StructuredSyslogServer::StructuredSyslogServerImpl {
    1950             : public:
    1951           0 :     StructuredSyslogServerImpl(EventManager *evm, uint16_t port,
    1952             :         const vector<string> &structured_syslog_tcp_forward_dst,
    1953             :         const std::string &structured_syslog_kafka_broker,
    1954             :         const std::string &structured_syslog_kafka_topic,
    1955             :         const Options::Kafka &kafka_options,
    1956             :         uint16_t structured_syslog_kafka_partitions,
    1957             :         uint64_t structured_syslog_active_session_map_limit,
    1958             :         ConfigClientCollector *config_client,
    1959           0 :         StatWalker::StatTableInsertFn stat_db_callback) :
    1960           0 :         udp_server_(new StructuredSyslogUdpServer(evm, port,
    1961           0 :             stat_db_callback)),
    1962           0 :         tcp_server_(new StructuredSyslogTcpServer(evm, port,
    1963           0 :             stat_db_callback)),
    1964           0 :         structured_syslog_config_(new StructuredSyslogConfig(config_client, structured_syslog_active_session_map_limit)) {
    1965           0 :         if ((structured_syslog_tcp_forward_dst.size() != 0) || structured_syslog_kafka_broker != "") {
    1966           0 :             forwarder_.reset(new StructuredSyslogForwarder (evm, structured_syslog_tcp_forward_dst,
    1967             :                                                             structured_syslog_kafka_broker,
    1968             :                                                             structured_syslog_kafka_topic,
    1969             :                                                             kafka_options,
    1970           0 :                                                             structured_syslog_kafka_partitions));
    1971             :         } else {
    1972           0 :             LOG(DEBUG, "forward destination not configured");
    1973             :         }
    1974             : 
    1975           0 :     }
    1976             : 
    1977           0 :     ~StructuredSyslogServerImpl() {
    1978           0 :     }
    1979             : 
    1980           0 :     StructuredSyslogConfig *GetStructuredSyslogConfig() {
    1981           0 :         return structured_syslog_config_;
    1982             :     }
    1983             : 
    1984           0 :     boost::shared_ptr<StructuredSyslogForwarder> GetStructuredSyslogForwarder() {
    1985           0 :         return forwarder_;
    1986             :     }
    1987           0 :     bool Initialize() {
    1988           0 :         if (udp_server_->Initialize(GetStructuredSyslogConfig(), GetStructuredSyslogForwarder())) {
    1989           0 :             return tcp_server_->Initialize(GetStructuredSyslogConfig(), GetStructuredSyslogForwarder());
    1990             :         } else {
    1991           0 :             return false;
    1992             :         }
    1993             :     }
    1994             : 
    1995           0 :     void Shutdown() {
    1996           0 :         udp_server_->Shutdown();
    1997           0 :         UdpServerManager::DeleteServer(udp_server_);
    1998           0 :         udp_server_ = NULL;
    1999           0 :         tcp_server_->Shutdown();
    2000           0 :         TcpServerManager::DeleteServer(tcp_server_);
    2001           0 :         if (forwarder_ != NULL)
    2002           0 :             forwarder_->Shutdown();
    2003           0 :     }
    2004             : 
    2005           0 :     boost::asio::ip::udp::endpoint GetLocalEndpoint(
    2006             :         boost::system::error_code *ec) {
    2007           0 :         return udp_server_->GetLocalEndpoint(ec);
    2008             :     }
    2009             : 
    2010             : private:
    2011             :     //
    2012             :     // StructuredSyslogUdpServer
    2013             :     //
    2014             :     class StructuredSyslogUdpServer : public UdpServer {
    2015             :     public:
    2016           0 :         StructuredSyslogUdpServer(EventManager *evm, uint16_t port,
    2017           0 :             StatWalker::StatTableInsertFn stat_db_callback) :
    2018             :             UdpServer(evm, kBufferSize),
    2019           0 :             port_(port),
    2020           0 :             stat_db_callback_(stat_db_callback) {
    2021           0 :         }
    2022             : 
    2023           0 :         bool Initialize(StructuredSyslogConfig *config_obj,
    2024             :                         boost::shared_ptr<StructuredSyslogForwarder> forwarder) {
    2025           0 :             int count = 0;
    2026           0 :             while (count++ < kMaxInitRetries) {
    2027           0 :                 if (UdpServer::Initialize(port_)) {
    2028           0 :                     break;
    2029             :                 }
    2030           0 :                 sleep(1);
    2031             :             }
    2032           0 :             if (!(count < kMaxInitRetries)) {
    2033           0 :                 LOG(ERROR, "EXITING: StructuredSyslogUdpServer initialization failed "
    2034             :                     << "for port " << port_);
    2035           0 :                 exit(1);
    2036             :             }
    2037           0 :             StartReceive();
    2038           0 :             config_obj_ = config_obj;
    2039           0 :             forwarder_ = forwarder;
    2040           0 :             return true;
    2041             :         }
    2042             : 
    2043           0 :         virtual void OnRead(const boost::asio::const_buffer &recv_buffer,
    2044             :             const boost::asio::ip::udp::endpoint &remote_endpoint) {
    2045           0 :             size_t recv_buffer_size(boost::asio::buffer_size(recv_buffer));
    2046           0 :             if (!structured_syslog::impl::ProcessStructuredSyslog(boost::asio::buffer_cast<const uint8_t *>(recv_buffer),
    2047           0 :                     recv_buffer_size, remote_endpoint.address(), stat_db_callback_, config_obj_, forwarder_,
    2048           0 :                     boost::shared_ptr<std::string>())) {
    2049           0 :                 LOG(ERROR, "ProcessStructuredSyslog UDP FAILED for : " << remote_endpoint);
    2050             :             } else {
    2051           0 :                 LOG(DEBUG, "ProcessStructuredSyslog UDP SUCCESS for : " << remote_endpoint);
    2052             :             }
    2053             : 
    2054           0 :             DeallocateBuffer(recv_buffer);
    2055           0 :         }
    2056             : 
    2057             :     private:
    2058             : 
    2059             :         static const int kMaxInitRetries = 5;
    2060             :         static const int kBufferSize = 32 * 1024;
    2061             : 
    2062             :         uint16_t port_;
    2063             :         StatWalker::StatTableInsertFn stat_db_callback_;
    2064             :         StructuredSyslogConfig *config_obj_;
    2065             :         boost::shared_ptr<StructuredSyslogForwarder> forwarder_;
    2066             :     };
    2067             : 
    2068             :     class StructuredSyslogTcpServer;
    2069             : 
    2070             :     class StructuredSyslogTcpSession : public TcpSession {
    2071             :     public:
    2072             :         typedef boost::intrusive_ptr<StructuredSyslogTcpSession> StructuredSyslogTcpSessionPtr;
    2073           0 :         StructuredSyslogTcpSession (StructuredSyslogTcpServer *server, Socket *socket) :
    2074           0 :             TcpSession(server, socket) {
    2075           0 :             sess_buf.reset(new std::string(""));
    2076             :             //set_observer(boost::bind(&SyslogTcpSession::OnEvent, this, _1, _2));
    2077           0 :         }
    2078           0 :         virtual void OnRead (const boost::asio::const_buffer buf) {
    2079           0 :             boost::system::error_code ec;
    2080           0 :             StructuredSyslogTcpServer *sserver = dynamic_cast<StructuredSyslogTcpServer *>(server());
    2081             :             //TODO: handle error
    2082           0 :             sserver->ReadMsg(StructuredSyslogTcpSessionPtr(this), buf, socket ()->remote_endpoint(ec));
    2083           0 :         }
    2084             :         boost::shared_ptr<std::string> sess_buf;
    2085             :     };
    2086             : 
    2087             :     //
    2088             :     // StructuredSyslogTcpServer
    2089             :     //
    2090             :     class StructuredSyslogTcpServer : public TcpServer {
    2091             :     public:
    2092             :         typedef boost::intrusive_ptr<StructuredSyslogTcpSession> StructuredSyslogTcpSessionPtr;
    2093           0 :         StructuredSyslogTcpServer(EventManager *evm, uint16_t port,
    2094           0 :             StatWalker::StatTableInsertFn stat_db_callback) :
    2095             :             TcpServer(evm),
    2096           0 :             port_(port),
    2097           0 :             session_(NULL),
    2098           0 :             stat_db_callback_(stat_db_callback) {
    2099           0 :         }
    2100             : 
    2101           0 :         virtual TcpSession *AllocSession(Socket *socket)
    2102             :         {
    2103           0 :             session_ = new StructuredSyslogTcpSession (this, socket);
    2104           0 :             return session_;
    2105             :         }
    2106             : 
    2107           0 :         bool Initialize(StructuredSyslogConfig *config_obj, boost::shared_ptr<StructuredSyslogForwarder> forwarder) {
    2108           0 :             TcpServer::Initialize (port_);
    2109           0 :             LOG(DEBUG, __func__ << " Initialization of TCP StructuredSyslog listener @" << port_);
    2110           0 :             config_obj_ = config_obj;
    2111           0 :             forwarder_ = forwarder;
    2112           0 :             return true;
    2113             :         }
    2114             : 
    2115           0 :         virtual void ReadMsg(StructuredSyslogTcpSessionPtr sess, const boost::asio::const_buffer &recv_buffer,
    2116             :             const boost::asio::ip::tcp::endpoint &remote_endpoint) {
    2117           0 :             size_t recv_buffer_size(boost::asio::buffer_size(recv_buffer));
    2118             : 
    2119           0 :             if (!structured_syslog::impl::ProcessStructuredSyslog(
    2120             :                     boost::asio::buffer_cast<const uint8_t *>(recv_buffer),
    2121           0 :                     recv_buffer_size, remote_endpoint.address(), stat_db_callback_, config_obj_,
    2122           0 :                     forwarder_, sess->sess_buf)) {
    2123           0 :                 LOG(ERROR, "ProcessStructuredSyslog TCP FAILED for : " << remote_endpoint);
    2124             :             } else {
    2125           0 :                 LOG(DEBUG, "ProcessStructuredSyslog TCP SUCCESS for : " << remote_endpoint);
    2126             :             }
    2127             : 
    2128             :             //sess->server()->DeleteSession (sess.get());
    2129           0 :             sess->ReleaseBuffer(recv_buffer);
    2130           0 :         }
    2131             : 
    2132             :     private:
    2133             :         uint16_t port_;
    2134             :         StructuredSyslogTcpSession *session_;
    2135             :         StatWalker::StatTableInsertFn stat_db_callback_;
    2136             :         StructuredSyslogConfig *config_obj_;
    2137             :         boost::shared_ptr<StructuredSyslogForwarder> forwarder_;
    2138             :     };
    2139             :     StructuredSyslogUdpServer *udp_server_;
    2140             :     StructuredSyslogTcpServer *tcp_server_;
    2141             :     boost::shared_ptr<StructuredSyslogForwarder> forwarder_;
    2142             :     StructuredSyslogConfig *structured_syslog_config_;
    2143             : };
    2144             : 
    2145           0 : StructuredSyslogServer::StructuredSyslogServer(EventManager *evm,
    2146             :     uint16_t port, const vector<string> &structured_syslog_tcp_forward_dst,
    2147             :     const std::string &structured_syslog_kafka_broker,
    2148             :     const std::string &structured_syslog_kafka_topic,
    2149             :     uint16_t structured_syslog_kafka_partitions,
    2150             :     uint64_t structured_syslog_active_session_map_limit,
    2151             :     const Options::Kafka &kafka_options,
    2152             :     ConfigClientCollector *config_client,
    2153           0 :     StatWalker::StatTableInsertFn stat_db_fn) {
    2154           0 :     impl_ = new StructuredSyslogServerImpl(evm, port, structured_syslog_tcp_forward_dst,
    2155             :                                            structured_syslog_kafka_broker,
    2156             :                                            structured_syslog_kafka_topic,
    2157             :                                            kafka_options,
    2158             :                                            structured_syslog_kafka_partitions,
    2159             :                                            structured_syslog_active_session_map_limit,
    2160           0 :                                            config_client, stat_db_fn);
    2161           0 : }
    2162             : 
    2163           0 : StructuredSyslogServer::~StructuredSyslogServer() {
    2164           0 :     if (impl_) {
    2165           0 :         delete impl_;
    2166           0 :         impl_ = NULL;
    2167             :     }
    2168           0 : }
    2169             : 
    2170           0 : bool StructuredSyslogServer::Initialize() {
    2171           0 :     return impl_->Initialize();
    2172             : }
    2173             : 
    2174           0 : void StructuredSyslogServer::Shutdown() {
    2175           0 :     impl_->Shutdown();
    2176           0 : }
    2177             : 
    2178           0 : boost::asio::ip::udp::endpoint StructuredSyslogServer::GetLocalEndpoint(
    2179             :     boost::system::error_code *ec) {
    2180           0 :     return impl_->GetLocalEndpoint(ec);
    2181             : }
    2182             : 
    2183             : //
    2184             : // StructuredSyslogTcpForwarderSession
    2185             : //
    2186             : class StructuredSyslogTcpForwarderSession : public TcpSession {
    2187             : private:
    2188             :     StructuredSyslogTcpForwarder *server_;
    2189             : 
    2190             : public:
    2191           0 :     StructuredSyslogTcpForwarderSession (StructuredSyslogTcpForwarder *server, Socket *socket) :
    2192             :         TcpSession((TcpServer*)server, socket),
    2193           0 :         server_(server){
    2194           0 :     }
    2195             : 
    2196           0 :     virtual void OnRead (const boost::asio::const_buffer buf) {
    2197           0 :         LOG(DEBUG, "StructuredSyslogTcpForwarderSession OnRead");
    2198           0 :     }
    2199             : 
    2200           0 :     virtual void WriteReady(const boost::system::error_code &ec) {
    2201           0 :         server_->WriteReady(ec);
    2202           0 :     }
    2203             : };
    2204             : 
    2205           0 : StructuredSyslogTcpForwarder::StructuredSyslogTcpForwarder(EventManager *evm, const std::string &ipaddress, int port) :
    2206             :     TcpServer(evm),
    2207           0 :     ipaddress_(ipaddress),
    2208           0 :     port_(port),
    2209           0 :     session_(NULL),
    2210           0 :     ready_to_send_(true) {
    2211           0 : }
    2212             : 
    2213           0 : TcpSession* StructuredSyslogTcpForwarder::AllocSession(Socket *socket) {
    2214           0 :     session_ = new StructuredSyslogTcpForwarderSession(this, socket);
    2215           0 :     return session_;
    2216             : }
    2217             : 
    2218           0 : void StructuredSyslogTcpForwarder::WriteReady(const boost::system::error_code &ec) {
    2219           0 :     LOG(DEBUG, "StructuredSyslogTcpForwarder::WriteReady");
    2220           0 :     if (ec) {
    2221           0 :         return;
    2222             :     }
    2223             :     {
    2224           0 :         std::scoped_lock lock(send_mutex_);
    2225           0 :         ready_to_send_ = true;
    2226           0 :     }
    2227             : }
    2228             : 
    2229           0 : void StructuredSyslogTcpForwarder::Connect() {
    2230           0 :     boost::system::error_code ec;
    2231           0 :     boost::asio::ip::tcp::endpoint endpoint;
    2232           0 :     endpoint.address(AddressFromString(ipaddress_, &ec));
    2233           0 :     endpoint.port(port_);
    2234           0 :     TcpServer::Connect(session_, endpoint);
    2235           0 : }
    2236             : 
    2237           0 : bool StructuredSyslogTcpForwarder::Send(const u_int8_t *data, size_t size, size_t *actual) {
    2238           0 :     *actual = 0;
    2239           0 :     std::scoped_lock lock(send_mutex_);
    2240           0 :     if (ready_to_send_) {
    2241           0 :         ready_to_send_ = session_->Send(data, size, actual);
    2242             :     }
    2243           0 :     return ready_to_send_;
    2244           0 : }
    2245             : 
    2246           0 : bool StructuredSyslogTcpForwarder::Connected() {
    2247           0 :     boost::system::error_code ec;
    2248           0 :     Endpoint remote = session_->socket()->remote_endpoint(ec);
    2249           0 :     return session_->Connected(remote);
    2250             : }
    2251             : 
    2252           0 : void StructuredSyslogTcpForwarder::SetSocketOptions() {
    2253           0 :     session_->SetSocketOptions();
    2254           0 : }
    2255             : 
    2256           0 : StructuredSyslogForwarder::StructuredSyslogForwarder(EventManager *evm,
    2257             :                                                      const vector <std::string> &tcp_forward_dst,
    2258             :                                                      const std::string &structured_syslog_kafka_broker,
    2259             :                                                      const std::string &structured_syslog_kafka_topic,
    2260             :                                                      const Options::Kafka &kafka_options,
    2261           0 :                                                      uint16_t structured_syslog_kafka_partitions):
    2262           0 :     evm_(evm) {
    2263           0 :     if (tcp_forward_dst.size() != 0) {
    2264           0 :         tcpForwarder_poll_timer_= TimerManager::CreateTimer(*evm->io_service(),
    2265             :                                   "tcpForwarder poll timer",
    2266             :                                   TaskScheduler::GetInstance()->GetTaskId("tcpForwarder poller"));
    2267           0 :         tcpForwarder_poll_timer_->Start(tcpForwarderPollInterval,
    2268             :         boost::bind(&StructuredSyslogForwarder::PollTcpForwarder, this),
    2269             :         boost::bind(&StructuredSyslogForwarder::PollTcpForwarderErrorHandler, this, _1, _2));
    2270             :     }
    2271           0 :     Init(tcp_forward_dst, structured_syslog_kafka_broker, structured_syslog_kafka_topic,
    2272             :          kafka_options,
    2273             :          structured_syslog_kafka_partitions);
    2274           0 : }
    2275             : 
    2276           0 : void StructuredSyslogForwarder::Init(const std::vector<std::string> &tcp_forward_dst,
    2277             :                                      const std::string &structured_syslog_kafka_broker,
    2278             :                                      const std::string &structured_syslog_kafka_topic,
    2279             :                                      const Options::Kafka &kafka_options,
    2280             :                                      uint16_t structured_syslog_kafka_partitions) {
    2281           0 :     for (std::vector<std::string>::const_iterator it = tcp_forward_dst.begin(); it != tcp_forward_dst.end(); ++it) {
    2282           0 :         std::vector<std::string> dest;
    2283           0 :         boost::split(dest, *it, boost::is_any_of(":"), boost::token_compress_on);
    2284             :         StructuredSyslogTcpForwarder* fwder = new StructuredSyslogTcpForwarder(evm_,
    2285           0 :                                                                                dest[0],
    2286           0 :                                                                                atoi(dest[1].c_str()));
    2287           0 :         fwder->CreateSession();
    2288           0 :         fwder->Connect();
    2289           0 :         fwder->SetSocketOptions();
    2290           0 :         tcpForwarder_.push_back(fwder);
    2291           0 :     }
    2292           0 :     if (structured_syslog_kafka_broker != "") {
    2293           0 :         kafkaForwarder_ = new KafkaForwarder(evm_, structured_syslog_kafka_broker,
    2294             :                                              structured_syslog_kafka_topic,
    2295             :                                              kafka_options,
    2296           0 :                                              structured_syslog_kafka_partitions);
    2297             :     } else {
    2298           0 :         kafkaForwarder_ = NULL;
    2299             :     }
    2300           0 : }
    2301             : 
    2302           0 : StructuredSyslogForwarder::~StructuredSyslogForwarder() {
    2303           0 :     Shutdown();
    2304           0 :     if (tcpForwarder_poll_timer_) {
    2305           0 :         TimerManager::DeleteTimer(tcpForwarder_poll_timer_);
    2306           0 :         tcpForwarder_poll_timer_ = NULL;
    2307             :     }
    2308           0 : }
    2309             : 
    2310           0 : void StructuredSyslogForwarder::PollTcpForwarderErrorHandler(string error_name,
    2311             :     string error_message) {
    2312           0 :     LOG(ERROR, "PollTcpForwarder Timer Err: " << error_name << " " << error_message);
    2313           0 : }
    2314             : 
    2315           0 : bool StructuredSyslogForwarder::PollTcpForwarder() {
    2316           0 :     LOG(DEBUG, "PollTcpForwarder start");
    2317           0 :     for (std::vector<StructuredSyslogTcpForwarder*>::iterator it = tcpForwarder_.begin();
    2318           0 :          it != tcpForwarder_.end(); ++it) {
    2319           0 :         if ((*it)->Connected() ==  false) {
    2320           0 :             std::string dst = (*it)->GetIpAddress();
    2321           0 :             int port = (*it)->GetPort();
    2322           0 :             LOG(DEBUG,"reconnecting to remote syslog server " << dst << ":" << port);
    2323           0 :             StructuredSyslogTcpForwarder* old_fwder = *it;
    2324           0 :             StructuredSyslogTcpForwarder* new_fwder = new StructuredSyslogTcpForwarder(evm_, dst, port);
    2325           0 :             new_fwder->CreateSession();
    2326           0 :             new_fwder->Connect();
    2327           0 :             new_fwder->SetSocketOptions();
    2328           0 :             std::replace(tcpForwarder_.begin(),tcpForwarder_.end(), old_fwder, new_fwder);
    2329           0 :             old_fwder->ClearSessions();
    2330           0 :             TcpServerManager::DeleteServer(old_fwder);
    2331           0 :         } else {
    2332           0 :             LOG(DEBUG,"connection to remote syslog server " << (*it)->GetIpAddress() << ":"<< (*it)->GetPort() << " is fine");
    2333             :         }
    2334             :     }
    2335           0 :     return true;
    2336             : }
    2337             : 
    2338           0 : void StructuredSyslogForwarder::Shutdown() {
    2339           0 :     if (kafkaForwarder_ != NULL) {
    2340           0 :         kafkaForwarder_->Shutdown();
    2341             :     }
    2342           0 :     LOG(DEBUG, __func__ << " structured_syslog_forwarder shutdown done");
    2343           0 : }
    2344             : 
    2345           0 : bool StructuredSyslogForwarder::kafkaForwarder() {
    2346           0 :     return (kafkaForwarder_ != NULL);
    2347             : }
    2348             : 
    2349           0 : void StructuredSyslogForwarder::Forward(boost::shared_ptr<StructuredSyslogQueueEntry> sqe) {
    2350           0 :     for (std::vector<StructuredSyslogTcpForwarder*>::iterator it = tcpForwarder_.begin();
    2351           0 :          it != tcpForwarder_.end(); ++it) {
    2352             :         size_t bytes_written;
    2353           0 :         (*it)->Send((const u_int8_t*)sqe->data->c_str(), sqe->length, &bytes_written);
    2354           0 :         if (bytes_written < sqe->length) {
    2355           0 :             LOG(DEBUG, "error writing - bytes_written: " << bytes_written);
    2356             :         }
    2357             :     }
    2358           0 :     if (kafkaForwarder_ != NULL) {
    2359           0 :         LOG(DEBUG, "forwarding json  - " << *(sqe->json_data));
    2360           0 :         kafkaForwarder_->Send(*(sqe->json_data), *(sqe->skey));
    2361             :     }
    2362           0 : }
    2363             : 
    2364           0 : StructuredSyslogQueueEntry::StructuredSyslogQueueEntry(boost::shared_ptr<std::string> d, size_t len,
    2365             :                                                        boost::shared_ptr<std::string> jd,
    2366           0 :                                                        boost::shared_ptr<std::string> key):
    2367           0 :         length(len), data(d), json_data(jd),skey(key) {
    2368           0 : }
    2369             : 
    2370           0 : StructuredSyslogQueueEntry::~StructuredSyslogQueueEntry() {
    2371           0 : }
    2372             : 
    2373             : }  // namespace structured_syslog

Generated by: LCOV version 1.14