Skip to content

Commit

Permalink
Add notifications for cpu, memory, added, removed, state change (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
austinwbest committed Nov 21, 2023
1 parent d8b962c commit 10c9411
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 36 deletions.
81 changes: 49 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,47 +20,62 @@ Simple UI driven way to manage updates & notifications for containers. As this i
- Auto update
- Check for update

### Image
`ghcr.io/notifiarr/dockwatch:main`
### Permissions
No matter how docker is installed (native, unraid, etc), it is required that the user running the container has permission to use the docker commands. View `root/app/www/public/functions/docker.php` to see what is used

Unraid: This is built into the container with
```
addgroup -g 281 unraiddocker && \
usermod -aG unraiddocker abc
```

### Install
`docker pull ghcr.io/notifiarr/dockwatch:main`
Ubuntu: This is an example
```
usermod -aG ping abc
```

### Run
This is an example from an Unraid install
This is an unraid example, adjust paths and settings for your setup

```
docker run
-d
--name='dockwatch'
--net='custom-bridge'
-e TZ="America/New_York"
-e HOST_OS="Unraid"
-e 'PUID'='1001'
-e 'PGID'='100'
-e 'UMASK'='022'
-l net.unraid.docker.managed=dockerman
-l net.unraid.docker.webui='http://[IP]:[PORT:9999]'
-l net.unraid.docker.icon='https://golift.io/crontabs.png'
-p '9999:80/tcp'
-v '/mnt/disk1/appdata/dockwatch/config':'/config':'rw'
-v '/mnt/disk1/appdata/dockwatch/logs':'/logs':'rw'
docker run \
-d \
--name='dockwatch' \
--net='custom-bridge' \
-e TZ="America/New_York" \
-e HOST_OS="Unraid" \
-e 'PUID'='1001' \
-e 'PGID'='100' \
-e 'UMASK'='022' \
-l net.unraid.docker.managed=dockerman \
-l net.unraid.docker.webui='http://[IP]:[PORT:9999]' \
-l net.unraid.docker.icon='https://golift.io/crontabs.png' \
-p '9999:80/tcp' \
-v '/mnt/disk1/appdata/dockwatch/config':'/config':'rw' \
-v '/var/run/docker.sock':'/var/run/docker.sock':'rw' 'ghcr.io/notifiarr/dockwatch:main'
```

### Permissions
No matter how docker is installed (native, unraid, etc), it is required that the user running the container has permission to use the docker commands
### Compose
This is an example, adjust paths and settings for your setup

Unraid: This is built into the container with
```
addgroup -g 281 unraiddocker && \
usermod -aG unraiddocker abc
dockwatch:
container_name: dockwatch
image: ghcr.io/notifiarr/dockwatch:main
ports:
- 9999:80/tcp
environment:
- PUID=1001
- PGID=100
- UMASK=022
- TZ=Etc/UTC
volumes:
- /appdata/dockwatch/config:/config
- /var/run/docker.sock:/var/run/docker.sock
```

Ubuntu: This is an example
```
usermod -aG ping abc
```
### Manual
`docker pull ghcr.io/notifiarr/dockwatch:main`

### ENV
These are my settings, adjust them to fit your setup!!
Expand Down Expand Up @@ -102,6 +117,8 @@ Firstly i **am not** a docker expert so there are likely other/better ways to do

### Screenshots
![image](https://github.com/Notifiarr/dockwatch/assets/8321115/bac13748-fffd-4624-bc94-6631e054d536)
![image](https://github.com/Notifiarr/dockwatch/assets/8321115/d76842e2-d362-4e3b-9c01-168f0497e464)
![image](https://github.com/Notifiarr/dockwatch/assets/8321115/3df6c25c-5329-4289-bb92-23220ebac9be)
![image](https://github.com/Notifiarr/dockwatch/assets/8321115/271e4b7d-cc72-4d4f-ae24-a7e2f91a8141)
![image](https://github.com/Notifiarr/dockwatch/assets/8321115/835e095a-ca5f-4671-852e-588276787c37)
![image](https://github.com/Notifiarr/dockwatch/assets/8321115/57b57a2a-808b-4ac9-85fe-60c71bbb57e5)
![image](https://github.com/Notifiarr/dockwatch/assets/8321115/6b89da1a-975a-4757-a4b2-2db02635330d)
![image](https://github.com/Notifiarr/dockwatch/assets/8321115/93e66d78-ce87-4fbc-b8b3-de3ec547e9ac)

7 changes: 4 additions & 3 deletions root/app/www/public/ajax/notification.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,13 @@
//-- PLATFORM SETTINGS
$newSettings = [];
foreach ($_POST as $key => $val) {
if (strpos($key, '-platform-') === false) {
$strip = str_replace('notifications-platform-', '', $key);
list($platformId, $platformField) = explode('-', $strip);

if (!is_numeric($platformId)) {
continue;
}

$strip = str_replace('notifications-platform-', '', $key);
list($platformId, $platformField) = explode('-', $strip);
$newSettings[$platformId][$platformField] = trim($val);
}
$settings['notifications']['platforms'] = $newSettings;
Expand Down
122 changes: 121 additions & 1 deletion root/app/www/public/crons/state.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,125 @@
$logfile = LOGS_PATH . 'crons/cron-state-' . date('Ymd') . '.log';
logger($logfile, 'Cron run started');
echo 'Cron run started: state' . "\n";
setFile(STATE_FILE, dockerState());

$settings = getFile(SETTINGS_FILE);
$previousStates = getFile(STATE_FILE);
$currentStates = dockerState();
setFile(STATE_FILE, $currentStates);
$notify = $added = $removed = [];

//-- CHECK FOR ADDED CONTAINERS
foreach ($previousStates as $previousIndex => $previousState) {
$found = false;
foreach ($currentStates as $currentIndex => $currentState) {
if ($settings['notifications']['triggers']['added']['active']) {
if ($previousState['Names'] == $currentState['Names']) {
$found = true;
break;
}
}
}
if (!$found) {
$added[] = ['container' => $currentState['Names']];
}
}

if ($added) {
$notify['state']['added'] = $added;
}

//-- CHECK FOR REMOVED CONTAINERS
foreach ($currentStates as $currentIndex => $currentState) {
$found = false;
foreach ($previousStates as $previousIndex => $previousState) {
if ($settings['notifications']['triggers']['removed']['active']) {
if ($previousState['Names'] == $currentState['Names']) {
$found = true;
break;
}
}
}
if (!$found) {
$removed[] = ['container' => $currentState['Names']];
}
}

if ($removed) {
$notify['state']['removed'] = $added;
}

//-- CHECK FOR STOPPED CONTAINERS
foreach ($currentStates as $currentState) {
foreach ($previousStates as $previousState) {
if ($settings['notifications']['triggers']['stateChange']['active'] && $currentState['Names'] == $previousState['Names']) {
if ($previousState['State'] != $currentState['State']) {
$notify['state']['changed'] = ['container' => $currentState['Names'], 'previous' => $previousState['State'], 'current' => $currentState['State']];
}
}
}
}

foreach ($currentStates as $currentState) {
//-- CHECK FOR HIGH CPU USAGE CONTAINERS
if ($settings['notifications']['triggers']['cpuHigh']['active'] && floatval($settings['global']['cpuThreshold']) > 0) {
if ($currentState['stats']['CPUPerc']) {
$cpu = floatval(str_replace('%', '', $currentState['stats']['CPUPerc']));
if ($cpu > floatval($settings['global']['cpuThreshold'])) {
$notify['usage']['cpu'] = ['container' => $currentState['Names'], 'usage' => $cpu];
}
}
}

//-- CHECK FOR HIGH MEMORY USAGE CONTAINERS
if ($settings['notifications']['triggers']['memHigh']['active'] && floatval($settings['global']['memThreshold']) > 0) {
if ($currentState['stats']['MemPerc']) {
$mem = floatval(str_replace('%', '', $currentState['stats']['MemPerc']));
if ($mem > floatval($settings['global']['memThreshold'])) {
$notify['usage']['mem'] = ['container' => $currentState['Names'], 'usage' => $mem];
}
}
}
}

if ($notify['state']) {
//-- IF THEY USE THE SAME PLATFORM, COMBINE THEM
if ($settings['notifications']['triggers']['stateChange']['platform'] == $settings['notifications']['triggers']['added']['platform'] && $settings['notifications']['triggers']['stateChange']['platform'] == $settings['notifications']['triggers']['removed']['platform']) {
$payload = ['event' => 'state', 'changes' => $notify['state']['changed'], 'added' => $notify['state']['added'], 'removed' => $notify['state']['removed']];
$notifications->notify($settings['notifications']['triggers']['stateChange']['platform'], $payload);
} else {
if ($notify['state']['changed']) {
$payload = ['event' => 'state', 'changes' => $notify['state']['changed']];
$notifications->notify($settings['notifications']['triggers']['stateChange']['platform'], $payload);
}

if ($notify['state']['added']) {
$payload = ['event' => 'state', 'added' => $notify['state']['added']];
$notifications->notify($settings['notifications']['triggers']['added']['platform'], $payload);
}

if ($notify['state']['removed']) {
$payload = ['event' => 'state', 'removed' => $notify['state']['removed']];
$notifications->notify($settings['notifications']['triggers']['removed']['platform'], $payload);
}
}
}

if ($notify['usage']) {
//-- IF THEY USE THE SAME PLATFORM, COMBINE THEM
if ($settings['notifications']['triggers']['cpuHigh']['platform'] == $settings['notifications']['triggers']['memHigh']['platform']) {
$payload = ['event' => 'usage', 'cpu' => $notify['usage']['cpu'], 'cpuThreshold' => $settings['global']['cpuThreshold'], 'mem' => $notify['usage']['mem'], 'memThreshold' => $settings['global']['memThreshold']];
$notifications->notify($settings['notifications']['triggers']['cpuHigh']['platform'], $payload);
} else {
if ($notify['usage']['cpu']) {
$payload = ['event' => 'usage', 'cpu' => $notify['usage']['cpu'], 'cpuThreshold' => $settings['global']['cpuThreshold']];
$notifications->notify($settings['notifications']['triggers']['cpuHigh']['platform'], $payload);
}

if ($notify['usage']['mem']) {
$payload = ['event' => 'usage', 'mem' => $notify['usage']['mem'], 'memThreshold' => $settings['global']['memThreshold']];
$notifications->notify($settings['notifications']['triggers']['memHigh']['platform'], $payload);
}
}
}

logger($logfile, 'Cron run finished');

0 comments on commit 10c9411

Please sign in to comment.