// Module: Log4CPLUS // File: socketappender.cxx // Created: 5/2003 // Author: Tad E. Smith // // // Copyright (C) Tad E. Smith All rights reserved. // // This software is published under the terms of the Apache Software // License version 1.1, a copy of which has been included with this // distribution in the LICENSE.APL file. // // $Log: socketappender.cxx,v $ // Revision 1.10 2003/06/29 16:48:25 tcsmith // Modified to support that move of the getLogLog() method into the LogLog // class. // // Revision 1.9 2003/06/23 20:56:43 tcsmith // Modified to support the changes in the spi::InternalLoggingEvent class. // // Revision 1.8 2003/06/13 15:27:48 tcsmith // Modified to support changes to the InternalLoggingEvent. // // Revision 1.7 2003/06/11 22:58:38 tcsmith // Updated to support the changes in the InternalLoggingEvent class. // // Revision 1.6 2003/06/06 17:04:31 tcsmith // Changed the ctor to take a 'const' Properties object. // // Revision 1.5 2003/06/03 20:22:00 tcsmith // Modified the close() method to set "closed = true;". // // Revision 1.4 2003/05/21 22:14:46 tcsmith // Fixed compiler warning: "conversion from 'size_t' to 'int', possible loss // of data". // // Revision 1.3 2003/05/04 17:47:13 tcsmith // Fixed for UNICODE. // // Revision 1.2 2003/05/04 08:40:30 tcsmith // Fixed the readFromBuffer() to properly prepend the ServerName to the NDC. // // Revision 1.1 2003/05/04 07:25:16 tcsmith // Initial version. // #include #include #include #include using namespace std; using namespace log4cplus; using namespace log4cplus::helpers; #define LOG4CPLUS_MESSAGE_VERSION 2 ////////////////////////////////////////////////////////////////////////////// // log4cplus::SocketAppender ctors and dtor ////////////////////////////////////////////////////////////////////////////// log4cplus::SocketAppender::SocketAppender(const log4cplus::tstring& host, int port, const log4cplus::tstring& serverName) : host(host), port(port), serverName(serverName) { openSocket(); } log4cplus::SocketAppender::SocketAppender(const Properties properties) : Appender(properties), port(9998) { host = properties.getProperty( LOG4CPLUS_TEXT("host") ); if(properties.exists( LOG4CPLUS_TEXT("port") )) { tstring tmp = properties.getProperty( LOG4CPLUS_TEXT("port") ); port = atoi(LOG4CPLUS_TSTRING_TO_STRING(tmp).c_str()); } serverName = properties.getProperty( LOG4CPLUS_TEXT("ServerName") ); openSocket(); } log4cplus::SocketAppender::~SocketAppender() { destructorImpl(); } ////////////////////////////////////////////////////////////////////////////// // log4cplus::SocketAppender public methods ////////////////////////////////////////////////////////////////////////////// void log4cplus::SocketAppender::close() { getLogLog().debug(LOG4CPLUS_TEXT("Entering SocketAppender::close()...")); socket.close(); closed = true; } ////////////////////////////////////////////////////////////////////////////// // log4cplus::SocketAppender protected methods ////////////////////////////////////////////////////////////////////////////// void log4cplus::SocketAppender::openSocket() { if(!socket.isOpen()) { socket = Socket(host, port); } } void log4cplus::SocketAppender::append(const spi::InternalLoggingEvent& event) { if(!socket.isOpen()) { openSocket(); if(!socket.isOpen()) { getLogLog().error(LOG4CPLUS_TEXT("SocketAppender::append()- Cannot connect to server")); return; } } SocketBuffer buffer = convertToBuffer(event, serverName); SocketBuffer msgBuffer(LOG4CPLUS_MAX_MESSAGE_SIZE); msgBuffer.appendSize_t(buffer.getSize()); msgBuffer.appendBuffer(buffer); socket.write(msgBuffer); } ///////////////////////////////////////////////////////////////////////////// // namespace log4cplus::helpers methods ///////////////////////////////////////////////////////////////////////////// SocketBuffer log4cplus::helpers::convertToBuffer(const log4cplus::spi::InternalLoggingEvent& event, const log4cplus::tstring& serverName) { SocketBuffer buffer(LOG4CPLUS_MAX_MESSAGE_SIZE - sizeof(unsigned int)); buffer.appendByte(LOG4CPLUS_MESSAGE_VERSION); #ifndef UNICODE buffer.appendByte(1); #else buffer.appendByte(2); #endif buffer.appendString(serverName); buffer.appendString(event.getLoggerName()); buffer.appendInt(event.getLogLevel()); buffer.appendString(event.getNDC()); buffer.appendString(event.getMessage()); buffer.appendString(event.getThread()); buffer.appendInt( static_cast(event.getTimestamp().sec()) ); buffer.appendInt( static_cast(event.getTimestamp().usec()) ); buffer.appendString(event.getFile()); buffer.appendInt(event.getLine()); return buffer; } log4cplus::spi::InternalLoggingEvent log4cplus::helpers::readFromBuffer(SocketBuffer& buffer) { unsigned char msgVersion = buffer.readByte(); if(msgVersion != LOG4CPLUS_MESSAGE_VERSION) { SharedObjectPtr loglog = log4cplus::helpers::LogLog::getLogLog(); loglog->warn(LOG4CPLUS_TEXT("helpers::readFromBuffer() received socket message with an invalid version")); } unsigned char sizeOfChar = buffer.readByte(); tstring serverName = buffer.readString(sizeOfChar); tstring loggerName = buffer.readString(sizeOfChar); LogLevel ll = buffer.readInt(); tstring ndc = buffer.readString(sizeOfChar); if(serverName.length() > 0) { if(ndc.length() == 0) { ndc = serverName; } else { ndc = serverName + LOG4CPLUS_TEXT(" - ") + ndc; } } tstring message = buffer.readString(sizeOfChar); tstring thread = buffer.readString(sizeOfChar); long sec = buffer.readInt(); long usec = buffer.readInt(); tstring file = buffer.readString(sizeOfChar); int line = buffer.readInt(); return log4cplus::spi::InternalLoggingEvent(loggerName, ll, ndc, message, thread, Time(sec, usec), file, line); }