LogsContainer.tsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. import React, { Component } from 'react';
  2. import { hot } from 'react-hot-loader';
  3. import { connect } from 'react-redux';
  4. import {
  5. RawTimeRange,
  6. LogLevel,
  7. TimeZone,
  8. AbsoluteTimeRange,
  9. DataSourceApi,
  10. LogsModel,
  11. LogRowModel,
  12. LogsDedupStrategy,
  13. LoadingState,
  14. } from '@grafana/ui';
  15. import { ExploreId, ExploreItemState } from 'app/types/explore';
  16. import { StoreState } from 'app/types';
  17. import { changeDedupStrategy, updateTimeRange } from './state/actions';
  18. import Logs from './Logs';
  19. import Panel from './Panel';
  20. import { toggleLogLevelAction, changeRefreshIntervalAction } from 'app/features/explore/state/actionTypes';
  21. import { deduplicatedLogsSelector, exploreItemUIStateSelector } from 'app/features/explore/state/selectors';
  22. import { getTimeZone } from '../profile/state/selectors';
  23. import { LiveLogsWithTheme } from './LiveLogs';
  24. import { offOption } from '@grafana/ui/src/components/RefreshPicker/RefreshPicker';
  25. interface LogsContainerProps {
  26. datasourceInstance: DataSourceApi | null;
  27. exploreId: ExploreId;
  28. loading: boolean;
  29. logsHighlighterExpressions?: string[];
  30. logsResult?: LogsModel;
  31. dedupedResult?: LogsModel;
  32. onClickLabel: (key: string, value: string) => void;
  33. onStartScanning: () => void;
  34. onStopScanning: () => void;
  35. timeZone: TimeZone;
  36. scanning?: boolean;
  37. scanRange?: RawTimeRange;
  38. toggleLogLevelAction: typeof toggleLogLevelAction;
  39. changeDedupStrategy: typeof changeDedupStrategy;
  40. dedupStrategy: LogsDedupStrategy;
  41. hiddenLogLevels: Set<LogLevel>;
  42. width: number;
  43. isLive: boolean;
  44. stopLive: typeof changeRefreshIntervalAction;
  45. updateTimeRange: typeof updateTimeRange;
  46. absoluteRange: AbsoluteTimeRange;
  47. }
  48. export class LogsContainer extends Component<LogsContainerProps> {
  49. onChangeTime = (absoluteRange: AbsoluteTimeRange) => {
  50. const { exploreId, updateTimeRange } = this.props;
  51. updateTimeRange({ exploreId, absoluteRange });
  52. };
  53. onStopLive = () => {
  54. const { exploreId } = this.props;
  55. this.props.stopLive({ exploreId, refreshInterval: offOption.value });
  56. };
  57. handleDedupStrategyChange = (dedupStrategy: LogsDedupStrategy) => {
  58. this.props.changeDedupStrategy(this.props.exploreId, dedupStrategy);
  59. };
  60. hangleToggleLogLevel = (hiddenLogLevels: Set<LogLevel>) => {
  61. const { exploreId } = this.props;
  62. this.props.toggleLogLevelAction({
  63. exploreId,
  64. hiddenLogLevels,
  65. });
  66. };
  67. getLogRowContext = async (row: LogRowModel, options?: any) => {
  68. const { datasourceInstance } = this.props;
  69. if (datasourceInstance) {
  70. return datasourceInstance.getLogRowContext(row, options);
  71. }
  72. return [];
  73. };
  74. // Limit re-rendering to when a query is finished executing or when the deduplication strategy changes
  75. // for performance reasons.
  76. shouldComponentUpdate(nextProps: LogsContainerProps): boolean {
  77. return (
  78. nextProps.loading !== this.props.loading ||
  79. nextProps.dedupStrategy !== this.props.dedupStrategy ||
  80. nextProps.logsHighlighterExpressions !== this.props.logsHighlighterExpressions
  81. );
  82. }
  83. render() {
  84. const {
  85. exploreId,
  86. loading,
  87. logsHighlighterExpressions,
  88. logsResult,
  89. dedupedResult,
  90. onClickLabel,
  91. onStartScanning,
  92. onStopScanning,
  93. absoluteRange,
  94. timeZone,
  95. scanning,
  96. scanRange,
  97. width,
  98. hiddenLogLevels,
  99. isLive,
  100. } = this.props;
  101. if (isLive) {
  102. return (
  103. <Panel label="Logs" loading={false} isOpen>
  104. <LiveLogsWithTheme logsResult={logsResult} timeZone={timeZone} stopLive={this.onStopLive} />
  105. </Panel>
  106. );
  107. }
  108. return (
  109. <Panel label="Logs" loading={loading} isOpen>
  110. <Logs
  111. dedupStrategy={this.props.dedupStrategy || LogsDedupStrategy.none}
  112. data={logsResult}
  113. dedupedData={dedupedResult}
  114. exploreId={exploreId}
  115. highlighterExpressions={logsHighlighterExpressions}
  116. loading={loading}
  117. onChangeTime={this.onChangeTime}
  118. onClickLabel={onClickLabel}
  119. onStartScanning={onStartScanning}
  120. onStopScanning={onStopScanning}
  121. onDedupStrategyChange={this.handleDedupStrategyChange}
  122. onToggleLogLevel={this.hangleToggleLogLevel}
  123. absoluteRange={absoluteRange}
  124. timeZone={timeZone}
  125. scanning={scanning}
  126. scanRange={scanRange}
  127. width={width}
  128. hiddenLogLevels={hiddenLogLevels}
  129. getRowContext={this.getLogRowContext}
  130. />
  131. </Panel>
  132. );
  133. }
  134. }
  135. function mapStateToProps(state: StoreState, { exploreId }) {
  136. const explore = state.explore;
  137. const item: ExploreItemState = explore[exploreId];
  138. const {
  139. logsHighlighterExpressions,
  140. logsResult,
  141. loadingState,
  142. scanning,
  143. scanRange,
  144. datasourceInstance,
  145. isLive,
  146. absoluteRange,
  147. } = item;
  148. const loading = loadingState === LoadingState.Loading || loadingState === LoadingState.Streaming;
  149. const { dedupStrategy } = exploreItemUIStateSelector(item);
  150. const hiddenLogLevels = new Set(item.hiddenLogLevels);
  151. const dedupedResult = deduplicatedLogsSelector(item);
  152. const timeZone = getTimeZone(state.user);
  153. return {
  154. loading,
  155. logsHighlighterExpressions,
  156. logsResult,
  157. scanning,
  158. scanRange,
  159. timeZone,
  160. dedupStrategy,
  161. hiddenLogLevels,
  162. dedupedResult,
  163. datasourceInstance,
  164. isLive,
  165. absoluteRange,
  166. };
  167. }
  168. const mapDispatchToProps = {
  169. changeDedupStrategy,
  170. toggleLogLevelAction,
  171. stopLive: changeRefreshIntervalAction,
  172. updateTimeRange,
  173. };
  174. export default hot(module)(
  175. connect(
  176. mapStateToProps,
  177. mapDispatchToProps
  178. )(LogsContainer)
  179. );