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

Generated by: LCOV version 1.14