diff --git a/interface/src/api/Env.ts b/interface/src/api/Env.ts index 3bfef1d74..16d361cf3 100644 --- a/interface/src/api/Env.ts +++ b/interface/src/api/Env.ts @@ -4,6 +4,7 @@ export const PROJECT_PATH = process.env.REACT_APP_PROJECT_PATH!; export const ENDPOINT_ROOT = calculateEndpointRoot('/rest/'); export const WEB_SOCKET_ROOT = calculateWebSocketRoot('/ws/'); export const EVENT_SOURCE_ROOT = calculateEndpointRoot('/es/'); +export const API_ENDPOINT_ROOT = calculateEndpointRoot('/api/'); function calculateEndpointRoot(endpointPath: string) { const httpRoot = process.env.REACT_APP_HTTP_ROOT; diff --git a/interface/src/system/LogEventController.tsx b/interface/src/system/LogEventController.tsx index f34fed1c2..fff3f9478 100644 --- a/interface/src/system/LogEventController.tsx +++ b/interface/src/system/LogEventController.tsx @@ -12,21 +12,29 @@ import { SelectValidator } from 'react-material-ui-form-validator'; -import { Grid, Slider, FormLabel, Checkbox, MenuItem } from '@material-ui/core'; +import { + Grid, + Slider, + FormLabel, + Checkbox, + MenuItem, + Button +} from '@material-ui/core'; import { addAccessTokenParameter, redirectingAuthorizedFetch } from '../authentication'; +import DownloadIcon from '@material-ui/icons/GetApp'; + import { ENDPOINT_ROOT, EVENT_SOURCE_ROOT } from '../api'; export const FETCH_LOG_ENDPOINT = ENDPOINT_ROOT + 'fetchLog'; export const LOG_SETTINGS_ENDPOINT = ENDPOINT_ROOT + 'logSettings'; export const LOG_EVENT_EVENT_SOURCE_URL = EVENT_SOURCE_ROOT + 'log'; import LogEventConsole from './LogEventConsole'; - -import { LogEvent, LogSettings } from './types'; +import { LogEvent, LogSettings, LogLevel } from './types'; import { Decoder } from '@msgpack/msgpack'; const decoder = new Decoder(); @@ -185,6 +193,54 @@ class LogEventController extends Component< }); }; + levelLabel = (level: LogLevel) => { + switch (level) { + case LogLevel.ERROR: + return 'E'; + case LogLevel.WARNING: + return 'W'; + case LogLevel.NOTICE: + return 'N'; + case LogLevel.INFO: + return 'I'; + case LogLevel.DEBUG: + return 'D'; + case LogLevel.TRACE: + return 'TRACE'; + default: + return ''; + } + }; + + onDownload = () => { + const { events, level } = this.state; + let result = ''; + for (const i in events) { + if (events[i].l <= level) { + result += + events[i].t + + ' ' + + this.levelLabel(events[i].l) + + ' ' + + events[i].i + + ': [' + + events[i].n + + '] ' + + events[i].m + + '\n'; + } + } + const a = document.createElement('a'); + a.setAttribute( + 'href', + 'data:text/plain;charset=utf-8,' + encodeURIComponent(result) + ); + a.setAttribute('download', 'log.txt'); + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + }; + render() { const { saveData } = this.props; return ( @@ -244,6 +300,16 @@ class LogEventController extends Component< label="Compact Layout" /> + + +