PPI: Implement PPI tracing support
g0dil [Wed, 12 Aug 2009 08:55:17 +0000 (08:55 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1289 270642c3-0616-0410-b53a-bc976706d245

PPI/Connectors.cc
PPI/Connectors.cci
PPI/Connectors.hh
Packets/Packet.cci
Packets/Packet.hh

index 6c1dade..46c762e 100644 (file)
@@ -30,6 +30,7 @@
 #include "Route.hh"
 #include "Module.hh"
 #include "ModuleManager.hh"
+#include "../Utils/Console/Console.hh"
 
 //#include "Connectors.mpp"
 #define prefix_
@@ -74,6 +75,78 @@ prefix_ void senf::ppi::connector::Connector::connect(Connector & target)
         peer().enqueueInitializable();
 }
 
+senf::ppi::connector::Connector::TraceState senf::ppi::connector::Connector::traceState_ (
+    senf::ppi::connector::Connector::NO_TRACING);
+
+prefix_ void senf::ppi::connector::Connector::trace(Packet const & p, char const * label)
+{
+    if (traceState_ ==  NO_TRACING)
+        return;
+    SENF_LOG_BLOCK(({
+                std::string type (prettyName(p.typeId().id()));
+                log << "PPI trace: 0x" << std::hex << p.id() << " " 
+                    << type.substr(21, type.size()-22) << " " << label
+                    << " on " << & module() << " " << prettyName(typeid(module()))
+                    << " connector 0x" << this << "\n";
+                if (traceState_ == TRACE_CONTENTS)
+                    p.dump(log);
+            }));
+}
+
+namespace senf { namespace ppi { namespace connector {
+
+    SENF_CONSOLE_REGISTER_ENUM_MEMBER( 
+        Connector, TraceState, (NO_TRACING)(TRACE_IDS)(TRACE_CONTENTS) );
+
+}}}
+
+namespace {
+
+    struct ConsoleRegister
+    {
+        ConsoleRegister();
+    };
+
+    ConsoleRegister::ConsoleRegister()
+    {
+        senf::console::sysdir()
+            .add("ppiTracing", SENF_FNP(senf::ppi::connector::Connector::TraceState,
+                                         senf::ppi::connector::Connector::tracing, ()))
+            .doc("Log every packet sent or received by any module.\n"
+                 "There are three different tracing levels:\n"
+                 "\n"
+                 "    NO_TRACING      don't output any tracing information\n"
+                 "    TRACE_IDS       trace packet id's but do not show packet contents\n"
+                 "    TRACE_CONTENTS  trace complete packet contents\n"
+                 "\n"
+                 "A log message is generated whenever the packet traverses a connector. The\n"
+                 "TRACE_IDS log message has the following format:\n"
+                 "\n"
+                 "    PPI trace: <packet-id> <packet-type> <direction>\n"
+                 "                      on <module-id> <module-type> connector <connector-id>\n"
+                 "\n"
+                 "The fields are:\n"
+                 "\n"
+                 "    packet-id       Numeric unique packet id. This value is unique for packets\n"
+                 "                    alive at the same time, packets at different times may (and\n"
+                 "                    will) share id's\n"
+                 "    packet-type     The type of the packet header\n"
+                 "    direction       'INCOMING' for packets entering the module, 'OUTGOING' for\n"
+                 "                    packets leaving it\n"
+                 "    module-id       Unique module id\n"
+                 "    module-type     Type of the module the packet is sent to/from\n"
+                 "    connector-id    Unique connector id\n");
+
+        senf::console::sysdir()
+            .add("ppiTracing", SENF_FNP(void, senf::ppi::connector::Connector::tracing,
+                                         (senf::ppi::connector::Connector::TraceState)))
+            .arg("state", "new tracing state");
+    }
+
+    ConsoleRegister consoleRegister;
+
+}
+
 prefix_ void senf::ppi::connector::Connector::disconnect()
 {
     // Cannot disconnected a non-connected connector
@@ -184,6 +257,7 @@ prefix_ senf::Packet senf::ppi::connector::InputConnector::operator()()
         queue_.pop_back();
         v_dequeueEvent();
     }
+    trace(p, "INCOMING");
     return p;
 }
 
index e6a7391..f480b02 100644 (file)
@@ -50,6 +50,16 @@ prefix_ senf::ppi::module::Module & senf::ppi::connector::Connector::module()
     return *module_;
 }
 
+prefix_ void senf::ppi::connector::Connector::tracing(TraceState state)
+{
+    traceState_ = state;
+}
+
+prefix_ senf::ppi::connector::Connector::TraceState senf::ppi::connector::Connector::tracing()
+{
+    return traceState_;
+}
+
 ////////////////////////////////////////
 // protected members
 
@@ -276,6 +286,7 @@ prefix_ senf::ppi::connector::InputConnector & senf::ppi::connector::OutputConne
 
 prefix_ void senf::ppi::connector::OutputConnector::operator()(Packet const & p)
 {
+    trace(p, "OUTGOING");
     if (connected())
         peer().enqueue(p);
 }
index 78b7023..002154e 100644 (file)
@@ -161,6 +161,8 @@ namespace connector {
     class Connector
         : ModuleManager::Initializable, boost::noncopyable
     {
+        SENF_LOG_CLASS_AREA();
+        SENF_LOG_DEFAULT_LEVEL(senf::log::NOTICE);
     public:
         Connector & peer() const;       ///< Get peer connected to this connector
         module::Module & module() const; ///< Get this connectors containing module
@@ -169,11 +171,18 @@ namespace connector {
 
         void disconnect();              ///< Disconnect connector from peer
 
+        enum TraceState { NO_TRACING, TRACE_IDS, TRACE_CONTENTS };
+
+        static void tracing(TraceState state);
+        static TraceState tracing();
+
     protected:
         Connector();
         virtual ~Connector();
 
         void connect(Connector & target);
+
+        void trace(Packet const & p, char const * label);
         
     private:
         virtual std::type_info const & packetTypeID();
@@ -183,6 +192,8 @@ namespace connector {
         Connector * peer_;
         module::Module * module_;
 
+        static TraceState traceState_;
+
         friend class module::Module;
     };
 
index 001f69c..6e9d735 100644 (file)
@@ -171,6 +171,12 @@ prefix_ senf::Packet::factory_t senf::Packet::factory()
     return ptr()->factory();
 }
 
+prefix_ unsigned long senf::Packet::id()
+    const
+{
+    return reinterpret_cast<unsigned long>(&ptr()->impl());
+}
+
 prefix_ bool senf::Packet::boolean_test()
     const
 {
index d148598..03016c3 100644 (file)
@@ -390,8 +390,8 @@ namespace senf {
         ///@{
 
         bool operator==(Packet const & other) const; ///< Check for packet identity
-        /**< Two packet handles compare equal if they really are the
-             same packet header in the same packet chain. */
+                                        /**< Two packet handles compare equal if they really are the
+                                             same packet header in the same packet chain. */
         bool boolean_test() const;      ///< Check, whether the packet is valid()
                                         /**< \see valid() */
         bool valid() const;             ///< Check, whether the packet is valid()
@@ -437,16 +437,16 @@ namespace senf {
                                              \endcode */
 
         void finalizeTo(Packet const & other);  ///< Update calculated fields
-        /**< The finalize() fammily of members will update
-             calculated packet fields: checksums, size fields and so
-             on. This includes any field, which can be set from
-             other information in the packet. Each concrete packet
-             type should document, which fields are set by
-             finalize().
-
-             finalizeTo(other) will automatically process all
-             packets/headers/interpreters beginning at \a other
-             backwards towards outer packets up to \c this. */
+                                        /**< The finalize() fammily of members will update
+                                             calculated packet fields: checksums, size fields and so
+                                             on. This includes any field, which can be set from
+                                             other information in the packet. Each concrete packet
+                                             type should document, which fields are set by
+                                             finalize().
+                                             
+                                             finalizeTo(other) will automatically process all
+                                             packets/headers/interpreters beginning at \a other
+                                             backwards towards outer packets up to \c this. */
 
         void finalizeAll();             ///< Update calculated fields
                                         /**< The finalize() fammily of members will update
@@ -470,23 +470,27 @@ namespace senf {
                                              headers. */
 
         void dump(std::ostream & os) const; ///< Write out a printable packet representation
-        /**< This method is provided mostly to help debugging packet
-             problems. Each concrete packet should implement a dump
-             method writing out all fields of the packet in a
-             readable representation. dump() will call this member
-             for each packet/header/interpreter in the chain from \c
-             this packet up to the end of the chain. */
-
-        TypeIdValue typeId() const;     ///< Get id of \c this packet
-        /**< This value is used e.g. in the packet registry to
-             associate packet types with other information.
-             \returns A type holding the same information as a
-                 type_info object, albeit assignable */
+                                        /**< This method is provided mostly to help debugging packet
+                                             problems. Each concrete packet should implement a dump
+                                             method writing out all fields of the packet in a
+                                             readable representation. dump() will call this member
+                                             for each packet/header/interpreter in the chain from \c
+                                             this packet up to the end of the chain. */
+
+        TypeIdValue typeId() const;     ///< Get type of \c this packet
+                                        /**< This value is used e.g. in the packet registry to
+                                             associate packet types with other information.
+                                             \returns A type holding the same information as a
+                                             type_info object, albeit assignable */
         factory_t factory() const;      ///< Return factory instance of \c this packet
-        /**< The returned factory instance can be used to create new
-             packets of the given type without knowing the concrete
-             type of the packet. The value may be stored away for
-             later use if needed. */
+                                        /**< The returned factory instance can be used to create new
+                                             packets of the given type without knowing the concrete
+                                             type of the packet. The value may be stored away for
+                                             later use if needed. */
+
+        unsigned long id() const;       ///< Unique packet id
+                                        /**< Get a unique packet id. If two packets have the same
+                                             id, they share the internal data representation.. */
 
         ///@}