Closed emaysyuk closed 5 months ago
Maybe I'm missing something, but isn't this an unused value in these lines:
i.e. you're throwing away the value from the for yield:
...
.flatMap { httpServer =>
for {
given Logger[IO] <- DefaultLogger.makeIo(Output.fromConsole)
_ <- Logger[IO].warn("Before exception") // TODO: doesn't print anything
} yield () // this value is not saved or returned from the function?
Stream.eval(httpServer.useForever).concurrently {
throw new RuntimeException("Catch me and log to console")
}
}
I'll try to reproduce it
This works well on my end:
//> using dep co.fs2::fs2-core::3.10.2
//> using dep org.legogroup::woof-core::0.7.0
import cats.effect.unsafe.implicits.global
import org.legogroup.woof.{given, *}
import cats.effect.IO
import fs2.Stream
import Logger.*
given Filter = Filter.everything
given Printer = NoColorPrinter()
@main
def main(): Unit =
val program = for
given Logger[IO] <- DefaultLogger.makeIo(Output.fromConsole[IO])
_ <- Logger[IO].info("Hello, world!")
_ <- logInStream.withLogContext("stream" -> "log")
yield ()
program.unsafeRunSync()
def logInStream(using Logger[IO]): IO[Unit] =
Stream
.emits(1 to 10)
.evalMap(i => Logger[IO].info(s"Processing $i"))
.compile
.drain
prints
2024-05-20 20:43:37 [INFO ] fs2-woof$package$: Hello, world! (fs2-woof.scala:16)
2024-05-20 20:43:37 [INFO ] stream=log fs2-woof$package$: Processing 1 (fs2-woof.scala:25)
2024-05-20 20:43:37 [INFO ] stream=log fs2-woof$package$: Processing 2 (fs2-woof.scala:25)
2024-05-20 20:43:37 [INFO ] stream=log fs2-woof$package$: Processing 3 (fs2-woof.scala:25)
2024-05-20 20:43:37 [INFO ] stream=log fs2-woof$package$: Processing 4 (fs2-woof.scala:25)
2024-05-20 20:43:37 [INFO ] stream=log fs2-woof$package$: Processing 5 (fs2-woof.scala:25)
2024-05-20 20:43:37 [INFO ] stream=log fs2-woof$package$: Processing 6 (fs2-woof.scala:25)
2024-05-20 20:43:37 [INFO ] stream=log fs2-woof$package$: Processing 7 (fs2-woof.scala:25)
2024-05-20 20:43:37 [INFO ] stream=log fs2-woof$package$: Processing 8 (fs2-woof.scala:25)
2024-05-20 20:43:37 [INFO ] stream=log fs2-woof$package$: Processing 9 (fs2-woof.scala:25)
2024-05-20 20:43:37 [INFO ] stream=log fs2-woof$package$: Processing 10 (fs2-woof.scala:25)
Oh yeah, on the handleError
you're again giving it an unused value. The type of handleError
is:
def handleError[B >: A](f: Throwable => B): IO[B] =
handleErrorWith[B](t => IO.pure(f(t)))
you want to use handleErrorWith(...)
if you want side effects. So looks to me like you have unused effect values in both cases.
Made a pull request to demonstrate: https://github.com/emaysyuk/scala-woof-logger-issue/pull/1
@hejfelix Thank you for your prompt response and assistance. The example you provided is very helpful. This is my first experience with Cats Effect and FS2, so I'm finding it a bit challenging to understand everything. The logger works perfectly, so I believe we can consider this issue resolved.
Can anybody tell why logger doesn't print from inside of FS2 Stream (here and here)?
I've prepared a simple project to illustrate the problem.
https://github.com/emaysyuk/scala-woof-logger-issue
Looks like the problem in DefaultLogger#logToOutputs, the logger cannot summon
Local[IO, List[(String, String)]]
but I don't see why because no errors are thrown.