diagnostics panel
This commit is contained in:
parent
746afaf573
commit
7e45773d02
|
@ -1,81 +0,0 @@
|
|||
<script>
|
||||
import {
|
||||
Layout,
|
||||
Heading,
|
||||
Body,
|
||||
Divider,
|
||||
Icon,
|
||||
Input,
|
||||
TextArea,
|
||||
} from "@budibase/bbui"
|
||||
import { CopyInput } from "@budibase/bbui"
|
||||
import { auth, admin } from "stores/portal"
|
||||
import { redirect } from "@roxi/routify"
|
||||
import { processStringSync } from "@budibase/string-templates"
|
||||
import { API } from "api"
|
||||
import { onMount } from "svelte"
|
||||
|
||||
const BROWSER_MAP = {
|
||||
edge: "Microsoft Edge",
|
||||
"edg/": "Chromium Based Edge",
|
||||
opr: "Opera",
|
||||
chrome: "Chrome",
|
||||
trident: "Internet Explorer",
|
||||
firefox: "Firefox",
|
||||
safari: "Safari",
|
||||
}
|
||||
|
||||
let diagnosticInfo = ""
|
||||
|
||||
// Make sure page can't be visited directly in cloud
|
||||
$: {
|
||||
if ($admin.cloud) {
|
||||
$redirect("../../portal")
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchDiagnostics() {
|
||||
const diagnostics = await API.fetchDiagnostics()
|
||||
return {
|
||||
browser: {
|
||||
language: navigator.language || navigator.userLanguage,
|
||||
userAgent: navigator.userAgent,
|
||||
platform: navigator.platform,
|
||||
vendor: navigator.vendor,
|
||||
},
|
||||
server: diagnostics,
|
||||
}
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
const info = await fetchDiagnostics()
|
||||
diagnosticInfo = info
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if $auth.isAdmin}
|
||||
<Layout noPadding>
|
||||
<Layout gap="XS" noPadding>
|
||||
<Heading size="M">Diagnostics</Heading>
|
||||
<Body size="M">
|
||||
<pre>
|
||||
{JSON.stringify(diagnosticInfo, null, 2)}
|
||||
</pre>
|
||||
<!-- <CopyInput value={JSON.stringify(diagnosticInfo, null, 2)} /> -->
|
||||
</Body>
|
||||
</Layout>
|
||||
<Divider />
|
||||
<div>
|
||||
<!-- <Button secondary on:click={refresh}>Refresh</Button> -->
|
||||
</div>
|
||||
</Layout>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
pre {
|
||||
overflow-x: auto;
|
||||
white-space: pre;
|
||||
word-wrap: break-word;
|
||||
font-size: 15px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,86 @@
|
|||
<script>
|
||||
import {
|
||||
Layout,
|
||||
Heading,
|
||||
Body,
|
||||
Helpers,
|
||||
Button,
|
||||
Divider,
|
||||
notifications,
|
||||
Icon,
|
||||
Input,
|
||||
TextArea,
|
||||
} from "@budibase/bbui"
|
||||
import { auth, admin } from "stores/portal"
|
||||
import { redirect } from "@roxi/routify"
|
||||
import { API } from "api"
|
||||
import { onMount } from "svelte"
|
||||
|
||||
let diagnosticInfo = ""
|
||||
|
||||
// Make sure page can't be visited directly in cloud
|
||||
$: {
|
||||
if ($admin.cloud) {
|
||||
$redirect("../../portal")
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchSystemDebugInfo() {
|
||||
const diagnostics = await API.fetchSystemDebugInfo()
|
||||
diagnosticInfo = {
|
||||
browser: {
|
||||
language: navigator.language || navigator.userLanguage,
|
||||
userAgent: navigator.userAgent,
|
||||
platform: navigator.platform,
|
||||
vendor: navigator.vendor,
|
||||
},
|
||||
server: diagnostics,
|
||||
}
|
||||
}
|
||||
|
||||
const copyToClipboard = async () => {
|
||||
await Helpers.copyToClipboard(JSON.stringify(diagnosticInfo, undefined, 2))
|
||||
notifications.success("Copied")
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
await fetchSystemDebugInfo()
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if $auth.isAdmin && diagnosticInfo}
|
||||
<Layout noPadding>
|
||||
<Layout gap="XS">
|
||||
<Heading size="M">Diagnostics</Heading>
|
||||
Please include this diagnostic information in support requests and github issues
|
||||
by clicking the button on the top right to copy to clipboard.
|
||||
<Divider />
|
||||
<Body size="M">
|
||||
<section>
|
||||
<div on:click={copyToClipboard} class="copy-icon">
|
||||
<Icon name="Copy" size="M" />
|
||||
</div>
|
||||
<TextArea
|
||||
height="45vh"
|
||||
disabled
|
||||
value={JSON.stringify(diagnosticInfo, undefined, 2)}
|
||||
/>
|
||||
</section>
|
||||
</Body>
|
||||
</Layout>
|
||||
</Layout>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
section {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.copy-icon {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
|
@ -58,6 +58,10 @@ export const menu = derived([admin, auth], ([$admin, $auth]) => {
|
|||
title: "Environment",
|
||||
href: "/builder/portal/settings/environment",
|
||||
},
|
||||
{
|
||||
title: "Diagnostics",
|
||||
href: "/builder/portal/settings/diagnostics",
|
||||
},
|
||||
]
|
||||
if (!$admin.cloud) {
|
||||
settingsSubPages.push({
|
||||
|
@ -85,14 +89,6 @@ export const menu = derived([admin, auth], ([$admin, $auth]) => {
|
|||
title: "Audit Logs",
|
||||
href: "/builder/portal/account/auditLogs",
|
||||
})
|
||||
accountSubPages.push({
|
||||
title: "Diagnostics",
|
||||
href: "/builder/portal/account/diagnostics",
|
||||
})
|
||||
accountSubPages.push({
|
||||
title: "Logs",
|
||||
href: "/builder/portal/account/debugLogs",
|
||||
})
|
||||
}
|
||||
if ($admin.cloud && $auth?.user?.accountPortalAccess) {
|
||||
accountSubPages.push({
|
||||
|
|
|
@ -124,11 +124,11 @@ export const buildAppEndpoints = API => ({
|
|||
},
|
||||
|
||||
/**
|
||||
* Gets application diagnostics.
|
||||
* Gets budibase platform debug information.
|
||||
*/
|
||||
fetchDiagnostics: async () => {
|
||||
fetchSystemDebugInfo: async () => {
|
||||
return await API.get({
|
||||
url: `/api/dev/diagnostics`,
|
||||
url: `/api/dev/debug`,
|
||||
})
|
||||
},
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import fetch from "node-fetch"
|
||||
import env from "../../environment"
|
||||
import os from "os"
|
||||
import process from "process"
|
||||
import { checkSlashesInUrl } from "../../utilities"
|
||||
import { request } from "../../utilities/workerRequests"
|
||||
import { clearLock as redisClearLock } from "../../utilities/redis"
|
||||
|
@ -7,6 +9,7 @@ import { DocumentType } from "../../db/utils"
|
|||
import { context, env as envCore } from "@budibase/backend-core"
|
||||
import { events, db as dbCore, cache } from "@budibase/backend-core"
|
||||
|
||||
|
||||
async function redirect(ctx: any, method: string, path: string = "global") {
|
||||
const { devPath } = ctx.params
|
||||
const queryString = ctx.originalUrl.split("?")[1] || ""
|
||||
|
@ -128,9 +131,9 @@ export async function getBudibaseVersion(ctx: any) {
|
|||
await events.installation.versionChecked(version)
|
||||
}
|
||||
|
||||
export async function troubleshootingInfo(ctx: any) {
|
||||
const os = require("os")
|
||||
const process = require("process")
|
||||
export async function systemDebugInfo(ctx: any) {
|
||||
const { days, hours, minutes } = secondsToHMS(os.uptime())
|
||||
const totalMemory = convertBytes(os.totalmem())
|
||||
|
||||
ctx.body = {
|
||||
budibaseVersion: envCore.VERSION,
|
||||
|
@ -140,8 +143,32 @@ export async function troubleshootingInfo(ctx: any) {
|
|||
cpuArch: process.arch,
|
||||
cpuCores: os.cpus().length,
|
||||
cpuInfo: os.cpus()[0].model,
|
||||
totalMemory: os.totalmem(),
|
||||
freeMemory: os.freemem(),
|
||||
uptime: os.uptime(),
|
||||
totalMemory: `${totalMemory.gb}GB`,
|
||||
uptime: `${days} day(s), ${hours} hour(s), ${minutes} minute(s)`,
|
||||
}
|
||||
}
|
||||
|
||||
function secondsToHMS(seconds: number) {
|
||||
const MINUTE_IN_SECONDS = 60
|
||||
const HOUR_IN_SECONDS = 3600
|
||||
const DAY_IN_SECONDS = HOUR_IN_SECONDS * 24
|
||||
|
||||
const minutes = Math.floor((seconds / MINUTE_IN_SECONDS) % 60);
|
||||
const hours = Math.floor((seconds / HOUR_IN_SECONDS) % 24);
|
||||
const days = Math.floor(seconds / DAY_IN_SECONDS)
|
||||
|
||||
return {
|
||||
days,
|
||||
hours,
|
||||
minutes,
|
||||
seconds
|
||||
}
|
||||
}
|
||||
|
||||
function convertBytes(bytes: number) {
|
||||
const kb = bytes / 1024;
|
||||
const mb = kb / 1024;
|
||||
const gb = mb / 1024;
|
||||
|
||||
return { gb, mb, kb }
|
||||
}
|
||||
|
|
|
@ -25,9 +25,9 @@ router
|
|||
controller.getBudibaseVersion
|
||||
)
|
||||
.get(
|
||||
"/api/dev/diagnostics",
|
||||
"/api/dev/debug",
|
||||
authorized(permissions.BUILDER),
|
||||
controller.troubleshootingInfo
|
||||
controller.systemDebugInfo
|
||||
)
|
||||
.delete(
|
||||
"/api/dev/:appId/lock",
|
||||
|
|
Loading…
Reference in New Issue