PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // pl_log.cc 00004 // 00005 // Copyright (C) 2004-2006 Nicolas Chapados 00006 // 00007 // Redistribution and use in source and binary forms, with or without 00008 // modification, are permitted provided that the following conditions are met: 00009 // 00010 // 1. Redistributions of source code must retain the above copyright 00011 // notice, this list of conditions and the following disclaimer. 00012 // 00013 // 2. Redistributions in binary form must reproduce the above copyright 00014 // notice, this list of conditions and the following disclaimer in the 00015 // documentation and/or other materials provided with the distribution. 00016 // 00017 // 3. The name of the authors may not be used to endorse or promote 00018 // products derived from this software without specific prior written 00019 // permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 // 00032 // This file is part of the PLearn library. For more information on the PLearn 00033 // library, go to the PLearn Web site at www.plearn.org 00034 00035 /* ******************************************************* 00036 * $Id: pl_log.cc 6834 2007-04-05 01:35:37Z saintmlx $ 00037 ******************************************************* */ 00038 00039 // Authors: Nicolas Chapados, Christian Dorion 00040 00043 // From C++ stdlib 00044 #include <map> 00045 #include <string> 00046 #include <algorithm> 00047 #include <iterator> 00048 00049 // From FinLearn 00050 #include <plearn/base/stringutils.h> 00051 #include <plearn/io/StringPStreamBuf.h> 00052 #include "pl_log.h" 00053 #include "ServerLogStreamBuf.h" 00054 00055 namespace PLearn { 00056 using namespace std; 00057 00058 00059 //##### Default Plugin Implementation ####################################### 00060 00061 PL_LogPlugin::~PL_LogPlugin() 00062 { } 00063 00064 PStream& PL_LogPluginPStream::getStream( 00065 PStream::mode_t outmode, const string& module_name, int requested_verbosity) 00066 { 00067 m_pstream.setOutMode(outmode); 00068 if (! module_name.empty()) 00069 m_pstream << '[' << module_name << "] "; 00070 return m_pstream; 00071 } 00072 00073 //##### Server Plugin Implementation ####################################### 00074 00075 PStream& PL_LogPluginServer::getStream( 00076 PStream::mode_t outmode, const string& module_name, int requested_verbosity) 00077 { 00078 //gets everything as raw ascii, outputs it in desired format. 00079 //m_pstream.setOutMode(outmode); 00080 m_sstream= new ServerLogStreamBuf(m_pstream, module_name, requested_verbosity); 00081 m_sstream.setOutMode(outmode); 00082 //m_sstream.setOutMode(PStream::raw_ascii); 00083 return m_sstream; 00084 } 00085 00086 00087 00088 00089 00090 //##### LogInterceptorPStreamBuf ############################################ 00091 00095 class LogInterceptorPStreamBuf : public StringPStreamBuf 00096 { 00097 typedef StringPStreamBuf inherited; 00098 00099 public: 00100 LogInterceptorPStreamBuf(PL_LogPluginInterceptor* log_plugin) 00101 : inherited(new string, "w", true /* DO own */), 00102 m_log_plugin(log_plugin), 00103 m_requested_verbosity(-1) 00104 { } 00105 00107 void outputParameters(const string& module_name, int requested_verbosity); 00108 00111 virtual void flush(); 00112 00113 protected: 00114 PL_LogPluginInterceptor* m_log_plugin; 00115 string m_module_name; 00116 int m_requested_verbosity; 00117 }; 00118 00119 void LogInterceptorPStreamBuf::outputParameters(const string& module_name, 00120 int requested_verbosity) 00121 { 00122 m_module_name = module_name; 00123 m_requested_verbosity = requested_verbosity; 00124 } 00125 00126 void LogInterceptorPStreamBuf::flush() 00127 { 00128 PLASSERT( st && m_log_plugin ); 00129 inherited::flush(); 00130 if (! st->empty()) { 00131 m_log_plugin->appendLog(m_module_name, *st); 00132 st->clear(); 00133 } 00134 } 00135 00136 00137 //##### PL_LogPluginInterceptor ############################################# 00138 00139 PL_LogPluginInterceptor::PL_LogPluginInterceptor(const set<string>& intercept_lognames, 00140 PL_LogPlugin* previous) 00141 : m_intercept_lognames(intercept_lognames), 00142 m_previous(previous), 00143 m_streambuf(new LogInterceptorPStreamBuf(this)), 00144 m_pstream(m_streambuf) 00145 { 00146 PLASSERT( m_previous ); 00147 } 00148 00149 00150 PStream& PL_LogPluginInterceptor::getStream( 00151 PStream::mode_t outmode, const string& module_name, int requested_verbosity) 00152 { 00153 // If the module name is not intercepted, hand to previous handler 00154 PLASSERT( m_previous && m_streambuf ); 00155 if (m_intercept_lognames.find(module_name) == m_intercept_lognames.end()) 00156 return m_previous->getStream(outmode, module_name, requested_verbosity); 00157 00158 m_pstream.setOutMode(outmode); 00159 m_streambuf->outputParameters(module_name, requested_verbosity); 00160 m_streambuf->flush(); 00161 return m_pstream; 00162 } 00163 00164 00165 const deque<string>& PL_LogPluginInterceptor::logEntries(const string& logname) const 00166 { 00167 // May be empty -- don't barf 00168 return m_log_entries[logname]; 00169 } 00170 00171 00172 void PL_LogPluginInterceptor::clearLog(const string& logname) 00173 { 00174 if (logname.empty()) 00175 m_log_entries.clear(); 00176 else 00177 m_log_entries[logname].clear(); 00178 } 00179 00180 00181 void PL_LogPluginInterceptor::appendLog(const string& logname, const string& logentry) 00182 { 00183 m_log_entries[logname].push_back(logentry); 00184 } 00185 00186 00187 //##### PL_Log Implementation ############################################### 00188 00189 PL_Log::PL_Log(PP<PL_LogPlugin> plugin) 00190 : runtime_verbosity(VLEVEL_NORMAL), 00191 m_plugin(plugin), 00192 null_stream(get_pnull()), 00193 m_outmode(PStream::raw_ascii), 00194 logger_count(0), 00195 named_logging_kind(NoModules) 00196 { } 00197 00198 00202 PStream& PL_Log::logger(int requested_verbosity) 00203 { 00204 static const string module_name; // Empty string 00205 PLASSERT( m_plugin ); 00206 logger_count++; 00207 if (requested_verbosity <= runtime_verbosity) 00208 return m_plugin->getStream(m_outmode, module_name, requested_verbosity); 00209 else 00210 return null_stream; 00211 } 00212 00213 00217 PStream& PL_Log::namedLogger(const string& module_name, int requested_verbosity) 00218 { 00219 logger_count++; 00220 if (requested_verbosity <= runtime_verbosity && 00221 (named_logging_kind == AllModules || 00222 (named_logging_kind == SomeModules && 00223 enabled_modules.find(module_name) != enabled_modules.end()))) 00224 { 00225 return m_plugin->getStream(m_outmode, module_name, requested_verbosity); 00226 } 00227 00228 return null_stream; 00229 } 00230 00231 00237 void PL_Log::enableNamedLogging(const vector<string>& module_names) 00238 { 00239 enabled_modules.clear(); 00240 named_logging_kind = SomeModules; 00241 for (int i=0, n=int(module_names.size()) ; i<n ; ++i) { 00242 if (module_names[i] == "__ALL__") { 00243 named_logging_kind = AllModules; 00244 break; 00245 } 00246 else if (module_names[i] == "__NONE__") { 00247 named_logging_kind = NoModules; 00248 break; 00249 } 00250 else 00251 enabled_modules.insert(module_names[i]); 00252 } 00253 } 00254 00255 00260 void PL_Log::enableNamedLogging(const string& comma_separated_module_names) 00261 { 00262 vector<string> module_names = split(comma_separated_module_names, 00263 ", \t\n\r"); 00264 enableNamedLogging(module_names); 00265 } 00266 00267 00271 vector<string> PL_Log::namedLogging() const 00272 { 00273 vector<string> r; 00274 if (named_logging_kind == AllModules) 00275 r.push_back("__ALL__"); 00276 else if (named_logging_kind == NoModules) 00277 r.push_back("__NONE__"); 00278 else 00279 copy(enabled_modules.begin(), enabled_modules.end(), back_inserter(r)); 00280 00281 return r; 00282 } 00283 00284 00288 bool PL_Log::loggingEnabled(const string& module_name) const 00289 { 00290 return (named_logging_kind == AllModules || 00291 (named_logging_kind == SomeModules && 00292 enabled_modules.find(module_name) != enabled_modules.end())); 00293 } 00294 00295 00296 PL_Log& PL_Log::instance() 00297 { 00298 static PP<PL_LogPlugin> global_plugin = new PL_LogPluginPStream(get_perr()); 00299 static PL_Log global_logger(global_plugin); 00300 return global_logger; 00301 } 00302 00303 00308 VerbosityLevel PL_Log::vlevelFromString(const string& v) 00309 { 00310 static map<string, VerbosityLevel> _vlevels; 00311 if ( _vlevels.size() == 0 ) 00312 { 00313 _vlevels["VLEVEL_MAND"] = VLEVEL_MAND; 00314 _vlevels["VLEVEL_IMP"] = VLEVEL_IMP; 00315 _vlevels["VLEVEL_NORMAL"] = VLEVEL_NORMAL ; 00316 _vlevels["VLEVEL_DBG"] = VLEVEL_DBG ; 00317 _vlevels["VLEVEL_EXTREME"] = VLEVEL_EXTREME; 00318 } 00319 00320 map<string, VerbosityLevel>::iterator it = _vlevels.find(v); 00321 if ( it != _vlevels.end() ) 00322 return it->second; 00323 return (VerbosityLevel)toint(v); 00324 } 00325 00326 00327 PStream& plsep(PStream& p) 00328 { 00329 return p << plhead(""); 00330 } 00331 00332 00333 PStream& operator<<(PStream& p, PL_Log::Heading heading) 00334 { 00335 // The loggerCount is likely to change in test even if nothing more is 00336 // printed... PyTest dislikes. 00337 // string msg = "##### " + tostring(PL_Log::instance().loggerCount()) 00338 // + (heading.h.size() > 0? (": "+heading.h) : string("")) + " "; 00339 string msg = "##### " + (heading.h.size() > 0? (heading.h + " ") : string("")); 00340 string::size_type rest_length = msg.size() > 70 ? 5 : 75 - msg.size(); 00341 string rest(rest_length,'#'); 00342 return p << endl << (msg + rest) << endl; 00343 } 00344 00345 } // end of namespace PLearn 00346 00347 00348 /* 00349 Local Variables: 00350 mode:c++ 00351 c-basic-offset:4 00352 c-file-style:"stroustrup" 00353 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00354 indent-tabs-mode:nil 00355 fill-column:79 00356 End: 00357 */ 00358 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :