20130313
[gdash.git] / src / misc / logger.hpp
blob55ed7c2eb16949c53c03e61445337c15799b131f
1 /*
2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #ifndef _GD_LOGGER
18 #define _GD_LOGGER
20 #include "config.h"
22 #include <string>
23 #include <vector>
25 /// A simple class to store an error message.
26 /// Each message has a string and a severity level.
27 class ErrorMessage {
28 public:
29 enum Severity {
30 Debug,
31 Info,
32 Message,
33 Warning,
34 Critical,
35 Error,
38 Severity sev;
39 std::string message;
40 ErrorMessage(Severity sev_, std::string msg_)
42 sev(sev_),
43 message(msg_)
48 /**
49 * A logger class, which is able to record error messages.
51 * This class records error messages, stores them in a list.
52 * One can get the list by calling get_messages(). A const_iterator
53 * is provided to allow the user iterating through the messages.
55 * Each logger object remembers if it stores an error message;
56 * upon deletion, the destructor will check if there were any
57 * messages still unread. If that is the case, an error
58 * message is printed to the console. Currently, a GLib
59 * log handler is also installed by the misc/logger.
61 * The Logger class keeps track of all Logger objects in
62 * existence, using the loggers static variable.
63 * Global error logging functions are provided for simple
64 * usage - they allow callers to use the logging facility
65 * without the need of passing the references to a logger
66 * object.
68 * The global log functions always log errors to the most recently
69 * created Logger object. The scheme to use this thing is:
70 * @code
71 * { // a code block for the logger object
72 * Logger l; // create a logger
74 * ...
75 * ... // do things that use the global gd_message() etc
76 * ...
78 * if (!l.empty()) {
79 * // there were errors reported
80 * for (Logger::ConstIterator it=l.begin(); it!=l.end(); ++it)
81 * std::cout << it->message << std::endl;
82 * l.clear();
83 * }
84 * } // logger is deleted here
85 * @endcode
87 * It is up to the caller to create the logger objects.
88 * It is recommended to create a "global" logger object int the
89 * main() function, which will receive all log messages, when
90 * no other logger objects exist.
91 * @code
92 * int main()
93 * {
94 * Logger global_logger;
95 * ...
96 * ...
97 * ...
98 * global_misc/logger.clear();
99 * }
100 * @endcode
102 class Logger {
103 private:
104 static std::vector<Logger *> loggers;
105 public:
106 typedef std::vector<ErrorMessage> Container;
107 typedef Container::const_iterator ConstIterator;
109 private:
110 bool ignore; ///< if true, all errors reported are ignored
111 bool read; ///< if false, not all messages are seen by the user.
112 Container messages; ///< list of messages
113 std::string context; ///< context which is added to all messages
115 Logger(Logger const&); // deliberately not implemented
116 Logger& operator=(Logger const&); // deliberately not implemented
118 void set_context(std::string const& new_context=std::string());
119 std::string const& get_context() const;
121 public:
122 Logger(bool ignore_=false);
123 ~Logger();
124 void clear();
125 bool empty() const;
126 Container const& get_messages() const;
127 std::string get_messages_in_one_string() const;
128 void log(ErrorMessage::Severity sev, std::string const& message);
130 friend void log(ErrorMessage::Severity sev, std::string const& message);
131 friend bool has_error();
132 friend Logger& get_active_logger();
133 friend class SetLoggerContextForFunction;
137 /* error handling */
138 void log(ErrorMessage::Severity sev, std::string const& message);
139 Logger& get_active_logger();
141 void gd_critical(const char *message);
142 void gd_warning(const char *message);
143 void gd_message(const char *message);
145 void gd_debug(const char *message);
148 /** Set the logger context for the lifetime of the object.
149 * To be used to set the context while inside a function or a statement block:
151 * @code
153 * SetLoggerContextForFunction slc(get_active_logger(), "Reading file");
155 * // Log messages generated here will have the context
157 * } // slc object goes out of scope here, context is set back to original value
158 * @endcode
160 class SetLoggerContextForFunction {
161 Logger &l;
162 std::string orig_context;
163 public:
164 SetLoggerContextForFunction(std::string const& context, Logger &l = get_active_logger())
165 : l(l), orig_context(l.get_context()) {
166 l.set_context(orig_context.empty() ? context : (orig_context + ", " + context));
168 ~SetLoggerContextForFunction() { l.set_context(orig_context); }
172 #endif /* GD_LOGGER */