Scala记录行号 - slf4s / slf4j?

时间:2011-01-29 08:06:11

标签: scala logging slf4j

更新:已解决!!!
请参阅我在下面添加的答案


有没有人知道是否有办法将实际行号输出到控制台?我在这里试图进入Scala,但是由于我无法获得我所依赖的基本内容,所以很难获得更多。

我已经设置了slf4s来包装slf4j - log4j - jcl-over-slf4j。问题是我得到的行号根本不匹配。比Scala类甚至包含的行数要高得多。这是因为行号实际上是Java中间行号吗?

是否有 EASY 方式来设置符合这些要求的日志记录?:

  1. 可互操作,与java和&阶
  2. 像log4j
  3. 一样轻松更改单个包的日志记录级别
  4. 提供准确的行号。
  5. 谢谢!

    杰米

4 个答案:

答案 0 :(得分:7)

我发现 logback (按Ceki Gülcü)效果很好,也保留了行号! (它可以替代log4j:真棒!)

import ch.qos.logback._
import org.slf4j._

object Main {

    def logger = LoggerFactory.getLogger("Main")
    var thingy = {
        x:Int =>
        logger.info("x=" + x)
        x + 1
    }
    def main(args: Array[String]) {
        logger.info("Hello.")
        logger.info("Hello again!")

        val myInts : List[Int] = List(-25,1,5,20)

        val myInts2 : List[Int] = myInts.filter { x:Int => x > 0 }

        logger.info("my ints2:" + myInts2)

        val myInts3 = myInts2.map(p =>  p * 2 )
        logger.info("my ints3:" + myInts3)

        logger.info(thingy(1) + "")
    }
}

对于那些努力开始使用Scala的人来说,这就是我为了获得基本骨架而做的事情:

1)Download sbt-launcher.jar并将其置于/opt/之间 我使用" sbt-launch-0.7.5.RC0.jar"

2)创建一个bash脚本作为nano /opt/bin/sbt中sbt启动器的快捷方式:

#!/bin/bash
java -jar /opt/sbt-launch-0.7.5.RC0.jar "$@"

(使其可执行)

$ sudo chmod ug+x ./sbt

确保它也在你的道路上。

3)创建并配置sbt项目:

$ mkdir ./sc01
$ cd ./sc01
$ sbt
$ mkdir ./project/build</pre>
$ nano ./project/build/Project.scala</pre>

把它放在那里:

import sbt._

class sc01(info: ProjectInfo) extends DefaultProject(info)
{
    // dependencies
    val logback_core = "ch.qos.logback" % "logback-core" % "0.9.24" % "compile" //LGPL 2.1
    val logback_classic = "ch.qos.logback" % "logback-classic" % "0.9.24" % "compile" //LGPL 2.1
    val log4j_over_slf4j = "org.slf4j" % "log4j-over-slf4j" % "1.6.1"


   // if you are going to have any unmanaged (manually-added) jars
   //    def baseDirectories = "lib"
   //    def extraJars = descendents(baseDirectories, "*.jar")
   //    override def unmanagedClasspath = super.unmanagedClasspath +++ extraJars

    // tasks - easy to define
    lazy val hi = task { println("Hello World"); None }

    // classpath
    //override def mainScalaSourcePath = "src"

}

4)将上面的东西粘贴到Main:

$ nano ./src/main/scala/Main.scala

5)我差点忘了!把它放在/src/main/resources/logback.xml中 (它需要获得行号)

<configuration>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoders are assigned the type
     ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} %line --- %msg%n</pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

6)$ sbt

现在你应该进入shell中的sbt控制台:

> update
> compile
> run

希望这有帮助。

答案 1 :(得分:2)

当您在Scala logging问题中发表评论时,在Scala中获取精确的行号信息很难。

  
      
  • 为什么Scala不仅仅通过保存来重载现有的基础设施   绝对偏移而不是LineNumberTable中的行号?   另一种寻址方式可以是通过对令牌进行编号而不是   实际的偏移到源文件中。
  •   
  • 虽然我喜欢使用令牌进行索引的想法,但这意味着任何能够使用调试信息的工具都需要访问完整的解析器。
      另一种可能性是根据一些严格定义的规则重新格式化文件,然后继续使用行号。
  •   
  • 我开始致力于改进Scala程序的调试体验,其中一个痛点就是行号。理想情况下,支持的不仅仅是行号。我正在查看JSR 45(其他语言的调试支持)。我不确定这是否足够,但也许Scala阶层可以使用你的计划   我认为更好的方法是在classfile属性或注释中提供额外的Scala特定调试信息。据我所知,JDI不提供对classfile属性的访问,也不提供对注释的访问,但是我们可以使用一些技巧来获取它们。这样我们就可以保留现有功能,并允许工具在了解Scala属性时执行更多操作。
  •   

(注意:Scalate报告在scalate-24中针对不同类型的源文件进行了类似的工作)

答案 2 :(得分:2)

2016年更新:像lihaoyi/sourcecode这样的图书馆确实包含logging use case新方法:

您可以使用sourcecode.File和sourcecode.Line来定义自动捕获其行号和文件名的日志函数

def log(foo: String)(implicit line: sourcecode.Line, file: sourcecode.File) = {
  println(s"${file.value}:${line.value} $foo")
}

log("Foooooo") // sourcecode/shared/src/test/scala/sourcecode/Tests.scala:86 Fooooo
  

这可以方便您查看日志行的来源,而无需使用唯一的前缀标记每个日志语句。   此外,这在编译时发生,因此比通过生成堆栈跟踪获取此信息快几个数量级,并且在Scala.js处理堆栈检查不。   最后,如果您希望向日志记录功能提供方法名称,类名称或包等其他信息,可以通过询问sourcecode.Namesourcecode.FullName或{{1}来轻松完成此操作。侮辱。

答案 3 :(得分:0)

我建议你看一下Scribe。它是Scala使用宏在编译时生成行号和其他信息的完整日志记录解决方案,因此不会降低速度,而且它是内置的,因此您不必使用sourcecode之类的内容并进行集成手动:

https://github.com/outr/scribe