• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *          Copyright Andrey Semashev 2007 - 2015.
3  * Distributed under the Boost Software License, Version 1.0.
4  *    (See accompanying file LICENSE_1_0.txt or copy at
5  *          http://www.boost.org/LICENSE_1_0.txt)
6  */
7 /*!
8  * \file   main.cpp
9  * \author Andrey Semashev
10  * \date   16.11.2008
11  *
12  * \brief  An example of logging into Windows event log.
13  *
14  * The example shows the basic usage of the Windows NT event log backend.
15  * The code defines custom severity levels, initializes the sink and a couple of
16  * attributes to test with, and writes several records at different levels.
17  * As a result the written records should appear in the Application log, and
18  * should be displayed correctly with the Windows event log viewer.
19  */
20 
21 #include <stdexcept>
22 #include <string>
23 #include <iostream>
24 #include <boost/smart_ptr/shared_ptr.hpp>
25 #include <boost/date_time/posix_time/posix_time_types.hpp>
26 
27 #include <boost/log/common.hpp>
28 #include <boost/log/attributes.hpp>
29 #include <boost/log/expressions.hpp>
30 #include <boost/log/sinks/sync_frontend.hpp>
31 #include <boost/log/sinks/event_log_backend.hpp>
32 
33 #if !defined(WIN32_LEAN_AND_MEAN)
34 #define WIN32_LEAN_AND_MEAN
35 #endif
36 
37 #include <windows.h>
38 #include "event_log_messages.h"
39 
40 namespace logging = boost::log;
41 namespace attrs = boost::log::attributes;
42 namespace src = boost::log::sources;
43 namespace sinks = boost::log::sinks;
44 namespace expr = boost::log::expressions;
45 namespace keywords = boost::log::keywords;
46 
47 //[ example_sinks_event_log_severity
48 // Define application-specific severity levels
49 enum severity_level
50 {
51     normal,
52     warning,
53     error
54 };
55 //]
56 
init_logging()57 void init_logging()
58 {
59     //[ example_sinks_event_log_create_backend
60     // Create an event log sink
61     boost::shared_ptr< sinks::event_log_backend > backend(
62         new sinks::event_log_backend((
63             keywords::message_file = "%SystemDir%\\event_log_messages.dll",
64             keywords::log_name = "My Application",
65             keywords::log_source = "My Source"
66         ))
67     );
68     //]
69 
70     //[ example_sinks_event_log_event_composer
71     // Create an event composer. It is initialized with the event identifier mapping.
72     sinks::event_log::event_composer composer(
73         sinks::event_log::direct_event_id_mapping< int >("EventID"));
74 
75     // For each event described in the message file, set up the insertion string formatters
76     composer[LOW_DISK_SPACE_MSG]
77         // the first placeholder in the message
78         // will be replaced with contents of the "Drive" attribute
79         % expr::attr< std::string >("Drive")
80         // the second placeholder in the message
81         // will be replaced with contents of the "Size" attribute
82         % expr::attr< boost::uintmax_t >("Size");
83 
84     composer[DEVICE_INACCESSIBLE_MSG]
85         % expr::attr< std::string >("Drive");
86 
87     composer[SUCCEEDED_MSG]
88         % expr::attr< unsigned int >("Duration");
89 
90     // Then put the composer to the backend
91     backend->set_event_composer(composer);
92     //]
93 
94     //[ example_sinks_event_log_mappings
95     // We'll have to map our custom levels to the event log event types
96     sinks::event_log::custom_event_type_mapping< severity_level > type_mapping("Severity");
97     type_mapping[normal] = sinks::event_log::make_event_type(MY_SEVERITY_INFO);
98     type_mapping[warning] = sinks::event_log::make_event_type(MY_SEVERITY_WARNING);
99     type_mapping[error] = sinks::event_log::make_event_type(MY_SEVERITY_ERROR);
100 
101     backend->set_event_type_mapper(type_mapping);
102 
103     // Same for event categories.
104     // Usually event categories can be restored by the event identifier.
105     sinks::event_log::custom_event_category_mapping< int > cat_mapping("EventID");
106     cat_mapping[LOW_DISK_SPACE_MSG] = sinks::event_log::make_event_category(MY_CATEGORY_1);
107     cat_mapping[DEVICE_INACCESSIBLE_MSG] = sinks::event_log::make_event_category(MY_CATEGORY_2);
108     cat_mapping[SUCCEEDED_MSG] = sinks::event_log::make_event_category(MY_CATEGORY_3);
109 
110     backend->set_event_category_mapper(cat_mapping);
111     //]
112 
113     //[ example_sinks_event_log_register_sink
114     // Create the frontend for the sink
115     boost::shared_ptr< sinks::synchronous_sink< sinks::event_log_backend > > sink(
116         new sinks::synchronous_sink< sinks::event_log_backend >(backend));
117 
118     // Set up filter to pass only records that have the necessary attribute
119     sink->set_filter(expr::has_attr< int >("EventID"));
120 
121     logging::core::get()->add_sink(sink);
122     //]
123 }
124 
125 //[ example_sinks_event_log_facilities
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(event_logger,src::severity_logger_mt<severity_level>)126 BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(event_logger, src::severity_logger_mt< severity_level >)
127 
128 // The function raises an event of the disk space depletion
129 void announce_low_disk_space(std::string const& drive, boost::uintmax_t size)
130 {
131     BOOST_LOG_SCOPED_THREAD_TAG("EventID", (int)LOW_DISK_SPACE_MSG);
132     BOOST_LOG_SCOPED_THREAD_TAG("Drive", drive);
133     BOOST_LOG_SCOPED_THREAD_TAG("Size", size);
134     // Since this record may get accepted by other sinks,
135     // this message is not completely useless
136     BOOST_LOG_SEV(event_logger::get(), warning) << "Low disk " << drive
137         << " space, " << size << " Mb is recommended";
138 }
139 
140 // The function raises an event of inaccessible disk drive
announce_device_inaccessible(std::string const & drive)141 void announce_device_inaccessible(std::string const& drive)
142 {
143     BOOST_LOG_SCOPED_THREAD_TAG("EventID", (int)DEVICE_INACCESSIBLE_MSG);
144     BOOST_LOG_SCOPED_THREAD_TAG("Drive", drive);
145     BOOST_LOG_SEV(event_logger::get(), error) << "Cannot access drive " << drive;
146 }
147 
148 // The structure is an activity guard that will emit an event upon the activity completion
149 struct activity_guard
150 {
activity_guardactivity_guard151     activity_guard()
152     {
153         // Add a stop watch attribute to measure the activity duration
154         m_it = event_logger::get().add_attribute("Duration", attrs::timer()).first;
155     }
~activity_guardactivity_guard156     ~activity_guard()
157     {
158         BOOST_LOG_SCOPED_THREAD_TAG("EventID", (int)SUCCEEDED_MSG);
159         BOOST_LOG_SEV(event_logger::get(), normal) << "Activity ended";
160         event_logger::get().remove_attribute(m_it);
161     }
162 
163 private:
164     logging::attribute_set::iterator m_it;
165 };
166 //]
167 
main(int argc,char * argv[])168 int main(int argc, char* argv[])
169 {
170     try
171     {
172         // Initialize the library
173         init_logging();
174 
175         // Make some events
176         {
177             activity_guard activity;
178 
179             announce_low_disk_space("C:", 2 * 1024 * 1024);
180             announce_device_inaccessible("D:");
181         }
182 
183         return 0;
184     }
185     catch (std::exception& e)
186     {
187         std::cout << "FAILURE: " << e.what() << std::endl;
188         return 1;
189     }
190 }
191