Номера строк в журнале Scala - slf4s / slf4j? - PullRequest
8 голосов
/ 29 января 2011

ОБНОВЛЕНИЕ: РЕШЕНО !!!
Пожалуйста, смотрите ответ, который я добавил ниже


Кто-нибудь знает, есть ли способ ведения журнала, который выводит на консоль реальные номера строк? Я пытаюсь попасть сюда в Scala, но, не имея возможности получить такие базовые вещи, от которых я зависел, очень трудно добиться успеха.

Я настроил slf4s для переноса с slf4j - log4j - jcl-over-slf4j. Проблема в том, что я получаю номера строк, которые не совпадают вообще. Значения строк намного выше, чем в классе Scala. Это потому, что номера строк на самом деле являются номерами промежуточных строк Java?

Есть ли какой-либо ЛЕГКИЙ способ настроить ведение журнала, отвечающий этим требованиям?:

  1. совместим, работает как с Java, так и с Scala
  2. так же легко изменить уровень регистрации отдельных пакетов, как и log4j
  3. предоставляет ТОЧНЫЕ номера строк.

Спасибо!

Jamie

Ответы [ 4 ]

7 голосов
/ 08 марта 2011

Я обнаружил, что logback (by 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) Загрузите sbt-launcher.jar и поместите его где-нибудь как /opt/
Я использовал "sbt-launch-0.7.5.RC0.jar"

2) Создайте скрипт bash какярлык для sbt launcher в nano /opt/bin/sbt:

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

(сделайте его исполняемым)

$ sudo chmod ug+x ./sbt

Убедитесь, что он тоже на вашем пути.

3)Создайте и настройте проект sbt:

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

вставьте это здесь:

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

Теперь вы должны быть в консоли sbt в вашемshell:

> update
> compile
> run

Надеюсь, это поможет.

2 голосов
/ 15 марта 2016

Обновление 2016: библиотека, подобная lihaoyi/sourcecode, включает сценарий использования журнала с новым подходом:

Вы можете использовать sourcecode.File и sourcecode.Строка для определения функций журнала, которые автоматически фиксируют их номер строки и имя файла

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.

2 голосов
/ 29 января 2011

Когда вы комментируете вопрос В журнале Scala , получить точную информацию о номере строки в Scala сложно.

  • Почему Scala не просто перегружает существующую инфраструктуру, сохраняя абсолютные смещения вместо номеров строк в LineNumberTable?
    Другой способадресации может быть нумерация токенов вместо фактических смещений в исходных файлах.
  • Хотя мне нравится идея индексации по токенам, это означает, что любой инструмент, способный использовать отладочную информацию, должен иметь доступ кполный синтаксический анализатор.
    Другой возможностью было бы переформатировать файл в соответствии с каким-то строго определенным набором правил, а затем продолжить использовать нумерацию строк.
  • Я начал работать над улучшением процесса отладки для программ Scala, и одна из больничных точек - это действительно номера строк.В идеале должна быть поддержка не только номеров строк.Я смотрю на JSR 45 (поддержка отладки для других языков).Я еще не уверен, достаточно ли этого, но, возможно, слой Scala мог бы использовать вашу схему.
    Я думаю, что лучший способ - предоставить дополнительную, специфичную для Scala отладочную информацию в classfile атрибутах или аннотациях.Насколько я знаю, JDI не дает доступа ни к атрибутам classfile, ни к аннотациям, но есть некоторые приемы, которые мы могли бы использовать, чтобы получить к ним доступ.Таким образом мы сохраним существующую функциональность и позволим инструментам делать больше, когда они знают об атрибутах Scala.

(Примечание: Scalate сообщает о проделанной аналогичной работе в scalate-24 для различных типов исходных файлов)

0 голосов
/ 10 января 2017

Я бы порекомендовал взглянуть на писца.Это полное решение для ведения журналов для Scala, использующее макросы для генерации номеров строк и другой информации во время компиляции, поэтому нет снижения скорости, и оно встроено, поэтому вам не нужно использовать что-то вроде sourcecode и интегрировать его вручную:

https://github.com/outr/scribe

...