Skip to content

Instantly share code, notes, and snippets.

@twolfe18
Last active December 22, 2015 11:18
Show Gist options
  • Save twolfe18/6464602 to your computer and use it in GitHub Desktop.
Save twolfe18/6464602 to your computer and use it in GitHub Desktop.
a simple logging scheme in scala (that i can understand). i know there are a million logging frameworks, most of which probably have more features than this. but the way i see it, the time that it takes to learn one of those is about the same as the time it takes to write this one. the nice benefit of doing it this way is that i can always just …
// NOTE: I actually made a mistake in this implementation
// Logging needs to have a redirect with type Logging, not Logger
// this is so that if a->b and b gets redirected, things logged via a.log()
// actually get forwarded along (regardless of what came first: redirecting
// b somewhere else or the call to a.log()).
// the only thing to worry about is loops, but i'm willing to take that risk for now.
// i have an implementation of this in Parma called Logging2
import util.Random
// TODO in a real implementation, this would be a trait
class Logger {
private[this] val id = Random.nextInt
def log(msg: String) {
println("from logger %d, message: %s".format(id, msg))
}
}
trait Logging {
// TODO include ability to tee? thats a bit more than i need...
private[Logging] val defaultLogger = new Logger
private[Logging] var logger = defaultLogger
def log(msg: String) {
logger.log(this + "\t" + msg)
}
def redirectLogTo(l: Logging) {
logger = l.logger
}
def undoLogRedirection {
logger = defaultLogger
}
def logTo(l: Logger)(block: => Any) {
val temp = logger
logger = l
block
logger = temp
}
}
class Foo extends Logging {
val specialLogger = new Logger
def foo { log("hello") }
def specialFun {
logTo(specialLogger) {
log("special!")
}
log("not-so-special")
}
}
class Bar extends Logging {
def bar { log("hello") }
// namespace is not polluted by things defined as private[Logging]
// error: value defaultLogger in trait Logging cannot be accessed in Bar
//def baz { defaultLogger.log("polluted namespace!") }
}
object Run {
def main(args: Array[String]) {
val f = new Foo
val b = new Bar
val b2 = new Bar
f.foo
b.bar
b2.bar
f.redirectLogTo(b)
f.foo // prints from b
f.specialFun // prints from its own log
b2.bar // prints from b2's original logger
f.foo // prints from b
f.undoLogRedirection
f.foo // prints from f's original logger
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment