2011-01-29 65 views
7

更新:已解決!
請參閱我在下面Scala登錄行號 - slf4s/slf4j?

答案

有誰知道是否有一種方法做記錄,真正的行號輸出到控制檯?我試圖在這裏進入Scala,但是沒有能夠獲得我所依賴的基本東西,實際上很難做到。

我設置了slf4s來包裝slf4j - log4j - jcl-over-slf4j。問題是我得到的行數完全不匹配。比Scala類所包含的行號還要高得多。這是因爲行號實際上是Java中間行號?

是否有任何EASY這樣,才能建立記錄符合這些要求?:

  1. 互操作,與包括Java &斯卡拉工作
  2. 那麼容易改變的個人日誌記錄級別軟件包與log4j一樣容易
  3. 提供了精確的行號。

謝謝!

傑米

回答

6

我發現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腳本的快捷方式,SBT發射在nano /opt/bin/sbt

#!/bin/bash 
java -jar /opt/sbt-launch-0.7.5.RC0.jar "[email protected]" 

(使其可執行文件)

$ 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)的東西從上面粘貼到主營:

$ 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 

希望這幫助。

+0

有趣的反饋。我會試一試。 +1(不要忘記你可以選擇你自己的答案作爲官方答案) – VonC 2011-03-08 05:03:06

2

正如你在Scala logging問題發表評論,Scala中獲得精確的行數信息是很難的。

  • 爲什麼Scala的不只是節省 超載現有的基礎設施絕對偏移而不是LineNumberTable中的行號?
    另一種尋址方式可以是編碼令牌而不是 到源文件的實際偏移量。
  • 雖然我喜歡使用標記進行索引的想法,但這意味着任何能夠使用調試信息的工具都需要訪問完整的分析器。
    另一種可能性是根據一些嚴格定義的規則集重新格式化文件,然後繼續使用行編號。
  • 我開始致力於改善Scala程序的調試體驗,其中一個痛點確實是行號。理想情況下,不僅僅支持行號。我正在查看JSR 45(調試對其他語言的支持)。我還不確定這是否足夠,但也許一個Scala階層可以使用你的方案。
    我認爲更好的方法是在classfile屬性或註釋中提供額外的,Scala特定的調試信息。據我所知,JDI不允許訪問classfile屬性,也不能提供註釋,但是我們可以使用一些技巧來獲取它們。這樣我們就可以保留現有的功能,並允許工具在知道Scala屬性時做更多的事情。

(注:已經做Scalate報告中scalate-24類似的工作,爲不同類型的源文件)

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.FullNamesourcecode.Pkg含義輕鬆地完成此操作。

0

我會推薦看看Scribe。這是一個完整的Scala記錄解決方案,它使用宏在編譯時生成行號和其他信息,因此速度沒有降低,並且它是內置的,因此您不必使用類似sourcecode的東西並手動集成它:

https://github.com/outr/scribe