UPDATE: SOLVED!!!
Please see the answer I added below
Does anyone know if there is a way to do logging that outputs real line numbers to the console? I'm trying to get into Scala here, but without being able to get basic stuff like this that I depend on, it's really hard to get much going.
I have set up slf4s to wrap with slf4j - log4j - jcl-over-slf4j. The problem is I get line numbers that do not match at all. The are much higher line numbers than the Scala class even contains. Is this because the line numbers are actually Java-intermediate line numbers?
Is there any EASY way to get set up logging that meets these requirements?:
Thanks!
Jamie
I have found that logback
(by Ceki Gülcü) works great and preserves line numbers too!
(And it works as a replacement for 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) + "")
}
}
For anyone struggling to get started with Scala, this is what I did to get the basic skeleton up:
1) Download sbt-launcher.jar
and put it someplace like /opt/
I used "sbt-launch-0.7.5.RC0.jar
"
2) Create a bash script as a shortcut to the sbt launcher in nano /opt/bin/sbt
:
#!/bin/bash
java -jar /opt/sbt-launch-0.7.5.RC0.jar "$@"
(make it executable)
$ sudo chmod ug+x ./sbt
Make sure it's in your path too.
3) Create and configure the sbt project:
$ mkdir ./sc01
$ cd ./sc01
$ sbt
$ mkdir ./project/build</pre>
$ nano ./project/build/Project.scala</pre>
put this in there:
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) Paste the stuff from above into Main:
$ nano ./src/main/scala/Main.scala
5) I almost forgot! put this in /src/main/resources/logback.xml
(it's required to get the line numbers)
<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
Now you should be in the sbt
console in your shell:
> update
> compile
> run
Hope this helps.
As you are commenting in Scala logging question, getting precise line number information in Scala is hard.
-g line
or -g vars
- Why does Scala not just overload the existing infrastructure by saving absolute offsets instead of line numbers in the
LineNumberTable
?
Another way of addressing could be by numbering the tokens instead of the actual offsets into source files.- While I love the idea of indexing by tokens, this means that any tool capable of using the debug information would need to have access to a full parser.
Another possibility would be to reformat the file according to some strictly-defined set of rules, and then continue to use line numbering.- I started working on improving the debugging experience for Scala programs, and one of the sore-points is indeed line numbers. Ideally there would be support for more than just line numbers. I am looking at JSR 45 (Debugging support for other languages). I am not sure yet if that is enough, but maybe a Scala stratum could use your scheme.
I think the better way is to provide additional, Scala specific, debugging information inclassfile
attributes or annotations. As far as I know, JDI does not give access toclassfile
attributes, nor to annotations, but there are some tricks we could use to get to them. This way we'd preserve existing functionality, and allow tools to do more when they know about Scala attributes.
(Note: Scalate reports having done a similar work in scalate-24 for a different kind of source files)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With