使用 InfluxDB、Telegraf 和 Python 追踪 Fortnite 玩家表现

导航至

虽然我不太玩游戏,但自从我上中学的儿子向我介绍了在线游戏 Fortnite 以来,随着我的技能每周都在提高,我玩得非常开心。事实证明我并不孤单,我的老大学朋友,现在也有了自己的孩子,也和我们组队,在我们与来自世界各地的其他玩家战斗的同时,互相交流近况。难怪 Epic Games 制作的 Fortnite 拥有超过 3.5 亿玩家,并被认为是有史以来最受欢迎的在线视频游戏之一。

虽然有很多第三方 Fortnite 追踪器,但它们中的大多数都提供当前的统计数据,但时间序列可视化功能有限。这使得查看 Fortnite 比赛历史记录变得困难,甚至不可能。通过使用时间序列数据库 InfluxDB,我着手构建实时仪表板,以可视化和警报我们的进度,并深入了解我们与其他玩家相比的表现。

我的 Fortnite 追踪器概述

我专注于开发此 Fortnite 玩家追踪系统的三个主要组件

  1. 数据收集:第一部分涉及数据收集,它使用 Telegraf 和 Python 来检索数据并将其发送到 InfluxDB Cloud
  2. 仪表板:第二部分侧重于使用 Flux 查询和 InfluxDB 脚本编辑器中的 查询变量 开发仪表板,以可视化玩家表现。
  3. 警报:最后一个组件涉及警报,因为我希望在我的朋友和家人赢得比赛时收到通知。有一天晚上,当我祝贺儿子赢得单人比赛时,他给我的微笑使此功能变得物有所值!

虽然所有三个仪表板都提供了有用的信息来追踪玩家表现,但我最喜欢的仪表板是 Fortnite - 玩家对比仪表板,它显示了任意两个玩家之间的比赛分析,获胜者将被授予一个巨大的庆祝表情符号。看看您与您的朋友、家人或专业人士相比表现如何!

Fortnite player comparison dashboard<figcaption> 我们将在您的 InfluxDB Cloud 帐户中设置的仪表板之一</figcaption>

这是一个关于如何使用非官方 Fortnite API 和 InfluxDB Cloud 构建 Fortnite 排行榜的详细分步教程。

如何使用 Fortnite API 显示排行榜统计数据

首先,注册一个 免费的非官方 Fortnite API 帐户 以获取 Fortnite API 令牌。免费帐户已经足够好;除非您每天进行超过 10,000 次请求,否则您不需要付费帐户。1 万次请求的限制允许您每十秒轮询一次,这足以使用免费 API for Fortnite 而不会被拒绝访问。

然后,进入 Fortnite 本身,确保在帐户隐私部分中,在职业排行榜上显示选项设置为开启。您想要追踪其统计数据的每位朋友也需要这样做。

Fortnite account and privacy settings<figcaption> Fortnite 帐户和隐私设置</figcaption>

设置您的计算机

需要明确的是,如果您有 Mac 或 Linux 机器,本教程适用。(向所有 Windows 用户致歉!)

确保您的计算机上安装了 curl 终端命令,因为我们将使用它与 Fortnite API 进行交互。这是 如何在 macOS 上安装 curl,以及 如何在 Linux 上安装 curl

我们也将使用 Python 来运行 Python 脚本。您需要最新版本,版本 3。这是 如何在 Mac 上安装 Python 3,以及 如何在 Linux 上安装 Python

下载并安装 Telegraf,我们的开源数据收集代理,可在 macOS 和 Linux 上使用(以及 Windows,但这超出了本文的范围)。这是 如何安装 Telegraf。如果您使用的是 Mac 并且使用 Homebrew,只需在终端中运行以下命令

brew install telegraf

安装 Telegraf 后,请注意它所在的目录。您可能还想 将该路径位置放入您的 $PATH 中

接下来,获取 InfluxDB v2.0.0-beta CLI,可在 macOS 或 Linux 上使用,您将在终端中运行它以导入 InfluxDB Fortnite 模板。为此

  1. 转到 https://portal.influxdata.com/downloads/
  2. 单击 InfluxDB 2.0 按钮: InfluxDB-2.0 button
    选择 InfluxDB 2.0
  3. 为 Mac 或 Linux 选择“仅 CLI”。这使您可以访问可以在终端中运行的命令,以与 InfluxDB Cloud 交互,而无需下载您不会使用的 InfluxDB OSS 位。

Options for downloading InfluxDB<figcaption> 下载 InfluxDB 的选项</figcaption>

如何获取 InfluxDB Cloud

注册一个 免费的 InfluxDB Cloud 帐户这将为您提供一个时间序列数据库,您无需设置或维护。

完成后,从 InfluxDB Cloud UI 的“数据 / 令牌”部分创建并复制您的 InfluxDB 身份验证令牌。要查看实际的令牌值,请单击 UI 中的令牌名称。

Get the token value<figcaption> 单击令牌名称以获取令牌值</figcaption>

如何使用 curl 从 Fortnite 获取数据

首先,您需要获取 Fortnite 玩家 ID。为此,打开一个终端窗口(这是在 MacLinux 上执行此操作的方法)并在 Fortnite API 上运行以下 curl 命令

curl --request GET 'https://fortniteapi.io/lookup?username=<USERNAME>' \
       --header 'Authorization: <API_KEY>'

例如,如果用户名是 JohnDoe,并且您的 Fortnite API 密钥是 08fd8613a,您将输入

curl --request GET 'https://fortniteapi.io/lookup?username=JohnDoe' \
       --header 'Authorization: 08fd8613a'

如果用户名存在,则输出显示

{"result":true,"account_id":"4735ce913"}

如果用户名不存在,则输出显示

{"result":false,"error":"此帐户不存在"}

接下来,我们需要检查帐户是否返回指标

curl --location --request GET 'https://fortniteapi.io/stats?account=<PLAYER_ID>&season=<SEASON>' --header 'Authorization: <API-KEY>'

使用之前的示例和当前赛季 13,您将输入

curl --location --request GET 'https://fortniteapi.io/stats?account=JohnDoe'&season=13' --header 'Authorization: 08fd8613a''

如果帐户返回指标,您将看到类似以下内容

..."account":{"level":241,"progress_pct":89},"global_stats":{"squad":{"placetop1":75…

如果帐户未返回指标,您将看到

..."account":{"level":null,"progress_pct":null},"global_stats":null...

如前所述,如果帐户未返回指标,则表明玩家已将在职业排行榜上显示设置为关闭,在其个人资料的帐户和隐私部分中。

为了访问性能指标,Fortnite API 希望以 CSV 文件的形式输入您感兴趣的各种玩家 ID。

社区模板 下载 players.csv,并将其以 players.csv(全部小写)保存在您的 /etc/telegraf 目录中。然后使用文本编辑器(例如 Visual Studio Codevim 或 Mac 上的 TextEdit)打开 players.csv 的本地副本。

您会看到 players.csv 中播种了几个专业的 Fortnite 玩家和第二个字段 pro。我们有一个名为“pro”字段的原因是专业和业余玩家的指标差异很大。作为一名 Fortnite 玩家,我喜欢在 YouTube 和 Twitch 上观看我最喜欢的职业玩家,我也有我想要追踪的一组业余朋友/家人。但我不想将它们组合在一起,因为它们的指标差异太大,无法在单个图表上清晰地可视化。

因此,需要明确的是:帐户是否被认为是“专业”帐户由您手动确定;Fortnite API 不提供此信息。

在随后的行中,输入玩家 ID(您从上面的 curl 命令中获得),他们是否是专业玩家以及他们的用户名。每行应如下所示

4735ce913,yes,Ninja

将所有这些放在一起,您应该得到一个类似于以下的 CSV 文件

acct_id,pro,player_name
4735ce9132924caf8a5b17789b40f79c,yes,Ninja
827abb1cd9fb4618991425c2d3ba9b76,yes,bugha
8a3a179679194354b1eae7e3a4620ded,yes,LazarLazar
d44eaa65d78c444abccc7129a0a06a79,yes,Cloak

将此 CSV 文件以 players.csv(全部小写)保存在您的 /etc/telegraf 目录中。

上面的 CSV 文件包括一些著名的专业 Fortnite 玩家 NinjaBughaLazarLazarCloak

如何加载 InfluxDB Fortnite 模板

现在我们有了 CSV 文件,使用 influxdb CLI,导入 此 InfluxDB Fortnite 模板 中的所有 Fortnite 资源。这包括 Telegraf 配置InfluxDB 仪表板变量警报 和 Python 脚本。为此,请从您的终端运行以下命令

influx apply -u https://raw.githubusercontent.com/influxdata/community-templates/master/fortnite/fn-template.yml --env-ref=fn_bucket=fortnite

此命令将 Fortnite 玩家排行榜模板从 GitHub 拉取到您的 InfluxDB Cloud 实例中。它还会创建一个名为 fortnite 的存储桶(如果需要)。如果您想使用不同的存储桶,也可以更改它。请记住,如果使用另一个存储桶,则需要在名为 wins 的 InfluxDB 任务以及名为 playerplayer2 和 season 的 InfluxDB 查询变量中更新存储桶名称。

您需要做的另一个更改:Fortnite - 所有玩家 仪表板显示到 Fortnite - 个人统计数据 仪表板的 URL 钻取。此 URL 必须在朋友和家人以及专业人士单元格中更改

<INFLUX_HOST>/orgs/<INFLUX_ORG_ID>/dashboards/<FORTNITE_INDIVIDUAL_STATS_DASHBOARD_ID>

… 其中

  • <INFLUX_HOST> 是您的 InfluxDB Cloud URL
  • <INFLUX_ORG_ID> 是您的 InfluxDB Cloud 组织 ID(不是您的电子邮件;一个十六进制数字)
  • <FORTNITE_INDIVIDUAL_STATS_DASHBOARD_ID> 是 Fortnite 个人统计数据仪表板的 ID,它显示在其 URL 中的“dashboards”之后,如下所示

ID of the Fortnite individual stats

要获取完整链接,请打开 Fortnite - 个人统计数据 仪表板,并将 URL 复制到但不包括“?”。完成此操作后,您将在 InfluxDB 中看到一些与 Fortnite 相关的仪表板,但没有任何数据。要将数据放入这些仪表板中,请继续阅读。

如何使用 Python 从 Fortnite 获取数据

InfluxDB Fortnite 模板依赖于下面的 Python 脚本,该脚本将您之前复制和编辑的 CSV 文件作为输入,并获取每个用户的统计数据。要创建此脚本,请将 此 Python 脚本 的文本复制到文本编辑器中,然后将文件另存为 get_fn_stats.py(全部小写)在您的 /etc/telegraf 目录中。

此 Python 脚本的作用是循环遍历每个 ID 并使用 Fortnite 的 API 检索每个玩家的性能指标。我不会在此处粘贴整个 Python 脚本,因为它大约有 100 行长。最有趣的部分如下;通读注释以了解每一行的作用。

# Open the csv file /etc/telegraf/players.csv
with open('/etc/telegraf/players.csv', newline='') as csvfile:
    reader = csv.DictReader(csvfile)

    # For each row in our csv file...
    for row in reader:
        # Get the account ID field
        acct_id = row['acct_id']

        # Get the pro field
        pro = row['pro']
        
        # Set up our HTTP request
        response = requests.get(url,
                        	     headers = {'Authorization': FORTNITE_API_TOKEN},
                                params={'account': acct_id,
                                        'season': season
                                       }
                               )
        # Make our HTTP request, and store the response in data
        data = response.json()
        # Access the Python dictionary (list of name/value pairs)
        data_api_dict = parse_data(data)

        # Find the name/value entry for the current account ID
        data_api_dict['acct_id'] = acct_id
        data_api_dict['pro'] = pro

        # Append the stats for the current account ID to our list of stats
        data_api_list.append(data_api_dict.copy())

# Once we call our stats, write it in JSON to the api_output variable.
api_output = json.dumps(data_api_list)

(对于那些不熟悉 Python 的人:请务必保持缩进与上面完全一致。与其他语言不同,Python 将 缩进量视为指定不同代码块的方式。具有八个空格缩进的代码行都在我们的 for 循环中运行。)

如何在 Telegraf 中运行 Python 脚本

使用 Telegraf exec 输入插件,您可以安排上述 Python 脚本(您已将其保存在 /etc/telegraf/get_fn_stats.py)每小时运行一次。使用此插件,您可以通过将以下内容放入您的 Telegraf 配置文件 中来标记帐户名称、ID、专业状态和赛季作为 InfluxDB 的标签以进行更快的查询,您可以使用文本编辑器修改该文件

[[inputs.exec]]
          commands = [ "/etc/telegraf/get_fn_stats.py" ]
          data_format = "json"
          interval = "1h"
          tag_keys = [ "name", "acct_id", "pro", "season" ]

以下是上面每一行的含义

  • [[inputs.exec]] 告诉 Telegraf 加载 exec 插件
  • commands = [ "/etc/telegraf/get_fn_stats.py" ] 告诉 exec 插件运行我们刚刚创建的 Python 文件
  • data_format = "json" 告诉 exec 插件以 JSON 格式 输出
  • interval = "1h" 告诉 exec 插件每小时运行一次。这等效于“60m”。您也可以使用其他值,例如 10m 表示 10 分钟,2h 表示两小时,依此类推。
  • tag_keys = [ "name", "acct_id", "pro", "season" ] 告诉 exec 插件将玩家姓名、帐户 ID、专业状态(是或否)和赛季作为标签添加到发送到 InfluxDB 的 行协议 的每一行。

将您的 Telegraf 配置文件另存为 /etc/telegraf/telegraf.conf

如何将数据发送到 InfluxDB Cloud

同样在您的 Telegraf 配置文件中,您需要指定数据发送的位置:哪个 InfluxDB Cloud 实例、哪个帐户以及哪个存储桶。为此,请将以下内容添加到您的 Telegraf 配置文件中

[[outputs.influxdb_v2]]
  urls = ["$INFLUX_HOST"]
  token = "$INFLUX_TOKEN"
  organization = "$INFLUX_ORG"
  bucket = "$INFLUX_BUCKET"
  namepass = ["exec_fortnite"]
  timeout = "20s"

以下是上面每一行的作用

  • [[outputs.influxdb_v2]] 告诉 Telegraf 写入 InfluxDB 2.0(如果您要写入 InfluxDB 1.x,请使用 influxdb 输出插件,末尾没有 _v2)。
  • urls = ["$INFLUX_HOST"] 是您要发送到的 InfluxDB 数据库的 URL
  • token = "$INFLUX_TOKEN" 是您的 InfluxDB 访问令牌
  • organization = "$INFLUX_ORG" 是您的 InfluxDB 组织
  • bucket = "$INFLUX_BUCKET" 是您要写入的 InfluxDB 存储桶
  • namepass = ["exec_fortnite"] 如果您在 Telegraf 配置文件中有多个 InfluxDB 输出插件,这将非常有用。它指示 Telegraf 仅发送名为 exec_fortnite 的指标。如果您的 Telegraf 配置中只有一个 InfluxDB 输出插件,您可以安全地删除此行。
  • timeout = "20s" 告诉 Telegraf 在写入数据时超时之前等待 20 秒。

$INFLUX_HOST$INFLUX_TOKEN$INFLUX_ORG$INFLUX_BUCKET 前面的美元符号指示 Telegraf 查找具有每个名称的环境变量。让我们现在设置这些环境变量。

如何为 InfluxDB 设置环境变量

Telegraf 配置需要设置以下环境变量才能用于 InfluxDB Cloud 2

  • INFLUX_HOST - 您的 InfluxDB 2 实例的 URL
  • INFLUX_TOKEN - 具有读取 Telegraf 配置和将数据写入 <FORTNITE> bucket 权限的 token
  • INFLUX_ORG - 您的 组织 名称,可在 InfluxDB 个人资料页面上找到。
  • INFLUX_BUCKET - 要写入的 bucket 名称
  • FORTNITE_API_TOKEN - Fortnite API token

有关使用环境变量的信息,请参阅 Telegraf 配置文档。(如果您不熟悉如何设置环境变量,请参阅 如何在 Mac 上设置环境变量如何在 Linux 上设置环境变量。)

如何运行 Telegraf

在您的终端中,输入

/path/to/telegraf --config /etc/telegraf/telegraf.conf

(当然,将 “/path/to” 替换为 Telegraf 的实际路径!)

您将看到类似于以下的输出

2020-08-05T01:34:54Z I! Starting Telegraf 1.15.2
2020-08-05T01:34:54Z I! Loaded inputs: exec
2020-08-05T01:34:54Z I! Loaded outputs: influxdb_v2

如果是这样,您的 Telegraf 代理正在运行,并且应该正在向 InfluxDB 发送数据。要停止 Telegraf,请在键盘上按 ctrl-c。

如何将 Telegraf 作为服务运行

如果您希望 Telegraf 作为服务运行,即使您关闭终端窗口,您也应该将其作为服务运行。为此,请将以下变量添加到 /etc/default/telegraf

INFLUX_TOKEN=your_influxdb_token
[email protected]
INFLUX_BUCKET=fortnite
FORTNITE_API_TOKEN=your_fortnite_api_token

然后运行以下命令集之一,具体取决于您使用的是 Mac 还是 Linux

要在 Mac 上将 Telegraf 作为服务运行,此命令将使 launchd 在下次登录时启动 telegraf

ln -sfv /usr/local/opt/telegraf/*.plist ~/Library/LaunchAgents

要立即加载 Telegraf

launchctl load ~/Library/LaunchAgents/homebrew.mxcl.telegraf.plist

要在 Mac 上检查您的 Telegraf 服务状态

launchctl list | grep telegraf

如果 Telegraf 正在运行,您将在输出中看到它。如果它没有运行,您将看不到任何内容。更多信息请参阅 launchctl 手册页

要在 Linux 上将 Telegraf 作为服务运行,请使用 systemctl 命令,该命令随支持 systemd 的 Linux 发行版一起提供,包括 Ubuntu、Debian、Red Hat 和 Centos

sudo systemctl restart telegraf # (Re)start Telegraf as a service 
sudo systemctl enable telegraf  # Run Telegraf as a service at boot

要在 Linux 上检查您的 Telegraf 服务状态

sudo systemctl status telegraf

Telegraf 安装页面 提供了更多详细信息。

如何使用 InfluxDB 仪表盘

InfluxDB 模板的妙处在于它们会自动为您创建仪表盘(和其他资产),如果您不花费数小时甚至数天的时间,这将为您节省时间。

例如,这是自定义指标 Flux 脚本,用于确定一对一统计数据对决的获胜者

InfluxDB 查询编辑器中的 Flux 代码<figcaption> InfluxDB 查询编辑器中的 Flux 代码</figcaption>

InfluxDB 查询变量 v.player 在上面的示例中用于仪表盘下拉菜单,并在跨仪表盘和单元格的 Flux 脚本中引用。

如果一切运行良好,您应该看到如下所示的仪表盘

InfluxDB 中的 Fortnite 仪表盘<figcaption> InfluxDB 中的 Fortnite 仪表盘</figcaption>

所有 Fortnite 仪表盘的屏幕截图都在 Fortnite 社区模板 的 readme 中。

如何安全地将 InfluxDB 与 Slack 集成

Fornite 的 InfluxDB 模板 中,我创建了一个自定义 InfluxDB 任务,其中包含 HTTP Slack 端点 和内置检查。这样做的好处是,与使用 InfluxDB 警报 相比,这种方法为您提供了更多的控制权。缺点是 InfluxDB 警报需要的编码知识较少。

要使用此 InfluxDB 任务,您需要将 Slack webhook 保存为 InfluxDB secret。InfluxDB secret 是一些敏感信息,例如登录凭据、帐户信息或(在本例中)Slack webhook 的 secret URL。

您应该使用以下 InfluxDB CLI 命令存储您的 Slack webhook

influx secret update -k SLACK_WEBHOOK

运行此命令后,系统将提示您输入一个值;输入

https://hooks.slack.com/services/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

这是我们的 InfluxDB 社区 Slack 沙箱,任何人都可以使用。要访问它,请访问 https://influxcommunity.slack.com,如果需要,请注册 Slack,然后转到 #notifications-testing 频道以查看您的警报。当您的警报触发时,您应该在 Slack UI 中看到如下所示的内容

UI alert

当然,您的警报将与其他所有人的沙箱警报混合在一起。但对于简单的测试,这应该可以正常工作。请做一个好的社区成员,并在验证它工作后关闭此警报。

验证您的 Slack 通知工作正常后,您将需要 为您自己的 Slack 实例设置您自己的传入 webhook。因为那是您自己的 secret webhook URL,所以您肯定希望将其存储在 InfluxDB secret 中。

此时,您的 Fortnite 仪表盘和警报应该已填充并正确运行。但是,让我们更深入地了解一下它是如何工作的。

如何使用 InfluxDB 任务发送 Slack 警报

让我们检查一下用于警报的 InfluxDB 任务。当您在上面的步骤中使用 influx apply CLI 命令加载 Fortnite 的 InfluxDB 模板时,会自动创建此任务。您可以在 模板 yaml 文件 中看到此代码;只需搜索 “slack_webhook”。

因此,您无需执行任何操作来创建此任务,但查看下面的 Flux 代码是有启发意义的。

// Retrieve the secret Slack webhook URL
webhook = secrets.get(key: "SLACK_WEBHOOK")

// Define the Slack messaging function
sendSlackMessage = (text) =>
	(slack.message(
		url: webhook,
		token: "",
		channel: "",
		text: text,
		color: "good",
	))

// Retrieve wins from previous period from our fortnite bucket
from(bucket: "fortnite")
	// Look at data starting from 30 to 120 minute ago
	|> range(start: -2h, stop: -30m)
	// Look only for measurements from the Telegraf exec plugin
	// that are related to fortnite.
	|> filter(fn: (r) =>
		(r["_measurement"] == "exec_fortnite"))
	// Look for the fields squad_placetop1, solo_placetop1 & duo_placetop1
	|> filter(fn: (r) =>
		(r["_field"] == "squad_placetop1" or r["_field"] == "solo_placetop1" or r["_field"] == "duo_placetop1"))
	// Ensure that "pro" is properly defined one way or the other
	|> filter(fn: (r) =>
		(r["pro"] == "no" or r["pro"] == "yes"))
	// Group all rows by player name and _field
	|> group(columns: ["name", "_field"])
	// We don't need the start time, stop time, or "is a pro" columns
	|> drop(columns: ["_start", "_stop", "pro"])
	|> difference()
	|> group(columns: ["_time", "name"])
	|> filter(fn: (r) =>
		(r["_value"] == 1))
	// Create a new column with text of Slack message
	|> map(fn: (r) =>
		({r with newColumn: if r["_value"] == 1 then 
                            sendSlackMessage(text: 
                                "Congratulations to *${string(v: r.name)}* for winning a Fortnite *${strings.trimSuffix(v: r._field, suffix: "_placetop1")}* match! :boom: :boom: :boom:") else 
                            100}))

当玩家赢得比赛时,我上面向您展示的 Slack 消息会自动发送。

可以自定义警报条件,以便只有朋友和家人触发警报

|> filter(fn: (r) => (r["pro"] == "no"))

或仅限特定玩家

|> filter(fn: (r) => (r["name"] == "Ninja"))

当您查看 模板 yaml 文件 时,您会看到我已将此任务设置为每小时运行一次

every: 1h0m0s

创建 InfluxDB 模板

自从 第 2 章 - 第 3 赛季 于 6 月开始以来,我一直在跟踪和警报 Fortnite,并且很高兴看到我和我的儿子在本赛季中的进步。当我的 Fortnite 游戏朋友查看它时,他们问的第一件事是如何获得访问权限,因此我决定创建一个模板,其中包含您自己的 Fortnite 跟踪系统所需的一切。这包括仪表盘、查询变量、警报和 Telegraf 配置。由于所有资产都标记为 fortnite,因此将其导出为模板非常简单

influx export all --filter=labelName=fortnite -f fn-template.yml

您可以使用相同的方法导出您自己的 InfluxDB 模板,并 轻松分享您的监控专业知识

将所有内容整合在一起

这是一个视频,介绍了如何按照上面的许多步骤操作,以便您可以构建自己的 Fortnite 玩家跟踪仪表盘

结论

Flux 和 InfluxDB UI 使我能够快速迭代开发可视化和警报解决方案,以跟踪 Fortnite 玩家随时间推移的表现。如果您也想要这样做,请注册一个免费的 InfluxDB Cloud 帐户 并安装 Fortnite 社区模板,以便您可以立即开始跟踪和警报!

如果您有任何问题,请在我们的 InfluxDB 社区 Slack社区网站 上提问。