diff --git a/packages/grafana-ui/src/types/logs.ts b/packages/grafana-ui/src/types/logs.ts index 3d8cc0951b8..c0b295c55aa 100644 --- a/packages/grafana-ui/src/types/logs.ts +++ b/packages/grafana-ui/src/types/logs.ts @@ -46,6 +46,7 @@ export interface LogRowModel { timeFromNow: string; timeEpochMs: number; timeLocal: string; + timeUtc: string; uniqueLabels?: Labels; } diff --git a/public/app/core/logs_model.ts b/public/app/core/logs_model.ts index 5fe95a182d0..3bfa704f546 100644 --- a/public/app/core/logs_model.ts +++ b/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, diff --git a/public/app/features/explore/LiveLogs.tsx b/public/app/features/explore/LiveLogs.tsx index 073eff5ec92..c06fc0cf99b 100644 --- a/public/app/features/explore/LiveLogs.tsx +++ b/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 { } 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 { className={row.fresh ? cx(['logs-row', styles.logsRowFresh]) : cx(['logs-row', styles.logsRowOld])} key={`${row.timeEpochMs}-${index}`} > -
- {row.timeLocal} -
+ {showUtc && ( +
+ {row.timeUtc} +
+ )} + {!showUtc && ( +
+ {row.timeLocal} +
+ )}
{row.entry}
); diff --git a/public/app/features/explore/LogRow.tsx b/public/app/features/explore/LogRow.tsx index e626782f1de..e1bdaa09b07 100644 --- a/public/app/features/explore/LogRow.tsx +++ b/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 { row, showDuplicates, showLabels, - showLocalTime, - showUtc, + timeZone, + showTime, } = this.props; const { fieldCount, @@ -229,6 +230,7 @@ export class LogRow extends PureComponent { const highlightClassName = classnames('logs-row__match-highlight', { 'logs-row__match-highlight--preview': previewHighlights, }); + const showUtc = timeZone === 'utc'; return ( @@ -242,13 +244,13 @@ export class LogRow extends PureComponent {
{row.duplicates > 0 ? `${row.duplicates + 1}x` : null}
)}
- {showUtc && ( -
- {row.timestamp} + {showTime && showUtc && ( +
+ {row.timeUtc}
)} - {showLocalTime && ( -
+ {showTime && !showUtc && ( +
{row.timeLocal}
)} diff --git a/public/app/features/explore/Logs.tsx b/public/app/features/explore/Logs.tsx index 201eda44ece..1d6d6460ff8 100644 --- a/public/app/features/explore/Logs.tsx +++ b/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 { @@ -88,8 +87,7 @@ export default class Logs extends PureComponent { deferLogs: true, renderAll: false, showLabels: false, - showLocalTime: true, - showUtc: false, + showTime: true, }; componentDidMount() { @@ -130,17 +128,10 @@ export default class Logs extends PureComponent { }); }; - 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 { 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 {
- - + {Object.keys(LogsDedupStrategy).map((dedupType, i) => ( @@ -265,8 +255,8 @@ export default class Logs extends PureComponent { 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 { row={row} showDuplicates={showDuplicates} showLabels={showLabels && hasLabel} - showLocalTime={showLocalTime} - showUtc={showUtc} + showTime={showTime} + timeZone={timeZone} onClickLabel={onClickLabel} /> ))} diff --git a/public/app/features/explore/LogsContainer.tsx b/public/app/features/explore/LogsContainer.tsx index 88639aa6864..93fb547eb87 100644 --- a/public/app/features/explore/LogsContainer.tsx +++ b/public/app/features/explore/LogsContainer.tsx @@ -116,7 +116,7 @@ export class LogsContainer extends Component { if (isLive) { return ( - + ); } diff --git a/public/app/features/explore/utils/ResultProcessor.test.ts b/public/app/features/explore/utils/ResultProcessor.test.ts index 4420450c221..50b1bd5cecf 100644 --- a/public/app/features/explore/utils/ResultProcessor.test.ts +++ b/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: {}, }, diff --git a/public/sass/components/_panel_logs.scss b/public/sass/components/_panel_logs.scss index b0156ce9cee..62e9850b7c0 100644 --- a/public/sass/components/_panel_logs.scss +++ b/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;