Boost logo

Boost-Commit :

From: john.groups_at_[hidden]
Date: 2008-01-21 08:16:50


Author: jtorjo
Date: 2008-01-21 08:16:49 EST (Mon, 21 Jan 2008)
New Revision: 42894
URL: http://svn.boost.org/trac/boost/changeset/42894

Log:
[logging]
v0.20.14, 20 jan 2008
- more docs about @ref defining_your_logger_filter
Text files modified:
   sandbox/logging/boost/logging/detail/log_keeper.hpp | 3
   sandbox/logging/boost/logging/detail/logger.hpp | 116 +++++-----
   sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp | 3
   sandbox/logging/boost/logging/detail/raw_doc/defining_your_logger_filter.hpp | 435 ++++++++++++++++++++++++++++++++++++++-
   sandbox/logging/boost/logging/detail/raw_doc/table_of_contents.hpp | 18 +
   sandbox/logging/boost/logging/detail/raw_doc/todo.hpp | 10
   6 files changed, 503 insertions(+), 82 deletions(-)

Modified: sandbox/logging/boost/logging/detail/log_keeper.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/log_keeper.hpp (original)
+++ sandbox/logging/boost/logging/detail/log_keeper.hpp 2008-01-21 08:16:49 EST (Mon, 21 Jan 2008)
@@ -102,9 +102,6 @@
     @brief Allows using a log without knowing its full type yet. Even if the log is not fully @b defined, you can still use it.
 
     This will allow you to log messages even if you don't know the full type of the log (which can aid compilation time).
-
- This keeps the logger by value, so that the after_being_destroyed stuff works.
- More specifically, in case the logger is used after it's been destroyed, the logger_holder instances CAN ONLY BE GLOBAL.
 */
 template<class type> struct logger_holder_by_ptr : logger_holder<type> {
     typedef logger_holder<type> base_type;

Modified: sandbox/logging/boost/logging/detail/logger.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/logger.hpp (original)
+++ sandbox/logging/boost/logging/detail/logger.hpp 2008-01-21 08:16:49 EST (Mon, 21 Jan 2008)
@@ -52,62 +52,6 @@
     };
 
 
-
-
- /**
- @brief The logger class. Every log from your application is an instance of this (see @ref workflow_processing "workflow")
-
- As described in @ref workflow_processing "workflow", processing the message is composed of 2 things:
- - @ref workflow_2a "Gathering the message"
- - @ref workflow_2b "Processing the message"
-
- The logger class has 2 template parameters:
-
-
- @param gather_msg A new gather instance is created each time a message is written.
- The @c gather_msg class needs to be default-constructible.
- The @c gather_msg must have a function called @c .msg() which contains all information about the written message.
- It will be passed to the write_msg class.
- You can implement your own @c gather_msg class, or use any from the gather namespace.
-
-
- @param write_msg This is the object that does the @ref workflow_2b "second step" - the writing of the message.
- It can be a simple functor.
- Or, it can be a more complex object that contains logic of how the message is to be further formatted,
- and written to multiple destinations.
- You can implement your own @c write_msg class, or it can be any of the classes defined in writer namespace.
- Check out writer::format_write - which allows you to use
- several formatters to further format the message, and then write it to destinations.
-
- \n\n
- You will seldom need to use the logger class directly. You can use @ref defining_your_logger "other wrapper classes".
-
-
- \n\n
- The logger forwards
- the gathering of the message to the @c gather_msg class. Once all message is gathered, it's passed on to the writer.
- This is usually done through a @ref macros_use "macro".
-
- @code
- typedef logger< ... > log_type;
- BOOST_DECLARE_LOG_FILTER(g_log_filter, filter::no_ts )
- BOOST_DECLARE_LOG(g_l, log_type)
-
- #define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l(), g_log_filter()->is_enabled() )
-
- // usage
- L_ << "this is so cool " << i++;
-
- @endcode
-
-
-
- \n\n
- To understand more on the workflow that involves %logging:
- - check out the gather namespace
- - check out the writer namespace
-
- */
     template<class gather_msg = default_, class write_msg = default_ > struct logger ;
 
 
@@ -216,8 +160,64 @@
 
 
 
- // default implementation - when gather_msg and write_msg are both known
- template<class gather_msg , class write_msg > struct logger : logger_base<gather_msg, write_msg> {
+ /**
+ @brief The logger class. Every log from your application is an instance of this (see @ref workflow_processing "workflow")
+
+ As described in @ref workflow_processing "workflow", processing the message is composed of 2 things:
+ - @ref workflow_2a "Gathering the message"
+ - @ref workflow_2b "Processing the message"
+
+ The logger class has 2 template parameters:
+
+
+ @param gather_msg A new gather instance is created each time a message is written.
+ The @c gather_msg class needs to be default-constructible.
+ The @c gather_msg must have a function called @c .msg() which contains all information about the written message.
+ It will be passed to the write_msg class.
+ You can implement your own @c gather_msg class, or use any from the gather namespace.
+
+
+ @param write_msg This is the object that does the @ref workflow_2b "second step" - the writing of the message.
+ It can be a simple functor.
+ Or, it can be a more complex object that contains logic of how the message is to be further formatted,
+ and written to multiple destinations.
+ You can implement your own @c write_msg class, or it can be any of the classes defined in writer namespace.
+ Check out writer::format_write - which allows you to use
+ several formatters to further format the message, and then write it to destinations.
+
+ \n\n
+ You will seldom need to use the logger class directly. You can use @ref defining_your_logger "other wrapper classes".
+
+
+ \n\n
+ The logger forwards
+ the gathering of the message to the @c gather_msg class. Once all message is gathered, it's passed on to the writer.
+ This is usually done through a @ref macros_use "macro".
+
+ @code
+ typedef logger< ... > log_type;
+ BOOST_DECLARE_LOG_FILTER(g_log_filter, filter::no_ts )
+ BOOST_DECLARE_LOG(g_l, log_type)
+
+ #define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l(), g_log_filter()->is_enabled() )
+
+ // usage
+ L_ << "this is so cool " << i++;
+
+ @endcode
+
+
+
+ \n\n
+ To understand more on the workflow that involves %logging:
+ - check out the gather namespace
+ - check out the writer namespace
+
+ */
+ template<class gather_msg , class write_msg > struct logger
+ // note: default implementation - when gather_msg and write_msg are both known
+ : logger_base<gather_msg, write_msg> {
+
         typedef typename detail::find_gather_if_default<gather_msg>::gather_type gather_type;
         typedef typename gather_type::msg_type msg_type;
         typedef write_msg write_type;

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-21 08:16:49 EST (Mon, 21 Jan 2008)
@@ -1,7 +1,8 @@
 /**
 @page page_changelog Changelog
 
-_at_section changelog_cur_ver Current Version: v0.20.12, 20 jan 2008
+@section changelog_cur_ver Current Version: v0.20.14, 20 jan 2008
+- more docs about @ref defining_your_logger_filter
 - added example using profiling, @ref common_scenario_profile "see it"
 - refactored finding the writer; added logger_to_writer class
 - fully implemented profiling

Modified: sandbox/logging/boost/logging/detail/raw_doc/defining_your_logger_filter.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/defining_your_logger_filter.hpp (original)
+++ sandbox/logging/boost/logging/detail/raw_doc/defining_your_logger_filter.hpp 2008-01-21 08:16:49 EST (Mon, 21 Jan 2008)
@@ -3,25 +3,93 @@
 /**
 @page defining_your_logger_filter Declaring/Defining your logger/filter class(es)
 
+- @ref defining_prerequisites
+ - @ref defining_prerequisites_typedef
+ - @ref defining_prerequisites_dd
+
+- @ref typedefing_your_filter
+ - @ref typedefing_your_filter_scenario
+ - @ref typedefing_your_filter_manually
+- @ref typedefing_your_logger
+ - @ref typedefing_your_logger_scenario
+ - @ref typedefing_your_logger_format_write
+ - @ref typedefing_your_logger_use_logger
+
+- @ref declare_define
+ - @ref declare_define_use_macros
+ - @ref declare_define_use_macros_under_the_hood
+ - @ref declare_define_use_macros_as_functions
+ - @ref declare_define_use_macros_fast_compile
+ - @ref declare_define_use_macros_before_main
+ - @ref declare_define_manually
+ - @ref declare_define_manually_f_vs_v
+ - @ref declare_define_manually_logger_holder
+ - @ref declare_define_manually_before_main
 
-- @ref defining_your_filter
- - @ref defining_your_filter_scenario
- - @ref defining_your_filter_manually
-- @ref defining_your_logger
- - @ref defining_your_logger_scenario
- - @ref defining_your_logger_format_write
- - @ref defining_your_logger_use_logger
 
 
+
+
+@section defining_prerequisites Prerequisites
+
 When using the Boost Logging Lib, you need 2 things (see @ref workflow "Workflow"):
 - a filter : which tells you if a logger is enabled or not. Note that you can use the same filter for multiple loggers - if you want.
 - a logger : which does the actual logging, once it's enabled
 
+In order to declare/define filters and loggers:
+- you have to choose the filter and logger based on your needs (@ref defining_prerequisites_typedef "typedefing")
+- you have to declare and define your fiter and logger (@ref defining_prerequisites_dd "declare and define")
+
+
+\n\n
+@subsection defining_prerequisites_typedef Prerequisites - Typedefing
+
+Typedefing your filter/logger is the process where you find the @c type of your filter/logger.
 
+Example 1:
+@code
+using namespace boost::logging::scenario::usage;
+typedef use< filter_::change::often<10> > finder;
+// now, finder::logger contains the logger type and finder::filter contains the filter type
+@endcode
+
+Example 2:
+@code
+namespace bl = boost::logging;
+typedef bl::logger_format_write< > logger_type;
+typedef bl::filter::no_ts filter_type;
+@endcode
 
-_at_section defining_your_filter Declaring/Defining your filter class
 
-_at_subsection defining_your_filter_scenario Declare/Define your filter using scenarios (the easy way)
+\n\n
+@subsection defining_prerequisites_dd Prerequisites - Declare and define
+
+Now that you know the types of your logger(s) and filter(s), you have to declare and define them.
+The easiest way is to use the @c BOOST_DECLARE_LOG* and @c BOOST_DEFINE_LOG* macros:
+
+@code
+// in a header file
+BOOST_DECLARE_LOG_FILTER(g_log_filter, filter_type )
+BOOST_DECLARE_LOG(g_l, logger_type)
+
+// in a source file
+BOOST_DEFINE_LOG_FILTER(g_log_filter, filter_type )
+BOOST_DEFINE_LOG(g_l, logger_type)
+
+// ... manipulating the logger/filter in the code
+g_l()->writer().add_formatter( formatter::idx(), "[%] " );
+g_log_filter()->set_enabled(false);
+@endcode
+
+However, there are other ways to declare/define your loggers/filters. We'll explore them @ref declare_define "later".
+
+
+
+
+\n\n
+@section typedefing_your_filter Typedefing your filter class
+
+@subsection typedefing_your_filter_scenario Typedefing your filter using scenarios (the easy way)
 
 You can declare/define both your logger and filter based on how you'll use them (scenario::usage).
 Thus, you'll deal with the filter like this:
@@ -46,7 +114,7 @@
 @endcode
 
 
-_at_subsection defining_your_filter_manually Declare/Define your filter manually
+@subsection typedefing_your_filter_manually Typedefing your filter manually
 
 This is where you manually specify the filter class you want. There are multiple filter implementations:
 - not using levels - the classes from the filter namespace
@@ -65,9 +133,9 @@
 
 
 
-_at_section defining_your_logger Declaring/defining your logger class(es)
+@section typedefing_your_logger Typedefing your logger class(es)
 
-_at_subsection defining_your_logger_scenario Declare/Define your logger using scenarios (the very easy way)
+@subsection typedefing_your_logger_scenario Typedefing your logger using scenarios (the very easy way)
 
 When you use formatters and destinations, you can declare/define both your logger and filter based on how you'll use them (scenario::usage).
 Thus, you'll deal with the logger like this:
@@ -95,7 +163,7 @@
 
 
 
-_at_subsection defining_your_logger_format_write Declare/Define your logger using logger_format_write (the easy way)
+@subsection typedefing_your_logger_format_write Typedefing your logger using logger_format_write (the easy way)
 
 When you use formatters and destinations, you can use the logger_format_write class. The template params you don't want to set,
 just leave them @c default_.
@@ -115,7 +183,7 @@
 
 
 
-_at_subsection defining_your_logger_use_logger Declare/Define your logger using the logger class
+@subsection typedefing_your_logger_use_logger Typedefing your logger using the logger class
 
 In case you don't use formatters and destinations, or have custom needs that the above methods can't satisfy, or
 just like to do things very manually, you can use the logger class directly:
@@ -133,6 +201,345 @@
 @endcode
 
 
+
+
+
+
+
+
+\n\n
+@section declare_define Declaring and defining your logger and filter
+
+At this point, you @em have your logger class and your filter class. Lets assume they are @c logger_type and @c filter_type.
+You could have obtained them like this:
+
+@code
+namespace bl = boost::logging;
+typedef bl::logger_format_write< > logger_type;
+typedef bl::filter::no_ts filter_type;
+@endcode
+
+
+
+
+\n\n
+@subsection declare_define_use_macros Declaring and defining your logger/filter using macros
+
+This is the simplest way to declare/define your filters.
+
+Declaring:
+
+@code
+// in a header file
+
+#include <boost/logging/format_fwd.hpp>
+// if you don't use formatters/destinations, you can include only <boost/logging/logging.hpp>
+
+// declare a filter, called g_log_filter
+BOOST_DECLARE_LOG_FILTER(g_log_filter, filter_type)
+
+// declare a logger, called g_log
+BOOST_DECLARE_LOG(g_log, logger_type)
+@endcode
+
+
+
+Defining:
+
+@code
+// in a source file
+#include <boost/logging/format.hpp>
+
+// define a filter, called g_log_filter
+BOOST_DEFINE_LOG_FILTER(g_log_filter, filter_type)
+
+// define a logger, called g_log
+BOOST_DEFINE_LOG(g_log, logger_type)
+@endcode
+
+
+
+Specifying some arguments when defining the logger/filter:
+@code
+// in a source file
+#include <boost/logging/format.hpp>
+
+// define a filter, called g_log_filter - assuming it needs an 2 arguments at construction
+BOOST_DEFINE_LOG_FILTER_WITH_ARGS(g_log_filter, filter_type, (level::debug, true) )
+
+// define a logger, called g_log - assuming it needs an extra argument at construction
+BOOST_DEFINE_LOG_WITH_ARGS(g_log, logger_type, ("log.txt") )
+@endcode
+
+
+\n\n
+@subsection declare_define_use_macros_under_the_hood Declaring and defining your logger/filter using macros - what happens under the hood?
+
+When using the @c BOOST_DECLARE_LOG* and @c BOOST_DEFINE_LOG* macros, this is what the lib takes care for you:
+-# it declares and defines a logger/filter name, as a @b function (which internally contains a static variable)
+-# cares about @ref BOOST_LOG_COMPILE_FAST_ON "Fast Compile" (default) or @ref BOOST_LOG_COMPILE_FAST_OFF "not"
+-# ensures the logger/filter object is instantiated before @c main(), even if not used before main(). This is very useful,
+ since we can assume that before main() there won't be more than 1 threads, thus no problems at initializing the static variable.
+
+\n\n
+@subsubsection declare_define_use_macros_as_functions logger/filter as functions
+
+
+We declare/define the logger/filter as a function, in order to avoid being used before it's initialized. Example:
+
+@code
+// Translation unit 1:
+logger<...> g_l;
+
+// Translation unit 2:
+struct widget {
+ widget() {
+ // use g_l
+ g_l.writer() ....
+ }
+} g_global_widget;
+
+@endcode
+
+In the above code we have 2 global variables (g_l and g_global_widget) in 2 different translation units. In this case, it's unspecified
+which will be constructed first - thus, we could end up having g_global_widget constructed first, and using g_l before g_l is initialized.
+
+To avoid this, g_l should be a function, like this:
+
+@code
+// Translation unit 1:
+logger<...> & g_l() { static logger<...> l; return l; }
+
+// Translation unit 2:
+struct widget {
+ widget() {
+ // use g_l
+ g_l().writer() ....
+ }
+} g_global_widget;
+
+@endcode
+
+In the above case, when g_l() is used for the first time, it constructs the local @c l, and it all works.
+The @c BOOST_DECLARE_LOG* and @c BOOST_DEFINE_LOG* macros take care of this automatically.
+
+
+
+\n\n
+@subsubsection declare_define_use_macros_fast_compile Fast compiling : On/Off
+
+The @c BOOST_DECLARE_LOG* and @c BOOST_DEFINE_LOG* macros also automatically take care of fast compiling or not.
+
+Fast compiling (on by default) applies only to loggers. It means that you can use the loggers in code, even without knowing their definition.
+More to the point, you can log messages throughout your application, even if you don't know the full type of the logger
+(a @em typedef is enough).
+This avoids inclusion of a lot of header files, speeding the compile process.
+
+If fast compile is on, you only need this when using logs:
+
+@code
+// usually in a header file
+#include <boost/logging/format_fwd.hpp>
+typedef logger_format_write< > logger_type;
+
+BOOST_DECLARE_LOG(g_l, logger_type)
+
+// macro used for logging
+#define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l(), g_log_filter()->is_enabled() )
+
+
+// in your code, only by #including boost/logging/format_fwd.hpp, you can log messages
+L_ << "this is so cool " << i++;
+std::string hello = "hello", world = "world";
+L_ << hello << ", " << world;
+@endcode
+
+If fast compile is off, when using the logs, you'll need to know the full type of the logger (the definition of the logger class).
+When using formatters/destinations, this means <tt>\#include <boost/logging/format.hpp></tt>. Also, when logging a message,
+the code for doing the actual logging will be generated inline, this taking a bit of compilation time.
+
+From my experiments, with fast compiling on, you get about 30% faster compile times. If you'd like to share your results, please drop me an email.
+
+In short,
+
+When fast compile is off, BOOST_DEFINE_LOG will generate code similar to this:
+
+@code
+logger_type * g_l() { static logger_type l; return &l; }
+@endcode
+
+When fast compile is off, BOOST_DEFINE_LOG will generate code similar to this:
+
+@code
+logger_holder<logger_type> & g_l() { static logger_holder_by_value<logger_type> l; return l; }
+@endcode
+
+In the latter case, logger_holder<> holds a pointer to the original log, and when a message is logged,
+it forwards it to the real logger (implemented in logger_holder_by_value).
+
+
+\n\n
+@subsubsection declare_define_use_macros_before_main Ensuring instantiation before main()
+
+The @c BOOST_DECLARE_LOG* and @c BOOST_DEFINE_LOG* macros also automatically ensure that the logger/filter is instantiated before main().
+This is very useful, since we can assume that before main() there won't be more than 1 threads, thus no problems at initializing the static variable.
+
+For this, it uses the @c ensure_early_log_creation class, like this:
+
+@code
+// this will ensure g_l() is called before main(), even if not used anywhere else before main()
+ensure_early_log_creation ensure( g_l() );
+@endcode
+
+
+
+
+
+\n\n
+@subsection declare_define_manually Declaring and defining your logger/filter manually
+
+As explained @ref declare_define_use_macros "above", you can use macros to declare/define your loggers/filters.
+
+Of course, you can declare/define them manually. If you decide to do it, please read the @ref declare_define_use_macros "Define/declare ... macros" section
+throughly, so that you know what you should watch for.
+
+For example, declaring/defining your logger can be as easy as:
+
+@code
+// in a header file
+logger_type * g_l();
+
+// example of macro used for logging
+#define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l(), g_log_filter()->is_enabled() )
+
+
+// in a source file
+logger_type * g_l() { static logger_type l; return &l; }
+
+// example of usage
+L_ << "this is so cool " << i++;
+std::string hello = "hello", world = "world";
+L_ << hello << ", " << world;
+@endcode
+
+
+
+\n\n
+@subsubsection declare_define_manually_f_vs_v Functions versus variables
+
+As I said, you should prefer @ref declare_define_use_macros_as_functions "functions instead of variables" for the obvious reasons.
+
+Thus (when using functions), your code should look like:
+
+@code
+// in a header file
+logger_type * g_l();
+
+// example of macro used for logging
+#define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l(), g_log_filter()->is_enabled() )
+
+
+// in a source file
+logger_type * g_l() { static logger_type l; return &l; }
+
+// example of usage
+L_ << "this is so cool " << i++;
+std::string hello = "hello", world = "world";
+L_ << hello << ", " << world;
+@endcode
+
+\n
+You can use variables, provided that @ref declare_define_use_macros_as_functions "you know the risks".
+
+@code
+// in a header file
+extern logger_type g_l;
+
+// example of macro used for logging
+#define L_ BOOST_LOG_USE_LOG_IF_FILTER((*g_l), g_log_filter()->is_enabled() )
+
+
+// in a source file
+logger_type g_l;
+
+// example of usage
+L_ << "this is so cool " << i++;
+std::string hello = "hello", world = "world";
+L_ << hello << ", " << world;
+@endcode
+
+
+
+
+\n\n
+@subsubsection declare_define_manually_logger_holder Using logger_holder class
+
+You should use @c logger_holder<> when you want to be able to use the logger without knowing its definition (in other words, you only have a typedef).
+Thus, you'll only need to #include <boost/logging/format_fwd.hpp> throughout the application.
+
+In case you're using formatters and destinations, you'll need to #include <boost/logging/format.hpp> :
+- when defining the logger
+- when initializing it
+
+Note that this will involve a virtual function call for each logged message - when performing the actual logging.
+
+<tt>logger_holder<logger></tt> is the base class - the one that will be used in code/presented to clients.
+The possible implementations are :
+- logger_holder_by_value<logger> - holds the original logger by value
+ - in case you think the logger could be used after it's been destroyed, you should use this
+- logger_holder_by_ptr<logger> - holds the original logger as a pointer (allocates it constructor, deallocates it in destructor)
+
+Example of using logger_holder<> :
+
+@code
+// in a header file
+logger_holder<logger_type> & g_l();
+
+// example of macro used for logging
+#define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l(), g_log_filter()->is_enabled() )
+
+
+// in a source file
+logger_holder<logger_type> & g_l() {
+ static logger_holder_by_value<logger_type> l;
+ return l;
+}
+
+// example of usage
+L_ << "this is so cool " << i++;
+std::string hello = "hello", world = "world";
+L_ << hello << ", " << world;
+@endcode
+
+
+\n\n
+@subsubsection declare_define_manually_before_main Ensure initialized before main()
+
+If you use loggers/filters as global variables, you don't need to worry about this.
+
+If you use loggers/filters as functions with static variables, they will be initialized on first usage.
+
+This could be problematic, in case the variable is initialized when more than one thread is running.
+In some current implementations , if 2 threads are calling the function at the same time (and when each function enters, needs to construct the variable),
+you might end up with 2 different instances of the same static variable. Thus, trouble.
+
+The easy solution is to use @c ensure_early_log_creation class, like this:
+
+@code
+// in the source file
+logger_holder<logger_type> & g_l() {
+ static logger_holder_by_value<logger_type> l;
+ return l;
+}
+ensure_early_log_creation ensure( g_l() );
+
+@endcode
+
+
+This will ensure the logger is initialized before main(), thus the above problem does not happen.
+
+
+
 */
 
 }}

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-21 08:16:49 EST (Mon, 21 Jan 2008)
@@ -33,11 +33,19 @@
     - @ref scenario_multiple_files
     - @ref starter_project
 
-- @ref headers_to_include "Headers to #include"
-- @ref defining_your_logger_filter
-- @ref scenario::usage "Choose the best filter/logger class, based on your application's needs"
-- @ref scoped_logs
-- @ref tag "Using tags"
+- Tutorial
+ - @ref headers_to_include "Headers to #include"
+ - @ref defining_your_logger_filter
+ - @ref scenario::usage "Choose the best filter/logger class, based on your application's needs"
+ - @ref scoped_logs
+ - @ref tag "Using tags"
+
+ FIXME macros for logging/ profiling
+
+ FIXME Special cases : after destruction
+
+\n\n
+Advanced concepts
 - @ref thread_safety
 - @ref misc_unicode
 - @ref caching

Modified: sandbox/logging/boost/logging/detail/raw_doc/todo.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/todo.hpp (original)
+++ sandbox/logging/boost/logging/detail/raw_doc/todo.hpp 2008-01-21 08:16:49 EST (Mon, 21 Jan 2008)
@@ -26,7 +26,11 @@
 
 - @c normal must have helper to call on on_destructed - like, to be able to write to cout,etc
 
-- @c high make it compile faster (most likely improve use_format_write, etc)
+- @c high cut down compile time: make it compile faster (most likely improve use_format_write, etc)
+
+- @c high logger_format_write<> should be just like other find classes - have logger_format_write<>::type
+ this should uncomplicate code a bit - at least specializing logger_to_gather/writer for logger_format_write<>. \n
+ I will first need to see if this will cut down compilation time or not.
 
 - @c normal profiler - we can care about threads as well (that is, for instance, when logging on another thread, see how much time
                     it takes from the threads that actually work)
@@ -132,6 +136,10 @@
                     By looking at the namespace itself, it contains other stuff as well. See if I can use @ ingroup or something
 
 - @c normal Explain about config files - you can use named_spacer,named.
+
+- @c high explain about common_base()
+
+
 */
 
 }}


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