使用 Ansibles uri 模块从非平凡 JSON 解析值
Parsing value from non-trivial JSON using Ansibles uri module
我有这个(在所示的示例中,我通过删除许多行来减少它)从 Spark 服务器检索到的非平凡 JSON:
{
"spark.worker.cleanup.enabled": true,
"spark.worker.ui.retainedDrivers": 50,
"spark.worker.cleanup.appDataTtl": 7200,
"fusion.spark.worker.webui.port": 8082,
"fusion.spark.worker.memory": "4g",
"fusion.spark.worker.port": 8769,
"spark.worker.timeout": 30
}
我尝试阅读 fusion.spark.worker.memory
但没能读懂。在我的调试语句中,我可以看到信息在那里:
msg: "Spark memory: {{spark_worker_cfg.json}}
显示:
ok: [process1] => {
"msg": "Spark memory: {u'spark.worker.ui.retainedDrivers': 50, u'spark.worker.cleanup.enabled': True, u'fusion.spark.worker.port': 8769, u'spark.worker.cleanup.appDataTtl': 7200, u'spark.worker.timeout': 30, u'fusion.spark.worker.memory': u'4g', u'fusion.spark.worker.webui.port': 8082}"
}
使用 var: spark_worker_cfg
的转储显示如下:
ok: [process1] => {
"spark_worker_cfg": {
"changed": false,
"connection": "close",
"content_length": "279",
"content_type": "application/json",
"cookies": {},
"cookies_string": "",
"failed": false,
"fusion_request_id": "Pj2zeWThLw",
"json": {
"fusion.spark.worker.memory": "4g",
"fusion.spark.worker.port": 8769,
"fusion.spark.worker.webui.port": 8082,
"spark.worker.cleanup.appDataTtl": 7200,
"spark.worker.cleanup.enabled": true,
"spark.worker.timeout": 30,
"spark.worker.ui.retainedDrivers": 50
},
"msg": "OK (279 bytes)",
"redirected": false,
"server": "Jetty(9.4.12.v20180830)",
"status": 200,
"url": "http://localhost:8765/api/v1/configurations?prefix=spark.worker"
}
}
我无法使用 {{spark_worker_cfg.json.fusion.spark.worker.memory}}
访问该值,我的问题似乎是由包含点的名称引起的:
The task includes an option with an undefined variable. The error was:
'dict object' has no attribute 'fusion'
我查看了两个 SO 帖子 ( and 2),它们看起来像我的问题的副本,但无法从中得出如何解决我当前问题的方法。
数据结构的 'json' 元素中的键包含文字点,而不是表示结构。这会导致问题,因为如果使用点分符号,Ansible 将不知道将它们视为文字。因此,使用方括号表示法来引用它们,而不是点:
- debug:
msg: "{{ spark_worker_cfg['json']['fusion.spark.worker.memory'] }}"
(乍一看,这看起来像是一个需要解码的 JSON 编码字符串的问题,本来可以处理的:"{{ spark_worker_cfg.json | from_json }}"
)
您可以使用 json_query 过滤器来获取结果。 https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html
msg="{{ spark_worker_cfg.json | json_query('fusion.spark.worker.memory') }}
编辑:
作为对您的评论的回应,我们返回空字符串这一事实使我相信查询不正确。在使用 json_query 过滤器时找到确切的查询可能会令人沮丧,所以我通常会事先使用 jsonpath 工具。我在下面的评论中链接了一个,但我个人使用 intelliJ 中的 jsonUtils 插件来找到我的路径(仍然需要调整,因为两者之间的路径处理方式略有不同)。
如果您的 json 看起来像这样:
{
value: "theValue"
}
然后
json_query('value')
会起作用。
您传递给 json_query 的路径对于您要执行的操作不正确。
如果您的顶级对象被命名为 fusion_spark_worker_memory(没有句点),那么您的查询应该有效。我相信这些点正在把东西扔掉。可能有一种方法可以避开查询中的那些...
编辑 2:clockworknet 获胜!他两次都打败了我。 :鞠躬:
我有这个(在所示的示例中,我通过删除许多行来减少它)从 Spark 服务器检索到的非平凡 JSON:
{
"spark.worker.cleanup.enabled": true,
"spark.worker.ui.retainedDrivers": 50,
"spark.worker.cleanup.appDataTtl": 7200,
"fusion.spark.worker.webui.port": 8082,
"fusion.spark.worker.memory": "4g",
"fusion.spark.worker.port": 8769,
"spark.worker.timeout": 30
}
我尝试阅读 fusion.spark.worker.memory
但没能读懂。在我的调试语句中,我可以看到信息在那里:
msg: "Spark memory: {{spark_worker_cfg.json}}
显示:
ok: [process1] => {
"msg": "Spark memory: {u'spark.worker.ui.retainedDrivers': 50, u'spark.worker.cleanup.enabled': True, u'fusion.spark.worker.port': 8769, u'spark.worker.cleanup.appDataTtl': 7200, u'spark.worker.timeout': 30, u'fusion.spark.worker.memory': u'4g', u'fusion.spark.worker.webui.port': 8082}"
}
使用 var: spark_worker_cfg
的转储显示如下:
ok: [process1] => {
"spark_worker_cfg": {
"changed": false,
"connection": "close",
"content_length": "279",
"content_type": "application/json",
"cookies": {},
"cookies_string": "",
"failed": false,
"fusion_request_id": "Pj2zeWThLw",
"json": {
"fusion.spark.worker.memory": "4g",
"fusion.spark.worker.port": 8769,
"fusion.spark.worker.webui.port": 8082,
"spark.worker.cleanup.appDataTtl": 7200,
"spark.worker.cleanup.enabled": true,
"spark.worker.timeout": 30,
"spark.worker.ui.retainedDrivers": 50
},
"msg": "OK (279 bytes)",
"redirected": false,
"server": "Jetty(9.4.12.v20180830)",
"status": 200,
"url": "http://localhost:8765/api/v1/configurations?prefix=spark.worker"
}
}
我无法使用 {{spark_worker_cfg.json.fusion.spark.worker.memory}}
访问该值,我的问题似乎是由包含点的名称引起的:
The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'fusion'
我查看了两个 SO 帖子 (
数据结构的 'json' 元素中的键包含文字点,而不是表示结构。这会导致问题,因为如果使用点分符号,Ansible 将不知道将它们视为文字。因此,使用方括号表示法来引用它们,而不是点:
- debug:
msg: "{{ spark_worker_cfg['json']['fusion.spark.worker.memory'] }}"
(乍一看,这看起来像是一个需要解码的 JSON 编码字符串的问题,本来可以处理的:"{{ spark_worker_cfg.json | from_json }}"
)
您可以使用 json_query 过滤器来获取结果。 https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html
msg="{{ spark_worker_cfg.json | json_query('fusion.spark.worker.memory') }}
编辑: 作为对您的评论的回应,我们返回空字符串这一事实使我相信查询不正确。在使用 json_query 过滤器时找到确切的查询可能会令人沮丧,所以我通常会事先使用 jsonpath 工具。我在下面的评论中链接了一个,但我个人使用 intelliJ 中的 jsonUtils 插件来找到我的路径(仍然需要调整,因为两者之间的路径处理方式略有不同)。
如果您的 json 看起来像这样:
{
value: "theValue"
}
然后
json_query('value')
会起作用。
您传递给 json_query 的路径对于您要执行的操作不正确。
如果您的顶级对象被命名为 fusion_spark_worker_memory(没有句点),那么您的查询应该有效。我相信这些点正在把东西扔掉。可能有一种方法可以避开查询中的那些...
编辑 2:clockworknet 获胜!他两次都打败了我。 :鞠躬: