org.apache.logging.log4j.core.layout.XmlLayout Maven / Gradle / Ivy
Show all versions of log4j-core Show documentation
/*
* 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.
*/
package org.apache.logging.log4j.core.layout;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.Node;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
import org.apache.logging.log4j.core.jackson.XmlConstants;
import org.apache.logging.log4j.core.util.KeyValuePair;
/**
* Appends a series of {@code event} elements as defined in the log4j.dtd.
*
* Complete well-formed XML vs. fragment XML
*
* If you configure {@code complete="true"}, the appender outputs a well-formed XML document where the default namespace
* is the log4j namespace {@value XmlConstants#XML_NAMESPACE}. By default, with {@code complete="false"}, you should
* include the output as an external entity in a separate file to form a well-formed XML document.
*
*
* If {@code complete="false"}, the appender does not write the XML processing instruction and the root element.
*
* Encoding
*
* Appenders using this layout should have their {@code charset} set to {@code UTF-8} or {@code UTF-16}, otherwise
* events containing non-ASCII characters could result in corrupted log files.
*
* Pretty vs. compact XML
*
* By default, the XML layout is not compact (compact = not "pretty") with {@code compact="false"}, which means the
* appender uses end-of-line characters and indents lines to format the XML. If {@code compact="true"}, then no
* end-of-line or indentation is used. Message content may contain, of course, end-of-lines.
*
* Additional Fields
*
* This property allows addition of custom fields into generated JSON.
* {@code } inserts {@code bar } directly
* into XML output. Supports Lookup expressions.
*
*/
@Plugin(name = "XmlLayout", category = Node.CATEGORY, elementType = Layout.ELEMENT_TYPE, printObject = true)
public final class XmlLayout extends AbstractJacksonLayout {
private static final String ROOT_TAG = "Events";
public static class Builder> extends AbstractJacksonLayout.Builder
implements org.apache.logging.log4j.core.util.Builder {
public Builder() {
super();
setCharset(StandardCharsets.UTF_8);
}
@Override
public XmlLayout build() {
return new XmlLayout(getConfiguration(), isLocationInfo(), isProperties(), isComplete(),
isCompact(), getCharset(), isIncludeStacktrace(), isStacktraceAsString(),
isIncludeNullDelimiter(), getAdditionalFields());
}
}
/**
* @deprecated Use {@link #newBuilder()} instead
*/
@Deprecated
protected XmlLayout(final boolean locationInfo, final boolean properties, final boolean complete,
final boolean compact, final Charset charset, final boolean includeStacktrace) {
this(null, locationInfo, properties, complete, compact, charset, includeStacktrace, false, false, null);
}
private XmlLayout(final Configuration config, final boolean locationInfo, final boolean properties,
final boolean complete, final boolean compact, final Charset charset,
final boolean includeStacktrace, final boolean stacktraceAsString,
final boolean includeNullDelimiter,
final KeyValuePair[] additionalFields) {
super(config, new JacksonFactory.XML(includeStacktrace, stacktraceAsString).newWriter(
locationInfo, properties, compact),
charset, compact, complete, false, null, null, includeNullDelimiter,
additionalFields);
}
/**
* Returns appropriate XML headers.
*
* - XML processing instruction
* - XML root element
*
*
* @return a byte array containing the header.
*/
@Override
public byte[] getHeader() {
if (!complete) {
return null;
}
final StringBuilder buf = new StringBuilder();
buf.append("");
buf.append(this.eol);
// Make the log4j namespace the default namespace, no need to use more space with a namespace prefix.
buf.append('<');
buf.append(ROOT_TAG);
buf.append(" xmlns=\"" + XmlConstants.XML_NAMESPACE + "\">");
buf.append(this.eol);
return buf.toString().getBytes(this.getCharset());
}
/**
* Returns appropriate XML footer.
*
* @return a byte array containing the footer, closing the XML root element.
*/
@Override
public byte[] getFooter() {
if (!complete) {
return null;
}
return getBytes("' + this.eol);
}
/**
* Gets this XmlLayout's content format. Specified by:
*
* - Key: "dtd" Value: "log4j-events.dtd"
* - Key: "version" Value: "2.0"
*
*
* @return Map of content format keys supporting XmlLayout
*/
@Override
public Map getContentFormat() {
final Map result = new HashMap<>();
// result.put("dtd", "log4j-events.dtd");
result.put("xsd", "log4j-events.xsd");
result.put("version", "2.0");
return result;
}
/**
* @return The content type.
*/
@Override
public String getContentType() {
return "text/xml; charset=" + this.getCharset();
}
/**
* Creates an XML Layout.
*
* @param locationInfo If "true", includes the location information in the generated XML.
* @param properties If "true", includes the thread context map in the generated XML.
* @param complete If "true", includes the XML header and footer, defaults to "false".
* @param compact If "true", does not use end-of-lines and indentation, defaults to "false".
* @param charset The character set to use, if {@code null}, uses "UTF-8".
* @param includeStacktrace
* If "true", includes the stacktrace of any Throwable in the generated XML, defaults to "true".
* @return An XML Layout.
*
* @deprecated Use {@link #newBuilder()} instead
*/
@Deprecated
public static XmlLayout createLayout(
final boolean locationInfo,
final boolean properties,
final boolean complete,
final boolean compact,
final Charset charset,
final boolean includeStacktrace) {
return new XmlLayout(null, locationInfo, properties, complete, compact, charset, includeStacktrace, false,
false, null);
}
@PluginBuilderFactory
public static > B newBuilder() {
return new Builder().asBuilder();
}
/**
* Creates an XML Layout using the default settings.
*
* @return an XML Layout.
*/
public static XmlLayout createDefaultLayout() {
return new XmlLayout(null, false, false, false, false, StandardCharsets.UTF_8, true, false, false, null);
}
}