Skip to content

Commit

Permalink
fix: argument out of range
Browse files Browse the repository at this point in the history
  • Loading branch information
manuel-rw committed Nov 29, 2024
1 parent 3acf4c2 commit 462d6f0
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 58 deletions.
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
"gridstack",
"homarr",
"jellyfin",
"llen",
"lpop",
"lpush",
"lrange",
"ltrim",
"mantine",
"manuel-rw",
"Meierschlumpf",
Expand Down
48 changes: 23 additions & 25 deletions packages/integrations/src/dashdot/dashdot-integration.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { humanFileSize } from "@homarr/common";
import { } from "@homarr/redis";

import { Integration } from "../base/integration";
import type { HealthMonitoring } from "../types";
import { createChannelEventHistory } from "../../../redis/src/lib/channel";
import "@homarr/redis";

import dayjs from "dayjs";

import { logger } from "@homarr/log";

import { createChannelEventHistory } from "../../../redis/src/lib/channel";
import { Integration } from "../base/integration";
import type { HealthMonitoring } from "../types";

export class DashDotIntegration extends Integration {
public async testConnectionAsync(): Promise<void> {
const response = await fetch(this.appendPathToUrlWithEndingSlash(this.integration.url, "info"));
Expand All @@ -19,8 +22,18 @@ export class DashDotIntegration extends Integration {
const memoryLoad = await this.getCurrentMemoryLoadAsync();
const storageLoad = await this.getCurrentStorageLoadAsync();

const channel = createChannelEventHistory<CpuLoadApi[]>(`integration:${this.integration.id}:history:cpu`);
const history = await channel.getSliceUntilTimeAsync(dayjs().subtract(15, 'minutes').toDate());
const channel = createChannelEventHistory<CpuLoadApi[]>(`integration:${this.integration.id}:history:cpu`, 100);
const history = await channel.getSliceUntilTimeAsync(dayjs().subtract(15, "minutes").toDate());

// logger.info(JSON.stringify(history));

logger.info(
JSON.stringify({
"1min": this.getAverageOfCpu(history[0]).toFixed(2),
"5min": this.getAverageOfCpuFlat(history.slice(0, 4)).toFixed(2),
"15min": this.getAverageOfCpuFlat(history.slice(0, 14)).toFixed(2),
}),
);

return {
cpuUtilization: cpuLoad.sumLoad,
Expand All @@ -41,9 +54,9 @@ export class DashDotIntegration extends Integration {
uptime: info.uptime,
version: `${info.operatingSystemVersion}`,
loadAverage: {
"1min": this.getAverageOfCpu(history[0]),
"5min": this.getAverageOfCpuFlat(history.slice(0, 4)),
"15min": this.getAverageOfCpuFlat(history.slice(0, 14)),
"1min": Math.round(this.getAverageOfCpu(history[0])),
"5min": Math.round(this.getAverageOfCpuFlat(history.slice(0, 4))),
"15min": Math.round(this.getAverageOfCpuFlat(history.slice(0, 14))),
},
};
}
Expand All @@ -62,7 +75,7 @@ export class DashDotIntegration extends Integration {
}

private async getCurrentCpuLoadAsync() {
const channel = createChannelEventHistory<CpuLoadApi[]>(`integration:${this.integration.id}:history:cpu`);
const channel = createChannelEventHistory<CpuLoadApi[]>(`integration:${this.integration.id}:history:cpu`, 100);
const cpu = await fetch(this.appendPathToUrlWithEndingSlash(this.integration.url, "load/cpu"));
const data = (await cpu.json()) as CpuLoadApi[];
await channel.pushAsync(data);
Expand All @@ -72,7 +85,6 @@ export class DashDotIntegration extends Integration {
};
}


private getAverageOfCpuFlat(cpuLoad: CpuLoadApi[][]) {
const averages = cpuLoad.map((load) => this.getAverageOfCpu(load));
return averages.reduce((acc, current) => acc + current, 0) / averages.length;
Expand All @@ -97,15 +109,6 @@ export class DashDotIntegration extends Integration {
loadInBytes: data.load,
};
}

private async getCurrentNetworkLoadAsync() {
const memoryLoad = await fetch(this.appendPathToUrlWithEndingSlash(this.integration.url, "load/network"));
const data = (await memoryLoad.json()) as NetworkLoadApi;
return {
down: data.down,
up: data.up,
};
}
}

/**
Expand All @@ -120,11 +123,6 @@ interface MemoryLoadApi {
load: number;
}

interface NetworkLoadApi {
up: number;
down: number;
}

interface InternalServerInfo {
os: {
distro: string;
Expand Down
17 changes: 8 additions & 9 deletions packages/redis/src/lib/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,8 @@ export const createChannelEventHistory = <TData>(channelName: string, maxElement
if (length <= maxElements) {
return;
}

await Promise.all(new Array(maxElements - length).map(() => getSetClient.lpop(channelName)));
logger.warn(`Trimming from ${length - maxElements} to ${length}`);
await getSetClient.ltrim(channelName, length - maxElements, length);
};

return {
Expand Down Expand Up @@ -230,14 +230,13 @@ export const createChannelEventHistory = <TData>(channelName: string, maxElement
getSliceUntilTimeAsync: async (time: Date) => {
const length = await getSetClient.llen(channelName);
const items: TData[] = [];
while (true) {
const item = await getSetClient.lrange(channelName, length - 2, length - 1);
if (!item[0]) {
break;
}
const deserializedItem = superjson.parse<{ data: TData, timestamp: Date }>(item[0]);
const itemsInCollection = await getSetClient.lrange(channelName, 0, length - 1);

for (let i = 0; i < length -1; i++) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const deserializedItem = superjson.parse<{ data: TData, timestamp: Date }>(itemsInCollection[i]!);
if (deserializedItem.timestamp < time) {
break;
continue;
}
items.push(deserializedItem.data);
}
Expand Down
1 change: 1 addition & 0 deletions packages/request-handler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@homarr/log": "workspace:^0.1.0",
"@homarr/redis": "workspace:^0.1.0",
"dayjs": "^1.11.13",
"pretty-print-error": "^1.1.2",
"superjson": "2.2.1"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type { inferSupportedIntegrationsStrict } from "../../../widgets/src";
import { reduceWidgetOptionsWithDefaultValues } from "../../../widgets/src";
import type { WidgetComponentProps } from "../../../widgets/src/definition";
import type { createCachedIntegrationRequestHandler } from "./cached-integration-request-handler";
import { formatError } from "pretty-print-error";

export const createRequestIntegrationJobHandler = <
TWidgetKind extends WidgetKind,
Expand Down Expand Up @@ -95,7 +96,7 @@ export const createRequestIntegrationJobHandler = <
);
} catch (error) {
logger.error(
`Failed to run integration job integration=${integrationId} inputHash='${inputHash}' error=${error as string}`,
`Failed to run integration job integration=${integrationId} inputHash='${inputHash}' error=${formatError(error)}`,
);
}
}
Expand Down
6 changes: 3 additions & 3 deletions packages/widgets/src/health-monitoring/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,15 +169,15 @@ export default function HealthMonitoringWidget({ options, integrationIds }: Widg
</List.Item>
<List m="0.5cqmin" withPadding center spacing="0.5cqmin" icon={<IconCpu size="1cqmin" />}>
<List.Item className="health-monitoring-information-load-average-1min">
{t("widget.healthMonitoring.popover.minute")} {healthInfo.loadAverage["1min"]}
{t("widget.healthMonitoring.popover.minute")} {healthInfo.loadAverage["1min"]}%
</List.Item>
<List.Item className="health-monitoring-information-load-average-5min">
{t("widget.healthMonitoring.popover.minutes", { count: 5 })}{" "}
{healthInfo.loadAverage["5min"]}
{healthInfo.loadAverage["5min"]}%
</List.Item>
<List.Item className="health-monitoring-information-load-average-15min">
{t("widget.healthMonitoring.popover.minutes", { count: 15 })}{" "}
{healthInfo.loadAverage["15min"]}
{healthInfo.loadAverage["15min"]}%
</List.Item>
</List>
</List>
Expand Down
50 changes: 30 additions & 20 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 462d6f0

Please sign in to comment.