Skip to content
This repository was archived by the owner on Feb 5, 2026. It is now read-only.

Commit 03f4def

Browse files
authored
Merge pull request #39 from renanstuchi/support_access_logs
Adding support for Logback-access events
2 parents 8e14012 + 9d8e7af commit 03f4def

File tree

7 files changed

+479
-270
lines changed

7 files changed

+479
-270
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,18 @@ Logentries handler configuration (e.g. to support different tokens).
6060
Logger logger1 = Logger.getLogger("logger1");
6161
Logger logger2 = Logger.getLogger("logger2");
6262
```
63+
-------
64+
65+
Logback Access Events
66+
==================
67+
This library allows you to setup logback access events, as part of the standard logback distribution, with Servlet
68+
containers such as Jetty or Tomcat to provide HTTP-access log functionality.
69+
70+
Instructions to setup logback access events can be found in the [Official logback-access documentation](https://logback.qos.ch/access.html)
71+
72+
After downloading the latest r7insight_java distribution, depending on your servlet container, place the r7insight_java-VERSION.jar under either :
73+
74+
* **$TOMCAT_HOME/lib/** directory, where $TOMCAT_HOME is the folder where you have installed Tomcat.
75+
* **$JETTY_HOME/lib** directory, where $JETTY_HOME is the folder where you have installed Jetty.
76+
77+
Refer to the sample logback-access.xml template provided and place the file according to the instructions in the logback-access documentation.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<configuration>
3+
<appender name="LE" class="com.rapid7.logback.access.LogentriesAccessAppender">
4+
<Token>LOGENTRIES_TOKEN</Token>
5+
<Region>eu</Region>
6+
<Ssl>true</Ssl>
7+
<encoder>
8+
<pattern>combined</pattern>
9+
</encoder>
10+
</appender>
11+
12+
<appender-ref ref="LE" />
13+
</configuration>

pom.xml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66

77
<jackson.version>2.15.0</jackson.version>
88
<log4j2.version>2.20.0</log4j2.version>
9+
<logback.version>1.3.8</logback.version>
910
<junit.version>5.9.3</junit.version>
1011
<mockito.version>4.11.0</mockito.version>
1112

1213
<disruptor.version>4.0.0.RC1</disruptor.version>
14+
<javax.servlet.version>4.0.1</javax.servlet.version>
1315
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1416
</properties>
1517

@@ -213,10 +215,22 @@
213215
<dependency>
214216
<groupId>ch.qos.logback</groupId>
215217
<artifactId>logback-classic</artifactId>
216-
<version>1.2.3</version>
218+
<version>${logback.version}</version>
219+
<optional>true</optional>
220+
</dependency>
221+
<dependency>
222+
<groupId>ch.qos.logback</groupId>
223+
<artifactId>logback-access</artifactId>
224+
<version>${logback.version}</version>
217225
<optional>true</optional>
218226
</dependency>
219227
<!-- TEST -->
228+
<dependency>
229+
<groupId>javax.servlet</groupId>
230+
<artifactId>javax.servlet-api</artifactId>
231+
<version>${javax.servlet.version}</version>
232+
<scope>provided</scope>
233+
</dependency>
220234
<dependency>
221235
<groupId>org.junit.jupiter</groupId>
222236
<artifactId>junit-jupiter-engine</artifactId>

src/main/java/com/rapid7/logback/LogentriesAppender.java

Lines changed: 9 additions & 269 deletions
Original file line numberDiff line numberDiff line change
@@ -8,292 +8,32 @@
88
import ch.qos.logback.core.encoder.Encoder;
99
import ch.qos.logback.core.encoder.LayoutWrappingEncoder;
1010
import ch.qos.logback.core.net.SyslogConstants;
11+
import com.rapid7.logback.LogentriesAppenderBase;
1112
import com.rapid7.net.AsyncLogger;
1213
import com.rapid7.net.LoggerConfiguration;
1314

1415
import static java.nio.charset.StandardCharsets.UTF_8;
1516

17+
1618
/**
17-
* Logentries appender for logback.
19+
* Logentries appender for logback-classic events.
1820
*
19-
* @author Mark Lacomber
20-
* @author Ben McCann
21-
* @author Chris Mowforth
21+
* @author Renan Stuchi
2222
*/
23-
public class LogentriesAppender extends AppenderBase<ILoggingEvent> {
23+
public class LogentriesAppender extends LogentriesAppenderBase<ILoggingEvent, PatternLayout> {
2424

2525
/**
2626
* Default Suffix Pattern
2727
*/
2828
public static final String DEFAULT_SUFFIX_PATTERN = "[%thread] %logger %msg";
29-
/**
30-
* Asynchronous Background logger
31-
*/
32-
AsyncLogger iopsAsync;
33-
34-
private final LoggerConfiguration.Builder configurationBuilder;
35-
/**
36-
* Layout
37-
*/
38-
private Layout<ILoggingEvent> layout;
39-
40-
private Encoder<ILoggingEvent> encoder;
41-
/**
42-
* Facility String
43-
*/
44-
private String facilityStr;
45-
private String suffixPattern;
46-
47-
/**
48-
* Creates a new Logentries appender.
49-
*/
50-
public LogentriesAppender() {
51-
configurationBuilder = new LoggerConfiguration.Builder();
52-
}
53-
54-
55-
/*
56-
* Public methods to send logback parameters to AsyncLogger
57-
*/
58-
59-
/**
60-
* Sets the token.
61-
*
62-
* @param token Insight OPS token
63-
*/
64-
public void setToken(String token) {
65-
this.configurationBuilder.useToken(token);
66-
}
67-
68-
/**
69-
* Sets the region.
70-
*
71-
* @param region region to send the log to (e.g. eu or us)
72-
*/
73-
public void setRegion(String region) {
74-
this.configurationBuilder.inRegion(region);
75-
}
76-
77-
/**
78-
* Sets the HTTP PUTflag. <p>Send logs via HTTP PUT instead of default Token
79-
* TCP.</p>
80-
*
81-
* @param httpPut true to use HTTP PUT API
82-
*/
83-
public void setHttpPut(boolean httpPut) {
84-
this.configurationBuilder.useHttpPut(httpPut);
85-
}
86-
87-
/**
88-
* Sets the ACCOUNT KEY value for HTTP PUT.
89-
*
90-
* @param accountKey account key value (for http put only)
91-
*/
92-
public void setKey(String accountKey) {
93-
this.configurationBuilder.useAccountKey(accountKey);
94-
}
95-
96-
/**
97-
* Sets the LOCATION value for HTTP PUT.
98-
*
99-
* @param logLocation location on server (for http put only)
100-
*/
101-
public void setLocation(String logLocation) {
102-
this.configurationBuilder.httpPutLocation(logLocation);
103-
}
104-
105-
/**
106-
* Sets the SSL boolean flag
107-
*
108-
* @param ssl true to send logs encrypted over ssl/tls
109-
*/
110-
public void setSsl(boolean ssl) {
111-
this.configurationBuilder.useSSL(ssl);
112-
}
113-
114-
/**
115-
* Sets the debug flag.
116-
* <p>Appender in debug mode will print error messages on error console.</p>
117-
*
118-
* @param debug debug flag to set
119-
*/
120-
public void setDebug(boolean debug) {
121-
this.configurationBuilder.runInDebugMode(debug);
122-
}
123-
124-
/**
125-
* Sets the flag which determines if DataHub instance is used instead of Logentries service.
126-
*
127-
* @param useDataHub set to true to send log messaged to a DataHub instance.
128-
*/
129-
public void setIsUsingDataHub(boolean useDataHub) {
130-
this.configurationBuilder.useDataHub(useDataHub);
131-
}
132-
133-
/**
134-
* Sets the address where DataHub server resides.
135-
*
136-
* @param dataHubAddr address like "127.0.0.1"
137-
*/
138-
public void setDataHubAddr(String dataHubAddr) {
139-
this.configurationBuilder.toServerAddress(dataHubAddr);
140-
}
141-
142-
/**
143-
* Sets the port number on which DataHub instance waits for log messages.
144-
*
145-
* @param dataHubPort data hub port number
146-
*/
147-
public void setDataHubPort(int dataHubPort) {
148-
this.configurationBuilder.toServerPort(dataHubPort);
149-
}
150-
151-
/**
152-
* Determines whether to send HostName alongside with the log message
153-
*
154-
* @param logHostName true to add server host name as log prefix
155-
*/
156-
public void setLogHostName(boolean logHostName) {
157-
this.configurationBuilder.logHostNameAsPrefix(logHostName);
158-
}
159-
160-
/**
161-
* Sets the HostName from the configuration
162-
*
163-
* @param hostName host name value
164-
*/
165-
public void setHostName(String hostName) {
166-
this.configurationBuilder.useAsHostName(hostName);
167-
}
168-
169-
/**
170-
* Sets LogID parameter from the configuration
171-
*
172-
* @param logID log prefix
173-
*/
174-
public void setLogID(String logID) {
175-
this.configurationBuilder.setLogIdPrefix(logID);
176-
}
177-
178-
/**
179-
* Sets the encoder for this appender
180-
*
181-
* @param encoder Logback Encoder
182-
*/
183-
public void setEncoder(Encoder<ILoggingEvent> encoder) {
184-
this.encoder = encoder;
185-
}
18629

18730
@Override
188-
public void start() {
189-
if (encoder == null) {
190-
layout = layout == null ? buildLayout() : layout;
191-
LayoutWrappingEncoder<ILoggingEvent> lwe = new LayoutWrappingEncoder<>();
192-
lwe.setLayout(layout);
193-
lwe.setContext(getContext());
194-
encoder = lwe;
195-
}
196-
this.iopsAsync = new AsyncLogger(configurationBuilder.build());
197-
super.start();
198-
}
199-
200-
String getPrefixPattern() {
201-
return "%syslogStart{" + getFacility() + "}%nopex";
31+
public PatternLayout getPatternLayout() {
32+
return new PatternLayout();
20233
}
20334

204-
/**
205-
* Returns the string value of the <b>Facility</b> option.
206-
* <p>
207-
* See {@link #setFacility} for the set of allowed values.
208-
* @return facility name
209-
*/
210-
public String getFacility() {
211-
return facilityStr;
212-
}
213-
214-
/**
215-
* The <b>Facility</b> option must be set one of the strings KERN, USER,
216-
* MAIL, DAEMON, AUTH, SYSLOG, LPR, NEWS, UUCP, CRON, AUTHPRIV, FTP, NTP,
217-
* AUDIT, ALERT, CLOCK, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5,
218-
* LOCAL6, LOCAL7. Case is not important.
219-
* <p>See {@link SyslogConstants} and RFC 3164 for more information about
220-
* the <b>Facility</b> option.
221-
*
222-
* @param facilityStr facility name
223-
*/
224-
public void setFacility(String facilityStr) {
225-
if (facilityStr != null) {
226-
facilityStr = facilityStr.trim();
227-
}
228-
this.facilityStr = facilityStr;
229-
}
230-
231-
public Layout<ILoggingEvent> getLayout() {
232-
return layout;
233-
}
234-
235-
/**
236-
* Sets the layout for the Appender
237-
*
238-
* @param layout logback layout
239-
*/
240-
public void setLayout(Layout<ILoggingEvent> layout) {
241-
this.layout = layout;
242-
}
243-
244-
/**
245-
* Implements AppenderSkeleton Append method, handles time and format
246-
*
247-
* @param event event to log
248-
*/
249-
@Override
250-
protected void append(ILoggingEvent event) {
251-
// Render the event according to layout
252-
byte[] encodedEvent = encoder.encode(event);
253-
String formattedEvent;
254-
formattedEvent = new String(encodedEvent, UTF_8);
255-
256-
// Prepare to be queued
257-
this.iopsAsync.addLineToQueue(formattedEvent);
258-
}
259-
260-
/**
261-
* Closes all connections to Logentries
262-
*/
26335
@Override
264-
public void stop() {
265-
super.stop();
266-
this.iopsAsync.close();
267-
}
268-
269-
public Layout<ILoggingEvent> buildLayout() {
270-
PatternLayout l = new PatternLayout();
271-
l.getInstanceConverterMap().put("syslogStart", SyslogStartConverter.class.getName());
272-
if (suffixPattern == null) {
273-
suffixPattern = DEFAULT_SUFFIX_PATTERN;
274-
}
275-
l.setPattern(getPrefixPattern() + suffixPattern);
276-
l.setContext(getContext());
277-
l.start();
278-
return l;
279-
}
280-
281-
/**
282-
* See @link #setSuffixPattern(String).
283-
*
284-
* @return suffix pattern
285-
*/
286-
public String getSuffixPattern() {
287-
return suffixPattern;
288-
}
289-
290-
/**
291-
* The <b>suffixPattern</b> option specifies the format of the
292-
* non-standardized part of the message sent to the syslog server.
293-
*
294-
* @param suffixPattern suffix pattern
295-
*/
296-
public void setSuffixPattern(String suffixPattern) {
297-
this.suffixPattern = suffixPattern;
36+
public String getDefaultSuffixPattern() {
37+
return DEFAULT_SUFFIX_PATTERN;
29838
}
29939
}

0 commit comments

Comments
 (0)