libassa 3.5.0
|
00001 // -*- c++ -*- 00002 //------------------------------------------------------------------------------ 00003 // Logger.cpp 00004 //------------------------------------------------------------------------------ 00005 // $Id: Logger.cpp,v 1.7 2006/07/20 02:30:54 vlg Exp $ 00006 //------------------------------------------------------------------------------ 00007 // Copyright (c) 2001,2005 by Vladislav Grinchenko 00008 // 00009 // This library is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU Library General Public 00011 // License as published by the Free Software Foundation; either 00012 // version 2 of the License, or (at your option) any later version. 00013 //------------------------------------------------------------------------------ 00014 00015 #include <stdarg.h> 00016 00017 #include <iostream> // for WIN32 hacking 00018 00019 #include "assa/Connector.h" 00020 #include "assa/INETAddress.h" 00021 #include "assa/IPv4Socket.h" 00022 #include "assa/FileLogger.h" 00023 #include "assa/StdOutLogger.h" 00024 #include "assa/RemoteLogger.h" 00025 #include "assa/AutoPtr.h" 00026 #include "assa/Logger.h" 00027 00028 using namespace ASSA; 00029 00030 ASSA_DECL_SINGLETON(Logger); 00031 00032 // Internal storage 00033 static const int TMPBUF_SZ = 4096; 00034 00035 // Logger's member functions 00036 00037 int 00038 Logger:: 00039 log_close (void) 00040 { 00041 int ret = 0; 00042 00043 if (m_impl) { 00044 ret = m_impl->log_close (); 00045 delete m_impl; 00046 m_impl = 0; 00047 } 00048 return ret; 00049 } 00050 00051 int 00052 Logger:: 00053 log_open (u_long groups_) 00054 { 00055 if (m_impl != NULL) { 00056 std::cerr << "Logger::log_open - Implementation already exist" 00057 << std::endl; 00058 return -1; 00059 } 00060 m_impl = new StdOutLogger; 00061 return m_impl->log_open (groups_); 00062 } 00063 00064 int 00065 Logger:: 00066 log_open (const char* logfname_, u_long groups_, u_long maxsize_) 00067 { 00068 if (m_impl != NULL) { 00069 return -1; 00070 } 00071 m_impl = new FileLogger; 00072 return m_impl->log_open (logfname_, groups_, maxsize_); 00073 } 00074 00075 int 00076 Logger:: 00077 log_open (const std::string& logsvraddr_, 00078 const char* logfname_, 00079 u_long groups_, 00080 u_long maxsize_, 00081 Reactor* reactor_) 00082 { 00083 { 00084 TimeVal tv (10.0); 00085 INETAddress addr (logsvraddr_.c_str ()); 00086 if (addr.bad ()) { 00087 return -1; 00088 } 00089 00090 Connector <RemoteLogger, IPv4Socket> log_connector; 00091 AutoPtr<RemoteLogger> lsp (new RemoteLogger); 00092 log_connector.open (tv); 00093 00094 if (log_connector.connect (lsp.get (), addr) < 0) { 00095 delete m_impl; 00096 m_impl = NULL; 00097 return -1; 00098 } 00099 00100 m_impl = lsp.release (); 00101 } 00102 int ret = m_impl->log_open (m_app_name.c_str (), logfname_, 00103 groups_, maxsize_, reactor_); 00104 return ret; 00105 } 00106 00142 int 00143 Logger:: 00144 log_msg (u_long g_, const char* fmt_, ...) 00145 { 00146 va_list ap; 00147 va_list ap2; 00148 string empty_str; 00149 size_t expected_sz = 0; 00150 00151 static char tmpbuf[TMPBUF_SZ]; 00152 char* bufp = tmpbuf; 00153 int len = TMPBUF_SZ; 00154 int ret; 00155 00156 if (m_impl == NULL) { 00157 return -1; 00158 } 00159 00162 #if defined(WIN32) 00163 00164 va_copy (ap2, ap); 00165 ret = vsnprintf (bufp, len-1, fmt_, ap2); 00166 va_end (ap2); 00167 00168 if (ret == -1 || ret >= len) 00169 { 00170 len *= 2; 00171 bufp = new char [len]; 00172 while (1) { 00173 va_copy (ap2, ap); 00174 ret = vsnprintf (bufp, len-1, fmt_, ap2); 00175 va_end (ap2); 00176 if (ret > -1 && ret < len) { 00177 delete [] bufp; 00178 break; 00179 } 00180 len *= 2; 00181 delete [] bufp; 00182 bufp = new char [len]; 00183 // std::cout << "Logger::log_func : malloc(" << len << ")\n" 00184 // << std::flush; 00185 } 00186 } 00187 00188 #else /* POSIX, C99 compliant */ 00189 00190 char c; 00191 va_start (ap, fmt_); 00192 ret = ::vsnprintf (&c, 1, fmt_, ap); 00193 va_end (ap); 00194 00195 #endif 00196 00197 expected_sz = ret + 1; 00198 00199 // std::cout << "Logger::log_func : expected_sz = " 00200 // << expected_sz << "\n" << std::flush; 00201 00204 va_start (ap, fmt_); 00205 ret = m_impl->log_msg (static_cast<Group> (g_), 00206 m_context.size (), 00207 m_context.size () ? m_context.top () : empty_str, 00208 expected_sz, 00209 fmt_, 00210 ap); 00211 va_end (ap); 00212 00225 return ret; 00226 } 00227 00228 int 00229 Logger:: 00230 log_func (u_long g_, marker_t type_) 00231 { 00232 std::string empty_str; 00233 00234 if (m_impl == NULL) { 00235 return -1; 00236 } 00237 00238 return m_impl->log_func (static_cast<Group> (g_), 00239 m_context.size (), 00240 m_context.size () ? m_context.top () : empty_str, 00241 type_); 00242 } 00243 00244 00245