diff --git a/monkey/monkey_island/cc/ui/src/components/map/TelemetryLog.tsx b/monkey/monkey_island/cc/ui/src/components/map/TelemetryLog.tsx
new file mode 100644
index 000000000..f247bbf91
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/map/TelemetryLog.tsx
@@ -0,0 +1,96 @@
+import React, {useEffect, useRef, useState} from 'react';
+import AuthComponent from '../AuthComponent';
+
+
+const authComponent = new AuthComponent({});
+
+const TelemetryLog = (props: { onStatusChange: Function }) => {
+
+ let [telemetryUpdateInProgress, setTelemetryUpdateInProgress] = useState(false);
+ let [telemetry, setTelemetry] = useState([]);
+ let [lastTelemetryTimestamp, setLastTelemetryTimestamp] = useState(null);
+ let [isScrolledUp, setIsScrolledUp] = useState(false);
+ let [telemetryLines, setTelemetryLines] = useState(0);
+ let [telemetryCurrentLine, setTelemetryCurrentLine] = useState(0);
+
+ let scrollTop = 0;
+ const telemetryConsole = useRef(null);
+
+ useEffect(() => {
+ const interval = setInterval(updateTelemetryFromServer, 5000);
+ return function cleanup() {
+ clearInterval(interval);
+ };
+ }, []);
+
+ function updateTelemetryFromServer() {
+ if (telemetryUpdateInProgress) {
+ return
+ }
+ setTelemetryUpdateInProgress(true);
+ authComponent.authFetch('/api/telemetry-feed?timestamp=' + lastTelemetryTimestamp)
+ .then(res => res.json())
+ .then(res => {
+ if ('telemetries' in res) {
+ let newTelem = telemetry.concat(res['telemetries']);
+ setTelemetry(newTelem);
+ setLastTelemetryTimestamp(res['timestamp']);
+ setTelemetryUpdateInProgress(false);
+ props.onStatusChange();
+
+ let telemConsoleRef = telemetryConsole.current;
+ if (!isScrolledUp) {
+ telemConsoleRef.scrollTop = telemConsoleRef.scrollHeight - telemConsoleRef.clientHeight;
+ scrollTop = telemConsoleRef.scrollTop;
+ }
+ }
+ });
+ }
+
+ function handleScroll(e) {
+ let element = e.target;
+
+ let telemetryStyle = window.getComputedStyle(element);
+ let telemetryLineHeight = parseInt((telemetryStyle.lineHeight).replace('px', ''));
+
+ setIsScrolledUp((element.scrollTop < scrollTop));
+ setTelemetryCurrentLine(Math.trunc(element.scrollTop / telemetryLineHeight) + 1);
+ setTelemetryLines(Math.trunc(element.scrollHeight / telemetryLineHeight));
+ }
+
+ function renderTelemetryConsole() {
+ return (
+
+ {
+ telemetry.map(renderTelemetryEntry)
+ }
+
+ );
+ }
+
+ function renderTelemetryEntry(telemetry) {
+ return (
+
+ {telemetry.timestamp}
+ {telemetry.hostname}:
+ {telemetry.brief}
+
+ );
+ }
+
+ function renderTelemetryLineCount() {
+ return (
+
+ [{telemetryCurrentLine}/{telemetryLines}]
+
+ );
+ }
+
+ return (
+ <>
+ {renderTelemetryLineCount()}
+ {renderTelemetryConsole()}
+ >);
+}
+
+export default TelemetryLog;
diff --git a/monkey/monkey_island/cc/ui/src/components/pages/MapPage.js b/monkey/monkey_island/cc/ui/src/components/pages/MapPage.js
index da11c7ed6..6026cebb6 100644
--- a/monkey/monkey_island/cc/ui/src/components/pages/MapPage.js
+++ b/monkey/monkey_island/cc/ui/src/components/pages/MapPage.js
@@ -10,6 +10,7 @@ import {getOptions, edgeGroupToColor} from 'components/map/MapOptions';
import AuthComponent from '../AuthComponent';
import '../../styles/components/Map.scss';
import {faInfoCircle} from '@fortawesome/free-solid-svg-icons/faInfoCircle';
+import TelemetryLog from '../map/TelemetryLog';
class MapPageComponent extends AuthComponent {
constructor(props) {
@@ -20,17 +21,8 @@ class MapPageComponent extends AuthComponent {
selected: null,
selectedType: null,
killPressed: false,
- showKillDialog: false,
- telemetry: [],
- telemetryLastTimestamp: null,
- isScrolledUp: false,
- telemetryLines: 0,
- telemetryCurrentLine: 0,
- telemetryUpdateInProgress: false
+ showKillDialog: false
};
- this.telemConsole = React.createRef();
- this.handleScroll = this.handleScroll.bind(this);
- this.scrollTop = 0;
}
events = {
@@ -40,7 +32,7 @@ class MapPageComponent extends AuthComponent {
componentDidMount() {
this.getNodeStateListFromServer();
this.updateMapFromServer();
- this.interval = setInterval(this.timedEvents, 5000);
+ this.interval = setInterval(this.updateMapFromServer, 5000);
}
componentWillUnmount() {
@@ -55,11 +47,6 @@ class MapPageComponent extends AuthComponent {
});
};
- timedEvents = () => {
- this.updateMapFromServer();
- this.updateTelemetryFromServer();
- };
-
updateMapFromServer = () => {
this.authFetch('/api/netmap')
.then(res => res.json())
@@ -74,33 +61,6 @@ class MapPageComponent extends AuthComponent {
});
};
- updateTelemetryFromServer = () => {
- if (this.state.telemetryUpdateInProgress) {
- return
- }
- this.setState({telemetryUpdateInProgress: true});
- this.authFetch('/api/telemetry-feed?timestamp=' + this.state.telemetryLastTimestamp)
- .then(res => res.json())
- .then(res => {
- if ('telemetries' in res) {
- let newTelem = this.state.telemetry.concat(res['telemetries']);
- this.setState(
- {
- telemetry: newTelem,
- telemetryLastTimestamp: res['timestamp'],
- telemetryUpdateInProgress: false
- });
- this.props.onStatusChange();
-
- let telemConsoleRef = this.telemConsole.current;
- if (!this.state.isScrolledUp) {
- telemConsoleRef.scrollTop = telemConsoleRef.scrollHeight - telemConsoleRef.clientHeight;
- this.scrollTop = telemConsoleRef.scrollTop;
- }
- }
- });
- };
-
selectionChanged(event) {
if (event.nodes.length === 1) {
this.authFetch('/api/netmap/node?id=' + event.nodes[0])
@@ -157,46 +117,6 @@ class MapPageComponent extends AuthComponent {
)
};
- renderTelemetryEntry(telemetry) {
- return (
-
- {telemetry.timestamp}
- {telemetry.hostname}:
- {telemetry.brief}
-
- );
- }
-
- handleScroll(e) {
- let element = e.target;
-
- let telemetryStyle = window.getComputedStyle(element);
- let telemetryLineHeight = parseInt((telemetryStyle.lineHeight).replace('px', ''));
-
- this.setState({
- isScrolledUp: (element.scrollTop < this.scrollTop),
- telemetryCurrentLine: Math.trunc(element.scrollTop / telemetryLineHeight) + 1,
- telemetryLines: Math.trunc(element.scrollHeight / telemetryLineHeight)
- });
- }
-
- renderTelemetryConsole() {
- return (
-
- {
- this.state.telemetry.map(this.renderTelemetryEntry)
- }
-
- );
- }
-
- renderTelemetryLineCount() {
- return (
-
- [{this.state.telemetryCurrentLine}/{this.state.telemetryLines}]
-
- );
- }
render() {
return (
@@ -220,10 +140,9 @@ class MapPageComponent extends AuthComponent {
Island Communication
- {this.renderTelemetryLineCount()}
- {this.renderTelemetryConsole()}
+