121 lines
2.8 KiB
JavaScript
121 lines
2.8 KiB
JavaScript
//
|
|
// Copyright 2020 DxOS.org
|
|
//
|
|
|
|
import clsx from 'clsx';
|
|
import moment from 'moment';
|
|
import React, { Fragment } from 'react';
|
|
import { makeStyles } from '@material-ui/core/styles';
|
|
|
|
const useStyles = makeStyles(theme => ({
|
|
root: {
|
|
display: 'flex',
|
|
flex: 1,
|
|
flexDirection: 'column'
|
|
},
|
|
|
|
container: {
|
|
display: 'flex',
|
|
flex: 1,
|
|
overflowX: 'scroll',
|
|
overflowY: 'scroll'
|
|
},
|
|
|
|
log: {
|
|
padding: theme.spacing(1),
|
|
fontSize: 16,
|
|
// fontFamily: 'monospace',
|
|
whiteSpace: 'nowrap'
|
|
},
|
|
|
|
level: {
|
|
display: 'inline-block',
|
|
width: 48,
|
|
marginRight: 8,
|
|
color: theme.palette.grey[500]
|
|
},
|
|
level_warn: {
|
|
color: theme.palette.warning.main
|
|
},
|
|
level_error: {
|
|
color: theme.palette.error.main
|
|
},
|
|
|
|
ts: {
|
|
marginRight: 8,
|
|
color: theme.palette.primary[500]
|
|
}
|
|
}));
|
|
|
|
const Log = ({ log = [], onClear }) => {
|
|
const classes = useStyles();
|
|
|
|
const levels = {
|
|
'I': { label: 'INFO', className: classes.level_info },
|
|
'W': { label: 'WARN', className: classes.level_warn },
|
|
'E': { label: 'ERROR', className: classes.level_error }
|
|
};
|
|
|
|
// TODO(burdon): Parse in backend and normalize numbers.
|
|
const Line = ({ message }) => {
|
|
// https://regex101.com/
|
|
const patterns = [
|
|
{
|
|
// 2020-03-30T18:02:43.189Z bot-factory
|
|
pattern: /()(.+Z)\s+(.+)/,
|
|
transform: ([datetime]) => moment(datetime)
|
|
},
|
|
{
|
|
// I[2020-03-30|15:29:05.436] Executed block module=state height=11533 validTxs=0 invalidTxs=0
|
|
pattern: /(.)\[(.+)\|(.+)]\s+(.+)/,
|
|
transform: ([date, time]) => moment(`${date} ${time}`)
|
|
},
|
|
{
|
|
// [cors] 2020/03/30 15:28:53 Handler: Actual request
|
|
pattern: /\[(\w+)] (\S+) (\S+)\s+(.+)/,
|
|
transform: ([date, time]) => moment(`${date.replace(/\//g, '-')} ${time}`)
|
|
}
|
|
];
|
|
|
|
patterns.some(({ pattern, transform }) => {
|
|
const match = message.match(pattern);
|
|
if (match) {
|
|
const [, level = 'I', ...rest] = match;
|
|
const datetime = transform(rest).format('YYYY-MM-DD HH:mm:ss');
|
|
const text = match[match.length - 1];
|
|
|
|
const { label, className } = levels[level] || levels['I'];
|
|
const pkg = levels[level] ? '' : `[${level}]: `;
|
|
|
|
message = (
|
|
<Fragment>
|
|
<span className={classes.ts}>{datetime}</span>
|
|
<span className={clsx(classes.level, className)}>{label || level}</span>
|
|
<span>{pkg}{text}</span>
|
|
</Fragment>
|
|
);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
});
|
|
|
|
return (
|
|
<div>{message}</div>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<div className={classes.root}>
|
|
<div className={classes.container}>
|
|
<div className={classes.log}>
|
|
{log.reverse().map((line, i) => <Line key={i} message={line} />)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Log;
|