// Module: Log4CPLUS // File: appender.cxx // Created: 6/2001 // Author: Tad E. Smith // // // Copyright 2003-2010 Tad E. Smith // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include #include #include #include #include #include using namespace log4cplus; using namespace log4cplus::helpers; using namespace log4cplus::spi; /////////////////////////////////////////////////////////////////////////////// // log4cplus::ErrorHandler dtor /////////////////////////////////////////////////////////////////////////////// ErrorHandler::~ErrorHandler() { } /////////////////////////////////////////////////////////////////////////////// // log4cplus::OnlyOnceErrorHandler public methods /////////////////////////////////////////////////////////////////////////////// void OnlyOnceErrorHandler::error(const log4cplus::tstring& err) { if(firstTime) { getLogLog().error(err); firstTime = false; } } void OnlyOnceErrorHandler::reset() { firstTime = true; } /////////////////////////////////////////////////////////////////////////////// // log4cplus::Appender ctors /////////////////////////////////////////////////////////////////////////////// Appender::Appender() : layout(new SimpleLayout()), name( LOG4CPLUS_TEXT("") ), threshold(NOT_SET_LOG_LEVEL), errorHandler(new OnlyOnceErrorHandler()), closed(false) { } Appender::Appender(const log4cplus::helpers::Properties properties) : layout(new SimpleLayout()), name( LOG4CPLUS_TEXT("") ), threshold(NOT_SET_LOG_LEVEL), errorHandler(new OnlyOnceErrorHandler()), closed(false) { if(properties.exists( LOG4CPLUS_TEXT("layout") )) { log4cplus::tstring factoryName = properties.getProperty( LOG4CPLUS_TEXT("layout") ); LayoutFactory* factory = getLayoutFactoryRegistry().get(factoryName); if(factory == 0) { getLogLog().error( LOG4CPLUS_TEXT("Cannot find LayoutFactory: \"") + factoryName + LOG4CPLUS_TEXT("\"") ); return; } Properties layoutProperties = properties.getPropertySubset( LOG4CPLUS_TEXT("layout.") ); try { std::auto_ptr newLayout(factory->createObject(layoutProperties)); if(newLayout.get() == 0) { getLogLog().error( LOG4CPLUS_TEXT("Failed to create appender: ") + factoryName); } else { layout = newLayout; } } catch(std::exception& e) { getLogLog().error( LOG4CPLUS_TEXT("Error while creating Layout: ") + LOG4CPLUS_C_STR_TO_TSTRING(e.what())); return; } } // Support for appender.Threshold in properties configuration file if(properties.exists(LOG4CPLUS_TEXT("Threshold"))) { tstring tmp = properties.getProperty(LOG4CPLUS_TEXT("Threshold")); tmp = log4cplus::helpers::toUpper(tmp); threshold = log4cplus::getLogLevelManager().fromString(tmp); } // Configure the filters Properties filterProps = properties.getPropertySubset( LOG4CPLUS_TEXT("filters.") ); int filterCount = 0; FilterPtr filterChain; tstring filterName, factoryName; while( filterProps.exists(filterName = convertIntegerToString(++filterCount)) ) { factoryName = filterProps.getProperty(filterName); FilterFactory* factory = getFilterFactoryRegistry().get(factoryName); if(factory == 0) { tstring err = LOG4CPLUS_TEXT("Appender::ctor()- Cannot find FilterFactory: "); getLogLog().error(err + factoryName); continue; } FilterPtr tmp_filter = factory->createObject (filterProps.getPropertySubset(filterName + LOG4CPLUS_TEXT("."))); if(tmp_filter.get() == 0) { tstring err = LOG4CPLUS_TEXT("Appender::ctor()- Failed to create filter: "); getLogLog().error(err + filterName); } if(filterChain.get() == 0) { filterChain = tmp_filter; } else { filterChain->appendFilter(tmp_filter); } } setFilter(filterChain); } Appender::~Appender() { } /////////////////////////////////////////////////////////////////////////////// // log4cplus::Appender public methods /////////////////////////////////////////////////////////////////////////////// void Appender::destructorImpl() { getLogLog().debug( LOG4CPLUS_TEXT("Destroying appender named [") + name + LOG4CPLUS_TEXT("].")); // An appender might be closed then destroyed. There is no // point in closing twice. if(closed) { return; } close(); closed = true; } void Appender::doAppend(const log4cplus::spi::InternalLoggingEvent& event) { LOG4CPLUS_BEGIN_SYNCHRONIZE_ON_MUTEX( access_mutex ) if(closed) { getLogLog().error( LOG4CPLUS_TEXT("Attempted to append to closed appender named [") + name + LOG4CPLUS_TEXT("].")); return; } if(!isAsSevereAsThreshold(event.getLogLevel())) { return; } if(checkFilter(filter.get(), event) == DENY) { return; } append(event); LOG4CPLUS_END_SYNCHRONIZE_ON_MUTEX; } log4cplus::tstring Appender::getName() { return name; } void Appender::setName(const log4cplus::tstring& name_) { this->name = name_; } ErrorHandler* Appender::getErrorHandler() { return errorHandler.get(); } void Appender::setErrorHandler(std::auto_ptr eh) { if(eh.get() == NULL) { // We do not throw exception here since the cause is probably a // bad config file. getLogLog().warn(LOG4CPLUS_TEXT("You have tried to set a null error-handler.")); return; } LOG4CPLUS_BEGIN_SYNCHRONIZE_ON_MUTEX( access_mutex ) this->errorHandler = eh; LOG4CPLUS_END_SYNCHRONIZE_ON_MUTEX; } void Appender::setLayout(std::auto_ptr lo) { LOG4CPLUS_BEGIN_SYNCHRONIZE_ON_MUTEX( access_mutex ) this->layout = lo; LOG4CPLUS_END_SYNCHRONIZE_ON_MUTEX; } Layout* Appender::getLayout() { return layout.get(); }