1 // ANNA - Anna is Not Nothingness Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // http://redmine.teslayout.com/projects/anna-suite
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
39 #include <anna/core/tracing/Logger.hpp>
40 #include <anna/core/RuntimeException.hpp>
41 #include <anna/core/DataBlock.hpp>
42 #include <anna/core/tracing/TraceLogger.hpp>
43 #include <anna/core/functions.hpp>
47 Logger::Writer* Logger::st_writer = NULL;
48 bool Logger::st_enabled(true);
51 pid_t Logger::st_pid(-1);
55 Logger::Level Logger::st_level(Logger::Debug);
57 Logger::Level Logger::st_level(Logger::Warning);
60 NRMutex Logger::st_mutex;
62 void Logger::initialize(const char* ident)
64 if(st_writer == NULL) {
65 st_writer = new TraceLogger;
66 st_writer->initialize(ident);
70 void Logger::initialize(const char* ident, Writer* writer)
72 if(st_writer == NULL && writer != NULL) {
73 writer->initialize(ident);
78 void Logger::showPID(const bool show)
91 void Logger::write(const Level level, const char* text, const char* fromFile, const int fromLine)
95 if(isActive(level) && st_writer != NULL) {
97 st_writer->do_write(level, "%s (%d) | %s", fromFile, fromLine, text);
99 st_writer->do_write(level, "%s (%d) | pid: %d | %s", fromFile, fromLine, st_pid, text);
104 if(isActive(level) && st_writer != NULL)
105 st_writer->do_write(level, "%s (%d) | thr: 0x%x | %s", fromFile, fromLine, (unsigned int) pthread_self(), text);
110 void Logger::write(const Level level, const char* text, const char* value, const char* fromFile, const int fromLine)
114 if(isActive(level) && st_writer != NULL) {
116 st_writer->do_write(level, "%s (%d) | %s | %s", fromFile, fromLine, text, value);
118 st_writer->do_write(level, "%s (%d) | pid: %d | %s | %s", fromFile, fromLine, st_pid, text, value);
123 if(isActive(level) && st_writer != NULL)
124 st_writer->do_write(level, "%s (%d) | thr: 0x%x | %s | %s", fromFile, fromLine, (unsigned int) pthread_self(), text, value);
129 void Logger::write(const Level level, const char* text, const int value, const char* fromFile, const int fromLine)
133 if(isActive(level) && st_writer != NULL) {
135 st_writer->do_write(level, "%s (%d) | %s | %d (%x)", fromFile, fromLine, text, value, value);
137 st_writer->do_write(level, "%s (%d) | pid: %d | %s | %d (%x)", fromFile, fromLine, st_pid, text, value, value);
142 if(isActive(level) && st_writer != NULL)
143 st_writer->do_write(level, "%s (%d) | thr: 0x%x | %s | %d (%x)", fromFile, fromLine, (unsigned int) pthread_self(), text, value, value);
148 void Logger::write(const Level level, const char* text, const DataBlock& value, const char* fromFile, const int fromLine)
150 if(isActive(level) && st_writer != NULL) {
154 st_writer->do_write(level, "%s (%d) | %s | Data block: %s", fromFile, fromLine, text, functions::asString(value).c_str());
156 st_writer->do_write(level, "%s (%d) | %s | Data block: <fault!>", fromFile, fromLine, text);
162 st_writer->do_write(level, "%s (%d) | thr: 0x%x | %s | Data block: %s", fromFile, fromLine, (unsigned int) pthread_self(), text, functions::asString(value).c_str());
164 st_writer->do_write(level, "%s (%d) | thr: 0x%x | %s | Data block: <fault!>", fromFile, fromLine, (unsigned int) pthread_self(), text);
171 void Logger::disable()
172 throw(RuntimeException) {
178 void Logger::enable()
179 throw(RuntimeException) {
185 Logger::Level Logger::asLevel(const char* stringLevel)
186 throw(RuntimeException) {
188 const char* stringLevel;
191 { "emergency", Emergency }, { "alert", Alert }, { "critical", Critical }, { "error", Error },
192 { "warning", Warning }, { "notice", Notice }, { "information", Information }, { "debug", Debug },
193 { "local0", Local0 }, { "local1", Local1 }, { "local2", Local2 }, { "local3", Local3 },
194 { "local4", Local4 }, { "local5", Local5 }, { "local6", Local6 }, { "local7", Local7 },
195 { NULL, (Level) - 1 }
199 while(values [i].stringLevel != NULL) {
200 if(strcasecmp(stringLevel, values [i].stringLevel) == 0)
206 if(values [i].stringLevel == NULL) {
207 std::string msg = "Level not registered: '";
209 msg += "'. Possible values: ";
211 for(i = 0; values [i].stringLevel != NULL; i ++) {
212 msg += values [i].stringLevel;
216 throw RuntimeException(msg, ANNA_FILE_LOCATION);
219 return values [i].level;
222 const char* Logger::asString(const Level level)
224 static const char* levels [] = {
225 "Emergency", "Alert", "Critical", "Error", "Warning", "Notice", "Information", "Debug"
228 const char* stringLevel;
231 { "Local0", Local0 }, { "Local1", Local1 }, { "Local2", Local2 }, { "Local3", Local3 },
232 { "Local4", Local4 }, { "Local5", Local5 }, { "Local6", Local6 }, { "Local7", Local7 },
233 { NULL, (Level) - 1 }
235 const char* result = NULL;
237 if(level >= Emergency && level <= Debug)
238 result = levels [level];
240 for(int i = 0; values [i].stringLevel != NULL; i ++) {
241 if(level == values [i].level) {
242 result = values [i].stringLevel;
254 Logger::Writer::Writer(const int bufferSize) {
256 a_dataBlock = new DataBlock(true);
257 a_dataBlock->allocate(bufferSize);
258 } catch(Exception&) {
262 Logger::Writer::Writer() {
264 a_dataBlock = new DataBlock(true);
265 a_dataBlock->allocate(1024);
266 } catch(Exception&) {
270 Logger::Writer::~Writer() {
271 Logger::st_writer = NULL;