Query not called when variable changes
Closed this issue · 15 comments
Grafana Cloud share link
https://chenhesuo.grafana.net/d/kf3u8ysnk/jsontest?orgId=1&var-name=var2
test account
suochenhe_dev@163.com test111111
same as
#234 (comment)
https://fb412151502.grafana.net/goto/WVWpzqQ7k?orgId=1
test account
suochenhe_dev@163.com test111111
The previous account's 14-day trial period expired
@simPod I have the same issue as @suochenhe. Where is no call on my backend whenever variables are changed. Backend is only called on interval or manual refresh.
@suochenhe last link for me and reproduce the issue.
Any ideas?
So far I have nothing to debug. Can you test the behaviour is not the same with other datasources + setup testing dashboard (ideally provide as json dashboard definition) where I can reproduce the issue?
I do not have a publicly accessible GrafanaJsonDataSource-compatible REST endpoint at the moment.
In my dashboard different data sources (PostgreSQL i.e.) are queried on variable changes, but then the dependent variables are explicitly stated in the query.
Is the current supposed behavior that a GrafanaJsonDataSource-query is fired whenever any of the dashboard variables are changed? Or do I have to specify a dependence on a specific variable somehow? The only thing I see in the query editor is "Payload" which awaits a valid json.
I don't know grafana so well because I use it only for visualization.
How are dependent variables stated in your query? Is it different from stating it in jsonDS query payload?
Here's an example of the statement for a PostgreSQL data source:
SELECT ... FROM "Jobs" WHERE $__timeFilter("StartedAt") AND "EnvironmentKey" = ${Env:sqlstring} AND $SqlResults
That way the query knows that it needs to be fired whenever the dashboard time filter or the variables "Env" or "SqlResults" are changed.
I cannot state any explicit dependence on a variable in jsonDS like I can in PostgreSQL. You do provide all the variables configured in the dashboard in the query, but then the query is not fired when any of these variables are changed.
Using suochenhe's dashboard as an example:
Whenever the user selects a different value for the "name" variable in the drop box (i.e. var2 -> var7), the expectation is that either:
a) both tables are reloaded as they both use the jsonDS (and return the selected variable value in the query_name column)
or
b) one can state an explicit dependence on 1 or more variables in either table queries, so it only fires when any of the stated dependencies have changed
this is the server
from flask import Blueprint, request, jsonify, make_response, Flask
bp = Blueprint('grafana_test', __name__, url_prefix='/')
print(__name__)
class GrafanaTest:
def __init__(self, blueprint=None):
self.blueprint = blueprint
if blueprint and isinstance(blueprint, Blueprint):
self.register_blueprint(blueprint)
def register_blueprint(self, bp: Blueprint):
self.blueprint = bp
# 使用simple json ,必须实现的接口
bp.route('/', methods=['GET'])(self.grafana_index) # 用来测试datasource
bp.route('/search', methods=['POST'])(self.grafana_search) # 查询筛选条件(下拉框)
bp.route('/variable', methods=['POST'])(self.grafana_variable) # 查询筛选条件(下拉框)
bp.route('/query', methods=['POST'])(self.grafana_query) # 查询数据
bp.route('/annotations', methods=['POST'])(self.grafana_annotations) # 某个时间点的注释(可以不用实现)
def grafana_annotations(self):
pass
def grafana_index(self):
response = make_response(self.blueprint.name)
return response
def grafana_search(self):
return jsonify([f'metric{x}' for x in range(1, 21)])
def grafana_variable(self):
params = request.json
payload = params['payload']
target: str = payload['target']
if target == 'name_query':
return jsonify([{'__text': f'var{x}', 'value': f'var{x}'} for x in range(1, 21)])
if target == 'name1_query':
name = payload['name']
if name:
return jsonify([{'__text': f'{name}_var1_{x}', 'value': f'{name}_var1_{x}'} for x in range(1, 4)])
return jsonify([{'__text': f'var1{x}', 'value': f'var1{x}'} for x in range(1, 11)])
def grafana_query(self):
params = request.json
print(params)
scopedVars: dict = params['scopedVars']
filter = dict()
for key, value_dict in scopedVars.items():
filter[key] = value_dict['value']
print(filter)
name = filter.get('name')
name1 = filter.get('name1')
targets = params['targets']
target = targets[0]['target']
x = {
"columns": [
{"text": f"metric", "type": "string"},
{"text": f"query_name", "type": "string"},
{"text": f"query_name1", "type": "string"},
],
"rows": [
[target, name, name1],
],
"type": "table"
}
return jsonify([x])
grafana = GrafanaTest(bp)
def create_app():
app = Flask(__name__)
app.register_blueprint(grafana.blueprint)
return app
application = create_app()
if __name__ == '__main__':
application.run()
In my dashboard different data sources (PostgreSQL i.e.) are queried on variable changes, but then the dependent variables are explicitly stated in the query.
This was a good point. I remember a while ago I debugged similar issue in grafana and the panel had no dependency on the variable.
I believe your panels are missing the dependency on the variable and therefore grafana does not re-query.
There's nothing that can be done in the datasource.
I can confirm that the query is called if one adds references to the dependent variables directly to the panel (i.e. in the description field). IMHO it is not optimal because other data sources work with explicit variable references, but it is still more than workable.
I have just stumbled upon the same issue.
I don't know whether other datasources do it and if so, how. If you have some examples, provide them.
The problem is that this datasource extra adds all variables to the request, even though they're not included in panel definition and therefore the panel is not explicitly dependent on it.
GrafanaJsonDatasource/src/DataSource.ts
Lines 259 to 288 in d47cb57
It's a feature but it has not full support in Grafana since it reloads only those panels whose dependency changed.