Listen to JSON UPD from LogstashSocketAppender - advantageous/rsyslog-journald-repeater GitHub Wiki

LogstashSocketAppender

<configuration>

    <!--<appender name="SYSLOG" class="ch.qos.logback.classic.net.SyslogAppender">-->
        <!--<syslogHost>localhost</syslogHost>-->
        <!--<port>5514</port>-->
        <!--<facility>AUTH</facility>-->
        <!--<suffixPattern>[%thread] %logger %msg</suffixPattern>-->
    <!--</appender>-->

    <appender name="STASH-UDP" class="net.logstash.logback.appender.LogstashSocketAppender">
        <host>localhost</host>
        <port>5514</port>
        <customFields>
            {
            "serviceName":"impressionsService",
            "serviceHost":"${HOST}",
            "servicePort":"${PORT0}",
            "serviceId":"impressions-${HOST}-${PORT0}",
            "serviceAdminPort":"${PORT1}"
            }
        </customFields>
    </appender>


    <root level="DEBUG">
        <!--<appender-ref ref="SYSLOG" />-->
        <appender-ref ref="STASH-UDP" />
    </root>
</configuration>

Simple POC written in golang.

package main


import (

	"net"
	"fmt"
)

func main() {
	addr, err := net.ResolveUDPAddr("udp", "0.0.0.0:5514")

	if err != nil {
		panic(err)
	}


	conn, err := net.ListenUDP("udp",  addr)
	if err != nil {
		panic(err)
	}

	for {
		var buf [1024]byte
		n, err := conn.Read(buf[:])
		if err != nil {
			panic(err)
		}
		fmt.Printf("%s\n\n", string(buf[:n]));
	}
}
package org.example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;



public class Main {

    public static void main(String args[]) throws Exception{



        System.out.println("THIS FAR 1");
        Logger logger = LoggerFactory.getLogger(Main.class);
        System.out.println("THIS FAR 2");

        for (int i =0; i < 10; i++) {
            logger.info("HELLO CRUEL WORLD " + i);
        }

        System.out.println("DONE");

        Thread.sleep(10000);
    }
}

Output

{"@timestamp":"2016-12-12T16:14:12.215-08:00","@version":1,"message":"HELLO CRUEL WORLD 9","logger_name":"org.example.Main","thread_name":"main","level":"INFO","level_value":20000,"HOSTNAME":"Richards-MacBook-Pro-2.local","serviceName":"impressionsService","serviceHost":"HOST_IS_UNDEFINED","servicePort":"PORT0_IS_UNDEFINED","serviceId":"impressions-HOST_IS_UNDEFINED-PORT0_IS_UNDEFINED","serviceAdminPort":"PORT1_IS_UNDEFINED"}

{"@timestamp":"2016-12-12T16:14:17.223-08:00","@version":1,"message":"HELLO CRUEL WORLD 0","logger_name":"org.example.Main","thread_name":"main","level":"INFO","level_value":20000,"HOSTNAME":"Richards-MacBook-Pro-2.local","serviceName":"impressionsService","serviceHost":"HOST_IS_UNDEFINED","servicePort":"PORT0_IS_UNDEFINED","serviceId":"impressions-HOST_IS_UNDEFINED-PORT0_IS_UNDEFINED","serviceAdminPort":"PORT1_IS_UNDEFINED"}

{"@timestamp":"2016-12-12T16:14:17.242-08:00","@version":1,"message":"HELLO CRUEL WORLD 1","logger_name":"org.example.Main","thread_name":"main","level":"INFO","level_value":20000,"HOSTNAME":"Richards-MacBook-Pro-2.local","serviceName":"impressionsService","serviceHost":"HOST_IS_UNDEFINED","servicePort":"PORT0_IS_UNDEFINED","serviceId":"impressions-HOST_IS_UNDEFINED-PORT0_IS_UNDEFINED","serviceAdminPort":"PORT1_IS_UNDEFINED"}

{"@timestamp":"2016-12-12T16:14:17.242-08:00","@version":1,"message":"HELLO CRUEL WORLD 2","logger_name":"org.example.Main","thread_name":"main","level":"INFO","level_value":20000,"HOSTNAME":"Richards-MacBook-Pro-2.local","serviceName":"impressionsService","serviceHost":"HOST_IS_UNDEFINED","servicePort":"PORT0_IS_UNDEFINED","serviceId":"impressions-HOST_IS_UNDEFINED-PORT0_IS_UNDEFINED","serviceAdminPort":"PORT1_IS_UNDEFINED"}

{"@timestamp":"2016-12-12T16:14:17.243-08:00","@version":1,"message":"HELLO CRUEL WORLD 3","logger_name":"org.example.Main","thread_name":"main","level":"INFO","level_value":20000,"HOSTNAME":"Richards-MacBook-Pro-2.local","serviceName":"impressionsService","serviceHost":"HOST_IS_UNDEFINED","servicePort":"PORT0_IS_UNDEFINED","serviceId":"impressions-HOST_IS_UNDEFINED-PORT0_IS_UNDEFINED","serviceAdminPort":"PORT1_IS_UNDEFINED"}

{"@timestamp":"2016-12-12T16:14:17.243-08:00","@version":1,"message":"HELLO CRUEL WORLD 4","logger_name":"org.example.Main","thread_name":"main","level":"INFO","level_value":20000,"HOSTNAME":"Richards-MacBook-Pro-2.local","serviceName":"impressionsService","serviceHost":"HOST_IS_UNDEFINED","servicePort":"PORT0_IS_UNDEFINED","serviceId":"impressions-HOST_IS_UNDEFINED-PORT0_IS_UNDEFINED","serviceAdminPort":"PORT1_IS_UNDEFINED"}

{"@timestamp":"2016-12-12T16:14:17.243-08:00","@version":1,"message":"HELLO CRUEL WORLD 5","logger_name":"org.example.Main","thread_name":"main","level":"INFO","level_value":20000,"HOSTNAME":"Richards-MacBook-Pro-2.local","serviceName":"impressionsService","serviceHost":"HOST_IS_UNDEFINED","servicePort":"PORT0_IS_UNDEFINED","serviceId":"impressions-HOST_IS_UNDEFINED-PORT0_IS_UNDEFINED","serviceAdminPort":"PORT1_IS_UNDEFINED"}

Journald allows extra fields. We could pull out the fields. Map them to the right levels. Copy known values. Then create extra fields for the rest.

Go allows reading/writing from maps.

This could allow us access to a lot more fields than just the basic ones.

https://gobyexample.com/json

    compile 'net.logstash.logback:logstash-logback-encoder:4.6'

This would work with https://www.npmjs.com/package/logstash-client too.

⚠️ **GitHub.com Fallback** ⚠️