You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置Yesod日志的日期时间格式及自定义日志内容?

如何配置Yesod日志的日期时间格式及自定义日志内容?

嘿,我刚好处理过类似的Yesod日志自定义需求,你遇到的日期格式固定、自动带源码位置的问题,其实是因为Yesod默认用了monad-logger的一套默认输出逻辑,咱们可以通过自定义日志函数来完全掌控日志格式,下面一步步来:

一、核心思路:替换默认的LogFunc

Yesod的日志系统依赖LogFunc类型的函数来处理日志输出,默认实现会自动添加时间戳、源码位置这些内容,我们只需要自己实现一个符合要求的LogFunc,再替换掉Yesod应用的默认日志器就行。

二、具体实现步骤

1. 准备必要的导入模块

首先把这些模块导入加到你的Main.hs里:

import Control.Monad.Logger (LogLevel(..), LogFunc, ToLogStr(..), fromLogStr)
import Data.Time (getZonedTime, formatTime)
import System.Locale (defaultTimeLocale)
import Yesod.Core (Yesod(..))

2. 编写自定义日志输出函数

这个函数可以完全由你控制输出内容:

  • 自定义日期格式:用formatTime指定你想要的时间格式(比如%Y-%m-%d %H:%M:%S %Z对应2024-10-20 13:12:39 UTC)
  • 去掉源码位置:直接忽略传入的loc参数就行,不用把它加到日志里
customLogFunc :: IO LogFunc
customLogFunc = do
  -- 这里可以随便改你想要的日期格式,比如换成"%d/%b/%Y:%H:%M:%S %z"就是默认的格式
  let desiredTimeFormat = "%Y-%m-%d %H:%M:%S %Z"
  return $ \_loc logLevel sourceStr msg -> do
    -- 获取当前时间并格式化
    currentTime <- getZonedTime
    let formattedTime = formatTime defaultTimeLocale desiredTimeFormat currentTime
        -- 拼接你要的日志内容,完全自定义
        logContent = unwords
          [ formattedTime
          , "[" ++ show logLevel ++ "#" ++ sourceStr ++ "]"
          , fromLogStr msg
          ]
    -- 输出到标准输出,你也可以改成写入文件等其他逻辑
    putStrLn logContent

3. 让Yesod应用使用自定义日志器

找到你定义Yesod App实例的地方,重写makeLogger方法,替换成我们的自定义函数:

instance Yesod App where
  -- 保留你原有的其他Yesod配置...
  makeLogger _ = customLogFunc

4. 测试你的自定义日志

这个自定义日志函数完全兼容你原来的$logInfoS调用方式,不需要修改你现有的postFailed代码,运行后日志就会变成你定义的格式,比如:

2024-10-20 13:12:39 UTC [Info#(Parser)] Error[...]

完全没有多余的源码位置信息,日期格式也是你想要的样子。

额外小技巧

  • 如果只是想保留默认日期格式但去掉源码位置,只需要在默认的日志输出逻辑里忽略loc参数就行
  • 如果要把日志写入文件而不是标准输出,只需要把putStrLn改成对应的文件写入逻辑(比如用appendFile)

备注:内容来源于stack exchange,提问作者OrenIshShalom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 12:48:10