Collect campus status
This commit is contained in:
parent
535b3956a1
commit
f6029ae134
1929
server/package-lock.json
generated
1929
server/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
|
@ -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])
|
||||
}
|
||||
|
|
|
@ -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 * * *', () => {
|
||||
|
|
57
server/src/lib/networkStats.js
Normal file
57
server/src/lib/networkStats.js
Normal 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)
|
||||
}
|
||||
}
|
|
@ -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: {
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
7
web/src/views/WifiStats.vue
Normal file
7
web/src/views/WifiStats.vue
Normal file
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<v-container>stat</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {}
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user