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?
|
speed Int?
|
||||||
usage BigInt?
|
usage BigInt?
|
||||||
uptime Int?
|
uptime Int?
|
||||||
|
networkId Int?
|
||||||
|
network Network? @relation(fields: [networkId], references: [id])
|
||||||
accessPoint AccessPoint? @relation("wifidevice_to_ap", fields: [accessPointId], references: [id])
|
accessPoint AccessPoint? @relation("wifidevice_to_ap", fields: [accessPointId], references: [id])
|
||||||
owner User? @relation("wifidevice_to_owner", fields: [ownerId], references: [id])
|
owner User? @relation("wifidevice_to_owner", fields: [ownerId], references: [id])
|
||||||
user User? @relation("wifidevice_to_user", fields: [userId], references: [id])
|
user User? @relation("wifidevice_to_user", fields: [userId], references: [id])
|
||||||
|
@ -173,13 +175,27 @@ model AccessPointStats {
|
||||||
@@index([timestamp(sort: Desc)])
|
@@index([timestamp(sort: Desc)])
|
||||||
}
|
}
|
||||||
|
|
||||||
model Network {
|
model NetworkStats {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
name String @unique
|
timestamp DateTime @default(now())
|
||||||
shortName String @unique
|
clients Int?
|
||||||
cidr String @unique
|
avgUsage BigInt?
|
||||||
createdAt DateTime @default(now())
|
sumUsage BigInt?
|
||||||
updatedAt DateTime @updatedAt
|
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])
|
@@index([id])
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
deleteOldStats,
|
deleteOldStats,
|
||||||
generateStatsForAllAccessPoints
|
generateStatsForAllAccessPoints
|
||||||
} from './lib/accessPointStats'
|
} from './lib/accessPointStats'
|
||||||
|
import { generateStatsForAllNetworks } from './lib/networkStats'
|
||||||
|
|
||||||
// WARNING! All crontasks are blocking! Do not await inside it
|
// WARNING! All crontasks are blocking! Do not await inside it
|
||||||
|
|
||||||
|
@ -48,6 +49,7 @@ cron.schedule('0 */2 * * * *', () => {
|
||||||
|
|
||||||
cron.schedule('0 */1 * * * *', () => {
|
cron.schedule('0 */1 * * * *', () => {
|
||||||
generateStatsForAllAccessPoints()
|
generateStatsForAllAccessPoints()
|
||||||
|
generateStatsForAllNetworks()
|
||||||
})
|
})
|
||||||
|
|
||||||
cron.schedule('0 0 2 * * *', () => {
|
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 { logError, logInfo, logLow, logSuccess } from './logger'
|
||||||
|
|
||||||
import { performance } from 'perf_hooks'
|
import { performance } from 'perf_hooks'
|
||||||
|
import { getSubnetInfo } from './subnetInfo'
|
||||||
|
|
||||||
const RECENT_THRESHOLD_IN_MINUTES = 2
|
const RECENT_THRESHOLD_IN_MINUTES = 2
|
||||||
|
|
||||||
|
@ -95,11 +96,18 @@ async function updateDB(onlineDevices) {
|
||||||
|
|
||||||
const hostname = device.hostname || mockHostName(device)
|
const hostname = device.hostname || mockHostName(device)
|
||||||
|
|
||||||
|
const network = getSubnetInfo(device.ip)
|
||||||
|
|
||||||
return prisma.wifiDevice
|
return prisma.wifiDevice
|
||||||
.upsert({
|
.upsert({
|
||||||
where: { mac: device.mac },
|
where: { mac: device.mac },
|
||||||
create: {
|
create: {
|
||||||
...device,
|
...device,
|
||||||
|
network: {
|
||||||
|
connect: {
|
||||||
|
id: network.id
|
||||||
|
}
|
||||||
|
},
|
||||||
hostname,
|
hostname,
|
||||||
firstSeen: device.firstSeen || new Date(),
|
firstSeen: device.firstSeen || new Date(),
|
||||||
user,
|
user,
|
||||||
|
@ -111,6 +119,11 @@ async function updateDB(onlineDevices) {
|
||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
...device,
|
...device,
|
||||||
|
network: {
|
||||||
|
connect: {
|
||||||
|
id: network.id
|
||||||
|
}
|
||||||
|
},
|
||||||
hostname,
|
hostname,
|
||||||
user,
|
user,
|
||||||
accessPoint: {
|
accessPoint: {
|
||||||
|
@ -221,7 +234,7 @@ function updateDevicesInfo() {
|
||||||
|
|
||||||
logSuccess({
|
logSuccess({
|
||||||
tags: ['wifiDevices'],
|
tags: ['wifiDevices'],
|
||||||
message: `${onlineDevices.length} dispositivos Wi-Fi atualizados em
|
message: `${onlineDevices.length} dispositivos Wi-Fi atualizados em
|
||||||
${((endTime - startTime) / 1000).toFixed(2)}s. BD em ${(
|
${((endTime - startTime) / 1000).toFixed(2)}s. BD em ${(
|
||||||
(endTimeDB - startTimeDB) /
|
(endTimeDB - startTimeDB) /
|
||||||
1000
|
1000
|
||||||
|
|
|
@ -12,12 +12,6 @@ export default {
|
||||||
icon: 'mdi-view-dashboard-outline',
|
icon: 'mdi-view-dashboard-outline',
|
||||||
route: { name: 'home' }
|
route: { name: 'home' }
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// title: 'Crachá Virtual',
|
|
||||||
// icon: 'mdi-badge-account-horizontal',
|
|
||||||
// route: { name: 'user-id' },
|
|
||||||
// role: 'servant'
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
title: 'Alterar minha senha',
|
title: 'Alterar minha senha',
|
||||||
icon: 'mdi-form-textbox-password',
|
icon: 'mdi-form-textbox-password',
|
||||||
|
@ -71,6 +65,12 @@ export default {
|
||||||
route: { name: 'access-points' },
|
route: { name: 'access-points' },
|
||||||
role: 'superAdmin'
|
role: 'superAdmin'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Status Wi-Fi',
|
||||||
|
icon: 'mdi-chart-bell-curve-cumulative',
|
||||||
|
route: { name: 'wifi-stats' },
|
||||||
|
role: 'superAdmin'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: 'Inspecionar Usuário',
|
title: 'Inspecionar Usuário',
|
||||||
icon: 'mdi-account-search',
|
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',
|
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