1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
//
// XMLLayout.cpp
//
// Copyright (C) : 2000 - 2002
// LifeLine Networks BV (www.lifeline.nl). All rights reserved.
// Bastiaan Bakker. All rights reserved.
//
// 2004,2005,2006,2007,2008,2009,2010,2011,2012
// Synchrotron SOLEIL
// L'Orme des Merisiers
// Saint-Aubin - BP 48 - France
//
// This file is part of log4tango.
//
// Log4ango is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Log4tango is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Log4Tango. If not, see <http://www.gnu.org/licenses/>.
#include "PortabilityImpl.hh"
#include <stdio.h>
#include <log4tango/threading/Threading.hh>
#include <log4tango/LoggingEvent.hh>
#include <log4tango/XmlLayout.hh>
namespace log4tango {
XMLLayout::XMLLayout()
{
// no-op
}
XMLLayout::~XMLLayout()
{
// no-op
}
std::string XMLLayout::format (const LoggingEvent& event)
{
std::string buf;
buf.append("<log4j:event logger=\"");
buf.append(event.logger_name);
buf.append("\" timestamp=\"");
double ts_ms = 1000. * event.timestamp.get_seconds();
ts_ms += event.timestamp.get_milliseconds();
char ts_str[32];
::sprintf(ts_str, "%.0f", ts_ms);
buf.append(ts_str);
buf.append("\" level=\"");
buf.append(log4tango::Level::get_name(event.level));
buf.append("\" thread=\"");
buf.append(log4tango::threading::get_thread_id());
buf.append("\">\r\n");
buf.append("<log4j:message><![CDATA[");
#if APPEND_ECAPING_CDATA_IMPLEMENTED
appendEscapingCDATA(buf, event.message);
#else
buf.append(event.message);
#endif
buf.append("]]></log4j:message>\r\n");
buf.append("<log4j:NDC><![CDATA[");
#ifdef LOG4TANGO_HAS_NDC
# if APPEND_ECAPING_CDATA_IMPLEMENTED
appendEscapingCDATA(buf, event.ndc);
# else
buf.append(event.ndc);
# endif
#endif
buf.append("]]></log4j:NDC>\r\n");
buf.append("</log4j:event>\r\n\r\n");
return buf;
}
/*
* Ensures that embeded CDEnd strings (]]>) are handled properly
* within message, NDC and throwable tag text.
*
* @param buf StringBuffer holding the XML data to this point. The
* initial CDStart (<![CDATA[) and final CDEnd (]]>) of the CDATA
* section are the responsibility of the calling method.
* @param str The String that is inserted into an existing CDATA Section within buf.
*/
void XMLLayout::appendEscapingCDATA(std::string buf, std::string str)
{
const std::string CDATA_START("<![CDATA[");
const std::string CDATA_END("]]>");
const std::string CDATA_PSEUDO_END("]]>");
const std::string CDATA_EMBEDED_END = CDATA_END + CDATA_PSEUDO_END + CDATA_START;
const int CDATA_END_LEN = CDATA_END.size();
std::string::size_type end = str.find(CDATA_END);
if (end == std::string::npos) {
buf.append(str);
return;
}
unsigned int start = 0;
while (end != std::string::npos) {
buf.append(str.substr(start, end - start));
buf.append(CDATA_EMBEDED_END);
start = end + CDATA_END_LEN;
if (start < str.size()) {
end = str.find(CDATA_END, start);
} else {
return;
}
}
buf.append(str.substr(start));
}
} // namespace log4tango
|