Browse Source

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
David Kaltschmidt 7 years ago
parent
commit
979f3f3e0c

+ 1 - 0
public/app/core/logs_model.ts

@@ -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[];

+ 33 - 1
public/app/core/utils/explore.ts

@@ -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,

+ 10 - 35
public/app/features/explore/Explore.tsx

@@ -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}

+ 12 - 12
public/app/features/explore/Logs.tsx

@@ -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) {
-    // Reset to render minimal only
-    if (nextProps.data !== this.props.data) {
-      this.setState({ deferLogs: true, renderAll: false });
+  componentDidMount() {
+    // Staged rendering
+    if (this.state.deferLogs) {
+      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) {
-      clearTimeout(this.deferLogsTimer);
-      this.deferLogsTimer = setTimeout(() => this.setState({ deferLogs: false }), 1000);
-    } else if (prevState.deferLogs && !this.state.deferLogs) {
-      clearTimeout(this.renderAllTimer);
+    if (prevState.deferLogs && !this.state.deferLogs && !this.state.renderAll) {
       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 lastRows = dedupedData.rows.slice(RENDER_LIMIT);
+    const firstRows = dedupedData.rows.slice(0, PREVIEW_LIMIT);
+    const lastRows = dedupedData.rows.slice(PREVIEW_LIMIT);
 
 
     // Check for labels
     // Check for labels
     if (showLabels === null) {
     if (showLabels === null) {

+ 4 - 0
public/app/plugins/datasource/logging/result_transformer.ts

@@ -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,
   };
   };