NewRelic PHP-agent Laravel环境下raw模式SQL值显示为?问题求助
newrelic.transaction_tracer.record_sql=raw 不显示实际SQL参数的问题排查与解决 问题背景
配置newrelic.transaction_tracer.record_sql="raw"后,NewRelic APM中SQL语句的参数仍显示为?,而非实际值。切换到off模式SQL不再显示,obfuscated模式显示?符合预期,但raw模式始终异常。同版本NewRelic agent在CodeIgniter环境中可正常显示实际参数,已确认newrelic.high_security为默认false,显式设置newrelic.framework="laravel"也未解决问题。当前环境:PHP 8.0.30 (NTS),NewRelic PHP-agent 10.14.0.3-1563e8045968。
排查与解决方法
1. 检查Laravel查询日志的影响
Laravel的查询日志机制会预处理SQL语句,将参数替换为?后再记录,可能在NewRelic捕获前就修改了SQL内容。试试临时关闭查询日志测试:
// 在测试代码中临时禁用查询日志 DB::connection()->disableQueryLog();
如果关闭后NewRelic能显示实际参数,说明是Laravel查询日志的干扰。生产环境中可以调整config/database.php里的query_log配置,或者只在特定环境开启查询日志。
2. 调整NewRelic agent版本或框架适配
部分NewRelic agent版本对Laravel Eloquent的参数捕获存在兼容性问题。试试升级agent到最新稳定版,或者对比CodeIgniter环境的agent版本,若版本一致则跳过此步骤。
3. 验证PHP扩展加载顺序
确保NewRelic扩展在数据库扩展(如pdo_mysql、mysqli)之前加载,否则agent无法正确拦截数据库查询的参数。检查php.ini中的扩展加载顺序:
extension=newrelic.so extension=pdo_mysql.so
如果顺序颠倒,调整后重启PHP服务。
4. 排查其他拦截类工具/扩展
Laravel Debugbar、其他APM工具或安全扩展可能会修改SQL输出,导致NewRelic无法获取原始参数。临时禁用这些工具,测试是否恢复正常。
5. 手动通过NewRelic API记录SQL参数
如果自动捕获失效,可以在Laravel中监听查询事件,手动记录完整SQL和参数到NewRelic自定义事件:
// 在AppServiceProvider的boot方法中添加 DB::listen(function ($query) { if (extension_loaded('newrelic')) { // 绑定参数替换到SQL中(可选,根据需求调整) $rawSql = vsprintf(str_replace('?', '%s', $query->sql), array_map(function ($binding) { return is_string($binding) ? "'{$binding}'" : $binding; }, $query->bindings)); newrelic_record_custom_event('Raw_SQL_Query', [ 'sql' => $rawSql, 'execution_time' => $query->time, 'connection' => $query->connectionName ]); } });
这样可以在NewRelic的自定义事件面板中查看带实际参数的SQL语句。
内容的提问来源于stack exchange,提问作者Scott H

