Skip to content

Commit

Permalink
[apps] Added timepoint in json stats format (#1780)
Browse files Browse the repository at this point in the history
  • Loading branch information
ethouris authored Feb 2, 2021
1 parent a6a7a20 commit 524565f
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 29 deletions.
86 changes: 57 additions & 29 deletions apps/apputil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,11 @@ string OptionHelpItem(const OptionName& o)

// Stats module

// Note: std::put_time is supported only in GCC 5 and higher
#if !defined(__GNUC__) || defined(__clang__) || (__GNUC__ >= 5)
#define HAS_PUT_TIME
#endif

template <class TYPE>
inline SrtStatData* make_stat(SrtStatCat cat, const string& name, const string& longname,
TYPE CBytePerfMon::*field)
Expand Down Expand Up @@ -420,16 +425,55 @@ string srt_json_cat_names [] = {
"recv"
};

#ifdef HAS_PUT_TIME
// Follows ISO 8601
std::string SrtStatsWriter::print_timestamp()
{
using namespace std;
using namespace std::chrono;

const auto systime_now = system_clock::now();
const time_t time_now = system_clock::to_time_t(systime_now);

std::ostringstream output;

// SysLocalTime returns zeroed tm_now on failure, which is ok for put_time.
const tm tm_now = SysLocalTime(time_now);
output << std::put_time(&tm_now, "%FT%T.") << std::setfill('0') << std::setw(6);
const auto since_epoch = systime_now.time_since_epoch();
const seconds s = duration_cast<seconds>(since_epoch);
output << duration_cast<microseconds>(since_epoch - s).count();
output << std::put_time(&tm_now, "%z");
return output.str();
}
#else

// This is a stub. The error when not defining it would be too
// misleading, so this stub will work if someone mistakenly adds
// the item to the output format without checking that HAS_PUT_TIME.
string SrtStatsWriter::print_timestamp()
{ return "<NOT IMPLEMENTED>"; }
#endif // HAS_PUT_TIME


class SrtStatsJson : public SrtStatsWriter
{
static string keyspec(const string& name)
static string quotekey(const string& name)
{
if (name == "")
return "";

return R"(")" + name + R"(":)";
}

static string quote(const string& name)
{
if (name == "")
return "";

return R"(")" + name + R"(")";
}

public:
string WriteStats(int sid, const CBytePerfMon& mon) override
{
Expand All @@ -446,10 +490,17 @@ class SrtStatsJson : public SrtStatsWriter
SrtStatCat cat = SSC_GEN;

// Do general manually
output << keyspec(srt_json_cat_names[cat]) << "{" << pretty_cr;
output << quotekey(srt_json_cat_names[cat]) << "{" << pretty_cr;

// SID is displayed manually
output << pretty_tab << keyspec("sid") << sid;
output << pretty_tab << quotekey("sid") << sid;

// Extra Timepoint is also displayed manually
#ifdef HAS_PUT_TIME
// NOTE: still assumed SSC_GEN category
output << "," << pretty_cr << pretty_tab
<< quotekey("timepoint") << quote(print_timestamp());
#endif

// Now continue with fields as specified in the table
for (auto& i: g_SrtStatsTable)
Expand All @@ -476,13 +527,13 @@ class SrtStatsJson : public SrtStatsWriter
if (cat != SSC_GEN)
output << pretty_tab;

output << keyspec(srt_json_cat_names[cat]) << "{" << pretty_cr << pretty_tab;
output << quotekey(srt_json_cat_names[cat]) << "{" << pretty_cr << pretty_tab;
if (cat != SSC_GEN)
output << pretty_tab;
}

// Print the current field
output << keyspec(i->name);
output << quotekey(i->name);
output << qt;
i->PrintValue(output, mon);
output << qt;
Expand Down Expand Up @@ -518,10 +569,6 @@ class SrtStatsCsv : public SrtStatsWriter

string WriteStats(int sid, const CBytePerfMon& mon) override
{
// Note: std::put_time is supported only in GCC 5 and higher
#if !defined(__GNUC__) || defined(__clang__) || (__GNUC__ >= 5)
#define HAS_PUT_TIME
#endif
std::ostringstream output;

// Header
Expand All @@ -547,25 +594,7 @@ class SrtStatsCsv : public SrtStatsWriter

#ifdef HAS_PUT_TIME
// HDR: Timepoint
// Follows ISO 8601
auto print_timestamp = [&output]() {
using namespace std;
using namespace std::chrono;

const auto systime_now = system_clock::now();
const time_t time_now = system_clock::to_time_t(systime_now);

// SysLocalTime returns zeroed tm_now on failure, which is ok for put_time.
const tm tm_now = SysLocalTime(time_now);
output << std::put_time(&tm_now, "%FT%T.") << std::setfill('0') << std::setw(6);
const auto since_epoch = systime_now.time_since_epoch();
const seconds s = duration_cast<seconds>(since_epoch);
output << duration_cast<microseconds>(since_epoch - s).count();
output << std::put_time(&tm_now, "%z");
output << ",";
};

print_timestamp();
output << print_timestamp() << ",";
#endif // HAS_PUT_TIME

// HDR: Time,SocketID
Expand Down Expand Up @@ -657,4 +686,3 @@ SrtStatsPrintFormat ParsePrintFormat(string pf, string& w_extras)
return SRTSTATS_PROFMAT_INVALID;
}


3 changes: 3 additions & 0 deletions apps/apputil.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,9 @@ class SrtStatsWriter
virtual std::string WriteBandwidth(double mbpsBandwidth) = 0;
virtual ~SrtStatsWriter() { };

// Only if HAS_PUT_TIME. Specified in the imp file.
std::string print_timestamp();

void Option(const std::string& key, const std::string& val)
{
options[key] = val;
Expand Down

0 comments on commit 524565f

Please sign in to comment.