-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add subcommands plugins {list,status}
, to inquire plugins
#91
Conversation
Problem@bhks: Even with the most recent Grafana 10.1.2 release,
Thoughts
Q&AYou can install the package including this feature directly from the corresponding branch using this pip install --upgrade 'git+https://github.com/panodata/grafana-wtf@list-plugins' |
Thanks for pinging me into this thread. The panel plugin does not have any server running which can give us health or metrics from the backend. Also not all of the plugin servers implement this. The After plugin sdk kind of enforces for plugin developers to implement the protobuff model from version-1, so I don't know if all of the marketplace plugins of type datasource or App follows those. |
I can try this out when I get a chance and see what works and what not. |
grafana_wtf/core.py
Outdated
plugins = self.grafana.plugin.get_installed_plugins() | ||
for plugin in plugins: | ||
plugin = munchify(plugin) | ||
item = Munch( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can filter out the panel type as they don't have server to respond from.
Not all servers/plugins have implemented the metric endpoint, this was I believe introduced in the new SDK which helps build an external plugin. Also all core plugins does not have a server so they are built within grafana golang code , they don't have health or metric endpoint. So we need to filter them out as well. |
Thanks for your response. According to {
"name": "Alert list",
"type": "panel",
"id": "alertlist",
"enabled": true,
"pinned": false,
"info": {
"author": {
"name": "Grafana Labs",
"url": "https://grafana.com"
},
"description": "Shows list of alerts and their current status",
"links": null,
"logos": {
"small": "public/app/plugins/panel/alertlist/img/icn-singlestat-panel.svg",
"large": "public/app/plugins/panel/alertlist/img/icn-singlestat-panel.svg"
},
"build": {},
"screenshots": null,
"version": "",
"updated": ""
},
"dependencies": {
"grafanaDependency": "",
"grafanaVersion": "*",
"plugins": []
},
"latestVersion": "",
"hasUpdate": false,
"defaultNavUrl": "/grafana",
"category": "",
"state": "",
"signature": "internal",
"signatureType": "",
"signatureOrg": ""
}
Would skipping all plugins having |
Exactly that and the following one as well
|
Maybe just including the items with |
I've amended the patch to only use |
But internal/core plugins will not be able to respond like Cloudwatch, prometheus, rds they are datasource type. Also the App Plugin do respond to these endpoints like
Similarly for metrics
|
Thanks. I've added |
Do you mind updating that if with following :
|
5bd2674
to
435595b
Compare
tests/test_commands.py
Outdated
def test_plugins_status(grafana_version, docker_grafana, capsys, caplog): | ||
""" | ||
Verify the plugin status (metrics endpoint). | ||
|
||
TODO: Verify a plugin which properly responds to a health check response. | ||
""" | ||
if version.parse(grafana_version) < version.parse("8"): | ||
raise pytest.skip(f"Plugin status inquiry only works on Grafana 8 and newer") | ||
|
||
# Before conducting a plugin status test, install a non-internal one. | ||
grafana = grafana_client.GrafanaApi.from_url(url=docker_grafana, timeout=15) | ||
grafana.plugin.install_plugin("yesoreyeram-infinity-datasource") | ||
|
||
# Which subcommand to test? | ||
set_command("plugins status", "--format=yaml") | ||
|
||
# Run command and capture YAML output. | ||
with caplog.at_level(logging.DEBUG): | ||
grafana_wtf.commands.run() | ||
captured = capsys.readouterr() | ||
data = yaml.safe_load(captured.out) | ||
|
||
# Grafana 6 has 28 plugins preinstalled. | ||
assert len(data) >= 28 | ||
|
||
# Proof the output is correct. | ||
infinity_datasource = next(item for item in data if item["id"] == "yesoreyeram-infinity-datasource") | ||
assert "go_gc_duration_seconds" in infinity_datasource["metrics"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bhks: This is a first real integration test, using your contribution to the grafana-client library.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work Andreas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just building upon your work here ;], thanks again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CI currently fails here, because a few more adjustments will be submitted to grafana-client to make it work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also:
TODO: Verify a plugin which properly responds to a health check response.
Haven't been able to discover one, yet. If that plugin sample you just shared with me, will respond to such a response, I will be happy about it.
Can you convince me why this is better? To me, it sounds more inadequate, because we are mostly talking about "datasource" plugins here? Are there any other types of plugins which yield sensible responses on their metrics or health endpoints? If so, can you provide a sample (plugin id) of that kind, so I can use it on behalf of a corresponding software test case? Thanks! |
tests/test_commands.py
Outdated
def test_plugins_status(grafana_version, docker_grafana, capsys, caplog): | ||
""" | ||
Verify the plugin status (metrics endpoint). | ||
|
||
TODO: Verify a plugin which properly responds to a health check response. | ||
""" | ||
if version.parse(grafana_version) < version.parse("8"): | ||
raise pytest.skip(f"Plugin status inquiry only works on Grafana 8 and newer") | ||
|
||
# Before conducting a plugin status test, install a non-internal one. | ||
grafana = grafana_client.GrafanaApi.from_url(url=docker_grafana, timeout=15) | ||
grafana.plugin.install_plugin("yesoreyeram-infinity-datasource") | ||
|
||
# Which subcommand to test? | ||
set_command("plugins status", "--format=yaml") | ||
|
||
# Run command and capture YAML output. | ||
with caplog.at_level(logging.DEBUG): | ||
grafana_wtf.commands.run() | ||
captured = capsys.readouterr() | ||
data = yaml.safe_load(captured.out) | ||
|
||
# Grafana 6 has 28 plugins preinstalled. | ||
assert len(data) >= 28 | ||
|
||
# Proof the output is correct. | ||
infinity_datasource = next(item for item in data if item["id"] == "yesoreyeram-infinity-datasource") | ||
assert "go_gc_duration_seconds" in infinity_datasource["metrics"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work Andreas.
Apologies about being too specific here. May be the example plugin id in comment can help :#91 (comment) I was referring to a third type which is App plugin type which have data source as well as panel plugins bundled. Example like
Here are multiple app type plugins we can explore , I am not 100% sure if they all have these endpoints : https://grafana.com/grafana/plugins/app-plugins/ |
[
{
"name": "AWS Data Sources",
"type": "app",
"id": "aws-datasource-provisioner-app",
"enabled": false,
"category": "",
"version": "1.13.0",
"signature": "valid",
"health": {
"message": "",
"status": "OK"
},
"metrics": "# HELP go_cgo_go_to_c_calls_calls_total Count of calls made from Go to C by the current process.\n# TYPE go_cgo_go_to_c_calls_calls_total counter\ngo_cgo_go_to_c_calls_calls_total 0\n# HELP go_cpu_classes_gc_mark_assist_cpu_seconds_total Estimated total CPU time goroutines spent performing GC tasks to assist the GC and prevent it from falling behind the application. This metric is an overestimate, and not directly ..."
}
] |
grafana_wtf/core.py
Outdated
plugins = self.grafana.plugin.get_installed_plugins() | ||
for plugin in plugins: | ||
plugin = munchify(plugin) | ||
item = Munch( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow I haven't used munchify
ever , that seems like a great way to remove the tedious key value mapping with strings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you can afford the runtime speed bump, it definitively saves a few keystrokes!
By the way, big thanks to @dsc, @vmalloc, @JosePVB, @innermatrix, @d1618033, and all others who conceived it, and are maintaining it.
grafana_wtf/core.py
Outdated
|
||
# Status inquiry is not provided by all plugins. Let's filter them. | ||
# Effectively, run it only on non-internal "app" and "datasource" items. | ||
if item.type != "panel" and item.signature != "internal": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for incorporating !!
log.warning(f"Metrics inquiry failed for plugin {item.id}, type={item.type}: {ex}") | ||
else: | ||
log.info(f"Skipping status inquiry for plugin {item.id}, type={item.type}") | ||
status.append(item) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice in one go we can get all of them.
Also, test status inquiry after plugin uninstall.
About
At grafana-toolbox/grafana-client#110, @bhks added a few more API wrapper functions for Grafana. Thanks! This patch wraps them once more into the command line interface of grafana-wtf.
Synopsis