Skip to content

Commit

Permalink
add metric support
Browse files Browse the repository at this point in the history
  • Loading branch information
MGJamJam committed May 2, 2024
1 parent 0865467 commit f4851da
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 20 deletions.
38 changes: 26 additions & 12 deletions bitmovin-analytics-datasource/src/components/QueryEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { DEFAULT_SELECTABLE_QUERY_INTERVAL, SELECTABLE_QUERY_INTERVALS } from '.
import { DEFAULT_SELECTABLE_AGGREGATION, SELECTABLE_AGGREGATIONS } from '../types/aggregations';
import { SELECTABLE_QUERY_AD_ATTRIBUTES } from '../types/queryAdAttributes';
import { SELECTABLE_QUERY_ATTRIBUTES } from '../types/queryAttributes';
import { isMetric, SELECTABLE_METRICS } from '../types/metric';

enum LoadingState {
Default = 'DEFAULT',
Expand All @@ -24,6 +25,7 @@ export function QueryEditor({ query, onChange, onRunQuery, datasource }: Props)
const [licenseLoadingState, setLicenseLoadingState] = useState<LoadingState>(LoadingState.Default);
const [licenseErrorMessage, setLicenseErrorMessage] = useState('');
const [isTimeSeries, setIsTimeSeries] = useState(true);
const [isDimensionMetricSelected, setIsDimensionMetricSelected] = useState(false);

useEffect(() => {
setLicenseLoadingState(LoadingState.Loading);
Expand All @@ -43,13 +45,19 @@ export function QueryEditor({ query, onChange, onRunQuery, datasource }: Props)
onRunQuery();
};

const onMetricChange = (item: SelectableValue) => {
onChange({ ...query, aggregation: item.value });
const onAggregationChange = (item: SelectableValue) => {
onChange({ ...query, aggregation: item.value, metric: undefined });
onRunQuery();
};

const onDimensionChange = (item: SelectableValue) => {
onChange({ ...query, dimension: item.value });
if (isMetric(item.value)) {
setIsDimensionMetricSelected(true);
onChange({ ...query, aggregation: undefined, dimension: undefined, metric: item.value });
} else {
setIsDimensionMetricSelected(false);
onChange({ ...query, dimension: item.value });
}
onRunQuery();
};

Expand Down Expand Up @@ -102,19 +110,25 @@ export function QueryEditor({ query, onChange, onRunQuery, datasource }: Props)
placeholder={licenseLoadingState === LoadingState.Loading ? 'Loading Licenses' : 'Choose License'}
/>
</InlineField>
<InlineField label="Metric" labelWidth={20}>
<Select
defaultValue={DEFAULT_SELECTABLE_AGGREGATION}
onChange={(item) => onMetricChange(item)}
width={40}
options={SELECTABLE_AGGREGATIONS}
/>
</InlineField>
{!isDimensionMetricSelected && (
<InlineField label="Metric" labelWidth={20}>
<Select
defaultValue={DEFAULT_SELECTABLE_AGGREGATION}
onChange={(item) => onAggregationChange(item)}
width={40}
options={SELECTABLE_AGGREGATIONS}
/>
</InlineField>
)}
<InlineField label="Dimension" labelWidth={20}>
<Select
onChange={onDimensionChange}
width={40}
options={datasource.adAnalytics ? SELECTABLE_QUERY_AD_ATTRIBUTES : SELECTABLE_QUERY_ATTRIBUTES}
options={
datasource.adAnalytics
? SELECTABLE_QUERY_AD_ATTRIBUTES
: SELECTABLE_QUERY_ATTRIBUTES.concat(SELECTABLE_METRICS)
}
/>
</InlineField>
<InlineField label="Format as time series" labelWidth={20}>
Expand Down
21 changes: 15 additions & 6 deletions bitmovin-analytics-datasource/src/datasource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ import { transformGroupedTimeSeriesData, transformSimpleTimeSeries, transformTab
import { calculateQueryInterval, QueryInterval } from './utils/intervalUtils';
import { QueryAttribute } from './types/queryAttributes';
import { QueryAdAttribute } from './types/queryAdAttributes';
import { Metric } from './types/metric';
import { Aggregation } from './types/aggregations';

type AnalyticsQuery = {
filters: Array<{ name: string; operator: string; value: number }>;
groupBy: string[];
orderBy: Array<{ name: string; order: string }>;
dimension: QueryAttribute | QueryAdAttribute;
dimension?: QueryAttribute | QueryAdAttribute;
metric?: Metric;
start: Date;
end: Date;
licenseKey: string;
Expand Down Expand Up @@ -56,7 +59,6 @@ export class DataSource extends DataSourceApi<MyQuery, MyDataSourceOptions> {
const to = range!.to.toDate();

const promises = options.targets.map(async (target) => {
const urlAppendix = target.aggregation;
const interval = target.interval
? calculateQueryInterval(target.interval!, from.getTime(), to.getTime())
: undefined;
Expand Down Expand Up @@ -85,7 +87,9 @@ export class DataSource extends DataSourceApi<MyQuery, MyDataSourceOptions> {
interval: interval,
};

const response = await lastValueFrom(this.request(this.getRequestUrl() + urlAppendix, 'POST', query));
const response = await lastValueFrom(
this.request(this.getRequestUrl(target.metric, target.aggregation), 'POST', query)
);

const dataRows: MixedDataRowList = response.data.data.result.rows;
const columnLabels: Array<{ key: string; label: string }> = response.data.data.result.columnLabels;
Expand Down Expand Up @@ -122,12 +126,17 @@ export class DataSource extends DataSourceApi<MyQuery, MyDataSourceOptions> {
return Promise.all(promises).then((data) => ({ data }));
}

getRequestUrl(): string {
getRequestUrl(metric?: Metric, aggregation?: Aggregation): string {
let url = '/analytics';
if (this.adAnalytics === true) {
return '/analytics/ads/queries/';
url += '/ads';
}

return '/analytics/queries/';
if (metric !== undefined) {
return url + '/metrics/' + metric;
}

return url + '/queries/' + aggregation;
}

request(url: string, method: string, payload?: any): Observable<Record<any, any>> {
Expand Down
6 changes: 4 additions & 2 deletions bitmovin-analytics-datasource/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import { QueryInterval } from './utils/intervalUtils';
import { Aggregation } from './types/aggregations';
import { QueryAttribute } from './types/queryAttributes';
import { QueryAdAttribute } from './types/queryAdAttributes';
import { Metric } from './types/metric';

export interface MyQuery extends DataQuery {
licenseKey: string;
interval?: QueryInterval | 'AUTO';
aggregation: Aggregation;
dimension: QueryAttribute | QueryAdAttribute;
aggregation?: Aggregation;
metric?: Metric;
dimension?: QueryAttribute | QueryAdAttribute;
}

export const DEFAULT_QUERY: Partial<MyQuery> = {};
Expand Down
19 changes: 19 additions & 0 deletions bitmovin-analytics-datasource/src/types/metric.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { SelectableValue } from '@grafana/data';

export enum METRICS {
AVG_CONCURRENTVIEWERS = 'avg-concurrentviewers',
MAX_CONCURRENTVIEWERS = 'max-concurrentviewers',
AVG_DROPPED_FRAMES = 'avg-dropped-frames',
}

export type Metric = (typeof METRICS)[keyof typeof METRICS];

export const SELECTABLE_METRICS: Array<SelectableValue<Metric>> = [
{ value: METRICS.AVG_CONCURRENTVIEWERS, label: 'Avg Concurrent Viewers' },
{ value: METRICS.MAX_CONCURRENTVIEWERS, label: 'Max Concurrent Viewers' },
{ value: METRICS.AVG_DROPPED_FRAMES, label: 'Avg Dropped Frames' },
];

export const isMetric = (value: string): boolean => {
return Object.values(METRICS).includes(value as Metric);
};

0 comments on commit f4851da

Please sign in to comment.