EQL 搜索 API

编辑

返回 事件查询语言 (EQL) 查询的搜索结果。

EQL 假设数据流或索引中的每个文档都对应一个事件。

resp = client.eql.search(
    index="my-data-stream",
    query="\n    process where process.name == \"regsvr32.exe\"\n  ",
)
print(resp)
response = client.eql.search(
  index: 'my-data-stream',
  body: {
    query: "\n    process where process.name == \"regsvr32.exe\"\n  "
  }
)
puts response
const response = await client.eql.search({
  index: "my-data-stream",
  query: '\n    process where process.name == "regsvr32.exe"\n  ',
});
console.log(response);
GET /my-data-stream/_eql/search
{
  "query": """
    process where process.name == "regsvr32.exe"
  """
}

请求

编辑

GET /<target>/_eql/search

POST /<target>/_eql/search

先决条件

编辑
  • 如果启用了 Elasticsearch 安全功能,则您必须具有目标数据流、索引或别名的 read 索引权限
  • 请参阅 必填字段
  • [预览] 此功能为技术预览版,可能会在未来版本中更改或删除。Elastic 将努力修复任何问题,但技术预览版中的功能不受官方 GA 功能的支持 SLA 约束。 对于跨集群搜索,如果本地和远程集群的版本早于 7.17.7(含)或早于 8.5.1(含),则它们必须使用相同的 Elasticsearch 版本。有关安全性,请参阅 远程集群

限制

编辑

请参阅 EQL 限制

路径参数

编辑
<target>

(必需,字符串)用于限制请求的数据流、索引或别名的逗号分隔列表。支持通配符(*)。要搜索所有数据流和索引,请使用 *_all

[预览] 此功能为技术预览版,可能会在未来版本中更改或删除。Elastic 将努力修复任何问题,但技术预览版中的功能不受官方 GA 功能的支持 SLA 约束。 要搜索远程集群,请使用 <cluster>:<target> 语法。请参阅 跨集群运行 EQL 搜索

查询参数

编辑
allow_no_indices

(可选,布尔值)

此参数的行为与其他 多目标 API 中使用的 allow_no_indices 参数不同。

如果为 false,则如果任何通配符模式、别名或 _all 值仅以缺失或关闭的索引为目标,则请求会返回错误。即使请求以其他打开的索引为目标,此行为也适用。例如,如果一个索引以 foo 开头,但没有索引以 bar 开头,则以 foo*,bar* 为目标的请求会返回错误。

如果为 true,则仅当请求专门以缺失或关闭的索引为目标时才会返回错误。例如,如果一个索引以 foo 开头,但没有索引以 bar 开头,则以 foo*,bar* 为目标的请求不会返回错误。但是,仅以 bar* 为目标的请求仍然会返回错误。

默认为 true

ccs_minimize_roundtrips

(可选,布尔值)如果为 true,则在运行跨集群搜索 (CCS) 请求时,本地集群和远程集群之间的网络往返次数会最小化。

此选项对于以完全包含在一个远程集群中的数据为目标的请求有效;当数据分布在多个集群中时,将忽略此设置。

默认为 true

expand_wildcards

(可选,字符串)通配符模式可以匹配的索引类型。如果请求可以以数据流为目标,则此参数确定通配符表达式是否匹配隐藏的数据流。支持逗号分隔的值,例如 open,hidden。有效值为

all
匹配任何数据流或索引,包括隐藏的数据流或索引。
open
匹配打开的、非隐藏的索引。也匹配任何非隐藏的数据流。
closed
匹配关闭的、非隐藏的索引。也匹配任何非隐藏的数据流。数据流不能关闭。
hidden
匹配隐藏的数据流和隐藏的索引。必须与 openclosed 或两者结合使用。
none
不接受通配符模式。

默认为 open

filter_path
(可选,字符串)API 响应的过滤器逗号分隔列表。请参阅响应过滤
ignore_unavailable
(可选,布尔值)如果为 false,则如果请求以缺失或关闭的索引为目标,则返回错误。默认为 true
keep_alive

(可选,时间值)搜索及其结果在集群上存储的时间段。默认为 5d(五天)。

当此时间段到期时,即使搜索仍在进行中,也会删除搜索及其结果。

如果 keep_on_completion 参数为 false,则 Elasticsearch 仅存储 异步搜索,这些异步搜索在 wait_for_completion_timeout 参数设置的时间段内未完成,而不管此值如何。

您也可以使用 keep_alive 请求主体参数指定此值。如果同时指定了这两个参数,则仅使用查询参数。

keep_on_completion

(可选,布尔值)如果为 true,则搜索及其结果存储在集群上。

如果为 false,则仅当请求未在 wait_for_completion_timeout 参数设置的时间段内完成时,搜索及其结果才会存储在集群上。默认为 false

您也可以使用 keep_on_completion 请求主体参数指定此值。如果同时指定了这两个参数,则仅使用查询参数。

wait_for_completion_timeout

(可选,时间值)等待请求完成的超时时间。默认为无超时,这意味着请求会等待完整的搜索结果。

如果指定了此参数,并且请求在此期间完成,则会返回完整的搜索结果。

如果请求在此期间未完成,则搜索将变为异步搜索

您也可以使用 wait_for_completion_timeout 请求主体参数指定此值。如果同时指定了这两个参数,则仅使用查询参数。

请求主体

编辑
event_category_field

(必需*,字符串)包含事件分类的字段,例如 processfilenetwork

默认为 Elastic Common Schema (ECS) 中定义的 event.category。如果数据流或索引不包含 event.category 字段,则此值为必需。

事件类别字段必须在 keyword 系列中映射为字段类型。

fetch_size

(可选,整数)对于序列查询,每次搜索的最大事件数。默认为 1000

此值必须大于 2,但不能超过 index.max_result_window 设置的值,该设置默认为 10000

在内部,序列查询会提取并分页事件集以搜索匹配项。此参数控制这些集的大小。此参数不限制搜索的事件总数或返回的匹配事件数。

更大的 fetch_size 值通常会提高搜索速度,但会使用更多内存。

fields

(可选,字符串和对象的数组)字段模式数组。请求会在响应的 hits.fields 属性中返回与这些模式匹配的字段名称的值。

您可以将数组中的项指定为字符串或对象。请参阅fields 选项

fields 对象的属性
field
(必需,字符串)要返回的字段。支持通配符(*)。
format

(可选,字符串)日期和地理空间字段的格式。其他字段数据类型不支持此参数。

datedate_nanos 字段接受日期格式geo_pointgeo_shape 字段接受

geojson(默认)
GeoJSON
wkt
众所周知的文本
mvt(<spec>)

二进制 Mapbox 矢量瓦片。API 将瓦片作为 base64 编码的字符串返回。 <spec> 的格式为 <zoom>/<x>/<y>,带有两个可选后缀:@<extent> 和/或 :<buffer>。例如,2/0/12/0/1@4096:5

mvt 参数
<zoom>
(必需,整数)瓦片的缩放级别。接受 0-29
<x>
(必需,整数)瓦片的 X 坐标。
<y>
(必需,整数)瓦片的 Y 坐标。
<extent>
(可选,整数)瓦片一侧的像素大小。矢量瓦片是正方形,边长相等。默认为 4096
<buffer>
(可选,整数)瓦片外部裁剪缓冲区的像素大小。这允许渲染器避免几何图形超出瓦片范围而产生的轮廓伪影。默认为 5
filter
(可选,Query DSL 对象)用 Query DSL 编写的查询,用于筛选 EQL 查询在其上运行的事件。
keep_alive

(可选,时间值)搜索及其结果在集群上存储的时间段。默认为 5d(五天)。

当此时间段到期时,即使搜索仍在进行中,也会删除搜索及其结果。

如果 keep_on_completion 参数为 false,则 Elasticsearch 仅存储 异步搜索,这些异步搜索在 wait_for_completion_timeout 参数设置的时间段内未完成,而不管此值如何。

您也可以使用 keep_alive 查询参数指定此值。如果同时指定了这两个参数,则仅使用查询参数。

keep_on_completion

(可选,布尔值)如果为 true,则搜索及其结果存储在集群上。

如果为 false,则仅当请求未在 wait_for_completion_timeout 参数设置的时间段内完成时,搜索及其结果才会存储在集群上。默认为 false

您也可以使用 keep_on_completion 查询参数指定此值。如果同时指定了这两个参数,则仅使用查询参数。

query
(必需,字符串)您希望运行的 EQL 查询。
result_position

(可选,枚举)要返回的匹配事件或序列集。

result_position 的有效值
tail
(默认)返回最近的匹配项,类似于 Unix tail 命令
head
返回最早的匹配项,类似于 Unix head 命令

此参数可能会更改返回的命中集。但是,它不会更改响应中命中的排序顺序。

runtime_mappings

(可选,对象)在搜索请求中定义一个或多个运行时字段。这些字段优先于同名的映射字段。

runtime_mappings 对象的属性
<field-name>

(必需,对象)运行时字段的配置。键是字段名称。

<field-name> 的属性
type

(必需,字符串)字段类型,可以是以下任何一种

  • boolean
  • composite
  • date
  • double
  • geo_point
  • ip
  • keyword
  • long
  • lookup
script

(可选,字符串)在查询时执行的 Painless 脚本。该脚本可以访问文档的整个上下文,包括原始的 _source 和任何映射的字段及其值。

此脚本必须包含 emit 以返回计算的值。例如

"script": "emit(doc['@timestamp'].value.dayOfWeekEnum.toString())"
size

(可选,整数或浮点数)对于基本查询,要返回的最大匹配事件数。

对于序列查询,要返回的最大匹配序列数。

默认为 10。此值必须大于 0

您不能使用管道,例如 headtail 来超出此值。

tiebreaker_field
(可选,字符串)用于对具有相同时间戳的命中进行升序排序的字段。请参阅指定排序决胜器
timestamp_field

(必需*,字符串)包含事件时间戳的字段。

默认为 @timestamp,如Elastic Common Schema (ECS) 中定义的那样。如果数据流或索引不包含 @timestamp 字段,则此值是必需的。

API 响应中的事件按此字段的值排序,转换为自 Unix 纪元以来的毫秒数,并按升序排列。

时间戳字段应映射为datedate_nanos 字段类型不受支持。

wait_for_completion_timeout

(可选,时间值)等待请求完成的超时时间。默认为无超时,这意味着请求会等待完整的搜索结果。

如果指定了此参数,并且请求在此期间完成,则会返回完整的搜索结果。

如果请求在此期间未完成,则搜索将变为异步搜索

您也可以使用 wait_for_completion_timeout 查询参数指定此值。如果同时指定了这两个参数,则仅使用查询参数。

响应正文

编辑
id

(字符串)搜索的标识符。

仅当满足以下条件之一时,才会提供此搜索 ID

您可以将此 ID 与获取异步 EQL 搜索 API 一起使用,以获取搜索的当前状态和可用结果,或使用 获取异步 EQL 状态 API 仅获取当前状态。

is_partial
(布尔值)如果为 true,则响应不包含完整的搜索结果。
is_running

(布尔值)如果为 true,则搜索请求仍在执行中。

如果此参数和 is_partial 参数均为 true,则搜索是正在进行的异步搜索。如果 keep_alive 期间没有过去,则搜索完成时将提供完整的搜索结果。

如果 is_partialtrueis_runningfalse,则搜索由于失败而返回部分结果。只有一些分片返回了结果,或者协调搜索的节点失败了。

took

(整数)Elasticsearch 执行请求所花费的毫秒数。

此值是通过测量协调节点上收到请求的时间与协调节点准备好发送响应的时间之间经过的时间来计算的。

Took 时间包括

  • 协调节点和数据节点之间的通信时间
  • 请求在 search 线程池中等待执行的时间
  • 实际执行时间

Took 时间包括

  • 将请求发送到 Elasticsearch 所需的时间
  • 序列化 JSON 响应所需的时间
  • 将响应发送到客户端所需的时间
timed_out
(布尔值)如果为 true,则请求在完成之前超时。
hits

(对象)包含匹配的事件和序列。还包含相关的元数据。

hits 的属性
total

(对象)有关匹配事件或序列数量的元数据。

total 的属性
value

(整数)对于基本查询,匹配事件的总数。

对于序列查询,匹配序列的总数。

relation

(字符串)指示返回的事件或序列数是准确的还是下限。

返回的值为

eq
准确
gte
下限,包括返回的事件或序列
sequences

(对象数组)包含与查询匹配的事件序列。每个对象代表一个匹配的序列。仅对于包含序列的 EQL 查询,才会返回此参数。

sequences 对象的属性
join_keys
(值数组)用于约束序列中匹配项的共享字段值。这些是使用 EQL 查询语法中的 by 关键字定义的。
events

(对象数组)包含与查询匹配的事件。每个对象代表一个匹配的事件。

events 对象的属性
_index
(字符串)包含该事件的索引的名称。
_id
(字符串)事件的唯一标识符。此 ID 仅在索引内唯一。
_source
(对象)在索引时为事件传递的原始 JSON 正文。
events

(对象数组)包含与查询匹配的事件。每个对象代表一个匹配的事件。

events 对象的属性
_index
(字符串)包含该事件的索引的名称。
_id
(字符串)(字符串)事件的唯一标识符。此 ID 仅在索引内唯一。
_source
(对象)在索引时为事件传递的原始 JSON 正文。

示例

编辑

基本查询示例

编辑

以下 EQL 搜索请求搜索 event.categoryprocess 且满足以下条件的事件

  • process.namecmd.exe
  • process.pid 不为 2013
resp = client.eql.search(
    index="my-data-stream",
    query="\n    process where (process.name == \"cmd.exe\" and process.pid != 2013)\n  ",
)
print(resp)
response = client.eql.search(
  index: 'my-data-stream',
  body: {
    query: "\n    process where (process.name == \"cmd.exe\" and process.pid != 2013)\n  "
  }
)
puts response
const response = await client.eql.search({
  index: "my-data-stream",
  query:
    '\n    process where (process.name == "cmd.exe" and process.pid != 2013)\n  ',
});
console.log(response);
GET /my-data-stream/_eql/search
{
  "query": """
    process where (process.name == "cmd.exe" and process.pid != 2013)
  """
}

API 返回以下响应。hits.events 属性中的匹配事件按时间戳排序,转换为自 Unix 纪元以来的毫秒数,并按升序排列。

如果两个或多个事件共享相同的时间戳,则使用tiebreaker_field 字段按升序对事件进行排序。

{
  "is_partial": false,
  "is_running": false,
  "took": 6,
  "timed_out": false,
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "events": [
      {
        "_index": ".ds-my-data-stream-2099.12.07-000001",
        "_id": "babI3XMBI9IjHuIqU0S_",
        "_source": {
          "@timestamp": "2099-12-06T11:04:05.000Z",
          "event": {
            "category": "process",
            "id": "edwCRnyD",
            "sequence": 1
          },
          "process": {
            "pid": 2012,
            "name": "cmd.exe",
            "executable": "C:\\Windows\\System32\\cmd.exe"
          }
        }
      },
      {
        "_index": ".ds-my-data-stream-2099.12.07-000001",
        "_id": "b6bI3XMBI9IjHuIqU0S_",
        "_source": {
          "@timestamp": "2099-12-07T11:06:07.000Z",
          "event": {
            "category": "process",
            "id": "cMyt5SZ2",
            "sequence": 3
          },
          "process": {
            "pid": 2012,
            "name": "cmd.exe",
            "executable": "C:\\Windows\\System32\\cmd.exe"
          }
        }
      }
    ]
  }
}

序列查询示例

编辑

以下 EQL 搜索请求匹配事件序列,这些事件

  1. 以具有以下内容的事件开头

    • event.categoryfile
    • file.namecmd.exe
    • process.pid 不为 2013
  2. 后跟具有以下内容的事件

    • event.categoryprocess
    • process.executable 包含子字符串 regsvr32

这些事件还必须共享相同的 process.pid 值。

resp = client.eql.search(
    index="my-data-stream",
    query="\n    sequence by process.pid\n      [ file where file.name == \"cmd.exe\" and process.pid != 2013 ]\n      [ process where stringContains(process.executable, \"regsvr32\") ]\n  ",
)
print(resp)
response = client.eql.search(
  index: 'my-data-stream',
  body: {
    query: "\n    sequence by process.pid\n      [ file where file.name == \"cmd.exe\" and process.pid != 2013 ]\n      [ process where stringContains(process.executable, \"regsvr32\") ]\n  "
  }
)
puts response
const response = await client.eql.search({
  index: "my-data-stream",
  query:
    '\n    sequence by process.pid\n      [ file where file.name == "cmd.exe" and process.pid != 2013 ]\n      [ process where stringContains(process.executable, "regsvr32") ]\n  ',
});
console.log(response);
GET /my-data-stream/_eql/search
{
  "query": """
    sequence by process.pid
      [ file where file.name == "cmd.exe" and process.pid != 2013 ]
      [ process where stringContains(process.executable, "regsvr32") ]
  """
}

API 返回以下响应。匹配的序列包含在 hits.sequences 属性中。hits.sequences.join_keys 属性包含每个匹配事件的共享 process.pid 值。

{
  "is_partial": false,
  "is_running": false,
  "took": 6,
  "timed_out": false,
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "sequences": [
      {
        "join_keys": [
          2012
        ],
        "events": [
          {
            "_index": ".ds-my-data-stream-2099.12.07-000001",
            "_id": "AtOJ4UjUBAAx3XR5kcCM",
            "_source": {
              "@timestamp": "2099-12-06T11:04:07.000Z",
              "event": {
                "category": "file",
                "id": "dGCHwoeS",
                "sequence": 2
              },
              "file": {
                "accessed": "2099-12-07T11:07:08.000Z",
                "name": "cmd.exe",
                "path": "C:\\Windows\\System32\\cmd.exe",
                "type": "file",
                "size": 16384
              },
              "process": {
                "pid": 2012,
                "name": "cmd.exe",
                "executable": "C:\\Windows\\System32\\cmd.exe"
              }
            }
          },
          {
            "_index": ".ds-my-data-stream-2099.12.07-000001",
            "_id": "OQmfCaduce8zoHT93o4H",
            "_source": {
              "@timestamp": "2099-12-07T11:07:09.000Z",
              "event": {
                "category": "process",
                "id": "aR3NWVOs",
                "sequence": 4
              },
              "process": {
                "pid": 2012,
                "name": "regsvr32.exe",
                "command_line": "regsvr32.exe  /s /u /i:https://...RegSvr32.sct scrobj.dll",
                "executable": "C:\\Windows\\System32\\regsvr32.exe"
              }
            }
          }
        ]
      }
    ]
  }
}