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 @PluginFactory
108 public static SocketAppender createAppender(
109
110 @PluginAttribute("host") final String host,
111 @PluginAttribute("port") final String portNum,
112 @PluginAttribute("protocol") final String protocolStr,
113 @PluginElement("SSL") final SslConfiguration sslConfig,
114 @PluginAliases("reconnectionDelay")
115 @PluginAttribute("reconnectionDelayMillis") final String delayMillis,
116 @PluginAttribute("immediateFail") final String immediateFail,
117 @PluginAttribute("name") final String name,
118 @PluginAttribute("immediateFlush") final String immediateFlush,
119 @PluginAttribute("ignoreExceptions") final String ignore,
120 @PluginElement("Layout") Layout<? extends Serializable> layout,
121 @PluginElement("Filter") final Filter filter,
122 @PluginAttribute("advertise") final String advertise,
123 @PluginConfiguration final Configuration config) {
124
125 boolean isFlush = Booleans.parseBoolean(immediateFlush, true);
126 final boolean isAdvertise = Boolean.parseBoolean(advertise);
127 final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
128 final boolean fail = Booleans.parseBoolean(immediateFail, true);
129 final int reconnectDelayMillis = AbstractAppender.parseInt(delayMillis, 0);
130 final int port = AbstractAppender.parseInt(portNum, 0);
131 if (layout == null) {
132 layout = SerializedLayout.createLayout();
133 }
134
135 if (name == null) {
136 LOGGER.error("No name provided for SocketAppender");
137 return null;
138 }
139
140 final Protocol protocol = EnglishEnums.valueOf(Protocol.class,
141 protocolStr != null ? protocolStr : Protocol.TCP.name());
142 if (protocol == Protocol.UDP) {
143 isFlush = true;
144 }
145
146 final AbstractSocketManager manager = createSocketManager(name, protocol, host, port, sslConfig,
147 reconnectDelayMillis, fail, layout);
148
149 return new SocketAppender(name, layout, filter, manager, ignoreExceptions, isFlush,
150 isAdvertise ? config.getAdvertiser() : null);
151 }
152
153
154
155
156
157
158
159 protected static AbstractSocketManager createSocketManager(final String name, Protocol protocol, final String host,
160 final int port, final SslConfiguration sslConfig, final int delayMillis, final boolean immediateFail,
161 final Layout<? extends Serializable> layout) {
162 if (protocol == Protocol.TCP && sslConfig != null) {
163
164 protocol = Protocol.SSL;
165 }
166 if (protocol != Protocol.SSL && sslConfig != null) {
167 LOGGER.info("Appender {} ignoring SSL configuration for {} protocol", name, protocol);
168 }
169 switch (protocol) {
170 case TCP:
171 return TcpSocketManager.getSocketManager(host, port, delayMillis, immediateFail, layout);
172 case UDP:
173 return DatagramSocketManager.getSocketManager(host, port, layout);
174 case SSL:
175 return SslSocketManager.getSocketManager(sslConfig, host, port, delayMillis, immediateFail, layout);
176 default:
177 throw new IllegalArgumentException(protocol.toString());
178 }
179 }
180 }