Collect campus status

This commit is contained in:
Douglas Barone 2022-12-08 10:24:45 -04:00
parent 535b3956a1
commit f6029ae134
9 changed files with 1053 additions and 1030 deletions

1929
server/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
-- AlterTable
ALTER TABLE "WifiDevice" ADD COLUMN "networkId" INTEGER;
-- CreateTable
CREATE TABLE "NetworkStats" (
"id" SERIAL NOT NULL,
"timestamp" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"clients" INTEGER,
"avgUsage" BIGINT,
"sumUsage" BIGINT,
"networkId" INTEGER NOT NULL,
CONSTRAINT "NetworkStats_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "NetworkStats_timestamp_idx" ON "NetworkStats"("timestamp" DESC);
-- AddForeignKey
ALTER TABLE "WifiDevice" ADD CONSTRAINT "WifiDevice_networkId_fkey" FOREIGN KEY ("networkId") REFERENCES "Network"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "NetworkStats" ADD CONSTRAINT "NetworkStats_networkId_fkey" FOREIGN KEY ("networkId") REFERENCES "Network"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@ -101,6 +101,8 @@ model WifiDevice {
speed Int?
usage BigInt?
uptime Int?
networkId Int?
network Network? @relation(fields: [networkId], references: [id])
accessPoint AccessPoint? @relation("wifidevice_to_ap", fields: [accessPointId], references: [id])
owner User? @relation("wifidevice_to_owner", fields: [ownerId], references: [id])
user User? @relation("wifidevice_to_user", fields: [userId], references: [id])
@ -173,13 +175,27 @@ model AccessPointStats {
@@index([timestamp(sort: Desc)])
}
model Network {
model NetworkStats {
id Int @id @default(autoincrement())
name String @unique
shortName String @unique
cidr String @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
timestamp DateTime @default(now())
clients Int?
avgUsage BigInt?
sumUsage BigInt?
networkId Int
network Network @relation(fields: [networkId], references: [id])
@@index([timestamp(sort: Desc)])
}
model Network {
id Int @id @default(autoincrement())
name String @unique
shortName String @unique
cidr String @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
NetworkStats NetworkStats[]
WifiDevice WifiDevice[]
@@index([id])
}

View File

@ -9,6 +9,7 @@ import {
deleteOldStats,
generateStatsForAllAccessPoints
} from './lib/accessPointStats'
import { generateStatsForAllNetworks } from './lib/networkStats'
// WARNING! All crontasks are blocking! Do not await inside it
@ -48,6 +49,7 @@ cron.schedule('0 */2 * * * *', () => {
cron.schedule('0 */1 * * * *', () => {
generateStatsForAllAccessPoints()
generateStatsForAllNetworks()
})
cron.schedule('0 0 2 * * *', () => {

View File

@ -0,0 +1,57 @@
import prisma from '../prisma'
import { logError, logSuccess } from './logger'
import { subDays } from 'date-fns'
const DAYS_TO_KEEP = 90
async function generateStatsForNetwork(shortName) {
const timestamp = new Date()
const dbStats = await prisma.wifiDevice.aggregate({
where: {
status: 'ONLINE',
network: {
shortName
}
},
_count: {
_all: true
},
_avg: {
usage: true
},
_sum: {
usage: true
}
})
const stats = {
timestamp: timestamp.toISOString(),
clients: dbStats._count._all,
avgUsage: Math.floor(dbStats._avg.usage, 0),
sumUsage: dbStats._sum.usage || 0
}
prisma.networkStats.create({
data: {
network: {
connect: {
shortName
}
},
...stats
}
})
}
export async function generateStatsForAllNetworks() {
const networks = await prisma.network.findMany()
for (const network of networks) {
await generateStatsForNetwork(network.shortName)
}
}

View File

@ -8,6 +8,7 @@ import { pubsub, USER_PRESENCE_UPDATED, ACCESS_POINTS_UPDATED } from '../pubsub'
import { logError, logInfo, logLow, logSuccess } from './logger'
import { performance } from 'perf_hooks'
import { getSubnetInfo } from './subnetInfo'
const RECENT_THRESHOLD_IN_MINUTES = 2
@ -95,11 +96,18 @@ async function updateDB(onlineDevices) {
const hostname = device.hostname || mockHostName(device)
const network = getSubnetInfo(device.ip)
return prisma.wifiDevice
.upsert({
where: { mac: device.mac },
create: {
...device,
network: {
connect: {
id: network.id
}
},
hostname,
firstSeen: device.firstSeen || new Date(),
user,
@ -111,6 +119,11 @@ async function updateDB(onlineDevices) {
},
update: {
...device,
network: {
connect: {
id: network.id
}
},
hostname,
user,
accessPoint: {

View File

@ -12,12 +12,6 @@ export default {
icon: 'mdi-view-dashboard-outline',
route: { name: 'home' }
},
// {
// title: 'Crachá Virtual',
// icon: 'mdi-badge-account-horizontal',
// route: { name: 'user-id' },
// role: 'servant'
// },
{
title: 'Alterar minha senha',
icon: 'mdi-form-textbox-password',
@ -71,6 +65,12 @@ export default {
route: { name: 'access-points' },
role: 'superAdmin'
},
{
title: 'Status Wi-Fi',
icon: 'mdi-chart-bell-curve-cumulative',
route: { name: 'wifi-stats' },
role: 'superAdmin'
},
{
title: 'Inspecionar Usuário',
icon: 'mdi-account-search',

View File

@ -207,6 +207,16 @@ const routes = [
}
]
},
{
path: '/wifi-stats',
name: 'wifi-stats',
meta: {
title: 'Status Wi-Fi',
roles: ['superAdmin']
},
component: () =>
import(/* webpackChunkName: "wifi-stats" */ '../views/WifiStats.vue')
},
{
path: '/access-points/:id/clients',

View File

@ -0,0 +1,7 @@
<template>
<v-container>stat</v-container>
</template>
<script>
export default {}
</script>