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
00031
00032
00037 #include "blocxx/BLOCXX_config.h"
00038 #include "blocxx/LogAppender.hpp"
00039 #include "blocxx/String.hpp"
00040 #include "blocxx/Array.hpp"
00041 #include "blocxx/LogMessage.hpp"
00042 #include "blocxx/Logger.hpp"
00043 #include "blocxx/Assertion.hpp"
00044 #include "blocxx/StringBuffer.hpp"
00045 #include "blocxx/NullAppender.hpp"
00046 #ifndef BLOCXX_WIN32
00047 #include "blocxx/SyslogAppender.hpp"
00048 #endif
00049 #include "blocxx/CerrAppender.hpp"
00050 #include "blocxx/FileAppender.hpp"
00051 #include "blocxx/Format.hpp"
00052
00053 namespace BLOCXX_NAMESPACE
00054 {
00055
00057 const StringArray LogAppender::ALL_COMPONENTS(String("*").tokenize());
00058 const StringArray LogAppender::ALL_CATEGORIES(String("*").tokenize());
00059 const String LogAppender::STR_TTCC_MESSAGE_FORMAT("%r [%t] %-5p %c - %m");
00060 const String LogAppender::TYPE_SYSLOG("syslog");
00061 const String LogAppender::TYPE_STDERR("stderr");
00062 const String LogAppender::TYPE_FILE("file");
00063 const String LogAppender::TYPE_NULL("null");
00064
00065
00066
00067 const char* const LogAppender::LOG_1_LOCATION_opt = "log.%1.location";
00068 const char* const LogAppender::LOG_1_MAX_FILE_SIZE_opt = "log.%1.max_file_size";
00069 const char* const LogAppender::LOG_1_MAX_BACKUP_INDEX_opt = "log.%1.max_backup_index";
00070 const char* const LogAppender::LOG_1_FLUSH_opt = "log.%1.flush";
00071 const char* const LogAppender::LOG_1_SYSLOG_IDENTITY_opt = "log.%1.identity";
00072 const char* const LogAppender::LOG_1_SYSLOG_FACILITY_opt = "log.%1.facility";
00073
00075 LogAppender::LogAppender(const StringArray& components, const StringArray& categories, const String& pattern)
00076 : m_components(components.begin(), components.end())
00077 , m_categories(categories.begin(), categories.end())
00078 , m_formatter(pattern)
00079 {
00080 m_allComponents = m_components.count("*") > 0;
00081 m_allCategories = m_categories.count("*") > 0;
00082 }
00083
00085 void
00086 LogAppender::logMessage(const LogMessage& message) const
00087 {
00088 if (componentAndCategoryAreEnabled(message.component, message.category))
00089 {
00090 StringBuffer buf;
00091 m_formatter.formatMessage(message, buf);
00092 doProcessLogMessage(buf.releaseString(), message);
00093 }
00094 }
00095
00097 LogAppender::~LogAppender()
00098 {
00099 }
00100
00102 bool
00103 LogAppender::categoryIsEnabled(const String& category) const
00104 {
00105 return m_allCategories || m_categories.count(category) > 0;
00106 }
00107
00109 bool
00110 LogAppender::componentAndCategoryAreEnabled(const String& component, const String& category) const
00111 {
00112 return (m_allComponents || m_components.count(component) > 0) &&
00113 categoryIsEnabled(category);
00114 }
00115
00117 ELogLevel
00118 LogAppender::getLogLevel() const
00119 {
00120 int nonLevelCategoryCount = m_categories.size() -
00121 m_categories.count(Logger::STR_DEBUG_CATEGORY) -
00122 m_categories.count(Logger::STR_INFO_CATEGORY) -
00123 m_categories.count(Logger::STR_ERROR_CATEGORY) -
00124 m_categories.count(Logger::STR_FATAL_CATEGORY);
00125
00126 if (m_allCategories || nonLevelCategoryCount > 0 || categoryIsEnabled(Logger::STR_DEBUG_CATEGORY))
00127 {
00128 return E_DEBUG_LEVEL;
00129 }
00130 else if (categoryIsEnabled(Logger::STR_INFO_CATEGORY))
00131 {
00132 return E_INFO_LEVEL;
00133 }
00134 else if (categoryIsEnabled(Logger::STR_ERROR_CATEGORY))
00135 {
00136 return E_ERROR_LEVEL;
00137 }
00138 else if (categoryIsEnabled(Logger::STR_FATAL_CATEGORY))
00139 {
00140 return E_FATAL_ERROR_LEVEL;
00141 }
00142 BLOCXX_ASSERTMSG(0, "Internal error. LogAppender unable to determine log level!");
00143 return E_DEBUG_LEVEL;
00144 }
00145
00147 LogAppenderRef
00148 LogAppender::createLogAppender(
00149 const String& name,
00150 const StringArray& components,
00151 const StringArray& categories,
00152 const String& messageFormat,
00153 const String& type,
00154 const LoggerConfigMap& configItems)
00155 {
00156
00157
00158
00159 LogAppenderRef appender;
00160 if (type.empty() || type.equalsIgnoreCase(TYPE_NULL))
00161 {
00162 appender = new NullAppender(components, categories, messageFormat);
00163 }
00164 #ifndef BLOCXX_WIN32
00165 else if ( type == TYPE_SYSLOG )
00166 {
00167 String identity = Logger::getConfigItem(configItems, Format(LOG_1_SYSLOG_IDENTITY_opt, name), BLOCXX_DEFAULT_LOG_1_SYSLOG_IDENTITY);
00168
00169 String facility = Logger::getConfigItem(configItems, Format(LOG_1_SYSLOG_FACILITY_opt, name), BLOCXX_DEFAULT_LOG_1_SYSLOG_FACILITY);
00170
00171 appender = new SyslogAppender(components, categories, messageFormat, identity, facility);
00172 }
00173 #endif
00174 else if (type == TYPE_STDERR || type == "cerr")
00175 {
00176 appender = new CerrAppender(components, categories, messageFormat);
00177 }
00178 else if (type == TYPE_FILE)
00179 {
00180 String configItem = Format(LOG_1_LOCATION_opt, name);
00181
00182 String filename = Logger::getConfigItem(configItems, configItem);
00183
00184 UInt64 maxFileSize(0);
00185 try
00186 {
00187 maxFileSize = Logger::getConfigItem(configItems, Format(LOG_1_MAX_FILE_SIZE_opt, name),
00188 BLOCXX_DEFAULT_LOG_1_MAX_FILE_SIZE).toUInt64();
00189 }
00190 catch (StringConversionException& e)
00191 {
00192 BLOCXX_THROW_ERR_SUBEX(LoggerException,
00193 Format("%1: Invalid config value: %2", LOG_1_MAX_FILE_SIZE_opt, e.getMessage()).c_str(),
00194 Logger::E_INVALID_MAX_FILE_SIZE, e);
00195 }
00196
00197 unsigned int maxBackupIndex(0);
00198 try
00199 {
00200 maxBackupIndex = Logger::getConfigItem(configItems, Format(LOG_1_MAX_BACKUP_INDEX_opt, name),
00201 BLOCXX_DEFAULT_LOG_1_MAX_BACKUP_INDEX).toUnsignedInt();
00202 }
00203 catch (StringConversionException& e)
00204 {
00205 BLOCXX_THROW_ERR_SUBEX(LoggerException,
00206 Format("%1: Invalid config value: %2", LOG_1_MAX_BACKUP_INDEX_opt, e.getMessage()).c_str(),
00207 Logger::E_INVALID_MAX_BACKUP_INDEX, e);
00208 }
00209
00210 bool flushLog = Logger::getConfigItem(configItems, Format(LOG_1_FLUSH_opt, name), BLOCXX_DEFAULT_LOG_1_FLUSH).equalsIgnoreCase("true");
00211
00212 appender = new FileAppender(components, categories, filename.c_str(), messageFormat, maxFileSize, maxBackupIndex, flushLog);
00213 }
00214 else
00215 {
00216 BLOCXX_THROW_ERR(LoggerException, Format("Unknown log type: %1", type).c_str(), Logger::E_UNKNOWN_LOG_APPENDER_TYPE);
00217 }
00218
00219 return appender;
00220 }
00221
00222
00223 }
00224
00225