Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd, dashboard, internal, log, node: logging feature #17097

Merged
merged 5 commits into from
Jul 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,15 @@ func init() {

app.Before = func(ctx *cli.Context) error {
runtime.GOMAXPROCS(runtime.NumCPU())
if err := debug.Setup(ctx); err != nil {

logdir := ""
if ctx.GlobalBool(utils.DashboardEnabledFlag.Name) {
logdir = (&node.Config{DataDir: utils.MakeDataDir(ctx)}).ResolvePath("logs")
}
if err := debug.Setup(ctx, logdir); err != nil {
return err
}
// Cap the cache allowance and tune the garbage colelctor
// Cap the cache allowance and tune the garbage collector
var mem gosigar.Mem
if err := mem.Get(); err == nil {
allowance := int(mem.Total / 1024 / 1024 / 3)
Expand Down
2 changes: 1 addition & 1 deletion cmd/swarm/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ pv(1) tool to get a progress bar:
app.Flags = append(app.Flags, swarmmetrics.Flags...)
app.Before = func(ctx *cli.Context) error {
runtime.GOMAXPROCS(runtime.NumCPU())
if err := debug.Setup(ctx); err != nil {
if err := debug.Setup(ctx, ""); err != nil {
return err
}
swarmmetrics.Setup(ctx)
Expand Down
4 changes: 2 additions & 2 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ var (
}
// Dashboard settings
DashboardEnabledFlag = cli.BoolFlag{
Name: "dashboard",
Name: metrics.DashboardEnabledFlag,
Usage: "Enable the dashboard",
}
DashboardAddrFlag = cli.StringFlag{
Expand Down Expand Up @@ -1185,7 +1185,7 @@ func RegisterEthService(stack *node.Node, cfg *eth.Config) {
// RegisterDashboardService adds a dashboard to the stack.
func RegisterDashboardService(stack *node.Node, cfg *dashboard.Config, commit string) {
stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
return dashboard.New(cfg, commit)
return dashboard.New(cfg, commit, ctx.ResolvePath("logs")), nil
})
}

Expand Down
17,652 changes: 9,898 additions & 7,754 deletions dashboard/assets.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dashboard/assets/common.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@ export const styles = {
light: {
color: 'rgba(255, 255, 255, 0.54)',
},
}
};
10 changes: 6 additions & 4 deletions dashboard/assets/components/Body.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ const styles = {
};

export type Props = {
opened: boolean,
opened: boolean,
changeContent: string => void,
active: string,
content: Content,
shouldUpdate: Object,
active: string,
content: Content,
shouldUpdate: Object,
send: string => void,
};

// Body renders the body of the dashboard.
Expand All @@ -52,6 +53,7 @@ class Body extends Component<Props> {
active={this.props.active}
content={this.props.content}
shouldUpdate={this.props.shouldUpdate}
send={this.props.send}
/>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion dashboard/assets/components/CustomTooltip.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export type Props = {
class CustomTooltip extends Component<Props> {
render() {
const {active, payload, tooltip} = this.props;
if (!active || typeof tooltip !== 'function') {
if (!active || typeof tooltip !== 'function' || !Array.isArray(payload) || payload.length < 1) {
return null;
}
return tooltip(payload[0].value);
Expand Down
45 changes: 31 additions & 14 deletions dashboard/assets/components/Dashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import Header from './Header';
import Body from './Body';
import {MENU} from '../common';
import type {Content} from '../types/content';
import {inserter as logInserter} from './Logs';

// deepUpdate updates an object corresponding to the given update data, which has
// the shape of the same structure as the original object. updater also has the same
Expand Down Expand Up @@ -75,8 +76,11 @@ const appender = <T>(limit: number, mapper = replacer) => (update: Array<T>, pre
...update.map(sample => mapper(sample)),
].slice(-limit);

// defaultContent is the initial value of the state content.
const defaultContent: Content = {
// defaultContent returns the initial value of the state content. Needs to be a function in order to
// instantiate the object again, because it is used by the state, and isn't automatically cleaned
// when a new connection is established. The state is mutated during the update in order to avoid
// the execution of unnecessary operations (e.g. copy of the log array).
const defaultContent: () => Content = () => ({
general: {
version: null,
commit: null,
Expand All @@ -95,10 +99,14 @@ const defaultContent: Content = {
diskRead: [],
diskWrite: [],
},
logs: {
log: [],
logs: {
chunks: [],
endTop: false,
endBottom: true,
topChanged: 0,
bottomChanged: 0,
},
};
});

// updaters contains the state updater functions for each path of the state.
//
Expand All @@ -122,9 +130,7 @@ const updaters = {
diskRead: appender(200),
diskWrite: appender(200),
},
logs: {
log: appender(200),
},
logs: logInserter(5),
};

// styles contains the constant styles of the component.
Expand All @@ -151,10 +157,11 @@ export type Props = {
};

type State = {
active: string, // active menu
sideBar: boolean, // true if the sidebar is opened
content: Content, // the visualized data
shouldUpdate: Object, // labels for the components, which need to re-render based on the incoming message
active: string, // active menu
sideBar: boolean, // true if the sidebar is opened
content: Content, // the visualized data
shouldUpdate: Object, // labels for the components, which need to re-render based on the incoming message
server: ?WebSocket,
};

// Dashboard is the main component, which renders the whole page, makes connection with the server and
Expand All @@ -165,8 +172,9 @@ class Dashboard extends Component<Props, State> {
this.state = {
active: MENU.get('home').id,
sideBar: true,
content: defaultContent,
content: defaultContent(),
shouldUpdate: {},
server: null,
};
}

Expand All @@ -181,7 +189,7 @@ class Dashboard extends Component<Props, State> {
// PROD is defined by webpack.
const server = new WebSocket(`${((window.location.protocol === 'https:') ? 'wss://' : 'ws://')}${PROD ? window.location.host : 'localhost:8080'}/api`);
server.onopen = () => {
this.setState({content: defaultContent, shouldUpdate: {}});
this.setState({content: defaultContent(), shouldUpdate: {}, server});
};
server.onmessage = (event) => {
const msg: $Shape<Content> = JSON.parse(event.data);
Expand All @@ -192,10 +200,18 @@ class Dashboard extends Component<Props, State> {
this.update(msg);
};
server.onclose = () => {
this.setState({server: null});
setTimeout(this.reconnect, 3000);
};
};

// send sends a message to the server, which can be accessed only through this function for safety reasons.
send = (msg: string) => {
if (this.state.server != null) {
this.state.server.send(msg);
}
};

// update updates the content corresponding to the incoming message.
update = (msg: $Shape<Content>) => {
this.setState(prevState => ({
Expand Down Expand Up @@ -226,6 +242,7 @@ class Dashboard extends Component<Props, State> {
active={this.state.active}
content={this.state.content}
shouldUpdate={this.state.shouldUpdate}
send={this.send}
/>
</div>
);
Expand Down
Loading