diff options
Diffstat (limited to 'common/openecomp-logging-lib/openecomp-logging-core/src/main/java/org/openecomp/core/logging/logback/DispatchingAppender.java')
-rw-r--r-- | common/openecomp-logging-lib/openecomp-logging-core/src/main/java/org/openecomp/core/logging/logback/DispatchingAppender.java | 142 |
1 files changed, 142 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> + * <appender name="DISPATCHER" class="DispatchingAppender"> + * <discriminator class="EventTypeDiscriminator"/> + * <appenderNamePattern>asyncEELF%s</appenderNamePattern> + * </appender> + * <root level="INFO" additivity="false"> + * <appender-ref ref="DISPATCHER" /> + * </root> + * </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(); + } + } +} |