Browse Source

Merge pull request 'develop' (#1) from develop into master

Reviewed-on: https://git.poyner.page/david/netmon/pulls/1
master
david 3 years ago
parent
commit
1cc524877d
  1. 4
      .dockerignore
  2. 5
      .gitignore
  3. 41
      README.md
  4. 0
      data/.keep
  5. 2
      database.js
  6. 2
      docker-compose.yml
  7. 12
      netmon.py
  8. 81
      swarm/docker-compose.netmon.yml
  9. 2
      swarm/netmonDeploy.bash
  10. 2
      swarm/netmonStatus.bash
  11. 24
      views/Card.jsx
  12. 8
      views/TimeDiff.jsx

4
.dockerignore

@ -4,4 +4,6 @@ db.sqlite3
data.csv data.csv
public/styles/style.css public/styles/style.css
README.md README.md
Dockerfile Dockerfile
data/db.sqlite3
data/data.csv

5
.gitignore vendored

@ -2,5 +2,10 @@ node_modules/
rubbish/ rubbish/
db.sqlite3 db.sqlite3
data.csv data.csv
data/db.sqlite3
data/data.csv
public/styles/style.css public/styles/style.css
swarm/.env.deploy swarm/.env.deploy
swarm/.env.netmon.brent
swarm/.env.netmon.josh
swarm/.env.netmon.shannon

41
README.md

@ -3,13 +3,14 @@
super basic way to run super basic way to run
``` ```
touch db.sqlite3 *untested now
mkdir data
docker run --rm -d \ docker run --rm -d \
--name netmon \ --name netmon \
-p 4000:3000 \ -p 4000:3000 \
-e dstHost=1.1.1.1 \ -e dstHost=1.1.1.1 \
-e dstPort=53 \ -e dstPort=53 \
--mount type=bind,source=$(pwd)/db.sqlite3,target=/app/db.sqlite3 \ -v $(pwd)/data:/app/data \
daveplsno/netmon:latest daveplsno/netmon:latest
``` ```
@ -36,3 +37,39 @@ npm install -D tailwindcss@latest postcss@latest autoprefixer@latest postcss-cli
npm install tailwindcss postcss autoprefixer postcss-cli npm install tailwindcss postcss autoprefixer postcss-cli
``` ```
dev outside the container
```
python3 -m http.server 8000
python3 netmon.py monitor
npm run dev
```
## docker img update steps
update tag
`docker-compose build`
`docker push daveplsno/netmon:<tag>`
misc container things
```
docker run --rm \
--name netmonThrowaway \
-p 4000:3000 \
-e dstHost=1.1.1.1 \
-e dstPort=53 \
daveplsno/netmon:2
# used this to migrate data between old/new mounts
docker run --rm -it --name pls -w /app \
-v netmon_netmon-data:/dataOld \
-v netmon_data-david:/dataNew \
nikolaik/python-nodejs:python3.9-nodejs16-alpine sh
docker run --rm -it --name pls -w /app \
-v netmon_netmon-data-shannon:/dataOld \
-v netmon_data-shannon:/dataNew \
nikolaik/python-nodejs:python3.9-nodejs16-alpine sh
```

0
data/.keep

2
database.js

@ -1,6 +1,6 @@
var sqlite3 = require('sqlite3').verbose(); var sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database('db.sqlite3', (err) => { const db = new sqlite3.Database('data/db.sqlite3', (err) => {
if (err) { if (err) {
console.error(err.message); console.error(err.message);
throw err; throw err;

2
docker-compose.yml

@ -5,4 +5,4 @@ services:
netmon-build: netmon-build:
build: build:
context: . context: .
image: daveplsno/netmon:latest image: daveplsno/netmon:4

12
netmon.py

@ -15,7 +15,7 @@ path = Path(__file__).resolve().parent
def update_db(payload): def update_db(payload):
conn = None conn = None
try: try:
db = (str(path) + "/db.sqlite3") db = (str(path) + "/data/db.sqlite3")
conn = sqlite3.connect(db) conn = sqlite3.connect(db)
c = conn.cursor() c = conn.cursor()
@ -76,12 +76,12 @@ def secs_to_HMS(secs):
def record_file_exist(): def record_file_exist():
""" Check if records file exist """ """ Check if records file exist """
return os.path.isfile('data.csv') return os.path.isfile('data/data.csv')
def create_record_file(): def create_record_file():
""" Create a new record file """ """ Create a new record file """
with open('data.csv', 'a') as csvfile: with open('data/data.csv', 'a') as csvfile:
columns = ['timestamp', 'status'] columns = ['timestamp', 'status']
writer = csv.DictWriter(csvfile, fieldnames=columns) writer = csv.DictWriter(csvfile, fieldnames=columns)
writer.writeheader() writer.writeheader()
@ -90,7 +90,7 @@ def create_record_file():
def last_record_status(): def last_record_status():
""" Get last record """ """ Get last record """
result = None result = None
with open('data.csv', 'r') as csvfile: with open('data/data.csv', 'r') as csvfile:
reader = csv.DictReader(csvfile) reader = csv.DictReader(csvfile)
for row in reader: for row in reader:
result = row result = row
@ -99,7 +99,7 @@ def last_record_status():
def write_record(status): def write_record(status):
""" Create a new record """ """ Create a new record """
with open('data.csv', 'a') as csvfile: with open('data/data.csv', 'a') as csvfile:
columns = ['timestamp', 'status'] columns = ['timestamp', 'status']
writer = csv.DictWriter(csvfile, fieldnames=columns) writer = csv.DictWriter(csvfile, fieldnames=columns)
writer.writerow({'timestamp': str(current_timestamp()), 'status': status}) writer.writerow({'timestamp': str(current_timestamp()), 'status': status})
@ -110,7 +110,7 @@ def get_total_downtime():
seconds = 0 seconds = 0
down = None down = None
up = None up = None
with open('data.csv', 'r') as csvfile: with open('data/data.csv', 'r') as csvfile:
reader = csv.DictReader(csvfile) reader = csv.DictReader(csvfile)
for record in reader: for record in reader:
try: try:

81
swarm/docker-compose.netmon.yml

@ -6,15 +6,18 @@ networks:
external: true external: true
volumes: volumes:
netmon-data: data-david:
data-brent:
data-shannon:
data-josh:
services: services:
app: app:
image: daveplsno/netmon:latest image: daveplsno/netmon:4
hostname: netmon hostname: netmon
env_file: .env.netmon env_file: .env.netmon
volumes: volumes:
- netmon-data:/app - data-david:/app/data
networks: networks:
- swarmnet-public - swarmnet-public
deploy: deploy:
@ -32,3 +35,75 @@ services:
- traefik.http.routers.${netmonTraefikGrp? Variable not set}.tls=true - traefik.http.routers.${netmonTraefikGrp? Variable not set}.tls=true
- traefik.http.routers.${netmonTraefikGrp? Variable not set}.tls.certresolver=le - traefik.http.routers.${netmonTraefikGrp? Variable not set}.tls.certresolver=le
- traefik.http.services.${netmonTraefikGrp? Variable not set}.loadbalancer.server.port=3000 - traefik.http.services.${netmonTraefikGrp? Variable not set}.loadbalancer.server.port=3000
brent:
image: daveplsno/netmon:4
hostname: netmonBrent
env_file: .env.netmon.brent
volumes:
- data-brent:/app/data
networks:
- swarmnet-public
deploy:
restart_policy:
condition: on-failure
placement:
constraints:
- node.labels.${netmonNode? Variable not set} == true
labels:
- traefik.enable=true
- traefik.docker.network=swarmnet-public
- traefik.constraint-label=swarmnet-public
- traefik.http.routers.${netmonBrentTraefikGrp? Variable not set}.rule=Host(`${netmonBrentTraefikUrl? Variable not set}`)
- traefik.http.routers.${netmonBrentTraefikGrp? Variable not set}.entrypoints=websecure
- traefik.http.routers.${netmonBrentTraefikGrp? Variable not set}.tls=true
- traefik.http.routers.${netmonBrentTraefikGrp? Variable not set}.tls.certresolver=le
- traefik.http.services.${netmonBrentTraefikGrp? Variable not set}.loadbalancer.server.port=3000
shannon:
image: daveplsno/netmon:4
hostname: netmonShannon
env_file: .env.netmon.shannon
volumes:
- data-shannon:/app/data
networks:
- swarmnet-public
deploy:
restart_policy:
condition: on-failure
placement:
constraints:
- node.labels.${netmonNode? Variable not set} == true
labels:
- traefik.enable=true
- traefik.docker.network=swarmnet-public
- traefik.constraint-label=swarmnet-public
- traefik.http.routers.${netmonShannonTraefikGrp? Variable not set}.rule=Host(`${netmonShannonTraefikUrl? Variable not set}`)
- traefik.http.routers.${netmonShannonTraefikGrp? Variable not set}.entrypoints=websecure
- traefik.http.routers.${netmonShannonTraefikGrp? Variable not set}.tls=true
- traefik.http.routers.${netmonShannonTraefikGrp? Variable not set}.tls.certresolver=le
- traefik.http.services.${netmonShannonTraefikGrp? Variable not set}.loadbalancer.server.port=3000
josh:
image: daveplsno/netmon:4
hostname: netmonJosh
env_file: .env.netmon.josh
volumes:
- data-josh:/app/data
networks:
- swarmnet-public
deploy:
restart_policy:
condition: on-failure
placement:
constraints:
- node.labels.${netmonNode? Variable not set} == true
labels:
- traefik.enable=true
- traefik.docker.network=swarmnet-public
- traefik.constraint-label=swarmnet-public
- traefik.http.routers.${netmonJoshTraefikGrp? Variable not set}.rule=Host(`${netmonJoshTraefikUrl? Variable not set}`)
- traefik.http.routers.${netmonJoshTraefikGrp? Variable not set}.entrypoints=websecure
- traefik.http.routers.${netmonJoshTraefikGrp? Variable not set}.tls=true
- traefik.http.routers.${netmonJoshTraefikGrp? Variable not set}.tls.certresolver=le
- traefik.http.services.${netmonJoshTraefikGrp? Variable not set}.loadbalancer.server.port=3000

2
swarm/netmonDeploy.bash

@ -2,7 +2,7 @@
export $(cat .env.deploy) export $(cat .env.deploy)
# deploy to swarm # deploy to swarm
docker stack deploy -c docker-compose.netmon.yml netmon docker stack deploy -c docker-compose.netmon.yml --prune netmon
# unset the env vars # unset the env vars
unset $(cat .env.deploy | cut -f 1 -d '=' $1) unset $(cat .env.deploy | cut -f 1 -d '=' $1)

2
swarm/netmonStatus.bash

@ -1,2 +1,2 @@
#!/bin/bash #!/bin/bash
docker service ps netmon_app docker stack services netmon

24
views/Card.jsx

@ -1,12 +1,25 @@
const React = require('react'); const React = require('react');
import { TimeBetweenRows } from './DiffCard'; import { TimeDiff } from './TimeDiff';
export const Card = ({ dbdata }) => { export const Card = ({ dbdata }) => {
return dbdata.reverse().map((row, index) => { return dbdata.reverse().map((row, index) => {
const nextRow = dbdata[index + 1]; const nextRow = dbdata[index + 1];
const lastRow = dbdata.slice()[0];
const textStyles = 'flex justify-center items-center py-2 text-sm';
return ( return (
<div className="grid grid-cols-1 px-2"> <div className="grid grid-cols-1 px-2">
{row.id === lastRow.id ? (
<div
className={`${textStyles} ${
row.status === 1 ? 'text-green-600' : 'text-red-600'
}`}
>
{row.status === 1 ? 'yeh all good for ' : 'absolutely cooked for '}
<TimeDiff row={row} nextRow={lastRow} />
</div>
) : null}
<div <div
className={`shadow-md p-1 flex items-center justify-between ${ className={`shadow-md p-1 flex items-center justify-between ${
row.status === 1 ? 'bg-green-50' : 'bg-red-50' row.status === 1 ? 'bg-green-50' : 'bg-red-50'
@ -15,10 +28,13 @@ export const Card = ({ dbdata }) => {
<div className="flex-grow pl-2">{row.timestamp}</div> <div className="flex-grow pl-2">{row.timestamp}</div>
<div className="p-1 pr-2">{row.status === 1 ? '🟢' : '🔴'}</div> <div className="p-1 pr-2">{row.status === 1 ? '🟢' : '🔴'}</div>
</div> </div>
{!!nextRow ? ( {!!nextRow ? (
<div className="flex justify-center items-center py-1 text-gray-400"> <div
<TimeBetweenRows row={row} nextRow={nextRow} /> className={`${textStyles} ${
row.status === 0 ? 'text-green-600' : 'text-red-600'
}`}
>
<TimeDiff row={row} nextRow={nextRow} />
</div> </div>
) : null} ) : null}
</div> </div>

8
views/DiffCard.jsx → views/TimeDiff.jsx

@ -1,18 +1,18 @@
const React = require('react'); const React = require('react');
const dayjs = require('dayjs'); const dayjs = require('dayjs');
export const TimeBetweenRows = ({ row, nextRow }) => { export const TimeDiff = ({ row, nextRow }) => {
if (nextRow) { if (nextRow) {
const now = dayjs();
const firstDate = dayjs(row.timestamp); const firstDate = dayjs(row.timestamp);
const secondDate = dayjs(nextRow.timestamp); const secondDate = dayjs(nextRow.timestamp);
const theDiff = firstDate.diff(secondDate); const theDiff =
row.id === nextRow.id ? now.diff(firstDate) : firstDate.diff(secondDate);
const theSeconds = theDiff / 1000; const theSeconds = theDiff / 1000;
const theMinutes = theSeconds / 60; const theMinutes = theSeconds / 60;
const theHours = theMinutes / 60; const theHours = theMinutes / 60;
const theDays = theHours / 24; const theDays = theHours / 24;
// console.log(theDiff, theSeconds, theMinutes, theHours, theDays);
const renderSecs = <>{theSeconds === 1 ? 'sec' : 'secs'}</>; const renderSecs = <>{theSeconds === 1 ? 'sec' : 'secs'}</>;
const renderMins = <>{theMinutes === 1 ? 'min ' : 'mins '}</>; const renderMins = <>{theMinutes === 1 ? 'min ' : 'mins '}</>;
const renderHrs = <>{theHours === 1 ? 'hr ' : 'hrs '}</>; const renderHrs = <>{theHours === 1 ? 'hr ' : 'hrs '}</>;
Loading…
Cancel
Save