1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.appender;
18
19 import java.io.Serializable;
20 import java.util.HashMap;
21 import java.util.Map;
22
23 import org.apache.logging.log4j.core.Filter;
24 import org.apache.logging.log4j.core.Layout;
25 import org.apache.logging.log4j.core.config.Configuration;
26 import org.apache.logging.log4j.core.config.plugins.Plugin;
27 import org.apache.logging.log4j.core.config.plugins.PluginAliases;
28 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
29 import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
30 import org.apache.logging.log4j.core.config.plugins.PluginElement;
31 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
32 import org.apache.logging.log4j.core.layout.SerializedLayout;
33 import org.apache.logging.log4j.core.net.AbstractSocketManager;
34 import org.apache.logging.log4j.core.net.Advertiser;
35 import org.apache.logging.log4j.core.net.DatagramSocketManager;
36 import org.apache.logging.log4j.core.net.Protocol;
37 import org.apache.logging.log4j.core.net.SslSocketManager;
38 import org.apache.logging.log4j.core.net.TcpSocketManager;
39 import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
40 import org.apache.logging.log4j.core.util.Booleans;
41 import org.apache.logging.log4j.util.EnglishEnums;
42
43
44
45
46 @Plugin(name = "Socket", category = "Core", elementType = "appender", printObject = true)
47 public class SocketAppender extends AbstractOutputStreamAppender<AbstractSocketManager> {
48
49 private static final long serialVersionUID = 1L;
50
51 private Object advertisement;
52 private final Advertiser advertiser;
53
54 protected SocketAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
55 final AbstractSocketManager manager, final boolean ignoreExceptions, final boolean immediateFlush,
56 final Advertiser advertiser) {
57 super(name, layout, filter, ignoreExceptions, immediateFlush, manager);
58 if (advertiser != null) {
59 final Map<String, String> configuration = new HashMap<String, String>(layout.getContentFormat());
60 configuration.putAll(manager.getContentFormat());
61 configuration.put("contentType", layout.getContentType());
62 configuration.put("name", name);
63 this.advertisement = advertiser.advertise(configuration);
64 }
65 this.advertiser = advertiser;
66 }
67
68 @Override
69 public void stop() {
70 super.stop();
71 if (this.advertiser != null) {
72 this.advertiser.unadvertise(this.advertisement);
73 }
74 }
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109 @PluginFactory
110 public static SocketAppender createAppender(
111
112 @PluginAttribute("host") final String host,
113 @PluginAttribute("port") final String portNum,
114 @PluginAttribute("protocol") final String protocolStr,
115 @PluginElement("SSL") final SslConfiguration sslConfig,
116 @PluginAttribute(value = "connectTimeoutMillis", defaultInt = 0) final int connectTimeoutMillis,
117 @PluginAliases("reconnectionDelay")
118 @PluginAttribute("reconnectionDelayMillis") final String delayMillis,
119 @PluginAttribute("immediateFail") final String immediateFail,
120 @PluginAttribute("name") final String name,
121 @PluginAttribute("immediateFlush") final String immediateFlush,
122 @PluginAttribute("ignoreExceptions") final String ignore,
123 @PluginElement("Layout") Layout<? extends Serializable> layout,
124 @PluginElement("Filter") final Filter filter,
125 @PluginAttribute("advertise") final String advertise, @PluginConfiguration final Configuration config) {
126
127 boolean isFlush = Booleans.parseBoolean(immediateFlush, true);
128 final boolean isAdvertise = Boolean.parseBoolean(advertise);
129 final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
130 final boolean fail = Booleans.parseBoolean(immediateFail, true);
131 final int reconnectDelayMillis = AbstractAppender.parseInt(delayMillis, 0);
132 final int port = AbstractAppender.parseInt(portNum, 0);
133 if (layout == null) {
134 layout = SerializedLayout.createLayout();
135 }
136
137 if (name == null) {
138 LOGGER.error("No name provided for SocketAppender");
139 return null;
140 }
141
142 final Protocol protocol = EnglishEnums.valueOf(Protocol.class,
143 protocolStr != null ? protocolStr : Protocol.TCP.name());
144 if (protocol == Protocol.UDP) {
145 isFlush = true;
146 }
147
148 final AbstractSocketManager manager = createSocketManager(name, protocol, host, port, connectTimeoutMillis,
149 sslConfig, reconnectDelayMillis, fail, layout);
150
151 return new SocketAppender(name, layout, filter, manager, ignoreExceptions, isFlush,
152 isAdvertise ? config.getAdvertiser() : null);
153 }
154
155
156
157
158
159
160
161 protected static AbstractSocketManager createSocketManager(final String name, Protocol protocol, final String host,
162 final int port, int connectTimeoutMillis, final SslConfiguration sslConfig, final int delayMillis,
163 final boolean immediateFail, final Layout<? extends Serializable> layout) {
164 if (protocol == Protocol.TCP && sslConfig != null) {
165
166 protocol = Protocol.SSL;
167 }
168 if (protocol != Protocol.SSL && sslConfig != null) {
169 LOGGER.info("Appender {} ignoring SSL configuration for {} protocol", name, protocol);
170 }
171 switch (protocol) {
172 case TCP:
173 return TcpSocketManager.getSocketManager(host, port, connectTimeoutMillis, delayMillis, immediateFail,
174 layout);
175 case UDP:
176 return DatagramSocketManager.getSocketManager(host, port, layout);
177 case SSL:
178 return SslSocketManager.getSocketManager(sslConfig, host, port, connectTimeoutMillis, delayMillis,
179 immediateFail, layout);
180 default:
181 throw new IllegalArgumentException(protocol.toString());
182 }
183 }
184 }