Browse Source

Explore: Displays only one Time column as configured in TimeZone settings (#17775)

* Refactor: Removes switches for TimeStamp and LocalTime and displays time as configured for user

* Styles: Updates classname used to display timeUtc

* Refactor: Adds switch for Time column
Hugo Häggmark 6 years ago
parent
commit
7cac7435ce

+ 1 - 0
packages/grafana-ui/src/types/logs.ts

@@ -46,6 +46,7 @@ export interface LogRowModel {
   timeFromNow: string;
   timeEpochMs: number;
   timeLocal: string;
+  timeUtc: string;
   uniqueLabels?: Labels;
 }
 

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

@@ -24,7 +24,7 @@ import {
 } from '@grafana/ui';
 import { getThemeColor } from 'app/core/utils/colors';
 import { hasAnsiCodes } from 'app/core/utils/text';
-import { dateTime } from '@grafana/ui/src/utils/moment_wrapper';
+import { dateTime, toUtc } from '@grafana/ui/src/utils/moment_wrapper';
 
 export const LogLevelColor = {
   [LogLevel.critical]: colors[7],
@@ -369,6 +369,7 @@ export function processLogSeriesRow(
   const timeEpochMs = time.valueOf();
   const timeFromNow = time.fromNow();
   const timeLocal = time.format('YYYY-MM-DD HH:mm:ss');
+  const timeUtc = toUtc(ts).format('YYYY-MM-DD HH:mm:ss');
 
   let logLevel = LogLevel.unknown;
   const logLevelField = fieldCache.getFieldByName('level');
@@ -388,6 +389,7 @@ export function processLogSeriesRow(
     timeFromNow,
     timeEpochMs,
     timeLocal,
+    timeUtc,
     uniqueLabels,
     hasAnsi,
     searchWords,

+ 14 - 4
public/app/features/explore/LiveLogs.tsx

@@ -8,6 +8,7 @@ import {
   LinkButton,
   LogsModel,
   LogRowModel,
+  TimeZone,
 } from '@grafana/ui';
 
 import ElapsedTime from './ElapsedTime';
@@ -42,6 +43,7 @@ const getStyles = (theme: GrafanaTheme) => ({
 
 export interface Props extends Themeable {
   logsResult?: LogsModel;
+  timeZone: TimeZone;
   stopLive: () => void;
 }
 
@@ -73,10 +75,11 @@ class LiveLogs extends PureComponent<Props, State> {
   }
 
   render() {
-    const { theme } = this.props;
+    const { theme, timeZone } = this.props;
     const { renderCount } = this.state;
     const styles = getStyles(theme);
     const rowsToRender: LogRowModel[] = this.props.logsResult ? this.props.logsResult.rows : [];
+    const showUtc = timeZone === 'utc';
 
     return (
       <>
@@ -87,9 +90,16 @@ class LiveLogs extends PureComponent<Props, State> {
                 className={row.fresh ? cx(['logs-row', styles.logsRowFresh]) : cx(['logs-row', styles.logsRowOld])}
                 key={`${row.timeEpochMs}-${index}`}
               >
-                <div className="logs-row__localtime" title={`${row.timestamp} (${row.timeFromNow})`}>
-                  {row.timeLocal}
-                </div>
+                {showUtc && (
+                  <div className="logs-row__localtime" title={`Local: ${row.timeLocal} (${row.timeFromNow})`}>
+                    {row.timeUtc}
+                  </div>
+                )}
+                {!showUtc && (
+                  <div className="logs-row__localtime" title={`${row.timeUtc} (${row.timeFromNow})`}>
+                    {row.timeLocal}
+                  </div>
+                )}
                 <div className="logs-row__message">{row.entry}</div>
               </div>
             );

+ 11 - 9
public/app/features/explore/LogRow.tsx

@@ -23,6 +23,7 @@ import {
   LogRowModel,
   LogLabelStatsModel,
   LogsParser,
+  TimeZone,
 } from '@grafana/ui';
 import { LogRowContext } from './LogRowContext';
 import tinycolor from 'tinycolor2';
@@ -32,8 +33,8 @@ interface Props {
   row: LogRowModel;
   showDuplicates: boolean;
   showLabels: boolean;
-  showLocalTime: boolean;
-  showUtc: boolean;
+  showTime: boolean;
+  timeZone: TimeZone;
   getRows: () => LogRowModel[];
   onClickLabel?: (label: string, value: string) => void;
   onContextClick?: () => void;
@@ -209,8 +210,8 @@ export class LogRow extends PureComponent<Props, State> {
       row,
       showDuplicates,
       showLabels,
-      showLocalTime,
-      showUtc,
+      timeZone,
+      showTime,
     } = this.props;
     const {
       fieldCount,
@@ -229,6 +230,7 @@ export class LogRow extends PureComponent<Props, State> {
     const highlightClassName = classnames('logs-row__match-highlight', {
       'logs-row__match-highlight--preview': previewHighlights,
     });
+    const showUtc = timeZone === 'utc';
 
     return (
       <ThemeContext.Consumer>
@@ -242,13 +244,13 @@ export class LogRow extends PureComponent<Props, State> {
                 <div className="logs-row__duplicates">{row.duplicates > 0 ? `${row.duplicates + 1}x` : null}</div>
               )}
               <div className={row.logLevel ? `logs-row__level logs-row__level--${row.logLevel}` : ''} />
-              {showUtc && (
-                <div className="logs-row__time" title={`Local: ${row.timeLocal} (${row.timeFromNow})`}>
-                  {row.timestamp}
+              {showTime && showUtc && (
+                <div className="logs-row__localtime" title={`Local: ${row.timeLocal} (${row.timeFromNow})`}>
+                  {row.timeUtc}
                 </div>
               )}
-              {showLocalTime && (
-                <div className="logs-row__localtime" title={`${row.timestamp} (${row.timeFromNow})`}>
+              {showTime && !showUtc && (
+                <div className="logs-row__localtime" title={`${row.timeUtc} (${row.timeFromNow})`}>
                   {row.timeLocal}
                 </div>
               )}

+ 10 - 20
public/app/features/explore/Logs.tsx

@@ -76,8 +76,7 @@ interface State {
   deferLogs: boolean;
   renderAll: boolean;
   showLabels: boolean;
-  showLocalTime: boolean;
-  showUtc: boolean;
+  showTime: boolean;
 }
 
 export default class Logs extends PureComponent<Props, State> {
@@ -88,8 +87,7 @@ export default class Logs extends PureComponent<Props, State> {
     deferLogs: true,
     renderAll: false,
     showLabels: false,
-    showLocalTime: true,
-    showUtc: false,
+    showTime: true,
   };
 
   componentDidMount() {
@@ -130,17 +128,10 @@ export default class Logs extends PureComponent<Props, State> {
     });
   };
 
-  onChangeLocalTime = (event: React.SyntheticEvent) => {
+  onChangeTime = (event: React.SyntheticEvent) => {
     const target = event.target as HTMLInputElement;
     this.setState({
-      showLocalTime: target.checked,
-    });
-  };
-
-  onChangeUtc = (event: React.SyntheticEvent) => {
-    const target = event.target as HTMLInputElement;
-    this.setState({
-      showUtc: target.checked,
+      showTime: target.checked,
     });
   };
 
@@ -178,7 +169,7 @@ export default class Logs extends PureComponent<Props, State> {
       return null;
     }
 
-    const { deferLogs, renderAll, showLabels, showLocalTime, showUtc } = this.state;
+    const { deferLogs, renderAll, showLabels, showTime } = this.state;
     const { dedupStrategy } = this.props;
     const hasData = data && data.rows && data.rows.length > 0;
     const hasLabel = hasData && dedupedData.hasUniqueLabels;
@@ -223,8 +214,7 @@ export default class Logs extends PureComponent<Props, State> {
         </div>
         <div className="logs-panel-options">
           <div className="logs-panel-controls">
-            <Switch label="Timestamp" checked={showUtc} onChange={this.onChangeUtc} transparent />
-            <Switch label="Local time" checked={showLocalTime} onChange={this.onChangeLocalTime} transparent />
+            <Switch label="Time" checked={showTime} onChange={this.onChangeTime} transparent />
             <Switch label="Labels" checked={showLabels} onChange={this.onChangeLabels} transparent />
             <ToggleButtonGroup label="Dedup" transparent={true}>
               {Object.keys(LogsDedupStrategy).map((dedupType, i) => (
@@ -265,8 +255,8 @@ export default class Logs extends PureComponent<Props, State> {
                 row={row}
                 showDuplicates={showDuplicates}
                 showLabels={showLabels && hasLabel}
-                showLocalTime={showLocalTime}
-                showUtc={showUtc}
+                showTime={showTime}
+                timeZone={timeZone}
                 onClickLabel={onClickLabel}
               />
             ))}
@@ -281,8 +271,8 @@ export default class Logs extends PureComponent<Props, State> {
                 row={row}
                 showDuplicates={showDuplicates}
                 showLabels={showLabels && hasLabel}
-                showLocalTime={showLocalTime}
-                showUtc={showUtc}
+                showTime={showTime}
+                timeZone={timeZone}
                 onClickLabel={onClickLabel}
               />
             ))}

+ 1 - 1
public/app/features/explore/LogsContainer.tsx

@@ -116,7 +116,7 @@ export class LogsContainer extends Component<LogsContainerProps> {
     if (isLive) {
       return (
         <Panel label="Logs" loading={false} isOpen>
-          <LiveLogsWithTheme logsResult={logsResult} stopLive={this.onStopLive} />
+          <LiveLogsWithTheme logsResult={logsResult} timeZone={timeZone} stopLive={this.onStopLive} />
         </Panel>
       );
     }

+ 13 - 0
public/app/features/explore/utils/ResultProcessor.test.ts

@@ -6,6 +6,11 @@ jest.mock('@grafana/ui/src/utils/moment_wrapper', () => ({
       format: (fmt: string) => 'format() jest mocked',
     };
   },
+  toUtc: (ts: any) => {
+    return {
+      format: (fmt: string) => 'format() jest mocked',
+    };
+  },
 }));
 
 import { ResultProcessor } from './ResultProcessor';
@@ -178,6 +183,7 @@ describe('ResultProcessor', () => {
               timeEpochMs: 1559038519831,
               timeFromNow: 'fromNow() jest mocked',
               timeLocal: 'format() jest mocked',
+              timeUtc: 'format() jest mocked',
               timestamp: 1559038519831,
               uniqueLabels: {},
             },
@@ -191,6 +197,7 @@ describe('ResultProcessor', () => {
               timeEpochMs: 1559038518831,
               timeFromNow: 'fromNow() jest mocked',
               timeLocal: 'format() jest mocked',
+              timeUtc: 'format() jest mocked',
               timestamp: 1559038518831,
               uniqueLabels: {},
             },
@@ -321,6 +328,7 @@ describe('ResultProcessor', () => {
                 timeEpochMs: 1558038519831,
                 timeFromNow: 'fromNow() jest mocked',
                 timeLocal: 'format() jest mocked',
+                timeUtc: 'format() jest mocked',
                 timestamp: 1558038519831,
                 uniqueLabels: {},
               },
@@ -335,6 +343,7 @@ describe('ResultProcessor', () => {
                 timeEpochMs: 1558038518831,
                 timeFromNow: 'fromNow() jest mocked',
                 timeLocal: 'format() jest mocked',
+                timeUtc: 'format() jest mocked',
                 timestamp: 1558038518831,
                 uniqueLabels: {},
               },
@@ -375,6 +384,7 @@ describe('ResultProcessor', () => {
               timeEpochMs: 1558038519831,
               timeFromNow: 'fromNow() jest mocked',
               timeLocal: 'format() jest mocked',
+              timeUtc: 'format() jest mocked',
               timestamp: 1558038519831,
               uniqueLabels: {},
             },
@@ -389,6 +399,7 @@ describe('ResultProcessor', () => {
               timeEpochMs: 1558038518831,
               timeFromNow: 'fromNow() jest mocked',
               timeLocal: 'format() jest mocked',
+              timeUtc: 'format() jest mocked',
               timestamp: 1558038518831,
               uniqueLabels: {},
             },
@@ -403,6 +414,7 @@ describe('ResultProcessor', () => {
               timeEpochMs: 1559038519831,
               timeFromNow: 'fromNow() jest mocked',
               timeLocal: 'format() jest mocked',
+              timeUtc: 'format() jest mocked',
               timestamp: 1559038519831,
               uniqueLabels: {},
             },
@@ -417,6 +429,7 @@ describe('ResultProcessor', () => {
               timeEpochMs: 1559038518831,
               timeFromNow: 'fromNow() jest mocked',
               timeLocal: 'format() jest mocked',
+              timeUtc: 'format() jest mocked',
               timestamp: 1559038518831,
               uniqueLabels: {},
             },

+ 0 - 5
public/sass/components/_panel_logs.scss

@@ -81,11 +81,6 @@ $column-horizontal-spacing: 10px;
   }
 }
 
-.logs-row__time {
-  white-space: nowrap;
-  width: 19em;
-}
-
 .logs-row__localtime {
   white-space: nowrap;
   width: 12.5em;