5 // Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11 #ifndef SERVICES_LOGGER_SERVICE_HPP
12 #define SERVICES_LOGGER_SERVICE_HPP
14 #include <boost/asio.hpp>
15 #include <boost/thread/thread.hpp>
16 #include <boost/bind.hpp>
17 #include <boost/date_time/posix_time/posix_time.hpp>
18 #include <boost/noncopyable.hpp>
19 #include <boost/scoped_ptr.hpp>
26 /// Service implementation for the logger.
28 : public boost::asio::io_service::service
31 /// The unique service identifier.
32 static boost::asio::io_service::id id;
34 /// The backend implementation of a logger.
37 explicit logger_impl(const std::string& ident) : identifier(ident) {}
38 std::string identifier;
41 /// The type for an implementation of the logger.
42 typedef logger_impl* impl_type;
44 /// Constructor creates a thread to run a private io_service.
45 logger_service(boost::asio::io_service& io_service)
46 : boost::asio::io_service::service(io_service),
48 work_(new boost::asio::io_service::work(work_io_service_)),
49 work_thread_(new boost::thread(
50 boost::bind(&boost::asio::io_service::run, &work_io_service_)))
54 /// Destructor shuts down the private io_service.
57 /// Indicate that we have finished with the private io_service. Its
58 /// io_service::run() function will exit once all other work has completed.
64 /// Destroy all user-defined handler objects owned by the service.
65 void shutdown_service()
69 /// Return a null logger implementation.
70 impl_type null() const
75 /// Create a new logger implementation.
76 void create(impl_type& impl, const std::string& identifier)
78 impl = new logger_impl(identifier);
81 /// Destroy a logger implementation.
82 void destroy(impl_type& impl)
88 /// Set the output file for the logger. The current implementation sets the
89 /// output file for all logger instances, and so the impl parameter is not
90 /// actually needed. It is retained here to illustrate how service functions
91 /// are typically defined.
92 void use_file(impl_type& /*impl*/, const std::string& file)
94 // Pass the work of opening the file to the background thread.
95 work_io_service_.post(boost::bind(
96 &logger_service::use_file_impl, this, file));
100 void log(impl_type& impl, const std::string& message)
102 // Format the text to be logged.
103 std::ostringstream os;
104 os << impl->identifier << ": " << message;
106 // Pass the work of opening the file to the background thread.
107 work_io_service_.post(boost::bind(
108 &logger_service::log_impl, this, os.str()));
112 /// Helper function used to open the output file from within the private
113 /// io_service's thread.
114 void use_file_impl(const std::string& file)
118 ofstream_.open(file.c_str());
121 /// Helper function used to log a message from within the private io_service's
123 void log_impl(const std::string& text)
125 ofstream_ << text << std::endl;
128 /// Private io_service used for performing logging operations.
129 boost::asio::io_service work_io_service_;
131 /// Work for the private io_service to perform. If we do not give the
132 /// io_service some work to do then the io_service::run() function will exit
134 boost::scoped_ptr<boost::asio::io_service::work> work_;
136 /// Thread used for running the work io_service's run loop.
137 boost::scoped_ptr<boost::thread> work_thread_;
139 /// The file to which log messages will be written.
140 std::ofstream ofstream_;
143 } // namespace services
145 #endif // SERVICES_LOGGER_SERVICE_HPP