简体   繁体   English

添加日志记录需要更改方法签名 Cats-Effect?

[英]Adding logging requires changing method signature Cats-Effect?

I'm learning the whole Cats-Effect FP framework, and am wondering about how to best implement logging.我正在学习整个 Cats-Effect FP 框架,并且想知道如何最好地实现日志记录。 I'm struggling with finding an elegant way to use logging in methods that return non-side-effect types, particularly class constructors.我正在努力寻找一种优雅的方法来使用返回非副作用类型的登录方法,尤其是 class 构造函数。 For example:例如:

case class Limit(name: String, value: Int)

object Limit {
  def max(name: String): Limit = Limit(name, Int.MaxValue)
}

Now, if I want to add logging to the construction, which is obviously a side-effect, I would have to change the method signature to something like:现在,如果我想在构造中添加日志记录,这显然是一个副作用,我将不得不将方法签名更改为如下内容:

object Limit {
  def max[F[_] : Sync](name: String): F[Limit] = {
    for {
      _ <- Slf4jLogger.getLogger[F].debug("Creating max limit.")
    } yield {
      Limit(name, Int.MaxValue)
    }
  }
}

Such a change breaks code compatibility, and now every place that uses Limit.max needs to be refactored to deal with the type signatures, mapping and/or call .unsafeRun .这样的更改破坏了代码兼容性,现在每个使用Limit.max的地方都需要重构以处理类型签名、映射和/或调用.unsafeRun Quite a radical change for something as small as adding a log line.对于像添加日志行这样小的事情来说,这是一个相当大的变化。

Is there some way to do this more elegantly?有没有办法更优雅地做到这一点? Do I just drop log4cats and use the regular, unsafe SLF4J?我是否只删除 log4cats 并使用常规的、不安全的 SLF4J? Or do I just need to accept that in PF/Cats-Effect world it's safer to just return F[..] from everything everywhere, no matter how small or trivial the method is?或者我是否只需要接受在 PF/Cats-Effect 世界中从任何地方返回F[..]更安全,无论该方法多么小或微不足道?

I think it would be better to use log4cats library.我认为使用log4cats库会更好。 If you use cats-effect, probably your Main class returns IO[Exit] and almost whole your logic wouldn't require any unsafe calls.如果您使用猫效应,您的 Main class 可能会返回 IO[Exit] 并且几乎整个逻辑都不需要任何不安全的调用。

But at the same time I saw a lot of projects that uses just a plain logging without wrapping logs inside of IO. It depends on you and/or your team/project.但与此同时,我看到很多项目只使用普通日志记录,而没有在 IO 内包装日志。这取决于你和/或你的团队/项目。 I personally prefer FP way.我个人更喜欢 FP 方式。

I left an example of using log4cats here:我在这里留下了一个使用 log4cats 的例子:


implicit def logger[F[_]: Sync]: Logger[F] = Slf4jLogger.getLogger[F]

case class Limit(name: String, value: Int)
  
object Limit {
  def max[F[_] : Sync: Logger](name: String): F[Limit] = {
    for {
      _ <- Logger[F].info("Creating max limit.")
    } yield {
      Limit(name, Int.MaxValue)
    }
  }
}

build.sbt file: build.sbt 文件:

libraryDependencies ++= Seq(
  "org.typelevel" %% "log4cats-core"    % "2.5.0",  // Only if you want to Support Any Backend
  "org.typelevel" %% "log4cats-slf4j"   % "2.5.0",  // Direct Slf4j Support - Recommended
  // and some backend such as logback or smth
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM