-
Notifications
You must be signed in to change notification settings - Fork 3.9k
/
Copy pathindex.tsx
136 lines (125 loc) · 4.21 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import _ from "lodash";
import React from "react";
import { Helmet } from "react-helmet";
import { RouterState } from "react-router";
import { connect } from "react-redux";
import * as protos from "src/js/protos";
import { NodeStatus$Properties } from "src/util/proto";
import { nodeIDAttr, REMOTE_DEBUGGING_ERROR_TEXT } from "src/util/constants";
import { LogEntriesResponseMessage } from "src/util/api";
import { LongToMoment } from "src/util/convert";
import { SortableTable } from "src/views/shared/components/sortabletable";
import { AdminUIState } from "src/redux/state";
import { refreshLogs, refreshNodes } from "src/redux/apiReducers";
import { currentNode } from "src/views/cluster/containers/nodeOverview";
import { CachedDataReducerState } from "src/redux/cachedDataReducer";
import { getDisplayName } from "src/redux/nodes";
import buildLoading from "src/views/shared/components/loading2";
import "./logs.styl";
interface LogProps {
logs: CachedDataReducerState<LogEntriesResponseMessage>;
currentNode: NodeStatus$Properties;
refreshLogs: typeof refreshLogs;
refreshNodes: typeof refreshNodes;
}
// tslint:disable-next-line:variable-name
const Loading = buildLoading<LogEntriesResponseMessage>();
/**
* Renders the main content of the logs page.
*/
class Logs extends React.Component<LogProps & RouterState, {}> {
componentWillMount() {
this.props.refreshNodes();
this.props.refreshLogs(new protos.cockroach.server.serverpb.LogsRequest({ node_id: this.props.params[nodeIDAttr] }));
}
renderContent (logs: LogEntriesResponseMessage) {
const logEntries = _.sortBy(logs.entries, (e) => e.time);
const columns = [
{
title: "Time",
cell: (index: number) => LongToMoment(logEntries[index].time).format("YYYY-MM-DD HH:mm:ss"),
},
{
title: "Severity",
cell: (index: number) => protos.cockroach.util.log.Severity[logEntries[index].severity],
},
{
title: "Message",
cell: (index: number) => (
<pre className="sort-table__unbounded-column logs-table__message">
{ logEntries[index].message }
</pre>
),
},
{
title: "File:Line",
cell: (index: number) => `${logEntries[index].file}:${logEntries[index].line}`,
},
];
return (
<SortableTable
count={logEntries.length}
columns={columns}
className="logs-table"
/>
);
}
render() {
const nodeAddress = this.props.currentNode
? this.props.currentNode.desc.address.address_field
: null;
const title = this.props.currentNode
? `Logs | ${getDisplayName(this.props.currentNode)} | Nodes`
: `Logs | Node ${this.props.params[nodeIDAttr]} | Nodes`;
// TODO(couchand): This is a really myopic way to check for this particular
// case, but making major changes to the CachedDataReducer or util.api seems
// fraught at this point. We should revisit this soon.
if (this.props.logs.lastError && this.props.logs.lastError.message === "Forbidden") {
return (
<div>
<Helmet>
<title>{ title }</title>
</Helmet>
<div className="section section--heading">
<h2>Logs Node { this.props.params[nodeIDAttr] } / { nodeAddress }</h2>
</div>
<section className="section">
{ REMOTE_DEBUGGING_ERROR_TEXT }
</section>
</div>
);
}
return (
<div>
<Helmet>
<title>{ title }</title>
</Helmet>
<div className="section section--heading">
<h2>Logs Node { this.props.params[nodeIDAttr] } / { nodeAddress }</h2>
</div>
<section className="section">
<Loading
data={ this.props.logs }
className="loading-image loading-image__spinner-left"
>
{ this.renderContent }
</Loading>
</section>
</div>
);
}
}
// Connect the EventsList class with our redux store.
const logsConnected = connect(
(state: AdminUIState, ownProps: RouterState) => {
return {
logs: state.cachedData.logs,
currentNode: currentNode(state, ownProps),
};
},
{
refreshLogs,
refreshNodes,
},
)(Logs);
export default logsConnected;