Commit 9c395884 authored by Kunshan Wang's avatar Kunshan Wang

Allow logback XML configuration

This will give the user more control over logging in Holstein.
Specifically, the XML configuration can configure appenders so that logs
can be written into stderr instead of stdout.
parent 9162db02
......@@ -241,7 +241,20 @@ globalSize must be a multiple of 32768 bytes (32K).*
[mu-client-pypy](https://gitlab.anu.edu.au/mu/mu-client-pypy/) project to
work. default: false
*Log levels can be: ALL, TRACE, DEBUG, INFO, WARN, ERROR, OFF. Case-insensitive.
Holstein uses the [logback](https://logback.qos.ch/) framework as its logging
backend. Logs can be configured using XML configuration by specifying the
following option:
- **logbackConfig**: The path to the logback XML configuration file.
Example:
```
./tools/runmu.sh --logbackConfig=./logging/logging.xml -- ./target/boot-image-echo.muref Hello world!
```
Alternatively, you can set the log level using the following options. *Log
levels can be: ALL, TRACE, DEBUG, INFO, WARN, ERROR, OFF. Case-insensitive.
Setting to WARN should get rid of most logging information, except the serious
ones.* The default log level is DEBUG.
......
<!-- This is an example. Make a copy of this file, and modify it for your need. -->
<configuration>
<!-- Set debug="true" to enable debugging for the logback logging framework itself -->
<!-- configuration debug="true" -->
<!-- This appender writes into stdout -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="uvm.refimpl.itpr" level="DEBUG" />
<!-- This appender writes into stderr -->
<appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender">
<target>System.err</target>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- Loggers are organised by packages. uvm includes everything in Holstein. -->
<logger name="uvm" level="INFO" />
<logger name="uvm.refimpl.itpr" level="INFO" /> <!-- Set this to DEBUG to print execution traces. -->
<logger name="uvm.refimpl.mem" level="INFO" /> <!-- Set this to DEBUG to print GC logs. -->
<root level="INFO">
<appender-ref ref="STDERR" />
</root>
</configuration>
<!--
vim: ts=2 sw=2 sts=2 et
-->
......@@ -8,13 +8,15 @@ package uvm.refimpl
import scala.collection.mutable.ArrayBuffer
import uvm.refimpl.mem.TypeSizes._
import org.slf4j.LoggerFactory
import ch.qos.logback.classic.joran.JoranConfigurator
import ch.qos.logback.classic.LoggerContext
class VMOption[+T](
val name: String,
val desc: String,
val parser: String => T,
val default: T
) {
val default: T) {
def maybeParse(maybeStr: Option[String]): T = {
maybeStr.map(parser).getOrElse(default)
}
......@@ -57,8 +59,7 @@ object VMConfParser {
name: String,
desc: String,
parser: String => T,
default: T
): VMOption[T] = {
default: T): VMOption[T] = {
val option = new VMOption[T](name, desc, parser, default)
options += option
option
......@@ -125,6 +126,12 @@ Each is passed to the dlsym function.""",
parser = parseMaybeString,
default = VMConf.DEFAULT_CONF.bootImg)
val logbackConfig = opt[String](
name = "logbackConfig",
desc = """The logback XML configuration file""",
parser = identity,
default = "")
val vmLog = opt[String](
name = "vmLog",
desc = """The log level of the micro VM. Can be ALL, TRACE, DEBUG, INFO, WARN, ERROR, OFF""",
......@@ -164,8 +171,7 @@ object VMConf {
}
def apply(kvMap: Map[String, String]): VMConf = {
kvMap.get("vmLog") foreach { value => setLog("uvm", value) }
kvMap.get("gcLog") foreach { value => setLog("uvm.refimpl.mem", value) }
configureLog(kvMap)
new VMConf(
sosSize = VMConfParser.sosSize(kvMap),
......@@ -178,8 +184,21 @@ object VMConf {
automagicReloc = VMConfParser.automagicReloc(kvMap),
extraLibs = VMConfParser.extraLibs(kvMap),
bootImg = VMConfParser.bootImg(kvMap),
uPtrHack = VMConfParser.uPtrHack(kvMap)
)
uPtrHack = VMConfParser.uPtrHack(kvMap))
}
def configureLog(kvMap: Map[String, String]): Unit = {
kvMap.get("logbackConfig") foreach { filename =>
val context = LoggerFactory.getILoggerFactory().asInstanceOf[LoggerContext]
context.reset()
val configurator = new JoranConfigurator();
configurator.setContext(context);
configurator.doConfigure(filename);
}
kvMap.get("vmLog") foreach { value => setLog("uvm", value) }
kvMap.get("gcLog") foreach { value => setLog("uvm.refimpl.mem", value) }
}
def setLog(name: String, levelStr: String): Unit = {
......@@ -204,6 +223,5 @@ class VMConf(
val automagicReloc: Boolean = false,
val extraLibs: Seq[String] = Seq(),
val bootImg: Option[String] = None,
val uPtrHack: Boolean = false
)
val uPtrHack: Boolean = false)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment