diff --git a/CHANGELOG.md b/CHANGELOG.md index e950148f7e..e03f4ec5cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ 1. [#5959](https://github.com/influxdata/chronograf/pull/5959): Allow to customize annotation color. 1. [#5967](https://github.com/influxdata/chronograf/pull/5967): Remember whether to start with shown annotations on Dashboard page. 1. [#5977](https://github.com/influxdata/chronograf/pull/5977): Select current value in dropdown search input. +1. [#5997](https://github.com/influxdata/chronograf/pull/5997): Simplify flux labels. 1. [#5998](https://github.com/influxdata/chronograf/pull/5998): Setup DBRP mapping automatically for a v2 connection. ### Bug Fixes diff --git a/ui/src/shared/parsing/flux/parseTablesByTime.ts b/ui/src/shared/parsing/flux/parseTablesByTime.ts index 313298b6ac..c25d154916 100644 --- a/ui/src/shared/parsing/flux/parseTablesByTime.ts +++ b/ui/src/shared/parsing/flux/parseTablesByTime.ts @@ -20,73 +20,90 @@ interface ParseTablesByTimeResult { nonNumericColumns: string[] } +const IGNORED_TABLE_KEYS = ['_start', '_stop', '_field'] + +function fluxTableKey(table: FluxTable, columnName: string): string { + const name = + columnName === '_value' && table.groupKey._field + ? table.groupKey._field + : columnName + const groupKeys = Object.entries(table.groupKey).reduce((acc, [k, v]) => { + if (!IGNORED_TABLE_KEYS.includes(k)) { + acc.push(`${k === '_measurement' ? 'measurement' : k}=${v}`) + } + return acc + }, []) + return groupKeys.length ? `${name} ${groupKeys.join(' ')}` : name +} + export const parseTablesByTime = ( tables: FluxTable[] ): ParseTablesByTimeResult => { const allColumnNames = [] const nonNumericColumns = [] - const tablesByTime = tables.map(table => { - const header = table.data[0] as string[] - const columnNames: {[k: number]: string} = {} + const tablesByTime = tables + .map(table => { + const header = table.data[0] as string[] + const columnNames: {[k: number]: string} = {} - for (let i = 0; i < header.length; i++) { - const columnName = header[i] - const dataType = table.dataTypes[columnName] + for (let i = 0; i < header.length; i++) { + const columnName = header[i] + const dataType = table.dataTypes[columnName] - if (COLUMN_BLACKLIST.has(columnName)) { - continue - } + if (COLUMN_BLACKLIST.has(columnName)) { + continue + } - if (table.groupKey[columnName]) { - continue - } + if (table.groupKey[columnName]) { + continue + } - if (!NUMERIC_DATATYPES.includes(dataType)) { - nonNumericColumns.push(columnName) - continue - } + if (!NUMERIC_DATATYPES.includes(dataType)) { + nonNumericColumns.push(columnName) + continue + } - const uniqueColumnName = Object.entries(table.groupKey).reduce( - (acc, [k, v]) => acc + `[${k}=${v}]`, - columnName - ) + const uniqueColumnName = fluxTableKey(table, columnName) - columnNames[i] = uniqueColumnName - allColumnNames.push(uniqueColumnName) - } + columnNames[i] = uniqueColumnName + allColumnNames.push(uniqueColumnName) + } - let timeIndex = header.indexOf('_time') + let timeIndex = header.indexOf('_time') - let isTimeFound = true - if (timeIndex < 0) { - timeIndex = header.indexOf('_stop') - isTimeFound = false - } + let isTimeFound = true + if (timeIndex < 0) { + timeIndex = header.indexOf('_stop') + if (timeIndex < 0) { + return undefined + } + isTimeFound = false + } - const result = {} - for (let i = 1; i < table.data.length; i++) { - const row = table.data[i] - const timeValue = row[timeIndex] - let time = '' - - if (isTimeFound) { - time = timeValue.toString() - } else { - // _stop and _start have values in date string format instead of number - time = Date.parse(timeValue as string).toString() + const result = {} + for (let i = 1; i < table.data.length; i++) { + const row = table.data[i] + const timeValue = row[timeIndex] + let time: string + if (isTimeFound) { + time = timeValue.toString() + } else { + // _stop and _start have values in date string format instead of number + time = Date.parse(timeValue as string).toString() + } + result[time] = Object.entries(columnNames).reduce( + (acc, [valueIndex, columnName]) => ({ + ...acc, + [columnName]: row[valueIndex], + }), + {} + ) } - result[time] = Object.entries(columnNames).reduce( - (acc, [valueIndex, columnName]) => ({ - ...acc, - [columnName]: row[valueIndex], - }), - {} - ) - } - return result - }) + return result + }) + .filter(x => x !== undefined) return {nonNumericColumns, tablesByTime, allColumnNames} } diff --git a/ui/test/shared/parsing/flux/dygraph.test.ts b/ui/test/shared/parsing/flux/dygraph.test.ts index 73c3333eff..6c12386025 100644 --- a/ui/test/shared/parsing/flux/dygraph.test.ts +++ b/ui/test/shared/parsing/flux/dygraph.test.ts @@ -39,10 +39,10 @@ describe('fluxTablesToDygraph', () => { const expected = { labels: [ 'time', - 'mean_usage_idle[_measurement=cpu]', - 'mean_usage_user[_measurement=cpu]', - 'mean_usage_idle[_measurement=mem]', - 'mean_usage_user[_measurement=mem]', + 'mean_usage_idle measurement=cpu', + 'mean_usage_user measurement=cpu', + 'mean_usage_idle measurement=mem', + 'mean_usage_user measurement=mem', ], dygraphsData: [ [new Date('2018-09-10T16:54:37Z'), 85, 10, 8, 1], @@ -60,8 +60,8 @@ describe('fluxTablesToDygraph', () => { const expected = { labels: [ 'time', - 'mean_usage_idle[_measurement=cpu]', - 'mean_usage_idle[_measurement=mem]', + 'mean_usage_idle measurement=cpu', + 'mean_usage_idle measurement=mem', ], dygraphsData: [ [new Date('2018-09-10T16:54:37Z'), 85, 8], diff --git a/ui/test/shared/parsing/flux/parseTablesByTime.test.ts b/ui/test/shared/parsing/flux/parseTablesByTime.test.ts new file mode 100644 index 0000000000..7effc352e3 --- /dev/null +++ b/ui/test/shared/parsing/flux/parseTablesByTime.test.ts @@ -0,0 +1,39 @@ +import {parseResponse} from 'src/shared/parsing/flux/response' +import {SIMPLE, TAGS_RESPONSE} from 'test/shared/parsing/flux/constants' +import {parseTablesByTime} from 'src/shared/parsing/flux/parseTablesByTime' + +describe('parseTablesByTime', () => { + it('can parse common flux table with simplified column names', () => { + const fluxTables = parseResponse(SIMPLE) + const actual = parseTablesByTime(fluxTables) + const expected = { + allColumnNames: [ + 'usage_guest measurement=cpu cpu=cpu1 host=bertrand.local', + ], + nonNumericColumns: [], + tablesByTime: [ + { + '1536618869000': { + 'usage_guest measurement=cpu cpu=cpu1 host=bertrand.local': 0, + }, + '1536618879000': { + 'usage_guest measurement=cpu cpu=cpu1 host=bertrand.local': 10, + }, + }, + ], + } + + expect(actual).toEqual(expected) + }) + it('can parse metadata flux response', () => { + const fluxTables = parseResponse(TAGS_RESPONSE) + const actual = parseTablesByTime(fluxTables) + const expected = { + allColumnNames: [], + nonNumericColumns: ['_value'], + tablesByTime: [], + } + + expect(actual).toEqual(expected) + }) +})