你当然可以。看看我创建的以下教程:https://www.varnish-software.com/developers/tutorials/vcl-synthetic-output-template-file/。
修改合成输出模板
这是您需要扩展常规 vcl_synth 子例程以防您从 VCL 代码调用 return(synth()) 的 VCL 代码,以及您需要扩展 vcl_backend_response 以防后端获取错误的代码:
vcl 4.1;
import std;
sub vcl_synth {
set resp.http.Content-Type = "text/html; charset=utf-8";
set resp.http.Retry-After = "5";
set resp.body = regsuball(std.fileread("/etc/varnish/synth.html"),"<<REASON>>",resp.reason);
return (deliver);
}
sub vcl_backend_error {
set beresp.http.Content-Type = "text/html; charset=utf-8";
set beresp.http.Retry-After = "5";
set beresp.body = regsuball(std.fileread("/etc/varnish/synth.html"),"<<REASON>>",beresp.reason);
return (deliver);
}
如教程中所述,您可以将要显示的 HTML 代码存储在 HTML 中,然后将其加载到 VCL 输出中。
诀窍是在您的 HTML 中放置一个 <<REASON>> 占位符,实际错误消息将被解析到该位置。
向您的 VCL 添加自定义日志记录
如果要添加发送到 VSL 的自定义日志记录,可以使用 std.log() 函数,它是 vmod_std 的一部分。
下面是一些使用此函数的示例 VCL 代码:
vcl 4.1;
import std;
sub vcl_recv {
std.log("Client IP: " + client.ip);
}
日志将通过您的 VSL 输出中的 VCL_Log 标签显示。
如果要过滤掉VCL_Log标签,可以使用如下命令:
varnishlog -g request -i VCL_Log
这是您可能收到的输出:
* << Request >> 32770
- VCL_Log Client IP: 127.0.0.1
** << BeReq >> 32771
如果您没有过滤 VCL_Log 标记,您会在运行 varnishlog -g request 时看到它出现在 VSL 输出中。
提示:如果您想查看完整的日志事务但仅针对特定 URL,只需运行 varnishlog -g request -q "ReqUrl eq '/'"。这只会显示主页的日志。
更新:在合成输出中显示客户端 IP
下面的 VCL 代码通过连接原因短语将 X-Forwarded-For 标头注入到输出中:
vcl 4.1;
import std;
sub vcl_synth {
set resp.http.Content-Type = "text/html; charset=utf-8";
set resp.http.Retry-After = "5";
set resp.body = regsuball(std.fileread("/etc/varnish/synth.html"),"<<REASON>>",resp.reason + " (" + req.http.X-Forwarded-For + ")");
return (deliver);
}
sub vcl_backend_error {
set beresp.http.Content-Type = "text/html; charset=utf-8";
set beresp.http.Retry-After = "5";
set beresp.body = regsuball(std.fileread("/etc/varnish/synth.html"),"<<REASON>>",beresp.reason + " (" + bereq.http.X-Forwarded-For + ")");
return (deliver);
}
还可以在模板中提供第二个占位符并执行额外的regsuball() 调用。但为了简单起见,X-Forwarded-For 标头只是附加到原因字符串。