You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rp...@apache.org on 2015/01/12 09:53:10 UTC
[13/18] logging-log4j2 git commit: added FormattingInfo and Charset
fields,
provide convenience methods for subclasses including LRU caching functionality
added FormattingInfo and Charset fields, provide convenience methods for
subclasses including LRU caching functionality
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/36a5bb15
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/36a5bb15
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/36a5bb15
Branch: refs/heads/LOG4J2-930
Commit: 36a5bb15b726a9ed3babfee2f8273d3c52d206c9
Parents: adef4e7
Author: rpopma <rp...@apache.org>
Authored: Mon Jan 12 17:40:13 2015 +0900
Committer: rpopma <rp...@apache.org>
Committed: Mon Jan 12 17:40:13 2015 +0900
----------------------------------------------------------------------
.../core/pattern/AbstractPatternConverter.java | 281 +++++++++++++------
1 file changed, 196 insertions(+), 85 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/36a5bb15/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/AbstractPatternConverter.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/AbstractPatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/AbstractPatternConverter.java
index 2118bd7..20bbb0e 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/AbstractPatternConverter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/AbstractPatternConverter.java
@@ -1,85 +1,196 @@
-/*
- * 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 org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.status.StatusLogger;
-
-
-/**
- * AbstractPatternConverter is an abstract class that provides the formatting functionality that derived classes need.
- * <p>
- * Conversion specifiers in a conversion patterns are parsed to individual PatternConverters. Each of which is
- * responsible for converting an object in a converter specific manner.
- * </p>
- */
-public abstract class AbstractPatternConverter implements PatternConverter {
- /**
- * Allow subclasses access to the status logger.
- */
- protected static final Logger LOGGER = StatusLogger.getLogger();
-
- /**
- * Converter name.
- */
- private final String name;
-
- /**
- * Converter style name.
- */
- private final String style;
-
- /**
- * Create a new pattern converter.
- *
- * @param name name for pattern converter.
- * @param style CSS style for formatted output.
- */
- protected AbstractPatternConverter(final String name, final String style) {
- this.name = name;
- this.style = style;
- }
-
- /**
- * This method returns the name of the conversion pattern.
- * <p>
- * The name can be useful to certain Layouts such as HtmlLayout.
- * </p>
- *
- * @return the name of the conversion pattern
- */
- @Override
- public final String getName() {
- return name;
- }
-
- /**
- * This method returns the CSS style class that should be applied to the LoggingEvent passed as parameter, which can
- * be null.
- * <p>
- * This information is currently used only by HtmlLayout.
- * </p>
- *
- * @param e
- * null values are accepted
- * @return the name of the conversion pattern
- */
- @Override
- public String getStyleClass(final Object e) {
- return style;
- }
-}
+/*
+ * 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.nio.charset.Charset;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.util.Charsets;
+import org.apache.logging.log4j.core.util.ConcurrentLRUCache;
+import org.apache.logging.log4j.status.StatusLogger;
+
+/**
+ * AbstractPatternConverter is an abstract class that provides the formatting functionality that derived classes need.
+ * <p>
+ * Conversion specifiers in a conversion patterns are parsed to individual PatternConverters. Each of which is
+ * responsible for converting an object in a converter specific manner.
+ * </p>
+ */
+public abstract class AbstractPatternConverter implements PatternConverter {
+ /**
+ * Allow subclasses access to the status logger.
+ */
+ protected static final Logger LOGGER = StatusLogger.getLogger();
+
+ /**
+ * Converter name.
+ */
+ private final String name;
+
+ /**
+ * Converter style name.
+ */
+ private final String style;
+
+ private final FormattingInfo formattingInfo;
+ protected final boolean hasFormattingInfo;
+ protected Charset charset;
+ private volatile ConcurrentLRUCache<Object, String> textCache;
+ private volatile ConcurrentLRUCache<Object, byte[]> binaryCache;
+ protected ThreadLocal<StringBuilder> formattingBuffer = new ThreadLocal<StringBuilder>() {
+ @Override
+ protected StringBuilder initialValue() {
+ return new StringBuilder(128);
+ };
+ };
+
+ /**
+ * Create a new pattern converter.
+ *
+ * @param name name for pattern converter.
+ * @param style CSS style for formatted output.
+ */
+ protected AbstractPatternConverter(final String name, final String style, final FormattingInfo formattingInfo) {
+ this.name = name;
+ this.style = style;
+ this.formattingInfo = formattingInfo;
+ this.hasFormattingInfo = formattingInfo != null && formattingInfo != FormattingInfo.getDefault();
+ }
+
+ /**
+ * This method returns the name of the conversion pattern.
+ * <p>
+ * The name can be useful to certain Layouts such as HtmlLayout.
+ * </p>
+ *
+ * @return the name of the conversion pattern
+ */
+ @Override
+ public final String getName() {
+ return name;
+ }
+
+ /**
+ * This method returns the CSS style class that should be applied to the LoggingEvent passed as parameter, which can
+ * be null.
+ * <p>
+ * This information is currently used only by HtmlLayout.
+ * </p>
+ *
+ * @param e null values are accepted
+ * @return the name of the conversion pattern
+ */
+ @Override
+ public String getStyleClass(final Object e) {
+ return style;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public FormattingInfo getFormattingInfo() {
+ return formattingInfo;
+ }
+
+ protected String applyFormattingInfo(final String unformatted) {
+ if (!hasFormattingInfo) {
+ return unformatted;
+ }
+ final FormattingInfo info = formattingInfo;
+ final StringBuilder buffer = formattingBuffer.get();
+ buffer.setLength(0);
+ buffer.append(unformatted);
+ info.format(0, buffer);
+ return buffer.toString();
+ }
+
+ protected String getCachedFormattedString(final String unformatted) {
+ if (!hasFormattingInfo) {
+ return unformatted; // no need to even access the cache
+ }
+ return getCachedFormattedString((Object) unformatted);
+ }
+
+ protected String getCachedFormattedString(final Object object) {
+ // first see if we already have the formatted value cached
+ final ConcurrentLRUCache<Object, String> cache = getTextCache();
+ final String cachedResult = cache.get(object);
+ if (cachedResult != null) {
+ return cachedResult; // if we have it cached we're done
+ }
+ // if not in cache we need to create the formatted String
+ final String formatted = applyFormattingInfo(convert(object));
+ cache.set(object, formatted); // cache the result for next time
+ return formatted;
+ }
+
+ protected String convert(final Object object) {
+ return object.toString();
+ }
+
+ protected byte[] getCachedFormattedBytes(final Object unformatted, final Charset charset) {
+ // first see if we already have the formatted value cached
+ final ConcurrentLRUCache<Object, byte[]> cache = getBinaryCache();
+ final byte[] cachedResult = cache.get(unformatted);
+ if (cachedResult != null) {
+ return cachedResult;
+ }
+ // if not in cache we need to create the formatted String and get its bytes
+ final String formatted = applyFormattingInfo(convert(unformatted));
+ final byte[] result = Charsets.getBytes(formatted, charset);
+ cache.set(unformatted, result);
+ return result;
+ }
+
+ protected ConcurrentLRUCache<Object, String> getTextCache() {
+ if (textCache == null) {
+ textCache = new ConcurrentLRUCache<Object, String>(128);
+ }
+ return textCache;
+ }
+
+ protected ConcurrentLRUCache<Object, byte[]> getBinaryCache() {
+ if (binaryCache == null) {
+ binaryCache = new ConcurrentLRUCache<Object, byte[]>(128);
+ }
+ return binaryCache;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder result = new StringBuilder(256);
+ result.append(getClass().getSimpleName()).append('[');
+ result.append(getName());
+ if (style != null) {
+ result.append(", style=").append(style);
+ }
+ if (formattingInfo != null) {
+ result.append(", ").append(formattingInfo);
+ }
+ result.append(']');
+ return result.toString();
+ }
+
+ public Charset getCharset() {
+ return charset;
+ }
+
+ public void setCharset(Charset charset) {
+ this.charset = charset;
+ }
+}