Boost logo

Boost-Commit :

From: john.groups_at_[hidden]
Date: 2008-01-04 22:12:12


Author: jtorjo
Date: 2008-01-04 22:12:11 EST (Fri, 04 Jan 2008)
New Revision: 42470
URL: http://svn.boost.org/trac/boost/changeset/42470

Log:
[logging]
v0.13.5, 5 jan 2008
- added docs about caching messages
Added:
   sandbox/logging/boost/logging/detail/raw_doc/caching.hpp (contents, props changed)
   sandbox/logging/boost/logging/detail/raw_doc/rationale.hpp (contents, props changed)
Text files modified:
   sandbox/logging/boost/logging/detail/cache_before_init.hpp | 2 +-
   sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp | 4 ++--
   sandbox/logging/boost/logging/detail/raw_doc/main.hpp | 8 ++++++++
   sandbox/logging/boost/logging/detail/raw_doc/table_of_contents.hpp | 3 ++-
   sandbox/logging/lib/logging/internal/vc8/loggingvc8/loggingvc8.vcproj | 8 ++++++++
   5 files changed, 21 insertions(+), 4 deletions(-)

Modified: sandbox/logging/boost/logging/detail/cache_before_init.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/cache_before_init.hpp (original)
+++ sandbox/logging/boost/logging/detail/cache_before_init.hpp 2008-01-04 22:12:11 EST (Fri, 04 Jan 2008)
@@ -174,7 +174,7 @@
     mutable cache m_cache;
     /**
     IMPORTANT: to make sure we know when the cache is off as efficiently as possible, I have this mechanism:
- - first, query m_is_enabled,which at the beginning is false (this is very efficient, we can use TSS here)
+ - first, query m_is_enabled, which at the beginning is false (this is very efficient, we can use TSS here)
       - if this is true, it's clear that caching has been turned off
       - if this is false, we don't know for sure, thus, continue to ask
     

Added: sandbox/logging/boost/logging/detail/raw_doc/caching.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/detail/raw_doc/caching.hpp 2008-01-04 22:12:11 EST (Fri, 04 Jan 2008)
@@ -0,0 +1,143 @@
+namespace boost { namespace logging {
+
+/**
+@page caching Caching messages before logs are initialized
+
+- @ref caching_why
+- @ref caching_BOOST_LOG_BEFORE_INIT_CACHE_FILTER
+- @ref caching_BOOST_LOG_BEFORE_INIT_LOG_ALL
+- @ref caching_BOOST_LOG_BEFORE_INIT_IGNORE_BEFORE_INIT
+- @ref caching_ts
+
+@section caching_why Caching - why is it needed?
+
+Logging is all fine and dandy, but what if you do some %logging before the actual logs are initialized?
+It's quite easy to end up doing this:
+- usually you initialize logs somewhere within your @c main()
+- as applications grow, you'll have global/static variables
+- you'll do %logging from the body of the global/static variable's constructors
+ - direcly (from a constructor)
+ - indirectly (from some constructor you call a function, which calls a function... which in turn does some logging)
+
+You could even run into more complicated scenarios, where you create other threads,
+which, until you initialize your logs, do some logging. It's good practice to log a thread's begin and end, for instance.
+
+Even though you think this'll never happen to you, usage of singletons and other static variables is quite common,
+so better to guard against it.
+
+One solution would be for the library to rely on an external function, like <tt>void boost::logging::init_logs()</tt>,
+and have your application have to define it, and it its body, initialize the logs. The library would then make sure
+the @c init_logs() is called before any log is used.
+
+There are several problems with this solution:
+- logs could be used too soon before you have all the needed data to initialize them (for instance, some could depend
+ on command line arguments)
+- before any log is used, I would need to make sure @c init_logs() has been called - thus, for each log usage,
+ I would need to check if init_logs has been called or not - not very efficient
+- within init_logs() I might end up using logs, thus ending in an infinite loop (log needs init_logs(), which uses log)
+- you would not have any control over when @c init_logs() is called - what if they need some context information -
+ they wouldn't have any context do rely on
+- depending on your application, some logs could only be initialized later than others
+- if your application has several modules, assume each module has its own log. Thus, each module should be able to
+ initialize its own log when the module is initialized
+
+Thus, I came up with a caching mechanism. You can choose to:
+- Cache messages that are written before logs are initialized. For each logged message, you will also cache its corresponding filter
+ (so that if, when initializing the logs, a certain filter is turned off, that message won't be logged)
+- Cache messages that are written before logs are initialized. When logs are initialized, all these cached messages are logged
+- Ignore messages that are written before the logs are initialized
+
+<b>By default, for each log, cache is turned on. To turn cache off (mark the log as initialized), just call @c turn_cache_off() on it.
+You'll see that I'm doing this on all examples that come with the library.</b>
+
+
+
+
+@section caching_BOOST_LOG_BEFORE_INIT_CACHE_FILTER Cache messages before logs are initialized/ cache their filter as well (BOOST_LOG_BEFORE_INIT_CACHE_FILTER)
+
+The first case is the default. It's a bit inefficient (after invoking the filter, it will always ask if cache is on or off). Also,
+it increases the application's size a bit - for each log statement, I will generate a callback that I can call later to see if the filter
+is still turned on or off.
+
+Again, this is the default - if you do want to enforce it, make sure you define the @c BOOST_LOG_BEFORE_INIT_CACHE_FILTER globally.
+
+@code
+...
+#define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l, g_log_filter->is_enabled() )
+...
+
+L_ << "this message will not be logged";
+g_log_filter->set_enabled(false);
+g_l->turn_cache_off();
+@endcode
+
+
+@section caching_BOOST_LOG_BEFORE_INIT_LOG_ALL Cache messages before logs are initialized regardless of their filter (BOOST_LOG_BEFORE_INIT_LOG_ALL)
+
+In the second case, when cache is on, all messages are cached, regardless of their filter (it's like all filters are on).
+Then, when cache is turned off, all messages are logged.
+
+If you do want to use this setting, make sure you define the @c BOOST_LOG_BEFORE_INIT_LOG_ALL globally.
+
+@code
+...
+#define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l, g_log_filter->is_enabled() )
+...
+
+L_ << "this message will be logged, even if filter will be turned off";
+g_log_filter->set_enabled(false);
+g_l->turn_cache_off();
+@endcode
+
+
+
+@section caching_BOOST_LOG_BEFORE_INIT_IGNORE_BEFORE_INIT Ignore all messages before turn_cache_off (BOOST_LOG_BEFORE_INIT_IGNORE_BEFORE_INIT)
+
+In the last case, all messages before @c turn_cache_off() are ignored.
+
+If you do want to use this setting, make sure you define the @c BOOST_LOG_BEFORE_INIT_IGNORE_BEFORE_INIT globally.
+
+@code
+...
+#define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l, g_log_filter->is_enabled() )
+...
+
+L_ << "this message will NOT be logged";
+g_l->turn_cache_off();
+@endcode
+
+
+
+@section caching_ts Setting thread-safety of "is_cache_turned_on"
+
+In case you chose to use cache (either @c BOOST_LOG_BEFORE_INIT_CACHE_FILTER or @c BOOST_LOG_BEFORE_INIT_LOG_ALL), you can also set
+thread-safety of "is_cache_turned_on".
+
+Each time a message is logged, we need to ask : @c is_cache_turned_on. However, we also want to be as efficient as possible - we don't want
+this question to take too much CPU time. Thus, I came up with a simple algorithm:
+- first, query an @c is_enabled bool-like variable, which at the beginning is false (very efficient, we can use TSS here)
+ - if this is true, it's clear that caching has been turned off
+ - if this is false, we don't know for sure, thus, continue to ask
+- second, use a thread-safe "bool"-like variable (surrounded by a mutex, a bit slow, but that's life)
+ - if this is true, we're still using cache
+ - if this is false, caching has been turned off
+ - set @c is_enabled to true
+
+Now, for the @c is_enabled variable, we can use several TSS tricks - like:
+- use @c ts_resource_single_thread (the default) - is_enabled is a simple bool variable. This is very efficient,
+ and is perfect if for your logs, you call turn_cache_off() while there's a single thread running (thus, no concurrency issues).
+- use @c tss_resource_once_init - this resource, once initialized, it propagates through all threads.
+- use @c tss_resource_with_cache - each thread updates its value once at a certain period
+
+There are several such policies, find them in the lock_resource_finder namespace.
+
+If you want to override the above, make sure you define the @c BOOST_LOG_BEFORE_INIT_LOCK_RESOURCE_CLASS macro before including
+any Boost Log headers. Example:
+
+@code
+#define BOOST_LOG_BEFORE_INIT_LOCK_RESOURCE_CLASS ::boost::logging::lock_resource_finder::tss_once_init<>
+@endcode
+
+*/
+
+}}

Modified: sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp (original)
+++ sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp 2008-01-04 22:12:11 EST (Fri, 04 Jan 2008)
@@ -1,8 +1,8 @@
 /**
 @page page_changelog Changelog
 
-_at_section changelog_cur_ver Current Version: v0.13.2, 4 jan 2008
-- breaks compilation on gcc4.1
+@section changelog_cur_ver Current Version: v0.13.5, 5 jan 2008
+- added docs about caching messages
 - can cache messages before initialization of logs
 - gather classes now have msg_type instead of param (msg_type contains the type of the returned msg - without const or &)
 

Modified: sandbox/logging/boost/logging/detail/raw_doc/main.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/main.hpp (original)
+++ sandbox/logging/boost/logging/detail/raw_doc/main.hpp 2008-01-04 22:12:11 EST (Fri, 04 Jan 2008)
@@ -41,6 +41,14 @@
       you can define your own writing mechanism
 - Easy manipulation of the logs (turning on/off, setting formatters, destinations, etc)
 - Allows you to use @ref tag "tags" (extra information about the context of the log: file/line, function name, thread id, etc.)
+- Allows for @ref scoped_logs "scoped logs"
+- Has @ref formatter::high_precision_time_t "high precision time formatter"
+- easy to configure at run-time, if you wish
+ - @ref formatter::named_spacer
+ - @ref destination::named
+- @ref caching "cache messages before logs are initialized"
+
+
 
 \n\n
 @section main_common_usage Common Usage

Added: sandbox/logging/boost/logging/detail/raw_doc/rationale.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/detail/raw_doc/rationale.hpp 2008-01-04 22:12:11 EST (Fri, 04 Jan 2008)
@@ -0,0 +1,37 @@
+namespace boost { namespace logging {
+
+/**
+@page rationale Rationales
+
+
+
+
+@section rationale_init_logs Rationale for not forcing an init_logs() function
+
+I could have used an init_logs() function which would be called first time a log is used. However, that would bring its own problems to the table:
+How do I know the first time a log is used? \n
+What if the logs are used too soon (and init_logs would be called too soon, before we can safely initialize the logs)? \n
+What if we're using the logs in a multi-threaded environment, how do we guard for the init_logs to be called only once (how costly will it turn out)? \n
+What about using it from DLL/EXE?
+
+
+
+@section rationale_caching Rationale for - when caching - to use a mutex
+
+When caching messages before logs are initialized, I internally use a mutex for adding each message to the cache.
+I use this because:
+- I assume there won't be too many (<1000), thus the impact on speed should be minimal
+- this will be applied only while cache is turned off
+- I do prefer safety over efficiency
+- easier to implement this scenario
+
+
+
+
+
+
+
+
+*/
+
+}}

Modified: sandbox/logging/boost/logging/detail/raw_doc/table_of_contents.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/table_of_contents.hpp (original)
+++ sandbox/logging/boost/logging/detail/raw_doc/table_of_contents.hpp 2008-01-04 22:12:11 EST (Fri, 04 Jan 2008)
@@ -36,6 +36,7 @@
 - @ref tag "Using tags"
 - @ref thread_safety
 - @ref misc_unicode
+- @ref caching
 - @ref macros
     - @ref macros_if_else_strategy
     - @ref macros_using
@@ -67,7 +68,7 @@
 
 - @ref boost_logging_requirements
 - @ref page_todo
-
+- @ref rationale
 
 */
 

Modified: sandbox/logging/lib/logging/internal/vc8/loggingvc8/loggingvc8.vcproj
==============================================================================
--- sandbox/logging/lib/logging/internal/vc8/loggingvc8/loggingvc8.vcproj (original)
+++ sandbox/logging/lib/logging/internal/vc8/loggingvc8/loggingvc8.vcproj 2008-01-04 22:12:11 EST (Fri, 04 Jan 2008)
@@ -702,6 +702,10 @@
>
                         </File>
                         <File
+ RelativePath="..\..\..\..\..\boost\logging\detail\raw_doc\caching.hpp"
+ >
+ </File>
+ <File
                                 RelativePath="..\..\..\..\..\boost\logging\detail\raw_doc\common_usage_steps_fd.hpp"
>
                         </File>
@@ -734,6 +738,10 @@
>
                         </File>
                         <File
+ RelativePath="..\..\..\..\..\boost\logging\detail\raw_doc\rationale.hpp"
+ >
+ </File>
+ <File
                                 RelativePath="..\..\..\..\..\boost\logging\detail\raw_doc\requirements.hpp"
>
                         </File>


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk