1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.log4j.builders.appender;
18
19 import static org.apache.log4j.builders.BuilderManager.CATEGORY;
20 import static org.apache.log4j.config.Log4j1Configuration.THRESHOLD_PARAM;
21 import static org.apache.log4j.xml.XmlConfiguration.FILTER_TAG;
22 import static org.apache.log4j.xml.XmlConfiguration.LAYOUT_TAG;
23 import static org.apache.log4j.xml.XmlConfiguration.NAME_ATTR;
24 import static org.apache.log4j.xml.XmlConfiguration.PARAM_TAG;
25 import static org.apache.log4j.xml.XmlConfiguration.VALUE_ATTR;
26 import static org.apache.log4j.xml.XmlConfiguration.forEachElement;
27
28 import java.util.ArrayList;
29 import java.util.List;
30 import java.util.Properties;
31 import java.util.concurrent.atomic.AtomicReference;
32
33 import org.apache.log4j.Appender;
34 import org.apache.log4j.Layout;
35 import org.apache.log4j.bridge.AppenderWrapper;
36 import org.apache.log4j.bridge.LayoutAdapter;
37 import org.apache.log4j.bridge.LayoutWrapper;
38 import org.apache.log4j.builders.AbstractBuilder;
39 import org.apache.log4j.config.Log4j1Configuration;
40 import org.apache.log4j.config.PropertiesConfiguration;
41 import org.apache.log4j.spi.Filter;
42 import org.apache.log4j.xml.XmlConfiguration;
43 import org.apache.logging.log4j.Logger;
44 import org.apache.logging.log4j.core.appender.ConsoleAppender;
45 import org.apache.logging.log4j.core.config.plugins.Plugin;
46 import org.apache.logging.log4j.status.StatusLogger;
47 import org.w3c.dom.Element;
48
49
50
51
52 @Plugin(name = "org.apache.log4j.ConsoleAppender", category = CATEGORY)
53 public class ConsoleAppenderBuilder extends AbstractBuilder implements AppenderBuilder {
54 private static final String SYSTEM_OUT = "System.out";
55 private static final String SYSTEM_ERR = "System.err";
56 private static final String TARGET = "target";
57
58 private static final Logger LOGGER = StatusLogger.getLogger();
59
60 public ConsoleAppenderBuilder() {
61 }
62
63 public ConsoleAppenderBuilder(String prefix, Properties props) {
64 super(prefix, props);
65 }
66
67 @Override
68 public Appender parseAppender(final Element appenderElement, final XmlConfiguration config) {
69 String name = appenderElement.getAttribute(NAME_ATTR);
70 AtomicReference<String> target = new AtomicReference<>(SYSTEM_OUT);
71 AtomicReference<Layout> layout = new AtomicReference<>();
72 AtomicReference<List<Filter>> filters = new AtomicReference<>(new ArrayList<>());
73 AtomicReference<String> level = new AtomicReference<>();
74 forEachElement(appenderElement.getChildNodes(), currentElement -> {
75 switch (currentElement.getTagName()) {
76 case LAYOUT_TAG:
77 layout.set(config.parseLayout(currentElement));
78 break;
79 case FILTER_TAG:
80 filters.get().add(config.parseFilters(currentElement));
81 break;
82 case PARAM_TAG: {
83 switch (currentElement.getAttribute(NAME_ATTR)) {
84 case TARGET: {
85 String value = currentElement.getAttribute(VALUE_ATTR);
86 if (value == null) {
87 LOGGER.warn("No value supplied for target parameter. Defaulting to System.out.");
88 } else {
89 switch (value) {
90 case SYSTEM_OUT:
91 target.set(SYSTEM_OUT);
92 break;
93 case SYSTEM_ERR:
94 target.set(SYSTEM_ERR);
95 break;
96 default:
97 LOGGER.warn("Invalid value \"{}\" for target parameter. Using default of System.out",
98 value);
99 }
100 }
101 break;
102 }
103 case THRESHOLD_PARAM: {
104 String value = currentElement.getAttribute(VALUE_ATTR);
105 if (value == null) {
106 LOGGER.warn("No value supplied for Threshold parameter, ignoring.");
107 } else {
108 level.set(value);
109 }
110 break;
111 }
112 }
113 break;
114 }
115 }
116 });
117 Filter head = null;
118 Filter current = null;
119 for (Filter f : filters.get()) {
120 if (head == null) {
121 head = f;
122 } else {
123 current.next = f;
124 }
125 current = f;
126 }
127 return createAppender(name, layout.get(), head, level.get(), target.get(), config);
128 }
129
130 @Override
131 public Appender parseAppender(final String name, final String appenderPrefix, final String layoutPrefix,
132 final String filterPrefix, final Properties props, final PropertiesConfiguration configuration) {
133 Layout layout = configuration.parseLayout(layoutPrefix, name, props);
134 Filter filter = configuration.parseAppenderFilters(props, filterPrefix, name);
135 String level = getProperty(THRESHOLD_PARAM);
136 String target = getProperty(TARGET);
137 return createAppender(name, layout, filter, level, target, configuration);
138 }
139
140 private <T extends Log4j1Configuration> Appender createAppender(String name, Layout layout, Filter filter,
141 String level, String target, T configuration) {
142 org.apache.logging.log4j.core.Layout<?> consoleLayout = null;
143
144 if (layout instanceof LayoutWrapper) {
145 consoleLayout = ((LayoutWrapper) layout).getLayout();
146 } else if (layout != null) {
147 consoleLayout = new LayoutAdapter(layout);
148 }
149 org.apache.logging.log4j.core.Filter consoleFilter = buildFilters(level, filter);
150 ConsoleAppender.Target consoleTarget = SYSTEM_ERR.equals(target)
151 ? ConsoleAppender.Target.SYSTEM_ERR : ConsoleAppender.Target.SYSTEM_OUT;
152 return new AppenderWrapper(ConsoleAppender.newBuilder()
153 .setName(name)
154 .setTarget(consoleTarget)
155 .setLayout(consoleLayout)
156 .setFilter(consoleFilter)
157 .setConfiguration(configuration)
158 .build());
159 }
160 }