1 /*
2  *  logging_manager.cpp
3  *
4  *  This file is part of NEST.
5  *
6  *  Copyright (C) 2004 The NEST Initiative
7  *
8  *  NEST is free software: you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation, either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  NEST is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with NEST.  If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #include "logging_manager.h"
24 
25 // C++ includes:
26 #include <cassert>
27 #include <iostream>
28 
29 // Includes from libnestutil:
30 #include "logging_event.h"
31 
32 // Includes from sli:
33 #include "dict.h"
34 #include "dictutils.h"
35 #include "sliexceptions.h"
36 
LoggingManager()37 nest::LoggingManager::LoggingManager()
38   : client_callbacks_()
39   , logging_level_( M_ALL )
40   , dict_miss_is_error_( true )
41 {
42 }
43 
44 void
initialize()45 nest::LoggingManager::initialize()
46 {
47   dict_miss_is_error_ = true;
48 }
49 
50 void
finalize()51 nest::LoggingManager::finalize()
52 {
53 }
54 
55 void
set_status(const DictionaryDatum & dict)56 nest::LoggingManager::set_status( const DictionaryDatum& dict )
57 {
58   updateValue< bool >( dict, names::dict_miss_is_error, dict_miss_is_error_ );
59 }
60 
61 void
get_status(DictionaryDatum & dict)62 nest::LoggingManager::get_status( DictionaryDatum& dict )
63 {
64   ( *dict )[ names::dict_miss_is_error ] = dict_miss_is_error_;
65 }
66 
67 
68 void
register_logging_client(const deliver_logging_event_ptr callback)69 nest::LoggingManager::register_logging_client( const deliver_logging_event_ptr callback )
70 {
71   assert( callback != 0 );
72 
73   client_callbacks_.push_back( callback );
74 }
75 
76 void
deliver_logging_event_(const LoggingEvent & event) const77 nest::LoggingManager::deliver_logging_event_( const LoggingEvent& event ) const
78 {
79   if ( client_callbacks_.empty() )
80   {
81     default_logging_callback_( event );
82   }
83   for ( const auto& client_callback : client_callbacks_ )
84   {
85     client_callback( event );
86   }
87 }
88 
89 void
default_logging_callback_(const LoggingEvent & event) const90 nest::LoggingManager::default_logging_callback_( const LoggingEvent& event ) const
91 {
92   std::ostream* out;
93 
94   if ( event.severity < M_WARNING )
95   {
96     out = &std::cout;
97   }
98   else
99   {
100     out = &std::cerr;
101   }
102 
103   *out << event << std::endl;
104 }
105 
106 void
publish_log(const nest::severity_t s,const std::string & fctn,const std::string & msg,const std::string & file,const size_t line) const107 nest::LoggingManager::publish_log( const nest::severity_t s,
108   const std::string& fctn,
109   const std::string& msg,
110   const std::string& file,
111   const size_t line ) const
112 {
113   if ( s >= logging_level_ )
114   {
115     LoggingEvent e( s, fctn, msg, file, line );
116 #pragma omp critical( logging )
117     {
118       deliver_logging_event_( e );
119     }
120   }
121 }
122 
123 void
all_entries_accessed(const Dictionary & d,const std::string & where,const std::string & msg,const std::string & file,const size_t line) const124 nest::LoggingManager::all_entries_accessed( const Dictionary& d,
125   const std::string& where,
126   const std::string& msg,
127   const std::string& file,
128   const size_t line ) const
129 {
130   std::string missed;
131   if ( not d.all_accessed( missed ) )
132   {
133     if ( dict_miss_is_error_ )
134     {
135       throw UnaccessedDictionaryEntry( missed );
136     }
137     else
138     {
139       publish_log( M_WARNING, where, msg + missed, file, line );
140     }
141   }
142 }
143 
144 void
all_entries_accessed(const Dictionary & d,const std::string & where,const std::string & msg1,const std::string & msg2,const std::string & file,const size_t line) const145 nest::LoggingManager::all_entries_accessed( const Dictionary& d,
146   const std::string& where,
147   const std::string& msg1,
148   const std::string& msg2,
149   const std::string& file,
150   const size_t line ) const
151 {
152   std::string missed;
153   if ( not d.all_accessed( missed ) )
154   {
155     if ( dict_miss_is_error_ )
156     {
157       throw UnaccessedDictionaryEntry( missed + "\n" + msg2 );
158     }
159     else
160     {
161       publish_log( M_WARNING, where, msg1 + missed + "\n" + msg2, file, line );
162     }
163   }
164 }
165 
166 void
set_logging_level(const nest::severity_t level)167 nest::LoggingManager::set_logging_level( const nest::severity_t level )
168 {
169   assert( level >= M_ALL );
170   assert( level <= M_QUIET );
171 
172   logging_level_ = level;
173 }
174 
175 nest::severity_t
get_logging_level() const176 nest::LoggingManager::get_logging_level() const
177 {
178   return logging_level_;
179 }
180