Skip to content

Commit

Permalink
chore: use k8s node client and watchers for faster updates
Browse files Browse the repository at this point in the history
  • Loading branch information
achauve committed Feb 4, 2024
1 parent 1a1798d commit b6e21da
Show file tree
Hide file tree
Showing 10 changed files with 449 additions and 330 deletions.
2 changes: 2 additions & 0 deletions .talismanrc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ fileignoreconfig:
checksum: feca2fb4f890b31270b7c02f9507389fcf680084113d9e7a13aa401eb3be934f
- filename: sentry.edge.config.ts
checksum: 045356a04fbdcee166279d6e0d75fd38c607177aa20414eed82fa39fcb948ee9
- filename: src/components/kube/cnpgCluster.tsx
checksum: 6bb5c888d67ffea6779f19b5d00b13defbdf8e2df0ed7040e2df35623fb941fc
- filename: src/components/kube/cronjob.tsx
checksum: 90f7b4d1ff3c0d30b35c52a9c80ccf2677db11b35a8f5c454d281558cf620a8f
- filename: src/components/kube/deployment.tsx
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@fortawesome/free-solid-svg-icons": "^6.4.2",
"@fortawesome/react-fontawesome": "^0.2.0",
"@heroicons/react": "^2.0.18",
"@kubernetes/client-node": "^0.20.0",
"@material-tailwind/react": "^2.1.4",
"@opentelemetry/exporter-trace-otlp-http": "^0.46.0",
"@opentelemetry/resources": "^1.19.0",
Expand Down
250 changes: 122 additions & 128 deletions src/components/kube/cnpgCluster.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import dayjs from "dayjs"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import {
faHardDrive,
faMemory,
faMicrochip,
faFloppyDisk,
faFileZipper,
} from "@fortawesome/free-solid-svg-icons"
import { faFloppyDisk } from "@fortawesome/free-solid-svg-icons"

import { getCnpgClusterStatus, Cluster, getInstances } from "@/lib/kube/types"
import Badge from "@/components/ui/badge"
Expand All @@ -24,10 +18,10 @@ export default function ClusterWidget({ cluster }: { cluster: Cluster }) {
<Meta cluster={cluster} />
<Instances cluster={cluster} />
<Backup cluster={cluster} />
<Dumps cluster={cluster} />
<Memory cluster={cluster} />
<Cpu cluster={cluster} />
<Storage cluster={cluster} />
{/* <Dumps cluster={cluster} /> */}
{/* <Memory cluster={cluster} /> */}
{/* <Cpu cluster={cluster} /> */}
{/* <Storage cluster={cluster} /> */}
<Phase cluster={cluster} />
</div>
</div>
Expand Down Expand Up @@ -109,123 +103,123 @@ function Backup({ cluster }: { cluster: Cluster }) {
)
}

function Dumps({ cluster }: { cluster: Cluster }) {
if (!cluster.dumps) return

if (cluster.dumps.length === 0) {
return (
<div className="font-bold text-xs text-orange-500 pr-2">
<FontAwesomeIcon
className={`h-4 w-4 inline-block mr-2`}
icon={faFileZipper}
/>
no dump
</div>
)
}
return (
<Tooltip
content={
<>
<div className="text-sm text-gray-700 font-bold">Dumps</div>
<ul>
{cluster.dumps?.map((dump) => {
return (
<li key={dump.name}>
{dayjs(dump.lastModified).format("YYYY/MM/DD HH:mm")}
{" - "}
{dump.size
? formatBytes({ bytes: dump.size, decimals: 2 })
: "empty"}{" "}
: {dump.name}
</li>
)
})}
</ul>
</>
}
>
<div className="font-bold text-xs text-gray-500 pr-2">
<FontAwesomeIcon
className={`h-4 w-4 inline-block mr-2`}
icon={faFileZipper}
/>
{cluster.dumps.length + " dumps"}
{` - last: ${formatBytes({
bytes: cluster.dumps[cluster.dumps.length - 1].size ?? 0,
decimals: 2,
})}`}
</div>
</Tooltip>
)
}

function Memory({ cluster }: { cluster: Cluster }) {
return (
<Tooltip
content={
<>
<div className="text-sm text-gray-700 font-bold">Memory</div>
request / current / limit
</>
}
>
<div className="font-bold text-xs text-gray-500 pr-2">
<FontAwesomeIcon
className={`h-4 w-4 inline-block mr-2`}
icon={faMemory}
/>
{`${cluster.spec.resources?.requests?.memory ?? "none"} / ${
cluster.podStats.memory
} / ${cluster.spec.resources?.limits?.memory ?? "none"}`}
</div>
</Tooltip>
)
}

function Cpu({ cluster }: { cluster: Cluster }) {
return (
<Tooltip
content={
<>
<div className="text-sm text-gray-700 font-bold">CPU</div>
request / current / limit
</>
}
>
<div className="font-bold text-xs text-gray-500 pr-2">
<FontAwesomeIcon
className={`h-4 w-4 inline-block mr-2`}
icon={faMicrochip}
/>
{`${cluster.spec.resources?.requests?.cpu ?? "none"} / ${
cluster.podStats.cpu
} / ${cluster.spec.resources?.limits?.cpu ?? "none"}`}
</div>
</Tooltip>
)
}

function Storage({ cluster }: { cluster: Cluster }) {
return (
<Tooltip
content={
<>
<div className="text-sm text-gray-700 font-bold">Storage</div>
%used (used / total)
</>
}
>
<div className="font-bold text-xs text-gray-500 pr-2">
<FontAwesomeIcon
className={`h-4 w-4 inline-block mr-2`}
icon={faHardDrive}
/>
{`${cluster.storageStats.percentUsed} (${cluster.storageStats.used} / ${cluster.storageStats.total})`}
</div>
</Tooltip>
)
}
// function Dumps({ cluster }: { cluster: Cluster }) {
// if (!cluster.dumps) return
//
// if (cluster.dumps.length === 0) {
// return (
// <div className="font-bold text-xs text-orange-500 pr-2">
// <FontAwesomeIcon
// className={`h-4 w-4 inline-block mr-2`}
// icon={faFileZipper}
// />
// no dump
// </div>
// )
// }
// return (
// <Tooltip
// content={
// <>
// <div className="text-sm text-gray-700 font-bold">Dumps</div>
// <ul>
// {cluster.dumps?.map((dump) => {
// return (
// <li key={dump.name}>
// {dayjs(dump.lastModified).format("YYYY/MM/DD HH:mm")}
// {" - "}
// {dump.size
// ? formatBytes({ bytes: dump.size, decimals: 2 })
// : "empty"}{" "}
// : {dump.name}
// </li>
// )
// })}
// </ul>
// </>
// }
// >
// <div className="font-bold text-xs text-gray-500 pr-2">
// <FontAwesomeIcon
// className={`h-4 w-4 inline-block mr-2`}
// icon={faFileZipper}
// />
// {cluster.dumps.length + " dumps"}
// {` - last: ${formatBytes({
// bytes: cluster.dumps[cluster.dumps.length - 1].size ?? 0,
// decimals: 2,
// })}`}
// </div>
// </Tooltip>
// )
// }
//
// function Memory({ cluster }: { cluster: Cluster }) {
// return (
// <Tooltip
// content={
// <>
// <div className="text-sm text-gray-700 font-bold">Memory</div>
// request / current / limit
// </>
// }
// >
// <div className="font-bold text-xs text-gray-500 pr-2">
// <FontAwesomeIcon
// className={`h-4 w-4 inline-block mr-2`}
// icon={faMemory}
// />
// {`${cluster.spec.resources?.requests?.memory ?? "none"} / ${
// cluster.podStats.memory
// } / ${cluster.spec.resources?.limits?.memory ?? "none"}`}
// </div>
// </Tooltip>
// )
// }
//
// function Cpu({ cluster }: { cluster: Cluster }) {
// return (
// <Tooltip
// content={
// <>
// <div className="text-sm text-gray-700 font-bold">CPU</div>
// request / current / limit
// </>
// }
// >
// <div className="font-bold text-xs text-gray-500 pr-2">
// <FontAwesomeIcon
// className={`h-4 w-4 inline-block mr-2`}
// icon={faMicrochip}
// />
// {`${cluster.spec.resources?.requests?.cpu ?? "none"} / ${
// cluster.podStats.cpu
// } / ${cluster.spec.resources?.limits?.cpu ?? "none"}`}
// </div>
// </Tooltip>
// )
// }
//
// function Storage({ cluster }: { cluster: Cluster }) {
// return (
// <Tooltip
// content={
// <>
// <div className="text-sm text-gray-700 font-bold">Storage</div>
// %used (used / total)
// </>
// }
// >
// <div className="font-bold text-xs text-gray-500 pr-2">
// <FontAwesomeIcon
// className={`h-4 w-4 inline-block mr-2`}
// icon={faHardDrive}
// />
// {`${cluster.storageStats.percentUsed} (${cluster.storageStats.used} / ${cluster.storageStats.total})`}
// </div>
// </Tooltip>
// )
// }

function Phase({ cluster }: { cluster: Cluster }) {
if (cluster.status.phase !== "Cluster in healthy state") {
Expand Down
6 changes: 5 additions & 1 deletion src/components/kube/events.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ export default function EventsWidget({ namespace }: { namespace: Namespace }) {
.filter((event) =>
dayjs(event.lastTimestamp).isAfter(dayjs().subtract(1, "hour"))
)
.sort((a, b) => b.lastTimestamp.getTime() - a.lastTimestamp.getTime())
.sort(
(a, b) =>
new Date(b.lastTimestamp).getTime() -
new Date(a.lastTimestamp).getTime()
)
.map((event) => (
<Tooltip
key={event.metadata.name}
Expand Down
6 changes: 4 additions & 2 deletions src/instrumentation.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
SentrySpanProcessor,
SentryPropagator,
} from "@sentry/opentelemetry-node"
import { startCron } from "./lib/cron"
import { startWatchingKube } from "./lib/node-kube"
// import { startCron } from "./lib/cron"

const sdk = new NodeSDK({
resource: new Resource({
Expand All @@ -19,4 +20,5 @@ const sdk = new NodeSDK({

sdk.start()

startCron()
// startCron()
startWatchingKube()
9 changes: 7 additions & 2 deletions src/lib/cron.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import _ from "lodash"
import cron from "node-cron"
import { makeCachedData } from "@/lib/kube/types"
import { getKubeData } from "@/lib/kube"

export async function refreshData() {
console.log("-- refreshing data")
const start = new Date().getTime()
global.cachedData = makeCachedData(await getKubeData())
console.log("-----> ok")
console.log("refreshed data in", new Date().getTime() - start, "ms")
}

export const debouncedRefreshData = _.debounce(refreshData, 1000, {
maxWait: 1000,
})

export function startCron() {
global.cachedData = makeCachedData({ namespaces: [] })
cron.schedule("*/10 * * * * *", refreshData)
Expand Down
Loading

0 comments on commit b6e21da

Please sign in to comment.