// -*- c++ -*- //------------------------------------------------------------------------------ // RemoteLogger.cpp //------------------------------------------------------------------------------ // $Id: RemoteLogger.cpp,v 1.3 2006/07/26 00:27:32 vlg Exp $ //------------------------------------------------------------------------------ // Copyright (c) 2003 by Vladislav Grinchenko // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version // 2 of the License, or (at your option) any later version. //------------------------------------------------------------------------------ // Date: //------------------------------------------------------------------------------ #include #include #include "Reactor.h" #include "Socket.h" #include "RemoteLogger.h" using namespace ASSA; /******************************************************************************* Class member functions *******************************************************************************/ RemoteLogger:: RemoteLogger () : m_state (closed), m_recursive_call (false) { // no-op } int RemoteLogger:: open () { return 0; } int RemoteLogger:: log_open (const char* appname_, const char* logfname_, u_long groups_, u_long maxsize_, Reactor* reactor_) { if (m_recursive_call) { return 0; } m_recursive_call = true; if (m_state == opened) { return 0; } m_logfname = logfname_; m_groups = groups_; m_reactor = reactor_; m_reactor->registerIOHandler (this, get_stream ().getHandler(), ASSA::READ_EVENT); /** Put stream in a blocking mode. Otherwise, fast clients can override log server. */ get_stream ().turnOptionOff (Socket::nonblocking); /** Send SIGN_ON message to the log server. */ size_t len = sizeof (maxsize_) + Socket::xdr_length (appname_) + Socket::xdr_length (logfname_); /** Header + Body */ get_stream () << 1234567890 << SIGN_ON << len << maxsize_ << appname_ << logfname_ << ASSA::flush; m_state = opened; m_recursive_call = false; return 0; } int RemoteLogger:: log_close (void) { /** Send SIGN_OFF message to the log server and stop data processing. * We are managed by Logger class. */ if (m_state == opened) { m_recursive_call = true; get_stream () << 1234567890 << SIGN_OFF << 0 << ASSA::flush; m_reactor->removeHandler (this, READ_EVENT); m_recursive_call = false; } return 0; } int RemoteLogger:: handle_close (int fd_) { m_state = closed; m_logfname.empty (); return 0; } void RemoteLogger:: log_resync (void) { if (m_state == opened) { m_recursive_call = true; get_stream () << ASSA::flush; m_recursive_call = false; } } int RemoteLogger:: log_msg (Group groups_, size_t indent_level_, const string& func_name_, size_t expected_sz_, const char* fmt_, va_list msg_list_) { if (m_recursive_call) { return 0; } if (m_state == closed) { return -1; } if (!group_enabled (groups_)) { return 0; } std::ostringstream os; add_timestamp (os); indent_func_name (os, func_name_, indent_level_, FUNC_MSG); bool release = false; char* msgbuf_ptr = format_msg (expected_sz_, fmt_, msg_list_, release); if (msgbuf_ptr == NULL) { return -1; // failed to format } os << msgbuf_ptr; if (release) { delete [] msgbuf_ptr; } /** Header + body (preamble;LOG_MSG;length;msg) */ if (get_stream ()) { m_recursive_call = true; Assure_exit (os.str ().length () != 0); get_stream () << 1234567890 << LOG_MSG << Socket::xdr_length (os.str ()) << os.str () << ASSA::flush; m_recursive_call = false; } else { m_state = closed; } return 0; } int RemoteLogger:: log_func (Group groups_, size_t indent_level_, const string& func_name_, marker_t type_) { if (m_recursive_call) { return 0; } if (m_state == closed) { return -1; } if (! group_enabled (groups_)) { return 0; } std::ostringstream os; add_timestamp (os); indent_func_name (os, func_name_, indent_level_, type_); os << ((type_ == FUNC_ENTRY) ? "---v---\n" : "---^---\n"); /** Header + body (preamble;LOG_MSG;length;msg) */ if (get_stream ().good ()) { m_recursive_call = true; get_stream () << 1234567890 << LOG_MSG << Socket::xdr_length (os.str ()) << os.str () << ASSA::flush; m_recursive_call = false; } else { m_state = closed; } return 0; }