From 1c456b70c00946a0af643a4f49d1da94c10c900c Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date: Mon, 7 Nov 2022 11:35:13 -0800
Subject: [PATCH] Re-create service ping, docker status changes
See #388
---
public/locales/en/common.json | 8 +++++-
src/components/services/item.jsx | 32 ++++++++++++++--------
src/components/services/ping.jsx | 44 ++++++++++++++++++++++++++++++
src/components/services/status.jsx | 27 ++++++++++++++----
src/pages/api/ping.js | 28 +++++++++++++++++++
src/utils/proxy/http.js | 2 +-
6 files changed, 123 insertions(+), 18 deletions(-)
create mode 100644 src/components/services/ping.jsx
create mode 100644 src/pages/api/ping.js
diff --git a/public/locales/en/common.json b/public/locales/en/common.json
index 8784443a4..24177db67 100644
--- a/public/locales/en/common.json
+++ b/public/locales/en/common.json
@@ -52,7 +52,13 @@
"tx": "TX",
"mem": "MEM",
"cpu": "CPU",
- "offline": "Offline"
+ "offline": "Offline",
+ "error": "Error",
+ "unknown": "Unknown"
+ },
+ "ping": {
+ "error": "Error",
+ "ping": "Ping"
},
"emby": {
"playing": "Playing",
diff --git a/src/components/services/item.jsx b/src/components/services/item.jsx
index 56ed2b4b1..3f9df9307 100644
--- a/src/components/services/item.jsx
+++ b/src/components/services/item.jsx
@@ -3,6 +3,7 @@ import { useContext, useState } from "react";
import Status from "./status";
import Widget from "./widget";
+import Ping from "./ping";
import Docker from "widgets/docker/component";
import { SettingsContext } from "utils/contexts/settings";
@@ -30,7 +31,7 @@ export default function Item({ service }) {
{service.icon &&
@@ -70,16 +71,25 @@ export default function Item({ service }) {
)}
- {service.container && (
-
- )}
+
+ {service.ping && (
+
+ )}
+
+ {service.container && (
+
+ )}
+
{service.container && service.server && (
diff --git a/src/components/services/ping.jsx b/src/components/services/ping.jsx
new file mode 100644
index 000000000..e30562323
--- /dev/null
+++ b/src/components/services/ping.jsx
@@ -0,0 +1,44 @@
+import { useTranslation } from "react-i18next";
+import useSWR from "swr";
+
+export default function Ping({ service }) {
+ const { t } = useTranslation();
+ const { data, error } = useSWR(`/api/ping?${new URLSearchParams({ping: service.ping}).toString()}`, {
+ refreshInterval: 30000
+ });
+
+ if (error) {
+ return (
+
+ );
+ }
+
+ if (!data) {
+ return (
+
+ );
+ }
+
+ const statusText = `${service.ping}: HTTP status ${data.status}`;
+
+ if (data && data.status !== 200) {
+ return (
+
+ );
+ }
+
+ if (data && data.status === 200) {
+ return (
+
+
{t("common.ms", { value: data.latency, style: "unit", unit: "millisecond", unitDisplay: "narrow", maximumFractionDigits: 0 })}
+
+ );
+ }
+
+}
diff --git a/src/components/services/status.jsx b/src/components/services/status.jsx
index dc9034081..2d07e49e8 100644
--- a/src/components/services/status.jsx
+++ b/src/components/services/status.jsx
@@ -1,19 +1,36 @@
+import { useTranslation } from "react-i18next";
import useSWR from "swr";
export default function Status({ service }) {
+ const { t } = useTranslation();
+
const { data, error } = useSWR(`/api/docker/status/${service.container}/${service.server || ""}`);
if (error) {
- return ;
+
}
if (data && data.status === "running") {
- return ;
+ return (
+
+ );
}
- if (data && data.status === "not found") {
- return ;
+ if (data && (data.status === "not found" || data.status === "exited")) {
+ return (
+
+ );
}
- return ;
+ return (
+
+
{t("docker.unknown")}
+
+ );
}
diff --git a/src/pages/api/ping.js b/src/pages/api/ping.js
new file mode 100644
index 000000000..79c7da0c9
--- /dev/null
+++ b/src/pages/api/ping.js
@@ -0,0 +1,28 @@
+import { performance } from "perf_hooks";
+
+import createLogger from "utils/logger";
+import { httpProxy } from "utils/proxy/http";
+
+const logger = createLogger("ping");
+
+export default async function handler(req, res) {
+ const { ping: pingURL } = req.query;
+
+ if (!pingURL) {
+ logger.debug("No ping URL specified");
+ return res.status(400).send({
+ error: "No ping URL given",
+ });
+ }
+
+ const startTime = performance.now();
+ const [status] = await httpProxy(pingURL, {
+ method: "HEAD"
+ });
+ const endTime = performance.now();
+
+ return res.status(200).json({
+ status,
+ latency: endTime - startTime
+ });
+}
diff --git a/src/utils/proxy/http.js b/src/utils/proxy/http.js
index 4eba83f32..8f180a7fe 100644
--- a/src/utils/proxy/http.js
+++ b/src/utils/proxy/http.js
@@ -96,7 +96,7 @@ export async function httpProxy(url, params = {}) {
return [status, contentType, data, responseHeaders];
}
catch (err) {
- logger.error("Error calling %s//%s%s...", url.protocol, url.hostname, url.pathname);
+ logger.error("Error calling %s//%s%s...", constructedUrl.protocol, constructedUrl.hostname, constructedUrl.pathname);
logger.error(err);
return [500, "application/json", { error: "Unexpected error" }, null];
}