· scala

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()
  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket