Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "PortabilityImpl.hh"
00010
00011 #include <log4cpp/PatternLayout.hh>
00012 #include <log4cpp/Priority.hh>
00013 #include <log4cpp/NDC.hh>
00014 #include <log4cpp/TimeStamp.hh>
00015 #include <log4cpp/FactoryParams.hh>
00016 #include <memory>
00017 #include <stdlib.h>
00018
00019 #ifdef LOG4CPP_HAVE_SSTREAM
00020 #include <sstream>
00021 #else
00022 #include <strstream>
00023 #endif
00024
00025 #include <iomanip>
00026 #include <ctime>
00027 #include <cmath>
00028 #include "Localtime.hh"
00029
00030 #ifdef LOG4CPP_HAVE_INT64_T
00031 #ifdef LOG4CPP_HAVE_STDINT_H
00032 #include <stdint.h>
00033 #endif // LOG4CPP_HAVE_STDINT_H
00034
00035 #ifdef LOG4CPP_MISSING_INT64_OSTREAM_OP
00036
00037
00038
00039
00040 #include <stdio.h>
00041
00042 std::ostream& operator<<(std::ostream& os, int64_t i) {
00043 char buf[20];
00044 ::sprintf(buf,"%I64d", i);
00045 return os << buf;
00046 }
00047 #endif // LOG4CPP_MISSING_INT64_OSTREAM_OP
00048 #endif // LOG4CPP_HAVE_INT64_T
00049
00050 namespace log4cpp {
00051
00052 struct StringLiteralComponent : public PatternLayout::PatternComponent {
00053 StringLiteralComponent(const std::string& literal) :
00054 _literal(literal) {
00055 }
00056
00057 virtual void append(std::ostringstream& out, const LoggingEvent& event) {
00058 out << _literal;
00059 }
00060
00061 private:
00062 std::string _literal;
00063 };
00064
00065 struct CategoryNameComponent : public PatternLayout::PatternComponent {
00066 CategoryNameComponent(std::string specifier) {
00067 if (specifier == "") {
00068 _precision = -1;
00069 } else {
00070 #ifdef LOG4CPP_HAVE_SSTREAM
00071 std::istringstream s(specifier);
00072 #else
00073 std::istrstream s(specifier.c_str());
00074 #endif
00075 s >> _precision;
00076 }
00077 }
00078
00079 virtual void append(std::ostringstream& out, const LoggingEvent& event) {
00080 if (_precision == -1) {
00081 out << event.categoryName;
00082 } else {
00083 std::string::size_type begin = std::string::npos;
00084 for(int i = 0; i < _precision; i++) {
00085 begin = event.categoryName.rfind('.', begin - 2);
00086 if (begin == std::string::npos) {
00087 begin = 0;
00088 break;
00089 }
00090 begin++;
00091 }
00092 out << event.categoryName.substr(begin);
00093 }
00094 }
00095
00096 private:
00097 int _precision;
00098 };
00099
00100 struct MessageComponent : public PatternLayout::PatternComponent {
00101 virtual void append(std::ostringstream& out, const LoggingEvent& event) {
00102 out << event.message;
00103 }
00104 };
00105
00106 struct NDCComponent : public PatternLayout::PatternComponent {
00107 virtual void append(std::ostringstream& out, const LoggingEvent& event) {
00108 out << event.ndc;
00109 }
00110 };
00111
00112 struct PriorityComponent : public PatternLayout::PatternComponent {
00113 virtual void append(std::ostringstream& out, const LoggingEvent& event) {
00114 out << Priority::getPriorityName(event.priority);
00115 }
00116 };
00117
00118 struct ThreadNameComponent : public PatternLayout::PatternComponent {
00119 virtual void append(std::ostringstream& out, const LoggingEvent& event) {
00120 out << event.threadName;
00121 }
00122 };
00123
00124 struct ProcessorTimeComponent : public PatternLayout::PatternComponent {
00125 virtual void append(std::ostringstream& out, const LoggingEvent& event) {
00126 out << std::clock();
00127 }
00128 };
00129
00130 struct TimeStampComponent : public PatternLayout::PatternComponent {
00131 static const char* const FORMAT_ISO8601;
00132 static const char* const FORMAT_ABSOLUTE;
00133 static const char* const FORMAT_DATE;
00134
00135 TimeStampComponent(std::string timeFormat) {
00136 if ((timeFormat == "") || (timeFormat == "ISO8601")) {
00137 timeFormat = FORMAT_ISO8601;
00138 } else if (timeFormat == "ABSOLUTE") {
00139 timeFormat = FORMAT_ABSOLUTE;
00140 } else if (timeFormat == "DATE") {
00141 timeFormat = FORMAT_DATE;
00142 }
00143
00144 std::string::size_type pos = timeFormat.find("%l");
00145 if (pos == std::string::npos) {
00146
00147
00148 std::string::size_type pos = timeFormat.find("%L");
00149 if (pos == std::string::npos) {
00150 _printMillis = false;
00151 _printMicros = false;
00152 _timeFormat1 = timeFormat;
00153 } else {
00154 _printMillis = false;
00155 _printMicros = true;
00156 _timeFormat1 = timeFormat.substr(0, pos);
00157 _timeFormat2 = timeFormat.substr(pos + 2);
00158 }
00159
00160 } else {
00161 _printMillis = true;
00162 _printMicros = false;
00163 _timeFormat1 = timeFormat.substr(0, pos);
00164 _timeFormat2 = timeFormat.substr(pos + 2);
00165 }
00166 }
00167
00168 virtual void append(std::ostringstream& out, const LoggingEvent& event) {
00169 struct std::tm currentTime;
00170 std::time_t t = event.timeStamp.getSeconds();
00171 localtime(&t, ¤tTime);
00172 char formatted[103];
00173 std::string timeFormat;
00174 if (_printMillis) {
00175 std::ostringstream formatStream;
00176 formatStream << _timeFormat1
00177 << std::setw(3) << std::setfill('0')
00178 << event.timeStamp.getMilliSeconds()
00179 << _timeFormat2;
00180 timeFormat = formatStream.str();
00181 } else if (_printMicros) {
00182 std::ostringstream formatStream;
00183 formatStream << _timeFormat1
00184 << std::setw(6) << std::setfill('0')
00185 << event.timeStamp.getMicroSeconds()
00186 << _timeFormat2;
00187 timeFormat = formatStream.str();
00188 } else {
00189 timeFormat = _timeFormat1;
00190 }
00191 std::strftime(formatted, sizeof(formatted), timeFormat.c_str(), ¤tTime);
00192 out << formatted;
00193 }
00194
00195 private:
00196 std::string _timeFormat1;
00197 std::string _timeFormat2;
00198 bool _printMillis;
00199 bool _printMicros;
00200 };
00201
00202 const char* const TimeStampComponent::FORMAT_ISO8601 = "%Y-%m-%d %H:%M:%S,%l";
00203 const char* const TimeStampComponent::FORMAT_ABSOLUTE = "%H:%M:%S,%l";
00204 const char* const TimeStampComponent::FORMAT_DATE = "%d %b %Y %H:%M:%S,%l";
00205
00206 struct SecondsSinceEpochComponent : public PatternLayout::PatternComponent {
00207 virtual void append(std::ostringstream& out, const LoggingEvent& event) {
00208 out << event.timeStamp.getSeconds();
00209 }
00210 };
00211
00212 struct MillisSinceEpochComponent : public PatternLayout::PatternComponent {
00213 virtual void append(std::ostringstream& out, const LoggingEvent& event) {
00214 #ifdef LOG4CPP_HAVE_INT64_T
00215 int64_t t = event.timeStamp.getSeconds() -
00216 TimeStamp::getStartTime().getSeconds();
00217 t *= 1000;
00218 t += event.timeStamp.getMilliSeconds() -
00219 TimeStamp::getStartTime().getMilliSeconds();
00220
00221 out << t;
00222 #else
00223 double t = event.timeStamp.getSeconds() -
00224 TimeStamp::getStartTime().getSeconds();
00225 t *= 1000;
00226 t += event.timeStamp.getMilliSeconds() -
00227 TimeStamp::getStartTime().getMilliSeconds();
00228
00229 out << std::setiosflags(std::ios::fixed)
00230 << std::setprecision(0) << t;
00231 #endif
00232 }
00233 };
00234
00235 struct FormatModifierComponent : public PatternLayout::PatternComponent {
00236 FormatModifierComponent(PatternLayout::PatternComponent* component,
00237 size_t minWidth, size_t maxWidth, bool alignLeft) :
00238 _component(component) ,
00239 _minWidth(minWidth),
00240 _maxWidth(maxWidth),
00241 _alignLeft(alignLeft) {
00242 }
00243
00244 virtual ~FormatModifierComponent() {
00245 delete _component;
00246 }
00247
00248 virtual void append(std::ostringstream& out, const LoggingEvent& event) {
00249 std::ostringstream s;
00250 _component->append(s, event);
00251 std::string msg = s.str();
00252 if (_maxWidth > 0 && _maxWidth < msg.length()) {
00253 msg.erase(_maxWidth);
00254 }
00255 size_t fillCount = _minWidth - msg.length();
00256 if (_minWidth > msg.length()) {
00257 if (_alignLeft) {
00258 out << msg << std::string(fillCount, ' ');
00259 } else {
00260 out << std::string(fillCount, ' ') << msg;
00261 }
00262 } else {
00263 out << msg;
00264 }
00265 }
00266
00267 private:
00268 PatternLayout::PatternComponent* _component;
00269 size_t _minWidth;
00270 size_t _maxWidth;
00271 bool _alignLeft;
00272 };
00273
00274 const char* PatternLayout::DEFAULT_CONVERSION_PATTERN = "%m%n";
00275 const char* PatternLayout::SIMPLE_CONVERSION_PATTERN = "%p - %m%n";
00276 const char* PatternLayout::BASIC_CONVERSION_PATTERN = "%R %p %c %x: %m%n";
00277 const char* PatternLayout::TTCC_CONVERSION_PATTERN = "%r [%t] %p %c %x - %m%n";
00278
00279 PatternLayout::PatternLayout() {
00280 try {
00281 setConversionPattern(DEFAULT_CONVERSION_PATTERN);
00282 } catch(ConfigureFailure&) {
00283 }
00284 }
00285
00286 PatternLayout::~PatternLayout() {
00287 clearConversionPattern();
00288 }
00289
00290 void PatternLayout::clearConversionPattern() {
00291 for(ComponentVector::const_iterator i = _components.begin();
00292 i != _components.end(); ++i) {
00293 delete (*i);
00294 }
00295 _components.clear();
00296 _conversionPattern = "";
00297 }
00298
00299 void PatternLayout::setConversionPattern(const std::string& conversionPattern) throw(ConfigureFailure) {
00300 #ifdef LOG4CPP_HAVE_SSTREAM
00301 std::istringstream conversionStream(conversionPattern);
00302 #else
00303 std::istrstream conversionStream(conversionPattern.c_str());
00304 #endif
00305 std::string literal;
00306
00307 char ch;
00308 PatternLayout::PatternComponent* component = NULL;
00309 int minWidth = 0;
00310 size_t maxWidth = 0;
00311 clearConversionPattern();
00312 while (conversionStream.get(ch)) {
00313 if (ch == '%') {
00314
00315 {
00316 char ch2;
00317 conversionStream.get(ch2);
00318 if ((ch2 == '-') || ((ch2 >= '0') && (ch2 <= '9'))) {
00319 conversionStream.putback(ch2);
00320 conversionStream >> minWidth;
00321 conversionStream.get(ch2);
00322 }
00323 if (ch2 == '.') {
00324 conversionStream >> maxWidth;
00325 } else {
00326 conversionStream.putback(ch2);
00327 }
00328 }
00329 if (!conversionStream.get(ch)) {
00330 std::ostringstream msg;
00331 msg << "unterminated conversion specifier in '" << conversionPattern << "' at index " << conversionStream.tellg();
00332 throw ConfigureFailure(msg.str());
00333 }
00334 std::string specPostfix = "";
00335
00336 {
00337 char ch2;
00338 if (conversionStream.get(ch2)) {
00339 if (ch2 == '{') {
00340 while(conversionStream.get(ch2) && (ch2 != '}'))
00341 specPostfix += ch2;
00342 } else {
00343 conversionStream.putback(ch2);
00344 }
00345 }
00346 }
00347 switch (ch) {
00348 case '%':
00349 literal += ch;
00350 break;
00351 case 'm':
00352 component = new MessageComponent();
00353 break;
00354 case 'n':
00355 {
00356 std::ostringstream endline;
00357 endline << std::endl;
00358 literal += endline.str();
00359 }
00360 break;
00361 case 'c':
00362 component = new CategoryNameComponent(specPostfix);
00363 break;
00364 case 'd':
00365 component = new TimeStampComponent(specPostfix);
00366 break;
00367 case 'p':
00368 component = new PriorityComponent();
00369 break;
00370 case 'r':
00371 component = new MillisSinceEpochComponent();
00372 break;
00373 case 'R':
00374 component = new SecondsSinceEpochComponent();
00375 break;
00376 case 't':
00377 component = new ThreadNameComponent();
00378 break;
00379 case 'u':
00380 component = new ProcessorTimeComponent();
00381 break;
00382 case 'x':
00383 component = new NDCComponent();
00384 break;
00385 default:
00386 std::ostringstream msg;
00387 msg << "unknown conversion specifier '" << ch << "' in '" << conversionPattern << "' at index " << conversionStream.tellg();
00388 throw ConfigureFailure(msg.str());
00389 }
00390 if (component) {
00391 if (!literal.empty()) {
00392 _components.push_back(new StringLiteralComponent(literal));
00393 literal = "";
00394 }
00395 if ((minWidth != 0) || (maxWidth != 0)) {
00396 component = new FormatModifierComponent(component, ::abs(minWidth), maxWidth, minWidth < 0);
00397 minWidth = maxWidth = 0;
00398 }
00399 _components.push_back(component);
00400 component = NULL;
00401 }
00402 } else {
00403 literal += ch;
00404 }
00405 }
00406 if (!literal.empty()) {
00407 _components.push_back(new StringLiteralComponent(literal));
00408 }
00409
00410 _conversionPattern = conversionPattern;
00411 }
00412
00413 std::string PatternLayout::getConversionPattern() const {
00414 return _conversionPattern;
00415 }
00416
00417 std::string PatternLayout::format(const LoggingEvent& event) {
00418 std::ostringstream message;
00419
00420 for(ComponentVector::const_iterator i = _components.begin();
00421 i != _components.end(); ++i) {
00422 (*i)->append(message, event);
00423 }
00424
00425 return message.str();
00426 }
00427
00428 std::auto_ptr<Layout> create_pattern_layout(const FactoryParams& params)
00429 {
00430 std::string pattern;
00431 params.get_for("pattern layout").optional("pattern", pattern);
00432 std::auto_ptr<Layout> result(new PatternLayout);
00433 PatternLayout* l = static_cast<PatternLayout*>(result.get());
00434 if (pattern.empty() || pattern == "default")
00435 return result;
00436
00437 if (pattern == "simple")
00438 {
00439 l->setConversionPattern(PatternLayout::SIMPLE_CONVERSION_PATTERN);
00440 return result;
00441 }
00442
00443 if (pattern == "basic")
00444 {
00445 l->setConversionPattern(PatternLayout::BASIC_CONVERSION_PATTERN);
00446 return result;
00447 }
00448
00449 if (pattern == "ttcc")
00450 {
00451 l->setConversionPattern(PatternLayout::TTCC_CONVERSION_PATTERN);
00452 return result;
00453 }
00454
00455 l->setConversionPattern(pattern);
00456 return result;
00457 }
00458 }
log4cpp
Author(s): Stephen Roderick, Bastiaan Bakker, Cedric Le Goater, Steve Ostlind, Marcel Harkema, Walter Stroebel, Glenn Scott and Tony Cheung.
autogenerated on Wed Sep 16 2015 10:27:14