blob: aed434dc64d2d2ede79ba171f3794aa9695f3d87 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache license, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the license for the specific language governing permissions and
* limitations under the license.
*/
package org.apache.logging.log4j.core.appender;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.message.StructuredDataMessage;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
*
*/
public class SyslogAppenderTest {
private static final String HOST = "localhost";
private static final String PORT = "8199";
private static final int PORTNUM = Integer.parseInt(PORT);
private static BlockingQueue<String> list = new ArrayBlockingQueue<String>(10);
private static TCPSocketServer tcp;
private static UDPSocketServer udp;
LoggerContext ctx = (LoggerContext) LogManager.getContext();
Logger root = ctx.getLogger("SyslogAppenderTest");
private static int tcpCount = 0;
private static int udpCount = 0;
private static final String line1 =
"TestApp - Audit [Transfer@18060 Amount=\"200.00\" FromAccount=\"123457\" ToAccount=\"123456\"]" +
"[RequestContext@18060 ipAddress=\"192.168.0.120\" loginId=\"JohnDoe\"] Transfer Complete\n";
@BeforeClass
public static void setupClass() throws Exception {
tcp = new TCPSocketServer();
tcp.start();
udp = new UDPSocketServer();
udp.start();
((LoggerContext) LogManager.getContext()).reconfigure();
}
@AfterClass
public static void cleanupClass() {
tcp.shutdown();
udp.shutdown();
}
@After
public void teardown() {
Map<String,Appender> map = root.getAppenders();
for (Map.Entry<String, Appender> entry : map.entrySet()) {
Appender app = entry.getValue();
root.removeAppender(app);
app.stop();
}
tcpCount = 0;
udpCount = 0;
}
@Test
public void testTCPAppender() throws Exception {
SyslogAppender appender = createAppender("tcp", "bsd");
appender.start();
// set appender on root and set level to debug
root.addAppender(appender);
root.setAdditive(false);
root.setLevel(Level.DEBUG);
root.debug("This is a test message");
String msg = list.poll(3, TimeUnit.SECONDS);
assertNotNull("No event retrieved", msg);
assertTrue("Incorrect msg: " + msg, msg.endsWith("This is a test message\n"));
assertTrue("Message not delivered via TCP", tcpCount > 0);
root.debug("This is test message 2");
msg = list.poll(3, TimeUnit.SECONDS);
assertNotNull("No event retrieved", msg);
assertTrue("Incorrect msg: " + msg, msg.endsWith("This is test message 2\n"));
assertTrue("Message not delivered via TCP", tcpCount > 1);
}
@Test
public void testTCPStructuredAppender() throws Exception {
SyslogAppender appender = createAppender("tcp", "RFC5424");
appender.start();
// set appender on root and set level to debug
root.addAppender(appender);
root.setLevel(Level.DEBUG);
root.setAdditive(false);
ThreadContext.put("loginId", "JohnDoe");
ThreadContext.put("ipAddress", "192.168.0.120");
ThreadContext.put("locale", Locale.US.getDisplayName());
StructuredDataMessage msg = new StructuredDataMessage("Transfer@18060", "Transfer Complete", "Audit");
msg.put("ToAccount", "123456");
msg.put("FromAccount", "123457");
msg.put("Amount", "200.00");
root.info(MarkerManager.getMarker("EVENT"), msg);
String str = list.poll(3, TimeUnit.SECONDS);
assertNotNull("No event retrieved", str);
assertTrue("Incorrect msg: " + str, str.endsWith(line1));
assertTrue("Message not delivered via TCP", tcpCount > 0);
}
@Test
public void testUDPAppender() throws Exception {
SyslogAppender appender = createAppender("udp", "bsd");
appender.start();
// set appender on root and set level to debug
root.addAppender(appender);
root.setLevel(Level.DEBUG);
root.setAdditive(false);
root.debug("This is a test message");
String str = list.poll(3, TimeUnit.SECONDS);
assertNotNull("No event retrieved", str);
assertTrue("Incorrect msg: " + str, str.endsWith("This is a test message\n"));
assertTrue("Message not delivered via UDP", udpCount > 0);
root.removeAppender(appender);
appender.stop();
}
@Test
public void testUDPStructuredAppender() throws Exception {
SyslogAppender appender = createAppender("udp", "RFC5424");
appender.start();
// set appender on root and set level to debug
root.addAppender(appender);
root.setLevel(Level.DEBUG);
root.setAdditive(false);
ThreadContext.put("loginId", "JohnDoe");
ThreadContext.put("ipAddress", "192.168.0.120");
ThreadContext.put("locale", Locale.US.getDisplayName());
StructuredDataMessage msg = new StructuredDataMessage("Transfer@18060", "Transfer Complete", "Audit");
msg.put("ToAccount", "123456");
msg.put("FromAccount", "123457");
msg.put("Amount", "200.00");
root.info(MarkerManager.getMarker("EVENT"), msg);
String str = list.poll(3, TimeUnit.SECONDS);
assertNotNull("No event retrieved", str);
assertTrue("Incorrect msg: " + str, str.endsWith(line1));
assertTrue("Message not delivered via TCP", udpCount > 0);
root.removeAppender(appender);
appender.stop();
}
private SyslogAppender createAppender(String protocol, String format) {
return SyslogAppender.createAppender("localhost", PORT, protocol, "-1", "Test", "true", "false", "LOCAL0", "Audit",
"18060", "true", "RequestContext", "true", "TestApp", "Test", null, "ipAddress,loginId", null, format, null,
null, null);
}
public static class UDPSocketServer extends Thread {
private final DatagramSocket sock;
private boolean shutdown = false;
private Thread thread;
public UDPSocketServer() throws IOException {
this.sock = new DatagramSocket(PORTNUM);
}
public void shutdown() {
this.shutdown = true;
thread.interrupt();
}
public void run() {
this.thread = Thread.currentThread();
byte[] bytes = new byte[4096];
DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
try {
while (!shutdown) {
sock.receive(packet);
String str = new String(packet.getData(), 0, packet.getLength());
++udpCount;
list.add(str);
}
} catch (Exception ex) {
if (!shutdown) {
throw new RuntimeException(ex);
}
}
}
}
public static class TCPSocketServer extends Thread {
private final ServerSocket sock;
private boolean shutdown = false;
private Thread thread;
public TCPSocketServer() throws IOException {
this.sock = new ServerSocket(PORTNUM);
}
public void shutdown() {
this.shutdown = true;
thread.interrupt();
}
public void run() {
this.thread = Thread.currentThread();
try {
byte[] buffer = new byte[4096];
while (!shutdown) {
Socket socket = sock.accept();
StringBuilder sb = new StringBuilder();
if (socket != null) {
InputStream in = socket.getInputStream();
int i = in.read(buffer, 0, buffer.length);
while (i != -1) {
if (i < buffer.length) {
String line = new String(buffer, 0, i);
++tcpCount;
list.add(line);
i = in.read(buffer, 0, buffer.length);
} else if (i == 0) {
System.out.println("No data received");
} else {
System.out.println("Message too long");
}
}
socket.close();
}
}
} catch (Exception ex) {
if (!shutdown) {
throw new RuntimeException(ex);
}
}
}
}
}