00001 /** @file nub/log.cc functions for hierarchical logging */ 00002 00003 /////////////////////////////////////////////////////////////////////// 00004 // 00005 // Copyright (c) 2001-2004 California Institute of Technology 00006 // Copyright (c) 2004-2007 University of Southern California 00007 // Rob Peters <rjpeters at usc dot edu> 00008 // 00009 // created: Wed Jun 20 17:49:28 2001 00010 // commit: $Id: log.cc 8249 2007-04-12 06:03:40Z rjpeters $ 00011 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/nub/log.cc $ 00012 // 00013 // -------------------------------------------------------------------- 00014 // 00015 // This file is part of GroovX. 00016 // [http://ilab.usc.edu/rjpeters/groovx/] 00017 // 00018 // GroovX is free software; you can redistribute it and/or modify it 00019 // under the terms of the GNU General Public License as published by 00020 // the Free Software Foundation; either version 2 of the License, or 00021 // (at your option) any later version. 00022 // 00023 // GroovX is distributed in the hope that it will be useful, but 00024 // WITHOUT ANY WARRANTY; without even the implied warranty of 00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00026 // General Public License for more details. 00027 // 00028 // You should have received a copy of the GNU General Public License 00029 // along with GroovX; if not, write to the Free Software Foundation, 00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 00031 // 00032 /////////////////////////////////////////////////////////////////////// 00033 00034 #ifndef GROOVX_NUB_LOG_CC_UTC20050626084019_DEFINED 00035 #define GROOVX_NUB_LOG_CC_UTC20050626084019_DEFINED 00036 00037 #include "log.h" 00038 00039 #include "nub/object.h" 00040 00041 #include "rutz/fstring.h" 00042 #include "rutz/sfmt.h" 00043 #include "rutz/shared_ptr.h" 00044 #include "rutz/stopwatch.h" 00045 #include "rutz/time.h" 00046 #include "rutz/timeformat.h" 00047 00048 #include <algorithm> 00049 #include <fstream> 00050 #include <functional> 00051 #include <iomanip> 00052 #include <iostream> 00053 #include <vector> 00054 00055 #include "rutz/trace.h" 00056 00057 using rutz::fstring; 00058 00059 namespace 00060 { 00061 struct scope_info 00062 { 00063 scope_info(const fstring& name) : m_name(name), m_timer() {} 00064 00065 fstring m_name; 00066 rutz::stopwatch m_timer; 00067 00068 void print(std::ostream& os, const rutz::time& now) const 00069 { 00070 GVX_TRACE("scope_info::print"); 00071 os << m_name << " @ "; 00072 00073 os.setf(std::ios::showpoint | std::ios::fixed); 00074 00075 os << std::setprecision(3) 00076 << m_timer.elapsed(now).msec() << " | "; 00077 } 00078 }; 00079 00080 std::vector<scope_info> scopes; 00081 rutz::shared_ptr<std::ofstream> s_log_fstream; 00082 bool s_copy_to_stdout = true; 00083 00084 template <class str> 00085 inline void log_impl(std::ostream& os, str msg) 00086 { 00087 const rutz::time now = rutz::time::wall_clock_now(); 00088 00089 for (unsigned int i = 0; i < scopes.size(); ++i) 00090 { 00091 scopes[i].print(os, now); 00092 } 00093 00094 os << msg << std::endl; 00095 } 00096 } 00097 00098 void nub::logging::reset() 00099 { 00100 GVX_TRACE("nub::logging::reset"); 00101 scopes.clear(); 00102 00103 log(rutz::sfmt("log reset %s", 00104 rutz::format_time(rutz::time::wall_clock_now()).c_str())); 00105 } 00106 00107 void nub::logging::add_scope(const fstring& name) 00108 { 00109 GVX_TRACE("nub::logging::add_scope"); 00110 scopes.push_back(scope_info(name)); 00111 } 00112 00113 void nub::logging::remove_scope(const fstring& name) 00114 { 00115 GVX_TRACE("nub::logging::remove_scope"); 00116 for (int i = int(scopes.size()); i > 0; /* decr in loop body */) 00117 { 00118 --i; 00119 if (scopes.at(i).m_name == name) 00120 { 00121 scopes.erase(scopes.begin() + i); 00122 00123 // Return immediately, since this function is intended to remove 00124 // at most one scope from the stack of scopes. 00125 return; 00126 } 00127 } 00128 } 00129 00130 void nub::logging::add_obj_scope(const nub::object& obj) 00131 { 00132 GVX_TRACE("nub::logging::add_obj_scope"); 00133 00134 const fstring scopename(obj.unique_name()); 00135 00136 add_scope(scopename); 00137 00138 log(rutz::sfmt("entering %s", scopename.c_str())); 00139 } 00140 00141 void nub::logging::remove_obj_scope(const nub::object& obj) 00142 { 00143 GVX_TRACE("nub::logging::remove_obj_scope"); 00144 00145 const fstring scopename = obj.unique_name(); 00146 00147 log(rutz::sfmt("leaving %s", scopename.c_str())); 00148 00149 remove_scope(scopename); 00150 } 00151 00152 void nub::logging::set_log_filename(const fstring& filename) 00153 { 00154 GVX_TRACE("nub::logging::set_log_filename"); 00155 00156 rutz::shared_ptr<std::ofstream> newfile 00157 (new std::ofstream(filename.c_str(), std::ios::out | std::ios::app)); 00158 00159 if (newfile->is_open() && newfile->good()) 00160 s_log_fstream.swap(newfile); 00161 } 00162 00163 void nub::logging::copy_to_stdout(bool shouldcopy) 00164 { 00165 GVX_TRACE("nub::logging::copy_to_stdout"); 00166 s_copy_to_stdout = shouldcopy; 00167 } 00168 00169 void nub::log(const char* msg) 00170 { 00171 GVX_TRACE("nub::log"); 00172 if (s_copy_to_stdout) 00173 log_impl(std::cout, msg); 00174 00175 if (s_log_fstream.get() != 0) 00176 log_impl(*s_log_fstream, msg); 00177 } 00178 00179 void nub::log(const fstring& msg) 00180 { 00181 GVX_TRACE("nub::log"); 00182 if (s_copy_to_stdout) 00183 log_impl(std::cout, msg); 00184 00185 if (s_log_fstream.get() != 0) 00186 log_impl(*s_log_fstream, msg); 00187 } 00188 00189 static const char __attribute__((used)) vcid_groovx_nub_log_cc_utc20050626084019[] = "$Id: log.cc 8249 2007-04-12 06:03:40Z rjpeters $ $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/nub/log.cc $"; 00190 #endif // !GROOVX_NUB_LOG_CC_UTC20050626084019_DEFINED