2011-01-29 13 views
7

AGGIORNAMENTO: RISOLTO !!!
Si prega di consultare la risposta ho aggiunto sottoNumeri di riga di registrazione di Scala - slf4s/slf4j?


Qualcuno sa se c'è un modo per fare la registrazione che emette i numeri reali di linea per la console? Sto cercando di entrare in Scala qui, ma senza essere in grado di ottenere cose di base come questa da cui dipendo, è davvero difficile ottenere molto.

Ho impostato slf4s per eseguire il wrapping con slf4j - log4j - jcl-over-slf4j. Il problema è che ottengo numeri di linea che non corrispondono affatto. I numeri di linea sono molto più alti di quanto la classe Scala contenga. È perché i numeri di riga sono in realtà numeri di linea intermedi Java?

C'è qualche EASY modo per impostare la registrazione che soddisfa questi requisiti ?:

  1. interoperabili, lavorando sia con Java & Scala
  2. facile da cambiare il livello di registrazione dei singoli pacchetti facilmente come log4j
  3. fornisce i numeri di linea ACCURATE.

Grazie!

Jamie

risposta

6

Ho scoperto che logback (da Ceki Gülcü) funziona alla grande e conserva numeri di riga troppo !
(e funziona come un sostituto per log4j: Awesome!)

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) + "") 
    } 
} 

Per tutti coloro che lottano per iniziare con Scala, questo è quello che ho fatto per ottenere lo scheletro di base fino:

1) Download sbt-launcher.jar e metterlo da qualche parte come /opt/
ho usato "sbt-launch-0.7.5.RC0.jar"

2) creare uno script bash come una scorciatoia per il lanciatore SBT in nano /opt/bin/sbt:

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

(renderlo eseguibile)

$ sudo chmod ug+x ./sbt 

Assicuratevi che sia nel tuo percorso troppo.

3) Creare e configurare il progetto SBT:

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

mettere questo in là:

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) Incollare la roba dall'alto nella principale:

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

5) Ho quasi dimenticato! mettere questo in /src/main/resources/logback.xml
(è necessario per ottenere i numeri di riga)

<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

Ora si dovrebbe essere nella console sbt nella shell:

> update 
> compile 
> run 

Spero che questo aiuta.

+0

Feedback interessante. Lo proverò. +1 (non dimenticare che puoi selezionare la tua risposta come quella ufficiale) – VonC

+1

La tua spiegazione qui è _so_ molto meglio della documentazione di sbt. Vorrei aver trovato questa risposta prima. – srparish

+0

@srparish Sono contento che ti abbia aiutato! Ho ottenuto un così grande aiuto nella mia carriera di programmazione relativamente breve da post di blog/stack overflow/mailing list che sono felice di poter contribuire a qualsiasi cosa possa offrire. – jpswain

2

Come si sta commentando in Scala logging questione, ricevendo linea di precise informazioni numero in Scala è difficile.

  • Perché Scala non solo sovraccaricare l'infrastruttura esistente salvando offset assoluti invece dei numeri di riga nello LineNumberTable?
    Un altro modo di indirizzarsi potrebbe essere la numerazione dei token invece degli offset effettivi nei file di origine.
  • Mentre amo l'idea di indicizzazione per token, questo significa che qualsiasi strumento in grado di utilizzare le informazioni di debug dovrebbe avere accesso a un parser completo.
    Un'altra possibilità potrebbe essere quella di riformattare il file in base a un insieme di regole rigorosamente definito e quindi continuare a utilizzare la numerazione delle righe.
  • Ho iniziato a lavorare sul miglioramento dell'esperienza di debug per i programmi Scala, e uno dei punti dolenti è in effetti numeri di linea. Idealmente ci sarebbe il supporto per più di un semplice numero di linea. Sto guardando JSR 45 (Supporto per il debug di altre lingue). Non sono ancora sicuro se questo è abbastanza, ma forse uno strato di Scala potrebbe usare il tuo schema.
    Penso che il modo migliore sia fornire informazioni aggiuntive, specifiche per Scala, di debug negli attributi classfile o annotazioni. Per quanto ne so, JDI non dà accesso agli attributi classfile, né alle annotazioni, ma ci sono alcuni trucchi che potremmo usare per raggiungerli.In questo modo conserveremmo le funzionalità esistenti e permetteremo agli strumenti di fare di più quando conoscono gli attributi di Scala.

(Nota: Scalate riferisce di aver fatto un lavoro simile in scalate-24 per un diverso tipo di file di origine)

2

Aggiornamento 2016: una libreria come lihaoyi/sourcecode include un logging use case con un nuovo approccio:

È possibile utilizzare sourcecode.File e sourcecode.Line per definire le funzioni di registro che catturano automaticamente il loro numero di riga e file-name

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 

Questo può essere utile per lasciare a vedere dove le linee di log sono provenienti da, senza noiosamente etichettare ogni affermazione registro con un prefisso univoco.
Inoltre, ciò avviene in fase di compilazione ed è quindi di ordine di grandezza più veloce di ottenere queste informazioni generando tracce di stack e funziona su Scala.js dove lo stack-inspection non è.
Infine, se si desidera fornire ulteriori informazioni come nomi di metodi, nomi di classi o pacchetti per la funzione di registrazione, è possibile farlo semplicemente chiedendo gli impliciti sourcecode.Name o sourcecode.FullName o sourcecode.Pkg.

0

Consiglierei di dare un'occhiata a Scribe. Scala è una soluzione di registrazione completa per Scala che utilizza i macro per generare numeri di linea e altre informazioni in fase di compilazione, quindi non c'è riduzione della velocità ed è integrata, quindi non devi usare qualcosa come e integrarla manualmente:

https://github.com/outr/scribe

Problemi correlati