Pattern 语句

适用于:✅Azure 数据资源管理器Azure MonitorMicrosoft Sentinel

模式是将字符串元组映射到表格表达式的构造。 每个模式都必须声明模式名称并选择性地定义模式映射 。 定义映射的模式在被调用时返回表格表达式。 必须用分号分隔任意两个语句。

空模式是已声明但未定义映射的模式。 调用时,它们会返回错误 SEM0036 以及 HTTP 头中缺少的模式定义的详细信息。 提供 Kusto 查询语言 (KQL) 体验的中间层应用程序可以在处理过程中使用返回的详细信息,以丰富 KQL 查询结果。 有关详细信息,请参阅使用中间层应用程序

语法

  • 声明空模式:

    declare pattern PatternName ;

  • 声明并定义空模式:

    declare pattern PatternName = (ArgName : ArgType [, ... ]) [[ PathName : PathArgType ]]

    {

          ( ArgValue1_1 [, ArgValue2_1, ... ] ) [ .[ PathValue_1 ] ] = { expression1 } ;

        [ ( ArgValue1_2 [, ArgValue2_2, ... ] ) [ .[ PathValue_2 ] ] = { expression2 } ; ... ]

    } ;

  • 调用模式:

    • PatternName ( ArgValue1 [, ArgValue2 ...] ).PathValue
    • PatternName ( ArgValue1 [, ArgValue2 ...] ).["PathValue"]

详细了解语法约定

参数

客户 类型​​ 必需 说明
PatternName string ✔️ 模式的名称。
ArgName string ✔️ 参数的名称。 模式可以有一个或多个参数。
ArgType string ✔️ ArgName 参数的标量数据类型。 可能的值:string
PathName string 路径参数的名称。 模式可以没有路径或只有一条路径。
PathArgType string PathArgType 参数的类型。 可能的值:string
ArgValue string ✔️ 要映射到 expression 的 ArgName 和可选的 PathName 元组值 。
PathValue string 要为 PathName 映射的值。
expression string ✔️ 引用返回表格数据的函数的表格或 lambda 表达式。 例如:Logs | where Timestamp > ago(1h)

示例

在下面的每个示例中,将声明、定义和调用模式。

定义简单模式

下面的示例定义一种模式,该模式将状态映射到返回其首都/主要城市的表达式。

declare pattern country = (name:string)[state:string]
{
  ("USA").["New York"] = { print Capital = "Albany" };
  ("USA").["Washington"] = { print Capital = "Olympia" };
  ("Canada").["Alberta"] = { print Capital = "Edmonton" };
};
country("Canada").Alberta

输出

Capital
埃德蒙顿

下面的示例定义了一种模式,该模式定义一些有作用域的应用程序数据。

declare pattern App = (applicationId:string)[scope:string]  
{
    ('a1').['Data']    = { range x from 1 to 5 step 1 | project App = "App #1", Data    = x };
    ('a1').['Metrics'] = { range x from 1 to 5 step 1 | project App = "App #1", Metrics = rand() };
    ('a2').['Data']    = { range x from 1 to 5 step 1 | project App = "App #2", Data    = 10 - x };
    ('a3').['Metrics'] = { range x from 1 to 5 step 1 | project App = "App #3", Metrics = rand() };
};
union App('a2').Data, App('a1').Metrics

输出

应用 数据 指标
应用 #2 9
应用 #2 8
应用 #2 7
应用 #2 6
应用 #2 5
应用 #1 0.53674122855537532
应用 #1 0.78304713305654439
应用 #1 0.20168860732346555
应用 #1 0.13249123867679469
应用 #1 0.19388305330563443

标准化

有适用于调用模式的语法变体。 例如,由于所有调用都属于相同的模式,下面的联合返回单个模式表达式。

declare pattern app = (applicationId:string)[eventType:string]
{
    ("ApplicationX").["StopEvents"] = { database("AppX").Events | where EventType == "StopEvent" };
    ("ApplicationX").["StartEvents"] = { database("AppX").Events | where EventType == "StartEvent" };
};
union
  app("ApplicationX").StartEvents,
  app('ApplicationX').StartEvents,
  app("ApplicationX").['StartEvents'],
  app("ApplicationX").["StartEvents"]

无通配符

对模式中的通配符没有特殊处理。 例如,下面的查询返回单个缺失的模式调用。

declare pattern app = (applicationId:string)[eventType:string]
{
    ("ApplicationX").["StopEvents"] = { database("AppX").Events | where EventType == "StopEvent" };
    ("ApplicationX").["StartEvents"] = { database("AppX").Events | where EventType == "StartEvent" };
};
union app("ApplicationX").["*"]
| count

返回语义错误

未声明一个或多个模式引用。 检测到的模式引用:["app('ApplicationX').['*']"]

使用中间层应用程序

中间层应用程序使用户能够使用 KQL,并希望通过使用来自其内部服务的已扩充数据来丰富查询结果,从而增强体验。

为此,应用程序向用户提供了一个模式语句,该语句返回其用户可以在其查询中使用的表格数据。 模式的参数是应用程序用于检索扩充数据的键。 当用户运行查询时,应用程序不会分析查询本身,而是计划利用空模式返回的错误来检索所需的键。 因此,它将带有空模式声明的查询放在前面,然后将其发送到群集进行处理,然后分析返回的 HTTP 标头以检索缺少的模式参数的值。 应用程序使用这些值来查找扩充数据,并生成一个新的声明来定义适当的扩充数据映射。 最后,应用程序将新定义添加到用户的查询前,重新发送该定义进行处理,并将其收到的结果返回给用户。

示例

在下面的示例中,中间层应用程序提供了使用经度/纬度位置丰富查询的功能。 该应用程序使用内部服务将 IP 地址映射到经度/纬度位置,并为此目的提供一个名为 map_ip_to_longlat 的模式。 假设应用程序从用户那里获取以下查询:

map_ip_to_longlat("10.10.10.10")

应用程序不分析此查询,因此不知道向模式传递了哪个 IP 地址 (10.10.10.10)。 因此,它在用户查询的前面加上一个空的 map_ip_to_longlat 模式声明,并发送它进行处理:

declare pattern map_ip_to_longlat;
map_ip_to_longlat("10.10.10.10")

应用程序在响应中接收到以下错误。

未声明一个或多个模式引用。 检测到的模式引用:["map_ip_to_longlat('10.10.10.10')"]

应用程序将检查错误,确定错误是否指示缺少模式引用,并检索缺少的 IP 地址 (10.10.10.10)。 它使用 IP 地址来查找其内部服务中的扩充数据,并生成新的模式,定义将 IP 地址映射到相应的经度和纬度数据。 新模式将添加到用户的查询之前并再次运行。 这次查询成功,因为扩充数据现在已在查询中声明,并将结果发送给用户。

declare pattern map_ip_to_longlat = (address:string)
{
  ("10.10.10.10") = { print Lat=37.405992, Long=-122.078515 }
};
map_ip_to_longlat("10.10.10.10")

输出

Lat Long
37.405992 -122.078515