GithubHelp home page GithubHelp logo

SLog4j

Allows you to stop logging prose and to start logging structured events.

License Coverage Chat

The Shifting Purpose of Logging

Historically, logging messages were supposed to be consumed by humans, and its main purpose were to aid the developer on a debugging process. Past the DevOps evolution and the increase on scale of applications, machines are nowadays the major consumers of logging messages.

So why are we still logging messages like these:

Processed 23 flight records for flight UA1234 for airline United

Instead of:

evt=FLIGHT_RECORDS_PROCESSED recordCount=23 airlineCode=UA flightNumber=1234 airlineName=United

Both messages convey the same information but the later format has the following advantages:

  1. It’s very easy to parse, avoiding complex and cumbersome regular expressions to extract semantics from them;

  2. It’s much easier to maintain. One can easily extend it with additional information without breaking the parser.

Quick-start

SLog4j is implemented itself on top of SLF4J and mimics its API. Therefore any application that already uses SLF4J can start using SLog4j very easily with a few minor modifications.

Step 1: add the SLog4j dependency

SLog4j requires Java 1.6+ and is available from both JCenter and Maven Central repositories.

Gradle

dependencies {
    // ...
    compile 'org.slog4j:slog4j:0.9.0'
    // ...
}

Maven

<dependency>
  <groupId>org.slog4j</groupId>
  <artifactId>slog4j</artifactId>
  <version>0.9.0</version>
</dependency>

Step 2: Configure your underlying logging framework

The default formatter used by SLog4j fits better the typical case where both structured and unstructured messages are being logged. On such cases, a basic pattern configuration for Logback and Log4J could be:

Logback

logback.xml
<configuration>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSSZ} %level %msg%n</pattern>
    </encoder>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="STDOUT" />
  </root>

</configuration>

Log4j

log4j.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="true" xmlns:log4j='http://jakarta.apache.org/log4j/'>

  <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSSZ} %p %m%n" />
    </layout>
  </appender>

  <root>
    <level value="DEBUG" />
    <appender-ref ref="STDOUT" />
  </root>

</log4j:configuration>

Step 3: Instantiate the logger

Instead of the standard SLF4J Logger, you must instantiate the SLog4j Logger:

import org.slog4j.SLogger;
import org.slog4j.SLoggerFactory;

class MyClass {
    private static final SLogger slog = SLoggerFactory.getLogger(MyClass.class);
    // ...
}

Step 4: Log the event messages

Before delving into details of SLog4j API, let’s see some examples that work out-of-the-box.

Example: Basic SLogger invocations
Map<String, ?> credentials = new HashMap<>() {{
  put("username", "jsmith");
  put("login_time", new Date());
}};
byte[] token = new byte[]{1, 2, 3, 4, 5, 6, 7, 8};

slog.info("CONNECT");
slog.info("SSL_CONNECT", "protocol", "tlsv1.2", "tcp_port", 443);
slog.info("USER_LOGIN", credentials, "token", token);
Resulting Log Messages (with default formatter)
2017-10-08T16:08:02.055-0500 INFO evt=CONNECT
2017-10-08T16:08:02.195-0500 INFO evt=SSL_CONNECT protocol=tlsv1.2 tcp_port=443
2017-10-08T16:08:02.913-0500 INFO evt=USER_LOGIN username=jsmith login_time=2017-10-08T16:08:02.899-0500 token=AQIDBAUGBwg=

The SLog4j API

A simplified view of the SLogger interface is shown below:

package org.slog4j;

public interface SLogger {
    void error(String eventId, Object... objs);
    void warn(String eventId, Object... objs);
    void info(String eventId, Object... objs);
    void debug(String eventId, Object... objs);
    void trace(String eventId, Object... objs);
}

With SLog4j you’ll be always logging structured events. At the API level this implies that your application will provide a sequence of one or more properties, i.e. Name/Value pairs, to one of the SLogger methods above. This sequence is conceptually comprised of:

  • A mandatory property to identify the event being logged. The value is taken from the eventId argument and the name is evt by default and can be configured to another value;

  • An optional spanId property used to correlate events;

  • Additional properties taken from the objs array.

The objs array, in its turn, contains a variable sequence of either:

  • Name/Value attribute, where Name is a String and Value is an object;

  • An object that can be expanded to a properties sequence.

  • A Throwable

Configuring SLog4j

Every object must be first marshalled to text to be logged. On SLog4j this marshalling is a four step process:

  1. Is it a Single Object? True if obj type is a String, a primitive wrapper class or has a registered joda-convert ToStringConverter;

  2. Is a Complex Object? Is there a registered ToPropertiesConverter for its type?

  3. Is a Throwable?

  4. Everything else

Why SLog4j?

The Structured logging technique was positioned on the Adopt ring on January 2015 edition of [ThoughtWorks' Technology Radar](https://www.thoughtworks.com/radar/techniques/structured-logging). Today most popular programming languages has at least one mature solution for Structured logging but Java, albeit surprisingly, still lacks behind. Until now ;-)

License

Copyright (c) 2017 Eliezio Oliveira. See the LICENSE file for license rights and limitations (MIT).

slog4j's Projects

slog4j icon slog4j

Structured Event Logging for Java.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.