├── .travis.yml
├── .idea
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── modules.xml
├── misc.xml
└── compiler.xml
├── src
├── test
│ └── java
│ │ └── tw
│ │ └── kewang
│ │ └── logback
│ │ └── appender
│ │ └── AppTest.java
└── main
│ ├── java
│ └── tw
│ │ └── kewang
│ │ └── logback
│ │ └── appender
│ │ ├── Authentication.java
│ │ ├── HttpAuthenticationAppender.java
│ │ ├── HttpAppender.java
│ │ └── HttpAppenderAbstract.java
│ └── resources
│ └── logback.xml
├── LICENSE
├── README.md
├── pom.xml
├── .gitignore
└── logback-http-appender.iml
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | jdk:
3 | - oraclejdk8
4 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/test/java/tw/kewang/logback/appender/AppTest.java:
--------------------------------------------------------------------------------
1 | package tw.kewang.logback.appender;
2 |
3 | import org.junit.Test;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | public class AppTest {
8 | private static final Logger LOG = LoggerFactory.getLogger(AppTest.class);
9 |
10 | @Test
11 | public void testApp() {
12 | try {
13 | throw new RuntimeException("Oops");
14 | } catch (Exception e) {
15 | LOG.error("Caught Exception: ", e);
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/tw/kewang/logback/appender/Authentication.java:
--------------------------------------------------------------------------------
1 | package tw.kewang.logback.appender;
2 |
3 | public class Authentication {
4 |
5 | private String username;
6 | private String password;
7 |
8 | public String getUsername() {
9 | return username;
10 | }
11 |
12 | public String getPassword() {
13 | return password;
14 | }
15 |
16 | public void setUsername(String username) {
17 | this.username = username;
18 | }
19 |
20 | public void setPassword(String password) {
21 | this.password = password;
22 | }
23 |
24 | public boolean isConfigured() {
25 | return HttpAppenderAbstract.isStringEmptyOrNull(username) == false && HttpAppenderAbstract.isStringEmptyOrNull(password) == false;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Kewang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Redmine-Appender
4 |
5 |
6 |
7 |
8 |
9 |
10 | ${PATTERN}
11 | ${CHARSET}
12 |
13 |
14 |
15 |
16 | ${LOG_HOME}/myLog.log
17 |
18 | ${PATTERN}
19 | ${CHARSET}
20 |
21 |
22 |
23 |
24 | post
25 | http://example.com/issues.json
26 | json
27 | {"issue": {"subject": "$subject", "project_id": 22, "description": "$event"}}
28 | {"X-Redmine-API-Key": "hello-this-is-a-key", "Another": "also-key"}
29 |
30 | ${PATTERN}
31 | ${CHARSET}
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # logback-http-appender
2 |
3 | [](https://travis-ci.org/kewang/logback-http-appender)
4 |
5 | ## How to use
6 |
7 | ```xml
8 |
9 | https
10 | localhost
11 | 443
12 | /logs/logstash
13 |
14 | username
15 | senha
16 |
17 | 10
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | {
29 | "appName": "upp-quality-control-framework-ws"
30 | }
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | ```
46 |
47 | ## References
48 |
49 | * [Chapter 4: Appenders](http://logback.qos.ch/manual/appenders.html)
50 | * [logback-redis-appender](https://github.com/kmtong/logback-redis-appender)
51 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | tw.kewang
6 | logback-http-appender
7 | 0.2.0-SNAPSHOT
8 | jar
9 |
10 | logback-http-appender
11 | http://maven.apache.org
12 |
13 |
14 | UTF-8
15 |
16 |
17 |
18 |
19 | junit
20 | junit
21 | 4.12
22 | test
23 |
24 |
25 | ch.qos.logback
26 | logback-classic
27 | 1.2.1
28 |
29 |
30 | commons-io
31 | commons-io
32 | 2.5
33 |
34 |
35 | org.json
36 | json
37 | 20160212
38 |
39 |
40 |
41 |
42 |
43 |
44 | org.apache.maven.plugins
45 | maven-compiler-plugin
46 | 3.6.1
47 |
48 | 1.8
49 | 1.8
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.gitignore.io/api/maven,intellij,java
2 |
3 | ### Maven ###
4 | target/
5 | pom.xml.tag
6 | pom.xml.releaseBackup
7 | pom.xml.versionsBackup
8 | pom.xml.next
9 | release.properties
10 | dependency-reduced-pom.xml
11 | buildNumber.properties
12 | .mvn/timing.properties
13 |
14 |
15 | ### Intellij ###
16 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
17 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
18 |
19 | # User-specific stuff:
20 | .idea/workspace.xml
21 | .idea/tasks.xml
22 | .idea/dictionaries
23 | .idea/vcs.xml
24 | .idea/jsLibraryMappings.xml
25 |
26 | # Sensitive or high-churn files:
27 | .idea/dataSources.ids
28 | .idea/dataSources.xml
29 | .idea/dataSources.local.xml
30 | .idea/sqlDataSources.xml
31 | .idea/dynamic.xml
32 | .idea/uiDesigner.xml
33 |
34 | # Gradle:
35 | .idea/gradle.xml
36 | .idea/libraries
37 |
38 | # Mongo Explorer plugin:
39 | .idea/mongoSettings.xml
40 |
41 | ## File-based project format:
42 | *.iws
43 |
44 | ## Plugin-specific files:
45 |
46 | # IntelliJ
47 | /out/
48 |
49 | # mpeltonen/sbt-idea plugin
50 | .idea_modules/
51 |
52 | # JIRA plugin
53 | atlassian-ide-plugin.xml
54 |
55 | # Crashlytics plugin (for Android Studio and IntelliJ)
56 | com_crashlytics_export_strings.xml
57 | crashlytics.properties
58 | crashlytics-build.properties
59 | fabric.properties
60 |
61 | ### Intellij Patch ###
62 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
63 |
64 | # *.iml
65 | # modules.xml
66 | # .idea/misc.xml
67 | # *.ipr
68 |
69 |
70 | ### Java ###
71 | *.class
72 |
73 | # Mobile Tools for Java (J2ME)
74 | .mtj.tmp/
75 |
76 | # Package Files #
77 | *.jar
78 | *.war
79 | *.ear
80 |
81 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
82 | hs_err_pid*
83 |
84 | ### Custom ###
85 | *.log
86 |
87 | .classpath
88 | .project
89 | .settings
90 |
--------------------------------------------------------------------------------
/src/main/java/tw/kewang/logback/appender/HttpAuthenticationAppender.java:
--------------------------------------------------------------------------------
1 | package tw.kewang.logback.appender;
2 |
3 | import java.net.HttpURLConnection;
4 | import java.net.URL;
5 |
6 | /**
7 | * Provide basic http authentication.
8 | *
9 | * @author Thiago Diniz da Silveira
10 | *
11 | */
12 | public class HttpAuthenticationAppender extends HttpAppenderAbstract {
13 |
14 | private static final String SEPARATOR_BASIC_AUTHENTICATION = ":";
15 |
16 | protected Authentication authentication;
17 | protected String encondedUserPassword;
18 |
19 | @SuppressWarnings("restriction")
20 | @Override
21 | public void start() {
22 | super.start();
23 | if (authentication == null || authentication.isConfigured() == false) {
24 | addError("No authentication was configured. Use to specify the and the for Basic Authentication.");
25 | return;
26 | }
27 |
28 | String userPassword = authentication.getUsername() + SEPARATOR_BASIC_AUTHENTICATION + authentication.getPassword();
29 | encondedUserPassword = new sun.misc.BASE64Encoder().encode(userPassword.getBytes());
30 |
31 | openConnection();
32 | addInfo("Using Basic Authentication");
33 | }
34 |
35 | @Override
36 | protected HttpURLConnection openConnection() {
37 | HttpURLConnection conn = null;
38 | try {
39 | URL urlObj = new URL(protocol, url, port, path);
40 | conn = (HttpURLConnection) urlObj.openConnection();
41 | conn.setRequestProperty("Authorization", "Basic " + encondedUserPassword);
42 | conn.setRequestMethod("POST");
43 | return conn;
44 | } catch (Exception e) {
45 | addError("Error to open connection Exception: ", e);
46 | return null;
47 | } finally {
48 | try {
49 | if (conn != null) {
50 | conn.disconnect();
51 | }
52 | } catch (Exception e) {
53 | addError("Error to open connection Exception: ", e);
54 | return null;
55 | }
56 | }
57 | }
58 |
59 | public Authentication getAuthentication() {
60 | return authentication;
61 | }
62 |
63 | public void setAuthentication(Authentication authentication) {
64 | this.authentication = authentication;
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/tw/kewang/logback/appender/HttpAppender.java:
--------------------------------------------------------------------------------
1 | package tw.kewang.logback.appender;
2 |
3 | import java.io.IOException;
4 | import java.net.HttpURLConnection;
5 | import java.net.URL;
6 | import java.nio.charset.Charset;
7 |
8 | import org.apache.commons.io.IOUtils;
9 | import org.json.JSONObject;
10 |
11 | import ch.qos.logback.classic.spi.ILoggingEvent;
12 | import ch.qos.logback.core.Layout;
13 | import ch.qos.logback.core.encoder.Encoder;
14 |
15 | public class HttpAppender extends HttpAppenderAbstract {
16 |
17 | /**
18 | * Defines default method to send data.
19 | */
20 | protected final static String DEFAULT_METHOD = "POST";
21 |
22 | protected String method = "POST";
23 |
24 | @Override
25 | public void start() {
26 | normalizeMethodName();
27 |
28 | super.start();
29 | }
30 |
31 | protected void checkProperties() {
32 | if (isStringEmptyOrNull(url)) {
33 | url = DEFAULT_URL;
34 | addInfo(String.format(MSG_NOT_SET, "url", url));
35 | } else {
36 | addInfo(String.format(MSG_USING, "url", url));
37 | }
38 |
39 | if (isStringEmptyOrNull(method)) {
40 | method = DEFAULT_METHOD;
41 | addInfo(String.format(MSG_NOT_SET, "method", method));
42 | } else {
43 | addInfo(String.format(MSG_USING, "method", method));
44 | }
45 | }
46 |
47 | @Override
48 | public void append(ILoggingEvent event) {
49 | createIssue(event);
50 | }
51 |
52 | public void createIssue(ILoggingEvent event) {
53 | HttpURLConnection conn = null;
54 |
55 | try {
56 | URL urlObj = new URL(url);
57 | addInfo("URL: " + url);
58 | conn = (HttpURLConnection) urlObj.openConnection();
59 | conn.setRequestMethod(method);
60 | transformHeaders(conn);
61 | boolean isOk = false;
62 | byte[] objEncoded = encoder.encode(event);
63 | if (method.equals("GET") || method.equals("DELETE")) {
64 | isOk = sendNoBodyRequest(conn);
65 | } else if (method.equals("POST") || method.equals("PUT")) {
66 | isOk = sendBodyRequest(objEncoded, conn);
67 | }
68 |
69 | if (!isOk) {
70 | addError("Not OK");
71 | return;
72 | }
73 | } catch (Exception e) {
74 | addError("Exception", e);
75 | return;
76 | } finally {
77 | try {
78 | if (conn != null) {
79 | conn.disconnect();
80 | }
81 | } catch (Exception e) {
82 | addError("Exception", e);
83 | return;
84 | }
85 | }
86 | }
87 |
88 | private void normalizeMethodName() {
89 | method = method.toUpperCase();
90 | }
91 |
92 | protected void transformHeaders(HttpURLConnection conn) {
93 | conn.setRequestProperty("Content-Type", contentType);
94 | if (headers == null || headers.isEmpty()) {
95 | return;
96 | }
97 |
98 | JSONObject jObj = new JSONObject(headers);
99 | for (String key : jObj.keySet()) {
100 | String value = (String) jObj.get(key);
101 | conn.setRequestProperty(key, value);
102 | }
103 |
104 | }
105 |
106 | protected boolean sendNoBodyRequest(HttpURLConnection conn) throws IOException {
107 | return showResponse(conn);
108 | }
109 |
110 | protected boolean sendBodyRequest(byte[] objEncoded, HttpURLConnection conn) throws IOException {
111 | conn.setDoOutput(true);
112 | if (body != null) {
113 | addInfo("Body: " + body);
114 | IOUtils.write(body, conn.getOutputStream(), Charset.defaultCharset());
115 | } else {
116 | IOUtils.write(objEncoded, conn.getOutputStream());
117 | }
118 | return showResponse(conn);
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/logback-http-appender.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
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 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/src/main/java/tw/kewang/logback/appender/HttpAppenderAbstract.java:
--------------------------------------------------------------------------------
1 | package tw.kewang.logback.appender;
2 |
3 | import java.io.IOException;
4 | import java.net.HttpURLConnection;
5 | import java.net.URL;
6 | import java.nio.charset.Charset;
7 | import java.time.Duration;
8 |
9 | import org.apache.commons.io.IOUtils;
10 | import org.json.JSONObject;
11 |
12 | import ch.qos.logback.classic.spi.ILoggingEvent;
13 | import ch.qos.logback.core.Layout;
14 | import ch.qos.logback.core.UnsynchronizedAppenderBase;
15 | import ch.qos.logback.core.encoder.Encoder;
16 |
17 | public abstract class HttpAppenderAbstract extends UnsynchronizedAppenderBase {
18 |
19 | /**
20 | * Defines default port to get access.
21 | */
22 | protected final static int DEFAULT_PORT = 8080;
23 |
24 | /**
25 | * Defines default protocol to use between HTTP or HTTPS.
26 | */
27 | protected final static String DEFAULT_PROTOCOL = "http";
28 |
29 | /**
30 | * Defines default content type to send data.
31 | */
32 | protected final static String DEFAULT_CONTENT_TYPE = "json";
33 |
34 | /**
35 | * Defines default URL server.
36 | */
37 | protected final static String DEFAULT_URL = "localhost";
38 |
39 | /**
40 | * Defines default server path.
41 | */
42 | protected final static String DEFAULT_PATH = "/";
43 |
44 | /**
45 | * Defines default time in seconds to try to reconnect if connection is lost.
46 | */
47 | protected final static int DEFAULT_RECONNECT_DELAY = 30;
48 |
49 | protected final String MSG_USING = "Using %s: %s";
50 | protected final String MSG_NOT_SET = "Assuming default value for %s: %s";
51 |
52 | protected Encoder encoder;
53 | protected Layout layout;
54 | protected String url;
55 |
56 | protected String protocol;
57 | protected String path;
58 | protected int port;
59 | protected String contentType;
60 | protected String body;
61 | protected String headers;
62 | protected int reconnectDelay;
63 |
64 | @Override
65 | public void start() {
66 | if (encoder == null) {
67 | addError("No encoder was configured. Use to specify the fully qualified class name of the encoder to use");
68 | return;
69 | }
70 |
71 | checkProperties();
72 | normalizeContentType();
73 |
74 | encoder.start();
75 | super.start();
76 | }
77 |
78 | protected void checkProperties() {
79 | if (isStringEmptyOrNull(protocol)) {
80 | protocol = DEFAULT_PROTOCOL;
81 | addInfo(String.format(MSG_NOT_SET, "protocol", protocol));
82 | } else {
83 | addInfo(String.format(MSG_USING, "protocol", protocol));
84 | }
85 |
86 | if (isStringEmptyOrNull(url)) {
87 | url = DEFAULT_URL;
88 | addInfo(String.format(MSG_NOT_SET, "url", url));
89 | } else {
90 | addInfo(String.format(MSG_USING, "url", url));
91 | }
92 |
93 | if (isStringEmptyOrNull(path)) {
94 | path = DEFAULT_PATH;
95 | addInfo(String.format(MSG_NOT_SET, "path", path));
96 | } else {
97 | addInfo(String.format(MSG_USING, "path", path));
98 | }
99 |
100 | if (port == 0) {
101 | port = DEFAULT_PORT;
102 | addInfo(String.format(MSG_NOT_SET, "port", port));
103 | } else {
104 | addInfo(String.format(MSG_USING, "port", port));
105 | }
106 |
107 | if (isStringEmptyOrNull(contentType)) {
108 | contentType = DEFAULT_CONTENT_TYPE;
109 | addInfo(String.format(MSG_NOT_SET, "contentType", contentType));
110 | } else {
111 | addInfo(String.format(MSG_USING, "contentType", contentType));
112 | }
113 |
114 | if (reconnectDelay == 0) {
115 | reconnectDelay = DEFAULT_RECONNECT_DELAY;
116 | addInfo(String.format(MSG_NOT_SET, "reconnectDelay", reconnectDelay));
117 | } else {
118 | addInfo(String.format(MSG_USING, "reconnectDelay", reconnectDelay));
119 | }
120 | }
121 |
122 | protected void normalizeContentType() {
123 | if (contentType.equalsIgnoreCase("json")) {
124 | contentType = "application/json";
125 | } else if (contentType.equalsIgnoreCase("xml")) {
126 | contentType = "application/xml";
127 | }
128 | }
129 |
130 | @Override
131 | public void append(ILoggingEvent event) {
132 | try {
133 | HttpURLConnection conn = openConnection();
134 | byte[] objEncoded = encoder.encode(event);
135 | transformHeaders(conn, objEncoded.length);
136 | sendBodyRequest(objEncoded, conn);
137 | } catch (IOException e) {
138 | addError("Error ocurred during the connection: ", e);
139 | reconnect(event);
140 | }
141 | }
142 |
143 | protected void transformHeaders(HttpURLConnection conn, int contentLength) {
144 | conn.setRequestProperty("Content-Type", contentType);
145 | conn.setRequestProperty("Content-length", Integer.toString(contentLength));
146 | if (headers == null || headers.isEmpty()) {
147 | return;
148 | }
149 |
150 | JSONObject jObj = new JSONObject(headers);
151 | for (String key : jObj.keySet()) {
152 | String value = (String) jObj.get(key);
153 | conn.setRequestProperty(key, value);
154 | }
155 | }
156 |
157 | protected boolean sendNoBodyRequest(HttpURLConnection conn) throws IOException {
158 | return showResponse(conn);
159 | }
160 |
161 | protected boolean sendBodyRequest(byte[] objEncoded, HttpURLConnection conn) throws IOException {
162 | conn.setDoOutput(true);
163 | IOUtils.write(objEncoded, conn.getOutputStream());
164 | return showResponse(conn);
165 | }
166 |
167 | protected void reconnect(ILoggingEvent event) {
168 | try {
169 | addInfo(String.format("Trying to reconnect in %s seconds", reconnectDelay));
170 | Thread.sleep(Duration.ofSeconds(reconnectDelay).toMillis());
171 | append(event);
172 | } catch (InterruptedException e1) {
173 | addError("Erro trying to reconnect: ", e1);
174 | e1.printStackTrace();
175 | }
176 | }
177 |
178 | protected boolean showResponse(HttpURLConnection conn) throws IOException {
179 | int responseCode = conn.getResponseCode();
180 |
181 | if (responseCode != HttpURLConnection.HTTP_OK) {
182 | addError(String.format("Error to send logs: %s", conn));
183 | return false;
184 | }
185 |
186 | String response = IOUtils.toString(conn.getInputStream(), Charset.defaultCharset());
187 | addInfo(String.format("Response result: %s", response));
188 | return true;
189 | }
190 |
191 | protected HttpURLConnection openConnection() {
192 | HttpURLConnection conn = null;
193 | try {
194 | URL urlObj = new URL(protocol, url, port, path);
195 | addInfo("URL: " + urlObj.toString());
196 | conn = (HttpURLConnection) urlObj.openConnection();
197 | conn.setRequestMethod("POST");
198 | return conn;
199 | } catch (Exception e) {
200 | addError("Error to open connection Exception: ", e);
201 | return null;
202 | } finally {
203 | try {
204 | if (conn != null) {
205 | conn.disconnect();
206 | }
207 | } catch (Exception e) {
208 | addError("Error to open connection Exception: ", e);
209 | return null;
210 | }
211 | }
212 | }
213 |
214 | public Layout getLayout() {
215 | return layout;
216 | }
217 |
218 | public void setLayout(Layout layout) {
219 | this.layout = layout;
220 | }
221 |
222 | public Encoder getEncoder() {
223 | return encoder;
224 | }
225 |
226 | public void setEncoder(Encoder encoder) {
227 | this.encoder = encoder;
228 | }
229 |
230 | public String getUrl() {
231 | return url;
232 | }
233 |
234 | public void setUrl(String url) {
235 | this.url = url;
236 | }
237 |
238 | public String getContentType() {
239 | return contentType;
240 | }
241 |
242 | public void setContentType(String contentType) {
243 | this.contentType = contentType;
244 | }
245 |
246 | public String getBody() {
247 | return body;
248 | }
249 |
250 | public void setBody(String body) {
251 | this.body = body;
252 | }
253 |
254 | public String getHeaders() {
255 | return headers;
256 | }
257 |
258 | public void setHeaders(String headers) {
259 | this.headers = headers;
260 | }
261 |
262 | public int getPort() {
263 | return port;
264 | }
265 |
266 | public String getProtocol() {
267 | return protocol;
268 | }
269 |
270 | public void setProtocol(String protocol) {
271 | this.protocol = protocol;
272 | }
273 |
274 | public void setPort(int port) {
275 | this.port = port;
276 | }
277 |
278 | public String getPath() {
279 | return path;
280 | }
281 |
282 | public void setPath(String path) {
283 | this.path = path;
284 | }
285 |
286 | public int getReconnectDelay() {
287 | return reconnectDelay;
288 | }
289 |
290 | public void setReconnectDelay(int reconnectDelay) {
291 | this.reconnectDelay = reconnectDelay;
292 | }
293 |
294 | protected static boolean isStringEmptyOrNull(String value){
295 | return value == null || value.isEmpty();
296 | }
297 | }
--------------------------------------------------------------------------------