cvo*_*ogt 6 logging trace haskell metaprogramming template-haskell
在我们的 haskell 代码库中,业务逻辑与跟踪和日志代码交织在一起。这会模糊业务逻辑,使其更难理解和调试。我正在寻找如何减少日志记录和跟踪的代码占用空间以使业务逻辑更加突出的想法。
我们的代码目前大致如下所示:
someFunction a b cs = 
  withTaggedSpan tracer "TRACE_someFunction" [("arg_b", show b)] $ do
    logDebug logger $ "someFunction start: " <> show (trimDownC <$> cs)
    result <- do ... some business logic ...
    if isError result then
      logError logger $ "someFunction error: " <> show result
    else
      logDebug logger $ "someFunction success: " <> show (trimDownResult result)
一个观察结果是 whe 主要跟踪整个函数体并在开始和结束时记录。这应该允许将跟踪和日志记录合并到单个帮助程序中,并通过元编程自动提取函数名称和捕获值的名称。我之前在其他语言中使用过 AST 转换编译时宏和运行时内省,但没有在 Haskell 中使用过。
使用 Template Haskell、HasCallStack 或其他选项执行此操作的好方法是什么?
(交叉发布在https://www.reddit.com/r/haskell/comments/gdfu52/extracting_context_for_tracinglogging_via_haskell/)
Mar*_*ann -2
纯函数是确定性的。如果您知道其中的内容,则始终可以重现结果。因此,您不需要在功能代码库的主要部分内进行大量日志记录。
仅记录不纯的操作,并将您的代码构建为具有小型命令式 shell 的纯核心。仅记录 shell 中发生的不纯操作。我已在此处的博客文章中描述了该技术。