PLearn 0.1
pl_log.cc
Go to the documentation of this file.
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 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines