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
public/styles/style.css
README.md
Dockerfile
Dockerfile
data/db.sqlite3
data/data.csv

5
.gitignore vendored

@ -2,5 +2,10 @@ node_modules/
rubbish/
db.sqlite3
data.csv
data/db.sqlite3
data/data.csv
public/styles/style.css
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
```
touch db.sqlite3
*untested now
mkdir data
docker run --rm -d \
--name netmon \
-p 4000:3000 \
-e dstHost=1.1.1.1 \
-e dstPort=53 \
--mount type=bind,source=$(pwd)/db.sqlite3,target=/app/db.sqlite3 \
-v $(pwd)/data:/app/data \
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
```
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();
const db = new sqlite3.Database('db.sqlite3', (err) => {
const db = new sqlite3.Database('data/db.sqlite3', (err) => {
if (err) {
console.error(err.message);
throw err;

2
docker-compose.yml

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

81
swarm/docker-compose.netmon.yml

@ -6,15 +6,18 @@ networks:
external: true
volumes:
netmon-data:
data-david:
data-brent:
data-shannon:
data-josh:
services:
app:
image: daveplsno/netmon:latest
image: daveplsno/netmon:4
hostname: netmon
env_file: .env.netmon
volumes:
- netmon-data:/app
- data-david:/app/data
networks:
- swarmnet-public
deploy:
@ -32,3 +35,75 @@ services:
- traefik.http.routers.${netmonTraefikGrp? Variable not set}.tls=true
- traefik.http.routers.${netmonTraefikGrp? Variable not set}.tls.certresolver=le
- 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)
# 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 $(cat .env.deploy | cut -f 1 -d '=' $1)

2
swarm/netmonStatus.bash

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

24
views/Card.jsx

@ -1,12 +1,25 @@
const React = require('react');
import { TimeBetweenRows } from './DiffCard';
import { TimeDiff } from './TimeDiff';
export const Card = ({ dbdata }) => {
return dbdata.reverse().map((row, index) => {
const nextRow = dbdata[index + 1];
const lastRow = dbdata.slice()[0];
const textStyles = 'flex justify-center items-center py-2 text-sm';
return (
<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
className={`shadow-md p-1 flex items-center justify-between ${
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="p-1 pr-2">{row.status === 1 ? '🟢' : '🔴'}</div>
</div>
{!!nextRow ? (
<div className="flex justify-center items-center py-1 text-gray-400">
<TimeBetweenRows row={row} nextRow={nextRow} />
<div
className={`${textStyles} ${
row.status === 0 ? 'text-green-600' : 'text-red-600'
}`}
>
<TimeDiff row={row} nextRow={nextRow} />
</div>
) : null}
</div>

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

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