LCOV - code coverage report
Current view: top level - /opt/artdaq/srcs/artdaq-mfextensions/mfextensions/Destinations - Friendly_mfPlugin.cc (source / functions) Coverage Total Hit
Test: artdaq.info.cleaned Lines: 0.0 % 80 0
Test Date: 2025-09-04 00:45:34 Functions: 0.0 % 6 0

            Line data    Source code
       1              : #include "cetlib/PluginTypeDeducer.h"
       2              : #include "cetlib/ostream_handle.h"
       3              : #include "fhiclcpp/ParameterSet.h"
       4              : #include "fhiclcpp/types/ConfigurationTable.h"
       5              : 
       6              : #include "cetlib/compiler_macros.h"
       7              : #include "messagefacility/MessageService/ELdestination.h"
       8              : #include "messagefacility/MessageService/ELostreamOutput.h"
       9              : #include "messagefacility/Utilities/ELseverityLevel.h"
      10              : #include "messagefacility/Utilities/exception.h"
      11              : 
      12              : // C/C++ includes
      13              : #include <algorithm>
      14              : #include <iostream>
      15              : #include <memory>
      16              : 
      17              : namespace mfplugins {
      18              : using namespace mf::service;
      19              : using mf::ErrorObj;
      20              : 
      21              : /// <summary>
      22              : /// Parser-Friendly Message Facility destination plugin
      23              : /// </summary>
      24              : class ELFriendly : public ELostreamOutput
      25              : {
      26              : public:
      27              :         /**
      28              :          * \brief Configuration Parameters for ELFriendly
      29              :          */
      30              :         struct Config
      31              :         {
      32              :                 /// Configuration parameters for ELostreamOutput
      33              :                 fhicl::TableFragment<ELostreamOutput::Config> elOstrConfig;
      34              :                 /// "field_delimiter" (Default: "  "): String to print between each message field
      35              :                 fhicl::Atom<std::string> delimiter = fhicl::Atom<std::string>{
      36              :                     fhicl::Name{"field_delimiter"}, fhicl::Comment{"String to print between each message field"}, "  "};
      37              :         };
      38              :         /// Used for ParameterSet validation
      39              :         using Parameters = fhicl::WrappedTable<Config>;
      40              : 
      41              : public:
      42              :         /// <summary>
      43              :         /// ELFriendly Constructor
      44              :         /// </summary>
      45              :         /// <param name="pset">ParameterSet used to configure ELFriendly</param>
      46              :         explicit ELFriendly(Parameters const& pset);
      47              : 
      48              :         /**
      49              :          * \brief Fill the "Prefix" portion of the message
      50              :          * \param o Output stringstream
      51              :          * \param msg MessageFacility object containing header information
      52              :          */
      53              :         void fillPrefix(std::ostringstream& o, const ErrorObj& msg) override;
      54              :         /**
      55              :          * \brief Fill the "User Message" portion of the message
      56              :          * \param o Output stringstream
      57              :          * \param msg MessageFacility object containing header information
      58              :          */
      59              :         void fillUsrMsg(std::ostringstream& o, const ErrorObj& msg) override;
      60              :         /**
      61              :          * \brief Fill the "Suffix" portion of the message
      62              :          * \param o Output stringstream
      63              :          * \param msg MessageFacility object containing header information
      64              :          */
      65              :         void fillSuffix(std::ostringstream& o, const ErrorObj& msg) override;
      66              : 
      67              : private:
      68              :         std::string delimeter_;
      69              : };
      70              : 
      71              : // END DECLARATION
      72              : //======================================================================
      73              : // BEGIN IMPLEMENTATION
      74              : 
      75              : //======================================================================
      76              : // ELFriendly c'tor
      77              : //======================================================================
      78              : 
      79            0 : ELFriendly::ELFriendly(Parameters const& pset)
      80            0 :     : ELostreamOutput(pset().elOstrConfig(), cet::ostream_handle{std::cout}, false), delimeter_(pset().delimiter()) {}
      81              : 
      82              : //======================================================================
      83              : // Message prefix filler ( overriddes ELdestination::fillPrefix )
      84              : //======================================================================
      85            0 : void ELFriendly::fillPrefix(std::ostringstream& oss, const ErrorObj& msg)
      86              : {
      87              :         // if (msg.is_verbatim()) return;
      88              : 
      89              :         // Output the prologue:
      90              :         //
      91              : 
      92            0 :         auto const& xid = msg.xid();
      93              : 
      94            0 :         auto id = xid.id();
      95            0 :         auto app = xid.application();
      96            0 :         auto module = xid.module();
      97            0 :         auto subroutine = xid.subroutine();
      98            0 :         std::replace(id.begin(), id.end(), ' ', '-');
      99            0 :         std::replace(app.begin(), app.end(), ' ', '-');
     100            0 :         std::replace(module.begin(), module.end(), ' ', '-');
     101            0 :         std::replace(subroutine.begin(), subroutine.end(), ' ', '-');
     102              : 
     103            0 :         emitToken(oss, "%MSG");
     104            0 :         emitToken(oss, xid.severity().getSymbol());
     105            0 :         emitToken(oss, delimeter_);
     106            0 :         emitToken(oss, id);
     107            0 :         emitToken(oss, msg.idOverflow());
     108            0 :         emitToken(oss, ":");
     109            0 :         emitToken(oss, delimeter_);
     110              : 
     111              :         // Output serial number of message:
     112              :         //
     113            0 :         if (format_.want(SERIAL))
     114              :         {
     115            0 :                 std::ostringstream s;
     116            0 :                 s << msg.serial();
     117            0 :                 emitToken(oss, "[serial #" + s.str() + "]");
     118            0 :                 emitToken(oss, delimeter_);
     119            0 :         }
     120              : 
     121              :         // Provide further identification:
     122              :         //
     123            0 :         bool needAspace = true;
     124            0 :         if (format_.want(EPILOGUE_SEPARATE))
     125              :         {
     126            0 :                 if (module.length() + subroutine.length() > 0)
     127              :                 {
     128            0 :                         emitToken(oss, "\n");
     129            0 :                         needAspace = false;
     130              :                 }
     131            0 :                 else if (format_.want(TIMESTAMP) && !format_.want(TIME_SEPARATE))
     132              :                 {
     133            0 :                         emitToken(oss, "\n");
     134            0 :                         needAspace = false;
     135              :                 }
     136              :         }
     137            0 :         if (format_.want(MODULE) && (module.length() > 0))
     138              :         {
     139            0 :                 if (needAspace)
     140              :                 {
     141            0 :                         emitToken(oss, delimeter_);
     142            0 :                         needAspace = false;
     143              :                 }
     144            0 :                 emitToken(oss, module + "  ");
     145              :         }
     146            0 :         if (format_.want(SUBROUTINE) && (subroutine.length() > 0))
     147              :         {
     148            0 :                 if (needAspace)
     149              :                 {
     150            0 :                         emitToken(oss, delimeter_);
     151            0 :                         needAspace = false;
     152              :                 }
     153            0 :                 emitToken(oss, subroutine + "()");
     154            0 :                 emitToken(oss, delimeter_);
     155              :         }
     156              : 
     157              :         // Provide time stamp:
     158              :         //
     159            0 :         if (format_.want(TIMESTAMP))
     160              :         {
     161            0 :                 if (format_.want(TIME_SEPARATE))
     162              :                 {
     163            0 :                         emitToken(oss, "\n");
     164            0 :                         needAspace = false;
     165              :                 }
     166            0 :                 if (needAspace)
     167              :                 {
     168            0 :                         emitToken(oss, delimeter_);
     169            0 :                         needAspace = false;
     170              :                 }
     171            0 :                 emitToken(oss, format_.timestamp(msg.timestamp()));
     172            0 :                 emitToken(oss, delimeter_);
     173              :         }
     174              : 
     175              :         // Provide the context information:
     176              :         //
     177            0 :         if (format_.want(SOME_CONTEXT))
     178              :         {
     179            0 :                 if (needAspace)
     180              :                 {
     181            0 :                         emitToken(oss, delimeter_);
     182              :                         // needAspace = false; // Uncomment this line if more fields are added in the future
     183              :                 }
     184            0 :                 emitToken(oss, msg.context());
     185              :         }
     186            0 : }
     187              : 
     188              : //=============================================================================
     189            0 : void ELFriendly::fillUsrMsg(std::ostringstream& oss, ErrorObj const& msg)
     190              : {
     191            0 :         if (!format_.want(TEXT))
     192              :         {
     193            0 :                 return;
     194              :         }
     195              : 
     196            0 :         auto const usrMsgStart = std::next(msg.items().cbegin(), 4);
     197            0 :         auto it = msg.items().cbegin();
     198              : 
     199              :         // Determine if file and line should be included
     200              : 
     201              :         // The first four items are { " ", "<FILENAME>", ":", "<LINE>" }
     202            0 :         while (it != usrMsgStart)
     203              :         {
     204            0 :                 if ((*it == " ") && (*std::next(it) == "--"))
     205              :                 {
     206              :                         // Do not emit if " --:0" is the match
     207              :                         std::advance(it, 4);
     208              :                 }
     209              :                 else
     210              :                 {
     211              :                         // Emit if <FILENAME> and <LINE> are meaningful
     212            0 :                         emitToken(oss, *it++);
     213              :                 }
     214              :         }
     215              : 
     216              :         // Check for user-requested line breaks
     217            0 :         if (format_.want(NO_LINE_BREAKS))
     218              :         {
     219            0 :                 emitToken(oss, " ==> ");
     220              :         }
     221              :         else
     222              :         {
     223            0 :                 emitToken(oss, "", true);
     224              :         }
     225              : 
     226              :         // For verbatim (and user-supplied) messages, just print the contents
     227            0 :         auto const end = msg.items().cend();
     228            0 :         for (; it != end; ++it)
     229              :         {
     230            0 :                 emitToken(oss, *it);
     231              :         }
     232              : }
     233              : 
     234              : //=============================================================================
     235            0 : void ELFriendly::fillSuffix(std::ostringstream& oss, ErrorObj const& /*msg*/)
     236              : {
     237            0 :         if (!format_.want(NO_LINE_BREAKS))
     238              :         {
     239            0 :                 emitToken(oss, "\n%MSG");
     240              :         }
     241            0 :         oss << '\n';
     242            0 : }
     243              : 
     244              : }  // end namespace mfplugins
     245              : 
     246              : //======================================================================
     247              : //
     248              : // makePlugin function
     249              : //
     250              : //======================================================================
     251              : 
     252              : #ifndef EXTERN_C_FUNC_DECLARE_START
     253              : #define EXTERN_C_FUNC_DECLARE_START extern "C" {
     254              : #endif
     255              : 
     256              : EXTERN_C_FUNC_DECLARE_START
     257            0 : auto makePlugin(const std::string& /*unused*/, const fhicl::ParameterSet& pset)
     258              : {
     259            0 :         return std::make_unique<mfplugins::ELFriendly>(pset);
     260              : }
     261              : }
     262              : 
     263            0 : DEFINE_BASIC_PLUGINTYPE_FUNC(mf::service::ELdestination)
        

Generated by: LCOV version 2.0-1