/*
 * 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.pattern;

import java.util.List;

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.apache.logging.log4j.util.EnglishEnums;
import org.apache.logging.log4j.util.PerformanceSensitive;
import org.apache.logging.log4j.util.StringBuilders;

Converter that encodes the output from a pattern using a specified format. Supported formats include HTML (default) and JSON.
/** * Converter that encodes the output from a pattern using a specified format. Supported formats include HTML * (default) and JSON. */
@Plugin(name = "encode", category = PatternConverter.CATEGORY) @ConverterKeys({"enc", "encode"}) @PerformanceSensitive("allocation") public final class EncodingPatternConverter extends LogEventPatternConverter { private final List<PatternFormatter> formatters; private final EscapeFormat escapeFormat;
Private constructor.
Params:
  • formatters – the PatternFormatters to generate the text to manipulate.
  • escapeFormat – the escape format strategy to use for encoding output of formatters
/** * Private constructor. * * @param formatters the PatternFormatters to generate the text to manipulate. * @param escapeFormat the escape format strategy to use for encoding output of formatters */
private EncodingPatternConverter(final List<PatternFormatter> formatters, final EscapeFormat escapeFormat) { super("encode", "encode"); this.formatters = formatters; this.escapeFormat = escapeFormat; }
Creates an EncodingPatternConverter using a pattern string and an optional escape format.
Params:
  • config – the current Configuration
  • options – first option is the nested pattern format; second option is the escape format (optional)
Returns:instance of pattern converter.
/** * Creates an EncodingPatternConverter using a pattern string and an optional escape format. * * @param config the current Configuration * @param options first option is the nested pattern format; second option is the escape format (optional) * @return instance of pattern converter. */
public static EncodingPatternConverter newInstance(final Configuration config, final String[] options) { if (options.length > 2 || options.length == 0) { LOGGER.error("Incorrect number of options on escape. Expected 1 or 2, but received {}", options.length); return null; } if (options[0] == null) { LOGGER.error("No pattern supplied on escape"); return null; } final EscapeFormat escapeFormat = options.length < 2 ? EscapeFormat.HTML : EnglishEnums.valueOf(EscapeFormat.class, options[1], EscapeFormat.HTML); final PatternParser parser = PatternLayout.createPatternParser(config); final List<PatternFormatter> formatters = parser.parse(options[0]); return new EncodingPatternConverter(formatters, escapeFormat); }
{@inheritDoc}
/** * {@inheritDoc} */
@Override public void format(final LogEvent event, final StringBuilder toAppendTo) { final int start = toAppendTo.length(); for (int i = 0; i < formatters.size(); i++) { formatters.get(i).format(event, toAppendTo); } escapeFormat.escape(toAppendTo, start); } private enum EscapeFormat { HTML { @Override void escape(final StringBuilder toAppendTo, final int start) { for (int i = toAppendTo.length() - 1; i >= start; i--) { // backwards: length may change final char c = toAppendTo.charAt(i); switch (c) { case '\r': toAppendTo.setCharAt(i, '\\'); toAppendTo.insert(i + 1, 'r'); break; case '\n': toAppendTo.setCharAt(i, '\\'); toAppendTo.insert(i + 1, 'n'); break; case '&': toAppendTo.setCharAt(i, '&'); toAppendTo.insert(i + 1, "amp;"); break; case '<': toAppendTo.setCharAt(i, '&'); toAppendTo.insert(i + 1, "lt;"); break; case '>': toAppendTo.setCharAt(i, '&'); toAppendTo.insert(i + 1, "gt;"); break; case '"': toAppendTo.setCharAt(i, '&'); toAppendTo.insert(i + 1, "quot;"); break; case '\'': toAppendTo.setCharAt(i, '&'); toAppendTo.insert(i + 1, "apos;"); break; case '/': toAppendTo.setCharAt(i, '&'); toAppendTo.insert(i + 1, "#x2F;"); break; } } } },
JSON string escaping as defined in RFC 4627.
See Also:
/** * JSON string escaping as defined in RFC 4627. * * @see <a href="https://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a> */
JSON { @Override void escape(final StringBuilder toAppendTo, final int start) { StringBuilders.escapeJson(toAppendTo, start); } }, CRLF { @Override void escape(final StringBuilder toAppendTo, final int start) { for (int i = toAppendTo.length() - 1; i >= start; i--) { // backwards: length may change final char c = toAppendTo.charAt(i); switch (c) { case '\r': toAppendTo.setCharAt(i, '\\'); toAppendTo.insert(i + 1, 'r'); break; case '\n': toAppendTo.setCharAt(i, '\\'); toAppendTo.insert(i + 1, 'n'); break; } } } },
XML string escaping as defined in XML specification.
See Also:
/** * XML string escaping as defined in XML specification. * * @see <a href="https://www.w3.org/TR/xml/">XML specification</a> */
XML { @Override void escape(final StringBuilder toAppendTo, final int start) { StringBuilders.escapeXml(toAppendTo, start); } };
Escapes text using a standardized format from a given starting point to the end of the string.
Params:
  • toAppendTo – string buffer to escape
  • start – where to start escaping from
/** * Escapes text using a standardized format from a given starting point to the end of the string. * * @param toAppendTo string buffer to escape * @param start where to start escaping from */
abstract void escape(final StringBuilder toAppendTo, final int start); } }