LCOV - code coverage report
Current view: top level - kafkaopmon/src - OpMonPublisher.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 44.6 % 56 25
Test Date: 2026-10-11 15:05:20 Functions: 66.7 % 3 2

            Line data    Source code
       1              : /**
       2              :  * @file OpMonPublisher.cpp OpMonPublisher Class Implementation
       3              :  *
       4              :  * This is part of the DUNE DAQ Software Suite, copyright 2020.
       5              :  * Licensing/copyright details are in the COPYING file that you should have
       6              :  * received with this code.
       7              :  */
       8              : 
       9              : #include "kafkaopmon/OpMonPublisher.hpp"
      10              : 
      11              : using namespace dunedaq::kafkaopmon;
      12              : 
      13            3 : OpMonPublisher::OpMonPublisher(const nlohmann::json& conf)
      14              : {
      15              : 
      16            3 :   RdKafka::Conf* k_conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL);
      17            3 :   std::string errstr;
      18              : 
      19              :   // Good observations on threadsafety here
      20              :   // https://www.confluent.io/blog/modern-cpp-kafka-api-for-safe-easy-messaging/
      21              : 
      22            3 :   auto it = conf.find("bootstrap");
      23            3 :   if (it == conf.end()) {
      24            1 :     throw MissingParameter(ERS_HERE, "bootstrap", nlohmann::to_string(conf));
      25              :   }
      26              : 
      27            2 :   k_conf->set("bootstrap.servers", *it, errstr);
      28            2 :   if (!errstr.empty()) {
      29            0 :     throw FailedConfiguration(ERS_HERE, "bootstrap.servers", errstr);
      30              :   }
      31              : 
      32            2 :   std::string client_id;
      33            2 :   it = conf.find("cliend_id");
      34            2 :   if (it != conf.end())
      35            0 :     client_id = *it;
      36              :   else
      37            2 :     client_id = "kafkaopmon_default_producer";
      38              : 
      39            2 :   k_conf->set("client.id", client_id, errstr);
      40            2 :   if (!errstr.empty()) {
      41            0 :     ers::error(FailedConfiguration(ERS_HERE, "client.id", errstr));
      42              :   }
      43              : 
      44              :   // Create producer instance
      45            2 :   m_producer.reset(RdKafka::Producer::create(k_conf, errstr));
      46              : 
      47            2 :   if (!m_producer) {
      48            0 :     throw FailedProducerCreation(ERS_HERE, errstr);
      49              :   }
      50              : 
      51            2 :   it = conf.find("default_topic");
      52            2 :   if (it != conf.end())
      53            1 :     m_default_topic = "monitoring." + it->get<std::string>();
      54            5 : }
      55              : 
      56            2 : OpMonPublisher::~OpMonPublisher()
      57              : {
      58              : 
      59            2 :   int timeout_ms = 500;
      60            2 :   RdKafka::ErrorCode err = m_producer->flush(timeout_ms);
      61              : 
      62            2 :   if (err == RdKafka::ERR__TIMED_OUT) {
      63            0 :     ers::warning(TimeoutReachedWhileFlushing(ERS_HERE, timeout_ms));
      64              :   }
      65            2 : }
      66              : 
      67              : void
      68            0 : OpMonPublisher::publish(dunedaq::opmon::OpMonEntry&& entry) const
      69              : {
      70              : 
      71            0 :   std::string binary;
      72            0 :   entry.SerializeToString(&binary);
      73              : 
      74            0 :   auto topic = extract_topic(entry);
      75            0 :   auto key = extract_key(entry);
      76              : 
      77            0 :   RdKafka::ErrorCode err = m_producer->produce(topic,
      78              :                                                RdKafka::Topic::PARTITION_UA,
      79              :                                                RdKafka::Producer::RK_MSG_COPY,
      80            0 :                                                const_cast<char*>(binary.c_str()),
      81              :                                                binary.size(),
      82            0 :                                                key.c_str(),
      83              :                                                key.size(),
      84              :                                                0,
      85              :                                                nullptr);
      86              : 
      87            0 :   if (err == RdKafka::ERR_NO_ERROR)
      88            0 :     return;
      89              : 
      90            0 :   std::string err_cause;
      91              : 
      92            0 :   switch (err) {
      93            0 :     case RdKafka::ERR__QUEUE_FULL:
      94            0 :       err_cause = "maximum number of outstanding messages reached";
      95              :       break;
      96            0 :     case RdKafka::ERR_MSG_SIZE_TOO_LARGE:
      97            0 :       err_cause = "message too large";
      98              :       break;
      99            0 :     case RdKafka::ERR__UNKNOWN_PARTITION:
     100            0 :       err_cause = "Unknown partition";
     101              :       break;
     102            0 :     case RdKafka::ERR__UNKNOWN_TOPIC:
     103            0 :       err_cause = "Unknown topic (";
     104            0 :       err_cause += topic;
     105            0 :       err_cause += ')';
     106              :       break;
     107            0 :     default:
     108            0 :       err_cause = "unknown";
     109              :       break;
     110              :   }
     111              : 
     112            0 :   throw FailedProduce(ERS_HERE, key, err_cause);
     113            0 : }
        

Generated by: LCOV version 2.0-1