UnleashThebeast
Mr. Midlife-Crisis
|
Hallo, folgendes Problem. Ich habe ein Node.js Zeugs, das läuft um Daten via einem ESP entgegenzunehmen und in eine mysql db zu schreiben. Das hat jetzt auch 4 Jahre lang einwandfrei funktioniert, plötzlich aber aus irgendeinem Grund nichtmehr... das script: index.js var express = require('express');
var mysql = require('mysql');
var app = express();
var bodyParser = require('body-parser');
var SavePassword = 'wetter';
var connection = mysql.createConnection({
host : 'localhost',
user : 'wetter',
password : 'x',
database : 'wetter',
debug : false,
connectionLimit : 100
});
app.set('port', (process.env.PORT || 8000))
app.use('/scripts', express.static(__dirname + '/node_modules/vis/dist/'));
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
// Send data
app.post('/', function(req, res){
var sender_id, temperature, humidity;
if (!req.body.hasOwnProperty("password") || req.body.password != SavePassword) {
res.json({"code" : 403, "error": "Password incorrect / missing"});
return;
}
if (!req.body.hasOwnProperty("sender_id") || req.body.sender_id == "") {
res.json({"code" : 403, "error": "Sender ID missing"});
return;
} else {
sender_id = req.body.sender_id;
}
if (!req.body.hasOwnProperty("temperature") || parseFloat(req.body.temperature) == NaN) {
res.json({"code" : 403, "error": "Temperature Value missing"});
return;
} else {
temperature = parseFloat(req.body.temperature);
}
if (!req.body.hasOwnProperty("humidity") || parseFloat(req.body.humidity) == NaN) {
res.json({"code" : 403, "error": "Humidity Value missing"});
return;
} else {
humidity = parseFloat(req.body.humidity);
}
// save
var query = connection.query('INSERT INTO temperature VALUES ' +
' (DEFAULT, '+mysql.escape(sender_id)+', NOW(), '+temperature+', '+humidity+');', function (error, results, fields) {
if (error) {
res.json({"code" : 403, "status" : "Error in connection database"});
return;
}
res.json({"code": 200});
});
});
app.listen(app.get('port'));
liegt auf dem raspi in /home/pi/wetter startet beim start automatisch via init.d: #!/bin/sh
### BEGIN INIT INFO
# Provides: wetter
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start daemon at boot time
# Description: Enable service provided by daemon.
### END INIT INFO
dir="/home/pi/wetter"
cmd="node index.js"
user="pi"
name=`basename $0`
pid_file="/var/run/$name.pid"
stdout_log="/var/log/$name.log"
stderr_log="/var/log/$name.err"
get_pid() {
cat "$pid_file"
}
is_running() {
[ -f "$pid_file" ] && ps -p `get_pid` > /dev/null 2>&1
}
case "$1" in
start)
if is_running; then
echo "Already started"
else
echo "Starting $name"
cd "$dir"
if [ -z "$user" ]; then
sudo $cmd >> "$stdout_log" 2>> "$stderr_log" &
else
sudo -u "$user" $cmd >> "$stdout_log" 2>> "$stderr_log" &
fi
echo $! > "$pid_file"
if ! is_running; then
echo "Unable to start, see $stdout_log and $stderr_log"
exit 1
fi
fi
;;
stop)
if is_running; then
echo -n "Stopping $name.."
kill `get_pid`
for i in 1 2 3 4 5 6 7 8 9 10
# for i in `seq 10`
do
if ! is_running; then
break
fi
echo -n "."
sleep 1
done
echo
if is_running; then
echo "Not stopped; may still be shutting down or shutdown may have failed"
exit 1
else
echo "Stopped"
if [ -f "$pid_file" ]; then
rm "$pid_file"
fi
fi
else
echo "Not running"
fi
;;
restart)
$0 stop
if is_running; then
echo "Unable to stop, will not attempt to start"
exit 1
fi
$0 start
;;
status)
if is_running; then
echo "Running"
else
echo "Stopped"
exit 1
fi
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
exit 0
Wenn ich jetzt aber im Browser $ip:8000 aufrufe, krieg ich nur ein "Cannot GET /", gleichweise mit $ip:8000/index.js ein "Cannot GET /index.js". Wieso funktioniert das auf einmal nimmer? Ich rauf mir jetzt seit 2 Stunden die Haare .
|
issue
Rock and Stone, brother!
|
Ohne mich wirklich auszukennen: du hast nur eine app.post aber keine app.get. Sprich ein Post request kannst nach / schicken, aber get / hat keine route
|
JDK
Oberwortwart
|
Ohne mich wirklich auszukennen: du hast nur eine app.post aber keine app.get. Sprich ein Post request kannst nach / schicken, aber get / hat keine route Das. Und was willst du mit dem /scripts Directory? Scheint als ob du dir da den GET / Endpoint, der dir eine HTML Page ausliefert, „verloren“ hast.
Bearbeitet von JDK am 29.01.2022, 18:49
|
UnleashThebeast
Mr. Midlife-Crisis
|
Es geht lustig weiter. Ich habe tatsächlich was verloren, das ist jetzt wieder da, index.js (und der Rest) sehen so aus: https://github.com/tutRPi/Raspberry...master/index.jsIch krieg jetzt auch wieder Werte in meine DB. Hab in der index.js mal debug auf true gestellt, somit krieg ich wenn Daten ankommen einen Output ins Terminal: pi@WetterPi:~/wetter $ node index.js
<-- HandshakeInitializationPacket {
protocolVersion: 10,
serverVersion: '5.5.5-10.3.17-MariaDB-0+deb10u1',
threadId: 63,
scrambleBuff1: <Buffer 64 3b 3a 51 67 32 60 71>,
filler1: <Buffer 00>,
serverCapabilities1: 63486,
serverLanguage: 45,
serverStatus: 2,
serverCapabilities2: 33215,
scrambleLength: 21,
filler2: <Buffer 00 00 00 00 00 00 07 00 00 00>,
scrambleBuff2: <Buffer 36 56 2e 25 6b 6c 5e 71 3e 22 2e 5f>,
filler3: <Buffer 00>,
pluginData: 'mysql_native_password',
protocol41: true }
--> (63) ClientAuthenticationPacket {
clientFlags: 455631,
maxPacketSize: 0,
charsetNumber: 33,
filler: undefined,
user: 'wetter',
scrambleBuff:
<Buffer 9f bd a4 7a c3 18 30 38 d5 83 7a 31 63 c3 e8 fb 97 e1 25 d6>,
database: 'wetter',
protocol41: true }
<-- (63) OkPacket {
fieldCount: 0,
affectedRows: 0,
insertId: 0,
serverStatus: 16386,
warningCount: 0,
message: '',
protocol41: true,
changedRows: 0 }
--> (63) ComQueryPacket {
command: 3,
sql:
'INSERT INTO temperature VALUES (DEFAULT, \'5e:cf:7f:c3:f8:3b\', NOW(), 26.2, 33.1);' }
<-- (63) OkPacket {
fieldCount: 0,
affectedRows: 1,
insertId: 760739,
serverStatus: 2,
warningCount: 0,
message: '',
protocol41: true,
changedRows: 0 }
Daten kommen alle 30 Sekunden. Funktioniert auch gut. A Zeitlang. Dann denk ich mir "passt, machst ein sexy sudo /etc/init.d/wetter start
funktioniert auch gut. Bis dann der Dienst nach ein paar Minuten einfach weg is. . Für heut reichts mir...
|
pinkey
Here to stay
|
Wird dir irgendein Fehler angezeigt oder bleibts einfach hängen oder ... ? Kann dir sehr gern damit weiterhelfen aber bissl mehr Infos wären super
|
JDK
Oberwortwart
|
Schau mal, was dir dein Skript in /var/log/ schreibt, sonst lass es halt mal direkt per node (anstelle via init.d) laufen und beobachte den Output.
|
UnleashThebeast
Mr. Midlife-Crisis
|
/var/log/wetter.err sagt: Error: Connection lost: The server closed the connection.
at Protocol.end (/home/pi/wetter/node_modules/mysql/lib/protocol/Protocol.js:112:13)
at Socket.<anonymous> (/home/pi/wetter/node_modules/mysql/lib/Connection.js:94:28)
at Socket.<anonymous> (/home/pi/wetter/node_modules/mysql/lib/Connection.js:526:10)
at Socket.emit (events.js:203:15)
at endReadableNT (_stream_readable.js:1143:12)
at process._tickCallback (internal/process/next_tick.js:63:19)
Emitted 'error' event at:
at Connection._handleProtocolError (/home/pi/wetter/node_modules/mysql/lib/Connection.js:423:8)
at Protocol.emit (events.js:198:13)
at Protocol._delegateError (/home/pi/wetter/node_modules/mysql/lib/protocol/Protocol.js:398:10)
at Protocol.end (/home/pi/wetter/node_modules/mysql/lib/protocol/Protocol.js:116:8)
at Socket.<anonymous> (/home/pi/wetter/node_modules/mysql/lib/Connection.js:94:28)
[... lines matching original stack trace ...]
at process._tickCallback (internal/process/next_tick.js:63:19)
events.js:174
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at TCP.onStreamRead (internal/stream_base_commons.js:111:27)
Emitted 'error' event at:
at Connection._handleProtocolError (/home/pi/wetter/node_modules/mysql/lib/Connection.js:423:8)
at Protocol.emit (events.js:198:13)
at Protocol._delegateError (/home/pi/wetter/node_modules/mysql/lib/protocol/Protocol.js:398:10)
at Protocol.handleNetworkError (/home/pi/wetter/node_modules/mysql/lib/protocol/Protocol.js:371:10)
at Connection._handleNetworkError (/home/pi/wetter/node_modules/mysql/lib/Connection.js:418:18)
at Socket.emit (events.js:198:13)
at emitErrorNT (internal/streams/destroy.js:91:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)
at process._tickCallback (internal/process/next_tick.js:63:19)
wenn ich via node index.js starte, krieg ich die OkPacket von oben, bis es nach einer Zeit einfach abschmiert.
|
spunz
Super ModeratorSuper Moderator
|
Wenn ich es richtig verstanden habe, fehlten einige Files oder diese waren ggf beschädigt? => ggf mal die SD Karte prüfen
|
UnleashThebeast
Mr. Midlife-Crisis
|
SD ist seit heute früh eine neue mit einer frischen Raspian Install drauf und das script frisch aus Github. Bis jetzt läufts via node index.js, mal ein paar Stunden schauen. Bin vorsichtig optimistisch, aber auch misstrauisch. Es fehlte nur in einem File ein Stück Text, das ist keine SD Corruption die ich bis jetzt kannte...
|
COLOSSUS
AdministratorGNUltra
|
|
UnleashThebeast
Mr. Midlife-Crisis
|
was genau is an init.d schwindlich?
|
COLOSSUS
AdministratorGNUltra
|
Du nutzt damit die Reste eines Init- bzw. Service-Management-Systems, das es de facto auf deinem Host nicht mehr gibt, bzw. das nicht mehr die "Hoheit" ueber den Host hat. (Auch vor systemd war es oftmals Falsch, Scripts in /etc/init.d/ direkt auszufuehren, und nicht ueber den `service`-Wrapper zu steuern, der das Environment fuer die Kindprozesse entsprechend aufraeumt/massiert.) Mit ausreichend Pech bzw. der entsprechenden Konfiguration (vgl. https://systemd.network/logind.conf...lUserProcesses=) knallt dir der diensthabende Service Manager (eben systemd) alle so gestarteten Prozesse, die nicht als Teil einer Service Unit gestartet wurden, nach deinem Logout ab.
|
UnleashThebeast
Mr. Midlife-Crisis
|
@colo wenn ich dich schon da hab, korrekt wär also: rm -rf /etc/init.d/wetter unter /lib/systemd/system/ eine wetter.service anlegen und folgendes rein: [Unit]
Description=Wetterservice
After=network.target
[Service]
Environment=NODE_PORT=8000
Type=simple
User=pi
ExecStart=/usr/bin/node /home/pi/wetter/index.js
Restart=on-failure
[Install]
WantedBy=multi-user.target
dann brauch ich ein sudo systemctl daemon-reload und ein sudo systemctl enable wetter sorry für die blöde Fragerei, aber das is alles schwarze Magie für mich Dafür kann ich dir einen SCCM super gschmeidig konfigurieren :x.
|
COLOSSUS
AdministratorGNUltra
|
Fast ganz richtig - das Unit File sollte besser in /etc/systemd/system/wetter.service zu liegen kommen, weil /lib/systemd/system/ dem Paketmanager "gehoert". Nach dem `sudo systemctl enable wetter` in deiner Kommandoabfolge wirst du dann auch noch ein `sudo systemctl start wetter` brauchen. Alternativ verwendest du `sudo systemctl enable --now wetter` (enable = sicherstellen, dass das Service beim Erreichenwollen des default targets gestartet wird - ohne start waere das ggf. nach dem naechsten Reboot).
Bevor du das alles tust, solltest du auch nochmal via `/etc/init.d/wetter stop` dafuer sorgen, dass moeglichst nix vom runtime state des alten Service uebrigbleibt.
|
UnleashThebeast
Mr. Midlife-Crisis
|
Cool. Ja, vorher hab ichs gestoppt und den noch laufenden screen via kill -9 abgeschossen. Ich war aber ungeduldig und habs schon in /lib/systemd/system abgelegt - is das jetzt sehr sehr schlimm und zerschiesst mir bei einem apt-get wieder das service oder is das eher ein semantisches Problem bzw "schöner wärs halt"?
läuft übrigens schon, mal schauen obs jetzt als service wieder stirbt, vorher is es mal von ~08:00 bis 13:00 in einem screen ohne crash gelaufen...
|