ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

FrankenPHP 日志实战指南:使用 frankenphp_log() 与 error_log() 接入 Caddy 结构化日志体系

FrankenPHP 日志实战指南:使用 frankenphp_log() 与 error_log() 接入 Caddy 结构化日志体系 FrankenPHP 日志实战指南使用 frankenphp_log() 与 error_log() 接入 Caddy 结构化日志体系【免费下载链接】frankenphp The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphpFrankenPHP 将 PHP 运行时嵌入 Caddy并直接复用 Caddy 成熟的日志基础设施让你在 PHP 代码中既能使用标准库的error_log()保持兼容性也能调用专有的frankenphp_log()输出带级别与上下文的结构化日志轻松对接 Datadog、Grafana Loki、Elastic 乃至 OpenTelemetry 等可观测性平台。读完本文你将掌握两种日志方式的完整用法、参数语义、输出格式以及它们背后的 Go slog 实现原理从而在生产环境中构建可筛选、可查询的日志链路。本文基于 docs/es/logging.md 编写并补充了仓库源码层面的实现证据。一、日志系统概览PHP 与 Caddy 日志的桥接FrankenPHP 的日志能力建立在两个层次之上Caddy 日志系统FrankenPHP 作为 Caddy 模块运行时会把 Caddy 的slog.Logger注入到 PHP 执行上下文见 caddy/app.go 中的frankenphp.WithLogger(f.logger)因此 PHP 侧发出的日志最终都汇入 Caddy 的统一日志流。PHP 侧两种写入途径面向新应用的frankenphp_log()结构化日志以及面向存量代码兼容的error_log()标准函数。两者可以混用日志都会出现在同一套 Caddy 日志输出中。使用docker compose logs或journalctl查看容器/服务日志时你能直接看到这两种方式产生的日志条目。二、frankenphp_log()结构化日志的首选frankenphp_log()允许 PHP 应用直接发出结构化日志内置严重级别与可选上下文数据是生产环境观测性的推荐入口。2.1 函数签名与参数语义function frankenphp_log(string $message, int $level FRANKENPHP_LOG_LEVEL_INFO, array $context []): void参数类型说明messagestring日志消息文本levelint日志严重级别可为任意整数默认FRANKENPHP_LOG_LEVEL_INFOcontextarray关联数组附加到日志条目的上下文数据内置的级别常量定义在 frankenphp.stub.php常量值对应 slog 级别FRANKENPHP_LOG_LEVEL_DEBUG-4DebugFRANKENPHP_LOG_LEVEL_INFO0InfoFRANKENPHP_LOG_LEVEL_WARN4WarnFRANKENPHP_LOG_LEVEL_ERROR8Errorlevel的值直接对应 Golog/slog的slog.Level数字越小越不重要因此你可以传入任意整数以表达介于标准级别之间的严重程度常量只是常用档位的便捷约定。2.2 基本示例?php // 记录一条简单的 info 日志 frankenphp_log(¡Hola desde FrankenPHP!); // 记录一条带上下文数据的警告日志 frankenphp_log( Uso de memoria alto, FRANKENPHP_LOG_LEVEL_WARN, [ uso_actual memory_get_usage(), uso_pico memory_get_peak_usage(), ], );查看日志例如通过docker compose logs时输出是 JSON 格式的结构化条目{level:info,ts:1704067200,logger:frankenphp,msg:¡Hola desde FrankenPHP!} {level:warn,ts:1704067200,logger:frankenphp,msg:Uso de memoria alto,uso_actual:10485760,uso_pico:12582912}每条记录都包含level严重级别、tsUnix 时间戳、logger来源标识固定为frankenphp、msg消息context数组中的键值对则被平铺展开为记录顶层字段如示例中的uso_actual、uso_pico。2.3 底层实现从 PHP 到 Go slog 的完整链路frankenphp_log()的 C 层实现在 frankenphp.c通过ZEND_PARSE_PARAMETERS依次解析message字符串、level长整型、context数组三个参数然后调用go_log_attrs()将请求交给 Go 层若 Go 层返回错误字符串则抛出RuntimeException例如 context 中存在无法转换为 Go 类型的值。Go 侧的go_log_attrs()位于 frankenphp.go核心逻辑分为三步级别过滤调用logger.Enabled(ctx, level)判断当前级别是否被启用被过滤的日志直接丢弃——这正是文档 Tips 中所说可按级别Debug、Error 等过滤日志的机制来源。上下文转换通过GoMap将 PHP 关联数组转换为 Go 的map[string]any转换失败时返回错误消息该消息会成为 PHP 侧的RuntimeException。结构化输出通过mapToAttr()将 map 的每个键值对转换为slog.Attr最终以logger.LogAttrs(...)写入 Caddy 日志流从而支持 JSON 序列化与各类日志后端摄取。也就是说frankenphp_log()本质上是对 Golog/slog包的一层薄封装见 frankenphp.go 引入的log/slog这也是它能无缝对接 OpenTelemetry、Loki、Datadog 等生态的原因——这些平台大多原生支持 slog 生态的结构化日志摄取。仓库中的示例与测试也印证了四种级别的用法测试脚本 testdata/log-frankenphp_log.php 依次以 DEBUG、INFO、WARN、ERROR 级别写入日志并携带不同类型的 context 值整数、字符串、数组profiles/app/frankenphp_log.php 则展示了在实际应用 profile 中的调用模式。三、error_log()面向存量代码的兼容通道FrankenPHP 同样支持标准error_log()函数。当第二个参数$message_type为4即 SAPI 类型时消息会被重定向到 Caddy 的日志记录器error_log(Fallo en la conexión a la base de datos, 4);这条日志会出现在 Caddy 的日志输出中且通常带有表明其来源于 PHP 的前缀标识。从源码看这一机制由 SAPI 层的日志钩子实现在 frankenphp.c 中frankenphp_log_message()将消息连同 syslog 级别一起转发给 Go 层的go_log()该函数被注册为 SAPI 模块的 Log message 处理器见 frankenphp.cPHP 标准库的error_log()在message_type4时正是经由该处理器落盘。Go 侧的go_log()frankenphp.go会把 syslog 级别映射为 slog 级别emerg/alert/crit/err映射为Error、warn映射为Warn、debug映射为Debug、其余归为Info并在记录中附带syslog_level属性。需要说明的是默认情况下经error_log()发出的消息被视为非结构化文本。它的价值在于兼容许多存量应用与第三方库仍依赖 PHP 标准库的日志函数无需修改业务代码即可把日志汇入 Caddy。四、生产环境选型建议新代码优先用frankenphp_log()它输出的 JSON 结构化记录天然带级别与可查询字段方便在 Datadog、Grafana Loki、Elastic 等平台按级别筛选、按字段检索也便于接入 OpenTelemetry。存量代码保留error_log(..., 4)作为兼容通道保证依赖标准库的库与框架无需改动即可被观测。利用级别过滤控制噪声得益于logger.Enabled()的级别过滤机制你可以通过调整 Caddy 侧的日志级别阈值在生产环境屏蔽 Debug 级噪声仅在排障时临时放开。五、延伸阅读原始文档西班牙文docs/es/logging.md可观测性相关文档docs/observability.md函数与常量声明PHP stubfrankenphp.stub.phpC 层实现frankenphp.cGo 层 slog 桥接frankenphp.go【免费下载链接】frankenphp The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表