Read from stdin and forward.
This commit is contained in:
parent
d3589faf9e
commit
422f1fbb71
|
@ -27,14 +27,15 @@ Some of my other related projects are:
|
|||
- Install the syslogd package (*.deb* or *.rpm*) from [packages](https://git.data.coop/nellemann/-/packages/generic/syslogd/) or build from source.
|
||||
|
||||
```text
|
||||
Usage: syslogd [-dhV] [--[no-]ansi] [--[no-]stdout] [--[no-]tcp] [--[no-]udp]
|
||||
[-f=<protocol>] [-p=<num>] [--to-gelf=<uri>] [--to-loki=<url>]
|
||||
[--to-syslog=<uri>]
|
||||
Usage: syslogd [-dhV] [--[no-]ansi] [--[no-]stdin] [--[no-]stdout] [--[no-]tcp]
|
||||
[--[no-]udp] [-f=<protocol>] [-p=<num>] [--to-gelf=<uri>]
|
||||
[--to-loki=<url>] [--to-syslog=<uri>]
|
||||
-d, --debug Enable debugging [default: 'false'].
|
||||
-f, --format=<protocol> Input format: RFC-5424, RFC-3164 or GELF [default:
|
||||
RFC-3164].
|
||||
-h, --help Show this help message and exit.
|
||||
--[no-]ansi Output in ANSI colors [default: true].
|
||||
--[no-]stdin Forward messages from stdin [default: true].
|
||||
--[no-]stdout Output messages to stdout [default: true].
|
||||
--[no-]tcp Listen on TCP [default: true].
|
||||
--[no-]udp Listen on UDP [default: true].
|
||||
|
|
|
@ -13,12 +13,12 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
annotationProcessor 'info.picocli:picocli-codegen:4.7.0'
|
||||
implementation 'info.picocli:picocli:4.7.0'
|
||||
annotationProcessor 'info.picocli:picocli-codegen:4.7.1'
|
||||
implementation 'info.picocli:picocli:4.7.1'
|
||||
implementation 'org.slf4j:slf4j-api:2.0.6'
|
||||
implementation 'org.slf4j:slf4j-simple:2.0.6'
|
||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.1'
|
||||
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.1'
|
||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
|
||||
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.2'
|
||||
implementation 'org.apache.commons:commons-collections4:4.4'
|
||||
|
||||
testImplementation 'org.spockframework:spock-core:2.3-groovy-3.0'
|
||||
|
|
|
@ -1 +1 @@
|
|||
<mxfile host="drawio-plugin" modified="2022-12-07T07:21:50.025Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36" etag="0NRdR40T7b5zyLZSsQHk" version="20.5.3" type="embed"><diagram id="23iRSUPoRavnBvh4doch" name="Page-1"><mxGraphModel dx="1115" dy="620" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0"><root><mxCell id="0"/><mxCell id="1" parent="0"/><mxCell id="10" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;curved=1;sketch=1;shadow=1;" parent="1" source="2" target="3" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell id="2" value="RFC--3164" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;shadow=1;fillColor=#ffe6cc;strokeColor=#d79b00;" parent="1" vertex="1"><mxGeometry x="100" y="40" width="120" height="60" as="geometry"/></mxCell><mxCell id="13" style="edgeStyle=orthogonalEdgeStyle;curved=1;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;shadow=1;" parent="1" source="3" target="9" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell id="14" style="edgeStyle=orthogonalEdgeStyle;curved=1;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;shadow=1;" parent="1" source="3" target="6" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell id="15" style="edgeStyle=orthogonalEdgeStyle;curved=1;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;shadow=1;" parent="1" source="3" target="7" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell id="16" style="edgeStyle=orthogonalEdgeStyle;curved=1;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;shadow=1;" parent="1" source="3" target="8" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell id="3" value="syslogd" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;sketch=1;rounded=1;shadow=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1"><mxGeometry x="280" y="130" width="120" height="60" as="geometry"/></mxCell><mxCell id="11" style="edgeStyle=orthogonalEdgeStyle;curved=1;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;shadow=1;" parent="1" source="4" target="3" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell id="4" value="RFC--5424" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;shadow=1;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1"><mxGeometry x="20" y="130" width="120" height="60" as="geometry"/></mxCell><mxCell id="12" style="edgeStyle=orthogonalEdgeStyle;curved=1;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;shadow=1;" parent="1" source="5" target="3" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell id="5" value="GELF" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;shadow=1;fillColor=#f8cecc;strokeColor=#b85450;" parent="1" vertex="1"><mxGeometry x="130" y="223.5" width="120" height="60" as="geometry"/></mxCell><mxCell id="6" value="Syslog<br>RFC-5424" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;shadow=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1"><mxGeometry x="570" y="80" width="120" height="60" as="geometry"/></mxCell><mxCell id="7" value="Grafana Loki" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;shadow=1;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1"><mxGeometry x="550" y="170" width="120" height="60" as="geometry"/></mxCell><mxCell id="8" value="Graylog" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;shadow=1;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1"><mxGeometry x="420" y="250" width="120" height="60" as="geometry"/></mxCell><mxCell id="9" value="Standard<br>Output" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;shadow=1;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1"><mxGeometry x="410" y="30" width="120" height="60" as="geometry"/></mxCell></root></mxGraphModel></diagram></mxfile>
|
||||
<mxfile host="drawio-plugin" modified="2023-02-05T13:04:08.556Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36" etag="__kq9uG-1g-sjP8t85Xj" version="20.5.3" type="embed"><diagram id="23iRSUPoRavnBvh4doch" name="Page-1"><mxGraphModel dx="809" dy="749" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0"><root><mxCell id="0"/><mxCell id="1" parent="0"/><mxCell id="10" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;curved=1;sketch=1;shadow=1;" parent="1" source="2" target="3" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell id="2" value="Syslog<br>RFC--3164" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;shadow=1;fillColor=#ffe6cc;strokeColor=#d79b00;" parent="1" vertex="1"><mxGeometry x="50" y="90" width="120" height="60" as="geometry"/></mxCell><mxCell id="13" style="edgeStyle=orthogonalEdgeStyle;curved=1;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;shadow=1;" parent="1" source="3" target="9" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell id="14" style="edgeStyle=orthogonalEdgeStyle;curved=1;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;shadow=1;" parent="1" source="3" target="6" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell id="15" style="edgeStyle=orthogonalEdgeStyle;curved=1;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;shadow=1;" parent="1" source="3" target="7" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell id="16" style="edgeStyle=orthogonalEdgeStyle;curved=1;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;shadow=1;" parent="1" source="3" target="8" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell id="3" value="syslogd" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;sketch=1;rounded=1;shadow=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1"><mxGeometry x="280" y="130" width="120" height="60" as="geometry"/></mxCell><mxCell id="11" style="edgeStyle=orthogonalEdgeStyle;curved=1;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;shadow=1;" parent="1" source="4" target="3" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell id="4" value="Syslog<br>RFC--5424" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;shadow=1;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1"><mxGeometry x="40" y="180" width="120" height="60" as="geometry"/></mxCell><mxCell id="12" style="edgeStyle=orthogonalEdgeStyle;curved=1;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;shadow=1;" parent="1" source="5" target="3" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell id="5" value="GELF" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;shadow=1;fillColor=#f8cecc;strokeColor=#b85450;" parent="1" vertex="1"><mxGeometry x="120" y="260" width="120" height="60" as="geometry"/></mxCell><mxCell id="6" value="Syslog<br>RFC-5424" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;shadow=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1"><mxGeometry x="570" y="80" width="120" height="60" as="geometry"/></mxCell><mxCell id="7" value="Grafana Loki" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;shadow=1;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1"><mxGeometry x="550" y="170" width="120" height="60" as="geometry"/></mxCell><mxCell id="8" value="Graylog" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;shadow=1;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1"><mxGeometry x="420" y="250" width="120" height="60" as="geometry"/></mxCell><mxCell id="9" value="Standard<br>Output" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;shadow=1;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1"><mxGeometry x="410" y="30" width="120" height="60" as="geometry"/></mxCell><mxCell id="17" value="Standard<br>Input" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;shadow=1;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1"><mxGeometry x="180" y="30" width="90" height="60" as="geometry"/></mxCell><mxCell id="19" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;curved=1;sketch=1;shadow=1;" edge="1" parent="1" source="17" target="3"><mxGeometry relative="1" as="geometry"><mxPoint x="190" y="110" as="sourcePoint"/><mxPoint x="300" y="170" as="targetPoint"/></mxGeometry></mxCell></root></mxGraphModel></diagram></mxfile>
|
BIN
doc/syslogd.png
BIN
doc/syslogd.png
Binary file not shown.
Before Width: | Height: | Size: 172 KiB After Width: | Height: | Size: 96 KiB |
|
@ -1,5 +1,5 @@
|
|||
id = syslogd
|
||||
name = syslogd
|
||||
group = biz.nellemann.syslogd
|
||||
version = 1.3.3
|
||||
version = 1.3.4
|
||||
description = "Syslog Director"
|
||||
|
|
|
@ -58,6 +58,9 @@ public class Application implements Callable<Integer>, LogReceiveListener {
|
|||
@CommandLine.Option(names = "--no-stdout", negatable = true, description = "Output messages to stdout [default: true].", defaultValue = "true")
|
||||
private boolean stdout;
|
||||
|
||||
@CommandLine.Option(names = "--no-stdin", negatable = true, description = "Forward messages from stdin [default: true].", defaultValue = "true")
|
||||
private boolean stdin;
|
||||
|
||||
@CommandLine.Option(names = {"-f", "--format"}, description = "Input format: RFC-5424, RFC-3164 or GELF [default: RFC-3164].", defaultValue = "RFC-3164")
|
||||
private String protocol;
|
||||
|
||||
|
@ -77,7 +80,6 @@ public class Application implements Callable<Integer>, LogReceiveListener {
|
|||
@Override
|
||||
public Integer call() throws IOException {
|
||||
|
||||
|
||||
if(enableDebug) {
|
||||
System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "DEBUG");
|
||||
}
|
||||
|
@ -115,6 +117,12 @@ public class Application implements Callable<Integer>, LogReceiveListener {
|
|||
t.start();
|
||||
}
|
||||
|
||||
if(stdin) {
|
||||
InputReader inputReader = new InputReader(System.in, protocol);
|
||||
inputReader.addEventListener(this);
|
||||
inputReader.start();
|
||||
}
|
||||
|
||||
if(udpServer) {
|
||||
UdpServer udpServer = new UdpServer(port);
|
||||
udpServer.addEventListener(this);
|
||||
|
|
69
src/main/java/biz/nellemann/syslogd/InputReader.java
Normal file
69
src/main/java/biz/nellemann/syslogd/InputReader.java
Normal file
|
@ -0,0 +1,69 @@
|
|||
package biz.nellemann.syslogd;
|
||||
|
||||
import biz.nellemann.syslogd.msg.SyslogMessage;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class InputReader extends Thread {
|
||||
|
||||
private final Scanner input;
|
||||
private final String protocol;
|
||||
|
||||
public InputReader(InputStream inputStream, String protocol) {
|
||||
input = new Scanner(inputStream);
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
while(input.hasNextLine()) {
|
||||
SyslogMessage msg = new SyslogMessage(input.nextLine());
|
||||
msg.hostname = "localhost";
|
||||
msg.application = "syslogd";
|
||||
|
||||
String payload;
|
||||
if(protocol.equalsIgnoreCase("GELF"))
|
||||
payload = SyslogPrinter.toGelf(msg);
|
||||
else if (protocol.equalsIgnoreCase("RFC-5424")) {
|
||||
payload = SyslogPrinter.toRfc5424(msg);
|
||||
} else {
|
||||
payload = SyslogPrinter.toRfc3164(msg);
|
||||
}
|
||||
|
||||
sendEvent(payload);
|
||||
}
|
||||
input.close();
|
||||
}
|
||||
|
||||
|
||||
private synchronized void sendEvent(String text) {
|
||||
LogReceiveEvent event = new LogReceiveEvent( this, text);
|
||||
for (LogReceiveListener eventListener : eventListeners) {
|
||||
eventListener.onLogEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Event Listener Configuration
|
||||
*/
|
||||
|
||||
protected List<LogReceiveListener> eventListeners = new ArrayList<>();
|
||||
|
||||
public synchronized void addEventListener(LogReceiveListener listener ) {
|
||||
eventListeners.add( listener );
|
||||
}
|
||||
|
||||
public synchronized void addEventListener(List<LogReceiveListener> listeners ) {
|
||||
eventListeners.addAll(listeners);
|
||||
}
|
||||
|
||||
public synchronized void removeEventListener( LogReceiveListener l ) {
|
||||
eventListeners.remove( l );
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -23,15 +23,13 @@ import java.util.EventObject;
|
|||
public class LogReceiveEvent extends EventObject {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
//private final String message;
|
||||
private final DatagramPacket packet;
|
||||
|
||||
/*
|
||||
public LogReceiveEvent(final Object source, final String message ) {
|
||||
super( source );
|
||||
this.message = message;
|
||||
byte[] bytes = message.getBytes();
|
||||
this.packet = new DatagramPacket(bytes, bytes.length);
|
||||
}
|
||||
*/
|
||||
|
||||
public LogReceiveEvent(final Object source, final DatagramPacket packet) {
|
||||
super( source );
|
||||
|
|
|
@ -36,7 +36,7 @@ public class SyslogMessage {
|
|||
|
||||
// The TIMESTAMP field is a formalized timestamp derived from [RFC3339].
|
||||
@JsonProperty("timestamp") // 1670357783.694 - in GELF: seconds since UNIX epoch with optional decimal places for milliseconds
|
||||
public Instant timestamp;
|
||||
public Instant timestamp = Instant.now();
|
||||
|
||||
// The HOSTNAME field identifies the machine that originally sent the syslog message.
|
||||
@JsonProperty("host")
|
||||
|
|
|
@ -8,6 +8,10 @@ public class JsonUtil {
|
|||
|
||||
public static String encode(String input) {
|
||||
|
||||
if(input == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
StringBuilder output = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < input.length(); i++) {
|
||||
|
|
|
@ -73,7 +73,7 @@ public abstract class SyslogParser {
|
|||
Inflater decompressor = new Inflater();
|
||||
decompressor.setInput(data, 0, data.length);
|
||||
//byte[] result = new byte[data.length * 2];
|
||||
int resultLength = decompressor.inflate(result);
|
||||
decompressor.inflate(result);
|
||||
decompressor.end();
|
||||
|
||||
// Decode the bytes into a String
|
||||
|
|
Loading…
Reference in a new issue