ResultProcessor.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import { LogsModel, GraphSeriesXY, DataFrame, FieldType } from '@grafana/data';
  2. import { ExploreItemState, ExploreMode } from 'app/types/explore';
  3. import TableModel, { mergeTablesIntoModel } from 'app/core/table_model';
  4. import { sortLogsResult, refreshIntervalToSortOrder } from 'app/core/utils/explore';
  5. import { dataFrameToLogsModel } from 'app/core/logs_model';
  6. import { getGraphSeriesModel } from 'app/plugins/panel/graph2/getGraphSeriesModel';
  7. export class ResultProcessor {
  8. constructor(
  9. private state: ExploreItemState,
  10. private replacePreviousResults: boolean,
  11. private dataFrames: DataFrame[]
  12. ) {}
  13. getGraphResult(): GraphSeriesXY[] {
  14. if (this.state.mode !== ExploreMode.Metrics) {
  15. return [];
  16. }
  17. const onlyTimeSeries = this.dataFrames.filter(series => series.fields.length === 2);
  18. return getGraphSeriesModel(
  19. onlyTimeSeries,
  20. {},
  21. { showBars: false, showLines: true, showPoints: false },
  22. { asTable: false, isVisible: true, placement: 'under' }
  23. );
  24. }
  25. getTableResult(): TableModel {
  26. if (this.state.mode !== ExploreMode.Metrics) {
  27. return new TableModel();
  28. }
  29. // For now ignore time series
  30. // We can change this later, just need to figure out how to
  31. // Ignore time series only for prometheus
  32. const onlyTables = this.dataFrames.filter(frame => {
  33. if (frame.fields.length === 2) {
  34. if (frame.fields[1].type === FieldType.time) {
  35. return false;
  36. }
  37. }
  38. return true;
  39. });
  40. const tables = onlyTables.map(frame => {
  41. const { fields } = frame;
  42. const fieldCount = fields.length;
  43. const rowCount = fields[0].values.length;
  44. const columns = fields.map(field => ({
  45. text: field.name,
  46. type: field.type,
  47. filterable: field.config.filterable,
  48. }));
  49. const rows: any[][] = [];
  50. for (let i = 0; i < rowCount; i++) {
  51. const row: any[] = [];
  52. for (let j = 0; j < fieldCount; j++) {
  53. row.push(frame.fields[j].values.get(i));
  54. }
  55. rows.push(row);
  56. }
  57. return new TableModel({
  58. columns,
  59. rows,
  60. meta: frame.meta,
  61. });
  62. });
  63. return mergeTablesIntoModel(new TableModel(), ...tables);
  64. }
  65. getLogsResult(): LogsModel {
  66. if (this.state.mode !== ExploreMode.Logs) {
  67. return null;
  68. }
  69. const graphInterval = this.state.queryIntervals.intervalMs;
  70. const newResults = dataFrameToLogsModel(this.dataFrames, graphInterval);
  71. const sortOrder = refreshIntervalToSortOrder(this.state.refreshInterval);
  72. const sortedNewResults = sortLogsResult(newResults, sortOrder);
  73. if (this.replacePreviousResults) {
  74. const slice = 1000;
  75. const rows = sortedNewResults.rows.slice(0, slice);
  76. const series = sortedNewResults.series;
  77. return { ...sortedNewResults, rows, series };
  78. }
  79. const prevLogsResult: LogsModel = this.state.logsResult || { hasUniqueLabels: false, rows: [] };
  80. const sortedLogResult = sortLogsResult(prevLogsResult, sortOrder);
  81. const rowsInState = sortedLogResult.rows;
  82. const processedRows = [];
  83. for (const row of rowsInState) {
  84. processedRows.push({ ...row, fresh: false });
  85. }
  86. for (const row of sortedNewResults.rows) {
  87. processedRows.push({ ...row, fresh: true });
  88. }
  89. const slice = -1000;
  90. const rows = processedRows.slice(slice);
  91. const series = sortedNewResults.series.slice(slice);
  92. return { ...sortedNewResults, rows, series };
  93. }
  94. }