Boost logo

Boost-Commit :

From: john.groups_at_[hidden]
Date: 2007-10-17 05:30:23


Author: jtorjo
Date: 2007-10-17 05:30:22 EDT (Wed, 17 Oct 2007)
New Revision: 40111
URL: http://svn.boost.org/trac/boost/changeset/40111

Log:
[logging]
worked on rolling_file (not finished)
worked on optimize - cache_string_several_str (not finished)
Text files modified:
   sandbox/logging/boost/logging/detail/raw_doc/fixme.hpp | 4
   sandbox/logging/boost/logging/detail/raw_doc/thread_safety.hpp | 2
   sandbox/logging/boost/logging/format/destination/file.hpp | 10 --
   sandbox/logging/boost/logging/format/destination/rolling_file.hpp | 129 ++++++++++++++++++++++++++++++++++++++-
   sandbox/logging/boost/logging/format/optimize.hpp | 124 ++++++++++++++++++++++++++++++++++++-
   sandbox/logging/boost/logging/writer/ts_write.hpp | 5
   6 files changed, 252 insertions(+), 22 deletions(-)

Modified: sandbox/logging/boost/logging/detail/raw_doc/fixme.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/fixme.hpp (original)
+++ sandbox/logging/boost/logging/detail/raw_doc/fixme.hpp 2007-10-17 05:30:22 EDT (Wed, 17 Oct 2007)
@@ -20,9 +20,9 @@
 where the code is - boost-sandbox
 
 
-convert_format - also explain that you can convert from str x to y; for instance write_time can actually append the time (instead of prepending it - default)!
-
+convert- also explain that you can convert from str x to y; for instance write_time can actually append the time (instead of prepending it - default)!
 
+formatters - most of them don't need thread-safety, destinations usually need . Explain why/how/when
 
 
 

Modified: sandbox/logging/boost/logging/detail/raw_doc/thread_safety.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/thread_safety.hpp (original)
+++ sandbox/logging/boost/logging/detail/raw_doc/thread_safety.hpp 2007-10-17 05:30:22 EDT (Wed, 17 Oct 2007)
@@ -2,7 +2,7 @@
 
 /**
 @page thread_safety Thread safety
-
+FIXME
 
 */
 

Modified: sandbox/logging/boost/logging/format/destination/file.hpp
==============================================================================
--- sandbox/logging/boost/logging/format/destination/file.hpp (original)
+++ sandbox/logging/boost/logging/format/destination/file.hpp 2007-10-17 05:30:22 EDT (Wed, 17 Oct 2007)
@@ -34,13 +34,9 @@
 struct file_settings {
     file_settings() : m_flush_each_time(true), m_initial_overwrite(false), m_do_append(true) {}
 
- file_settings & flush_each_time() { m_flush_each_time = true; return *this; }
- file_settings & initial_overwrite() { m_initial_overwrite = true; return *this; }
- file_settings & no_append() { m_do_append = false; return *this; }
-
- file_settings & no_flush_each_time() { m_flush_each_time = false; return *this; }
- file_settings & no_initial_overwrite() { m_initial_overwrite = false; return *this; }
- file_settings & append() { m_do_append = true; return *this; }
+ file_settings & flush_each_time(bool flush = true) { m_flush_each_time = flush; return *this; }
+ file_settings & initial_overwrite(bool overwrite = true) { m_initial_overwrite = overwrite; return *this; }
+ file_settings & do_append(bool append) { m_do_append = append; return *this; }
 
     file_settings & extra_open_flags(std::ios_base::open_mode extra_flags) { m_extra_flags = extra_flags; return *this; }
 

Modified: sandbox/logging/boost/logging/format/destination/rolling_file.hpp
==============================================================================
--- sandbox/logging/boost/logging/format/destination/rolling_file.hpp (original)
+++ sandbox/logging/boost/logging/format/destination/rolling_file.hpp 2007-10-17 05:30:22 EDT (Wed, 17 Oct 2007)
@@ -26,18 +26,137 @@
 #include <boost/logging/format/destination/convert_destination.hpp>
 #include <fstream>
 #include <string>
+#include <sstream>
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
 
 namespace boost { namespace logging { namespace destination {
 
 namespace detail {
+ template<class self_type, class type> struct flag_with_self_type {
+ flag(self_type * self, const type& val = type() ) : m_val(val), m_self(self) {}
+ flag(const flag & other) : m_val(other.m_val) {}
+
+ const type & operator()() const { return m_val; }
+ self_type & operator()(const type & val) {
+ m_val = val; return *m_self;
+ }
+
+ // FIXME operator=
+ private:
+ type m_val;
+ self_type * m_self;
+ };
+
+ template<class self_type> struct flag {
+ template<class val_type> struct t : flag_with_type<self_type,val_type> {
+ flag(self_type * self, const val_type& val = val_type() ) : flag_with_type(self,val) {}
+ };
+ };
+}
+
+/**
+ Settings you can pass to the rolling file
+*/
+struct rolling_file_settings {
+ typedef detail::flag<rolling_file_settings> flag;
+
+ rolling_file_settings()
+ : max_size_bytes(this, 1024 * 1024)
+ , file_count(this, 10)
+ , initial_erase(this, false)
+ , start_where_size_not_exceeded(this, true)
+ {}
+
+ /// maximum size in bytes, by default 1Mb
+ flag::t<int> max_size_bytes;
+ /// how many files has a rolling file, by default, 10
+ flag::t<int> file_count;
+ /// if true, it initially erases all files from the rolling file (by default, false)
+ flag::t<bool> initial_erase;
+ /// if true, it starts with the first file that hasn't exceeded the max size;
+ /// otherwise, it starts with the first file (default = true)
+ flag::t<bool> start_where_size_not_exceeded;
+};
+
+namespace detail {
+ template<class convert_dest >
     struct rolling_file_info {
- rolling_file_info (const std::string& name_prefix, file_settings settings) : out(name, open_flags(settings) ), settings(settings) {}
- std::basic_ofstream<char_type> out;
- file_settings settings;
- }
+ rolling_file_info (const std::string& name_prefix, rolling_file_settings flags ) : m_flags(flags), m_cur_idx(0) {
+ namespace fs = boost::filesystem;
+
+ if ( m_flags.initial_erase()) {
+ for ( int idx = 0; idx < m_flags.file_count(); ++idx)
+ if ( fs::exists( file_name(idx) )
+ fs::remove( file_name(idx) );
+ }
+
+ // see what file to start from
+ if ( m_flags.start_where_size_not_exceeded() ) {
+ for ( m_cur_idx = 0; m_cur_idx < m_flags.file_count(); ++m_cur_idx )
+ if ( fs::exists( file_name(m_cur_idx) ) {
+ if ( fs::file_size( file_name(m_cur_idx) < m_flags.max_size_bytes() )
+ // file hasn't reached max size
+ break;
+ }
+ else
+ // file not found, we'll create it now
+ break;
+
+ }
+
+ recreate_file();
+ }
+
+ std::string file_name(int idx) {
+ std::ostringstream out;
+ out << m_name_prefix << "." << (idx+1);
+ return out.str();
+ }
+
+ void recreate_file() {
+ m_out = boost::shared_ptr< std::basic_ofstream<char_type> >(new std::basic_ofstream<char_type>( file_name(m_cur_idx).c_str(),
+ std::ios_base::out | std::ios_base::app);
+ }
+
+ template<class msg_type> void write( const msg_type& msg) {
+ (convert_dest(msg, (*m_out) );
+ if ( m_out->ftellg() > m_flags.max_size_bytes()) {
+ m_cur_idx = (m_cur_idx + 1) % m_flags.file_count();
+ recreate_file();
+ }
+ }
+
+ boost::shared_ptr< std::basic_ofstream<char_type> > m_out;
+ std::string m_name_prefix;
+ rolling_file_settings m_flags;
+ // the index of the current file
+ int m_cur_idx;
+ };
 }
 
-template<class convert_dest = do_convert_destination > struct rolling_file : non_const_context<detail::file_info> {
+/**
+ @brief Writes to multiple files: name_prefix.1, name_prefix.2, ... name_prefix.N, and then restarts from 1.
+
+ We first write to name_prefix.1.
+
+ The log has a max_size. When max_size is reached, we start writing to name_prefix.2. When max_size is reached, we start writing to name_prefix.3.
+ And so on, until we reach name_prefix.N (N = file_count). When that gets fool, we start over, with name_prefix.1.
+*/
+template<class convert_dest = do_convert_destination > struct rolling_file : non_const_context<detail::file_info<convert_dest> > {
+
+ /**
+ Constructs a rolling file
+
+ @param name_prefix the name to be used as prefix for the files
+
+ @param flags [optional] extra settings to pass to the rolling file. See rolling_file_settings.
+ */
+ rolling_file(const std::string & name_prefix, rolling_file_settings flags = rolling_file_settings() ) : non_const_context(name_prefix, flags) {}
+
+ template<class msg_type> void operator()( const msg_type & msg) {
+ non_const_context::context().write(msg);
+ }
 };
 
 

Modified: sandbox/logging/boost/logging/format/optimize.hpp
==============================================================================
--- sandbox/logging/boost/logging/format/optimize.hpp (original)
+++ sandbox/logging/boost/logging/format/optimize.hpp 2007-10-17 05:30:22 EDT (Wed, 17 Oct 2007)
@@ -31,7 +31,7 @@
 namespace optimize {
 
     /**
- It optimizes the formatting for prepending and/or appending strings to the original message
+ @brief Optimizes the formatting for prepending and/or appending strings to the original message
 
         It keeps all the modified message in one string. Useful if some formatter needs to access the whole
         string at once.
@@ -89,6 +89,9 @@
         }
 
 
+ /**
+ @brief pre-pends a string (inserts it at the beginning)
+ */
         void prepend_string(const string_type & str) {
             if ( m_reserve_prepend < (int)str.size()) {
                 int new_reserve_prepend = (int)str.size() + m_grow_size ;
@@ -104,6 +107,9 @@
             m_full_msg_computed = false;
         }
 
+ /**
+ @brief appends a string (inserts it at the end)
+ */
         void append_string(const string_type & str) {
             if ( m_reserve_append < (int)str.size()) {
                 int new_reserve_append = (int)str.size() + m_grow_size ;
@@ -180,11 +186,119 @@
     };
 
     /**
- This gives you 2 extra streams :
- prepend(), and append()
+ @brief This holds 3 strings - one for prepend, one for modification, and one for appending
+
+ When you prepend or append, you can also specify an extra argument - an identifier.
+ This identifier uniquely identifies the prepended or appended message.
     */
- template<class char_type> struct extra_streams {
- // FIXME
+ template<class string_type_ = boost::logging::hold_string_type, class ptr_type = void* > struct cache_string_several_str {
+ private:
+ typedef string_type_ string_type;
+ typedef boost::shared_ptr<string_type> string_ptr;
+
+ struct cached_msg {
+ cached_msg() : prepended(true), id( ptr_type() ) {}
+ cached_msg(const string_type & str, bool prepended) : msg(new string_type(str)), prepended(prepended) {}
+
+ // when within the collection - it can never be null
+ // when within the array - if null, use it from the collection
+ string_ptr msg;
+ // if true, prepended; if false, appended
+ bool prepended;
+ // who wrote the message?
+ ptr_type id;
+ };
+
+ public:
+
+ /**
+ constructs an object
+
+ @param reserve_ [optional, default = 512] When creating the full msg, how much should we reserve?
+ */
+ cache_string_several_str(int reserve_ = 512) : m_full_msg_computed(false) {
+ m_full_msg.reserve(reserve_);
+ }
+
+ /**
+ sets the string with a swap (that is, you pass a non-const refererence, and we do a swap)
+ */
+ void set_string_swap(string_type & msg) {
+ std::swap(msg, m_msg);
+ m_full_msg_computed = false;
+ }
+
+ /**
+ @brief sets the string
+ */
+ void set_string(const string_type & msg) {
+ m_msg = msg;
+ m_full_msg_computed = false;
+ }
+
+ /**
+ @brief pre-pends a string (inserts it at the beginning)
+ */
+ void prepend_string(const string_type & str, ptr_type id = ptr_type() ) {
+ m_full_msg_computed = false;
+ }
+
+ /**
+ @brief pre-pends a string (inserts it at the beginning). The message was already cached
+ */
+ void prepend_string(ptr_type id ) {
+ m_full_msg_computed = false;
+ }
+
+ /**
+ @brief appends a string (inserts it at the end)
+ */
+ void append_string(const string_type & str, ptr_type id = ptr_type() ) {
+ m_full_msg_computed = false;
+ }
+
+ /**
+ @brief appends a string (inserts it at the end). The message was already cached
+ */
+ void append_string(ptr_type id ) {
+ m_full_msg_computed = false;
+ }
+
+ /**
+ @brief computes (if necessary) and returns the full string
+ */
+ const string_type & full_string() const {
+ if ( !m_full_msg_computed) {
+ m_full_msg_computed = true;
+ // FIXME
+ }
+ return m_full_msg;
+ }
+
+ /**
+ @brief computes (if necessary) and returns the full string
+ */
+ operator const string_type&() const { return full_string(); }
+
+
+ /**
+ @brief This restarts writing the messages. Whatever is cached can be used again
+ */
+ void restart() {
+ // ******** whatever msg is in vector that has an id, it to be placed in coll.
+ // FIXME
+ m_full_msg_computed = false;
+ }
+
+ private:
+ string_type m_msg;
+ mutable bool m_full_msg_computed;
+ mutable string_type m_full_msg;
+
+ typedef std::map<ptr_type, cached_msg> coll;
+ typedef std::vector<cached_msg> array;
+ coll m_cached;
+ array m_cur_msg;
     };
 
 }}}

Modified: sandbox/logging/boost/logging/writer/ts_write.hpp
==============================================================================
--- sandbox/logging/boost/logging/writer/ts_write.hpp (original)
+++ sandbox/logging/boost/logging/writer/ts_write.hpp 2007-10-17 05:30:22 EDT (Wed, 17 Oct 2007)
@@ -23,6 +23,7 @@
 
 #include <boost/logging/detail/fwd.hpp>
 #include <boost/logging/detail/forward_constructor.hpp>
+#include <boost/logging/detail/manipulator.hpp>
 
 namespace boost { namespace logging { namespace writer {
 
@@ -69,12 +70,12 @@
 
 @sa on_dedicated_thread
 */
- template<class base_type> struct ts_write : base_type {
+ template<class base_type> struct ts_write : base_type, non_const_context<ts_write_context> {
         BOOST_LOGGING_FORWARD_CONSTRUCTOR(ts_write,base_type)
 
         template<class msg_type> void operator()(msg_type msg) const {
             typedef boost::logging::threading::mutex::scoped_lock lock;
- lock lk(context().cs);
+ lock lk(non_const_context_base::context().cs);
 
             base_type::operator()(msg);
         }


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