source: trunk/src/logger.cc @ 9

Last change on this file since 9 was 4, checked in by epyon, 13 years ago
  • library.hh - dynamic library headers
  • logger.hh - logger headers
  • logging.hh - logger definitions and usage functionality
  • library.cc - dynamic library implementation
  • logger.cc - logger implementation
File size: 3.2 KB
Line 
1// Copyright (C) 2011 Kornel Kisielewicz
2// This file is part of NV Libraries.
3// For conditions of distribution and use, see copyright notice in nv.hh
4
5#include "nv/logger.hh"
6
7#include <iostream>
8#include <utility>
9#include <algorithm>
10#include <fstream>
11#include <nv/exception.hh>
12
13using namespace nv;
14
15// log level names
16const char *log_level_names[] =
17{
18        "NONE",
19        "FATAL",
20        "CRITICAL",
21        "ERROR",
22        "WARNING",
23        "NOTICE",
24        "INFO",
25        "INFO",
26        "DEBUG",
27        "DEBUG2",
28        "TRACE"
29};
30
31// helper macro to access log_level_names
32#define NV_LOG_LEVEL_NAME(level) (log_level_names[ (level) / 10 ])
33
34// log function
35void logger::log( log_level level, const std::string& message )
36{
37        // get the iterator to the beginning of the log_sink list
38        log_sink_list::reverse_iterator it = m_log_sinks.rbegin();
39
40        // iterate
41        while ( it != m_log_sinks.rend() )
42        {
43                // if we have a log sink with high enough level...
44                if ( it->first >= level )
45                {
46                        // log and iterate
47                        it->second->log( level, message );
48                }
49                else
50                {
51                        // otherwise return, the list is sorted by log level
52                        return;
53                }
54                ++it;
55        }
56}
57
58// add a new sink
59void logger::add_sink( log_sink* sink, int level )
60{
61        // add a sink
62        m_log_sinks.push_back( std::make_pair( log_level(level), sink ) );
63        // and sort the list (default sort of pairs is by first element)
64        m_log_sinks.sort();
65}
66
67// remove existing sink
68bool logger::remove_sink( log_sink* sink )
69{
70        // get the iterator to the beginning of the log_sink list
71        log_sink_list::iterator it = m_log_sinks.begin();
72
73        // iterate
74        while ( it != m_log_sinks.end() )
75        {
76                // found?
77                if ( it->second == sink )
78                {
79                        // erase and return true to report success
80                        m_log_sinks.erase(it);
81                        return true;
82                }
83                ++it;
84        }
85
86        // not found, return false
87        return false;
88}
89
90// destructor
91logger::~logger()
92{
93        // while we have sinks
94        while ( !m_log_sinks.empty() )
95        {
96                // delete the last one
97                delete m_log_sinks.back().second;
98                // and pop it
99                m_log_sinks.pop_back();
100        }
101}
102
103
104// console logging
105void log_console_sink::log( log_level level, const std::string& message )
106{
107        std::cout << "[" << NV_LOG_LEVEL_NAME(level) << "] " << message << std::endl;
108}
109
110// stream logging
111void log_stream_sink::log( log_level level, const std::string& message )
112{
113        // if flushing is enabled
114        if ( m_flush )
115        {
116                // write and flush using std::endl
117                *m_stream << "[" << NV_LOG_LEVEL_NAME(level) << "] " << message << std::endl;
118        }
119        else
120        {
121                // write and end with "\n" (no flush)
122                *m_stream << "[" << NV_LOG_LEVEL_NAME(level) << "] " << message << "\n";
123        }
124}
125
126// file logging
127log_file_sink::log_file_sink( const std::string file_name, bool flush_always /*= true */ )
128        : log_stream_sink( nullptr, flush_always )
129{
130        // create the stream manually
131        std::ofstream* fstream = new std::ofstream( file_name );
132
133        // check if it's open
134        if ( !fstream->is_open() )
135        {
136                // throw if not open
137                throw runtime_error( "Could not open file \""+file_name+"\" for logging!" );
138        }
139
140        m_stream = fstream;
141}
142
143// file logger destructor
144log_file_sink::~log_file_sink()
145{
146        // close the file
147        dynamic_cast< std::ofstream* >(m_stream)->close();
148        // dispose of the stream
149        delete m_stream;
150}
Note: See TracBrowser for help on using the repository browser.