summaryrefslogtreecommitdiffstats
path: root/common/openecomp-logging-lib/openecomp-logging-core/src/main/java/org/openecomp/core/logging/logback
diff options
context:
space:
mode:
Diffstat (limited to 'common/openecomp-logging-lib/openecomp-logging-core/src/main/java/org/openecomp/core/logging/logback')
-rw-r--r--common/openecomp-logging-lib/openecomp-logging-core/src/main/java/org/openecomp/core/logging/logback/DispatchingAppender.java142
-rw-r--r--common/openecomp-logging-lib/openecomp-logging-core/src/main/java/org/openecomp/core/logging/logback/EventTypeDiscriminator.java121
2 files changed, 263 insertions, 0 deletions
diff --git a/common/openecomp-logging-lib/openecomp-logging-core/src/main/java/org/openecomp/core/logging/logback/DispatchingAppender.java b/common/openecomp-logging-lib/openecomp-logging-core/src/main/java/org/openecomp/core/logging/logback/DispatchingAppender.java
new file mode 100644
index 0000000000..6d5642e374
--- /dev/null
+++ b/common/openecomp-logging-lib/openecomp-logging-core/src/main/java/org/openecomp/core/logging/logback/DispatchingAppender.java
@@ -0,0 +1,142 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.core.logging.logback;
+
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.sift.MDCBasedDiscriminator;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.AppenderBase;
+import ch.qos.logback.core.joran.spi.DefaultClass;
+import ch.qos.logback.core.sift.Discriminator;
+import org.slf4j.LoggerFactory;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * <p>Allows to use EELF logging configuration almost as is, by using a custom routing function, but
+ * pre-configured appenders attached to the standard EELF loggers.</p> <p>Changes that must be made
+ * in <i>logback.xml</i> supplied with EELF:</p>
+ * <pre>
+ * &lt;appender name="DISPATCHER" class="DispatchingAppender"&gt;
+ * &lt;discriminator class="EventTypeDiscriminator"/&gt;
+ * &lt;appenderNamePattern&gt;asyncEELF%s&lt;/appenderNamePattern&gt;
+ * &lt;/appender&gt;
+ * &lt;root level="INFO" additivity="false"&gt;
+ * &lt;appender-ref ref="DISPATCHER" /&gt;
+ * &lt;/root&gt;
+ * </pre>
+ */
+public class DispatchingAppender extends AppenderBase<ILoggingEvent> {
+
+ // "magic" appender to indicate a missing appender
+ private static final Appender<ILoggingEvent> NO_APPENDER = new DispatchingAppender();
+
+ private Map<String, Appender<ILoggingEvent>> appenders = new ConcurrentHashMap<>();
+
+ private Discriminator<ILoggingEvent> discriminator;
+ private String appenderNamePattern;
+
+ public Discriminator<ILoggingEvent> getDiscriminator() {
+ return this.discriminator;
+ }
+
+ @DefaultClass(MDCBasedDiscriminator.class)
+ public void setDiscriminator(Discriminator<ILoggingEvent> discriminator) {
+ this.discriminator = discriminator;
+ }
+
+ public String getAppenderNamePattern() {
+ return this.appenderNamePattern;
+ }
+
+ public void setAppenderNamePattern(String pattern) {
+ this.appenderNamePattern = pattern;
+ }
+
+ @Override
+ protected void append(ILoggingEvent event) {
+
+ if (this.isStarted()) {
+
+ String discriminatingValue = this.discriminator.getDiscriminatingValue(event);
+ String appenderName = String.format(this.appenderNamePattern, discriminatingValue);
+ Appender<ILoggingEvent> appender = this.lookupAppender(appenderName);
+ if (appender == NO_APPENDER) {
+ this.addError(String.format("Appender %s does not exist", appenderName));
+ } else {
+ appender.doAppend(event);
+ }
+ }
+ }
+
+ private Appender<ILoggingEvent> lookupAppender(String key) {
+
+ Appender<ILoggingEvent> appender = appenders.get(key);
+ if (appender != null) {
+ return appender;
+ }
+
+ LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
+ for (Logger log : context.getLoggerList()) {
+
+ Iterator<Appender<ILoggingEvent>> iterator = log.iteratorForAppenders();
+ while (iterator.hasNext()) {
+
+ Appender<ILoggingEvent> element = iterator.next();
+ if (key.equals(element.getName())) {
+ this.appenders.putIfAbsent(key, element);
+ return element;
+ }
+ }
+ }
+
+ // to avoid consecutive lookups if the required appender does not exist
+ this.appenders.putIfAbsent(key, NO_APPENDER);
+ return NO_APPENDER;
+ }
+
+ @Override
+ public void start() {
+
+ int errors = 0;
+ if (this.discriminator == null) {
+ this.addError("Missing discriminator. Aborting");
+ }
+
+ if (!this.discriminator.isStarted()) {
+ this.addError("Discriminator has not started successfully. Aborting");
+ ++errors;
+ }
+
+ if (this.appenderNamePattern == null) {
+ this.addError("Missing name pattern. Aborting");
+ ++errors;
+ }
+
+ if (errors == 0) {
+ super.start();
+ }
+ }
+}
diff --git a/common/openecomp-logging-lib/openecomp-logging-core/src/main/java/org/openecomp/core/logging/logback/EventTypeDiscriminator.java b/common/openecomp-logging-lib/openecomp-logging-core/src/main/java/org/openecomp/core/logging/logback/EventTypeDiscriminator.java
new file mode 100644
index 0000000000..107f6728d7
--- /dev/null
+++ b/common/openecomp-logging-lib/openecomp-logging-core/src/main/java/org/openecomp/core/logging/logback/EventTypeDiscriminator.java
@@ -0,0 +1,121 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.core.logging.logback;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.sift.AbstractDiscriminator;
+import org.openecomp.core.logging.Markers;
+import org.slf4j.Marker;
+
+/**
+ * Can be used with {@link ch.qos.logback.classic.sift.SiftingAppender} to route events of different
+ * types to separate log files. For example,
+ * <pre>
+ * &lt;configuration&gt;
+ * &lt;appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender"&gt;
+ * &lt;discriminator class="EventTypeDiscriminator"/&gt;
+ * &lt;sift&gt;
+ * &lt;appender name="{EventType}"
+ * class="ch.qos.logback.core.rolling.RollingFileAppender"&gt;
+ * &lt;file&gt;${logDirectory}/${eventType}.log&lt;/file&gt;
+ * &lt;rollingPolicy class="ch.
+ * qos.logback.core.rolling.FixedWindowRollingPolicy"&gt;
+ * &lt;fileNamePattern&gt;
+ * ${logDirectory}/${eventType}.
+ * %i.log.zip&lt;/fileNamePattern&gt;
+ * &lt;minIndex&gt;1&lt;/minIndex&gt;
+ * &lt;maxIndex&gt;9&lt;/maxIndex&gt;
+ * &lt;/rollingPolicy&gt;
+ * &lt;triggeringPolicy
+ * class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"&gt;
+ * &lt;maxFileSize&gt;5MB&lt;/maxFileSize&gt;
+ * &lt;/triggeringPolicy&gt;
+ * &lt;encoder&gt;
+ * &lt;pattern&gt;${defaultPattern}&lt;/pattern&gt;
+ * &lt;/encoder&gt;
+ * &lt;/appender&gt;
+ * &lt;/sift&gt;
+ * &lt;/appender&gt;
+ * &lt;root level="INFO"&gt;
+ * &lt;appender-ref ref="SIFT" /&gt;
+ * &lt;/root&gt;
+ * &lt;/configuration&gt;
+ * </pre>
+ */
+public class EventTypeDiscriminator extends AbstractDiscriminator<ILoggingEvent> {
+
+ private static final String KEY = "eventType";
+
+ private static final String AUDIT = "Audit";
+ private static final String METRICS = "Metrics";
+ private static final String ERROR = "Error";
+ private static final String DEBUG = "Debug";
+ private static final String DEFAULT = DEBUG;
+
+ private static final int MIN_ERROR_LEVEL = Level.WARN_INT;
+ private static final int MAX_ERROR_LEVEL = Level.ERROR_INT;
+ private static final int DEFAULT_LEVEL = Level.DEBUG_INT;
+
+ @Override
+ public String getDiscriminatingValue(ILoggingEvent event) {
+
+ Level level = event.getLevel();
+ final int levelInt = level == null ? DEFAULT_LEVEL : level.toInt();
+ if ((levelInt > MIN_ERROR_LEVEL - 1) && (levelInt < MAX_ERROR_LEVEL + 1)) {
+ return ERROR;
+ }
+
+ if (levelInt == Level.DEBUG_INT) {
+ return DEBUG;
+ }
+
+ /*
+ * After DEBUG, ERROR, and WARNING have been filtered out,
+ * only TRACE and INFO are left. TRACE is less than DEBUG
+ * and therefore cannot be used. So, INFO should be used for
+ * custom routing like AUDIT and METRICS
+ */
+ if (levelInt == Level.INFO_INT) {
+
+ final Marker marker = event.getMarker();
+ if (marker != null) {
+
+ if (marker.contains(Markers.AUDIT)) {
+ return AUDIT;
+ }
+
+ if (marker.contains(Markers.METRICS)) {
+ return METRICS;
+ }
+ }
+
+ return ERROR;
+ }
+
+ return DEFAULT;
+ }
+
+ @Override
+ public String getKey() {
+ return KEY;
+ }
+}