]> git.saurik.com Git - wxWidgets.git/commitdiff
Add component-level filtering to wxLog.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 12 Jul 2009 14:56:23 +0000 (14:56 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 12 Jul 2009 14:56:23 +0000 (14:56 +0000)
Each log message is now associated with its component, "wx" by default for
messages generated by wxWidgets and wxLOG_COMPONENT in general (which is empty
by default). Each component may have its own log level and they are
hierarchical allowing fine configuration of what exactly is logged.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61414 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/doxygen/overviews/log.h
include/wx/log.h
interface/wx/log.h
src/common/log.cpp
tests/log/logtest.cpp

index d8cb23e9f77148ed803e80456dd6a41d46d0ee7f..4042ec2955104dd440f5bdb10a47279a735c84e5 100644 (file)
@@ -120,10 +120,58 @@ classes are. Some of advantages in using wxWidgets log functions are:
     about data file writing error.
 
 
+@section overview_log_enable Log Messages Selection
+
+By default, most log messages are enabled. In particular, this means that
+errors logged by wxWidgets code itself (e.g. when it fails to perform some
+operation, for instance wxFile::Open() logs an error when it fails to open a
+file) will be processed and shown to the user. To disable the logging entirely
+you can use wxLog::EnableLogging() method or, more usually, wxLogNull class
+which temporarily disables logging and restores it back to the original setting
+when it is destroyed.
+
+To limit logging to important messages only, you may use wxLog::SetLogLevel()
+with e.g. wxLOG_Warning value -- this will completely disable all logging
+messages with the severity less than warnings, so wxLogMessage() output won't
+be shown to the user any more.
+
+Moreover, the log level can be set separately for different log components.
+Before showing how this can be useful, let us explain what log components are:
+they are simply arbitrary strings identifying the component, or module, which
+generated the message. They are hierarchical in the sense that "foo/bar/baz"
+component is supposed to be a child of "foo". And all components are children
+of the unnamed root component.
+
+By default, all messages logged by wxWidgets originate from "wx" component or
+one of its subcomponents such as "wx/net/ftp", while the messages logged by
+your own code are assigned empty log component. To change this, you need to
+define @c wxLOG_COMPONENT to a string uniquely identifying each component, e.g.
+you could give it the value "MyProgram" by default and re-define it as
+"MyProgram/DB" in the module working with the database and "MyProgram/DB/Trans"
+in its part managing the transactions. Then you could use
+wxLog::SetComponentLevel() in the following ways:
+    @code
+        // disable all database error messages, everybody knows databases never
+        // fail anyhow
+        wxLog::SetComponentLevel("MyProgram/DB", wxLOG_FatalError);
+
+        // but enable tracing for the transactions as somehow our changes don't
+        // get committed sometimes
+        wxLog::SetComponentLevel("MyProgram/DB/Trans", wxLOG_Trace);
+
+        // also enable tracing messages from wxWidgets dynamic module loading
+        // mechanism
+        wxLog::SetComponentLevel("wx/base/module", wxLOG_Trace);
+    @endcode
+Notice that the log level set explicitly for the transactions code overrides
+the log level of the parent component but that all other database code
+subcomponents inherit its setting by default and so won't generate any log
+messages at all.
+
 @section overview_log_targets Log Targets
 
 After having enumerated all the functions which are normally used to log the
-messages, and why would you want to use them we now describe how all this
+messages, and why would you want to use them, we now describe how all this
 works.
 
 wxWidgets has the notion of a <em>log target</em>: it is just a class deriving
index 34168befc1ef5d9169511db2b2744584577018fd..73a8e6055911165b26983538c76465ab3b7d09b7 100644 (file)
@@ -78,6 +78,19 @@ typedef unsigned long wxLogLevel;
     #endif
 #endif // wxUSE_LOG_TRACE
 
+// wxLOG_COMPONENT identifies the component which generated the log record and
+// can be #define'd to a user-defined value when compiling the user code to use
+// component-based filtering (see wxLog::SetComponentLevel())
+#ifndef wxLOG_COMPONENT
+    // this is a variable and not a macro in order to allow the user code to
+    // just #define wxLOG_COMPONENT without #undef'ining it first
+    extern WXDLLIMPEXP_DATA_BASE(const char *) wxLOG_COMPONENT;
+
+    #ifdef WXBUILDING
+        #define wxLOG_COMPONENT "wx"
+    #endif
+#endif
+
 // ----------------------------------------------------------------------------
 // forward declarations
 // ----------------------------------------------------------------------------
@@ -133,18 +146,20 @@ public:
     // default ctor creates an uninitialized object
     wxLogRecordInfo()
     {
-        memset(this, 0, sizeof(this));
+        memset(this, 0, sizeof(*this));
     }
 
     // normal ctor, used by wxLogger specifies the location of the log
     // statement; its time stamp and thread id are set up here
     wxLogRecordInfo(const char *filename_,
                     int line_,
-                    const char *func_)
+                    const char *func_,
+                    const char *component_)
     {
         filename = filename_;
         func = func_;
         line = line_;
+        component = component_;
 
         timestamp = time(NULL);
 
@@ -188,6 +203,10 @@ public:
     // if the compiler doesn't support __FUNCTION__)
     const char *func;
 
+    // the name of the component which generated this message, may be NULL if
+    // not set (i.e. wxLOG_COMPONENT not defined)
+    const char *component;
+
     // time of record generation
     time_t timestamp;
 
@@ -250,7 +269,7 @@ public:
 private:
     void Copy(const wxLogRecordInfo& other)
     {
-        memcpy(this, &other, sizeof(wxLogRecordInfo));
+        memcpy(this, &other, sizeof(*this));
         if ( other.m_data )
            m_data = new ExtraData(*other.m_data);
     }
@@ -285,20 +304,61 @@ public:
     virtual ~wxLog();
 
 
-    // these functions allow to completely disable all log messages
+    // log messages selection
+    // ----------------------
+
+    // these functions allow to completely disable all log messages or disable
+    // log messages at level less important than specified
 
     // is logging enabled at all now?
     static bool IsEnabled() { return ms_doLog; }
 
-    // is logging at this level enabled?
-    static bool IsLevelEnabled(wxLogLevel level)
-        { return IsEnabled() && level <= ms_logLevel; }
-
     // change the flag state, return the previous one
     static bool EnableLogging(bool doIt = true)
         { bool doLogOld = ms_doLog; ms_doLog = doIt; return doLogOld; }
 
+
+    // return the current global log level
+    static wxLogLevel GetLogLevel() { return ms_logLevel; }
+
+    // set global log level: messages with level > logLevel will not be logged
+    static void SetLogLevel(wxLogLevel logLevel) { ms_logLevel = logLevel; }
+
+    // set the log level for the given component
+    static void SetComponentLevel(const wxString& component, wxLogLevel level);
+
+    // return the effective log level for this component, falling back to
+    // parent component and to the default global log level if necessary
+    //
+    // NB: component argument is passed by value and not const reference in an
+    //     attempt to encourage compiler to avoid an extra copy: as we modify
+    //     the component internally, we'd create one anyhow and like this it
+    //     can be avoided if the string is a temporary anyhow
+    static wxLogLevel GetComponentLevel(wxString component);
+
+
+    // is logging of messages from this component enabled at this level?
+    //
+    // usually always called with wxLOG_COMPONENT as second argument
+    static bool IsLevelEnabled(wxLogLevel level, wxString component)
+    {
+        return IsEnabled() && level <= GetComponentLevel(component);
+    }
+
+
+    // enable/disable messages at wxLOG_Verbose level (only relevant if the
+    // current log level is greater or equal to it)
+    //
+    // notice that verbose mode can be activated by the standard command-line
+    // '--verbose' option
+    static void SetVerbose(bool bVerbose = true) { ms_bVerbose = bVerbose; }
+
+    // check if verbose messages are enabled
+    static bool GetVerbose() { return ms_bVerbose; }
+
+
     // message buffering
+    // -----------------
 
     // flush shows all messages if they're not logged immediately (FILE
     // and iostream logs don't need it, but wxGuiLog does to avoid showing
@@ -332,14 +392,6 @@ public:
     // must be called for each Suspend()!
     static void Resume() { ms_suspendCount--; }
 
-    // functions controlling the default wxLog behaviour
-    // verbose mode is activated by standard command-line '--verbose'
-    // option
-    static void SetVerbose(bool bVerbose = true) { ms_bVerbose = bVerbose; }
-
-    // Set log level.  Log messages with level > logLevel will not be logged.
-    static void SetLogLevel(wxLogLevel logLevel) { ms_logLevel = logLevel; }
-
     // should GetActiveTarget() try to create a new log object if the
     // current is NULL?
     static void DontCreateOnDemand();
@@ -377,17 +429,9 @@ public:
     static void DisableTimestamp() { SetTimestamp(wxEmptyString); }
 
 
-    // accessors
-
-    // gets the verbose status
-    static bool GetVerbose() { return ms_bVerbose; }
-
     // is this trace mask in the list?
     static bool IsAllowedTraceMask(const wxString& mask);
 
-    // return the current loglevel limit
-    static wxLogLevel GetLogLevel() { return ms_logLevel; }
-
     // get the current timestamp format string (maybe empty)
     static const wxString& GetTimestamp() { return ms_timestamp; }
 
@@ -742,9 +786,10 @@ public:
     wxLogger(wxLogLevel level,
              const char *filename,
              int line,
-             const char *func)
+             const char *func,
+             const char *component)
         : m_level(level),
-          m_info(filename, line, func)
+          m_info(filename, line, func, component)
     {
     }
 
@@ -778,7 +823,8 @@ public:
     void LogV(const wxString& format, va_list argptr)
     {
         // remember that fatal errors can't be disabled
-        if ( m_level == wxLOG_FatalError || wxLog::IsLevelEnabled(m_level) )
+        if ( m_level == wxLOG_FatalError ||
+                wxLog::IsLevelEnabled(m_level, m_info.component) )
             DoCallOnLog(format, argptr);
     }
 
@@ -980,7 +1026,7 @@ private:
 
     void DoLogAtLevel(wxLogLevel level, const wxChar *format, ...)
     {
-        if ( !wxLog::IsLevelEnabled(level) )
+        if ( !wxLog::IsLevelEnabled(level, m_info.component) )
             return;
 
         va_list argptr;
@@ -1049,7 +1095,7 @@ private:
 
     void DoLogAtLevelUtf8(wxLogLevel level, const char *format, ...)
     {
-        if ( !wxLog::IsLevelEnabled(level) )
+        if ( !wxLog::IsLevelEnabled(level, m_info.component) )
             return;
 
         va_list argptr;
@@ -1155,7 +1201,7 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0);
 
 // creates wxLogger object for the current location
 #define wxMAKE_LOGGER(level) \
-    wxLogger(wxLOG_##level, __FILE__, __LINE__, __WXFUNCTION__)
+    wxLogger(wxLOG_##level, __FILE__, __LINE__, __WXFUNCTION__, wxLOG_COMPONENT)
 
 // this macro generates the expression which logs whatever follows it in
 // parentheses at the level specified as argument
@@ -1188,7 +1234,7 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0);
 //       easily fixed by adding curly braces around wxLogError() and at least
 //       the code still does do the right thing.
 #define wxDO_LOG_IF_ENABLED(level)                                            \
-    if ( !wxLog::IsLevelEnabled(wxLOG_##level) )                              \
+    if ( !wxLog::IsLevelEnabled(wxLOG_##level, wxLOG_COMPONENT) )             \
     {}                                                                        \
     else                                                                      \
         wxDO_LOG(level)
@@ -1208,12 +1254,14 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0);
 
 // this one is special as it only logs if we're in verbose mode
 #define wxLogVerbose                                                          \
-    if ( !(wxLog::IsLevelEnabled(wxLOG_Info) && wxLog::GetVerbose()) )        \
+    if ( !(wxLog::IsLevelEnabled(wxLOG_Info, wxLOG_COMPONENT) &&              \
+            wxLog::GetVerbose()) )                                            \
     {}                                                                        \
     else                                                                      \
         wxDO_LOG(Info)
 #define wxVLogVerbose(format, argptr)                                         \
-    if ( !(wxLog::IsLevelEnabled(wxLOG_Info) && wxLog::GetVerbose()) )        \
+    if ( !(wxLog::IsLevelEnabled(wxLOG_Info, wxLOG_COMPONENT) &&              \
+            wxLog::GetVerbose()) )                                            \
     {}                                                                        \
     else                                                                      \
         wxDO_LOGV(Info, format, argptr)
@@ -1230,7 +1278,7 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0);
 // always evaluated, unlike for the other log functions
 #define wxLogGeneric wxMAKE_LOGGER(Max).LogAtLevel
 #define wxVLogGeneric(level, format, argptr) \
-    if ( !wxLog::IsLevelEnabled(wxLOG_##level) )                              \
+    if ( !wxLog::IsLevelEnabled(wxLOG_##level, wxLOG_COMPONENT) )             \
     {}                                                                        \
     else                                                                      \
         wxDO_LOGV(level, format, argptr)
@@ -1242,7 +1290,7 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0);
 #define wxLOG_KEY_SYS_ERROR_CODE "wx.sys_error"
 
 #define wxLogSysError                                                         \
-    if ( !wxLog::IsLevelEnabled(wxLOG_Error) )                                \
+    if ( !wxLog::IsLevelEnabled(wxLOG_Error, wxLOG_COMPONENT) )               \
     {}                                                                        \
     else                                                                      \
         wxMAKE_LOGGER(Error).MaybeStore(wxLOG_KEY_SYS_ERROR_CODE).Log
@@ -1259,7 +1307,7 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0);
     #define wxLOG_KEY_FRAME "wx.frame"
 
     #define wxLogStatus                                                       \
-        if ( !wxLog::IsLevelEnabled(wxLOG_Status) )                           \
+        if ( !wxLog::IsLevelEnabled(wxLOG_Status, wxLOG_COMPONENT) )          \
         {}                                                                    \
         else                                                                  \
             wxMAKE_LOGGER(Status).MaybeStore(wxLOG_KEY_FRAME).Log
@@ -1379,7 +1427,7 @@ public:
 
 #if wxUSE_LOG_TRACE
     #define wxLogTrace                                                        \
-        if ( !wxLog::IsLevelEnabled(wxLOG_Trace) )                            \
+        if ( !wxLog::IsLevelEnabled(wxLOG_Trace, wxLOG_COMPONENT) )           \
         {}                                                                    \
         else                                                                  \
             wxMAKE_LOGGER(Trace).LogTrace
index 42ef240c14da36b73b634a20c8343b8f71bf12e3..49a9f10d76b47f52c148130163bea50670fb2003 100644 (file)
@@ -828,11 +828,14 @@ public:
         Returns true if logging at this level is enabled.
 
         This function only returns @true if logging is globally enabled and if
-        this level is less than or equal to the global log level value.
+        @a level is less than or equal to the maximal log level enabled for the
+        given @a component.
 
-        @see IsEnabled(), SetLogLevel(), GetLogLevel()
+        @see IsEnabled(), SetLogLevel(), GetLogLevel(), SetComponentLevel()
+
+        @since 2.9.1
      */
-    static bool IsLevelEnabled(wxLogLevel level);
+    static bool IsLevelEnabled(wxLogLevel level, wxString component);
 
     /**
         Remove the @a mask from the list of allowed masks for
@@ -858,9 +861,33 @@ public:
     */
     static wxLog* SetActiveTarget(wxLog* logtarget);
 
+    /**
+        Sets the log level for the given component.
+
+        For example, to disable all but error messages from wxWidgets network
+        classes you may use
+        @code
+            wxLog::SetComponentLevel("wx/net", wxLOG_Error);
+        @endcode
+
+        SetLogLevel() may be used to set the global log level.
+
+        @param component
+            Non-empty component name, possibly using slashes (@c /) to separate
+            it into several parts.
+        @param level
+            Maximal level of log messages from this component which will be
+            handled instead of being simply discarded.
+
+        @since 2.9.1
+     */
+    static void SetComponentLevel(const wxString& component, wxLogLevel level);
+
     /**
         Specifies that log messages with level greater (numerically) than
         @a logLevel should be ignored and not sent to the active log target.
+
+        @see SetComponentLevel()
     */
     static void SetLogLevel(wxLogLevel logLevel);
 
index e0686ce3d877c38c2b1b05aa6f56a7c97bb9e636..1b599cc8f8f38ea193f3f8514e3703ab93375bfb 100644 (file)
@@ -63,6 +63,9 @@
     #include "wx/msw/private.h" // includes windows.h
 #endif
 
+#undef wxLOG_COMPONENT
+const char *wxLOG_COMPONENT = "";
+
 #if wxUSE_THREADS
 
 // define static functions providing access to the critical sections we use
@@ -85,6 +88,13 @@ static inline wxCriticalSection& GetPreviousLogCS()
     return s_csPrev;
 }
 
+static inline wxCriticalSection& GetLevelsCS()
+{
+    static wxCriticalSection s_csLevels;
+
+    return s_csLevels;
+}
+
 #endif // wxUSE_THREADS
 
 // ----------------------------------------------------------------------------
@@ -130,6 +140,12 @@ struct PreviousLogInfo
 
 PreviousLogInfo gs_prevLog;
 
+
+// map containing all components for which log level was explicitly set
+//
+// NB: all accesses to it must be protected by GetLevelsCS() critical section
+wxStringToNumHashMap gs_componentLevels;
+
 } // anonymous namespace
 
 // ============================================================================
@@ -437,6 +453,47 @@ void wxLog::DoCreateOnDemand()
     ms_bAutoCreate = true;
 }
 
+// ----------------------------------------------------------------------------
+// wxLog components levels
+// ----------------------------------------------------------------------------
+
+/* static */
+void wxLog::SetComponentLevel(const wxString& component, wxLogLevel level)
+{
+    if ( component.empty() )
+    {
+        SetLogLevel(level);
+    }
+    else
+    {
+        wxCRIT_SECT_LOCKER(lock, GetLevelsCS());
+
+        gs_componentLevels[component] = level;
+    }
+}
+
+/* static */
+wxLogLevel wxLog::GetComponentLevel(wxString component)
+{
+    wxCRIT_SECT_LOCKER(lock, GetLevelsCS());
+
+    while ( !component.empty() )
+    {
+        wxStringToNumHashMap::const_iterator
+            it = gs_componentLevels.find(component);
+        if ( it != gs_componentLevels.end() )
+            return static_cast<wxLogLevel>(it->second);
+
+        component = component.BeforeLast('/');
+    }
+
+    return GetLogLevel();
+}
+
+// ----------------------------------------------------------------------------
+// wxLog trace masks
+// ----------------------------------------------------------------------------
+
 void wxLog::AddTraceMask(const wxString& str)
 {
     wxCRIT_SECT_LOCKER(lock, GetTraceMaskCS());
@@ -460,6 +517,25 @@ void wxLog::ClearTraceMasks()
     ms_aTraceMasks.Clear();
 }
 
+/*static*/ bool wxLog::IsAllowedTraceMask(const wxString& mask)
+{
+    wxCRIT_SECT_LOCKER(lock, GetTraceMaskCS());
+
+    for ( wxArrayString::iterator it = ms_aTraceMasks.begin(),
+                                  en = ms_aTraceMasks.end();
+         it != en; ++it )
+    {
+        if ( *it == mask)
+            return true;
+    }
+
+    return false;
+}
+
+// ----------------------------------------------------------------------------
+// wxLog miscellaneous other methods
+// ----------------------------------------------------------------------------
+
 void wxLog::TimeStamp(wxString *str)
 {
 #if wxUSE_DATETIME
@@ -484,21 +560,6 @@ void wxLog::Flush()
     LogLastRepeatIfNeeded();
 }
 
-/*static*/ bool wxLog::IsAllowedTraceMask(const wxString& mask)
-{
-    wxCRIT_SECT_LOCKER(lock, GetTraceMaskCS());
-
-    for ( wxArrayString::iterator it = ms_aTraceMasks.begin(),
-                                  en = ms_aTraceMasks.end();
-         it != en; ++it )
-    {
-        if ( *it == mask)
-            return true;
-    }
-
-    return false;
-}
-
 // ----------------------------------------------------------------------------
 // wxLogBuffer implementation
 // ----------------------------------------------------------------------------
index f1dbb8cffab1ad197bd86319f9b4bceeb7963491..0334bc6d633dad225fbd8410dcf25c646e0b93ee 100644 (file)
@@ -31,6 +31,9 @@
     #endif // VC++ 7+
 #endif // WXWIN_COMPATIBILITY_2_8
 
+// all calls to wxLogXXX() functions from this file will use this log component
+#define wxLOG_COMPONENT "test"
+
 // ----------------------------------------------------------------------------
 // test loggers
 // ----------------------------------------------------------------------------
@@ -42,19 +45,28 @@ class TestLogBase : public wxLog
 public:
     TestLogBase() { }
 
-    wxString GetLog(wxLogLevel level) const
+    const wxString& GetLog(wxLogLevel level) const
     {
         return m_logs[level];
     }
 
+    const wxLogRecordInfo& GetInfo(wxLogLevel level) const
+    {
+        return m_logsInfo[level];
+    }
+
     void Clear()
     {
         for ( unsigned n = 0; n < WXSIZEOF(m_logs); n++ )
+        {
             m_logs[n].clear();
+            m_logsInfo[n] = wxLogRecordInfo();
+        }
     }
 
 protected:
     wxString m_logs[wxLOG_Trace + 1];
+    wxLogRecordInfo m_logsInfo[wxLOG_Trace + 1];
 
     wxDECLARE_NO_COPY_CLASS(TestLogBase);
 };
@@ -68,9 +80,10 @@ public:
 protected:
     virtual void DoLogRecord(wxLogLevel level,
                              const wxString& msg,
-                             const wxLogRecordInfo& WXUNUSED(info))
+                             const wxLogRecordInfo& info)
     {
         m_logs[level] = msg;
+        m_logsInfo[level] = info;
     }
 
 private:
@@ -147,6 +160,7 @@ private:
     CPPUNIT_TEST_SUITE( LogTestCase );
         CPPUNIT_TEST( Functions );
         CPPUNIT_TEST( Null );
+        CPPUNIT_TEST( Component );
 #if wxDEBUG_LEVEL
         CPPUNIT_TEST( Trace );
 #endif // wxDEBUG_LEVEL
@@ -158,6 +172,7 @@ private:
 
     void Functions();
     void Null();
+    void Component();
 #if wxDEBUG_LEVEL
     void Trace();
 #endif // wxDEBUG_LEVEL
@@ -220,6 +235,42 @@ void LogTestCase::Null()
     CPPUNIT_ASSERT_EQUAL( "Important warning", m_log->GetLog(wxLOG_Warning) );
 }
 
+void LogTestCase::Component()
+{
+    wxLogMessage("Message");
+    CPPUNIT_ASSERT_EQUAL( wxLOG_COMPONENT,
+                          m_log->GetInfo(wxLOG_Message).component );
+
+    // completely disable logging for this component
+    wxLog::SetComponentLevel("test/ignore", wxLOG_FatalError);
+
+    // but enable it for one of its subcomponents
+    wxLog::SetComponentLevel("test/ignore/not", wxLOG_Max);
+
+    #undef wxLOG_COMPONENT
+    #define wxLOG_COMPONENT "test/ignore"
+
+    // this shouldn't be output as this component is ignored
+    wxLogError("Error");
+    CPPUNIT_ASSERT_EQUAL( "", m_log->GetLog(wxLOG_Error) );
+
+    // and so are its subcomponents
+    #undef wxLOG_COMPONENT
+    #define wxLOG_COMPONENT "test/ignore/sub/subsub"
+    wxLogError("Error");
+    CPPUNIT_ASSERT_EQUAL( "", m_log->GetLog(wxLOG_Error) );
+
+    // but one subcomponent is not
+    #undef wxLOG_COMPONENT
+    #define wxLOG_COMPONENT "test/ignore/not"
+    wxLogError("Error");
+    CPPUNIT_ASSERT_EQUAL( "Error", m_log->GetLog(wxLOG_Error) );
+
+    // restore the original value
+    #undef wxLOG_COMPONENT
+    #define wxLOG_COMPONENT "test"
+}
+
 #if wxDEBUG_LEVEL
 
 void LogTestCase::Trace()