Skip to content

Commit 21a95e4

Browse files
authored
updated rudderstack events (#761)
1 parent a5f8612 commit 21a95e4

8 files changed

+93
-33
lines changed

.changeset/brown-clocks-remember.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'grafana-infinity-datasource': minor
3+
---
4+
5+
Updated health check messages to include details about custom health check settings

.changeset/friendly-months-tell.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
'grafana-infinity-datasource': patch
33
---
44

5-
Fixed a bug where query columns editor is unusable when sanbox enabled
5+
Fixed a bug where query columns editor is unusable when sandbox enabled

.changeset/late-hats-breathe.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'grafana-infinity-datasource': patch
3+
---
4+
5+
Updated rudderstack analytics events

cspell.config.json

+1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
"popperjs",
109109
"prismjs",
110110
"promhttp",
111+
"rudderstack",
111112
"scroller",
112113
"seriesgen",
113114
"sigv",

docs/sources/setup/configuration.md

+6
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ This datasource can work out of the box without any additional configuration. If
4545
4646
More details about the URL and related settings can be found in [url](/docs/url) page
4747

48+
## Health check
49+
50+
When you save the infinity datasource settings in the config page, By default this will just save the settings and won't perform any validation against any URLs. If you want to validate the settings such as authentication, api keys, then you must enable custom health check in the health check section of the configuration page.
51+
52+
> Currently only HTTP GET methods are supported in the custom health check. Also custom health checks only validate the response status code HTTP 200 and doesn't perform any validation against the response content
53+
4854
## Proxy outgoing requests
4955

5056
If you want your datasource to connect via proxy, set the environment appropriate environment variables. HTTP_PROXY, HTTPS_PROXY and NO_PROXY. HTTPS_PROXY takes precedence over HTTP_PROXY for https requests.

src/datasource.spec.ts

+21-2
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,28 @@ describe('metricFindQuery', () => {
7575

7676
describe('testDatasource', () => {
7777
beforeEach(() => jest.spyOn(DataSourceWithBackend.prototype, 'testDatasource').mockResolvedValue({ message: 'OK' }));
78-
it('should not throw error when allowed hosts configured', async () => {
78+
it('should pass with the default settings', async () => {
79+
const ds = new Datasource({ ...DummyDatasource });
80+
const result = await ds.testDatasource();
81+
expect(result).toStrictEqual({
82+
status: 'success',
83+
message: 'OK. Settings saved',
84+
});
85+
});
86+
it('should warn when no health check configured', async () => {
7987
const ds = new Datasource({ ...DummyDatasource, jsonData: { auth_method: 'apiKey', allowedHosts: ['foo'] } });
8088
const result = await ds.testDatasource();
81-
expect(result).toStrictEqual({ status: 'success', message: 'OK. Settings saved' });
89+
expect(result).toStrictEqual({
90+
status: 'warning',
91+
message: 'Success. Settings saved but no health checks performed. To validate the connection/credentials, you have to provide a sample URL in Health Check section',
92+
});
93+
});
94+
it('should pass when health check and allowed hosts configured', async () => {
95+
const ds = new Datasource({ ...DummyDatasource, jsonData: { auth_method: 'apiKey', allowedHosts: ['foo'], customHealthCheckEnabled: true, customHealthCheckUrl: 'https://foo.com' } });
96+
const result = await ds.testDatasource();
97+
expect(result).toStrictEqual({
98+
status: 'success',
99+
message: 'OK. Settings saved',
100+
});
82101
});
83102
});

src/datasource.ts

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { LoadingState, toDataFrame, DataFrame, DataQueryRequest, DataQueryResponse, ScopedVars, TimeRange } from '@grafana/data';
2-
import { DataSourceWithBackend } from '@grafana/runtime';
2+
import { DataSourceWithBackend, HealthStatus } from '@grafana/runtime';
33
import { flatten, sample } from 'lodash';
44
import { Observable } from 'rxjs';
55
import { applyGroq } from './app/GROQProvider';
@@ -25,7 +25,7 @@ export class Datasource extends DataSourceWithBackend<InfinityQuery, InfinityOpt
2525
query(options: DataQueryRequest<InfinityQuery>): Observable<DataQueryResponse> {
2626
return new Observable<DataQueryResponse>((subscriber) => {
2727
let request = getUpdatedDataRequest(options, this.instanceSettings);
28-
reportQuery(request?.targets || [], this.instanceSettings, request?.app);
28+
reportQuery(request?.targets || [], this.instanceSettings, this.meta, request?.app);
2929
super
3030
.query(request)
3131
.toPromise()
@@ -98,17 +98,24 @@ export class Datasource extends DataSourceWithBackend<InfinityQuery, InfinityOpt
9898
return super
9999
.testDatasource()
100100
.then((o) => {
101+
reportHealthCheck(o, this.instanceSettings, this.meta);
101102
switch (o?.message) {
102103
case 'OK':
103-
reportHealthCheck({ status: 'success', message: 'OK. Settings saved', authMethod: this.instanceSettings?.jsonData?.auth_method || '' });
104+
if (!(this.instanceSettings?.jsonData?.customHealthCheckEnabled && this.instanceSettings?.jsonData?.customHealthCheckUrl) && this.instanceSettings?.jsonData?.auth_method) {
105+
const healthCheckMessage = [
106+
'Success',
107+
'Settings saved but no health checks performed',
108+
'To validate the connection/credentials, you have to provide a sample URL in Health Check section',
109+
].join(`. `);
110+
return Promise.resolve({ status: 'warning', message: healthCheckMessage });
111+
}
104112
return Promise.resolve({ status: 'success', message: 'OK. Settings saved' });
105113
default:
106-
reportHealthCheck({ status: o?.status || 'success', message: o?.message || 'Settings saved' });
107114
return Promise.resolve({ status: o?.status || 'success', message: o?.message || 'Settings saved' });
108115
}
109116
})
110117
.catch((ex) => {
111-
reportHealthCheck({ status: 'error', message: ex.message });
118+
reportHealthCheck({ status: HealthStatus.Error, message: ex }, this.instanceSettings, this.meta);
112119
return Promise.resolve({ status: 'error', message: ex.message });
113120
});
114121
}

src/utils/analytics.ts

+42-25
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,79 @@
1-
import { CoreApp } from '@grafana/data';
2-
import { reportInteraction, config } from '@grafana/runtime';
1+
import { CoreApp, DataSourcePluginMeta } from '@grafana/data';
2+
import { reportInteraction, config, HealthCheckResult } from '@grafana/runtime';
33
import { isBackendQuery } from './../app/utils';
44
import { InfinityInstanceSettings, InfinityQuery } from './../types';
55

66
type Report_Action = 'grafana_infinity_query_executed' | 'grafana_infinity_health_check_executed';
77

8-
const reportActivity = (action: Report_Action, meta?: Record<string, any>) => {
8+
const reportActivity = (action: Report_Action, data: Record<string, any> = {}, instance_settings?: InfinityInstanceSettings, plugin_meta?: DataSourcePluginMeta) => {
99
try {
10-
reportInteraction(action, { ...meta, plugin_name: 'yesoreyeram-infinity-datasource', ts: new Date().getTime() });
10+
// Grafana related meta
11+
data['grafana_licenseInfo_stateInfo'] = config?.licenseInfo?.stateInfo || '';
12+
data['grafana_buildInfo_edition'] = config?.buildInfo?.edition || '';
13+
data['grafana_buildInfo_version'] = config?.buildInfo?.version || '';
14+
data['grafana_buildInfo_version_short'] = (config?.buildInfo?.version || '').split('-')[0];
15+
data['grafana_app_url'] = config?.appUrl || '';
16+
const grafana_url = new URL(window?.document?.URL);
17+
data['grafana_host'] = grafana_url?.host || grafana_url?.hostname || 'unknown';
18+
// Plugin meta
19+
data['plugin_id'] = plugin_meta?.id || 'yesoreyeram-infinity-datasource';
20+
data['plugin_version'] = plugin_meta?.info?.version || 'unknown';
21+
// Plugin configuration
22+
data['config_authType'] = instance_settings?.jsonData?.auth_method || instance_settings?.jsonData?.authType || 'unknown';
23+
data['config_oauth2_type'] = instance_settings?.jsonData?.oauth2?.oauth2_type || 'unknown';
24+
data['config_global_queries_count'] = (instance_settings?.jsonData?.global_queries || []).length;
25+
data['config_reference_data_count'] = (instance_settings?.jsonData?.refData || []).length;
26+
data['config_allowed_hosts_count'] = (instance_settings?.jsonData?.allowedHosts || []).length;
27+
data['config_custom_health_check_enabled'] = instance_settings?.jsonData?.customHealthCheckEnabled ? 'enabled' : 'unknown';
28+
reportInteraction(action, { ...data, ts: new Date().getTime() });
1129
} catch (ex) {
1230
console.error('error while reporting infinity query', ex);
1331
}
1432
};
1533

16-
export const reportHealthCheck = (meta: Record<string, string> = {}) => {
17-
reportActivity('grafana_infinity_health_check_executed', meta);
34+
export const reportHealthCheck = (o?: Omit<HealthCheckResult, 'details'>, instance_settings?: InfinityInstanceSettings, plugin_meta?: DataSourcePluginMeta) => {
35+
let meta: Record<string, any> = {
36+
plugin_healthcheck_status: o?.status || 'unknown',
37+
plugin_healthcheck_message: o?.message || 'unknown',
38+
};
39+
reportActivity('grafana_infinity_health_check_executed', meta, instance_settings, plugin_meta);
1840
};
1941

20-
export const reportQuery = (queries: InfinityQuery[] = [], instance_settings?: InfinityInstanceSettings, app = 'unknown') => {
42+
export const reportQuery = (queries: InfinityQuery[] = [], instance_settings?: InfinityInstanceSettings, plugin_meta?: DataSourcePluginMeta, app = 'unknown') => {
2143
if (app === CoreApp.Dashboard || app === CoreApp.PanelViewer) {
2244
return;
2345
}
24-
let input: Record<string, number | string> = {};
46+
let meta: Record<string, number | string> = {};
2547
for (const query of queries) {
26-
input['grafana_buildInfo_edition'] = config?.buildInfo?.edition || '';
27-
input['grafana_buildInfo_version'] = config?.buildInfo?.version || '';
28-
input['grafana_licenseInfo_stateInfo'] = config?.licenseInfo?.stateInfo || '';
29-
if (instance_settings) {
30-
input['config_authType'] = instance_settings.jsonData?.authType || 'unknown';
31-
input['config_oauth2_type'] = instance_settings.jsonData?.oauth2?.oauth2_type || 'unknown';
32-
}
33-
input['query_type'] = query.type;
34-
input['query_source'] = (query as any).source || 'unknown';
35-
input['query_parser'] = (query as any).parser || 'unknown';
48+
meta['grafana_app'] = app;
49+
meta['query_type'] = (query as any).type || 'unknown';
50+
meta['query_source'] = (query as any).source || 'unknown';
51+
meta['query_parser'] = (query as any).parser || 'unknown';
52+
meta['query_format'] = (query as any).format || 'unknown';
3653
const queryUrl = (query as any).url || '';
3754
if (queryUrl) {
3855
try {
3956
const baseUrl = new URL(queryUrl);
40-
input['query_url_host'] = baseUrl.host || baseUrl.hostname;
41-
input['query_url_path'] = baseUrl.pathname;
57+
meta['query_url_host'] = baseUrl.host || baseUrl.hostname;
4258
} catch (ex) {
4359
console.error(ex);
4460
}
4561
}
4662
if (isBackendQuery(query)) {
4763
if (query.summarizeExpression) {
48-
input['query_summarizeExpression'] = 'in_use';
64+
meta['query_summarizeExpression'] = 'in_use';
4965
}
5066
if (query.summarizeBy) {
51-
input['query_summarizeBy'] = 'in_use';
67+
meta['query_summarizeBy'] = 'in_use';
5268
}
5369
if (query.filterExpression) {
54-
input['query_filterExpression'] = 'in_use';
70+
meta['query_filterExpression'] = 'in_use';
5571
}
5672
if (query.computed_columns && query.computed_columns.length > 0) {
57-
input['query_computed_columns'] = query.computed_columns.length;
73+
meta['query_computed_columns'] = query.computed_columns.length;
5874
}
75+
meta['query_pagination_mode'] = query.pagination_mode || 'none';
5976
}
60-
reportActivity('grafana_infinity_query_executed', input);
77+
reportActivity('grafana_infinity_query_executed', meta, instance_settings, plugin_meta);
6178
}
6279
};

0 commit comments

Comments
 (0)