Cannot make a cronjob get the status of a service - linux

I'm using Upstart to run a couple of services when the systems reboots. Those services should always be running. I have noticed that some of then crashed eventually, so I'm trying (without success) to create a watchdog script.
This script will check the status of the service. If the service is down, then it should start the service and send me an email about the issue. The email script is in php and is okay.
The problem with the watchdog bash script is that I'm just able to execute the script and read the status of the service if I launch the script manually.When using a cronjob for executing the script I get an "empty status" output.
I'll show you the script:
#!/bin/bash
# Check the service
status=$(status SERVICE | awk '{print $2}')
echo "Status of the SERVICE: $status"
When I execute it manually I get:
Status of the SERVICE: stop/waiting
And If execute it with a cronjob I get:
Status of the SERVICE:
As you see I'm not getting any output when executing the script with a cronjob. In short, the cronjob is running but without providing me with the status of the service.
Hope your X-vision can see the error that I'm not able.
BR,
albertof

The difference is usually environment variables. Likely PATH. Run
which status
To show what executable it's running, and then put that full path into the cron invocation.

Related

Error restarting service: Failed to try-restart nscd.service: Unit nscd.service not found

I am trying to add a startup script in my GCP VM Instance to fetch data from a website (web crawler). I wanted to automate the crawling task following this answer. So, I added a startup script in my VM instance. The script looks like below:
#! /bin/bash
python3 /home/sadmanks/site-spider/src/main.py
Then, I wanted to schedule this instance. But when executing this startup script, it doesn't start the program that I want to execute. The log message that I get is following:
"Error restarting service: Failed to try-restart nscd.service: Unit nscd.service not found
I tried to do this in the browser ssh connection: sudo service nscd start outputs:
Failed to start nscd.service: Unit nscd.service not found.
Does anyone have any idea, how to resolve this issue?
Note: The program runs perfectly when I try to connect the instance with an SSH to my local machine.
The error "Error restarting service: Failed to try-restart nscd.service: Unit crond.service not found." is just harmless log spam. These error messages show up on every VM on start-up and are expected since systemd services like crond.service and nscd.service do not exist on COS. So, try updating the version of google-guest-agent service. But as suggested by #John Hanley that service is not related to python, web scraping/crawling, etc. So, make sure you know what the program is doing before running it on public servers.

Make ExecStartPost command to run in background

I have a systemd service for my spring boot application connected to consul server, behind haproxy. consul provides consul-template to automatically update the service location in haproxy configuration file via consul-template command.
consul-template takes a template file and writes to the final haproxy configuration file and then reload the haproxy.
Now, consul-template process needs to run in background always along with my application, so that as the application comes up, it can detect new application startup and update its location in the configuration file.
Here is my systemd service file for this.
[Unit]
Description=myservice
Requires=network-online.target
After=network-online.target
[Service]
Type=forking
PIDFile=/home/dragon/myservice/run/myservice.pid
ExecStart=/home/dragon/myservice/bin/myservice-script start
ExecReload=/home/dragon/myservice/bin/myservice-script reload
ExecStop=/home/dragon/myservice/bin/myservice-script stop
ExecStartPost=consul-template -template '/etc/haproxy/haproxy.cfg.template:/etc/haproxy/haproxy.cfg:sudo systemctl reload haproxy'
User=dragon
[Install]
WantedBy=multi-user.target
Now, when I start systemctl start myservice, my application starts and the call to consul-template also works, but consul-template process doesn't go in background. I have to press Ctl+C and then systemctl comes back and I have both my application and consul-template process running.
Is there way to run the consul-template process in background specified in ExecStartPost?
I was trying to add & at the end of the ExecStartPost command, but then consul-template complains that it is an additional invalid argument and it fails.
I was also trying to make the command as /bin/sh -c "consul-template command here...", but then this also doesn't work. Even nohup in this command wasn't working.
Any help is really appreciated.
A workaround would be to have a bash file as your entrypoint, add all you need in there, then it will all magically work
I was trying to accomplish the same task. I wanted to fire off some HTTP requests to Tomcat once the service had started, so that I could warmup our servers ahead of the first user request.
I went through a lot of trial and error with using trying to use ExecStartPost to fire off an async process, but actually worked. By calling a shell script, I could trigger off background processes, but from my testing Systemd appears to kill the process thread when ExecStartPost finishes, so any child processes end up getting killed too. I tried various combinations of using &, setsid, nohup, etc, even some Perl to try and trigger off the an executable in it's own thread, but as soon as the shell script exite from ExecStartPost any processes running where killed. It's possible there's some solution that would work using ExecStartPost, but I couldn't find it.
However, what did work is creating a new service (like #divinedragon mentions) which piggy backs off the service I wanted to monitor (in this case Tomcat).
Since it took me a little research to get something working the way I wanted, I wanted to share my solution in case it helps someone.
The first step is to create a new service (e.g. /usr/lib/systemd/system/tomcat-service-listener.service):
[Unit]
Description=Tomcat start/stop event listener
# make sure to stop the service when Tomcat stops
BindsTo=tomcat.service
# waits for both Nginx & Tomcat to be started before this service is started
After=nginx.service tomcat.service
[Service]
Type=oneshot
ExecStart=/path/to/your/script.sh start
ExecStop=/path/to/your/script.sh stop
RemainAfterExit=yes
TimeoutStartSec=300
[Install]
# When the service is enabled, forces this service to start when Tomcat is started
WantedBy=tomcat.service
Some notes on what is happening here:
The BindsTo make sure the service gets stopped when Tomcat is stopped. This triggers the ExecStop command.
The After make sure that on server reboot, this service does not start until both Nginx & Tomcat have started.
The WantedBy will create the wants symlink for Tomcat (when the service is enabled), which will force Tomcat to start this service any time it's restarted.
The RemainAfterExit=yes is necessary for the ExecStop to work. If you only care about triggering something when you're service is started and don't care about when the service is stopped, you can set this to no and remove the ExecStop line.
Make the TimeoutStartSec long enough for whatever task you plan on running.
To get this service working, you then need to do the following:
# make the service executable
chmod 664 /usr/lib/systemd/system/tomcat-service-listener.service
# make Systemd aware of the new service
systemctl daemon-reload
# register the service so it's started/stopped with Tomcat
systemctl enable tomcat-service-listener.service
Now all you need script to trigger off the logic you want. In my case, I wanted to warmup some servers once Tomcat started so my /path/to/your/script.sh looks something like:
#!/bin/sh
SCRIPT_MODE="$1"
LOGFILE=/var/logs/myscript.log
log_message() {
local MESSAGE="$1"
echo "$(date '+%Y-%m-%d %H:%M:%S') $MESSAGE" >> "$LOGFILE"
return 0
}
warmup_server() {
local SERVER_ADDRESS="$1"
local SERVER_DESCRIPTION="$2"
log_message "Warming up $SERVER_DESCRIPTION..."
# we want to track the time it took to warm up the server
local START_TIME=$(date +%s)
# server restarts can take a while for all services to start, so we must retry long enough for all relevant services to start
HTTP_STATUS=$(curl --insecure --location --silent --show-error --fail --retry 60 --retry-delay 2 --retry-max-time 240 --output /dev/null --write-out "%{http_code}" '$SERVER_ADDRESS')
# we want to track the time it took to warm up the server
local TOTAL_STARTUP_TIME=$(($(date +%s)-$START_TIME))
log_message "$SERVER_DESCRIPTION started in $TOTAL_STARTUP_TIME seconds... (Status: $HTTP_STATUS)"
return 0
}
# monitor when Tomcat has stopped
if [ "$SCRIPT_MODE" == "stop" ]; then
log_message "Tomcat listener shutting down..."
exit 0
elif [ "$SCRIPT_MODE" == "start" ]; then
log_message "Tomcat listener started..."
fi
# servers to warm up
warmup_server 'https://127.0.0.1' 'Localhost #1'
warmup_server 'https://127.0.0.2' 'Localhost #2'
This seems to be working exactly as I want. The service starts up when the server is reboot and starting/stopping/restarting Tomcat fires off the expected events. Since it's independent of the Tomcat service, I can restart this warmup script if needed. It also doesn't delay the Tomcat startup time, since it is its own service, therefore running asynchronously like I wanted.

ExecStopPost is not getting executed if Service is not running in Systemctl

The issue is that my service is not running and i tried to execute the stop service command. So as the service is not running if i try to stop the service by using systemctl stop $servicename.service the ExecStop command will not get executed and thus my ExecStopPost is also not getting executed.But i want that ExecStopPost command to be executed even though my service is not running and i try to execute the stop service command.
If the service is not running the command given to ExecStopPost will not execute.

"Service cron status" command does not give back the status of cron in the ubuntu docker container

I use ubuntu:latest image, cron is already installed, because my cron job doesn't run at all. I want to check if the cron deamon is running in my docker container.
so I type in
service cron status
results in:
Rather than invoking init scripts through /etc/init.d, use the service(8) utility, e.g. service cron status
Since the script you are attempting to invoke has been converted to an Upstart job, you may also use the status(8) utility, e.g. status cron
gives me no result of the status of cron, why is that?
The service name is wrong. Here is the fix with crond
service crond status

Starting and stopping a service remotely in RHEL/Fedora/CentOS

I have created a service on TerminalB. I can start and stop the service by executing following commands at terminalB. Now I want to start and stop this service on TerminalB by executing a shell script present on another machine TerminalA using ssh or any other possible way.
service servicename stop
//do some file copy
service servicename start
I have executed below command in Terminal. (In remote.sh I just kept service servicename stop, but the service is not stopping).
ssh user#TerminalB "bash -s" < /home/remote.sh

Resources