diff --git a/packages/console-app/src/components/LogPoller.js b/packages/console-app/src/components/LogPoller.js
new file mode 100644
index 0000000..d67d2f9
--- /dev/null
+++ b/packages/console-app/src/components/LogPoller.js
@@ -0,0 +1,54 @@
+//
+// Copyright 2020 DxOS.org
+//
+
+import React, { useContext } from 'react';
+import { useQuery } from '@apollo/react-hooks';
+
+import { ConsoleContext, useQueryStatusReducer } from '../hooks';
+
+import LOGS from '../gql/logs.graphql';
+
+import Log from './Log';
+
+const MAX_LINES = 1000;
+const _logBuffers = new Map();
+
+const getLogBuffer = (name) => {
+ let buffer = _logBuffers.get(name);
+ if (!buffer) {
+ buffer = [];
+ _logBuffers.set(name, buffer);
+ }
+ return buffer;
+};
+
+const LogPoller = ({ service }) => {
+ const { config } = useContext(ConsoleContext);
+ const logBuffer = getLogBuffer(service);
+ const data = useQueryStatusReducer(useQuery(LOGS, {
+ pollInterval: config.api.intervalLog,
+ variables: { service, incremental: logBuffer.length !== 0 }
+ }));
+
+ if (!data) {
+ return null;
+ }
+
+ const { incremental, lines } = JSON.parse(data.logs.json);
+
+ if (!incremental && lines.length) {
+ logBuffer.length = 0;
+ }
+
+ logBuffer.push(...lines);
+ if (logBuffer.length > MAX_LINES) {
+ logBuffer.splice(0, logBuffer.length - MAX_LINES);
+ }
+
+ return (
+
+ );
+};
+
+export default LogPoller;
diff --git a/packages/console-app/src/containers/panels/Status.js b/packages/console-app/src/containers/panels/Status.js
index ab54343..9303d37 100644
--- a/packages/console-app/src/containers/panels/Status.js
+++ b/packages/console-app/src/containers/panels/Status.js
@@ -2,11 +2,16 @@
// Copyright 2020 DxOS.org
//
-import React, { useContext } from 'react';
+import React, { useContext, useState } from 'react';
import { useQuery } from '@apollo/react-hooks';
+import { makeStyles } from '@material-ui/core';
+import Tab from '@material-ui/core/Tab';
+import Tabs from '@material-ui/core/Tabs';
+import TabContext from '@material-ui/lab/TabContext';
import Json from '../../components/Json';
+import SERVICE_STATUS from '../../gql/service_status.graphql';
import SYSTEM_STATUS from '../../gql/system_status.graphql';
import { ConsoleContext, useQueryStatusReducer } from '../../hooks';
@@ -14,22 +19,64 @@ import { ConsoleContext, useQueryStatusReducer } from '../../hooks';
import Panel from '../../components/Panel';
import Toolbar from '../../components/Toolbar';
+const TAB_SYSTEM = 'system';
+const TAB_SERVICES = 'services';
+
+const useStyles = makeStyles(() => ({
+ expand: {
+ flex: 1
+ },
+
+ panel: {
+ display: 'flex',
+ overflow: 'hidden',
+ flex: 1
+ },
+
+ paper: {
+ display: 'flex',
+ overflow: 'hidden',
+ flex: 1
+ }
+}));
+
const Status = () => {
+ const classes = useStyles();
const { config } = useContext(ConsoleContext);
+ const [tab, setTab] = useState(TAB_SYSTEM);
const systemResponse = useQueryStatusReducer(useQuery(SYSTEM_STATUS, { pollInterval: config.api.intervalQuery }));
- if (!systemResponse) {
+ const serviceResponse = useQueryStatusReducer(useQuery(SERVICE_STATUS, { pollInterval: config.api.intervalQuery }));
+ if (!systemResponse || !serviceResponse) {
return null;
}
- const data = JSON.parse(systemResponse.system_status.json);
+ const systemData = JSON.parse(systemResponse.system_status.json);
+ const serviceData = JSON.parse(serviceResponse.service_status.json);
return (
+
+ setTab(value)}>
+
+
+
+
}
>
-
+
+ {tab === TAB_SYSTEM && (
+
+
+
+ )}
+
+ {tab === TAB_SERVICES && (
+
+
+
+ )}
+
);
};
diff --git a/packages/console-app/src/containers/panels/apps/Apps.js b/packages/console-app/src/containers/panels/apps/Apps.js
index c026ca0..6675e99 100644
--- a/packages/console-app/src/containers/panels/apps/Apps.js
+++ b/packages/console-app/src/containers/panels/apps/Apps.js
@@ -11,8 +11,10 @@ import Panel from '../../../components/Panel';
import Toolbar from '../../../components/Toolbar';
import AppRecords from './AppRecords';
+import LogPoller from '../../../components/LogPoller';
const TAB_RECORDS = 'records';
+const TAB_LOG = 'log';
const useStyles = makeStyles(theme => ({
root: {}
@@ -29,6 +31,7 @@ const Apps = () => {
setTab(value)}>
+
}
@@ -36,6 +39,10 @@ const Apps = () => {
{tab === TAB_RECORDS && (
)}
+
+ {tab === TAB_LOG && (
+
+ )}
);
};
diff --git a/packages/console-app/src/containers/panels/bots/BotRecords.js b/packages/console-app/src/containers/panels/bots/BotRecords.js
index fac62c1..9a8d90c 100644
--- a/packages/console-app/src/containers/panels/bots/BotRecords.js
+++ b/packages/console-app/src/containers/panels/bots/BotRecords.js
@@ -29,7 +29,7 @@ const AppRecords = () => {
return null;
}
- const records = data.wns_records.json;
+ const records = JSON.parse(data.wns_records.json);
return (
diff --git a/packages/console-app/src/containers/panels/ipfs/IPFS.js b/packages/console-app/src/containers/panels/ipfs/IPFS.js
index 8334560..99a9388 100644
--- a/packages/console-app/src/containers/panels/ipfs/IPFS.js
+++ b/packages/console-app/src/containers/panels/ipfs/IPFS.js
@@ -3,122 +3,44 @@
//
import React, { useState } from 'react';
-import get from 'lodash.get';
-
-import { useQuery } from '@apollo/react-hooks';
import { makeStyles } from '@material-ui/core';
+import Paper from '@material-ui/core/Paper';
import Tab from '@material-ui/core/Tab';
import Tabs from '@material-ui/core/Tabs';
-import TableBody from '@material-ui/core/TableBody';
-import TableHead from '@material-ui/core/TableHead';
-import TableRow from '@material-ui/core/TableRow';
+import TabContext from '@material-ui/lab/TabContext';
-import IPFS_STATUS from '../../../gql/ipfs_status.graphql';
-import WNS_RECORDS from '../../../gql/wns_records.graphql';
-
-import { useQueryStatusReducer } from '../../../hooks';
-
-import Json from '../../../components/Json';
import Panel from '../../../components/Panel';
-import Table from '../../../components/Table';
-import TableCell from '../../../components/TableCell';
import Toolbar from '../../../components/Toolbar';
-import { BooleanIcon } from '../../../components/BooleanIcon';
-const RECORD_TYPE = 'wrn:service';
-const SERVICE_TYPE = 'ipfs';
-
-const useStyles = makeStyles((theme) => ({
- tableContainer: {
- flex: 1,
- overflowY: 'scroll'
- },
-
- table: {
- tableLayout: 'fixed',
-
- '& th': {
- fontVariant: 'all-small-caps',
- fontSize: 18,
- cursor: 'ns-resize'
- }
- },
-
- connected: {
- fontWeight: 'bold'
- },
-
- disconnected: {
- fontStyle: 'italic'
- },
-
- colShort: {
- width: '30%'
- },
-
- colWide: {},
-
- colBoolean: {
- width: '10%'
- },
-
- caption: {
- backgroundColor: theme.palette.primary[500],
- color: theme.palette.primary.contrastText,
- paddingLeft: '1em',
- margin: 0
- }
-}));
+import LogPoller from '../../../components/LogPoller';
+import IPFSStatus from './IPFSStatus';
const TAB_STATUS = 'status';
const TAB_LOG = 'log';
+const TAB_SWARM_LOG = 'swarm';
+
+const useStyles = makeStyles(() => ({
+ expand: {
+ flex: 1
+ },
+
+ panel: {
+ display: 'flex',
+ overflow: 'hidden',
+ flex: 1
+ },
+
+ paper: {
+ display: 'flex',
+ overflow: 'hidden',
+ flex: 1
+ }
+}));
const IPFS = () => {
const classes = useStyles();
const [tab, setTab] = useState(TAB_STATUS);
- const ipfsResponse = useQueryStatusReducer(useQuery(IPFS_STATUS));
- const wnsResponse = useQueryStatusReducer(useQuery(WNS_RECORDS, {
- variables: { attributes: { type: RECORD_TYPE, service: SERVICE_TYPE } }
- }));
-
- if (!wnsResponse || !ipfsResponse) {
- return null;
- }
-
- const ipfsData = JSON.parse(ipfsResponse.ipfs_status.json);
- const registeredServers = JSON.parse(wnsResponse.wns_records.json);
-
- const displayServers = registeredServers.map((service) => {
- console.error(service);
- const addresses = get(service, 'attributes.ipfs.addresses');
- let connected = false;
- for (const address of addresses) {
- const parts = address.split('/');
- const nodeId = parts[parts.length - 1];
- connected = !!ipfsData.swarm.peers.find(({ peer }) => peer === nodeId);
- if (connected) {
- break;
- }
- }
-
- return {
- name: get(service, 'name'),
- version: get(service, 'version'),
- description: get(service, 'attributes.description'),
- ipfs: get(service, 'attributes.ipfs'),
- connected
- };
- });
-
- displayServers.sort((a, b) => {
- return a.connected && !b.connected ? -1 : b.connected && !a.connected ? 1 : b.name < a.name ? 1 : -1;
- });
-
- if (displayServers.length === 0) {
- displayServers.push({ name: 'None' });
- }
-
return (
{
setTab(value)}>
+
}
>
- WNS-registered IPFS Servers
-
-
-
- Identifier
- Description
- Connected
- Address
-
-
-
- {displayServers.map(({ name, description, ipfs, connected }) => (
-
- {name}
- {description}
-
-
-
-
- {ipfs.addresses}
-
-
- ))}
-
-
+
+ {tab === TAB_STATUS && (
+
+ )}
- Local IPFS Server
-
+ {tab === TAB_LOG && (
+
+
+
+ )}
+
+ {tab === TAB_SWARM_LOG && (
+
+
+
+ )}
+
);
};
diff --git a/packages/console-app/src/containers/panels/ipfs/IPFSStatus.js b/packages/console-app/src/containers/panels/ipfs/IPFSStatus.js
new file mode 100644
index 0000000..ec708d4
--- /dev/null
+++ b/packages/console-app/src/containers/panels/ipfs/IPFSStatus.js
@@ -0,0 +1,157 @@
+//
+// Copyright 2020 DxOS.org
+//
+
+import React from 'react';
+import get from 'lodash.get';
+
+import { useQuery } from '@apollo/react-hooks';
+import { makeStyles } from '@material-ui/core';
+import TableBody from '@material-ui/core/TableBody';
+import TableHead from '@material-ui/core/TableHead';
+import TableRow from '@material-ui/core/TableRow';
+
+import IPFS_STATUS from '../../../gql/ipfs_status.graphql';
+import WNS_RECORDS from '../../../gql/wns_records.graphql';
+
+import { useQueryStatusReducer } from '../../../hooks';
+
+import Json from '../../../components/Json';
+import Panel from '../../../components/Panel';
+import Table from '../../../components/Table';
+import TableCell from '../../../components/TableCell';
+import { BooleanIcon } from '../../../components/BooleanIcon';
+
+const RECORD_TYPE = 'wrn:service';
+const SERVICE_TYPE = 'ipfs';
+
+const useStyles = makeStyles((theme) => ({
+ tableContainer: {
+ flex: 1,
+ overflowY: 'scroll'
+ },
+
+ table: {
+ tableLayout: 'fixed',
+
+ '& th': {
+ fontVariant: 'all-small-caps',
+ fontSize: 18,
+ cursor: 'ns-resize'
+ }
+ },
+
+ connected: {
+ fontWeight: 'bold'
+ },
+
+ disconnected: {
+ fontStyle: 'italic'
+ },
+
+ colShort: {
+ width: '30%'
+ },
+
+ colWide: {},
+
+ colBoolean: {
+ width: '10%'
+ },
+
+ caption: {
+ backgroundColor: theme.palette.primary[500],
+ color: theme.palette.primary.contrastText,
+ paddingLeft: '1em',
+ margin: 0
+ }
+}));
+
+const IPFSStatus = () => {
+ const classes = useStyles();
+
+ const ipfsResponse = useQueryStatusReducer(useQuery(IPFS_STATUS));
+ const wnsResponse = useQueryStatusReducer(useQuery(WNS_RECORDS, {
+ variables: { attributes: { type: RECORD_TYPE, service: SERVICE_TYPE } }
+ }));
+
+ if (!wnsResponse || !ipfsResponse) {
+ return null;
+ }
+
+ const ipfsData = JSON.parse(ipfsResponse.ipfs_status.json);
+ const registeredServers = JSON.parse(wnsResponse.wns_records.json);
+
+ const displayServers = registeredServers.map((service) => {
+ console.error(service);
+ const addresses = get(service, 'attributes.ipfs.addresses');
+ let connected = false;
+ for (const address of addresses) {
+ const parts = address.split('/');
+ const nodeId = parts[parts.length - 1];
+ connected = !!ipfsData.swarm.peers.find(({ peer }) => peer === nodeId);
+ if (connected) {
+ break;
+ }
+ }
+
+ return {
+ name: get(service, 'name'),
+ version: get(service, 'version'),
+ description: get(service, 'attributes.description'),
+ ipfs: get(service, 'attributes.ipfs'),
+ connected
+ };
+ });
+
+ displayServers.sort((a, b) => {
+ return a.connected && !b.connected ? -1 : b.connected && !a.connected ? 1 : b.name < a.name ? 1 : -1;
+ });
+
+ if (displayServers.length === 0) {
+ displayServers.push({ name: 'None' });
+ }
+
+ return (
+
+ WNS-registered IPFS Servers
+
+
+
+ Identifier
+ Description
+ Connected
+ Address
+
+
+
+ {displayServers.map(({ name, description, ipfs, connected }) => (
+
+ {name}
+ {description}
+
+
+
+
+ {ipfs.addresses}
+
+
+ ))}
+
+
+
+ Local IPFS Server
+
+
+ );
+};
+
+export default IPFSStatus;
diff --git a/packages/console-app/src/containers/panels/signal/SignalLog.js b/packages/console-app/src/containers/panels/signal/SignalLog.js
deleted file mode 100644
index 77a84ea..0000000
--- a/packages/console-app/src/containers/panels/signal/SignalLog.js
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright 2020 DxOS.org
-//
-
-import React, { useContext } from 'react';
-import { useQuery } from '@apollo/react-hooks';
-
-import SIGNAL_LOG from '../../../gql/signal_log.graphql';
-
-import { ConsoleContext, useQueryStatusReducer } from '../../../hooks';
-
-import Log from '../../../components/Log';
-
-const SignalLog = () => {
- const { config } = useContext(ConsoleContext);
- const data = useQueryStatusReducer(useQuery(SIGNAL_LOG, { pollInterval: config.api.intervalLog }));
- if (!data) {
- return null;
- }
-
- return (
-
- );
-};
-
-export default SignalLog;
diff --git a/packages/console-app/src/containers/panels/signal/Signaling.js b/packages/console-app/src/containers/panels/signal/Signaling.js
index bfe9fa4..278d0c4 100644
--- a/packages/console-app/src/containers/panels/signal/Signaling.js
+++ b/packages/console-app/src/containers/panels/signal/Signaling.js
@@ -12,8 +12,8 @@ import TabContext from '@material-ui/lab/TabContext';
import Panel from '../../../components/Panel';
import Toolbar from '../../../components/Toolbar';
-import SignalLog from './SignalLog';
import SignalStatus from './SignalStatus';
+import LogPoller from '../../../components/LogPoller';
const TAB_STATUS = 'status';
const TAB_LOG = 'log';
@@ -39,7 +39,6 @@ const useStyles = makeStyles(() => ({
const Signal = () => {
const classes = useStyles();
const [tab, setTab] = useState(TAB_STATUS);
- const [type, setType] = useState();
return (
{
{tab === TAB_LOG && (
-
+
)}
diff --git a/packages/console-app/src/containers/panels/wns/WNS.js b/packages/console-app/src/containers/panels/wns/WNS.js
index 0d7c80e..6d13354 100644
--- a/packages/console-app/src/containers/panels/wns/WNS.js
+++ b/packages/console-app/src/containers/panels/wns/WNS.js
@@ -9,10 +9,10 @@ import Tab from '@material-ui/core/Tab';
import Tabs from '@material-ui/core/Tabs';
import TabContext from '@material-ui/lab/TabContext';
+import LogPoller from '../../../components/LogPoller';
import Panel from '../../../components/Panel';
import Toolbar from '../../../components/Toolbar';
-import WNSLog from './WNSLog';
import WNSRecords, { WNSRecordType } from './WNSRecords';
import WNSStatus from './WNSStatus';
@@ -76,7 +76,7 @@ const WNS = () => {
{tab === TAB_LOG && (
-
+
)}
diff --git a/packages/console-app/src/containers/panels/wns/WNSLog.js b/packages/console-app/src/containers/panels/wns/WNSLog.js
deleted file mode 100644
index d0f40bb..0000000
--- a/packages/console-app/src/containers/panels/wns/WNSLog.js
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright 2020 DxOS.org
-//
-
-import React, { useContext } from 'react';
-import { useQuery } from '@apollo/react-hooks';
-
-import WNS_LOG from '../../../gql/wns_log.graphql';
-
-import { ConsoleContext, useQueryStatusReducer } from '../../../hooks';
-
-import Log from '../../../components/Log';
-
-const WNSLog = () => {
- const { config } = useContext(ConsoleContext);
- const data = useQueryStatusReducer(useQuery(WNS_LOG, { pollInterval: config.api.intervalLog }));
- if (!data) {
- return null;
- }
-
- return (
-
- );
-};
-
-export default WNSLog;
diff --git a/packages/console-app/src/gql/logs.graphql b/packages/console-app/src/gql/logs.graphql
new file mode 100644
index 0000000..fb4b122
--- /dev/null
+++ b/packages/console-app/src/gql/logs.graphql
@@ -0,0 +1,10 @@
+#
+# Copyright 2020 DxOS.org
+#
+
+query ($service: String!, $incremental: Boolean) {
+ logs(service: $service, incremental: $incremental) {
+ timestamp
+ json
+ }
+}
diff --git a/packages/console-app/src/gql/wns_log.graphql b/packages/console-app/src/gql/service_status.graphql
similarity index 51%
rename from packages/console-app/src/gql/wns_log.graphql
rename to packages/console-app/src/gql/service_status.graphql
index ab5f741..1abae0e 100644
--- a/packages/console-app/src/gql/wns_log.graphql
+++ b/packages/console-app/src/gql/service_status.graphql
@@ -3,8 +3,8 @@
#
query {
- wns_log @client {
- timestamp
- log
+ service_status {
+ timestamp,
+ json
}
}
diff --git a/packages/console-app/src/gql/signal_log.graphql b/packages/console-app/src/gql/signal_log.graphql
deleted file mode 100644
index 9e8194d..0000000
--- a/packages/console-app/src/gql/signal_log.graphql
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Copyright 2020 DxOS.org
-#
-
-query {
- signal_log @client {
- timestamp
- log
- }
-}
diff --git a/packages/console-app/src/resolvers.js b/packages/console-app/src/resolvers.js
index 019c0f4..0c5f13e 100644
--- a/packages/console-app/src/resolvers.js
+++ b/packages/console-app/src/resolvers.js
@@ -105,7 +105,7 @@ export const createResolvers = config => {
timestamp: timestamp(),
log: []
};
- },
+ }
}
};
};
diff --git a/packages/console-app/src/version.json b/packages/console-app/src/version.json
new file mode 100644
index 0000000..a7f299b
--- /dev/null
+++ b/packages/console-app/src/version.json
@@ -0,0 +1,7 @@
+{
+ "build": {
+ "name": "@dxos/console-app",
+ "buildDate": "2020-06-11T06:21:53.153Z",
+ "version": "1.0.0-beta.0"
+ }
+}
diff --git a/packages/console-server/src/gql/api.graphql b/packages/console-server/src/gql/api.graphql
index 62780ad..57d8838 100644
--- a/packages/console-server/src/gql/api.graphql
+++ b/packages/console-server/src/gql/api.graphql
@@ -8,33 +8,21 @@ type JSONResult {
json: String!
}
-type Result {
- timestamp: String!
- code: Int!
-}
-
-type Log {
- timestamp: String!
- log: [String]!
-}
-
#
# Schema
#
-type Mutation {
- action(command: String!): Result!
-}
-
type Query {
- system_status: SystemStatus!
+ logs(service: String!, incremental: Boolean): JSONResult!
+ app_status: JSONResult!
ipfs_status: JSONResult!
+ ipfs_swarm_status: JSONResult!
+ service_status: JSONResult!
+ signal_status: JSONResult!
+ system_status: JSONResult!
wns_status: JSONResult!
- wns_records(type: String): JSONResult!
- wns_log: Log!
}
schema {
- mutation: Mutation
query: Query
}
diff --git a/packages/console-server/src/gql/system.graphql b/packages/console-server/src/gql/system.graphql
deleted file mode 100644
index 937ce42..0000000
--- a/packages/console-server/src/gql/system.graphql
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Copyright 2020 DxOS.org
-#
-
-type SystemStatus {
- timestamp: String!
- json: String!
-}
diff --git a/packages/console-server/src/resolvers/index.js b/packages/console-server/src/resolvers/index.js
index d0fcd65..907ea1c 100644
--- a/packages/console-server/src/resolvers/index.js
+++ b/packages/console-server/src/resolvers/index.js
@@ -7,7 +7,9 @@ import defaultsDeep from 'lodash.defaultsdeep';
import { ipfsResolvers } from './ipfs';
import { systemResolvers } from './system';
+import { logResolvers } from './log';
+// eslint-disable-next-line
const log = debug('dxos:console:server:resolvers');
/**
@@ -19,14 +21,4 @@ export const resolvers = defaultsDeep({
// TODO(burdon): Auth.
// https://www.apollographql.com/docs/apollo-server/data/errors/#codes
- Mutation: {
- action: async (_, { command }) => {
- log(`WNS action: ${command}`);
-
- return {
- timestamp: new Date().toUTCString(),
- code: 0
- };
- }
- }
-}, ipfsResolvers, systemResolvers);
+}, ipfsResolvers, systemResolvers, logResolvers);
diff --git a/packages/console-server/src/resolvers/log.js b/packages/console-server/src/resolvers/log.js
new file mode 100644
index 0000000..8cdbaec
--- /dev/null
+++ b/packages/console-server/src/resolvers/log.js
@@ -0,0 +1,64 @@
+//
+// Copyright 2020 DxOS.org
+//
+
+import { spawnSync } from 'child_process';
+
+class LogCache {
+ constructor (maxLines = 500) {
+ // Sets in JS iterate in insertion order.
+ this.buffer = new Set();
+ this.maxLines = maxLines;
+ }
+
+ append (lines) {
+ const added = [];
+ for (const line of lines) {
+ if (!this.buffer.has(line)) {
+ this.buffer.add(line);
+ added.push(line);
+ }
+ }
+
+ if (this.buffer.size > this.maxLines) {
+ this.buffer = new Set(Array.from(this.buffer).slice(parseInt(this.maxLines / 2)));
+ }
+
+ return added;
+ }
+}
+
+const _caches = new Map();
+
+const getLogCache = (name) => {
+ let cache = _caches.get(name);
+ if (!cache) {
+ cache = new LogCache();
+ _caches.set(name, cache);
+ }
+ return cache;
+};
+
+const getLogs = async (name, incremental = false, lines = 100) => {
+ const command = 'wire';
+ const args = ['service', 'logs', '--lines', lines, name];
+
+ const child = spawnSync(command, args, { encoding: 'utf8' });
+ const logLines = child.stdout.split(/\n/);
+ const cache = getLogCache(name);
+ const added = cache.append(logLines);
+
+ return incremental ? added : Array.from(cache.buffer);
+};
+
+export const logResolvers = {
+ Query: {
+ logs: async (_, { service, incremental }) => {
+ const lines = await getLogs(service, incremental);
+ return {
+ timestamp: new Date().toUTCString(),
+ json: JSON.stringify({ incremental, lines })
+ };
+ },
+ }
+};
diff --git a/packages/console-server/src/resolvers/system.js b/packages/console-server/src/resolvers/system.js
index cd86bbd..2d03546 100644
--- a/packages/console-server/src/resolvers/system.js
+++ b/packages/console-server/src/resolvers/system.js
@@ -6,6 +6,7 @@ import moment from 'moment';
import pick from 'lodash.pick';
import os from 'os';
import si from 'systeminformation';
+import { spawnSync } from "child_process";
const num = new Intl.NumberFormat('en', { maximumSignificantDigits: 3 });
@@ -77,6 +78,18 @@ const getSystemInfo = async () => {
};
};
+/**
+ * Get system inforamtion.
+ * https://www.npmjs.com/package/systeminformation
+ */
+const getServiceInfo = async () => {
+ const command = 'wire';
+ const args = ['service', '--json'];
+
+ const child = spawnSync(command, args, { encoding: 'utf8' });
+ return JSON.parse(child.stdout);
+}
+
export const systemResolvers = {
Query: {
system_status: async () => {
@@ -86,6 +99,14 @@ export const systemResolvers = {
timestamp: new Date().toUTCString(),
json: JSON.stringify(system)
};
- }
+ },
+ service_status: async () => {
+ const serviceInfo = await getServiceInfo();
+
+ return {
+ timestamp: new Date().toUTCString(),
+ json: JSON.stringify(serviceInfo)
+ };
+ },
}
};
diff --git a/packages/console-server/src/server/main.js b/packages/console-server/src/server/main.js
index 073aeb6..8d7d22c 100644
--- a/packages/console-server/src/server/main.js
+++ b/packages/console-server/src/server/main.js
@@ -22,7 +22,6 @@ import SYSTEM_STATUS from '@dxos/console-app/src/gql/system_status.graphql';
import { resolvers } from '../resolvers';
import API_SCHEMA from '../gql/api.graphql';
-import SYSTEM_SCHEMA from '../gql/system.graphql';
const argv = yargs
.option('config', {
@@ -113,10 +112,7 @@ app.get(publicUrl, (req, res) => {
const server = new ApolloServer({
typeDefs: [
- API_SCHEMA,
- SYSTEM_SCHEMA
- // WNS_EXTENSIONS,
- // WNS_SCHEMA
+ API_SCHEMA
],
// https://www.apollographql.com/docs/graphql-tools/resolvers