slf4j+fluentd

2013-11-16T12:00:00+00:00 Java fluentd

まぁタイトルで分かるようにslf4jで送出されるログをfluentdにぶん投げるネタ

fluentd.conf

<source>
  type forward
</source>

<match slf4j.**>
  type file
  path fluentd.log
</match>

まぁ単純に

build.gradle

apply plugin: "java"
apply plugin: "eclipse"

repositories {
    mavenCentral()
}

dependencies {
    compile "org.slf4j:slf4j-api:1.7.5"
    compile "org.fluentd:fluent-logger:0.2.11"
}

slf4j-apiとfluent-loggerなライブラリが必要なので(ry

StaticLoggerBinder.java

slf4jでログを出力する実装基盤はorg.slf4j.impl.StaticLoggerBinder的なのを実装すれば良い模様。fluent-loggerにそういうのあるかなーって思ったけど無さそうだったので自分で書く

package org.slf4j.impl;

import org.slf4j.ILoggerFactory;
import org.slf4j.spi.LoggerFactoryBinder;

public class StaticLoggerBinder implements LoggerFactoryBinder {

    private static StaticLoggerBinder instance = null;

    private ILoggerFactory loggerFactory;

    public StaticLoggerBinder() {
        loggerFactory = new FluentLoggerFactory();
    }

    @Override
    public ILoggerFactory getLoggerFactory() {
        return loggerFactory;
    }

    @Override
    public String getLoggerFactoryClassStr() {
        return FluentLoggerFactory.class.getName();
    }

    public static StaticLoggerBinder getSingleton() {
        if (instance == null)
            instance = new StaticLoggerBinder();

        return instance;
    }
}

FluentLoggerFactory.java

package org.slf4j.impl;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;

public class FluentLoggerFactory implements ILoggerFactory {

    private Map<string, Logger> loggers;

    public FluentLoggerFactory() {
        loggers = new HashMap<string, Logger>();
    }

    @Override
    public Logger getLogger(String name) {
        synchronized(loggers) {
            if (!loggers.containsKey(name))
                loggers.put(name, new FluentLoggerAdapter(name));

            return loggers.get(name);
        }
    }
}

FluentLoggerAdapter.java

debugとinfoなログレベルだけ実装してみた

package org.slf4j.impl;

import java.util.HashMap;
import java.util.Map;

import org.fluentd.logger.FluentLogger;
import org.slf4j.Logger;
import org.slf4j.Marker;

public class FluentLoggerAdapter implements Logger {

    private static final String LOG_LEVEL_INFO = "info";
    private static final String LOG_LEVEL_DEBUG = "debug";

    String name;
    FluentLogger logger;

    public FluentLoggerAdapter(String name) {
        this.name = name;
        logger = FluentLogger.getLogger("slf4j");
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public boolean isTraceEnabled() {
        return false;
    }

    @Override
    public void trace(String msg) {
    }

    @Override
    public void trace(String format, Object arg) {
    }

    @Override
    public void trace(String format, Object arg1, Object arg2) {
    }

    @Override
    public void trace(String format, Object... arguments) {
    }

    @Override
    public void trace(String msg, Throwable t) {
    }

    @Override
    public boolean isTraceEnabled(Marker marker) {
        return false;
    }

    @Override
    public void trace(Marker marker, String msg) {
    }

    @Override
    public void trace(Marker marker, String format, Object arg) {
    }

    @Override
    public void trace(Marker marker, String format, Object arg1, Object arg2) {
    }

    @Override
    public void trace(Marker marker, String format, Object... argArray) {
    }

    @Override
    public void trace(Marker marker, String msg, Throwable t) {
    }

    @Override
    public boolean isDebugEnabled() {
        return false;
    }

    @Override
    public void debug(String msg) {
        Map<string, Object> log = new HashMap<string, Object>(2);
        log.put("level", LOG_LEVEL_DEBUG);
        log.put("message", msg);

        logger.log(getName(), log);
    }

    @Override
    public void debug(String format, Object arg) {
    }

    @Override
    public void debug(String format, Object arg1, Object arg2) {
    }

    @Override
    public void debug(String format, Object... arguments) {
    }

    @Override
    public void debug(String msg, Throwable t) {
    }

    @Override
    public boolean isDebugEnabled(Marker marker) {
        return true;
    }

    @Override
    public void debug(Marker marker, String msg) {
    }

    @Override
    public void debug(Marker marker, String format, Object arg) {
    }

    @Override
    public void debug(Marker marker, String format, Object arg1, Object arg2) {
    }

    @Override
    public void debug(Marker marker, String format, Object... arguments) {
    }

    @Override
    public void debug(Marker marker, String msg, Throwable t) {
    }

    @Override
    public boolean isInfoEnabled() {
        return false;
    }

    @Override
    public void info(String msg) {
        Map<string, Object> log = new HashMap<string, Object>(2);
        log.put("level", LOG_LEVEL_INFO);
        log.put("message", msg);

        logger.log(getName(), log);
    }

    @Override
    public void info(String format, Object arg) {
    }

    @Override
    public void info(String format, Object arg1, Object arg2) {
    }

    @Override
    public void info(String format, Object... arguments) {
    }

    @Override
    public void info(String msg, Throwable t) {
    }

    @Override
    public boolean isInfoEnabled(Marker marker) {
        return true;
    }

    @Override
    public void info(Marker marker, String msg) {
    }

    @Override
    public void info(Marker marker, String format, Object arg) {
    }

    @Override
    public void info(Marker marker, String format, Object arg1, Object arg2) {
    }

    @Override
    public void info(Marker marker, String format, Object... arguments) {
    }

    @Override
    public void info(Marker marker, String msg, Throwable t) {
    }

    @Override
    public boolean isWarnEnabled() {
        return false;
    }

    @Override
    public void warn(String msg) {
    }

    @Override
    public void warn(String format, Object arg) {
    }

    @Override
    public void warn(String format, Object... arguments) {
    }

    @Override
    public void warn(String format, Object arg1, Object arg2) {
    }

    @Override
    public void warn(String msg, Throwable t) {
    }

    @Override
    public boolean isWarnEnabled(Marker marker) {
        return false;
    }

    @Override
    public void warn(Marker marker, String msg) {
    }

    @Override
    public void warn(Marker marker, String format, Object arg) {
    }

    @Override
    public void warn(Marker marker, String format, Object arg1, Object arg2) {
    }

    @Override
    public void warn(Marker marker, String format, Object... arguments) {
    }

    @Override
    public void warn(Marker marker, String msg, Throwable t) {
    }

    @Override
    public boolean isErrorEnabled() {
        return false;
    }

    @Override
    public void error(String msg) {
    }

    @Override
    public void error(String format, Object arg) {
    }

    @Override
    public void error(String format, Object arg1, Object arg2) {
    }

    @Override
    public void error(String format, Object... arguments) {
    }

    @Override
    public void error(String msg, Throwable t) {
    }

    @Override
    public boolean isErrorEnabled(Marker marker) {
        return false;
    }

    @Override
    public void error(Marker marker, String msg) {
    }

    @Override
    public void error(Marker marker, String format, Object arg) {
    }

    @Override
    public void error(Marker marker, String format, Object arg1, Object arg2) {
    }

    @Override
    public void error(Marker marker, String format, Object... arguments) {
    }

    @Override
    public void error(Marker marker, String msg, Throwable t) {
    }
}

動かしてみる

fluentdを起動しておいて、普通にslf4jを動かす感じでdebugとinfoなログを出す

2013-11-16T17:16:23+09:00   slf4j.Main  {"message":"hoge","level":"info"}
2013-11-16T17:16:23+09:00   slf4j.Main  {"message":"hoge","level":"debug"}

ってな感じで出される

angular.js+chrome_ex_oauth slf4j