mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Review feedback
- fixed typo - moved result calculation to explore utils - use component keys instead of componentWillReceiveProps - require logs to have and id, to as use as Logs component key - render delay based on row count
This commit is contained in:
@@ -58,6 +58,7 @@ export interface LogsMetaItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface LogsModel {
|
export interface LogsModel {
|
||||||
|
id: string; // Identify one logs result from another
|
||||||
meta?: LogsMetaItem[];
|
meta?: LogsMetaItem[];
|
||||||
rows: LogRow[];
|
rows: LogRow[];
|
||||||
series?: TimeSeries[];
|
series?: TimeSeries[];
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
import { renderUrl } from 'app/core/utils/url';
|
import { renderUrl } from 'app/core/utils/url';
|
||||||
import { ExploreState, ExploreUrlState, HistoryItem } from 'app/types/explore';
|
import { ExploreState, ExploreUrlState, HistoryItem, QueryTransaction } from 'app/types/explore';
|
||||||
import { DataQuery, RawTimeRange } from 'app/types/series';
|
import { DataQuery, RawTimeRange } from 'app/types/series';
|
||||||
|
|
||||||
|
import TableModel, { mergeTablesIntoModel } from 'app/core/table_model';
|
||||||
import kbn from 'app/core/utils/kbn';
|
import kbn from 'app/core/utils/kbn';
|
||||||
import colors from 'app/core/utils/colors';
|
import colors from 'app/core/utils/colors';
|
||||||
import TimeSeries from 'app/core/time_series2';
|
import TimeSeries from 'app/core/time_series2';
|
||||||
@@ -133,6 +136,35 @@ export function hasNonEmptyQuery(queries: DataQuery[]): boolean {
|
|||||||
return queries.some(query => Object.keys(query).length > 2);
|
return queries.some(query => Object.keys(query).length > 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function calculcateResultsFromQueryTransactions(
|
||||||
|
queryTransactions: QueryTransaction[],
|
||||||
|
datasource: any,
|
||||||
|
graphInterval: number
|
||||||
|
) {
|
||||||
|
const graphResult = _.flatten(
|
||||||
|
queryTransactions.filter(qt => qt.resultType === 'Graph' && qt.done && qt.result).map(qt => qt.result)
|
||||||
|
);
|
||||||
|
const tableResult = mergeTablesIntoModel(
|
||||||
|
new TableModel(),
|
||||||
|
...queryTransactions.filter(qt => qt.resultType === 'Table' && qt.done && qt.result).map(qt => qt.result)
|
||||||
|
);
|
||||||
|
const logsResult =
|
||||||
|
datasource && datasource.mergeStreams
|
||||||
|
? datasource.mergeStreams(
|
||||||
|
_.flatten(
|
||||||
|
queryTransactions.filter(qt => qt.resultType === 'Logs' && qt.done && qt.result).map(qt => qt.result)
|
||||||
|
),
|
||||||
|
graphInterval
|
||||||
|
)
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
return {
|
||||||
|
graphResult,
|
||||||
|
tableResult,
|
||||||
|
logsResult,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function getIntervals(
|
export function getIntervals(
|
||||||
range: RawTimeRange,
|
range: RawTimeRange,
|
||||||
datasource,
|
datasource,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { RawTimeRange, DataQuery } from 'app/types/series';
|
|||||||
import store from 'app/core/store';
|
import store from 'app/core/store';
|
||||||
import {
|
import {
|
||||||
DEFAULT_RANGE,
|
DEFAULT_RANGE,
|
||||||
|
calculcateResultsFromQueryTransactions,
|
||||||
ensureQueries,
|
ensureQueries,
|
||||||
getIntervals,
|
getIntervals,
|
||||||
generateKey,
|
generateKey,
|
||||||
@@ -28,7 +29,7 @@ import ResetStyles from 'app/core/components/Picker/ResetStyles';
|
|||||||
import PickerOption from 'app/core/components/Picker/PickerOption';
|
import PickerOption from 'app/core/components/Picker/PickerOption';
|
||||||
import IndicatorsContainer from 'app/core/components/Picker/IndicatorsContainer';
|
import IndicatorsContainer from 'app/core/components/Picker/IndicatorsContainer';
|
||||||
import NoOptionsMessage from 'app/core/components/Picker/NoOptionsMessage';
|
import NoOptionsMessage from 'app/core/components/Picker/NoOptionsMessage';
|
||||||
import TableModel, { mergeTablesIntoModel } from 'app/core/table_model';
|
import TableModel from 'app/core/table_model';
|
||||||
import { DatasourceSrv } from 'app/features/plugins/datasource_srv';
|
import { DatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||||
|
|
||||||
import Panel from './Panel';
|
import Panel from './Panel';
|
||||||
@@ -50,35 +51,6 @@ interface ExploreProps {
|
|||||||
urlState: ExploreUrlState;
|
urlState: ExploreUrlState;
|
||||||
}
|
}
|
||||||
|
|
||||||
function calulcateResultsFromQueryTransactions(
|
|
||||||
queryTransactions: QueryTransaction[],
|
|
||||||
datasource: any,
|
|
||||||
graphInterval: number
|
|
||||||
) {
|
|
||||||
const graphResult = _.flatten(
|
|
||||||
queryTransactions.filter(qt => qt.resultType === 'Graph' && qt.done && qt.result).map(qt => qt.result)
|
|
||||||
);
|
|
||||||
const tableResult = mergeTablesIntoModel(
|
|
||||||
new TableModel(),
|
|
||||||
...queryTransactions.filter(qt => qt.resultType === 'Table' && qt.done && qt.result).map(qt => qt.result)
|
|
||||||
);
|
|
||||||
const logsResult =
|
|
||||||
datasource && datasource.mergeStreams
|
|
||||||
? datasource.mergeStreams(
|
|
||||||
_.flatten(
|
|
||||||
queryTransactions.filter(qt => qt.resultType === 'Logs' && qt.done && qt.result).map(qt => qt.result)
|
|
||||||
),
|
|
||||||
graphInterval
|
|
||||||
)
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
return {
|
|
||||||
graphResult,
|
|
||||||
tableResult,
|
|
||||||
logsResult,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Explore provides an area for quick query iteration for a given datasource.
|
* Explore provides an area for quick query iteration for a given datasource.
|
||||||
* Once a datasource is selected it populates the query section at the top.
|
* Once a datasource is selected it populates the query section at the top.
|
||||||
@@ -144,6 +116,8 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|||||||
const { datasource, queries, range } = props.urlState as ExploreUrlState;
|
const { datasource, queries, range } = props.urlState as ExploreUrlState;
|
||||||
initialQueries = ensureQueries(queries);
|
initialQueries = ensureQueries(queries);
|
||||||
const initialRange = range || { ...DEFAULT_RANGE };
|
const initialRange = range || { ...DEFAULT_RANGE };
|
||||||
|
// Millies step for helper bar charts
|
||||||
|
const initialGraphInterval = 15 * 1000;
|
||||||
this.state = {
|
this.state = {
|
||||||
datasource: null,
|
datasource: null,
|
||||||
datasourceError: null,
|
datasourceError: null,
|
||||||
@@ -151,7 +125,7 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|||||||
datasourceMissing: false,
|
datasourceMissing: false,
|
||||||
datasourceName: datasource,
|
datasourceName: datasource,
|
||||||
exploreDatasources: [],
|
exploreDatasources: [],
|
||||||
graphInterval: 15 * 1000,
|
graphInterval: initialGraphInterval,
|
||||||
graphResult: [],
|
graphResult: [],
|
||||||
initialQueries,
|
initialQueries,
|
||||||
history: [],
|
history: [],
|
||||||
@@ -458,7 +432,7 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|||||||
|
|
||||||
// Toggle off needs discarding of table queries
|
// Toggle off needs discarding of table queries
|
||||||
const nextQueryTransactions = state.queryTransactions.filter(qt => qt.resultType !== 'Table');
|
const nextQueryTransactions = state.queryTransactions.filter(qt => qt.resultType !== 'Table');
|
||||||
const results = calulcateResultsFromQueryTransactions(
|
const results = calculcateResultsFromQueryTransactions(
|
||||||
nextQueryTransactions,
|
nextQueryTransactions,
|
||||||
state.datasource,
|
state.datasource,
|
||||||
state.graphInterval
|
state.graphInterval
|
||||||
@@ -545,7 +519,7 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|||||||
|
|
||||||
// Discard transactions related to row query
|
// Discard transactions related to row query
|
||||||
const nextQueryTransactions = queryTransactions.filter(qt => qt.rowIndex !== index);
|
const nextQueryTransactions = queryTransactions.filter(qt => qt.rowIndex !== index);
|
||||||
const results = calulcateResultsFromQueryTransactions(
|
const results = calculcateResultsFromQueryTransactions(
|
||||||
nextQueryTransactions,
|
nextQueryTransactions,
|
||||||
state.datasource,
|
state.datasource,
|
||||||
state.graphInterval
|
state.graphInterval
|
||||||
@@ -660,7 +634,7 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|||||||
// Append new transaction
|
// Append new transaction
|
||||||
const nextQueryTransactions = [...remainingTransactions, transaction];
|
const nextQueryTransactions = [...remainingTransactions, transaction];
|
||||||
|
|
||||||
const results = calulcateResultsFromQueryTransactions(
|
const results = calculcateResultsFromQueryTransactions(
|
||||||
nextQueryTransactions,
|
nextQueryTransactions,
|
||||||
state.datasource,
|
state.datasource,
|
||||||
state.graphInterval
|
state.graphInterval
|
||||||
@@ -718,7 +692,7 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|||||||
return qt;
|
return qt;
|
||||||
});
|
});
|
||||||
|
|
||||||
const results = calulcateResultsFromQueryTransactions(
|
const results = calculcateResultsFromQueryTransactions(
|
||||||
nextQueryTransactions,
|
nextQueryTransactions,
|
||||||
state.datasource,
|
state.datasource,
|
||||||
state.graphInterval
|
state.graphInterval
|
||||||
@@ -979,6 +953,7 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|||||||
<Panel label="Logs" loading={logsLoading} isOpen={showingLogs} onToggle={this.onClickLogsButton}>
|
<Panel label="Logs" loading={logsLoading} isOpen={showingLogs} onToggle={this.onClickLogsButton}>
|
||||||
<Logs
|
<Logs
|
||||||
data={logsResult}
|
data={logsResult}
|
||||||
|
key={logsResult.id}
|
||||||
loading={logsLoading}
|
loading={logsLoading}
|
||||||
position={position}
|
position={position}
|
||||||
onChangeTime={this.onChangeTime}
|
onChangeTime={this.onChangeTime}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { Switch } from 'app/core/components/Switch/Switch';
|
|||||||
|
|
||||||
import Graph from './Graph';
|
import Graph from './Graph';
|
||||||
|
|
||||||
const RENDER_LIMIT = 100;
|
const PREVIEW_LIMIT = 100;
|
||||||
|
|
||||||
const graphOptions = {
|
const graphOptions = {
|
||||||
series: {
|
series: {
|
||||||
@@ -170,20 +170,20 @@ export default class Logs extends PureComponent<LogsProps, LogsState> {
|
|||||||
showUtc: false,
|
showUtc: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentDidMount() {
|
||||||
// Reset to render minimal only
|
// Staged rendering
|
||||||
if (nextProps.data !== this.props.data) {
|
if (this.state.deferLogs) {
|
||||||
this.setState({ deferLogs: true, renderAll: false });
|
const { data } = this.props;
|
||||||
|
const rowCount = data && data.rows ? data.rows.length : 0;
|
||||||
|
// Render all right away if not too far over the limit
|
||||||
|
const renderAll = rowCount <= PREVIEW_LIMIT * 2;
|
||||||
|
this.deferLogsTimer = setTimeout(() => this.setState({ deferLogs: false, renderAll }), rowCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps, prevState) {
|
componentDidUpdate(prevProps, prevState) {
|
||||||
// Staged rendering
|
// Staged rendering
|
||||||
if (prevProps.data !== this.props.data && this.state.deferLogs) {
|
if (prevState.deferLogs && !this.state.deferLogs && !this.state.renderAll) {
|
||||||
clearTimeout(this.deferLogsTimer);
|
|
||||||
this.deferLogsTimer = setTimeout(() => this.setState({ deferLogs: false }), 1000);
|
|
||||||
} else if (prevState.deferLogs && !this.state.deferLogs) {
|
|
||||||
clearTimeout(this.renderAllTimer);
|
|
||||||
this.renderAllTimer = setTimeout(() => this.setState({ renderAll: true }), 2000);
|
this.renderAllTimer = setTimeout(() => this.setState({ renderAll: true }), 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -258,8 +258,8 @@ export default class Logs extends PureComponent<LogsProps, LogsState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Staged rendering
|
// Staged rendering
|
||||||
const firstRows = dedupedData.rows.slice(0, RENDER_LIMIT);
|
const firstRows = dedupedData.rows.slice(0, PREVIEW_LIMIT);
|
||||||
const lastRows = dedupedData.rows.slice(RENDER_LIMIT);
|
const lastRows = dedupedData.rows.slice(PREVIEW_LIMIT);
|
||||||
|
|
||||||
// Check for labels
|
// Check for labels
|
||||||
if (showLabels === null) {
|
if (showLabels === null) {
|
||||||
|
|||||||
@@ -140,6 +140,9 @@ export function processEntry(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function mergeStreamsToLogs(streams: LogsStream[], limit = DEFAULT_LIMIT): LogsModel {
|
export function mergeStreamsToLogs(streams: LogsStream[], limit = DEFAULT_LIMIT): LogsModel {
|
||||||
|
// Unique model identifier
|
||||||
|
const id = streams.map(stream => stream.labels).join();
|
||||||
|
|
||||||
// Find unique labels for each stream
|
// Find unique labels for each stream
|
||||||
streams = streams.map(stream => ({
|
streams = streams.map(stream => ({
|
||||||
...stream,
|
...stream,
|
||||||
@@ -184,6 +187,7 @@ export function mergeStreamsToLogs(streams: LogsStream[], limit = DEFAULT_LIMIT)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
id,
|
||||||
meta,
|
meta,
|
||||||
rows: sortedRows,
|
rows: sortedRows,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user