Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Collecting Spring Boot Application Logs with Graylog

Tech 2

Spring Boot Log Aggregation with Graylog

  1. Graylog ovevriew
  • Centralized log platform built around Elasticsearch for search/storage and MongoDB for configuration/state.
  • Ingests logs via inputs such as GELF (UDP/TCP), Syslog, and more.
  • Web UI and REST API exposed on port 9000 by default.
  1. Deployment with Docker Compose The stack below runs MongoDB, Elasticsearch, and Graylog. Adjust versions and memory for your environment.
version: "3.8"

services:
  mongo:
    image: mongo:3

  es:
    image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.6.1
    environment:
      http.host: 0.0.0.0
      transport.host: localhost
      network.host: 0.0.0.0
      ES_JAVA_OPTS: "-Xms256m -Xmx256m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    deploy:
      resources:
        limits:
          memory: 512M

  graylog:
    image: graylog/graylog:3.0
    environment:
      GRAYLOG_PASSWORD_SECRET: somepasswordpepper  # at least 16 chars
      # SHA-256 for "admin"
      GRAYLOG_ROOT_PASSWORD_SHA2: 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
      GRAYLOG_HTTP_EXTERNAL_URI: "http://127.0.0.1:9000/"
    depends_on:
      - mongo
      - es
    ports:
      - "9000:9000"      # Web UI + REST API
      - "1514:1514"      # Syslog TCP
      - "1514:1514/udp"  # Syslog UDP
      - "12201:12201"    # GELF TCP
      - "12201:12201/udp"# GELF UDP

Notes

  • Replace 127.0.0.1 with your public IP/hostname for remote access.
  • Ensure UDP/TCP ports are reachable from application hosts.
  1. Graylog configuraton
  • Log in at http://:9000 using username admin and the configured password.
  • Navigate to System -> Inputs.
  • Choose GELF UDP and click Launch new input.
  • Select the running node, set port 12201, and save.
  • Verify the input is running before sending logs.
  1. Forwarding Spring Boot logs to Graylog Two configurations are demonstrated: Logback and Log4j2. Both send GELF messages to the Graylog input on port 12201.

4.1 Logback using logback-gelf Dependency configuration (Maven):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.4.RELEASE</version>
    <relativePath/>
  </parent>

  <groupId>com.example</groupId>
  <artifactId>boot-graylog-logback</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <properties>
    <java.version>1.8</java.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
      <groupId>de.siegmar</groupId>
      <artifactId>logback-gelf</artifactId>
      <version>2.0.0</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

Create src/main/resources/logback-spring.xml:

<configuration>
  <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
  <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
  <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>

  <property name="APP_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n%wEx"/>

  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>${APP_PATTERN}</pattern>
      <charset>UTF-8</charset>
    </encoder>
  </appender>

  <!-- Send logs to Graylog via GELF UDP -->
  <appender name="GELF_UDP" class="de.siegmar.logbackgelf.GelfUdpAppender">
    <graylogHost>127.0.0.1</graylogHost>
    <graylogPort>12201</graylogPort>
    <!-- Optional: <facility>spring-app</facility> -->
  </appender>

  <root level="INFO">
    <appender-ref ref="GELF_UDP"/>
    <appender-ref ref="CONSOLE"/>
  </root>
</configuration>

Start the application and verify events appear in Graylog’s "Search" page. If logs do not arrive, confirm that the GELF UDP input is running and the host/port are correct.

4.2 Log4j2 using log4j2-gelf Dependency configuration (Mavan):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.4.RELEASE</version>
    <relativePath/>
  </parent>

  <groupId>com.example</groupId>
  <artifactId>boot-graylog-log4j2</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <properties>
    <java.version>1.8</java.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <exclusions>
        <exclusion>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>

    <dependency>
      <groupId>org.graylog2.log4j2</groupId>
      <artifactId>log4j2-gelf</artifactId>
      <version>1.3.1</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

Create src/main/resources/log4j2-spring.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" packages="org.graylog2.log4j2">
  <Properties>
    <Property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] %c{1.}:%L - %m%n</Property>
  </Properties>

  <Appenders>
    <Console name="STDOUT" target="SYSTEM_OUT" follow="true">
      <PatternLayout pattern="${PATTERN}"/>
    </Console>

    <!-- GELF UDP appender to Graylog -->
    <GELF name="GelfToGraylog" server="127.0.0.1" port="12201" hostName="service-a">
      <PatternLayout pattern="%logger{36} - %msg%n"/>
      <Filters>
        <Filter type="MarkerFilter" marker="FLOW" onMatch="DENY" onMismatch="NEUTRAL"/>
        <Filter type="MarkerFilter" marker="EXCEPTION" onMatch="DENY" onMismatch="ACCEPT"/>
      </Filters>
      <KeyValuePair key="environment" value="dev"/>
      <KeyValuePair key="jvm" value="${java:vm}"/>
    </GELF>
  </Appenders>

  <Loggers>
    <Root level="INFO">
      <AppenderRef ref="GelfToGraylog"/>
      <AppenderRef ref="STDOUT"/>
    </Root>
  </Loggers>
</Configuration>
  1. Choosing Graylog vs. ELK (Elasticsearch, Logstash, Kibana)
  • Operational complexity: Graylog bundles the ingestion and UI layers, often simpler to stand up for GELF/Syslog sources. ELK provides more flexibility with Logstash/Beats but can require more moving parts.
  • Storage/search: Both rely on Elasticsearch (or compatible) for indexing and query performance.
  • Existing stack: If MongoDB is already part of your platform, Graylog’s MongoDB dependency may be acceptable. If you already operate Beats/Logstash pipelines, ELK may integrate more naturally.
  • Features: Graylog offers built-in streams, alerts, dashboards, and extractors foccused on log management; ELK offers broadder data ingestion and transformation options.

All examples assume a GELF UDP input bound to port 12201 and that host networking permits UDP traffic from application nodes to the Graylog server.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.