diff --git a/embark-ui/src/actions/index.js b/embark-ui/src/actions/index.js
index 7104d037..068316da 100644
--- a/embark-ui/src/actions/index.js
+++ b/embark-ui/src/actions/index.js
@@ -6,6 +6,10 @@ export const RECEIVE_ACCOUNTS_ERROR = 'RECEIVE_ACCOUNTS_ERROR';
export const FETCH_PROCESSES = 'FETCH_PROCESSES';
export const RECEIVE_PROCESSES = 'RECEIVE_PROCESSES';
export const RECEIVE_PROCESSES_ERROR = 'RECEIVE_PROCESSES_ERROR';
+// Process logs
+export const FETCH_PROCESS_LOGS = 'FETCH_PROCESS_LOGS';
+export const RECEIVE_PROCESS_LOGS = 'RECEIVE_PROCESS_LOGS';
+export const RECEIVE_PROCESS_LOGS_ERROR = 'RECEIVE_PROCESS_LOGS_ERROR';
// Blocks
export const FETCH_BLOCKS = 'FETCH_BLOCKS';
export const RECEIVE_BLOCKS = 'RECEIVE_BLOCKS';
@@ -47,9 +51,32 @@ export function receiveProcesses(processes) {
};
}
-export function receiveProcessesError() {
+export function receiveProcessesError(error) {
return {
- type: RECEIVE_PROCESSES_ERROR
+ type: RECEIVE_PROCESSES_ERROR,
+ error
+ };
+}
+
+export function fetchProcessLogs(processName) {
+ return {
+ type: FETCH_PROCESS_LOGS,
+ processName
+ };
+}
+
+export function receiveProcessLogs(processName, logs) {
+ return {
+ type: RECEIVE_PROCESS_LOGS,
+ processName,
+ logs
+ };
+}
+
+export function receiveProcessLogsError(error) {
+ return {
+ type: RECEIVE_PROCESS_LOGS_ERROR,
+ error
};
}
diff --git a/embark-ui/src/api/index.js b/embark-ui/src/api/index.js
index c878cec2..4ab0c14d 100644
--- a/embark-ui/src/api/index.js
+++ b/embark-ui/src/api/index.js
@@ -4,7 +4,7 @@ import constants from '../constants';
const BASE_URL = 'http://localhost:8000/embark-api';
export function fetchAccounts() {
- return axios.get(constants.httpEndpoint + 'blockchain/accounts');
+ return axios.get(constants.httpEndpoint + '/blockchain/accounts');
}
export function fetchBlocks(from) {
@@ -16,5 +16,9 @@ export function fetchTransactions(blockFrom) {
}
export function fetchProcesses() {
- return axios.get(constants.httpEndpoint + 'processes');
+ return axios.get(constants.httpEndpoint + '/processes');
+}
+
+export function fetchProcessLogs(processName) {
+ return axios.get(`${constants.httpEndpoint}/process-logs/${processName}`);
}
diff --git a/embark-ui/src/components/Process.js b/embark-ui/src/components/Process.js
index a1c914b4..18000340 100644
--- a/embark-ui/src/components/Process.js
+++ b/embark-ui/src/components/Process.js
@@ -1,5 +1,6 @@
import React, {Component} from 'react';
-import {Tab} from "tabler-react";
+import connect from "react-redux/es/connect/connect";
+import {fetchProcessLogs} from "../actions";
import constants from '../constants';
import PropTypes from 'prop-types';
@@ -9,11 +10,15 @@ class Process extends Component {
this.state = {
logs: []
};
+ this.gotOriginalLogs = false;
}
componentDidMount() {
const self = this;
- this.ws = new WebSocket(constants.wsEndpoint + 'process-logs/' + self.props.processName);
+
+ this.props.fetchProcessLogs(self.props.processName);
+
+ this.ws = new WebSocket(constants.wsEndpoint + '/process-logs/' + self.props.processName);
this.ws.onmessage = function(evt) {
const log = JSON.parse(evt.data);
@@ -33,6 +38,17 @@ class Process extends Component {
};
}
+ shouldComponentUpdate(nextProps, _nextState) {
+ if (!this.gotOriginalLogs && nextProps.logs && nextProps.logs[this.props.processName]) {
+ const logs = nextProps.logs[this.props.processName].concat(this.state.logs);
+ this.gotOriginalLogs = true;
+ this.setState({
+ logs
+ });
+ }
+ return true;
+ }
+
componentWillUnmount() {
this.ws.close();
this.ws = null;
@@ -44,7 +60,7 @@ class Process extends Component {
State: {this.props.state}
{
- this.state.logs.map((item, i) =>
{item.msg}
)
+ this.state.logs.map((item, i) =>
{item.msg_clear || item.msg}
)
}
);
@@ -52,8 +68,19 @@ class Process extends Component {
}
Process.propTypes = {
- processName: PropTypes.string,
- state: PropTypes.string
+ processName: PropTypes.string.isRequired,
+ state: PropTypes.string.isRequired,
+ fetchProcessLogs: PropTypes.func,
+ logs: PropTypes.object
};
-export default Process;
+function mapStateToProps(state) {
+ return {logs: state.processes.logs};
+}
+
+export default connect(
+ mapStateToProps,
+ {
+ fetchProcessLogs
+ }
+)(Process);
diff --git a/embark-ui/src/constants.json b/embark-ui/src/constants.json
index 06f14ec8..d8fafa6c 100644
--- a/embark-ui/src/constants.json
+++ b/embark-ui/src/constants.json
@@ -1,4 +1,4 @@
{
- "httpEndpoint": "http://localhost:8000/embark-api/",
- "wsEndpoint": "ws://localhost:8000/embark-api/"
+ "httpEndpoint": "http://localhost:8000/embark-api",
+ "wsEndpoint": "ws://localhost:8000/embark-api"
}
diff --git a/embark-ui/src/reducers/processesReducer.js b/embark-ui/src/reducers/processesReducer.js
index dc189048..a7ddae2e 100644
--- a/embark-ui/src/reducers/processesReducer.js
+++ b/embark-ui/src/reducers/processesReducer.js
@@ -1,11 +1,21 @@
-import {RECEIVE_PROCESSES, RECEIVE_PROCESSES_ERROR} from "../actions";
+import {RECEIVE_PROCESSES, RECEIVE_PROCESSES_ERROR, RECEIVE_PROCESS_LOGS, RECEIVE_PROCESS_LOGS_ERROR} from "../actions";
export default function processes(state = {}, action) {
switch (action.type) {
case RECEIVE_PROCESSES:
return Object.assign({}, state, {data: action.processes.data});
case RECEIVE_PROCESSES_ERROR:
- return Object.assign({}, state, {error: true});
+ return Object.assign({}, state, {error: action.error});
+ case RECEIVE_PROCESS_LOGS:
+ return {
+ ...state,
+ logs: {
+ ...state.logs,
+ [action.processName]: action.logs.data
+ }
+ };
+ case RECEIVE_PROCESS_LOGS_ERROR:
+ return Object.assign({}, state, {error: action.error});
default:
return state;
}
diff --git a/embark-ui/src/sagas/index.js b/embark-ui/src/sagas/index.js
index c2ad5da7..e242bf3a 100644
--- a/embark-ui/src/sagas/index.js
+++ b/embark-ui/src/sagas/index.js
@@ -46,7 +46,7 @@ export function *fetchProcesses() {
const processes = yield call(api.fetchProcesses);
yield put(actions.receiveProcesses(processes));
} catch (e) {
- yield put(actions.receiveProcessesError());
+ yield put(actions.receiveProcessesError(e));
}
}
@@ -54,10 +54,24 @@ export function *watchFetchProcesses() {
yield takeEvery(actions.FETCH_PROCESSES, fetchProcesses);
}
+export function *fetchProcessLogs(action) {
+ try {
+ const logs = yield call(api.fetchProcessLogs, action.processName);
+ yield put(actions.receiveProcessLogs(action.processName, logs));
+ } catch (e) {
+ yield put(actions.receiveProcessLogsError(e));
+ }
+}
+
+export function *watchFetchProcessLogs() {
+ yield takeEvery(actions.FETCH_PROCESS_LOGS, fetchProcessLogs);
+}
+
export default function *root() {
yield all([
fork(watchFetchAccounts),
fork(watchFetchProcesses),
+ fork(watchFetchProcessLogs),
fork(watchFetchBlocks),
fork(watchFetchTransactions)
]);
diff --git a/lib/core/processes/processLauncher.js b/lib/core/processes/processLauncher.js
index d470ca92..ef3b105f 100644
--- a/lib/core/processes/processLauncher.js
+++ b/lib/core/processes/processLauncher.js
@@ -21,6 +21,7 @@ class ProcessLauncher {
this.silent = options.silent;
this.exitCallback = options.exitCallback;
this.embark = options.embark;
+ this.logs = [];
this.subscriptions = {};
this._subscribeToMessages();
@@ -54,20 +55,29 @@ class ProcessLauncher {
_registerAsPlugin() {
const self = this;
+ const apiRoute = '/embark-api/process-logs/' + self.name;
self.embark.registerAPICall(
'ws',
- '/embark-api/process-logs/' + self.name,
+ apiRoute,
(ws, _req) => {
- self.events.on('log-' + self.name, function(logLevel, msg) {
+ self.events.on('process-log-' + self.name, function(logLevel, msg) {
ws.send(JSON.stringify({msg, msg_clear: msg.stripColors, logLevel}), () => {});
});
}
);
+ self.embark.registerAPICall(
+ 'get',
+ apiRoute,
+ (req, res) => {
+ res.send(JSON.stringify(self.logs));
+ }
+ );
}
// Translates logs from the child process to the logger
_handleLog(msg) {
- this.events.emit('log-' + this.name, msg.type, msg.message);
+ this.events.emit('process-log-' + this.name, msg.type, msg.message);
+ this.logs.push({msg: msg.message, msg_clear: msg.message.stripColors, logLevel: msg.logLevel});
if (this.silent && msg.type !== 'error') {
return;
}