]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
integrated base, cpu, event with formatters. added string value for formatters.
authorCarter Waxman <cwaxman@cisco.com>
Wed, 6 Apr 2016 19:50:23 +0000 (15:50 -0400)
committerCarter Waxman <cwaxman@cisco.com>
Wed, 6 Apr 2016 19:50:23 +0000 (15:50 -0400)
17 files changed:
src/detection/fp_detect.cc
src/network_inspectors/perf_monitor/base_tracker.cc
src/network_inspectors/perf_monitor/base_tracker.h
src/network_inspectors/perf_monitor/cpu_tracker.cc
src/network_inspectors/perf_monitor/csv_formatter.cc
src/network_inspectors/perf_monitor/csv_formatter.h
src/network_inspectors/perf_monitor/event_tracker.cc
src/network_inspectors/perf_monitor/event_tracker.h
src/network_inspectors/perf_monitor/flow_ip_tracker.cc
src/network_inspectors/perf_monitor/perf_formatter.cc
src/network_inspectors/perf_monitor/perf_formatter.h
src/network_inspectors/perf_monitor/perf_tracker.cc
src/network_inspectors/perf_monitor/perf_tracker.h
src/network_inspectors/perf_monitor/text_formatter.cc
src/network_inspectors/perf_monitor/text_formatter.h
src/utils/stats.cc
src/utils/stats.h

index f91e668a42b95ce166da61a03bfcf108b2e206cf..9d3660b9225f2c946ef578da18689d071c6b25e8 100644 (file)
@@ -473,13 +473,13 @@ static int rule_tree_match(
         {
             //  We have a qualified event from this tree
             pomd->pg->event_count++;
-            perf_event->UpdateQEvents();
+            perf_event->update_qualified_events();
         }
         else
         {
             // This means that the event is non-qualified.
             pomd->pg->match_count++;
-            perf_event->UpdateNQEvents();
+            perf_event->update_non_qualified_events();
         }
     }
 
@@ -1089,13 +1089,13 @@ static inline int fpEvalHeaderSW(PortGroup* port_group, Packet* p,
             {
                 // We have a qualified event from this tree
                 port_group->event_count++;
-                perf_event->UpdateQEvents();
+                perf_event->update_qualified_events();
             }
             else
             {
                 // This means that the event is non-qualified.
                 port_group->match_count++;
-                perf_event->UpdateNQEvents();
+                perf_event->update_non_qualified_events();
             }
             pc.slow_searches++;
         }
index 60ed0b0ddf49eff4e0668948b79ae84241b0c74c..e951d9682edd844d0fa915958d8be62244352e27 100644 (file)
@@ -34,69 +34,36 @@ using namespace std;
 BaseTracker::BaseTracker(PerfConfig* perf) : PerfTracker(perf,
     perf->output == PERF_FILE ? BASE_FILE : nullptr)
 {
-    csv_header.clear();
-
-    csv_header += ("#timestamp");
     for (unsigned i = 0; i < config->modules.size(); i++)
     {
         Module *m = config->modules.at(i);
         vector<unsigned> peg_map = config->mod_peg_idxs.at(i);
+
+        formatter->register_section(m->get_name());
         for (auto& idx : peg_map)
-        {
-            csv_header += ",";
-            csv_header += m->get_name();
-            csv_header += ".";
-            csv_header += m->get_pegs()[idx].name;
-        }
+             formatter->register_field(m->get_pegs()[idx].name);
     }
-    csv_header += "\n";
 }
 
 void BaseTracker::reset()
 {
-    if (fh && config->format == PERF_CSV)
-    {
-        fwrite(csv_header.c_str(), csv_header.length(), 1, fh);
-        fflush(fh);
-    }
+    formatter->finalize_fields(fh);
 }
 
 void BaseTracker::process(bool summary)
 {
-    char buf[32]; // > log10(2^64 - 1)
-
-    if (!fh)
-        return;
-
-    string statLine;
-    statLine.clear();
-    snprintf(buf, sizeof(buf), "%ld", (long)cur_time);
-    statLine += buf;
-
     for (unsigned i = 0; i < config->modules.size(); i++)
     {
         Module* m = config->modules.at(i);
         vector<unsigned> idxs = config->mod_peg_idxs.at(i);
         PegCount* pegs = m->get_counts();
 
-        if (config->format == PERF_CSV)
-        {
-            for (auto& idx : idxs)
-            {
-                snprintf(buf, sizeof(buf), ",%" PRIu64, pegs[idx]);
-                statLine += buf;
-            }
-        }
-        else if(config->format == PERF_TEXT)
-            m->show_interval_stats(idxs, fh);
+        for (unsigned j = 0; j < idxs.size(); j++)
+            formatter->set_field(i, j, (PegCount)pegs[idxs[j]]);
         if (!summary)
             m->sum_stats();
     }
-    if (config->format == PERF_CSV)
-    {
-        statLine += "\n";
-        fwrite(statLine.c_str(), statLine.length(), 1, fh);
-        fflush(fh);
-    }
+    formatter->write(fh, cur_time);
+    formatter->clear();
 }
 
index a7a36899671d0963bfab9882a68b59464900af6c..2100fef37ff3062d6afb077f4cceae0b9cabd993 100644 (file)
@@ -30,9 +30,6 @@ public:
 
     void reset() override;
     void process(bool) override;
-
-private:
-    std::string csv_header;
 };
 
 #endif
index 633681e34e4e56d98100f5239bd3754385dd329d..6ed2bf5389c83b54ba99f2e179635c63f2d143d1 100644 (file)
 #include "catch/catch.hpp"
 #endif
 
-static const std::string csv_header =
-    "#timestamp,user,system,idle\n";
+enum CPUFieldRef
+{
+    FR_USER = 0,
+    FR_SYSTEM,
+    FR_IDLE
+};
 
 static inline uint64_t get_microseconds(struct timeval t)
 {
@@ -46,7 +50,13 @@ static inline uint64_t get_microseconds(struct timeval t)
 
 
 CPUTracker::CPUTracker(PerfConfig *perf) :
-    PerfTracker(perf, perf->output == PERF_FILE ? CPU_FILE : nullptr){}
+    PerfTracker(perf, perf->output == PERF_FILE ? CPU_FILE : nullptr)
+{
+    formatter->register_section("cpu");
+    formatter->register_field("user");
+    formatter->register_field("system");
+    formatter->register_field("idle");    
+}
 
 void CPUTracker::get_clocks(struct timeval& user_time,
     struct timeval& sys_time, struct timeval& wall_time)
@@ -85,11 +95,7 @@ void CPUTracker::get_times(uint64_t& user, uint64_t& system, uint64_t& wall)
 void CPUTracker::reset()
 {
     get_times(last_ut, last_st, last_wt);
-    if (config->format == PERF_CSV)
-    {
-        fwrite(csv_header.c_str(), csv_header.length(), 1, fh);
-        fflush(fh);
-    }
+    formatter->finalize_fields(fh);
 }
 
 void CPUTracker::process(bool)
@@ -107,22 +113,12 @@ void CPUTracker::process(bool)
     last_st = system;
     last_wt = wall;
 
-    double d_user = (double) delt_user / delt_wall * 100;
-    double d_system = (double) delt_system / delt_wall * 100;
-    double d_idle = (double) delt_idle / delt_wall * 100;
-    if ( config->format == PERF_TEXT )
-    {
-        LogLabel("cpu usage", fh);
-        LogStat("User", d_user, fh);
-        LogStat("System", d_system, fh);
-        LogStat("Idle", d_idle, fh);
-    }
-    else if ( config->format == PERF_CSV )
-    {
-        fprintf(fh, CSVu64 "%g,%g,%g\n",
-            (uint64_t)cur_time, d_user, d_system, d_idle);
-    }
-    fflush(fh);
+    formatter->set_field(0, FR_USER, (double) delt_user / delt_wall * 100);
+    formatter->set_field(0, FR_SYSTEM, (double) delt_system / delt_wall * 100);
+    formatter->set_field(0, FR_IDLE, (double) delt_idle / delt_wall * 100);
+
+    formatter->write(fh, cur_time);
+    formatter->clear();
 }
 
 #ifdef UNIT_TEST
@@ -177,7 +173,7 @@ TEST_CASE("Timeval to scalar", "[cpu_tracker]")
 TEST_CASE("csv", "[cpu_tracker]")
 {
     const char* cooked =
-    "#timestamp,user,system,idle\n"
+    "#timestamp,cpu.user,cpu.system,cpu.idle\n"
     "1234567890,23.0769,38.4615,38.4615\n"
     "1234567890,0,0,100\n"
     "1234567890,23.0769,38.4615,38.4615\n";
@@ -223,10 +219,10 @@ TEST_CASE("text", "[cpu_tracker]")
 {
     const char* cooked =
     "--------------------------------------------------\n"
-    "cpu usage\n"
-    "                     User: 23.0769\n"
-    "                   System: 38.4615\n"
-    "                     Idle: 38.4615\n";
+    "cpu\n"
+    "                     user: 23.0769\n"
+    "                   system: 38.4615\n"
+    "                     idle: 38.4615\n";
 
     FILE* f = tmpfile();
 
index 22c9668dc3fd58141b24328d0b0868f0baa54d7b..1174b10c18b790a8e49d6cb3587ff19c33e25652 100644 (file)
 
 using namespace std;
 
-SectionRef CSVFormatter::register_section(string name)
+void CSVFormatter::register_section(string name)
 {
     section_names.push_back(name);
     field_names.push_back(vector<string>());
 
-    return PerfFormatter::register_section(name);
+    PerfFormatter::register_section(name);
 }
 
-FieldRef CSVFormatter::register_field(SectionRef section, string name)
+void CSVFormatter::register_field(string name)
 {
-    field_names[section].push_back(name);
-    return PerfFormatter::register_field(section, name);
+    field_names[last_section].push_back(name);
+    PerfFormatter::register_field(name);
 }
 
 void CSVFormatter::finalize_fields(FILE* fh)
@@ -78,6 +78,10 @@ void CSVFormatter::write(FILE* fh, time_t timestamp)
                 case FT_PEG_COUNT:
                     fprintf(fh, ",%" PRIu64, values[i][j].pc);
                     break;
+                case FT_STRING:
+                    fprintf(fh, ",%s", values[i][j].s ?
+                        values[i][j].s : "");
+                    break;
                 case FT_UNSET:
                     fputs(",0", fh);
                     break; 
@@ -93,26 +97,27 @@ void CSVFormatter::write(FILE* fh, time_t timestamp)
 TEST_CASE("csv output", "[CSVFormatter]")
 {
     const char* cooked =
-        "#timestamp,name.one,name.two,other.three,other.four\n"
-        "1234567890,0,1,2,34.5678\n"
-        "2345678901,0,0,0,0\n";
-    FieldRef fr[4];
+        "#timestamp,name.one,name.two,other.three,other.four,other.five\n"
+        "1234567890,0,1,2,34.5678,hellothere\n"
+        "2345678901,0,0,0,0,\n";
     
     FILE* fh = tmpfile();
     CSVFormatter f;
 
-    SectionRef s = f.register_section("name");
-    fr[0] = f.register_field(s, "one");
-    fr[1] = f.register_field(s, "two");
-    s = f.register_section("other");
-    fr[2] = f.register_field(s, "three");
-    fr[3] = f.register_field(s, "four");
+    f.register_section("name");
+    f.register_field("one");
+    f.register_field("two");
+    f.register_section("other");
+    f.register_field("three");
+    f.register_field("four");
+    f.register_field("five");
     f.finalize_fields(fh);
 
-    f.set_field(fr[0], (PegCount)0);
-    f.set_field(fr[1], (PegCount)1);
-    f.set_field(fr[2], (PegCount)2);
-    f.set_field(fr[3], 34.5678);
+    f.set_field(0, 0, (PegCount)0);
+    f.set_field(0, 1, (PegCount)1);
+    f.set_field(1, 0, (PegCount)2);
+    f.set_field(1, 1, 34.5678);
+    f.set_field(1, 2, "hellothere");
     f.write(fh, (time_t)1234567890);
 
     f.clear();
index 7d755adc27584c4f2b4ed321f99580a3d45fcae1..a12168723601d9760c6189f8e00000adf1fab956 100644 (file)
@@ -27,8 +27,8 @@ class CSVFormatter : public PerfFormatter
 {
 public:
     CSVFormatter() : PerfFormatter() {};
-    SectionRef register_section(std::string) override;
-    FieldRef register_field(SectionRef, std::string) override;
+    void register_section(std::string) override;
+    void register_field(std::string) override;
     void finalize_fields(FILE*) override;
     void write(FILE*, time_t) override;
 
index 1180dbd304f3eb32bd4e074fe34b3503e9643aa4..ad56472610d70ae40331effa4a473c9c323bee45 100644 (file)
 #include "utils/stats.h"
 #include "utils/util.h"
 
-#include "text_formatter.h"
-
 #define EVENT_FILE (PERF_NAME "_event.csv")
 
-THREAD_LOCAL EventTracker* perf_event;
+enum EventFieldRef
+{
+    FR_TOTAL = 0,
+    FR_QUALIFIED,
+    FR_NON_QUALIFIED
+};
 
-static std::string csv_header =
-    "#timestamp,qualified_events,non_qualified_events\n";
+THREAD_LOCAL EventTracker* perf_event;
 
 EventTracker::EventTracker(PerfConfig *perf) :
-    PerfTracker(perf, perf->output == PERF_FILE ? EVENT_FILE : nullptr) {}
+    PerfTracker(perf, perf->output == PERF_FILE ? EVENT_FILE : nullptr)
+{
+    formatter->register_section("event_stats");
+    formatter->register_field("total");
+    formatter->register_field("qualified");
+    formatter->register_field("non_qualified");
+}
 
 void EventTracker::reset()
 {
-    TextFormatter f;
-    f.write(nullptr, 0);
-    event_counts.NQEvents = 0;
-    event_counts.QEvents  = 0;
-    event_counts.TotalEvents  = 0;
-    if (fh && config->format == PERF_CSV)
-    {
-        fwrite(csv_header.c_str(), csv_header.length(), 1, fh);
-        fflush(fh);
-    }
+    event_counts.non_qualified_events = 0;
+    event_counts.qualified_events  = 0;
+    event_counts.total_events  = 0;
+    
+    formatter->finalize_fields(fh);   
 }
 
 void EventTracker::process(bool)
 {
-    if (config->format == PERF_TEXT)
-    {
-        LogLabel("Snort Setwise Event Stats", fh);
-        LogCount("Total Events", event_counts.TotalEvents, fh);
-        LogStat("Qualified Events", event_counts.QEvents, event_counts.TotalEvents, fh);
-        LogStat("Non-Qualified Events", event_counts.NQEvents, event_counts.TotalEvents, fh);
+    formatter->set_field(0, FR_TOTAL, event_counts.total_events);
+    formatter->set_field(0, FR_QUALIFIED, event_counts.qualified_events);
+    formatter->set_field(0, FR_NON_QUALIFIED,
+        event_counts.non_qualified_events);
 
-    }
-    else if (config->format == PERF_CSV)
-    {
-        fprintf(fh, "%ld,%" PRIu64 ",%" PRIu64 "\n",
-            (long)cur_time, event_counts.QEvents, event_counts.NQEvents);
-        fflush(fh);
-    }
+    formatter->write(fh, cur_time);
+    formatter->clear();
 
-    event_counts.NQEvents    = 0;
-    event_counts.QEvents     = 0;
-    event_counts.TotalEvents = 0;
+    event_counts.non_qualified_events = 0;
+    event_counts.qualified_events = 0;
+    event_counts.total_events = 0;
 }
 
-void EventTracker::UpdateNQEvents()
+void EventTracker::update_non_qualified_events()
 {
     if ((perfmon_config) &&
         (perfmon_config->perf_flags & PERF_EVENT))
     {
-        event_counts.NQEvents++;
-        event_counts.TotalEvents++;
+        event_counts.non_qualified_events++;
+        event_counts.total_events++;
     }
 }
 
-void EventTracker::UpdateQEvents()
+void EventTracker::update_qualified_events()
 {
     if ((perfmon_config) &&
         (perfmon_config->perf_flags & PERF_EVENT))
     {
-        event_counts.QEvents++;
-        event_counts.TotalEvents++;
+        event_counts.qualified_events++;
+        event_counts.total_events++;
     }
 }
 
index 855526cd0cbee2ccda6572ce56a33ec3da36bd40..e6c0cdd40c65d06dcc482e75323c0476e367dad1 100644 (file)
 #ifndef EVENT_TRACKER_H
 #define EVENT_TRACKER_H
 
+#include "perf_formatter.h"
 #include "perf_module.h"
 #include "perf_tracker.h"
 
 /* Raw event counters */
 struct PerfEventCounts
 {
-    uint64_t NQEvents;
-    uint64_t QEvents;
+    uint64_t non_qualified_events;
+    uint64_t qualified_events;
 
-    uint64_t TotalEvents;
+    uint64_t total_events;
 };
 
 class EventTracker : public PerfTracker
@@ -40,8 +41,8 @@ public:
     void reset() override;
     void process(bool) override;
 
-    void UpdateNQEvents();
-    void UpdateQEvents();
+    void update_non_qualified_events();
+    void update_qualified_events();
 
 private:
     PerfEventCounts event_counts;
index 7f162e2a28b9bcb9817dd5b83d6ffd4678661c65..3ca8d38714e41b35b53bfc8b90de59a2c5edca40 100644 (file)
@@ -75,7 +75,9 @@ FlowStateValue* FlowIPTracker::find_stats(const sfip_t* src_addr, const sfip_t*
 
 FlowIPTracker::FlowIPTracker(PerfConfig* perf) : PerfTracker(perf,
         perf->output == PERF_FILE ? FLIP_FILE : nullptr)
-{ }
+{
+
+}
 
 FlowIPTracker::~FlowIPTracker()
 {
@@ -210,11 +212,9 @@ void FlowIPTracker::write_stats()
 
 void FlowIPTracker::process(bool)
 {
-    if (config->format == PERF_CSV)
-        write_stats();
-
-    else if (config->format == PERF_TEXT)
-        display_stats();
+    
+    formatter->write(fh, cur_time);
+    formatter->clear();
 
     if ( !(config->perf_flags & PERF_SUMMARY) )
         reset();
index 2fa772830469a3835bce2a961cc020dc05c5e6b3..6cf99d38c475c64f6db0ca71ebe918139dd378ac 100644 (file)
 
 using namespace std;
 
-SectionRef PerfFormatter::register_section(string)
+void PerfFormatter::register_section(string)
 {
     types.push_back(vector<FormatterType>());
     values.push_back(vector<FormatterValue>());
-
-    return types.size() - 1;
+    last_section++;
 }
 
-FieldRef PerfFormatter::register_field(SectionRef section, string)
+void PerfFormatter::register_field(string)
 {
-    FieldRef ret;
     FormatterValue fv;
     fv.pc = 0;
 
-    values[section].push_back(fv);
-    types[section].push_back(FT_UNSET);
-    
-    ret.section = section;
-    ret.field = values[section].size() - 1;
-
-    return ret;
+    values[last_section].push_back(fv);
+    types[last_section].push_back(FT_UNSET);
 }
 
-void PerfFormatter::set_field(FieldRef ref, PegCount val)
+void PerfFormatter::set_field(unsigned section, unsigned field, PegCount val)
 {
     FormatterValue fv;
 
     fv.pc = val;
-    values[ref.section][ref.field] = fv;
-    types[ref.section][ref.field] = FT_PEG_COUNT;
+    values[section][field] = fv;
+    types[section][field] = FT_PEG_COUNT;
 }
 
-void PerfFormatter::set_field(FieldRef ref, double val)
+void PerfFormatter::set_field(unsigned section, unsigned field, double val)
 {
     FormatterValue fv;
 
     fv.d = val;
-    values[ref.section][ref.field] = fv;
-    types[ref.section][ref.field] = FT_DOUBLE;
+    values[section][field] = fv;
+    types[section][field] = FT_DOUBLE;
+}
+
+void PerfFormatter::set_field(unsigned section, unsigned field, const char* val)
+{
+    FormatterValue fv;
+
+    fv.s = val;
+    values[section][field] = fv;
+    types[section][field] = FT_STRING;
 }
 
 void PerfFormatter::clear()
 {
-    for(unsigned i = 0; i < types.size(); i++)
-        for(unsigned j = 0; j < types[i].size(); j++)
-            types[i][j] = FT_UNSET;
+    for( unsigned i = 0; i < types.size(); i++ )
+    {
+        for( unsigned j = 0; j < types[i].size(); j++ )
+        {
+            if( types[i][j] == FT_STRING )
+                values[i][j].s = nullptr;
+            else
+                types[i][j] = FT_UNSET;
+        }
+    }
 }
index 8d8d780bd860b905d448c97e6ce0cade17896e58..cf22709ac18f8a72f08a8dfafe6eb590cce4887a 100644 (file)
 #include <string>
 #include <vector>
 
-typedef unsigned SectionRef;
-
-struct FieldRef
-{
-    SectionRef section;
-    unsigned field;
-};
-
 union FormatterValue
 {
     PegCount pc;
     double d;
+    const char* s;
 };
 
 enum FormatterType : uint8_t
 {
     FT_UNSET,
     FT_PEG_COUNT,
-    FT_DOUBLE
+    FT_DOUBLE,
+    FT_STRING
 };
 
 class PerfFormatter
@@ -52,17 +46,19 @@ class PerfFormatter
 public:
     PerfFormatter() {};
     virtual ~PerfFormatter() {};
-    virtual SectionRef register_section(std::string);
-    virtual FieldRef register_field(SectionRef, std::string);
+    virtual void register_section(std::string);
+    virtual void register_field(std::string);
     virtual void finalize_fields(FILE*) = 0;
-    virtual void set_field(FieldRef, PegCount);
-    virtual void set_field(FieldRef, double);
+    virtual void set_field(unsigned, unsigned, PegCount);
+    virtual void set_field(unsigned, unsigned, double);
+    virtual void set_field(unsigned, unsigned, const char*);
     virtual void write(FILE*, time_t) = 0;
     virtual void clear();
 
 protected:
     std::vector<std::vector<FormatterType>> types;
     std::vector<std::vector<FormatterValue>> values;
+    unsigned last_section = -1;
 };
 #endif
 
index 39fe3052346bdf5049aa3d2546d1d7f3091ad14b..90b6948fd92118ccd06fd90b7470fdfd15cc78e1 100644 (file)
 #include <sys/stat.h>
 
 #include "perf_tracker.h"
+
+#include "csv_formatter.h"
 #include "perf_module.h"
+#include "text_formatter.h"
 
 #include "log/messages.h"
 #include "main/snort_config.h"
@@ -51,10 +54,17 @@ PerfTracker::PerfTracker(PerfConfig* config, const char* tracker_fname)
 
     if (tracker_fname)
         get_instance_file(fname, tracker_fname);
+
+    if (config->format == PERF_CSV)
+        formatter = new CSVFormatter();
+
+    else if (config->format == PERF_TEXT)
+        formatter = new TextFormatter();
 }
 
 PerfTracker::~PerfTracker()
 {
+    delete formatter;
     close();
 }
 
index 641d01e353a18624e71020a5018a476396b6ab18..6cdfabc74ff34f8878a74fd89508292ce2ccbc68 100644 (file)
 #ifndef PERF_TRACKER_H
 #define PERF_TRACKER_H
 
-#include <cstdio>
+#include "perf_formatter.h"
 #include "perf_monitor.h"
 
+#include <cstdio>
+
+
 class PerfTracker
 {
 public:
@@ -47,6 +50,7 @@ protected:
     FILE* fh = nullptr;
     std::string fname;
     time_t cur_time;
+    PerfFormatter* formatter;
 
     PerfTracker(PerfConfig*, const char* tracker_fname);
 };
index 4cc2e725012d3dc73d0a7db94c324382049a5bcb..1740aecc1897f47e288b9b967648d5c94213590c 100644 (file)
 
 using namespace std;
 
-SectionRef TextFormatter::register_section(string name)
+void TextFormatter::register_section(string name)
 {
     section_names.push_back(name);
     field_names.push_back(vector<string>());
-
-    return PerfFormatter::register_section(name);
+    PerfFormatter::register_section(name);
 }
 
-FieldRef TextFormatter::register_field(SectionRef section, string name)
+void TextFormatter::register_field(string name)
 {
-    field_names[section].push_back(name);
-    return PerfFormatter::register_field(section, name);
+    field_names[last_section].push_back(name);
+    PerfFormatter::register_field(name);
 }
 
 void TextFormatter::write(FILE* fh, time_t)
@@ -71,6 +70,17 @@ void TextFormatter::write(FILE* fh, time_t)
                     }
                     LogCount(field_names[i][j].c_str(), values[i][j].pc, fh);
                     break;
+                case FT_STRING:
+                    if( values[i][j].s )
+                    {
+                        if( !head )
+                        {
+                            LogLabel(section_names[i].c_str(), fh);
+                            head = true;
+                        }
+                        LogValue(field_names[i][j].c_str(), values[i][j].s, fh);
+                    }
+                    break;
                 case FT_UNSET:
                     break; 
             }
@@ -89,26 +99,26 @@ TEST_CASE("text output", "[TextFormatter]")
         "                      one: 1\n"
         "--------------------------------------------------\n"
         "other\n"
-        "                     four: 34.5678\n";
-
+        "                     four: 34.5678\n"
+        "                     five: hellothere\n";
         
-    FieldRef fr[4];
-    
     FILE* fh = tmpfile();
     TextFormatter f;
 
-    SectionRef s = f.register_section("name");
-    fr[0] = f.register_field(s, "one");
-    fr[1] = f.register_field(s, "two");
-    s = f.register_section("other");
-    fr[2] = f.register_field(s, "three");
-    fr[3] = f.register_field(s, "four");
+    f.register_section("name");
+    f.register_field("one");
+    f.register_field("two");
+    f.register_section("other");
+    f.register_field("three");
+    f.register_field("four");
+    f.register_field("five");
     f.finalize_fields(fh);
 
-    f.set_field(fr[0], (PegCount)1);
-    f.set_field(fr[1], (PegCount)0);
-    f.set_field(fr[2], (PegCount)0);
-    f.set_field(fr[3], 34.5678);
+    f.set_field(0, 0, (PegCount)1);
+    f.set_field(0, 1, (PegCount)0);
+    f.set_field(1, 0, (PegCount)0);
+    f.set_field(1, 1, 34.5678);
+    f.set_field(1, 2, "hellothere");
     f.write(fh, (time_t)1234567890);
 
     f.clear();
index e379812d65c400688f98c91bc55e9c946b443b58..dbe55d4e111642fb43c72a756e66e793f5043327 100644 (file)
@@ -27,8 +27,8 @@ class TextFormatter : public PerfFormatter
 {
 public:
     TextFormatter() : PerfFormatter() {};
-    SectionRef register_section(std::string) override;
-    FieldRef register_field(SectionRef, std::string) override;
+    void register_section(std::string) override;
+    void register_field(std::string) override;
     void finalize_fields(FILE*) override {};
     void write(FILE*, time_t) override;
 
index 4c7eff566d500de0f42d739943c739b7be11df47..5d26fdc1e73731c88d291d7d1854547827602679 100644 (file)
@@ -93,9 +93,9 @@ void LogLabel(const char* s, FILE* fh)
     }
 }
 
-void LogValue(const char* s, const char* v)
+void LogValue(const char* s, const char* v, FILE* fh)
 {
-    LogMessage("%25.25s: %s\n", s, v);
+    LogMessage(fh, "%25.25s: %s\n", s, v);
 }
 
 void LogCount(const char* s, uint64_t c, FILE* fh)
index 231428958cf7a4575c18ba9dcc1611d92e293ba1..bd374184dde1d8250e96f5a7712ee50823d2d55a 100644 (file)
@@ -115,7 +115,7 @@ extern const PegInfo proc_names[];
 SO_PUBLIC PegCount get_packet_number();
 
 SO_PUBLIC void LogLabel(const char*, FILE* = stdout);
-SO_PUBLIC void LogValue(const char*, const char*);
+SO_PUBLIC void LogValue(const char*, const char*, FILE* = stdout);
 SO_PUBLIC void LogCount(const char*, uint64_t, FILE* = stdout);
 
 SO_PUBLIC void LogStat(const char*, uint64_t n, uint64_t tot, FILE* = stdout);