Scala入門記007 sbt + ScalaLogging

Javaの潤沢なライブラリが使えるScalaですが、そのまま使おうとしてもあまりイケてないことが多いです。
Play Frameworkplay.api.Loggerを使っていると、通常はメッセージを渡す代わりに関数を渡せます。
そのためメッセージ文字列の生成を指定したログレベルが有効な時に限定できたりして実にScalaっぽいです。


今回はScalaLoggingというものがあるということなので使ってみました。
Scala入門記の目次はこちらです。


ScalaLogging


Scalaのマクロを使って、logger.isDebugEnabled等の判断をコンパイル時に追加しているらしいです。
PlayのLoggerはLoggerをラップして対応しているところをマクロで対応しているということですね。


sbtの設定

GitHubのドキュメントにはsbtの依存ライブラリに以下を追加するように書かれています。

libraryDependencies += "com.typesafe" %% "scalalogging-slf4j" % "1.0.1"

流し読みしてこれだけ設定すると、Loggerの実装がないという旨の以下のようにメッセージが出ます。

SLF4J: Defaulting to no-operation (NOP) logger implementation


ScalaLoggingはLoggerの実装としてSLF4J かLog4j2かを選択してsbtで設定しなければならないです。


SLF4J

SLF4Jを使うためにまずはこちらのサイトを参考に以下のように設定してみました。

libraryDependencies ++= Seq(
  "com.typesafe" %% "scalalogging-slf4j" % "1.0.1",
  "ch.qos.logback" % "logback-classic" % "1.0.13"
)


この設定をしたうえで入門記006で使ったHelloオブジェクトを以下のように変更しました。

package example

import com.typesafe.scalalogging.slf4j.Logging

object Hello extends Logging {

  def main(args: Array[String]) {
    println(createGreeting(args))
  }

  def createGreeting(args: Array[String]) = {

    logger.info("args size:" + args.length)

    args.headOption match {
      case Some(name) => "Hello " + name + "!"
      case None => "Hello!"
    }
  }

}


これで"sbt run"するとログが表示されるようになりました。


Log4j2

まだbetaですがLog4jの2.0系のライブラリも使えます。
こちらはライブラリへの依存に加え、最低限動かすにも設定ファイル(log4j2.xml)が必要です。

libraryDependencies ++= Seq(
  "com.typesafe" %% "scalalogging-log4j" % "1.0.1",
  "org.apache.logging.log4j" % "log4j-core" % "2.0-beta9"
)


また、src/main/resources/log4j2.xmlは以下のように設定しました。

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="OFF">
  <appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </appenders>
  <loggers>
    <root level="info">
      <appender-ref ref="Console"/>
    </root>
  </loggers>
</configuration>


ソースコードはpackageの指定のところだけがSLF4Jと異なります。

package example

import com.typesafe.scalalogging.log4j.Logging

object Hello extends Logging {

  def main(args: Array[String]) {
    println(createGreeting(args))
  }

  def createGreeting(args: Array[String]) = {

    logger.info("args size:" + args.length)

    args.headOption match {
      case Some(name) => "Hello " + name + "!"
      case None => "Hello!"
    }
  }

}


これで"sbt run"するSLF4Jと同様にログが表示されるようになりました。



依存ライブラリ

参考までに実際の依存ライブラリをInteliJ IDEAで表示してみました。

追加前

f:id:t_hachinohe:20140121024634p:plain

SLF4J

f:id:t_hachinohe:20140121024659p:plain

Log4j2

f:id:t_hachinohe:20140121025121p:plain


ソースコード

今回の記事で使ったソースコードは以下のGitリポジトリの2つのタグです。

https://github.com/thachi/scala-sample-001

まとめ

どのくらい使われているのかはわかりませんが、今回はScalaLoggingというものを使ってみました。
私はplay.api.Loggerのような対応が方が好みですが、コンパイル時に解決できるこちらの方がエコですよね。


実装の選択についてはサクッと試すにはSLF4Jの実装が楽そうです。
Log4j2は使ったことがなかったので今後は使ってみたいと思っています。


Scala入門記の目次はこちらです。