Övervaka på webbsida om pythonskript körs

Permalänk

Övervaka på webbsida om pythonskript körs

Hej!

Jag undrar om det finns någon lösning för att kontrollera om ett python-skript är igång eller inte.
Om det går hade det varit väldigt bra om det gick att se statusen på ett webbsida.

Jag tänker att det borde fungera såhär:
1. När skriptet startas så uppdateras statusen till grönt
2. Huvudskriptet körs klart
3. Uppdatera statusen till rött

Körs på en Raspberry Pi med raspbian.

Tack på förhand!

Permalänk
Medlem

@Anglaborg:
Kanske ingen riktigt snygg lösning men.

Använder du PHP på sidan? (har självbara använt det här för att kolla om omxplayer är aktiv) med:

<?php $playing = shell_exec("pgrep omxplayer"); ?>

så borde det kunna fungera med:

$cmd = shell_exec("pgrep scriptnamn.py");

Är $cmd ( = processID) tom, är programet/scriptet inte aktivt.
Använd en enkel if/else-sats beroende på vad du vill göra med resultatet.

Sedan en liten javascript-timer eller liknande som körs så länge cmd > "" eller uppdaterar sidan med jämna mellanrum eller kanske en meta http-equiv="refresh" i headern beroende på behov.

Visa signatur

Asus C6H | R9-3900XT | 4x8GB G-Skill Ripjaws V 3600@3466 CL14 | Asus Radeon RX 580 8GB Strix Gaming OC | Asus Strix Raid DLX | Corsair Obsidian 750D AE

Permalänk
Medlem

Om hemsidan ligger på en annan maskin hade du kunnat göra en vanlig HTTP POST till den från Python scriptet när du startar och avslutar.

Permalänk
Medlem

Kanske skapa ett litet REST API med python/flask och kolla om processen körs?
Skicka en http get från din frontend mot rest apiet som returnerar true eller false.

EDIT:
Jag gjorde ett litet test med Flask för att kolla om processen körs och det fungerade fint.

Flask-Appen ser ut såhär:

from flask import Flask import psutil import re import json app = Flask(__name__) @app.route("/status", methods=['GET']) def status(): running = False pname = 'test.py' for p in psutil.process_iter(): for x in p.cmdline(): if re.match(pname, x): running = True return json.dumps({'status': running}) if __name__ == "__main__": app.run(host='0.0.0.0', debug=True, port=6666)

Jag har en test.py som körs och kör cURL mot min app:

curl http://127.0.0.1:6666/status {"status": true}

Stänger av test.py

curl http://127.0.0.1:6666/status {"status": false}

Permalänk

@CloX:

Har tittat lite på Flask innan men förstår inte hur det fungerar.
Kan inte skriva kod själv så menar du att Flask-appen ska vara i ett eget pythonscript?

Permalänk
Medlem

Ja absolut,

koden jag skrev ovan är i ett pythonscript. Du behöver dock installera de moduler jag använde som inte finns med by default.
Dvs Flask och psutil.

Permalänk

@CloX:
Så hela den koden lägger jag in i mitt nuvarande skript?
Om jag startar så får jag

from flask import Flask ImportError: cannot import name Flask

Har gjort pip install flask och psutil

Permalänk
Medlem

EDIT:

Nej, gör ett nytt script för flask-appen.

kör du python 3 eller 2.7?

Permalänk

@CloX:

Haha jo det gjorde jag, bytte till test.py men får fortfarande samma fel.
Gjorde en egen fil till bara Flask.

2.7

Permalänk
Medlem

Kan du testa att bara importera psutil utan någon annan kod, se om du får liknande fel?

Har du apt på den där boxen?

Isåfall, testa att installera med det. sudo apt-get install python-flask

Permalänk

@CloX:
Testade att göra ett script som endast innehöll

import psutils

och likadant fast med

from flask import Flask

Då får jag inga felmeddelanden.

apt-get funkade inte heller.

Permalänk

@Terrell:
Är inte så insatt, hur gör man då?
Kan lägga hemsidan på en annan maskin om det skulle göra saken enklare.

Permalänk
Medlem

@Anglaborg:
Det kräver att du har någon sorts backend som kan ta emot HTTP POST:en och lagra informationen, sedan hämta den när folk besöker sidan.

Men dom andra alternativen är bättre om dom ligger på samma maskin.

Permalänk
Medlem

@Anglaborg

Om du inte får Flask att fungera kan du testa att köra via PHP.
Scriptet är testat i apache2 med php5 resp. php7 under raspbian samt apache2 och php5 under debian.
Jag har inte Python installerat på någon av datorerna just nu så det kan hända att du måste skriva om shell_exec lite grand.

Klistra in det här i en textfil och spara som valfritt_namn.php så den går att köra i din webb-server.
Öppna sidan i din webb-läsare på valfri dator/platta etc. i ditt nätverk.

För att kontrollera så det fungerar:
Öppna ett terminalfönster på din Pi och starta top.
Efter några sekunder (se meta refresh-taggen, content = tid i sekunder) ska div-taggen ändras från röd till grön i webb-läsaren och texten ändras.
Stäng ner top med CTRL+C och DIV-taggen kommer bli röd vid nästa uppdatering av sidan.

<!DOCTYPE html> <html lang='sv'> <head> <meta http-equiv='X-UA-Compatible' content='IE=edge'> <meta http-equiv='refresh' content='5'> <!-- Laddar om sidan var femte sekund. --> <title>Kontrollera om top körs.</title> </head> <body> <?php $cmd = shell_exec('pgrep top'); // Greppa top:s processid. Byt top mot namnet på ditt script och kolla om det fungerar. if($cmd == '') // Om top inte körs körs returneras ingenting. { $active = '#ff3232'; $label = '<font style="color:#ffffff; font-weight:bold; line-height:14px; vertical-align:middle; text-align:center;">Top körs inte.</font>'; } else // Om top körs returneras ett ProcessID: { $active = '#08ea03'; $label = '<font style="color:#ffffff; font-weight:bold; line-height:14px; vertical-align:middle; text-align:center;">Top körs.</font>'; } echo '<div style="position:absolute; top:10%; left:10%; width:15%; height:2%; padding:10px; background-color:'.$active.'">'.$label.'</div>'; // skriv ut någonting på skärmen baserat på if/else. ?> </body> </html>

Visa signatur

Asus C6H | R9-3900XT | 4x8GB G-Skill Ripjaws V 3600@3466 CL14 | Asus Radeon RX 580 8GB Strix Gaming OC | Asus Strix Raid DLX | Corsair Obsidian 750D AE

Permalänk

@Johan_G3:
Detta hade ju varit perfekt!
Men hur väljer jag mitt specifika pythonscript? Det är bara själva python som får ett processid?

Permalänk
Medlem

@Anglaborg:
Vad får du för resultat om du öppnar ett terminalfönster (eller kör via SSH) och skriver:

pgrep -a python | grep 'scriptnamn.py'

eller

ps -f -C python,python2.7 | grep 'scriptnamn.py'

Returneras ett resultat då borde du kunna använda liknande fråga med shell_exec() och sedan bara anpassa if/else.

Visa signatur

Asus C6H | R9-3900XT | 4x8GB G-Skill Ripjaws V 3600@3466 CL14 | Asus Radeon RX 580 8GB Strix Gaming OC | Asus Strix Raid DLX | Corsair Obsidian 750D AE

Permalänk

@Johan_G3:

Perfekt! Vet du hur jag låser process id så det är samma varje gång man startar pythonscriptet? Använder process id istället för scriptnamnet.
Men eftersom process id ändras varje gång man startar så måste jag ändra i php-filen.

Permalänk
Medlem
Skrivet av Anglaborg:

@Johan_G3:

Perfekt! Vet du hur jag låser process id så det är samma varje gång man startar pythonscriptet? Använder process id istället för scriptnamnet.
Men eftersom process id ändras varje gång man startar så måste jag ändra i php-filen.

Nej, det är fel metod. Använd pgrep -f script.py.

-f, --full The pattern is normally only matched against the process name. When -f is set, the full command line is used.

Visa signatur

Spela Swemantle! Du vet att du vill.

Ibland har jag fel, men då är det någon annans fel.

Permalänk

@LemonIllusion: Då fastnar statusen på att den körs hela tiden... Fick bara två process id när jag körde kommandot, kan de ha något med det att göra?
När jag körde det andra fick jag upp ett process id samt namnet på scriptet.

Permalänk
Medlem
Skrivet av Anglaborg:

@LemonIllusion: Då fastnar statusen på att den körs hela tiden... Fick bara två process id när jag körde kommandot, kan de ha något med det att göra?
När jag körde det andra fick jag upp ett process id samt namnet på scriptet.

Jag förstår inte vad du menar. Om du får två process-ID:n har du två processer igång som matchar "script.py". Om det finns processer som råkar ha ett liknande namn och därmed triggar pgrep, använd växeln -x/--exact. Kolla exitkoden för att se om du fick några matchande processer eller inte och släng in det hela i något som sköter webbandet så får du det du frågar efter.

Ex python:

from flask import Flask from subprocess import call app = Flask(__name__) @app.route("/") def _(): return "running" if call(["pgrep", "--full", "--exact", "python script.py"]) == 0 else "not running" if __name__ == "__main__": app.run(host='0.0.0.0', port=8080)

Ex php:

<?php exec('pgrep --full --exact "python script.py"', $_, $status); echo $status === 0 ? 'running' : 'not running';

Vill du göra en mer portabel lösning utan systemanrop får du läsa på hur du kan lista processer i diverse språk. All information finns om du bara söker efter den.

tre = ska det ju vara i php...
Visa signatur

Spela Swemantle! Du vet att du vill.

Ibland har jag fel, men då är det någon annans fel.

Permalänk

@LemonIllusion:
Löste det med att lägga in:
ps -f -C python,python2.7 | grep 'scriptnamn.py'

Nu funkar det som jag vill
Tack alla för hjälpen!