Skip to content

Commit

Permalink
Fixed not working logging mechanism on Windows (#123)
Browse files Browse the repository at this point in the history
* Fixed linker errors on Windows when turned on logging. Fixed crashing time formatting on Windows.
  • Loading branch information
ethouris authored and rndi committed Oct 10, 2017
1 parent 4b897ba commit a097e67
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 136 deletions.
4 changes: 2 additions & 2 deletions common/srt_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,10 @@ inline std::string SysStrError(int errnum)

inline struct tm LocalTime(time_t tt)
{
struct tm tm;
struct tm tm = {};
#ifdef WIN32
errno_t rr = localtime_s(&tm, &tt);
if (rr)
if (rr == 0)
return tm;
#else
tm = *localtime_r(&tt, &tm);
Expand Down
150 changes: 150 additions & 0 deletions srtcore/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,13 @@ modified by
#include <string>
#include <sstream>
#include <cmath>
#include <iostream>
#include <iomanip>
#include "srt.h"
#include "md5.h"
#include "common.h"
#include "logging.h"
#include "threadname.h"

#include <srt_compat.h> // SysStrError

Expand Down Expand Up @@ -816,3 +821,148 @@ std::string TransmissionEventStr(ETransmissionEvent ev)
return "UNKNOWN";
return vals[ev];
}

std::string logging::FormatTime(uint64_t time)
{
using namespace std;

time_t sec = time/1000000;
time_t usec = time%1000000;

time_t tt = sec;
struct tm tm = LocalTime(tt);

char tmp_buf[512];
#ifdef WIN32
strftime(tmp_buf, 512, "%Y-%m-%d.", &tm);
#else
strftime(tmp_buf, 512, "%T.", &tm);
#endif
ostringstream out;
out << tmp_buf << setfill('0') << setw(6) << usec;
return out.str();
}
// Some logging imps
#if ENABLE_LOGGING

logging::LogDispatcher::Proxy::Proxy(LogDispatcher& guy) : that(guy), that_enabled(that.CheckEnabled())
{
i_file = "";
i_line = 0;
flags = that.flags;
if (that_enabled)
{
// Create logger prefix
that.CreateLogLinePrefix(os);
}
}

logging::LogDispatcher::Proxy logging::LogDispatcher::operator()()
{
return Proxy(*this);
}

void logging::LogDispatcher::CreateLogLinePrefix(std::ostringstream& serr)
{
using namespace std;

char tmp_buf[512];
if ( (flags & SRT_LOGF_DISABLE_TIME) == 0 )
{
// Not necessary if sending through the queue.
timeval tv;
gettimeofday(&tv, 0);
time_t t = tv.tv_sec;
struct tm tm = LocalTime(t);

// Looxlike The %T is nonstandard and Windows
// uses %X here. And "excepts" when using %T.
#ifdef WIN32
strftime(tmp_buf, 512, "%X.", &tm);
#else
strftime(tmp_buf, 512, "%T.", &tm);
#endif

serr << tmp_buf << setw(6) << setfill('0') << tv.tv_usec;
}

// Note: ThreadName::get needs a buffer of size min. ThreadName::BUFSIZE
string out_prefix;
if ( (flags & SRT_LOGF_DISABLE_SEVERITY) == 0 )
{
out_prefix = prefix;
}

if ( (flags & SRT_LOGF_DISABLE_THREADNAME) == 0 && ThreadName::get(tmp_buf) )
{
serr << "/" << tmp_buf << out_prefix << ": ";
}
else
{
serr << out_prefix << ": ";
}
}

std::string logging::LogDispatcher::Proxy::ExtractName(std::string pretty_function)
{
if ( pretty_function == "" )
return "";
size_t pos = pretty_function.find('(');
if ( pos == std::string::npos )
return pretty_function; // return unchanged.

pretty_function = pretty_function.substr(0, pos);

// There are also template instantiations where the instantiating
// parameters are encrypted inside. Therefore, search for the first
// open < and if found, search for symmetric >.

int depth = 1;
pos = pretty_function.find('<');
if ( pos != std::string::npos )
{
size_t end = pos+1;
for(;;)
{
++pos;
if ( pos == pretty_function.size() )
{
--pos;
break;
}
if ( pretty_function[pos] == '<' )
{
++depth;
continue;
}

if ( pretty_function[pos] == '>' )
{
--depth;
if ( depth <= 0 )
break;
continue;
}
}

std::string afterpart = pretty_function.substr(pos+1);
pretty_function = pretty_function.substr(0, end) + ">" + afterpart;
}

// Now see how many :: can be found in the name.
// If this occurs more than once, take the last two.
pos = pretty_function.rfind("::");

if ( pos == std::string::npos || pos < 2 )
return pretty_function; // return whatever this is. No scope name.

// Find the next occurrence of :: - if found, copy up to it. If not,
// return whatever is found.
pos -= 2;
pos = pretty_function.rfind("::", pos);
if ( pos == std::string::npos )
return pretty_function; // nothing to cut

return pretty_function.substr(pos+2);
}
#endif
140 changes: 6 additions & 134 deletions srtcore/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ written by
#include <mutex>
#endif

#include "srt.h"
#include "utilities.h"
#include "threadname.h"
#include "logging_api.h"
Expand Down Expand Up @@ -95,7 +96,7 @@ struct LogConfig
};


struct LogDispatcher
struct SRT_API LogDispatcher
{
int fa;
LogLevel::type level;
Expand Down Expand Up @@ -245,79 +246,10 @@ struct LogDispatcher::Proxy
// to use this to translate __PRETTY_FUNCTION__ to
// something short, or just let's leave __FUNCTION__
// or better __func__.
std::string ExtractName(std::string pretty_function)
{
if ( pretty_function == "" )
return "";
size_t pos = pretty_function.find('(');
if ( pos == std::string::npos )
return pretty_function; // return unchanged.

pretty_function = pretty_function.substr(0, pos);

// There are also template instantiations where the instantiating
// parameters are encrypted inside. Therefore, search for the first
// open < and if found, search for symmetric >.

int depth = 1;
pos = pretty_function.find('<');
if ( pos != std::string::npos )
{
size_t end = pos+1;
for(;;)
{
++pos;
if ( pos == pretty_function.size() )
{
--pos;
break;
}
if ( pretty_function[pos] == '<' )
{
++depth;
continue;
}

if ( pretty_function[pos] == '>' )
{
--depth;
if ( depth <= 0 )
break;
continue;
}
}

std::string afterpart = pretty_function.substr(pos+1);
pretty_function = pretty_function.substr(0, end) + ">" + afterpart;
}

// Now see how many :: can be found in the name.
// If this occurs more than once, take the last two.
pos = pretty_function.rfind("::");

if ( pos == std::string::npos || pos < 2 )
return pretty_function; // return whatever this is. No scope name.

// Find the next occurrence of :: - if found, copy up to it. If not,
// return whatever is found.
pos -= 2;
pos = pretty_function.rfind("::", pos);
if ( pos == std::string::npos )
return pretty_function; // nothing to cut

return pretty_function.substr(pos+2);
}

Proxy(LogDispatcher& guy): that(guy), that_enabled(that.CheckEnabled())
{
flags = that.flags;
if ( that_enabled )
{
// Create logger prefix
that.CreateLogLinePrefix(os);
}
}
std::string ExtractName(std::string pretty_function);

Proxy(LogDispatcher& guy);

// Copy constructor is needed due to noncopyable ostringstream.
// This is used only in creation of the default object, so just
// use the default values, just copy the location cache.
Expand Down Expand Up @@ -379,13 +311,6 @@ struct LogDispatcher::Proxy
}
};

inline LogDispatcher::Proxy LogDispatcher::operator()()
{
LogDispatcher& that = *this;

Proxy proxy = that;
return proxy;
}

#endif

Expand Down Expand Up @@ -434,60 +359,7 @@ inline bool LogDispatcher::CheckEnabled()
return enabled;
}

inline std::string FormatTime(uint64_t time)
{
using namespace std;

time_t sec = time/1000000;
time_t usec = time%1000000;

time_t tt = sec;
struct tm tm = LocalTime(tt);

char tmp_buf[512];
#ifdef WIN32
strftime(tmp_buf, 512, "%Y-%m-%d.", &tm);
#else
strftime(tmp_buf, 512, "%T.", &tm);
#endif
ostringstream out;
out << tmp_buf << setfill('0') << setw(6) << usec;
return out.str();
}

inline void LogDispatcher::CreateLogLinePrefix(std::ostringstream& serr)
{
using namespace std;

char tmp_buf[512];
if ( (flags & SRT_LOGF_DISABLE_TIME) == 0 )
{
// Not necessary if sending through the queue.
timeval tv;
gettimeofday(&tv, 0);
time_t t = tv.tv_sec;
struct tm tm = LocalTime(t);
strftime(tmp_buf, 512, "%T.", &tm);

serr << tmp_buf << setw(6) << setfill('0') << tv.tv_usec;
}

// Note: ThreadName::get needs a buffer of size min. ThreadName::BUFSIZE
string out_prefix;
if ( (flags & SRT_LOGF_DISABLE_SEVERITY) == 0 )
{
out_prefix = prefix;
}

if ( (flags & SRT_LOGF_DISABLE_THREADNAME) == 0 && ThreadName::get(tmp_buf) )
{
serr << "/" << tmp_buf << out_prefix << ": ";
}
else
{
serr << out_prefix << ": ";
}
}
SRT_API std::string FormatTime(uint64_t time);

#if HAVE_CXX11

Expand Down

0 comments on commit a097e67

Please sign in to comment.