Hey,
I’m working on a framework, and I was wondering if there is any possible way of detecting server shutdown using the "quit " command as well as “Ctrl+C”?
Hey,
I’m working on a framework, and I was wondering if there is any possible way of detecting server shutdown using the "quit " command as well as “Ctrl+C”?
hmm…are you opposed to OS level monitoring? You may be able to use some bash scripting / some windows api scripting (or find something someone made already) in order to detect a particular service and do something if that service dies…
So basically what I’m trying to do here is, I’m trying to figure out a way to detect server shutdown.
because; the framework I’m working on, will have a lot of logs and data saved up after running the server for a certain period of time so I wanna save that data before its lost, and it’s easy to detect resource restart/stop because there’s already an event for it “onResourceStop”, but the problem is the server now, if you shut it down using “quit” in the terminal or just “ctrl+c” it will shutdown and kill all resources ungracefully.
I’ve already tried listening to process “SIG” events to no avail, I’m using JS for this framework.
and the framework is running with the fx-server?
because if thats the case you need some insane scripst to foresee that the quit is coming like @Wetter42 mentionend before.
I mean if your framework is running on the server you will kill it with “Ctrl+C” instand too.
Why don’t you save your Data in regularly times? like every minute or something?
sorry for my bad english and I’m not that deep into the rabbit hole you’re in but I think it’s not that easy…
Hey Mikrolai
Your English is understandable
and yes, the framework is running as a FXServer resource, I get what Watter was referring to, but that would force me to run the framework as another process outside of FXServer, and that defeats the framework’s simplicity feature.
and as you said, “Ctrl+C” will just kill the server with all the resource without a warning or an event to do any kind of a graceful stop.
I get what you’re saying. Well as another suggestion, rather than trying to interrupt the shutdown process it may be worth offloading the logs (almost realtime) off of the server somewhere…this will prevent the need to potentially modify the server because ‘ctrl + c’ is an os-level interrupt (sigint) which means you may need to speak with some fiveM devs to figure out exactly HOW they’re handling it, and if it can be safely interrupted before killing.
I’m probably wrong (and I hope I am because something like what you’re trying to do sounds awesome!). Or maybe the server already logs the logs prior to the server dying and stores them in some file…and you just need to dig em out…who knows…
thats what I’ve meant before. log your data constantly and get the last state of it (where ever you want to recall it)
ok so it’s late & i might have misunderstood your request here… but if you want to make a log of everytime the server shuts down and log it into a .txt document here is a simple lua. Its as basic as they get
local logFile = "shutdown_log.txt" -- Specify the log file name or path
AddEventHandler("onResourceStop", function(resource)
if GetCurrentResourceName() == resource then
local currentTime = os.date("%Y-%m-%d %H:%M:%S") -- Get the current timestamp
local logMessage = "[" .. currentTime .. "] Server shutdown"
-- Append the log message to the log file
Citizen.CreateThread(function()
local file = io.open(logFile, "a")
if file then
file:write(logMessage .. "\n")
file:close()
end
end)
end
end)
so; that could theoretically work if you are assuming that the server stops every resource properly before shutting down, of which; it isn’t the case.
doesn’t matter if you use the “quit” command in the terminal or just “Ctrl+C” (which is what the majority of the people are using; me included) it just doesn’t work, and the event doesn’t even get triggered at all.
I would normally do that, but the data I’m trying to log is constantly being updated while also being used by various modules within the framework, so realtime logging isn’t ideal; logging it before shutdown, at its final form is the best way of doing that.
Alternatively, I could keep updating the logs with the newest data, but that’s just not a good thing to do and considering the amount of data it could be stored, it probably wouldn’t be ideal performance wise.
I could but ya know (¯\(ツ)/¯)
I honestly don’t think you’re wrong, but I’m optimistic, and it could be that the server has the data stored somewhere but I just don’t know how to access it externally.
It would most likely be quite hard to detect that, other then the onResourceStop
event.
Considering you are trying to run the code after the code has been stopped/exited.
onResourceStop
would surely work if you use txadmin to run your server, which the majority of people use nowadays.
To be quite honest; I never thought about this, and I do see this as the only possible solution, or I could use txAdmin:events:serverShuttingDown
to detect server shutdowns, restarts, and scheduled restarts, but I really don’t want to relay on something other than the FXserver itself.
but generally speaking, I don’t mind it, and if all fails, this would be the one for sure, thanks for the recommendation!
Yeah, checking the event you mentioned would probably be even better/reliable then “onResourceStop”!
I’m glad to hear that my comment could help you.
a while back i had managed to create a fairly reliable system for saving data when the server is crashed: https://github.com/■■■■■■■■■■■■■■■/utility_framework/blob/main/server/managers/disconnect.lua#L21-L35
i have no idea if it still works or if it is still reliable enough, but it worked quite well (i had also tried crashing or crashing the server and from what I remember it still saved, i have never tested it intensively and that is where i think it loses reliability, try it and see if it meets your requirements
Hey,
I have taken a look into the repository and it seems that this framework logs stuff in realtime, meaning; things get logged as they get triggered/called and not when the server/resource stops or shutdown.
But I appreciate the effort and thought
Thanks
look at the lines i sent you, as you notice the data is saved only when it “detects” a shutdown
Should just handle server shutdowns/ restarts with txadmin and use the events it provides to save data
Issue with your example is that the server won’t wait for the data to save. Depending on the amount of data you need to save, some are prone to get lost
I know this isn’t an ideal fix. But ig I’ll just contribute, soooo, when the server shuts down it seems the ‘playerDropped’ event is triggered no matter how its shutdown, you might be able to save the logged data when the first player disconnects. However, one major flaw is that there might not be any online players
Alternatively, and I know this has been mentioned a lot in this post in different ways, but… why not save the log like every 5mins or something, at least if not all of the data is recovered, some can be recovered…
So, after a lot of digging and testing, I came to the conclusion that it’s not possible… -ish!
I came across a few weird behaviors while testing different events and approaches, first;
process.on('SIGINT', (code) => {
console.log('Process event SIGINT triggered with code:', code);
});
works-ish … but not reliably, normally, it wouldn’t get triggered using “Ctrl-C” or “quit” command, but with time and a bit of frustration from failing, I spammed “Ctrl-C” a few dozens of times to force it to quit quickly and …
the SIGINT
was triggered as shown below…
On the first “Ctrl-C” a message will pop up in the console saying: “Press Ctrl-C again (or type quit
) to exit.”
and after pressing “Ctrl-C” again for the second time confirming it, this will pop up: " Quitting: SIGINT received"
Now, from my testing, the SIGINT
event can ONLY be triggered if you spam “Ctrl-C” in between the two messages, meaning it will only work, if you press “Ctrl-C” after the first message, but before the second message, weird!
I’ve also tried spawning a child process and delay the process exit enough to log the stuff I need, but this method also suffers the same fate, it’s not reliable, and will ONLY be triggered if you spam “Ctrl-C” in between the two messages, same as first method.
something worthy of noting is that using the ‘quit’ command does not trigger the SIGINT
event at all, no matter how fast you spam it or how many times you can execute the command, whether spamming it my hand or using a file and executing it using the exec
command!
But; while I messing around with TxAdmin, I noticed that the SIGINT
event suddenly started working quite reliably and consistently, not skipping a single “Ctrl-C”, unless, you only do “Ctrl-C” once in the TxAdmin console, because Tx:Logger
will detect that the server is closed after a minute or so and will restart it automatically, but the second “Ctrl-C” will immediately close the terminal without a chance to trigger a single event!
I’ve also tried digging in the FiveM source code to try and figure something out, but let’s just say… it was too complicated for me and I don’t really understand C++'s syntax, so I came out empty handed.
so; in conclusion, detecting a server shutdown (without using TxAdmin) is not possible because there isn’t any way of detecting process exit reliably and consistently, thus; making using the combination of:
on('onResourceStop')
event - to detect resource stops/restarts (credit: DigitalDeluxeGamer)on('txAdmin:events:serverShuttingDown')
event - to detect scheduled/intentional shutdowns/restarts (credit: Zerio)process.on('SIGINT')
event (with TxAdmin) - to detect Ctrl-C in TxAdmin consolethe only reliable way, and that only leaves one thing undetectable, or for now at least, which is a server crash… although TxAdmin can do an awesome job detecting em’ and restart the server automatically, but my resource is out of luck, because the resource won’t be able to listen for txAdmin:events:serverShuttingDown
when it gets triggered as noted in the events page for TxAdmin .
also note that while using TxAdmin, the ‘quit’ command also does not trigger any of the events listed above, but TxAdmin will detect that the server is down when it’s not supposed to be down, and will restart it automatically!
and for anyone needing the code to do those 3 events, here it is:
process.on('SIGINT', (code) => {
RSRCINT('Process event SIGINT triggered with code: ' + code);
});
on('onResourceStop', resourceName => {
if(GetCurrentResourceName() === resourceName) RSRCINT('CitizenFX event onResourceStop triggered')
});
on('txAdmin:events:serverShuttingDown', details => {
RSRCINT('TxAdmin event serverShuttingDown triggered')
});
/**
* Resource Interrupt function to gracefully handle shutdowns
* @param {string} msg the event message
* @returns {void}
*/
const RSRCINT = msg => console.log(`^1Resource Interruption Detected! (${msg})^0`)
Thanks to everyone who suggested, recommended, and/or contributed to any possible solution, and happy coding my friends!