8

更新:解決済み!!!
以下に追加した回答をご覧ください


実際の行番号をコンソールに出力するロギングを行う方法があるかどうかは誰にもわかりませんか? 私はここで Scala に取り組もうとしていますが、私が依存しているこのような基本的なものを手に入れることができなければ、多くのことを始めるのは本当に難しいです.

slf4j - log4j - jcl-over-slf4j でラップするように slf4s をセットアップしました。問題は、行番号がまったく一致しないことです。Scala クラスに含まれているよりもはるかに多くの行番号があります。これは、行番号が実際には Java 中間の行番号であるためですか?

これらの要件を満たすロギングをセットアップする簡単な方法はありますか?:

  1. 相互運用可能、Java と Scala の両方で動作
  2. 個々のパッケージのログ レベルを log4j と同じくらい簡単に変更できます
  3. 正確な行番号を提供します。

ありがとう!

ジェイミー

4

4 に答える 4

7

logbackCeki Gülcüによる)うまく機能し、行番号も保持されることがわかりました!(そして、それは: Awesome!
の代わりとして機能します)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) 「 」 を使用したように、ダウンロードsbt-launcher.jarしてどこかに置きます。/opt/
sbt-launch-0.7.5.RC0.jar

2) で sbt ランチャーへのショートカットとして bash スクリプトを作成しますnano /opt/bin/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) 上記のものをメインに貼り付けます。

$ 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

sbtこれで、シェルのコンソールにいるはずです:

> update
> compile
> run

お役に立てれば。

于 2011-03-08T03:53:59.293 に答える
2

Scala logging question で コメントしているように、 Scala で正確な行番号情報を取得するのは困難です。

  • Scala が行番号の代わりに絶対オフセットを保存することで、既存のインフラストラクチャを過負荷にしないのはなぜLineNumberTableですか?
    アドレス指定の別の方法として、ソース ファイルへの実際のオフセットではなく、トークンに番号を付けることもできます。
  • トークンによるインデックス作成のアイデアは気に入っていますが、これは、デバッグ情報を使用できるツールは、完全なパーサーにアクセスできる必要があることを意味します。
    もう 1 つの可能性は、厳密に定義された一連の規則に従ってファイルを再フォーマットし、引き続き行番号を使用することです。
  • 私は Scala プログラムのデバッグ エクスペリエンスを改善する作業を開始しましたが、問題点の 1 つは実際に行番号です。理想的には、単なる行番号以上のサポートがあるでしょう。JSR 45 (他の言語のデバッグ サポート) を見ています。これで十分かどうかはまだわかりませんが、Scala ストラタムがあなたのスキームを使用できるかもしれません。より良い方法は、追加の Scala 固有のデバッグ情報を属性または注釈
    で提供することだと思います。classfile私の知る限り、JDI はclassfile属性にも注釈にもアクセスできませんが、それらにアクセスするために使用できるいくつかのトリックがあります。このようにして、既存の機能を保持し、ツールが Scala 属性を認識しているときに、より多くのことを実行できるようにします。

(注:異なる種類のソースファイルに対してscalate-24で同様の作業を行ったScalateレポート)

于 2011-01-29T09:02:19.670 に答える
2

2016年更新: のようなライブラリには、新しいアプローチによるロギングのユースケースlihaoyi/sourcecodeが含まれています:

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.Nameまたはsourcecode.FullNameまたはsourcecode.Pkg暗黙関数を要求することで簡単に行うことができます。

于 2016-03-15T13:20:40.867 に答える
0

Scribe を参照することをお勧めします。これは、マクロを使用してコンパイル時に行番号やその他の情報を生成する Scala の完全なログ ソリューションであるため、速度が低下することはありません。組み込みであるため、次のようなものを使用しsourcecodeて手動で統合する必要はありません。

https://github.com/outr/scribe

于 2017-01-09T21:59:03.280 に答える