00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00035 #include "OW_config.h"
00036 #include "OW_LogAppender.hpp"
00037 #include "OW_String.hpp"
00038 #include "OW_Array.hpp"
00039 #include "OW_LogMessage.hpp"
00040 #include "OW_Logger.hpp"
00041 #include "OW_Assertion.hpp"
00042 #include "OW_StringBuffer.hpp"
00043 #include "OW_NullAppender.hpp"
00044 #ifndef OW_WIN32
00045 #include "OW_SyslogAppender.hpp"
00046 #endif
00047 #include "OW_CerrAppender.hpp"
00048 #include "OW_FileAppender.hpp"
00049 #include "OW_Format.hpp"
00050 #include "OW_ConfigOpts.hpp"
00051 #include "OW_SortedVectorMap.hpp"
00052 
00053 namespace OW_NAMESPACE
00054 {
00055 
00056 
00058 const StringArray LogAppender::ALL_COMPONENTS(String("*").tokenize());
00059 const StringArray LogAppender::ALL_CATEGORIES(String("*").tokenize());
00060 const String LogAppender::STR_TTCC_MESSAGE_FORMAT("%r [%t] %-5p %c - %m");
00061 const String LogAppender::TYPE_SYSLOG("syslog");
00062 const String LogAppender::TYPE_STDERR("stderr");
00063 const String LogAppender::TYPE_FILE("file");
00064 const String LogAppender::TYPE_NULL("null");
00065 
00066 
00068 LogAppender::LogAppender(const StringArray& components, const StringArray& categories, const String& pattern)
00069    : m_components(components.begin(), components.end())
00070    , m_categories(categories.begin(), categories.end())
00071    , m_formatter(pattern)
00072 {
00073    m_allComponents = m_components.count("*") > 0;
00074    m_allCategories = m_categories.count("*") > 0;
00075 }
00076 
00078 void
00079 LogAppender::logMessage(const LogMessage& message) const
00080 {
00081    if (componentAndCategoryAreEnabled(message.component, message.category))
00082    {
00083       StringBuffer buf;
00084       m_formatter.formatMessage(message, buf);
00085       doProcessLogMessage(buf.releaseString(), message);
00086    }
00087 }
00088 
00090 LogAppender::~LogAppender()
00091 {
00092 }
00093 
00095 bool
00096 LogAppender::categoryIsEnabled(const String& category) const
00097 {
00098    return m_allCategories || m_categories.count(category) > 0;
00099 }
00100 
00102 bool
00103 LogAppender::componentAndCategoryAreEnabled(const String& component, const String& category) const
00104 {
00105    return (m_allComponents || m_components.count(component) > 0) &&
00106       categoryIsEnabled(category);
00107 }
00108 
00110 ELogLevel
00111 LogAppender::getLogLevel() const
00112 {
00113    int nonLevelCategoryCount = m_categories.size() -
00114       m_categories.count(Logger::STR_DEBUG_CATEGORY) -
00115       m_categories.count(Logger::STR_INFO_CATEGORY) -
00116       m_categories.count(Logger::STR_ERROR_CATEGORY) -
00117       m_categories.count(Logger::STR_FATAL_CATEGORY);
00118 
00119    if (m_allCategories || nonLevelCategoryCount > 0 || categoryIsEnabled(Logger::STR_DEBUG_CATEGORY))
00120    {
00121       return E_DEBUG_LEVEL;
00122    }
00123    else if (categoryIsEnabled(Logger::STR_INFO_CATEGORY))
00124    {
00125       return E_INFO_LEVEL;
00126    }
00127    else if (categoryIsEnabled(Logger::STR_ERROR_CATEGORY))
00128    {
00129       return E_ERROR_LEVEL;
00130    }
00131    else if (categoryIsEnabled(Logger::STR_FATAL_CATEGORY))
00132    {
00133       return E_FATAL_ERROR_LEVEL;
00134    }
00135    OW_ASSERTMSG(0, "Internal error. LogAppender unable to determine log level!");
00136    return E_DEBUG_LEVEL;
00137 }
00138 
00140 namespace
00141 {
00142    String
00143    getConfigItem(const LogAppender::ConfigMap& configItems, const String &itemName, const String& defRetVal = "")
00144    {
00145       LogAppender::ConfigMap::const_iterator i = configItems.find(itemName);
00146       if (i != configItems.end())
00147       {
00148          return i->second;
00149       }
00150       else
00151       {
00152          return defRetVal;
00153       }
00154    }
00155 }
00156 
00158 LogAppenderRef
00159 LogAppender::createLogAppender(
00160    const String& name,
00161    const StringArray& components,
00162    const StringArray& categories,
00163    const String& messageFormat,
00164    const String& type,
00165    const ConfigMap& configItems)
00166 {
00167    
00168    
00169 
00170    LogAppenderRef appender;
00171    if (type.empty() || type.equalsIgnoreCase(TYPE_NULL))
00172    {
00173       appender = new NullAppender(components, categories, messageFormat);
00174    }
00175 #ifndef OW_WIN32
00176    else if ( type == TYPE_SYSLOG )
00177    {
00178       appender = new SyslogAppender(components, categories, messageFormat);
00179    }
00180 #endif
00181    else if (type == TYPE_STDERR || type == "cerr")
00182    {
00183       appender = new CerrAppender(components, categories, messageFormat);
00184    }
00185    else if (type == TYPE_FILE)
00186    {
00187       String configItem = Format(ConfigOpts::LOG_1_LOCATION_opt, name);
00188       String filename = getConfigItem(configItems, configItem);
00189       
00190       UInt64 maxFileSize(0);
00191       try
00192       {
00193          maxFileSize = getConfigItem(configItems, Format(ConfigOpts::LOG_1_MAX_FILE_SIZE_opt, name), 
00194             OW_DEFAULT_LOG_1_MAX_FILE_SIZE).toUInt64();
00195       }
00196       catch (StringConversionException& e)
00197       {
00198          OW_THROW_ERR_SUBEX(LoggerException, 
00199             Format("%1: Invalid config value: %2", ConfigOpts::LOG_1_MAX_FILE_SIZE_opt, e.getMessage()).c_str(), 
00200             Logger::E_INVALID_MAX_FILE_SIZE, e);
00201       }
00202       
00203       unsigned int maxBackupIndex(0);
00204       try
00205       {
00206          maxBackupIndex = getConfigItem(configItems, Format(ConfigOpts::LOG_1_MAX_BACKUP_INDEX_opt, name), 
00207             OW_DEFAULT_LOG_1_MAX_BACKUP_INDEX).toUnsignedInt();
00208       }
00209       catch (StringConversionException& e)
00210       {
00211          OW_THROW_ERR_SUBEX(LoggerException, 
00212             Format("%1: Invalid config value: %2", ConfigOpts::LOG_1_MAX_BACKUP_INDEX_opt, e.getMessage()).c_str(), 
00213             Logger::E_INVALID_MAX_BACKUP_INDEX, e);
00214       }
00215 
00216       bool flushLog = getConfigItem(configItems, Format(ConfigOpts::LOG_1_FLUSH_opt, name), OW_DEFAULT_LOG_1_FLUSH).equalsIgnoreCase("true");
00217       
00218       appender = new FileAppender(components, categories, filename.c_str(), messageFormat, maxFileSize, maxBackupIndex, flushLog);
00219    }
00220    else
00221    {
00222       OW_THROW_ERR(LoggerException, Format("Unknown log type: %1", type).c_str(), Logger::E_UNKNOWN_LOG_APPENDER_TYPE);
00223    }
00224 
00225    return appender;
00226 }
00227 
00228 
00229 } 
00230 
00231