2020-09-22 18:45:16 +00:00
|
|
|
/*
|
|
|
|
Copyright 2020 mark.nellemann@gmail.com
|
|
|
|
|
|
|
|
Licensed 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.
|
|
|
|
*/
|
2020-09-22 18:33:22 +00:00
|
|
|
package biz.nellemann.syslogd;
|
|
|
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import picocli.CommandLine;
|
|
|
|
import picocli.CommandLine.Command;
|
2020-10-05 08:40:42 +00:00
|
|
|
|
2020-10-07 10:33:54 +00:00
|
|
|
import java.io.IOException;
|
2020-09-22 18:33:22 +00:00
|
|
|
import java.util.concurrent.Callable;
|
|
|
|
|
2020-10-05 08:40:42 +00:00
|
|
|
@Command(name = "syslogd",
|
|
|
|
mixinStandardHelpOptions = true,
|
2021-01-26 14:24:23 +00:00
|
|
|
description = "Syslog Daemon.",
|
2020-10-05 08:40:42 +00:00
|
|
|
versionProvider = biz.nellemann.syslogd.VersionProvider.class)
|
2020-12-15 09:29:54 +00:00
|
|
|
public class Application implements Callable<Integer>, LogListener {
|
2020-09-22 18:33:22 +00:00
|
|
|
|
2020-12-15 09:29:54 +00:00
|
|
|
private final static Logger log = LoggerFactory.getLogger(Application.class);
|
2020-09-22 18:33:22 +00:00
|
|
|
|
2021-01-26 14:24:23 +00:00
|
|
|
@CommandLine.Option(names = {"-p", "--port"}, description = "Listening port [default: 514].", defaultValue = "514")
|
|
|
|
private int port;
|
2020-09-22 18:33:22 +00:00
|
|
|
|
2021-01-26 14:24:23 +00:00
|
|
|
@CommandLine.Option(names = "--no-udp", negatable = true, description = "Listen on UDP [default: true].", defaultValue = "true")
|
|
|
|
private boolean udpServer;
|
2020-09-22 18:33:22 +00:00
|
|
|
|
2021-01-26 14:24:23 +00:00
|
|
|
@CommandLine.Option(names = "--no-tcp", negatable = true, description = "Listen on TCP [default: true].", defaultValue = "true")
|
|
|
|
private boolean tcpServer;
|
2020-09-22 18:33:22 +00:00
|
|
|
|
2021-01-26 14:24:23 +00:00
|
|
|
@CommandLine.Option(names = "--no-ansi", negatable = true, description = "Output ANSI colors [default: true].", defaultValue = "true")
|
|
|
|
private boolean ansiOutput;
|
2020-10-05 08:40:42 +00:00
|
|
|
|
2021-01-26 14:24:23 +00:00
|
|
|
@CommandLine.Option(names = "--no-stdout", negatable = true, description = "Output messages to stdout [default: true].", defaultValue = "true")
|
|
|
|
private boolean stdout;
|
2020-10-07 10:33:54 +00:00
|
|
|
|
2021-01-26 14:24:23 +00:00
|
|
|
@CommandLine.Option(names = "--rfc5424", description = "Parse RFC-5424 messages [default: RFC-3164].", defaultValue = "false")
|
|
|
|
private boolean rfc5424;
|
2020-10-05 08:40:42 +00:00
|
|
|
|
2021-01-26 14:24:23 +00:00
|
|
|
@CommandLine.Option(names = { "-f", "--forward"}, description = "Forward messages (UDP RFC-3164) [default: false].", defaultValue = "false")
|
|
|
|
private boolean forward;
|
|
|
|
|
|
|
|
@CommandLine.Option(names = "--forward-host", description = "Forward to host [default: localhost].", paramLabel = "<hostname>", defaultValue = "localhost")
|
|
|
|
private String forwardHost;
|
2020-09-22 18:33:22 +00:00
|
|
|
|
2021-01-26 14:24:23 +00:00
|
|
|
@CommandLine.Option(names = "--forward-port", description = "Forward to port [default: 1514].", paramLabel = "<port>", defaultValue = "1514")
|
|
|
|
private int forwardPort;
|
|
|
|
|
|
|
|
private UdpClient udpClient;
|
2020-09-22 18:33:22 +00:00
|
|
|
|
|
|
|
@Override
|
2020-10-07 10:33:54 +00:00
|
|
|
public Integer call() throws IOException {
|
2020-10-05 08:40:42 +00:00
|
|
|
|
2021-01-26 14:24:23 +00:00
|
|
|
if(forward) {
|
|
|
|
udpClient = new UdpClient(forwardHost, forwardPort);
|
|
|
|
}
|
|
|
|
|
2020-09-22 18:33:22 +00:00
|
|
|
if(udpServer) {
|
|
|
|
UdpServer udpServer = new UdpServer(port);
|
|
|
|
udpServer.addEventListener(this);
|
|
|
|
udpServer.start();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(tcpServer) {
|
|
|
|
TcpServer tcpServer = new TcpServer(port);
|
|
|
|
tcpServer.addEventListener(this);
|
|
|
|
tcpServer.start();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onLogEvent(LogEvent event) {
|
|
|
|
|
2020-10-05 08:40:42 +00:00
|
|
|
// Parse message
|
2020-09-22 18:33:22 +00:00
|
|
|
String message = event.getMessage();
|
|
|
|
SyslogMessage msg = null;
|
|
|
|
try {
|
2020-10-05 15:59:31 +00:00
|
|
|
if(rfc5424) {
|
2020-09-23 05:01:55 +00:00
|
|
|
msg = SyslogParser.parseRfc5424(message);
|
2020-10-05 15:59:31 +00:00
|
|
|
} else {
|
|
|
|
msg = SyslogParser.parseRfc3164(message);
|
2020-09-22 18:33:22 +00:00
|
|
|
}
|
|
|
|
} catch(Exception e) {
|
2021-01-26 14:24:23 +00:00
|
|
|
log.error("onLogEvent() - Error parsing message: ", e);
|
2020-09-22 18:33:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(msg != null) {
|
2021-01-26 14:24:23 +00:00
|
|
|
|
|
|
|
if(stdout) {
|
|
|
|
if(ansiOutput) {
|
|
|
|
System.out.println(SyslogPrinter.toAnsiString(msg));
|
|
|
|
} else {
|
|
|
|
System.out.println(SyslogPrinter.toString(msg));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(forward) {
|
|
|
|
try {
|
|
|
|
udpClient.send(SyslogPrinter.toRfc3164(msg));
|
|
|
|
} catch (Exception e) {
|
|
|
|
log.error("onLogEvent()", e);
|
|
|
|
}
|
2020-10-05 08:40:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-01-26 14:24:23 +00:00
|
|
|
|
|
|
|
public static void main(String... args) {
|
|
|
|
int exitCode = new CommandLine(new Application()).execute(args);
|
|
|
|
System.exit(exitCode);
|
|
|
|
}
|
|
|
|
|
2020-09-22 18:33:22 +00:00
|
|
|
}
|