2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.core.logging.logback;
23 import ch.qos.logback.classic.Logger;
24 import ch.qos.logback.classic.LoggerContext;
25 import ch.qos.logback.classic.sift.MDCBasedDiscriminator;
26 import ch.qos.logback.classic.spi.ILoggingEvent;
27 import ch.qos.logback.core.Appender;
28 import ch.qos.logback.core.AppenderBase;
29 import ch.qos.logback.core.joran.spi.DefaultClass;
30 import ch.qos.logback.core.sift.Discriminator;
31 import org.slf4j.LoggerFactory;
33 import java.util.Iterator;
35 import java.util.concurrent.ConcurrentHashMap;
38 * <p>Allows to use EELF logging configuration almost as is, by using a custom routing function, but
39 * pre-configured appenders attached to the standard EELF loggers.</p> <p>Changes that must be made
40 * in <i>logback.xml</i> supplied with EELF:</p>
42 * <appender name="DISPATCHER" class="DispatchingAppender">
43 * <discriminator class="EventTypeDiscriminator"/>
44 * <appenderNamePattern>asyncEELF%s</appenderNamePattern>
46 * <root level="INFO" additivity="false">
47 * <appender-ref ref="DISPATCHER" />
51 public class DispatchingAppender extends AppenderBase<ILoggingEvent> {
53 // "magic" appender to indicate a missing appender
54 private static final Appender<ILoggingEvent> NO_APPENDER = new DispatchingAppender();
56 private Map<String, Appender<ILoggingEvent>> appenders = new ConcurrentHashMap<>();
58 private Discriminator<ILoggingEvent> discriminator;
59 private String appenderNamePattern;
61 public Discriminator<ILoggingEvent> getDiscriminator() {
62 return this.discriminator;
65 @DefaultClass(MDCBasedDiscriminator.class)
66 public void setDiscriminator(Discriminator<ILoggingEvent> discriminator) {
67 this.discriminator = discriminator;
70 public String getAppenderNamePattern() {
71 return this.appenderNamePattern;
74 public void setAppenderNamePattern(String pattern) {
75 this.appenderNamePattern = pattern;
79 protected void append(ILoggingEvent event) {
81 if (this.isStarted()) {
83 String discriminatingValue = this.discriminator.getDiscriminatingValue(event);
84 String appenderName = String.format(this.appenderNamePattern, discriminatingValue);
85 Appender<ILoggingEvent> appender = this.lookupAppender(appenderName);
86 if (appender == NO_APPENDER) {
87 this.addError(String.format("Appender %s does not exist", appenderName));
89 appender.doAppend(event);
94 private Appender<ILoggingEvent> lookupAppender(String key) {
96 Appender<ILoggingEvent> appender = appenders.get(key);
97 if (appender != null) {
101 LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
102 for (Logger log : context.getLoggerList()) {
104 Iterator<Appender<ILoggingEvent>> iterator = log.iteratorForAppenders();
105 while (iterator.hasNext()) {
107 Appender<ILoggingEvent> element = iterator.next();
108 if (key.equals(element.getName())) {
109 this.appenders.putIfAbsent(key, element);
115 // to avoid consecutive lookups if the required appender does not exist
116 this.appenders.putIfAbsent(key, NO_APPENDER);
121 public void start() {
124 if (this.discriminator == null) {
125 this.addError("Missing discriminator. Aborting");
128 if (!this.discriminator.isStarted()) {
129 this.addError("Discriminator has not started successfully. Aborting");
133 if (this.appenderNamePattern == null) {
134 this.addError("Missing name pattern. Aborting");