mirror of
https://github.com/rajnandan1/kener.git
synced 2026-08-07 07:14:56 +00:00
refactor: improve error handling and logging in GamedigCall, SqlCall, and SSLCall classes; update documentation links and restructure introduction content
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
KENER_SECRET_KEY=some_secret_key_for_kener
|
||||
REDIS_URL=redis://localhost:6379
|
||||
@@ -31,3 +31,5 @@ static/uploads/*
|
||||
temp.txt
|
||||
temp.js
|
||||
.DS_Store
|
||||
knip-output.txt
|
||||
check-output.txt
|
||||
|
||||
+22
-26
@@ -2,43 +2,39 @@
|
||||
> kener@4.0.0 check
|
||||
> svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
|
||||
|
||||
[dotenv@17.2.4] injecting env (6) from .env -- tip: 🛠️ run anywhere with `dotenvx run -- yourcommand`
|
||||
[dotenv@17.2.4] injecting env (6) from .env -- tip: ⚙️ write to custom object with { processEnv: myObject }
|
||||
Loading svelte-check in workspace: /Users/rajnandan1/Code/kener
|
||||
Getting Svelte diagnostics...
|
||||
|
||||
[dotenv@17.2.4] injecting env (6) from .env -- tip: 🔄 add secrets lifecycle management: https://dotenvx.com/ops
|
||||
[dotenv@17.2.4] injecting env (6) from .env -- tip: ⚙️ specify custom .env file path with { path: '/custom/path/.env' }
|
||||
[dotenv@17.2.4] injecting env (0) from .env -- tip: 🔐 prevent committing .env to code: https://dotenvx.com/precommit
|
||||
[dotenv@17.2.4] injecting env (0) from .env -- tip: ⚙️ write to custom object with { processEnv: myObject }
|
||||
/Users/rajnandan1/Code/kener/src/lib/server/controllers/dashboardController.ts:285:9
|
||||
Error: Type '{ ts: number; countOfUp: number; countOfDown: number; countOfDegraded: number; countOfMaintenance: number; avgLatency: number; }' is missing the following properties from type 'TimestampStatusCount': maxLatency, minLatency
|
||||
latestData.reduce((sum, data) => sum + (data.latency || 0), 0) / (latestData.length || 1);
|
||||
const item: TimestampStatusCount = {
|
||||
ts: nowTs,
|
||||
|
||||
[dotenv@17.2.4] injecting env (0) from .env -- tip: ⚙️ override existing env vars with { override: true }
|
||||
/Users/rajnandan1/Code/kener/src/lib/components/ui/chart/chart-container.svelte:20:28
|
||||
Warn: This reference only captures the initial value of `id`. Did you mean to reference it inside a closure instead?
|
||||
https://svelte.dev/e/state_referenced_locally (svelte)
|
||||
|
||||
const chartId = `chart-${id || uid.replace(/:/g, "")}`;
|
||||
|
||||
/Users/rajnandan1/Code/kener/src/routes/(kener)/monitors/[monitor_tag]/+page.server.ts:50:7
|
||||
Error: Type '{ ts: number; countOfUp: number; countOfDown: number; countOfDegraded: number; countOfMaintenance: number; avgLatency: number; }' is missing the following properties from type 'TimestampStatusCount': maxLatency, minLatency
|
||||
//use uptime calculator tool to parse
|
||||
let item: TimestampStatusCount = {
|
||||
ts: lastStatus ? lastStatus.timestamp : GetNowTimestampUTC(),
|
||||
/Users/rajnandan1/Code/kener/src/lib/components/ui/toggle-group/toggle-group.svelte:36:3
|
||||
Warn: This reference only captures the initial value of `variant`. Did you mean to reference it inside a closure instead?
|
||||
https://svelte.dev/e/state_referenced_locally (svelte)
|
||||
setToggleGroupCtx({
|
||||
variant,
|
||||
size,
|
||||
|
||||
/Users/rajnandan1/Code/kener/src/routes/(docs)/docs/DocsNavbar.svelte:131:3
|
||||
Warn: Unused CSS selector ".active"
|
||||
https://svelte.dev/e/css_unused_selector (svelte)
|
||||
<style>
|
||||
.active {
|
||||
color: var(--foreground);
|
||||
/Users/rajnandan1/Code/kener/src/lib/components/ui/toggle-group/toggle-group.svelte:37:3
|
||||
Warn: This reference only captures the initial value of `size`. Did you mean to reference it inside a closure instead?
|
||||
https://svelte.dev/e/state_referenced_locally (svelte)
|
||||
variant,
|
||||
size,
|
||||
spacing,
|
||||
|
||||
/Users/rajnandan1/Code/kener/src/routes/(kener)/[page_path]/+page.svelte:58:5
|
||||
Error: Object literal may only specify known properties, and '"pageSettings"' does not exist in type 'Props'. (ts)
|
||||
<EventsCard
|
||||
pageSettings={data.pageDetails.page_settings}
|
||||
ongoingMaintenancesCount={data.ongoingMaintenances.length}
|
||||
/Users/rajnandan1/Code/kener/src/lib/components/ui/toggle-group/toggle-group.svelte:38:3
|
||||
Warn: This reference only captures the initial value of `spacing`. Did you mean to reference it inside a closure instead?
|
||||
https://svelte.dev/e/state_referenced_locally (svelte)
|
||||
size,
|
||||
spacing,
|
||||
});
|
||||
|
||||
/Users/rajnandan1/Code/kener/src/routes/(kener)/events/[MMMM]-[YYYY]/+page.svelte:34:28
|
||||
Warn: This reference only captures the initial value of `data`. Did you mean to reference it inside a closure instead?
|
||||
@@ -48,4 +44,4 @@ https://svelte.dev/e/state_referenced_locally (svelte)
|
||||
const currentMonth = format(parsedDate, "MMMM yyyy");
|
||||
|
||||
====================================
|
||||
svelte-check found 3 errors and 3 warnings in 6 files
|
||||
svelte-check found 0 errors and 5 warnings in 3 files
|
||||
|
||||
@@ -34,11 +34,16 @@ class GamedigCall {
|
||||
responseTime = response.ping;
|
||||
responseRaw = response.raw;
|
||||
} catch (error: unknown) {
|
||||
console.log(`Error while requesting game's information for ${tag}: `, (error as Error).message);
|
||||
let errorMessage = error instanceof Error ? error.message : String(error);
|
||||
if (errorMessage.length > 200) {
|
||||
errorMessage = errorMessage.substring(0, 200) + "...";
|
||||
}
|
||||
console.log(`Error while requesting game's information for ${tag}: `, errorMessage);
|
||||
return {
|
||||
status: GC.DOWN,
|
||||
latency: 0,
|
||||
type: GC.ERROR,
|
||||
error_message: errorMessage,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -52,11 +57,16 @@ class GamedigCall {
|
||||
try {
|
||||
evalResp = await evalFunction(responseTime, responseRaw);
|
||||
} catch (error: unknown) {
|
||||
console.log(`Error in gamedigEval for ${tag}: `, (error as Error).message);
|
||||
let errorMessage = error instanceof Error ? error.message : String(error);
|
||||
if (errorMessage.length > 200) {
|
||||
errorMessage = errorMessage.substring(0, 200) + "...";
|
||||
}
|
||||
console.log(`Error in gamedigEval for ${tag}: `, errorMessage);
|
||||
return {
|
||||
status: GC.DOWN,
|
||||
latency: 0,
|
||||
type: GC.ERROR,
|
||||
error_message: errorMessage,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,11 @@ class SqlCall {
|
||||
type: GC.REALTIME,
|
||||
};
|
||||
} catch (error: unknown) {
|
||||
let errorMessage = error instanceof Error ? error.message : String(error);
|
||||
if (errorMessage.length > 200) {
|
||||
errorMessage = errorMessage.substring(0, 200) + "...";
|
||||
}
|
||||
console.log(`Error executing SQL query for monitor with tag ${this.monitor.tag}:`, errorMessage);
|
||||
const latency = Date.now() - startTime;
|
||||
|
||||
// Handle timeout specifically
|
||||
@@ -67,6 +72,7 @@ class SqlCall {
|
||||
status: GC.DOWN,
|
||||
latency: latency,
|
||||
type: GC.TIMEOUT,
|
||||
error_message: "Query execution exceeded timeout of " + timeout + "ms",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -75,6 +81,7 @@ class SqlCall {
|
||||
status: GC.DOWN,
|
||||
latency: latency,
|
||||
type: GC.ERROR,
|
||||
error_message: errorMessage,
|
||||
};
|
||||
} finally {
|
||||
// Destroy knex instance to clean up connections
|
||||
|
||||
@@ -59,20 +59,27 @@ class SSLCall {
|
||||
status: GC.DEGRADED,
|
||||
latency: latency,
|
||||
type: GC.REALTIME,
|
||||
error_message: `SSL certificate for ${domain} is expiring in ${timeTillExpiryHours.toFixed(2)} hours.`,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
status: GC.DOWN,
|
||||
latency: latency,
|
||||
type: GC.REALTIME,
|
||||
error_message: `SSL certificate for ${domain} has expired or is expiring in less than ${downRemainingHours} hours.`,
|
||||
};
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
console.log(`Error checking SSL for ${domain}:`, (error as Error).message);
|
||||
let errorMessage = error instanceof Error ? error.message : String(error);
|
||||
if (errorMessage.length > 200) {
|
||||
errorMessage = errorMessage.substring(0, 200) + "...";
|
||||
}
|
||||
console.log(`Error checking SSL for ${domain}:`, errorMessage);
|
||||
return {
|
||||
status: GC.DOWN,
|
||||
latency: 0,
|
||||
type: GC.ERROR,
|
||||
error_message: errorMessage,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"pages": [
|
||||
{
|
||||
"title": "Introduction",
|
||||
"content": "v4/introduction"
|
||||
"content": "v4/getting-started/introduction"
|
||||
},
|
||||
{
|
||||
"title": "Quick Start",
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
title: Introduction
|
||||
description: Welcome to Kener - the modern, open-source status page system
|
||||
---
|
||||
|
||||
Kener is an open-source status page system designed to help you monitor and communicate the status of your services effectively.
|
||||
|
||||
> [!NOTE]
|
||||
> This documentation is for kener version 4x. There are few changes from version 3.x. Please refer to the [migration guide](/docs/migration/v3-to-v4) if you are upgrading from version 3.x. If you are looking for version 3.x documentation, you can find it [here](/docs/v3/home).
|
||||
|
||||
Kener is a simple status monitoring app that helps you keep your users informed about the status of your services. It is built with Node.js and Svelte, and uses Redis for caching.
|
||||
|
||||
Kener is built and maintained by [Rajnandan1](https://www.rajnandan.com). It is licensed under the MIT License. Please consider supporting the project by starring it on [GitHub](https://github.com/rajnandan1/kener) or by [sponsoring](https://github.com/sponsors/rajnandan1) the development.
|
||||
|
||||
## Important Links {#important-links}
|
||||
|
||||
1. Live demo - [https://kener.ing](https://kener.ing)
|
||||
2. Feature requests - [raise](https://github.com/rajnandan1/kener/issues/new?template=feature_request.md)
|
||||
3. Bug reports - [report](https://github.com/rajnandan1/kener/issues/new?template=bug_report.md)
|
||||
4. Discussions - [discuss](https://github.com/rajnandan1/kener/discussions)
|
||||
5. Roadmap - [view](https://github.com/users/rajnandan1/projects/4)
|
||||
6. Discord - [join](https://discord.gg/uSTpnuK9XR)
|
||||
7. Contribution - [contribute](/docs/v4/getting-started/contributing)
|
||||
|
||||
Ready to get started? Head over to the [Quick Start](/docs/v4/getting-started/quick-start) guide.
|
||||
|
||||
## Ways to Sponsor {#ways-to-sponsor}
|
||||
|
||||
1. [GitHub Sponsors](https://github.com/sponsors/rajnandan1)
|
||||
2. [PayPal](https://www.paypal.com/paypalme/rajnandan1)
|
||||
3. [Buy Me a Coffee](https://www.buymeacoffee.com/rajnandan1)
|
||||
4. [Github Star](https://github.com/rajnandan1/kener)
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
title: Introduction
|
||||
description: Welcome to Kener - the modern, open-source status page system
|
||||
---
|
||||
|
||||
Kener is an open-source status page system designed to help you monitor and communicate the status of your services effectively.
|
||||
|
||||
> [!NOTE]
|
||||
> This documentation is for kener version 4x. There are few changes from version 3.x. Please refer to the [migration guide](/docs/migration/v3-to-v4) if you are upgrading from version 3.x. If you are looking for version 3.x documentation, you can find it [here](/docs/v3/home).
|
||||
|
||||
## Getting Help {#getting-help}
|
||||
|
||||
If you need help:
|
||||
|
||||
1. Check the documentation
|
||||
2. Join our [Discord community](https://discord.gg/kener)
|
||||
3. Open an issue on [GitHub](https://github.com/rajnandan1/kener)
|
||||
|
||||
Ready to get started? Head over to the [Quick Start](/docs/quickstart) guide.
|
||||
@@ -7,8 +7,9 @@
|
||||
import { javascript } from "@codemirror/lang-javascript";
|
||||
import { githubLight, githubDark } from "@uiw/codemirror-theme-github";
|
||||
import { mode } from "mode-watcher";
|
||||
import EyeClosedIcon from "@lucide/svelte/icons/eye-closed";
|
||||
import EyeOpenIcon from "@lucide/svelte/icons/eye";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
let { data = $bindable() }: { data: any } = $props();
|
||||
|
||||
// Initialize defaults if not set
|
||||
@@ -17,6 +18,8 @@
|
||||
if (!data.query) data.query = "SELECT 1";
|
||||
if (!data.timeout) data.timeout = 5000;
|
||||
|
||||
let showConnectionString = $state(false);
|
||||
|
||||
const dbTypes = [
|
||||
{ value: "pg", label: "PostgreSQL" },
|
||||
{ value: "mysql2", label: "MySQL" },
|
||||
@@ -60,7 +63,7 @@
|
||||
{selectedDbType}
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
{#each dbTypes as db}
|
||||
{#each dbTypes as db (db.value)}
|
||||
<Select.Item value={db.value}>{db.label}</Select.Item>
|
||||
{/each}
|
||||
</Select.Content>
|
||||
@@ -81,8 +84,23 @@
|
||||
id="sql-connection"
|
||||
bind:value={data.connectionString}
|
||||
placeholder={connectionStringPlaceholder}
|
||||
type="password"
|
||||
type={showConnectionString ? "text" : "password"}
|
||||
/>
|
||||
<InputGroup.Addon align="inline-end">
|
||||
<InputGroup.Button
|
||||
type="button"
|
||||
aria-label={showConnectionString ? "Hide connection string" : "Show connection string"}
|
||||
title={showConnectionString ? "Hide connection string" : "Show connection string"}
|
||||
size="icon-xs"
|
||||
onclick={() => (showConnectionString = !showConnectionString)}
|
||||
>
|
||||
{#if showConnectionString}
|
||||
<EyeClosedIcon class="size-4" />
|
||||
{:else}
|
||||
<EyeOpenIcon class="size-4" />
|
||||
{/if}
|
||||
</InputGroup.Button>
|
||||
</InputGroup.Addon>
|
||||
</InputGroup.Root>
|
||||
<p class="text-muted-foreground mt-1 text-xs">Connection string will be stored securely</p>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user