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 org.apache.log4j.Appender;
20 import org.apache.log4j.Layout;
21 import org.apache.log4j.bridge.AppenderWrapper;
22 import org.apache.log4j.bridge.LayoutAdapter;
23 import org.apache.log4j.bridge.LayoutWrapper;
24 import org.apache.log4j.builders.AbstractBuilder;
25 import org.apache.log4j.builders.Holder;
26 import org.apache.log4j.config.Log4j1Configuration;
27 import org.apache.log4j.config.PropertiesConfiguration;
28 import org.apache.log4j.spi.Filter;
29 import org.apache.log4j.xml.XmlConfiguration;
30 import org.apache.logging.log4j.Logger;
31 import org.apache.logging.log4j.core.appender.SyslogAppender;
32 import org.apache.logging.log4j.core.config.plugins.Plugin;
33 import org.apache.logging.log4j.core.layout.SyslogLayout;
34 import org.apache.logging.log4j.core.net.Facility;
35 import org.apache.logging.log4j.core.net.Protocol;
36 import org.apache.logging.log4j.status.StatusLogger;
37 import org.w3c.dom.Element;
38
39 import java.util.Properties;
40
41 import static org.apache.log4j.builders.BuilderManager.CATEGORY;
42 import static org.apache.log4j.config.Log4j1Configuration.THRESHOLD_PARAM;
43 import static org.apache.log4j.xml.XmlConfiguration.FILTER_TAG;
44 import static org.apache.log4j.xml.XmlConfiguration.LAYOUT_TAG;
45 import static org.apache.log4j.xml.XmlConfiguration.NAME_ATTR;
46 import static org.apache.log4j.xml.XmlConfiguration.PARAM_TAG;
47 import static org.apache.log4j.xml.XmlConfiguration.VALUE_ATTR;
48 import static org.apache.log4j.xml.XmlConfiguration.forEachElement;
49
50
51
52
53 @Plugin(name = "org.apache.log4j.net.SyslogAppender", category = CATEGORY)
54 public class SyslogAppenderBuilder extends AbstractBuilder implements AppenderBuilder {
55
56 private static final Logger LOGGER = StatusLogger.getLogger();
57 private static final String FACILITY_PARAM = "Facility";
58 private static final String SYSLOG_HOST_PARAM = "SyslogHost";
59 private static int SYSLOG_PORT = 512;
60
61 public SyslogAppenderBuilder() {
62 }
63
64 public SyslogAppenderBuilder(String prefix, Properties props) {
65 super(prefix, props);
66 }
67
68 @Override
69 public Appender parseAppender(Element appenderElement, XmlConfiguration config) {
70 String name = appenderElement.getAttribute(NAME_ATTR);
71 Holder<Layout> layout = new Holder<>();
72 Holder<Filter> filter = new Holder<>();
73 Holder<String> facility = new Holder<>();
74 Holder<String> level = new Holder<>();
75 Holder<String> host = new Holder<>();
76 forEachElement(appenderElement.getChildNodes(), (currentElement) -> {
77 switch (currentElement.getTagName()) {
78 case LAYOUT_TAG:
79 layout.set(config.parseLayout(currentElement));
80 break;
81 case FILTER_TAG:
82 filter.set(config.parseFilters(currentElement));
83 break;
84 case PARAM_TAG: {
85 switch (currentElement.getAttribute(NAME_ATTR)) {
86 case SYSLOG_HOST_PARAM: {
87 host.set(currentElement.getAttribute(VALUE_ATTR));
88 break;
89 }
90 case FACILITY_PARAM:
91 facility.set(currentElement.getAttribute(VALUE_ATTR));
92 break;
93 case THRESHOLD_PARAM: {
94 String value = currentElement.getAttribute(VALUE_ATTR);
95 if (value == null) {
96 LOGGER.warn("No value supplied for Threshold parameter, ignoring.");
97 } else {
98 level.set(value);
99 }
100 break;
101 }
102 }
103 break;
104 }
105 }
106 });
107
108 return createAppender(name, config, layout.get(), facility.get(), filter.get(), host.get(), level.get());
109 }
110
111
112 @Override
113 public Appender parseAppender(final String name, final String appenderPrefix, final String layoutPrefix,
114 final String filterPrefix, final Properties props, final PropertiesConfiguration configuration) {
115 Filter filter = configuration.parseAppenderFilters(props, filterPrefix, name);
116 Layout layout = configuration.parseLayout(layoutPrefix, name, props);
117 String level = getProperty(THRESHOLD_PARAM);
118 String facility = getProperty(FACILITY_PARAM, "LOCAL0");
119 String syslogHost = getProperty(SYSLOG_HOST_PARAM, "localhost:514");
120
121 return createAppender(name, configuration, layout, facility, filter, syslogHost, level);
122 }
123
124 private Appender createAppender(final String name, final Log4j1Configuration configuration, Layout layout,
125 String facility, final Filter filter, final String syslogHost, final String level) {
126 Holder<String> host = new Holder<>();
127 Holder<Integer> port = new Holder<>();
128 resolveSyslogHost(syslogHost, host, port);
129 org.apache.logging.log4j.core.Layout appenderLayout;
130 if (layout instanceof LayoutWrapper) {
131 appenderLayout = ((LayoutWrapper) layout).getLayout();
132 } else if (layout != null) {
133 appenderLayout = new LayoutAdapter(layout);
134 } else {
135 appenderLayout = SyslogLayout.newBuilder()
136 .setFacility(Facility.toFacility(facility))
137 .setConfiguration(configuration)
138 .build();
139 }
140
141 org.apache.logging.log4j.core.Filter fileFilter = buildFilters(level, filter);
142 return new AppenderWrapper(SyslogAppender.newBuilder()
143 .setName(name)
144 .setConfiguration(configuration)
145 .setLayout(appenderLayout)
146 .setFilter(fileFilter)
147 .withPort(port.get())
148 .withProtocol(Protocol.TCP)
149 .withHost(host.get())
150 .build());
151 }
152
153 private void resolveSyslogHost(String syslogHost, Holder<String> host, Holder<Integer> port) {
154 int urlPort = -1;
155
156
157
158
159
160 String[] parts = syslogHost.split(":");
161 if (parts.length == 1) {
162 host.set(parts[0]);
163 port.set(SYSLOG_PORT);
164 } else if (parts.length == 2) {
165 host.set(parts[0]);
166 port.set(Integer.parseInt(parts[1]));
167 } else {
168 LOGGER.warn("Invalid syslogHost setting: {}. Using default", syslogHost);
169 host.set("localhost");
170 port.set(SYSLOG_PORT);
171 }
172 }
173 }