实时跟踪、可视化和警报资产
Elastic Stack Serverless
您对资产跟踪感兴趣吗?好消息!使用 地图 可以轻松地可视化和分析移动数据。您可以跟踪物联网设备的位置,并监控运输中的包裹或车辆。
在本教程中,您将查看来自俄勒冈州波特兰市的实时城市交通数据。您将观察城市公交车、有轨电车和火车,使用这些数据来可视化拥堵情况,并在车辆进入施工区域时通知调度团队。
您将学习如何
- 使用 Elastic Agent 将 TriMet REST API 摄取到 Elasticsearch 中。
- 创建包含图层的地图,这些图层可以可视化资产轨迹和最后已知位置。
- 使用符号和颜色来设置数据值的样式,并显示资产的行驶方向。
- 设置跟踪遏制警报以监控移动车辆。
- 在地图上显示这些警报。
完成本教程后,您将获得一张如下所示的地图

- 如果您还没有 Kibana,请注册 免费的 Elastic Cloud 试用版 并创建一个托管部署。创建时,请下载部署凭据。
- 在 TriMet Web 服务 的 https://developer.trimet.org/appid/registration/ 获取 API 密钥。
- Fleet 在您的集群上已启用,并且一个或多个 Elastic Agents 已注册。
为了体验可视化和警报波特兰公共交通车辆的乐趣,您必须首先将 自定义 API 集成添加到 Elastic Agent 策略,以将 TriMet 波特兰数据导入 Elasticsearch。
在 Kibana 中,使用导航菜单或 全局搜索字段 转到 开发者工具。
在 控制台 中,创建
tri_met_tracks
索引生命周期策略。此策略会将事件在热数据阶段保留 7 天。然后,数据将移动到温数据阶段。在温数据阶段 365 天后,数据将被删除。ILM 策略定义
PUT _ilm/policy/tri_met_tracks { "policy": { "phases": { "hot": { "min_age": "0ms", "actions": { "rollover": { "max_primary_shard_size": "50gb", "max_age": "7d" }, "set_priority": { "priority": 100 } } }, "warm": { "min_age": "0d", "actions": { "set_priority": { "priority": 50 } } }, "delete": { "min_age": "365d", "actions": { "delete": { "delete_searchable_snapshot": true } } } } } }
在 控制台 中,添加
tri_met_tracks_for_elastic_agent
提取管道。摄取策略定义
PUT _ingest/pipeline/tri_met_tracks_for_elastic_agent { "processors": [ { "set": { "field": "trimet.inCongestion", "value": "false", "if": "ctx?.trimet?.inCongestion == null" } }, { "convert": { "field": "trimet.bearing", "type": "float" } }, { "convert": { "field": "trimet.inCongestion", "type": "boolean" } }, { "script": { "source": """ double lat=Math.round(ctx['trimet']['latitude']*1e6)/1e6; double lon=Math.round(ctx['trimet']['longitude']*1e6)/1e6; ctx['trimet']['location'] = lat + "," + lon """, "description": "Generate the geometry rounding to six decimals" } }, { "script": { "source": """ctx['_id'] = ctx['trimet']['vehicleID'] + "_" + ctx['trimet']['time']""", "description": "Generate documentID" } }, { "remove": { "field": [ "message", "input", "agent", "ecs", "host", "event", "trimet.longitude", "trimet.latitude" ] } } ] }
在 控制台 中,创建组件和索引模板,该模板配置为使用数据流以及之前的 ILM 策略和摄取管道
索引组件模板
PUT _component_template/logs-httpjson.trimet@package { "template": { "settings": { "index": { "lifecycle": { "name": "tri_met_tracks" }, "codec": "best_compression", "default_pipeline": "tri_met_tracks_for_elastic_agent" } }, "mappings": { "_routing": { "required": false }, "numeric_detection": false, "dynamic_date_formats": [ "strict_date_optional_time", "yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z" ], "dynamic": true, "_source": { "excludes": [], "includes": [], "enabled": true }, "dynamic_templates": [], "date_detection": true, "properties": { "input": { "properties": { "type": { "ignore_above": 1024, "type": "keyword" } } }, "@timestamp": { "ignore_malformed": false, "type": "date" }, "ecs": { "properties": { "version": { "ignore_above": 1024, "type": "keyword" } } }, "data_stream": { "properties": { "namespace": { "type": "constant_keyword" }, "type": { "type": "constant_keyword" }, "dataset": { "type": "constant_keyword" } } }, "event": { "properties": { "created": { "type": "date" }, "module": { "type": "constant_keyword", "value": "httpjson" }, "dataset": { "type": "constant_keyword", "value": "httpjson.trimet" } } }, "message": { "type": "match_only_text" }, "tags": { "ignore_above": 1024, "type": "keyword" }, "trimet": { "type": "object", "properties": { "expires": { "type": "date" }, "signMessage": { "type": "text" }, "serviceDate": { "type": "date" }, "loadPercentage": { "type": "float" }, "nextStopSeq": { "type": "integer" }, "source": { "type": "keyword" }, "type": { "type": "keyword" }, "blockID": { "type": "integer" }, "signMessageLong": { "type": "text" }, "lastLocID": { "type": "keyword" }, "nextLocID": { "type": "keyword" }, "locationInScheduleDay": { "type": "integer" }, "newTrip": { "type": "boolean" }, "direction": { "type": "integer" }, "inCongestion": { "type": "boolean" }, "routeNumber": { "type": "integer" }, "bearing": { "type": "integer" }, "garage": { "type": "keyword" }, "tripID": { "type": "keyword" }, "delay": { "type": "integer" }, "extraBlockID": { "type": "keyword" }, "messageCode": { "type": "integer" }, "lastStopSeq": { "type": "integer" }, "location": { "type": "geo_point" }, "time": { "index": true, "ignore_malformed": false, "store": false, "type": "date", "doc_values": true }, "vehicleID": { "type": "keyword" }, "offRoute": { "type": "boolean" } } } } } } }
索引模板
PUT _index_template/logs-httpjson.trimet { "index_patterns": [ "logs-httpjson.trimet-*" ], "composed_of": [ "logs-httpjson.trimet@package", ".fleet_globals-1", ".fleet_agent_id_verification-1" ], "priority": 200, "data_stream": { "hidden": false, "allow_custom_routing": false } }
如果您还没有准备好代理策略
仍然在 控制台 中,为此数据源创建一个代理策略
POST kbn:/api/fleet/agent_policies?sys_monitoring=true { "name": "trimet", "description": "Policy to gather TriMet data", "namespace": "default", "monitoring_enabled": ["logs", "metrics"], "inactivity_timeout": 1209600, "is_protected": false }
注意请求结果的
item.id
值,稍后在注册集成时将使用它使用 UI 提供的任何方法(linux、Mac、Windows 等)将新的 Elastic Agent 注册到此新策略中
从 控制台 执行以下请求以安装新的自定义 API 集成。为 policy_id
和 tri_met_app_id
填写相应的值。
创建一个新的自定义 API 集成
POST kbn:/api/fleet/package_policies
{
"policy_id": "<policy_id>",
"package": {
"name": "httpjson",
"version": "1.18.0"
},
"name": "httpjson-trimet",
"description": "TriMet data upload",
"namespace": "default",
"inputs": {
"generic-httpjson": {
"enabled": true,
"streams": {
"httpjson.generic": {
"enabled": true,
"vars": {
"data_stream.dataset": "httpjson.trimet",
"request_url": "https://developer.trimet.org/ws/v2/vehicles?appID=<tri_met_app_id>",
"request_interval": "1m",
"request_method": "GET",
"response_split": "target: body.resultSet.vehicle",
"request_redirect_headers_ban_list": [],
"oauth_scopes": [],
"processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"trimet\"\n",
"tags": [
"trimet"
]
}
}
}
}
}
}
- 代理策略标识符
- TriMet 应用程序标识符
- 每分钟检索一次车辆位置
此请求将配置集成,以便每分钟向 TriMet REST API 发出请求,将 API 响应拆分为每个车辆一条消息,放入 httpjson.trimet
数据流中,并将车辆的数据编码到 trimet
字段中。其余数据管理将由第一步中定义的提取策略处理。
在 控制台 中,执行此请求以创建一个名为 TriMet Positions 的新 Kibana 数据视图
POST kbn:/api/data_views/data_view
{
"data_view": {
"title": "logs-httpjson.trimet-*",
"name": "TriMet Positions",
"timeFieldName": "trimet.time"
}
}
Kibana 显示数据视图中的字段。

您可能需要调整此数据视图,以根据您的个人喜好调整字段名称以及数字或日期格式。Maps 应用程序会在工具提示和其他 UI 元素中遵循这些设置。有关更多详细信息,请查看 格式化数据字段。
- 转到 Discover。
- 将数据视图设置为 TriMet Positions。
- 打开 时间过滤器,并将时间范围设置为过去 15 分钟。
- 展开一个文档并探索您稍后将在本教程中使用的一些字段:
trimet.bearing
、trimet.inCongestion
、trimet.location
和trimet.vehicleID
。

通过查看单个事件很难获得波特兰车辆的概览。让我们创建一个地图来显示每辆车的路线和当前位置,以及它们行驶的方向。
创建您的地图并将默认图层的主题设置为深色模式。
- 转到 地图。
- 单击 创建地图。
- 在 图层 列表中,单击 道路地图,然后单击 编辑图层设置。
- 打开 瓦片服务 下拉列表,然后选择 道路地图 - 深色。
- 单击 保留更改。
添加一个图层以显示过去 15 分钟的车辆路线。
单击 添加图层。
单击 轨迹。
选择 TriMet Positions 数据视图。
定义轨迹
- 将 实体 设置为
trimet.vehicleID
。 - 将 排序 设置为
trimet.time
。
- 将 实体 设置为
单击 添加并继续。
在图层设置中
- 将 名称 设置为 轨迹。
- 将 不透明度 设置为 80%。
滚动到 图层样式,并将 边框颜色 设置为粉红色。
单击 保留更改。
在 图层 列表中,单击 轨迹,然后单击 适应数据。
此时,您拥有一个地图,其中包含代表 TriMet 车辆在城市中移动的路线的线条。

添加一个图层,该图层使用数据中的属性来设置车辆的样式和方向。您将看到车辆的行驶方向以及交通状况。
单击 添加图层,然后选择 每个实体的热门点击。
选择 TriMet Positions 数据视图。
显示每个车辆的最新位置
- 将 实体 设置为
trimet.vehicleID
。 - 将 每个实体的文档 设置为 1。
- 将 排序字段 设置为
trimet.time
。 - 将 排序顺序 设置为 降序。
- 将 实体 设置为
单击 添加并继续。
将名称更改为 最新位置。
滚动到 图层样式。
单击 保留更改。
打开时间过滤器,并将每隔设置为 10 秒,然后单击开始。
您的地图应该会自动每 10 秒刷新一次,以显示最新的车辆位置和轨迹。

让我们使 TriMet 波特兰数据可操作,并在车辆进入施工区域时发出警报。
为施工区域添加一个图层,您将在地图上绘制该图层。 施工区域将用作您的地理围栏边界或阈值,作为触发警报的基础。
单击 添加图层。
单击创建索引。
将索引名称设置为
trimet_construction_zones
。单击创建索引。
在地图上绘制 2 或 3 个施工区域
- 在地图左侧的工具栏中,选择边界框图标
。
- 要绘制施工区域,请单击地图上的起点并拖动。
- 单击终点完成。
- 在地图左侧的工具栏中,选择边界框图标
完成绘制施工区域后,单击图例中图层名称下的退出。
在图层设置中,将名称设置为施工区域。
滚动到图层样式,并将填充颜色设置为黄色。
单击 保留更改。
保存地图。
- 为地图指定一个标题。
- 在添加到仪表板下,选择无。
- 单击保存并添加到库。
该地图现在代表了实时公共交通运行情况。 您将看到车辆的行驶方向,以及它们是否接近或已经进入施工区域。
您的地图现在已经完成,恭喜!

通过定义规则和连接器来创建新的警报。规则包括触发警报的条件,连接器定义触发警报后执行的操作。 在本例中,每个警报都会将一个新文档插入到 Elasticsearch 索引中。
对于此示例,您将规则设置为每分钟检查一次。 但是,在生产环境中运行时,可能需要将此值调整为更高的检查间隔,以避免性能问题。 有关更多信息,请参阅警报生产注意事项。
在 Kibana 控制台中创建一个新的索引和数据视图
为警报创建索引和数据视图
# Create the alerts index PUT trimet_alerts { "settings": { "number_of_replicas": 1, "number_of_shards": 1 }, "mappings": { "properties": { "vehicleId": {"type": "keyword"}, "documentId": {"type": "text"}, "vehicleTime": {"type": "date"}, "detectionTime": {"type": "date"}, "location": {"type": "geo_point"}, "boundaryId": {"type": "keyword"}, "message": {"type": "text"} } } } # Create the alerts index data view POST kbn:/api/data_views/data_view { "data_view": { "title": "trimet_alerts", "name": "TriMet Alerts", "timeFieldName": "detectionTime" } }
打开堆栈管理,然后单击规则。
单击创建规则。
将规则命名为TriMet 警报。
选择跟踪包含规则类型。
在实体块中
- 选择 TriMet 位置数据视图
- 选择
trimet.time
作为时间字段 - 选择
trimet.location
作为位置字段 - 选择
trimet.vehicleID
作为实体字段
在边界块中
- 选择 trimet_construction_zones 数据视图
- 选择
coordinates
作为位置字段 - 将显示名称和过滤器留空
选择规则为每分钟检查一次
将每隔检查设置为 1 分钟。
仅在状态更改时通知。
在操作下,选择 索引连接器类型。
添加一个名为TriMet 警报的新连接器
- 选择
trimet_alerts
索引 - 使用
detectionTime
字段为每个文档定义时间字段
- 选择
将操作频率保留为默认选项:状态更改时
将运行时间选择器保留为默认选项:满足跟踪包含
使用以下模板创建新的索引文档
{ "vehicleId": "{{context.entityId}}", "vehicleTime": "{{context.entityDateTime}}", "documentId": "{{context.entityDocumentId}}", "detectionTime": "{{context.detectionDateTime}}", "location": "{{context.entityLocation}}", "boundaryId": "{{context.containingBoundaryId}}" }
单击保存。
TriMet 警报连接器已添加到连接器页面。 有关常见连接器的更多信息,请参阅 Slack 和 电子邮件连接器。
配置并运行警报后,几分钟后,您的 trimet_alerts
索引应该开始获取数据。 您可以轻松地将此数据添加到运营地图中
打开您的运营地图
单击添加图层
单击文档
选择 TriMet 警报数据视图
将符号类型更改为图标,然后选择公交车图标
将颜色更改为粉色
使用
vehicleId
字段启用标签选项将
vehicleId
、boundaryId
、detectionTime
和vehicleTime
字段添加到工具提示配置,以允许在地图上查看警报详细信息。
恭喜! 您已完成本教程,并获得了跟踪资产的方法。 现在,您可以尝试使用自己的数据复制相同的分析。