Scala: Adding logging around a repository
We wanted to add some logging around one of our repositories to track how many times users were trying to do various things on the application and came across a cool blog post explaining how we might be able to do this.
We ended up with the following code:
class BarRepository {
def all: Seq[Bar] = Seq()
def find(barId:String) : Bar = Bar("myBar")
}
class TrackService(barRepository:BarRepository) {
def all : Seq[Bar] = {
var bars = barRepository.all;
println("tracking all bars");
bars
}
}
implicit def trackServiceToBarRepository(t:TrackService) : BarRepository = t.barRepository
We can then use it like this:
scala> val service = new TrackService(new BarRepository())
service: TrackService = TrackService@4e5394c
scala> service.all
tracking all bars
res6: Seq[Bar] = List()
If a method doesn’t exist on TrackService then the implicit conversion ensures that the appropriate method will be called on BarRepository directly:
scala> service.find("mark")
res7: Bar = Bar(myBar)
I came across another way to achieve the same results by making use of traits although we’d need to change our design a little bit to achieve this pattern:
trait IProvideBars {
def all : Seq[Bar]
def find(barId:String) : Bar
}
class BarRepository extends IProvideBars {
def all: Seq[Bar] = Seq()
def find(barId:String) : Bar = Bar("myBar")
}
trait Tracking extends IProvideBars {
abstract override def all : Seq[Bar] = {
val bars = super.all;
println("tracking all bars");
bars
}
}
scala> val b = new BarRepository() with Tracking
b: BarRepository with Tracking = $anon$1@ddc652f
scala> b.all
tracking all bars
res8: Seq[Bar] = List()
About the author
I'm currently working on short form content at ClickHouse. I publish short 5 minute videos showing how to solve data problems on YouTube @LearnDataWithMark. I previously worked on graph analytics at Neo4j, where I also co-authored the O'Reilly Graph Algorithms Book with Amy Hodler.