Merge branch 'log-ms'

Use milliseconds in wxLog timestamps.

See https://github.com/wxWidgets/wxWidgets/pull/2164
This commit is contained in:
Vadim Zeitlin
2021-01-16 16:00:57 +01:00
7 changed files with 101 additions and 13 deletions

View File

@@ -62,6 +62,7 @@ class WXDLLIMPEXP_FWD_BASE wxObject;
#include "wx/dynarray.h" #include "wx/dynarray.h"
#include "wx/hashmap.h" #include "wx/hashmap.h"
#include "wx/msgout.h" #include "wx/msgout.h"
#include "wx/time.h"
#if wxUSE_THREADS #if wxUSE_THREADS
#include "wx/thread.h" #include "wx/thread.h"
@@ -160,9 +161,11 @@ public:
// don't initialize the timestamp yet, we might not need it at all if // don't initialize the timestamp yet, we might not need it at all if
// the message doesn't end up being logged and otherwise we'll fill it // the message doesn't end up being logged and otherwise we'll fill it
// just before logging it, which won't change it by much and definitely // just before logging it, which won't change it by much
// less than a second resolution of the timestamp timestampMS = 0;
#if WXWIN_COMPATIBILITY_3_0
timestamp = 0; timestamp = 0;
#endif // WXWIN_COMPATIBILITY_3_0
#if wxUSE_THREADS #if wxUSE_THREADS
threadId = wxThread::GetCurrentId(); threadId = wxThread::GetCurrentId();
@@ -208,8 +211,13 @@ public:
// not set (i.e. wxLOG_COMPONENT not defined). It must be in ASCII. // not set (i.e. wxLOG_COMPONENT not defined). It must be in ASCII.
const char *component; const char *component;
// time of record generation // time of record generation in milliseconds since Epoch
wxLongLong_t timestampMS;
#if WXWIN_COMPATIBILITY_3_0
// preserved for compatibility only, use timestampMS instead now
time_t timestamp; time_t timestamp;
#endif // WXWIN_COMPATIBILITY_3_0
#if wxUSE_THREADS #if wxUSE_THREADS
// id of the thread which logged this record // id of the thread which logged this record
@@ -334,7 +342,12 @@ public:
protected: protected:
// Override this method to change just the time stamp formatting. It is // Override this method to change just the time stamp formatting. It is
// called by default Format() implementation. // called by default Format() implementation.
virtual wxString FormatTimeMS(wxLongLong_t msec) const;
#if WXWIN_COMPATIBILITY_3_0
// Old function which only worked at second resolution.
virtual wxString FormatTime(time_t t) const; virtual wxString FormatTime(time_t t) const;
#endif // WXWIN_COMPATIBILITY_3_0
}; };
@@ -1166,7 +1179,11 @@ private:
// As explained in wxLogRecordInfo ctor, we don't initialize its // As explained in wxLogRecordInfo ctor, we don't initialize its
// timestamp to avoid calling time() unnecessary, but now that we are // timestamp to avoid calling time() unnecessary, but now that we are
// about to log the message, we do need to do it. // about to log the message, we do need to do it.
m_info.timestamp = time(NULL); m_info.timestampMS = wxGetUTCTimeMillis().GetValue();
#if WXWIN_COMPATIBILITY_3_0
m_info.timestamp = m_info.timestampMS / 1000;
#endif // WXWIN_COMPATIBILITY_3_0
wxLog::OnLog(level, wxString::FormatV(format, argptr), m_info); wxLog::OnLog(level, wxString::FormatV(format, argptr), m_info);
} }

View File

@@ -54,7 +54,18 @@ public:
*/ */
const char *func; const char *func;
/// Time when the log message was generated. /**
Time in milliseconds since Epoch when the log message was generated.
@since 3.1.5
*/
wxLongLong_t timestampMS;
/**
Time when the log message was generated.
@deprecated Please use timestampMS instead.
*/
time_t timestamp; time_t timestamp;
/** /**
@@ -148,9 +159,30 @@ public:
const wxLogRecordInfo& info) const; const wxLogRecordInfo& info) const;
protected: protected:
/**
This function formats the time stamp part of the log message including
milliseconds.
Override this function if you need to customize just the time stamp
formatting in the log messages.
@param msec
Time to format as the number of milliseconds since
1970-01-01T00:00:00.
@return
The formatted time string, may be empty.
@since 3.1.5
*/
virtual wxString FormatTimeMS(wxLongLong_t msec) const;
/** /**
This function formats the time stamp part of the log message. This function formats the time stamp part of the log message.
@deprecated This function only exists for compatibility, please
override FormatTimeMS() in the new code.
Override this function if you need to customize just the time stamp. Override this function if you need to customize just the time stamp.
@param time @param time

View File

@@ -471,7 +471,7 @@ MyFrame::DoLogRecord(wxLogLevel level,
DoLogLine DoLogLine
( (
m_txtctrl, m_txtctrl,
wxDateTime(info.timestamp).FormatISOTime(), wxDateTime(wxLongLong(info.timestampMS)).FormatISOTime(),
info.threadId == wxThread::GetMainId() info.threadId == wxThread::GetMainId()
? wxString("main") ? wxString("main")
: wxString::Format("%lx", info.threadId), : wxString::Format("%lx", info.threadId),

View File

@@ -49,8 +49,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <time.h>
#if defined(__WINDOWS__) #if defined(__WINDOWS__)
#include "wx/msw/private.h" // includes windows.h #include "wx/msw/private.h" // includes windows.h
#endif #endif
@@ -196,6 +194,21 @@ void wxSafeShowMessage(const wxString& title, const wxString& text)
// wxLogFormatter class implementation // wxLogFormatter class implementation
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#if WXWIN_COMPATIBILITY_3_0
// Special string used to check if FormatTime() is overridden: hopefully
// different from anything that could be reasonably returned by the overridden
// version without being as long as a GUID.
static const char* DEFAULT_FORMAT_TIME = "??";
wxString
wxLogFormatter::FormatTime(time_t WXUNUSED(t)) const
{
return wxString::FromAscii(DEFAULT_FORMAT_TIME);
}
#endif // WXWIN_COMPATIBILITY_3_0
wxString wxString
wxLogFormatter::Format(wxLogLevel level, wxLogFormatter::Format(wxLogLevel level,
const wxString& msg, const wxString& msg,
@@ -208,7 +221,15 @@ wxLogFormatter::Format(wxLogLevel level,
#ifdef __WINDOWS__ #ifdef __WINDOWS__
if ( level != wxLOG_Debug && level != wxLOG_Trace ) if ( level != wxLOG_Debug && level != wxLOG_Trace )
#endif // __WINDOWS__ #endif // __WINDOWS__
{
#if WXWIN_COMPATIBILITY_3_0
// Another backwards compatibility hack: check if FormatTime() was
// overridden in the user code.
prefix = FormatTime(info.timestamp); prefix = FormatTime(info.timestamp);
if ( prefix == DEFAULT_FORMAT_TIME )
#endif // WXWIN_COMPATIBILITY_3_0
prefix = FormatTimeMS(info.timestampMS);
}
switch ( level ) switch ( level )
{ {
@@ -239,10 +260,14 @@ wxLogFormatter::Format(wxLogLevel level,
} }
wxString wxString
wxLogFormatter::FormatTime(time_t t) const wxLogFormatter::FormatTimeMS(wxLongLong_t msec) const
{ {
wxString str; wxString str;
wxLog::TimeStamp(&str, t);
#if wxUSE_DATETIME
str = wxDateTime(wxLongLong(msec)).Format(wxLog::GetTimestamp());
str += wxS(": ");
#endif // wxUSE_DATETIME
return str; return str;
} }
@@ -323,7 +348,7 @@ void
wxLog::OnLog(wxLogLevel level, const wxString& msg, time_t t) wxLog::OnLog(wxLogLevel level, const wxString& msg, time_t t)
{ {
wxLogRecordInfo info; wxLogRecordInfo info;
info.timestamp = t; info.timestampMS = 1000*t;
#if wxUSE_THREADS #if wxUSE_THREADS
info.threadId = wxThread::GetCurrentId(); info.threadId = wxThread::GetCurrentId();
#endif // wxUSE_THREADS #endif // wxUSE_THREADS

View File

@@ -342,7 +342,7 @@ void wxLogGui::DoLogRecord(wxLogLevel level,
{ {
m_aMessages.Add(msg); m_aMessages.Add(msg);
m_aSeverity.Add(wxLOG_Message); m_aSeverity.Add(wxLOG_Message);
m_aTimes.Add((long)info.timestamp); m_aTimes.Add((long)(info.timestampMS / 1000));
m_bHasMessages = true; m_bHasMessages = true;
} }
break; break;
@@ -395,7 +395,7 @@ void wxLogGui::DoLogRecord(wxLogLevel level,
m_aMessages.Add(msg); m_aMessages.Add(msg);
m_aSeverity.Add((int)level); m_aSeverity.Add((int)level);
m_aTimes.Add((long)info.timestamp); m_aTimes.Add((long)(info.timestampMS / 1000));
m_bHasMessages = true; m_bHasMessages = true;
break; break;

View File

@@ -454,4 +454,16 @@ void macroCompilabilityTest()
wxLogDebug("hello debug %d", 42); wxLogDebug("hello debug %d", 42);
} }
// This allows to check wxLogTrace() interactively by running this test with
// WXTRACE=logtest.
TEST_CASE("wxLog::Trace", "[log][.]")
{
// Running this test without setting WXTRACE is useless.
REQUIRE( wxGetEnv("WXTRACE", NULL) );
wxLogTrace("logtest", "Starting test");
wxMilliSleep(250);
wxLogTrace("logtest", "Ending test 1/4s later");
}
#endif // wxUSE_LOG #endif // wxUSE_LOG

View File

@@ -618,6 +618,8 @@ int TestApp::RunTests()
// running the tests. // running the tests.
if ( !wxGetEnv(wxASCII_STR("WXTRACE"), NULL) ) if ( !wxGetEnv(wxASCII_STR("WXTRACE"), NULL) )
wxLog::EnableLogging(false); wxLog::EnableLogging(false);
else
wxLog::SetTimestamp("%Y-%m-%d %H:%M:%S.%l");
#endif #endif
// Cast is needed under MSW where Catch also provides an overload taking // Cast is needed under MSW where Catch also provides an overload taking