VSL-查询

VarnishVSL查询表达式

手册部分:

7

OVERVIEW

Varnish VSL查询表达式从Varnish共享内存日志中提取事务,并在报告匹配之前对事务执行查询。

事务是一组属于一起的日志行,例如客户端请求或后端请求。API监视日志,并在报告该事务之前收集组成该事务的所有日志记录。事务也可以分组,这意味着后端事务与发起它的客户端事务一起报告。

对一组事务运行查询。如果组中有满足条件的日志记录,则查询表达式为TRUE。仅当没有日志记录满足条件时,才为FALSE。可以使用布尔函数组合查询表达式。除了日志记录外,还可以在查询中查询事务ID(Vxid)。

GROUPING

当对事务进行分组时,有一个层次结构来显示哪个事务启动了什么。在“Initiated By”关系上,级别增加1,因此,例如,后端事务的级别将比在缓存未命中时启动它的客户端事务高一个级别。请求重启事务的级别不会增加以使其可预测。

级别从1开始计数,除非使用RAW,而RAW始终为0。

分组模式包括:

  • session

    由客户端连接发起的所有事务一起报告。当使用HTTP Keep-Alive时,客户端连接是开放的,因此何时报告会话是未定义的。如果超过事务超时期限,将报告会话不完整。不报告非事务性数据(vxid==0)。

  • request

    事务按请求分组,其中集合将包括请求本身以及任何后端请求或ESI子请求。不报告会话数据和非事务数据(vxid==0)。

  • vxid

    事务没有分组,因此每个vxid都是完整报告的。会话、请求、ESI请求和后端请求均单独上报。不报告非事务性数据(vxid==0)。这是默认设置。

  • raw

    每条日志记录都将构成其自己的事务。将报告所有数据,包括非交易性数据。

事务层次结构

使用请求分组模式的事务层次结构示例:

Lvl 1: Client request (cache miss)
  Lvl 2: Backend request
  Lvl 2: ESI subrequest (cache miss)
    Lvl 3: Backend request
    Lvl 3: Backend request (VCL restart)
    Lvl 3: ESI subrequest (cache miss)
      Lvl 4: Backend request
  Lvl 2: ESI subrequest (cache hit)

内存使用情况

API将尽可能长时间地使用指向共享内存日志数据的指针,以将内存使用量保持在最低水平。但由于共享内存日志是环形缓冲区,数据最终会被覆盖,因此当varnishd接近覆盖仍未报告的内容时,API会创建引用的日志数据的本地副本。

这个过程在许多情况下避免了日志数据的丢失,但它不是故障安全的:当API客户端不能保持读取和/或复制时,例如由于输出阻塞,仍然可能发生溢出,即varnishd在环形缓冲区中“超越”日志读取器进程。

尽管原则上与分组无关,但复制日志数据与会话分组以及持久的客户端连接特别相关-对于此分组,日志API客户端进程可能会消耗相关的内存量。由于vxid分组还记录(可能持续时间较长的)会话,因此它也可能需要用于日志条目副本的内存,但远远少于会话分组。

查询语言

查询表达式由记录选择条件以及可选的运算符和值组成,以与所选记录进行匹配。**

<record selection criteria> <operator> <operand>

此外,查询表达式可以发生在事务本身上,而不是属于事务的日志记录上。**

vxid <numerical operator> <integer>

A vxid 查询允许您直接针对特定的交易,其id可以从 X-Varnish Http标头,默认的“大师冥想”错误页面,或者 BeginLink 日志记录。

一个查询必须适合一行,但可以一次传递多个查询,每行一个查询。空行被忽略,查询列表被视为使用‘or’运算符组合它们。

例如,以下查询列表:

# catch varnish errors
*Error

# catch backend errors
BerespStatus >= 500

与此查询相同::

(*Error) or (BerespStatus >= 500)

注释可以使用,但将被忽略,它们以 '#' 字符,当从文件中读取查询时,该字符可能更有用。

对于不能轻松拆分成多个查询的非常长的查询,可以将它们拆分成多行,在行尾前加一个反斜杠。

例如,此查询::

BerespStatus >= 500

与此查询相同::

BerespStatus \
>= \
500

反斜杠-换行符序列不会继续下一行的注释,也不允许出现在带引号的字符串中。

记录选择标准

记录选择标准确定该表达式适用于事务组中的哪种记录。语法:

{level}taglist:record-prefix[field]

标记列表是必需的,其他组件是可选的。

该级别将表达式限制为该级别的事务。如果未指定,则该表达式将应用于所有级别的事务。级别是正整数或零。如果Level后面跟一个‘+’字符,则表示大于或等于。如果Level后面跟一个‘-’,则表示小于或等于。

Taglist是一个逗号分隔的VSL记录标记列表,应根据该列表检查此表达式。每个列表元素可以是标记名或标签全局。GLOB允许‘ ' either in the beginning of the name or at the end, and will select all tags that match either the prefix or subscript. A single ' ‘将选择所有标签。

记录前缀将进一步将匹配限制到将该前缀作为其记录内容的第一部分后跟冒号的那些记录。然后,与之匹配的日志记录部分将被限制在前缀和冒号之后。这在与特定的HTTP头进行匹配时非常有用。记录前缀匹配不区分大小写。

如果存在该字段,则会将日志记录视为以空格分隔的字段列表,并且只对记录的第n部分进行匹配。字段从1开始计数。

如果在按条件选择的事务组中有任何记录,则仅使用记录选择标准的表达式将为真。

操作员

以下匹配运算符可用:

  • ==!=<<=>>=

    数值比较。在比较之前,记录内容将转换为整数或浮点数,具体取决于操作数的类型。

  • 方程式Ne

    字符串比较。‘eq’测试字符串相等,‘ne’测试不相等。

  • ~!~

    正则表达式匹配。“~”是正匹配,“!~”是不匹配。

操作数

操作数是选定记录将与之匹配的值。

操作数可以带引号或不带引号。引号可以是单引号也可以是双引号,对于带引号的操作数,可以使用反斜杠对引号进行转义。

未加引号的操作数只能由以下字符组成:

a-z A-Z 0-9 + - _ . *

以下类型的操作数可用:

  • 整型

    不含任何小数部分的数,对数值比较运算符有效。当操作数不包含任何句点(.)时,使用整型也不是指数(E)字符。但是,如果记录的计算结果为浮点数,则只使用其整数部分进行比较。

  • 浮标

    带小数部分的数,对数值比较运算符有效。当操作数包含句点(.)时,使用浮点类型。或指数(E)字符。

  • 细绳

    字符序列,对字符串相等运算符有效。

  • 正则表达式

    PCRE2正则表达式。对正则表达式运算符有效。

布尔函数

查询表达式可以使用布尔函数链接在一起。以下内容按优先顺序排列:

  • 不是<EXPR>

    反转<expr>的结果

  • <expr1>和<expr2>

    仅当expr1和expr2均为True时才为True

  • <expr1>或<expr2>

    如果expr1或expr2之一为真,则为真

可以使用括号对表达式进行分组。

查询表达式示例

  • 事务组包含一个等于“/foo”的请求URL::

    ReqURL eq "/foo"
    
  • 事务组包含请求Cookie标头::

    ReqHeader:cookie
    
  • 事务组不包含请求Cookie标头::

    not ReqHeader:cookie
    
  • 内部处理时间超过800毫秒的客户端请求。时间::

    Timestamp:Process[2] > 0.8
    
  • 交易组包含一个包含“iPod”的请求用户代理头,并且请求传递时间超过1秒::

    ReqHeader:user-agent ~ "iPod" and Timestamp:Resp[2] > 1.
    
  • 事务组包含大于或等于500的后端响应状态::

    BerespStatus >= 500
    
  • 事务处理组包含请求响应状态304,但其中请求不包含IF-MODIFIED-SES标头::

    RespStatus == 304 and not ReqHeader:if-modified-since
    
  • 在其ESI子请求上出现后端故障或传递时间较长的事务。(采用请求分组模式)。**

    BerespStatus >= 500 or {2+}Timestamp:Process[2] > 1.
    
  • 记录非事务性错误。(采用原始分组模式)。**

    vxid == 0 and Error
    

HISTORY

这份文件最初由马丁·布利克斯·格里德兰撰写,其他人对其进行了修改。