Merge pull request #11836 from influxdata/feat/view-logs-tasks

Add the ability to view logs for a specific task run
pull/11852/head
Palakp41 2019-02-12 18:55:11 -08:00 committed by GitHub
commit 2fca416bf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 236 additions and 42 deletions

View File

@ -5,6 +5,7 @@
1. [11821](https://github.com/influxdata/influxdb/pull/11821): Display scraper name as the first and only updatable column in scrapers list
1. [11804](https://github.com/influxdata/influxdb/pull/11804): Add the ability to view runs for a task
1. [11824](https://github.com/influxdata/influxdb/pull/11824): Display last completed run for tasks list
1. [11836](https://github.com/influxdata/influxdb/pull/11836): Add the ability to view the logs for a specific task run
### Bug Fixes
1. [11819](https://github.com/influxdata/influxdb/pull/11819): Update the inline edit for resource names to guard for empty strings

View File

@ -0,0 +1,64 @@
import React, {PureComponent} from 'react'
import _ from 'lodash'
import Container from 'src/clockface/components/overlays/OverlayContainer'
import Heading from 'src/clockface/components/overlays/OverlayHeading'
import Body from 'src/clockface/components/overlays/OverlayBody'
// DummyData
import {runLogs} from 'src/tasks/dummyData'
import {IndexList} from 'src/clockface'
interface Props {
onDismissOverlay: () => void
taskID: string
runID: string
}
class RunLogsOverlay extends PureComponent<Props> {
constructor(props: Props) {
super(props)
}
public render() {
const {onDismissOverlay} = this.props
return (
<Container maxWidth={800}>
<Heading title="Run Logs" onDismiss={onDismissOverlay} />
<Body>
<IndexList>
<IndexList.Header>
<IndexList.HeaderCell columnName="Time" width="50%" />
<IndexList.HeaderCell columnName="Message" width="50%" />
</IndexList.Header>
<IndexList.Body emptyState={<></>} columnCount={2}>
{this.listLogs}
</IndexList.Body>
</IndexList>
</Body>
</Container>
)
}
public get listLogs(): JSX.Element[] {
const logs = runLogs.events.map(rl => (
<IndexList.Row key={rl.message}>
<IndexList.Cell>{this.dateTimeString(rl.time)}</IndexList.Cell>
<IndexList.Cell>{rl.message}</IndexList.Cell>
</IndexList.Row>
))
return logs
}
private dateTimeString(dt: Date): string {
const date = dt.toDateString()
const time = dt.toLocaleTimeString()
const formatted = `${date} ${time}`
return formatted
}
}
export default RunLogsOverlay

View File

@ -0,0 +1,41 @@
// Libraries
import React, {PureComponent} from 'react'
// Components
import {Run} from '@influxdata/influx'
import {IndexList} from 'src/clockface'
import TaskRunsRow from './TaskRunsRow'
interface Props {
taskID: string
runs: Run[]
}
export default class TaskRunsList extends PureComponent<Props> {
public render() {
return (
<IndexList>
<IndexList.Header>
<IndexList.HeaderCell columnName="Requested At" width="20%" />
<IndexList.HeaderCell columnName="Started At" width="20%" />
<IndexList.HeaderCell columnName="Finished At" width="20%" />
<IndexList.HeaderCell columnName="Status" width="10%" />
<IndexList.HeaderCell columnName="Schedule For" width="20%" />
<IndexList.HeaderCell columnName="" width="10%" />
</IndexList.Header>
<IndexList.Body emptyState={<></>} columnCount={6}>
{this.listRuns}
</IndexList.Body>
</IndexList>
)
}
public get listRuns(): JSX.Element[] {
const {runs, taskID} = this.props
const taskRuns = runs.map(t => (
<TaskRunsRow key={t.id} taskID={taskID} run={t} />
))
return taskRuns
}
}

View File

@ -1,21 +1,25 @@
// Libraries
import React, {PureComponent} from 'react'
import {withRouter, WithRouterProps} from 'react-router'
// Types
import {Run} from '@influxdata/influx'
import {IndexList} from 'src/clockface'
import {taskRuns} from '../dummyData'
import {Page} from 'src/pageLayout'
import TaskRunsList from 'src/tasks/components/TaskRunsList'
// DummyData
import {taskRuns} from 'src/tasks/dummyData'
interface Props {
taskID: string
params: {id: string}
runs: Run[]
}
const dummyData = taskRuns
class TaskRunsPage extends PureComponent<Props> {
class TaskRunsPage extends PureComponent<Props & WithRouterProps> {
public render() {
const {params} = this.props
return (
<>
<Page titleTag="Runs">
@ -27,47 +31,13 @@ class TaskRunsPage extends PureComponent<Props> {
</Page.Header>
<Page.Contents fullWidth={false} scrollable={true}>
<div className="col-xs-12">
<IndexList>
<IndexList.Header>
<IndexList.HeaderCell columnName="Requested At" width="20%" />
<IndexList.HeaderCell columnName="Started At" width="20%" />
<IndexList.HeaderCell columnName="Finished At" width="20%" />
<IndexList.HeaderCell columnName="Status" width="10%" />
<IndexList.HeaderCell columnName="Schedule For" width="20%" />
<IndexList.HeaderCell columnName="" width="10%" />
</IndexList.Header>
<IndexList.Body emptyState={<></>} columnCount={6}>
{this.listRuns}
</IndexList.Body>
</IndexList>
<TaskRunsList taskID={params.id} runs={dummyData} />
</div>
</Page.Contents>
</Page>
</>
)
}
public get listRuns(): JSX.Element[] {
const taskRuns = dummyData.map(t => (
<IndexList.Row key={`task-id--${t.id}`}>
<IndexList.Cell>{this.dateTimeString(t.requestedAt)}</IndexList.Cell>
<IndexList.Cell>{this.dateTimeString(t.startedAt)}</IndexList.Cell>
<IndexList.Cell>{this.dateTimeString(t.finishedAt)}</IndexList.Cell>
<IndexList.Cell>{t.status}</IndexList.Cell>
<IndexList.Cell>{this.dateTimeString(t.scheduledFor)}</IndexList.Cell>
<IndexList.Cell />
</IndexList.Row>
))
return taskRuns
}
private dateTimeString(dt: Date): string {
const date = dt.toDateString()
const time = dt.toLocaleTimeString()
const formatted = `${date} ${time}`
return formatted
}
}
export default TaskRunsPage
export default withRouter<Props>(TaskRunsPage)

View File

@ -0,0 +1,89 @@
// Libraries
import React, {PureComponent} from 'react'
// Components
import {Run} from '@influxdata/influx'
import {
IndexList,
ComponentSize,
ComponentColor,
OverlayTechnology,
} from 'src/clockface'
import {Button} from '@influxdata/clockface'
import RunLogsOverlay from './RunLogsOverlay'
interface Props {
taskID: string
run: Run
}
interface State {
isImportOverlayVisible: boolean
}
export default class TaskRunsRow extends PureComponent<Props, State> {
constructor(props: Props) {
super(props)
this.state = {
isImportOverlayVisible: false,
}
}
public render() {
const {run} = this.props
return (
<>
<IndexList.Row>
<IndexList.Cell>
{this.dateTimeString(run.requestedAt)}
</IndexList.Cell>
<IndexList.Cell>{this.dateTimeString(run.startedAt)}</IndexList.Cell>
<IndexList.Cell>{this.dateTimeString(run.finishedAt)}</IndexList.Cell>
<IndexList.Cell>{run.status}</IndexList.Cell>
<IndexList.Cell>
{this.dateTimeString(run.scheduledFor)}
</IndexList.Cell>
<IndexList.Cell>
<Button
key={run.id}
size={ComponentSize.ExtraSmall}
color={ComponentColor.Default}
text="View Logs"
onClick={this.handleToggleOverlay}
/>
</IndexList.Cell>
</IndexList.Row>
{this.renderLogOverlay}
</>
)
}
private dateTimeString(dt: Date): string {
const date = dt.toDateString()
const time = dt.toLocaleTimeString()
const formatted = `${date} ${time}`
return formatted
}
private handleToggleOverlay = () => {
this.setState({isImportOverlayVisible: !this.state.isImportOverlayVisible})
}
private get renderLogOverlay(): JSX.Element {
const {isImportOverlayVisible} = this.state
const {taskID, run} = this.props
return (
<OverlayTechnology visible={isImportOverlayVisible}>
<RunLogsOverlay
onDismissOverlay={this.handleToggleOverlay}
taskID={taskID}
runID={run.id}
/>
</OverlayTechnology>
)
}
}

View File

@ -17,6 +17,7 @@ interface Task extends TaskAPI {
organization: Organization
owner?: User
}
import {Sort} from 'src/clockface'
import {addTaskLabelsAsync, removeTaskLabelsAsync} from 'src/tasks/actions/v2'

View File

@ -1,4 +1,4 @@
import {Run} from '@influxdata/influx'
import {Run, Logs} from '@influxdata/influx'
export const taskRuns: Run[] = [
{
@ -16,4 +16,32 @@ export const taskRuns: Run[] = [
logs: '/api/v2/tasks/1/runs/1/logs',
},
},
{
id: '40002342',
taskID: 'string',
status: Run.StatusEnum.Scheduled,
scheduledFor: new Date('2019-02-11T22:37:25.985Z'),
startedAt: new Date('2019-02-11T22:37:25.985Z'),
finishedAt: new Date('2019-02-11T22:37:25.985Z'),
requestedAt: new Date('2019-02-11T22:37:25.985Z'),
links: {
self: '/api/v2/tasks/1/runs/1',
task: '/arequei/v2/tasks/1',
retry: '/api/v2/tasks/1/runs/1/retry',
logs: '/api/v2/tasks/1/runs/1/logs',
},
},
]
export const runLogs: Logs = {
events: [
{
time: new Date('2019-02-12T22:00:09.572Z'),
message: 'Halt and catch fire',
},
{
time: new Date('2019-02-12T22:00:09.572Z'),
message: 'Catch fire and Halt',
},
],
}