View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2022, QOS.ch. All rights reserved.
4    * <p>
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    * <p>
9    * or (per the licensee's choosing)
10   * <p>
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.core.joran.sanity;
15  
16  import ch.qos.logback.core.model.AppenderModel;
17  import ch.qos.logback.core.model.Model;
18  import ch.qos.logback.core.spi.ContextAwareBase;
19  
20  import java.util.ArrayList;
21  import java.util.List;
22  import java.util.stream.Collectors;
23  
24  public class AppenderWithinAppenderSanityChecker extends ContextAwareBase implements SanityChecker  {
25  
26      static public String NESTED_APPENDERS_WARNING = "As of logback version 1.3, nested appenders are not allowed.";
27  
28      @Override
29      public void check(Model model) {
30          if (model == null)
31              return;
32  
33          List<Model> appenderModels = new ArrayList<>();
34          deepFindAllModelsOfType(AppenderModel.class, appenderModels, model);
35  
36          List<Pair<Model, Model>> nestedPairs = deepFindNestedSubModelsOfType(AppenderModel.class, appenderModels);
37  
38          List<Pair<Model, Model>> filteredNestedPairs = nestedPairs.stream().filter(pair -> !isSiftingAppender(pair.first)).collect(Collectors.toList());
39  
40          if(filteredNestedPairs.isEmpty()) {
41              return;
42          }
43          addWarn(NESTED_APPENDERS_WARNING);
44          for(Pair<Model, Model> pair: filteredNestedPairs) {
45              addWarn("Appender at line "+pair.first.getLineNumber() + " contains a nested appender at line "+pair.second.getLineNumber());
46          }
47      }
48  
49      private boolean isSiftingAppender(Model first) {
50          if(first instanceof  AppenderModel) {
51              AppenderModel appenderModel = (AppenderModel) first;
52              String classname = appenderModel.getClassName();
53              if(classname == null)
54                  return false;
55              return appenderModel.getClassName().contains("SiftingAppender");
56          }
57          return false;
58      }
59  
60  }