3434#include " process.hpp"
3535#include " flowifc.hpp"
3636
37+ #include < telemetry.hpp>
38+ #include < atomic>
39+ #include < cstdint>
40+
3741namespace ipxp {
3842
3943#define DEFAULT_EXPORTER_ID 1
4044
45+ struct OutputPluginStats {
46+ uint64_t flows_seen = 0 ;
47+ uint64_t flows_dropped = 0 ;
48+ uint64_t flows_exported = 0 ;
49+ uint64_t bytes_exported = 0 ;
50+
51+ void clear ()
52+ {
53+ flows_seen = 0 ;
54+ flows_dropped = 0 ;
55+ flows_exported = 0 ;
56+ bytes_exported = 0 ;
57+ }
58+ };
59+
60+ struct OutputPluginAtomicStats {
61+ std::atomic<uint64_t > flows_seen = 0 ;
62+ std::atomic<uint64_t > flows_dropped = 0 ;
63+ std::atomic<uint64_t > flows_exported = 0 ;
64+ std::atomic<uint64_t > bytes_exported = 0 ;
65+ std::atomic<uint64_t > fps_exported = 0 ;
66+ std::atomic<uint64_t > mbps_exported = 0 ;
67+
68+
69+ void updatePktBurstStats (const OutputPluginStats& basicStats, uint64_t timestamp)
70+ {
71+ flows_seen.fetch_add (basicStats.flows_seen , std::memory_order_relaxed);
72+ flows_dropped.fetch_add (basicStats.flows_dropped , std::memory_order_relaxed);
73+ flows_exported.fetch_add (basicStats.flows_exported , std::memory_order_relaxed);
74+ bytes_exported.fetch_add (basicStats.bytes_exported , std::memory_order_relaxed);
75+
76+ if (timestamp == 0 ) {
77+ fps_exported.store (0 );
78+ mbps_exported.store (0 );
79+ return ;
80+ }
81+
82+ fps_exported.store (basicStats.flows_exported * 1000000000 / timestamp);
83+ mbps_exported.store (basicStats.bytes_exported * 8 * 1000000000 / timestamp / 1024 / 1024 );
84+ }
85+ };
86+
87+ static telemetry::Dict createOutputPluginStatsDict (const OutputPluginAtomicStats& burstStats)
88+ {
89+ telemetry::Dict dict;
90+ dict[" flows_seen" ] = burstStats.flows_seen ;
91+ dict[" flows_dropped" ] = burstStats.flows_dropped ;
92+ dict[" flows_exported" ] = burstStats.flows_exported ;
93+ dict[" bytes_exported" ] = burstStats.bytes_exported ;
94+ dict[" fps_exported" ] = burstStats.fps_exported ;
95+ dict[" mbps_exported" ] = burstStats.mbps_exported ;
96+ return dict;
97+ }
98+
4199/* *
42100 * \brief Base class for flow exporters.
43101 */
44102class OutputPlugin : public Plugin
45103{
46104public:
47105 typedef std::vector<std::pair<std::string, ProcessPlugin *>> Plugins;
48- uint64_t m_flows_seen; /* *< Number of flows received to export. */
49- uint64_t m_flows_dropped; /* *< Number of flows that could not be exported. */
50106
51- OutputPlugin () : m_flows_seen(0 ), m_flows_dropped(0 ) {}
107+ OutputPlugin () = default ;
108+
52109 virtual ~OutputPlugin () {}
53110
54- virtual void init (const char *params, Plugins &plugins) = 0;
111+ void init (const char *params, Plugins &plugins, const std::shared_ptr<telemetry::Directory>& dir)
112+ {
113+ const auto statsFile = dir->addFile (
114+ " basic_stats" ,
115+ {.read = [this ]() { return createOutputPluginStatsDict (m_atomicStats); },
116+ .clear = nullptr });
117+
118+ m_holder.add (statsFile);
119+
120+ init_plugin (params, plugins, dir);
121+ }
55122
56123 enum class Result {
57124 EXPORTED = 0 ,
@@ -70,6 +137,34 @@ class OutputPlugin : public Plugin
70137 virtual void flush ()
71138 {
72139 }
140+
141+ void update_stats (uint64_t timestamp) override final
142+ {
143+ m_atomicStats.updatePktBurstStats (m_stats, timestamp);
144+ m_stats.clear ();
145+
146+ update_plugin_stats (timestamp);
147+ }
148+
149+ const OutputPluginAtomicStats& get_stats () const
150+ {
151+ return m_atomicStats;
152+ }
153+
154+
155+ protected:
156+ virtual void init_plugin (const char *params, Plugins &plugins, const std::shared_ptr<telemetry::Directory>& dir) = 0;
157+
158+
159+ virtual void update_plugin_stats (uint64_t timestamp)
160+ {
161+ (void ) timestamp;
162+ }
163+
164+ OutputPluginStats m_stats = {};
165+ telemetry::Holder m_holder;
166+ private:
167+ OutputPluginAtomicStats m_atomicStats = {};
73168};
74169
75170}
0 commit comments