DEV Community

Obinna Isiwekpeni
Obinna Isiwekpeni

Posted on

Logging GELF Log messages to Seq in Kotlin

Some weeks ago I did my first task in Kotlin to send log messages in Graylog format to Seq. This was a great introduction into Kotlin for me. This article shows a simple way of logging GELF messages to Seq.

The importance of logging in applications cannot be overemphasized. Logging generates a detailed set of events that occur within an application. These events include warnings, information, error, verbose and so on. They help in finding the causes of an application problem.

What is GELF?

GELF stands for Graylog Extended Log Format. It is a structured log event format that is implemented for logging libraries in many programming languages. Every log message in GELF contains the following fields:

  • host (the creator of the message)
  • timestamp
  • version
  • long and short version of the message
  • other custom fields you can freely configure on your own

What is Seq?

Seq is a centralized log file that is built for modern structured logging with message templates. Seq makes it easy to pin point log messages and this increases the speed of identifying and diagnosing problems in complex applications and microservices. Seq accepts logs via HTTP, GELF, custom inputs, with integrations available for .NET Core, JAVA, Python, Ruby and many other technologies.

Prerequisites

  • An Integrated Development Environment
  • Java Runtime Environment
  • Docker

Logging GELF to Seq

This section describes how to log GELF messages to Seq. Seq can receive GELF events via TCP and UDP. For this, we shall focus on UDP which stands for User Datagram Protocol. GELF is not enabled out-of-the-box, and must be enabled either of two ways:

  • On Windows, Seq.Input.Gelf app is installed and configured
  • On Docker/Linux, seq-input-gelf container is deployed alongside Seq container We shall look at the second method here. Now let us code.

Step 1- Creating a Kotlin Console project

First, we have to create a Kotlin project. I prefer to use IntelliJ IDEA because of its ease of use but you are welcome to use any IDE of your choice. I have named the project GELF_Logging. After creating the project, the directory should have the following structure

Folder Structure
Our main focus will be in the Main.Kt file in the kotlin subfolder and also the build.gradle.kts file.
The Main.kt file which is the entry point of the application initially contains the following lines of code:

fun main(args: Array<String>) {
    println("Hello World!")

    // Try adding program arguments at Run/Debug configuration
    println("Program arguments: ${args.joinToString()}")
}
Enter fullscreen mode Exit fullscreen mode

The build.gradle.kts file contains the following:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    kotlin("jvm") version "1.5.10"
    application
}

group = "me.obinnaisiwekpeni"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    testImplementation(kotlin("test"))
}

tasks.test {
    useJUnit()
}

tasks.withType<KotlinCompile>() {
    kotlinOptions.jvmTarget = "1.8"
}

application {
    mainClass.set("MainKt")
}
Enter fullscreen mode Exit fullscreen mode

Step 2 - Create logback.xml file

We will be using logback which is a popular logging framework in Java and SLF4J, an abstraction for various logging frameworks. We will create a logback.xml file in main/resources folder. We will put our logback config in this folder. We will keep this file empty for now.

Step 3 - Add dependencies in build.gradle.kts file

The next thing is to add all the necessary dependencies for logging. These dependencies are SLF4J, logback and logback-gelf. Logstash-gelf can also be used in place of logback-gelf.

The dependencies in build.gradle.kts looks like this now

dependencies {
    testImplementation(kotlin("test"))
    implementation("org.slf4j:slf4j-api:1.7.28")
    implementation("ch.qos.logback:logback-core:1.2.3")
    implementation ("ch.qos.logback:logback-classic:1.2.3")
    implementation("de.siegmar:logback-gelf:4.0.0")
}
Enter fullscreen mode Exit fullscreen mode

Step 4 - Add Configuration to logback.xml file

<configuration>
    <appender name="gelf_seq" class="de.siegmar.logbackgelf.GelfUdpAppender">
        <graylogHost>localhost</graylogHost>
        <graylogPort>12201</graylogPort>
    </appender>
    <root level="info">
        <appender-ref ref="gelf_seq"/>
    </root>
</configuration>
Enter fullscreen mode Exit fullscreen mode

The appender tag simply tells logback where to append the log messages to. Here we are logging to GELF with a host of localhost and port 12201 which is the default port for sending GELF messages via TCP and UDP. Also, take note of the class attribute in the appender tag. This indicates that we are using UDP. We give the appender a name gelf_seq which is used to reference our appender in the root tag.

Step 5 - Create a docker-compose file

version: '3'
services:
    seq:
        image: datalust/seq:latest
        ports:
           - "5341:80"
        environment:
            ACCEPT_EULA: "Y"
        restart: unless-stopped
        volumes:
            - ./seq-data:/data
    seq-input-gelf:
        image: datalust/seq-input-gelf:latest
        ports:
          - "12201:12201/udp"
        environment:
          SEQ_ADDRESS: "http://seq:5341"
        restart: unless-stopped
networks:
  default:
Enter fullscreen mode Exit fullscreen mode

The file contains the seq and seq-input-gelf services. The seq-input-gelf sends the GELF messages which it receives over UDP to the specified SEQ_ADDRESS env variable. Both services are connected using the default network.

Step 6 - Writing our log message and starting docker container

Now it is time to test our logs. In Main.kt, write the log message you want. I have chosen to write a simple message

import org.slf4j.LoggerFactory

fun main(args: Array<String>) {
    val logger = LoggerFactory.getLogger("Gelf Logging")
    val message = "Welcome to Gelf Logging to Seq"
    logger.info(message)
}
Enter fullscreen mode Exit fullscreen mode

Then we can start the docker-compose file using the command

docker-compose up
Enter fullscreen mode Exit fullscreen mode

If successful, you should see an information stating that Seq is listening on localhost:5341 in our case. Then run the code and the message should appear on Seq
Seq message

Conclusion

Logging GELF to Seq is quite straightforward and Seq helps to easily visualize log messages and makes it easy for troubleshooting.

References

You can find the full code on my Github

Top comments (0)