-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Close #461 - Add LoggerFLogHandler to support doobie's LogHandler
- Loading branch information
Showing
6 changed files
with
266 additions
and
15 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
58 changes: 58 additions & 0 deletions
58
modules/logger-f-doobie1/shared/src/main/scala/loggerf/doobie1/LoggerFLogHandler.scala
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package loggerf.doobie1 | ||
|
||
import cats.syntax.all._ | ||
import doobie.util.log | ||
import doobie.util.log.LogHandler | ||
import loggerf.core.Log | ||
import loggerf.syntax.all._ | ||
|
||
/** @author Kevin Lee | ||
* @since 2023-07-28 | ||
*/ | ||
object LoggerFLogHandler { | ||
def apply[F[*]: Log]: LogHandler[F] = new LoggerFLogHandlerF[F] | ||
|
||
// format: off | ||
final private class LoggerFLogHandlerF[F[*]: Log] extends LogHandler[F] { | ||
override def run(logEvent: log.LogEvent): F[Unit] = logEvent match { | ||
case log.Success(sql, args, label, e1, e2) => | ||
logS_( | ||
show"""Successful Statement Execution: | ||
| | ||
| ${sql.linesIterator.dropWhile(_.trim.isEmpty).mkString("\n ")} | ||
| | ||
| arguments = [${args.mkString(", ")}] | ||
| label = $label | ||
| elapsed = ${e1.toMillis} ms exec + ${e2.toMillis} ms processing (${(e1 + e2).toMillis} ms total) | ||
|""".stripMargin | ||
)(info) | ||
|
||
case log.ProcessingFailure(sql, args, label, e1, e2, failure) => | ||
logS_( | ||
show"""Failed Resultset Processing: | ||
| | ||
| ${sql.linesIterator.dropWhile(_.trim.isEmpty).mkString("\n ")} | ||
| | ||
| arguments = [${args.mkString(", ")}] | ||
| label = $label | ||
| elapsed = ${e1.toMillis} ms exec + ${e2.toMillis} ms processing (failed) (${(e1 + e2).toMillis} ms total) | ||
| failure = ${failure.getMessage} | ||
|""".stripMargin | ||
)(error) | ||
|
||
case log.ExecFailure(sql, args, label, e1, failure) => | ||
logS_( | ||
show"""Failed Statement Execution: | ||
| | ||
| ${sql.linesIterator.dropWhile(_.trim.isEmpty).mkString("\n ")} | ||
| | ||
| arguments = [${args.mkString(", ")}] | ||
| label = $label | ||
| elapsed = ${e1.toMillis} ms exec (failed) | ||
| failure = ${failure.getMessage} | ||
|""".stripMargin | ||
)(error) | ||
} | ||
} | ||
// format: on | ||
} |
166 changes: 166 additions & 0 deletions
166
modules/logger-f-doobie1/shared/src/test/scala/loggerf/doobie1/LoggerFLogHandlerSpec.scala
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
package loggerf.doobie1 | ||
|
||
import cats.effect._ | ||
import doobie.util.log.{ExecFailure, ProcessingFailure, Success} | ||
import effectie.instances.ce3.fx.ioFx | ||
import extras.hedgehog.ce3.syntax.runner._ | ||
import hedgehog._ | ||
import hedgehog.runner._ | ||
import loggerf.instances.cats.logF | ||
import loggerf.testing.CanLog4Testing | ||
import loggerf.testing.CanLog4Testing.OrderedMessages | ||
|
||
import scala.concurrent.duration._ | ||
|
||
/** @author Kevin Lee | ||
* @since 2023-07-29 | ||
*/ | ||
object LoggerFLogHandlerSpec extends Properties { | ||
|
||
override def tests: List[Prop] = List( | ||
property("testSuccess", testSuccess), | ||
property("testExecFailure", testExecFailure), | ||
property("testProcessingFailure", testProcessingFailure), | ||
) | ||
|
||
def testSuccess: Property = | ||
for { | ||
columns <- Gen.string(Gen.alpha, Range.linear(3, 10)).list(Range.linear(1, 5)).log("columns") | ||
table <- Gen.string(Gen.alpha, Range.linear(3, 10)).log("table") | ||
args <- Gen.string(Gen.alpha, Range.linear(3, 10)).list(Range.linear(0, 5)).log("args") | ||
label <- Gen.string(Gen.alpha, Range.linear(3, 10)).log("label") | ||
exec <- Gen.int(Range.linear(10, 3000)).log("exec") | ||
processing <- Gen.int(Range.linear(10, 3000)).log("processing") | ||
} yield runIO { | ||
implicit val canLog: CanLog4Testing = CanLog4Testing() | ||
|
||
val expected = | ||
OrderedMessages( | ||
Vector( | ||
( | ||
0, | ||
loggerf.Level.info, | ||
s"""Successful Statement Execution: | ||
| | ||
| SELECT ${columns.mkString(", ")} FROM $table | ||
| | ||
| arguments = ${args.mkString("[", ", ", "]")} | ||
| label = $label | ||
| elapsed = ${exec.toString} ms exec + ${processing.toString} ms processing (${(exec + processing).toString} ms total) | ||
|""".stripMargin, | ||
) | ||
) | ||
) | ||
|
||
LoggerFLogHandler[IO] | ||
.run( | ||
Success( | ||
s"SELECT ${columns.mkString(", ")} FROM $table", | ||
args, | ||
label, | ||
exec.milliseconds, | ||
processing.milliseconds, | ||
) | ||
) *> IO { | ||
val actual = canLog.getOrderedMessages | ||
actual ==== expected | ||
} | ||
} | ||
|
||
def testExecFailure: Property = | ||
for { | ||
columns <- Gen.string(Gen.alpha, Range.linear(3, 10)).list(Range.linear(1, 5)).log("columns") | ||
table <- Gen.string(Gen.alpha, Range.linear(3, 10)).log("table") | ||
args <- Gen.string(Gen.alpha, Range.linear(3, 10)).list(Range.linear(0, 5)).log("args") | ||
label <- Gen.string(Gen.alpha, Range.linear(3, 10)).log("label") | ||
exec <- Gen.int(Range.linear(10, 3000)).log("exec") | ||
errMessage <- Gen.string(Gen.alpha, Range.linear(3, 10)).log("errMessage") | ||
} yield runIO { | ||
implicit val canLog: CanLog4Testing = CanLog4Testing() | ||
|
||
val expectedException = new RuntimeException(errMessage) | ||
|
||
val expected = | ||
OrderedMessages( | ||
Vector( | ||
( | ||
0, | ||
loggerf.Level.error, | ||
s"""Failed Statement Execution: | ||
| | ||
| SELECT ${columns.mkString(", ")} FROM $table | ||
| | ||
| arguments = ${args.mkString("[", ", ", "]")} | ||
| label = $label | ||
| elapsed = ${exec.toString} ms exec (failed) | ||
| failure = ${expectedException.getMessage} | ||
|""".stripMargin, | ||
) | ||
) | ||
) | ||
|
||
LoggerFLogHandler[IO] | ||
.run( | ||
ExecFailure( | ||
s"SELECT ${columns.mkString(", ")} FROM $table", | ||
args, | ||
label, | ||
exec.milliseconds, | ||
expectedException, | ||
) | ||
) *> IO { | ||
val actual = canLog.getOrderedMessages | ||
actual ==== expected | ||
} | ||
} | ||
|
||
def testProcessingFailure: Property = | ||
for { | ||
columns <- Gen.string(Gen.alpha, Range.linear(3, 10)).list(Range.linear(1, 5)).log("columns") | ||
table <- Gen.string(Gen.alpha, Range.linear(3, 10)).log("table") | ||
args <- Gen.string(Gen.alpha, Range.linear(3, 10)).list(Range.linear(0, 5)).log("args") | ||
label <- Gen.string(Gen.alpha, Range.linear(3, 10)).log("label") | ||
exec <- Gen.int(Range.linear(10, 3000)).log("exec") | ||
processing <- Gen.int(Range.linear(10, 3000)).log("processing") | ||
errMessage <- Gen.string(Gen.alpha, Range.linear(3, 10)).log("errMessage") | ||
} yield runIO { | ||
implicit val canLog: CanLog4Testing = CanLog4Testing() | ||
|
||
val expectedException = new RuntimeException(errMessage) | ||
|
||
val expected = | ||
OrderedMessages( | ||
Vector( | ||
( | ||
0, | ||
loggerf.Level.error, | ||
s"""Failed Resultset Processing: | ||
| | ||
| SELECT ${columns.mkString(", ")} FROM $table | ||
| | ||
| arguments = ${args.mkString("[", ", ", "]")} | ||
| label = $label | ||
| elapsed = ${exec.toString} ms exec + ${processing.toString} ms processing (failed) (${(exec + processing).toString} ms total) | ||
| failure = ${expectedException.getMessage} | ||
|""".stripMargin, | ||
) | ||
) | ||
) | ||
|
||
LoggerFLogHandler[IO] | ||
.run( | ||
ProcessingFailure( | ||
s"SELECT ${columns.mkString(", ")} FROM $table", | ||
args, | ||
label, | ||
exec.milliseconds, | ||
processing.milliseconds, | ||
expectedException, | ||
) | ||
) *> IO { | ||
val actual = canLog.getOrderedMessages | ||
actual ==== expected | ||
} | ||
} | ||
|
||
} |
This file contains 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