00001 // 00002 // $Id: log.cpp 2 2008-03-01 20:58:50Z kulibali $ 00003 // 00004 // Copyright (c) 2008, The Periapsis Project. All rights reserved. 00005 // 00006 // Redistribution and use in source and binary forms, with or without 00007 // modification, are permitted provided that the following conditions are 00008 // met: 00009 // 00010 // * Redistributions of source code must retain the above copyright notice, 00011 // this list of conditions and the following disclaimer. 00012 // 00013 // * 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 // * Neither the name of the The Periapsis Project nor the names of its 00018 // contributors may be used to endorse or promote products derived from 00019 // this software without specific prior written permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00022 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00023 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00024 // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 00025 // OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00026 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00027 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00033 00034 #include "data/log.hpp" 00035 #include "data/fstream.hpp" 00036 00037 00038 #ifdef WIN32 00039 // forward declaration of utility function to print to windows debug output 00040 static void win32_debug_print(const wchar_t *str); 00041 #endif 00042 00043 00044 00045 namespace gsgl 00046 { 00047 00048 using namespace io; 00049 00050 namespace data 00051 { 00052 00053 global_register<log_target> *logger::instance = 0; 00054 int logger::global_log_level = logger::LOG_LEVEL_BASIC; 00055 00056 00057 // 00058 00059 logger::logger() 00060 : global_register<log_target>() 00061 { 00062 #ifdef DEBUG 00063 #ifdef WIN32 00064 win32_debug_print(L"logger: creating global logger\n"); 00065 #else 00066 io::ft_stream::out << L"logger: creating global logger\n"; 00067 #endif 00068 #endif 00069 } // logger::logger() 00070 00071 00072 logger::~logger() 00073 { 00074 #ifdef DEBUG 00075 #ifdef WIN32 00076 win32_debug_print(L"logger: destroying global logger\n"); 00077 #else 00078 io::ft_stream::out << L"logger: destroying global logger\n"; 00079 #endif 00080 #endif 00081 } // logger::~logger() 00082 00083 00084 00085 void logger::print_line(int log_level, const gsgl::string & msg) 00086 { 00087 if (log_level <= global_log_level) 00088 { 00089 for (list<log_target *>::iterator i = registered_resources.iter(); i.is_valid(); ++i) 00090 (*i)->print_line(msg); 00091 } 00092 } // logger::print_line() 00093 00094 00095 void logger::set_global_log_level(int new_log_level) 00096 { 00097 global_log_level = new_log_level; 00098 } // logger::set_global_log_level() 00099 00100 00101 logger *logger::global_instance() 00102 { 00103 logger *temp = dynamic_cast<logger *>(singleton<global_register<log_target> >::global_instance()); 00104 if (!temp) 00105 temp = new logger(); 00106 return temp; 00107 } // logger::global_instance() 00108 00109 00110 ////////////////////////////////////////// 00111 00112 log_target::log_target() 00113 { 00114 logger::global_instance()->register_resource(this); 00115 } // log_target::log_target() 00116 00117 00118 log_target::~log_target() 00119 { 00120 logger::global_instance()->unregister_resource(this); 00121 } // log_target::~log_target() 00122 00123 00124 ////////////////////////////////////////// 00125 00126 file_log_target::file_log_target(const gsgl::string & fname) 00127 : log_target(), f(new ft_stream(fname, io::FILE_OPEN_WRITE)) 00128 { 00129 #ifdef DEBUG 00130 string msg = string::format(L"file_log_target: creating new log target on %ls\n", fname.w_string()); 00131 00132 #ifdef WIN32 00133 win32_debug_print(msg.w_string()); 00134 #else 00135 io::ft_stream::out << msg; 00136 #endif 00137 #endif 00138 } // file_log_target::file_log_target() 00139 00140 00141 file_log_target::~file_log_target() 00142 { 00143 string msg = string::format(L"file_log_target: destroying log target on %ls\n", f->get_fname().w_string()); 00144 #ifdef DEBUG 00145 #ifdef WIN32 00146 win32_debug_print(msg.w_string()); 00147 #else 00148 io::ft_stream::out << msg; 00149 #endif 00150 #endif 00151 00152 delete f; 00153 } // file_log_target::~file_log_target() 00154 00155 00156 void file_log_target::print_line(const string & msg) 00157 { 00158 *f << msg << L"\n"; 00159 } // file_log_target::print_line() 00160 00161 00162 ////////////////////////////////////////// 00163 00164 debug_log_target *debug_log_target::instance; 00165 00166 00167 debug_log_target::debug_log_target() 00168 : singleton<debug_log_target>(), log_target() 00169 { 00170 #ifdef DEBUG 00171 #ifdef WIN32 00172 win32_debug_print(L"debug_log_target: creating debug log target\n"); 00173 #else 00174 io::ft_stream::out << L"debug_log_target: creating debug log target"); 00175 #endif 00176 #endif 00177 } // debug_log_target::debug_log_target() 00178 00179 00180 debug_log_target::~debug_log_target() 00181 { 00182 #ifdef DEBUG 00183 #ifdef WIN32 00184 win32_debug_print(L"debug_log_target: destroying debug log target\n"); 00185 #else 00186 io::ft_stream::out << L"debug_log_target: destroying debug log target"); 00187 #endif 00188 #endif 00189 } // debug_log_target::~debug_log_target() 00190 00191 00192 void debug_log_target::print_line(const string & msg) 00193 { 00194 #ifdef WIN32 00195 string msg_ln(msg); 00196 msg_ln += L"\n"; 00197 00198 win32_debug_print(msg_ln.w_string()); 00199 #else 00200 #error Debug log target is not implemented on this platform! 00201 #endif 00202 } // debug_log_target::print_line() 00203 00204 00205 } // namespace data 00206 00207 00208 } // namespace gsgl 00209 00210 00211 #ifdef WIN32 00212 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 00213 #include <windows.h> 00214 00215 static void win32_debug_print(const wchar_t *str) 00216 { 00217 OutputDebugString(str); 00218 } // win32_debug_print() 00219 00220 #endif