| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 <log4cxx/logstring.h> |
| #include <log4cxx/xml/xmllayout.h> |
| #include <log4cxx/spi/loggingevent.h> |
| #include <log4cxx/helpers/optionconverter.h> |
| #include <log4cxx/level.h> |
| #include <log4cxx/helpers/transform.h> |
| #include <log4cxx/helpers/iso8601dateformat.h> |
| #include <log4cxx/helpers/stringhelper.h> |
| #include <log4cxx/helpers/transcoder.h> |
| #include <log4cxx/ndc.h> |
| |
| |
| using namespace log4cxx; |
| using namespace log4cxx::helpers; |
| using namespace log4cxx::spi; |
| using namespace log4cxx::xml; |
| |
| IMPLEMENT_LOG4CXX_OBJECT(XMLLayout) |
| |
| XMLLayout::XMLLayout() |
| : locationInfo(false), properties(false) |
| { |
| } |
| |
| void XMLLayout::setOption(const LogString& option, |
| const LogString& value) |
| { |
| if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("LOCATIONINFO"), LOG4CXX_STR("locationinfo"))) |
| { |
| setLocationInfo(OptionConverter::toBoolean(value, false)); |
| } |
| |
| if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("PROPERTIES"), LOG4CXX_STR("properties"))) |
| { |
| setProperties(OptionConverter::toBoolean(value, false)); |
| } |
| } |
| |
| void XMLLayout::format(LogString& output, |
| const spi::LoggingEventPtr& event, |
| Pool& p) const |
| { |
| output.append(LOG4CXX_STR("<log4j:event logger=\"")); |
| Transform::appendEscapingTags(output, event->getLoggerName()); |
| output.append(LOG4CXX_STR("\" timestamp=\"")); |
| StringHelper::toString(event->getTimeStamp() / 1000L, p, output); |
| output.append(LOG4CXX_STR("\" level=\"")); |
| Transform::appendEscapingTags(output, event->getLevel()->toString()); |
| output.append(LOG4CXX_STR("\" thread=\"")); |
| Transform::appendEscapingTags(output, event->getThreadName()); |
| output.append(LOG4CXX_STR("\">")); |
| output.append(LOG4CXX_EOL); |
| |
| output.append(LOG4CXX_STR("<log4j:message><![CDATA[")); |
| // Append the rendered message. Also make sure to escape any |
| // existing CDATA sections. |
| Transform::appendEscapingCDATA(output, event->getRenderedMessage()); |
| output.append(LOG4CXX_STR("]]></log4j:message>")); |
| output.append(LOG4CXX_EOL); |
| |
| LogString ndc; |
| |
| if (event->getNDC(ndc)) |
| { |
| output.append(LOG4CXX_STR("<log4j:NDC><![CDATA[")); |
| Transform::appendEscapingCDATA(output, ndc); |
| output.append(LOG4CXX_STR("]]></log4j:NDC>")); |
| output.append(LOG4CXX_EOL); |
| } |
| |
| if (locationInfo) |
| { |
| output.append(LOG4CXX_STR("<log4j:locationInfo class=\"")); |
| const LocationInfo& locInfo = event->getLocationInformation(); |
| LOG4CXX_DECODE_CHAR(className, locInfo.getClassName()); |
| Transform::appendEscapingTags(output, className); |
| output.append(LOG4CXX_STR("\" method=\"")); |
| LOG4CXX_DECODE_CHAR(method, locInfo.getMethodName()); |
| Transform::appendEscapingTags(output, method); |
| output.append(LOG4CXX_STR("\" file=\"")); |
| LOG4CXX_DECODE_CHAR(fileName, locInfo.getFileName()); |
| Transform::appendEscapingTags(output, fileName); |
| output.append(LOG4CXX_STR("\" line=\"")); |
| StringHelper::toString(locInfo.getLineNumber(), p, output); |
| output.append(LOG4CXX_STR("\"/>")); |
| output.append(LOG4CXX_EOL); |
| } |
| |
| if (properties) |
| { |
| LoggingEvent::KeySet propertySet(event->getPropertyKeySet()); |
| LoggingEvent::KeySet keySet(event->getMDCKeySet()); |
| |
| if (!(keySet.empty() && propertySet.empty())) |
| { |
| output.append(LOG4CXX_STR("<log4j:properties>")); |
| output.append(LOG4CXX_EOL); |
| |
| for (LoggingEvent::KeySet::const_iterator i = keySet.begin(); |
| i != keySet.end(); |
| i++) |
| { |
| LogString key(*i); |
| LogString value; |
| |
| if (event->getMDC(key, value)) |
| { |
| output.append(LOG4CXX_STR("<log4j:data name=\"")); |
| Transform::appendEscapingTags(output, key); |
| output.append(LOG4CXX_STR("\" value=\"")); |
| Transform::appendEscapingTags(output, value); |
| output.append(LOG4CXX_STR("\"/>")); |
| output.append(LOG4CXX_EOL); |
| } |
| } |
| |
| for (LoggingEvent::KeySet::const_iterator i2 = propertySet.begin(); |
| i2 != propertySet.end(); |
| i2++) |
| { |
| LogString key(*i2); |
| LogString value; |
| |
| if (event->getProperty(key, value)) |
| { |
| output.append(LOG4CXX_STR("<log4j:data name=\"")); |
| Transform::appendEscapingTags(output, key); |
| output.append(LOG4CXX_STR("\" value=\"")); |
| Transform::appendEscapingTags(output, value); |
| output.append(LOG4CXX_STR("\"/>")); |
| output.append(LOG4CXX_EOL); |
| } |
| } |
| |
| output.append(LOG4CXX_STR("</log4j:properties>")); |
| output.append(LOG4CXX_EOL); |
| } |
| } |
| |
| output.append(LOG4CXX_STR("</log4j:event>")); |
| output.append(LOG4CXX_EOL); |
| output.append(LOG4CXX_EOL); |
| } |
| |