Skip to content

Commit

Permalink
Merge pull request #123 from TinkoffCreditSystems/atom-logging
Browse files Browse the repository at this point in the history
Add reference logging
  • Loading branch information
Odomontois authored Jan 23, 2020
2 parents 1682193 + 04ff3e1 commit 8b48c8f
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 12 deletions.
17 changes: 14 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Publish._, Dependencies._
import com.typesafe.sbt.SbtGit.git

val libVersion = "0.6.1"
val libVersion = "0.6.2"

lazy val setMinorVersion = minorVersion := {
CrossVersion.partialVersion(scalaVersion.value) match {
Expand Down Expand Up @@ -105,9 +105,20 @@ lazy val loggingLayout = project
)
.dependsOn(loggingStr)

lazy val loggingUtil = project
.in(file("logging/util"))
.settings(
defaultSettings,
publishName := "logging-util",
libraryDependencies += slf4j,
)
.dependsOn(loggingStr, concurrent)



lazy val logging = project
.dependsOn(loggingStr, loggingDer, loggingLayout)
.aggregate(loggingStr, loggingDer, loggingLayout)
.dependsOn(loggingStr, loggingDer, loggingLayout, loggingUtil)
.aggregate(loggingStr, loggingDer, loggingLayout, loggingUtil)
.settings(defaultSettings)

lazy val env = project
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/tofu/syntax/bracket.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ object bracket {

def bracketAlways[B, C](
use: A => F[B]
)(release: A => F[C])(implicit F: Applicative[F], FG: Guarantee[F]): F[B] =
)(release: A => F[C])(FG: Guarantee[F]): F[B] =
FG.bracket(fa)(use) { case (a, _) => release(a) }

def guaranteeIncomplete[B](release: F[B])(implicit F: Applicative[F], FG: Guarantee[F]): F[A] =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package tofu.logging

trait LogsVOps[I[_], F[_]]
trait LogsVOps[+I[_], F[_]]
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package tofu.logging

trait LogsVOps[I[_], F[_]] { self: Logs[I, F] =>
trait LogsVOps[+I[_], F[_]] { self: Logs[I, F] =>
final def named[name <: String with Singleton](
implicit name: ValueOf[name]
): I[ServiceLogging[F, name]] =
Expand Down
6 changes: 3 additions & 3 deletions logging/structured/src/main/scala/tofu/logging/Logging.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import cats.{Applicative, Apply, FlatMap}
import com.github.ghik.silencer.silent
import org.slf4j.{Logger, LoggerFactory, Marker}
import tofu.higherKind
import tofu.higherKind.{Embed, RepresentableK}
import tofu.higherKind.{Embed, Function2K, RepresentableK}
import tofu.logging.impl.EmbedLogging
import tofu.syntax.functionK._
import tofu.syntax.monoidalK._

import scala.reflect.ClassTag

Expand Down Expand Up @@ -94,7 +94,7 @@ object Logging {

/** having two logging implementation call `first` after `second` */
def combine[F[_]: Apply](first: Logging[F], second: Logging[F]): Logging[F] =
loggingRepresentable.map2K(first, second)(makeFunctionK(t => t.first *> t.second))
first.zipWithK(second)(Function2K[F, F, F](_ *> _))

private[logging] def loggerForService[S](implicit ct: ClassTag[S]): Logger =
LoggerFactory.getLogger(ct.runtimeClass)
Expand Down
6 changes: 3 additions & 3 deletions logging/structured/src/main/scala/tofu/logging/Logs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import tofu.syntax.monadic._

import scala.reflect.ClassTag

trait Logs[I[_], F[_]] extends LogsVOps[I, F] {
trait Logs[+I[_], F[_]] extends LogsVOps[I, F] {
def forService[Svc: ClassTag]: I[Logging[F]]
def byName(name: String): I[Logging[F]]

Expand Down Expand Up @@ -53,15 +53,15 @@ object Logs {
def byName(name: String): I[Logging[F]] = logging.pure[I]
}

def empty[I[_]: Applicative, F[_]: Applicative]: Logs[I, F] = const(Logging.empty[F])
def empty[I[_]: Applicative, F[_]: Applicative]: Logs[I, F] = const[I, F](Logging.empty[F])

def combine[I[_]: Apply, F[_]: Apply](las: Logs[I, F], lbs: Logs[I, F]): Logs[I, F] = new Logs[I, F] {
def forService[Svc: ClassTag]: I[Logging[F]] = las.forService.map2(lbs.forService)(Logging.combine[F])
def byName(name: String): I[Logging[F]] = las.byName(name).map2(lbs.byName(name))(Logging.combine[F])
}

implicit def logsMonoid[I[_]: Applicative, F[_]: Applicative]: Monoid[Logs[I, F]] = new Monoid[Logs[I, F]] {
def empty: Logs[I, F] = Logs.empty
def empty: Logs[I, F] = Logs.empty[I, F]
def combine(x: Logs[I, F], y: Logs[I, F]): Logs[I, F] = Logs.combine(x, y)
}

Expand Down
43 changes: 43 additions & 0 deletions logging/util/src/main/scala/tofu/logging/atom/AtomLogger.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package tofu.logging.atom
import java.time.Instant
import java.util.concurrent.TimeUnit

import cats.effect.Clock
import cats.{Applicative, FlatMap}
import tofu.concurrent.Atom
import tofu.higherKind.Embed
import tofu.logging.{LoggedValue, Logging, Logs}
import tofu.syntax.monadic._

import scala.reflect.{ClassTag, classTag}

final case class LogLine(
loggerName: String,
level: Logging.Level,
message: String,
timestamp: Instant,
values: Vector[LoggedValue],
)

class AtomLogging[F[_]: FlatMap: Clock](log: Atom[F, Vector[LogLine]], name: String) extends Logging[F] {
override def write(level: Logging.Level, message: String, values: LoggedValue*): F[Unit] =
Clock[F].realTime(TimeUnit.MILLISECONDS).flatMap { time =>
log.update(
_ :+ LogLine(
loggerName = name,
level = level,
message = message,
timestamp = Instant.ofEpochMilli(time),
values = values.toVector
)
)
}

}

final case class AtomLogs[I[_]: Applicative, F[_]: FlatMap: Clock](flog: F[Atom[F, Vector[LogLine]]])
extends Logs[I, F] {
def forService[Svc: ClassTag]: I[Logging[F]] = byName(classTag[Svc].runtimeClass.getName)
def byName(name: String): I[Logging[F]] =
Embed.of(flog.map[Logging[F]](new AtomLogging[F](_, name))).pure[I]
}

0 comments on commit 8b48c8f

Please sign in to comment.