Last active
December 22, 2015 11:18
-
-
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 …
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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