GithubHelp home page GithubHelp logo

bdd / runitor Goto Github PK

View Code? Open in Web Editor NEW
257.0 5.0 15.0 212 KB

A command runner with healthchecks.io integration

License: BSD Zero Clause License

Go 70.52% Shell 21.68% Nix 4.95% Dockerfile 2.85%
go golang healthchecks healthchecksio cron monitoring scheduled-job

runitor's Introduction

runitor

Runitor runs the supplied command, captures its output, and based on its exit code reports successful or failed execution to https://healthchecks.io or your private instance.

Healthchecks.io is a web service for monitoring periodic tasks. It's like a dead man's switch for your cron jobs. You get alerted if they don't run on time or terminate with a failure.

Installation

Download Signed Release Binaries

Binaries of the latest release for popular platforms are at https://github.com/bdd/runitor/releases/latest

Verify Signatures

SHA256 checksum manifest of the releases are signed with one of the SSH keys published at https://bdd.fi/x/runitor.pub.

An example verification script shows how to use ssh-keygen and sha256sum to verify downloads.

Build Locally

If you have Go 1.19 or newer installed, you can use the command:

go install bdd.fi/x/runitor/cmd/runitor@latest

...and the binary will be at $GOPATH/bin/runitor or if GOPATH isn't set, under $HOME/go/bin/runitor.

Cross Compilation

If you need to build the binary on a platform different than the target, you can pass the target operating system and architecture with GOOS and GOARCH environment variables to the go install command.

GOOS=plan9 GOARCH=arm go install bdd.fi/x/runitor/cmd/runitor@latest

...and the binary will be under $GOPATH/bin/plan9_arm/runitor.

Container Image

If you prefer to run your workloads in containers, runitor/runitor on Docker Hub provides images based on Alpine, Debian, and Ubuntu for x86_64, arm64v8, and armv7 architectures.

Why Do I Need This Instead of Calling curl from a Shell Script?

In addition to clean separation of concerns from the thing that needs to run and the act of calling an external monitor, runitor packs a few neat extra features that are bit more involved than single line additions to a script.

It can capture the stdout and stderr of the command to send it along with execution reports, a.k.a. "pings". When you respond to an alert you can quickly start investigating the issue with the relevant context already available.

It can be used as a long running process acting as a task scheduler, executing the command at specified intervals. This feature comes in handy when you don't readily have access to a job scheduler like crond or systemd.timer. Works well in one process per container environments.

Example Uses

Certificate Renewal

# (Using per check UUIDs.)
export CHECK_UUID=8116e449-d71c-4112-8f5d-a66f60902091
runitor -- dehydrated --cron --config example.com.conf

Repository Maintenance

# Run the maintenance script 10 times a day (24h/10 = 2h 24m)
# (Using per-project ping key, and check slugs.)
export HC_PING_KEY=edf72661-62ff-49e7-a921-33b41502d7e7
runitor -slug git-repo-maintenance \
	-every 2h24m -- \
	/script/git-maint

Backup

# Do not attach output to ping.
# Backup software may leak filenames and paths.

runitor -no-output-in-ping -- restic backup /home /etc

Triggering an Immediate Run in Periodic Mode

When invoked with -every <duration> flag, runitor will also act as a basic task scheduler.

Sometimes you may not want to restart the process or the container just to force an immediate run. Instead, you can send SIGALRM to runitor to get it run the command right away and reset the interval.

pkill -ALRM runitor

Usage

runitor [-uuid uuid] -- command

Flags

-api-retries uint
  Number of times an API request will be retried if it fails with a transient error (default 2)
-api-timeout duration
  Client timeout per request (default 5s)
-api-url string
  API URL. Takes precedence over HC_API_URL environment variable (default "https://hc-ping.com")
-create
  Create a new check if passed slug is not found in the project
-every duration
  If non-zero, periodically run command at specified interval
-no-output-in-ping
  Don't send command's output in pings
-no-run-id
  Don't generate and send a run id per run in pings
-no-start-ping
  Don't send start ping
-on-exec-fail value
  Ping type to send when runitor cannot execute the command (exit-code|success|fail|log (default fail))
-on-nonzero-exit value
  Ping type to send when command exits with a nonzero code (exit-code|success|fail|log (default exit-code))
-on-success value
  Ping type to send when command exits successfully (exit-code|success|fail|log (default success))
-ping-body-limit uint
  If non-zero, truncate the ping body to its last N bytes, including a truncation notice. (default 10000)
-ping-key string
  Ping Key. Takes precedence over HC_PING_KEY environment variable
-quiet
  Don't capture command's stdout
-req-header value
  Additional request header as "key: value" string
-silent
  Don't capture command's stdout or stderr
-slug string
  Slug of check. Requires a ping key. Takes precedence over CHECK_SLUG environment variable
-uuid string
  UUID of check. Takes precedence over CHECK_UUID environment variable
-version
  Show version

More on What healthchecks.io Provides

  • It listens for HTTP requests (pings) from services being monitored.

  • It keeps silent as long as pings arrive on time. It raises an alert as soon as a ping does not arrive on time.

  • Pings can signal start of execution so run durations can be tracked.

  • Pings can explicitly signal failure of execution so an alert can be send.

  • Pings can attach up to 100KB of logs. Runitor automatically handles truncation if needed.

  • It can alert you via email, SMS, WhatsApp, Slack, and many more services.

  • It has a free tier with up to 20 checks.

  • Software behind the service is open source. You can run your own instance if you'd like to.

runitor's People

Contributors

alex-phillips avatar apeschar avatar bdd avatar cuu508 avatar dependabot[bot] avatar t-yag avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

runitor's Issues

Supress command output

In my cron I'd like output to go to healthchecks and not to my email. I'm adding >/dev/null after the runitor command now, but it would be nice if runitor just didn't pass through the output it had captured.

PingStart: nonretriable error response: 404 Not Found

I have tried to use runitor with a self-hosted healthchecks instance, but failed so far.

Curl approach works fine:

m="test"; myserver="serveraddress"; code="apicode"
curl -fsS --retry 3 --data-raw "$m" https://$myserver/ping/$code > /dev/null

runitor command throws an error:

myserver="serveraddress"; code="apicode"
runitor -api-url="https://$myserver" -uuid=$code -- echo "test"
2021/01/31 11:44:11 PingStart: nonretriable error response: 404 Not Found
test
2021/01/31 11:44:11 PingSuccess: nonretriable error response: 404 Not Found

Is this a known issue? Anything I can do?

Thanks!

307/308 redirects aren't handled well

I want to use a custom domain for pings, and delegate to the healthchecks.io service, so that if I decide to self-host in future, I can do that without changing the API URL everywhere I use runitor.

This works fine by setting HC_API_URL to the redirect server, which just redirects to the same path on hc-ping.com.

A 301/302 redirect works, except that the body is not sent on the second (redirected) request to hc-ping.com. For this use case I discovered 307/308 redirects which require re-sending the request body.

Go supports this, but requires that GetBody be implemented, if not using *bytes.Buffer, *bytes.Reader, or *strings.Reader.

Implementing GetBody with the RingBuffer involves adding seeking functionality to the RingBuffer. Currently the RingBuffer allows for just one read. I stopped here because it seems involved.

I'd like to ask for your opinion, as I see two approaches:

  1. Add seeking functionality to the RingBuffer so that the request body can be read again, and GetBody can be implemented.
  2. Convert the RingBuffer to a *bytes.Buffer once, and rely on Go's automatic handling.

The second approach seems simpler and would also allow us to get rid of some extra code, as this would happen automatically: https://github.com/bdd/runitor/blob/main/internal/api.go#L147-L164

The only real downside would be a little extra memory use for one extra copy of the request body. But this seems very insignificant.

Do you have any thoughts?

No output in the body when using Django dev server

I am trying runitor and I notice log attachment is not working in the last 0.7.0
I succeed in attaching logs with curl command
I have a self provisioned hosted instance of healtcheck.io

 m=$(/bin/sh /data/scripts/pgsql_backup.sh -r sftp:[email protected]:/backup/restic/cachet/dev -p /data/cachet/dump -c cachet-db)
curl -fsS -m 10 --retry 5 --data "$m" https://healthcheck.openstack.local/ping/0b34abd2-1e0b-4620-acc0-1255a087ebf5

is working

but :

./runitor -uuid 0b34abd2-1e0b-4620-acc0-1255a087ebf5 -api-url https://healthcheck.openstack.local/ping -- /bin/sh /data/scripts/pgsql_backup.sh -r sftp:[email protected]:/backup/restic/cachet/dev -p /data/cachet/dump -c cachet-db

does not attach anything

Ping body limit?

Not sure if it's a runittor issue or something else but I am using Runitor v0.10.1 (latest) witn the following configuration

/home/user/go/bin/runitor -uuid xx -api-url $APIURL -ping-body-limit=0 -- /bin/bash -c "cmd"

This used to work fine but now the logs are being truncated.

image

Not sure why?

Windows Schedule Powershell Task

I've been banging my head on this for quite some time and I'm getting nowhere.
I have my ST setup to run as SYSTEM and with highest priv.
Program is set to the full path of the runitor binary.
Args are set to:
-api-url 'https://domain.tld/ping' -uuid 'UUID' -- powershell -NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass -File RenewCertificate.ps1
Start In is set to the directory containing the ps1 file.

The script runs, but I don't see anything in my HC dashboard.
If I run the command as administrator or as SYSTEM, it works just fine.

PS C:\ASSETS\Scripts> C:\ASSETS\Tools\runitor-v1.2.0-build.2-windows-amd64.exe -api-url 'https://domain.tld/ping' -uuid 'UUID' -- powershell -NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass -File RenewCertificate.ps1

Feature request: Ignore

This is a workaround for a feature that was already requested by someone to healthchecker healthchecks/healthchecks#525 . There was some people that said they are dealing with it on a much lower level when running the command/script so I was thinking runitor could also do that.

Suggestion

Add -fault-tolerance which would look like -fault-tolerance 2 which in summary the command that was being ran failed (exited code > 0) then it would catch the error and output and send as a "SUCCESS" to healthchecker, it was still a failure but flagged as a success.

How should this work

Basically runitor would have to look for "fault-tolerance" option and create a file say fault-tolerance-uuid.txt with the number of attempts it already did, so if it fails it creates/modifies the file to whatever content + 1, and if that content + 1 > fault tolerance it would fail otherwise it sends an OK HTTP with the actual buggy output for debug purposes. If it passed the file should be removed.

UnicodeDecodeError on success ping with special characters from a Windows host

Hi,

We use Runitor to monitor scheduled tasks involving PowerShell on Windows Server boxes. Some of our scripts may output a few line of text on stdout. In that case, the success ping may fail, as Django may reject it with a UnicodeDecodeError. So far, it seems the exception is raised only when the logged output contains special (non-latin1) characters.

We're using HealthChecks 1.23 with Runitor 0.8.0. HealthChecks 1.23 fixed a bug involving Unicode characters in webhook headers. I hoped the issue would disappear after upgrading to the new version, but it unfortunately did not. I don't know which project should deal with this issue. If this is a HealthChecks error, please let me know.

Here is the transcript of a job failing to send its success ping. The lines between the Runitor invocation and the Runitor error message were printed by the script. Note the Espace disque lib?r??:0 string which contains mangled special (French) characters:

C:\Users\bernardm>"C:\Program Files\Runitor\Runitor.exe" -api-url "https://<host>/ping" -uuid "<uuid>" -- "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -Command "& { Start-WsusMaintenance }"
Declining expired updates...
Declining superseeded updates...
Deleting obsolete computers...
Deleting obsolete updates...
Performing database maintenance...
Shrinking database files...
Removing unneeded content files...
Espace disque lib?r??:0
Starting a garbage collection job on the volume storing content files...
2021/10/18 14:27:32 PingSuccess: Post "https://<host>/ping/<uuid>": net/http: HTTP/1.x transport connection broken: http: ContentLength=318 with Body length 0

Running the very same script without the Runitor wrapper preserves special characters:

C:\Users\bernardm>"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -Command "& { Start-WsusMaintenance }"
Declining expired updates...
Declining superseeded updates...
Deleting obsolete computers...
Deleting obsolete updates...
Performing database maintenance...
Shrinking database files...
Removing unneeded content files...
Espace disque libéré :0
Starting a garbage collection job on the volume storing content files...

Here is the Django exception. I removed the settings; let me know if you need them.

Internal Server Error: /ping/<uuid>

UnicodeDecodeError at /ping/<uuid>
'utf-8' codec can't decode byte 0x82 in position 237: invalid start byte

Request Method: POST
Request URL: https://<host>/ping/<uuid>
Django Version: 3.2.8
Python Executable: /opt/healthchecks/venv/bin/python3
Python Version: 3.8.10
Python Path: ['/opt/healthchecks/healthchecks', '/opt/healthchecks/venv/bin', '/usr/lib/python38.zip', '/usr/lib/python3.8', '/usr/lib/python3.8/lib-dynload', '/opt/healthchecks/venv/lib/python3.8/site-packages']
Server time: Mon, 18 Oct 2021 12:27:31 +0000 Installed Applications:
('hc.accounts',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.humanize',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'compressor',
 'hc.api',
 'hc.front',
 'hc.payments')
Installed Middleware:
('django.middleware.security.SecurityMiddleware',
 'whitenoise.middleware.WhiteNoiseMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'hc.accounts.middleware.CustomHeaderMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'hc.accounts.middleware.TeamAccessMiddleware')


Traceback (most recent call last):
  File "/opt/healthchecks/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/opt/healthchecks/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/opt/healthchecks/venv/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/opt/healthchecks/venv/lib/python3.8/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/opt/healthchecks/healthchecks/hc/api/views.py", line 50, in ping
    body = request.body.decode()

Exception Type: UnicodeDecodeError at /ping/<uuid>
Exception Value: 'utf-8' codec can't decode byte 0x82 in position 237: invalid start byte Request information:
USER: AnonymousUser

GET: No GET data

POST: No POST data

FILES: No FILES data

COOKIES: No cookie data

META:
CONTENT_LENGTH = '318'
CONTENT_TYPE = 'text/plain'
HTTP_ACCEPT_ENCODING = 'gzip'
HTTP_CONNECTION = 'close'
HTTP_HOST = '<uuid>'
HTTP_USER_AGENT = 'runitor/v0.8.0 (+https://bdd.fi/x/runitor)'
HTTP_X_FORWARDED_FOR = '10.6.185.217, 10.6.104.217'
HTTP_X_FORWARDED_PROTO = 'https'
PATH_INFO = '/ping/<uuid>'
QUERY_STRING = ''
RAW_URI = '/ping/<uuid>'
REMOTE_ADDR = '127.0.0.1'
REMOTE_PORT = '53224'
REQUEST_METHOD = 'POST'
SCRIPT_NAME = ''
SERVER_NAME = '127.0.0.1'
SERVER_PORT = '8000'
SERVER_PROTOCOL = 'HTTP/1.0'
SERVER_SOFTWARE = 'gunicorn/20.1.0'
gunicorn.socket = <socket.socket fd=10, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8000), raddr=('127.0.0.1', 53224)> wsgi.errors = <gunicorn.http.wsgi.WSGIErrorsWrapper object at 0x7f0632eb00d0> wsgi.file_wrapper = <class 'gunicorn.http.wsgi.FileWrapper'> wsgi.input = <gunicorn.http.body.Body object at 0x7f0632ea2760> wsgi.input_terminated = True wsgi.multiprocess = False wsgi.multithread = False wsgi.run_once = False wsgi.url_scheme = 'https'
wsgi.version = '(1, 0)'

Settings:
<snip>

Many thanks for any help!

Feature request: add "log" endpoint

Hello,
I just found out over at the Healthchecks repo, that there is a way of not getting mails every time a job fails.
If we use the "log" endpoint, then we can be flexible about the times a job can fail, before the mails are sent. See this post for the explanation how it would work: healthchecks/healthchecks#525 (comment).
Maybe you can add an option (example: "no-error-ping=true" => sends to "log" endpoint) to send "log" when the job fails, instead of the normal exit code.
To have that feature would be awesome. Thanks for looking into it and for runitor! :)

No ping-status 'OK' when script has no stderr/out?

Hi, great tool! But i found the following problem.
When there is no output from the script, runitor seems to think it's still running.
Script to reproduce it:

#!/usr/bin/env bash
  
foo() {
  bar=$(ls /)
}
foo

cron entry:

HC_API_URL="https://mydomain.com/ping/"
* * * * * /usr/bin/runitor --uuid="xxxx-xxx-x-x-xxxx" -- bash /usr/local/bin/test.sh

The Script works without any problems, but my selfhosted healthchecks.io only shows the "Started" Ping, without the "OK" and the timestamp.
Like here:

#46 | Nov 20 | 05:55 | Started | HTTP POST from 1.2.4.5 - runitor/v0.9.0 (+https://bdd.fi/x/runitor)
#45 | Nov 20 | 05:54 | Started | HTTP POST from 1.2.4.5 - runitor/v0.9.0 (+https://bdd.fi/x/runitor)
#44 | Nov 20 | 05:53 | Started | HTTP POST from 1.2.4.5 - runitor/v0.9.0 (+https://bdd.fi/x/runitor)
#43 | Nov 20 | 05:52 | Started | HTTP POST from 1.2.4.5 - runitor/v0.9.0 (+https://bdd.fi/x/runitor)

When you now change the script to:

#!/usr/bin/env bash
  
foo() {
  bar=$(ls /)
  echo "123"
}

foo

It works like it should:

#52 | Nov 20 | 05:58 | OK | HTTP POST from 1.2.4.5 - runitor/v0.9.0 (+https://bdd.fi/x/runitor) 0.04 sec
#51 | Nov 20 | 05:58 | Started | HTTP POST from 1.2.4.5 - runitor/v0.9.0 (+https://bdd.fi/x/runitor)
#50 | Nov 20 | 05:57 | OK | HTTP POST from 1.2.4.5 - runitor/v0.9.0 (+https://bdd.fi/x/runitor) 0.03 sec
#49 | Nov 20 | 05:57 | Started | HTTP POST from 1.2.4.5 - runitor/v0.9.0 (+https://bdd.fi/x/runitor)
#48 | Nov 20 | 05:56 | OK | HTTP POST from 1.2.4.5 - runitor/v0.9.0 (+https://bdd.fi/x/runitor) 0.03 sec
#47 | Nov 20 | 05:56 | Started | HTTP POST from 1.2.4.5 - runitor/v0.9.0 (+https://bdd.fi/x/runitor)

And shows the output "123" in the body.

Is this a desired behavior? How can I tell runitor that the script has no output but has still finished?
Thanks!

Operating System: Ubuntu 20.04.3 LTS
Kernel: Linux 5.4.0-84-generic
runitor/v0.9.0

Show compiled URL on error

I'm first setting this up, and I'm doing it in a way that I can template things and dynamically create the slug.
My scripting is perfect yet, but currently I need to check my webserver logs to find the full URI as all I get from your app is 2023/07/27 12:00:01 Ping(start): nonretriable error response: 404 Not Found

I would request that the compiled URI is appended after the HTTP Error Response.

docker pull fails with docker rootless

Hello,
thanks for this useful project !

I switched from docker "default" (root) to docker rootless , and unfortunately I can no longer pull runitor images.

$ docker pull runitor/runitor:v1.2.0-ubuntu
v1.2.0-ubuntu: Pulling from runitor/runitor
bccd10f490ab: Already exists 
059bea526c98: Extracting [==================================================>]  2.215MB/2.215MB
bea230f2086c: Download complete 
failed to register layer: lsetxattr user.overlay.impure /usr: operation not supported

using this version:

$ docker info
Client: Docker Engine - Community
 Version:    26.1.0
 Context:    rootless
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.14.0
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.26.1
    Path:     /usr/libexec/docker/cli-plugins/docker-compose
(truncated)

Same problem with docker 26.0.2

Same problem when pulling from GHCR: docker pull ghcr.io/bdd/runitor:v1.2.0-ubuntu

It works OK with docker in docker default (root) mode, with the same versions of docker.

I searched for an answer: might be related to these issues ?
jsknnr/enshrouded-server#56
containers/storage#1847
i.e. images built with a problematic version of buildah ?

Feature Request: Remove version from binary filenames

Heya,

The thinking behind this request is to be able to more easily script/download the latest version of the binaries.

Instead of having to write grep/jq/findstr/convertfrom-json strings or creating env vars, we'd be able to do something akin to sudo curl -fL https://github.com/bdd/runitor/releases/latest/download/runitor-linux-amd64 -o /usr/local/bin/runitor (and similar in Windows with Invoke-WebRequest) allowing for easier updates/initial downloads/Ansible.

Feature Request: Custom Header Support

I am self-hosting my healthchecks instance and I have exposed it publically via Cloudflare tunnel.
I want to secure it using Cloudflare Access. And verify requests using Cloudflare service token headers...
It would be great if runitor supported setting custom headers.
I can do it manually via curl.
If you have got time, would love to have this feature.

`panic: runtime error: invalid memory address or nil pointer dereference` on invalid slugs

$ HC_PING_KEY=... runitor -slug nonexisting -- echo testing
2022/06/05 12:28:32 PingStart: nonretriable error response: 404 Not Found
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x626935]

goroutine 1 [running]:
main.Do({0xc000010280, 0x2, 0x2}, {0x0, 0x0, 0x0, 0x0, 0x0, 0x2710}, {0xc00001c2e0, ...}, ...)
	bdd.fi/x/runitor/cmd/runitor/main.go:242 +0x115
main.main.func4(...)
	bdd.fi/x/runitor/cmd/runitor/main.go:206
main.main()
	bdd.fi/x/runitor/cmd/runitor/main.go:209 +0xbf3

When using a valid slug it works fine

runitor-v0.10.0-linux-amd64, pre-compiled binary downloaded from github releases

Debian repository

This cool project was missing a debian repository so I took it as an opportunity to learn how that works. I'm not sure if you are interested in adding a stranger's third party repository to your project's readme, though if you are, here it is:

echo "deb [arch=amd64] https://deb.derkad.es any main" > /etc/apt/sources.list.d/derkades.list
wget -O - https://deb.derkad.es/gpg.key | sudo apt-key add -
apt update
apt install runitor

For now only amd64 but I will add arm and arm64 in the future once I figure out multiarch deb packaging

Feature request: Upload logs to S3

Currently I'm using Runitor and I really love it. Unfortunatly though, we lose (a lot) of important logs due to the 100-ping limit at Healthchecks.io. This because we run a cron every minute, and if a cron during the night fails - we won't be able to see the logs.

As a workaround or alternative, I'd love to purpose the solution to upload logs to S3 through Runitor. We're able to create policies on the S3 bucket to automatically archive and delete logs, so it's really only the uploading aspect.

I'd love to see that we're able to, together with sending logs to Healthchecks.io, upload logs to S3 automatically.

Would this be something you're interested in? If so, I'm more then happy to develop this myself.

Regression: API URL handling changed with release 1.1.0

Before commit bac4814, runitor would always append a / to the given API URL (-api-url or HC_API_URL). Since the stated commit this is no longer the case and given URL's are treated as-is, without appending a /. This can result in a breaking change, creating 404 errors due to invalid ping URLs being generated.

Examples:

runitor 1.0.0 behaviour:

HC_API_URL="https://healthchecks.example.com/ping/"
runitor --uuid foobar

generated final request URL:

https://healthchecks.example.com/ping//foobar (double slash is not removed, but usually automatically fixed/ignored by webservers)

HC_API_URL="https://healthchecks.example.com/ping" (no final slash)
runitor --uuid foobar

generated final request URL:

https://healthchecks.example.com/ping/foobar (one / automatically appended)

runitor 1.1.0 behaviour:

HC_API_URL="https://healthchecks.example.com/ping/"
runitor --uuid foobar

generates final request URL:

https://healthchecks.example.com/ping/foobar?rid=runid (single slash)

HC_API_URL="https://healthchecks.example.com/ping" (no final slash)
runitor --uuid foobar

generates final request URL:

https://healthchecks.example.com/pingfoobar?rid=runid (zero slashes used. Likely results in invalid URLs, generates 404 errors)

Feature idea: signal failure if command completes too quickly

Sometimes apps and scripts fail early, but still return exit code 0. And legacy systems can be hard to fix.

Perhaps there could be an optional feature where runitor measures the execution time of the command, and signals failure if the command completes too quickly? Something like:

# signals success
runitor -min-time=5s -uuid 6e1fbf8f-c17e-4749-af44-0c81461bdd19 -- sleep 1

# signals failure
runitor -min-time=5s -uuid 6e1fbf8f-c17e-4749-af44-0c81461bdd19 -- sleep 6

Feature request: `-create` flag

When pinging by slug, Healthchecks can optionally auto-create a new check if a check with the specified slug does not exist. To enable this feature, the ping URL needs a ?create=1 query parameter added at the end:

$ curl https://hc-ping.com/fixme-ping-key/does-not-exist
# returns HTTP 404 because a check with slug "does-not-exist" does indeed not exist


$ curl https://hc-ping.com/fixme-ping-key/does-not-exist?create=1
# creates a new check and returns HTTP 201


$ curl https://hc-ping.com/fixme-ping-key/does-not-exist?create=1
# the check now exists, so the server returns HTTP 200

It would be great if there was a way to tell runitor to add the create=1 parameter in ping URLs. Perhaps something like:

runitor -ping-key fixme-ping-key -slug does-not-exist -create -- somecommand

@bdd what do you think? If something like the above looks OK, I can try my hand at implementing it.

Add handling for HTTP 429 responses

When pinging a check via slug, if the request gets rate-limited, Healthchecks.io can return HTTP 429 response: https://healthchecks.io/docs/http_api/#success-slug

When this happens, runitor outputs:

2022/10/17 13:15:06 Ping(start): max tries reached after try 3. last error: <nil>

It would be nice if runitor would print a more descriptive "rate limit exceeded" message here.

Note: this only happens when pinging by slug. When pinging by uuid, Healthchecks.io always returns HTTP 200, even in rate-limited cases, for backwards compatibility.

Note 2: Healthchecks.io (the hosted service) has rate-limiting, but the open-source Healthchecks project does not. For efficiency, the rate-limiting is done by nginx, so there's no sign of it in the python code.

Shell command invocation (bug with v0.7.0-beta.4)

I noticed a bug with shell invocation on v0.7.0-beta (all versions from .1 to .4). Essentially, I am unable to get stdout to be reported to a self-hosted healthchecks instance.

apiurl="https://serveraddress/ping"; uuid="uuidstring"; /root/bin/runitor-v0.7.0-beta.4-linux-amd64 -api-url=$apiurl -uuid=$uuid -- bash -c "(echo out; echo foo; echo err >&2) | grep -v foo"

Screenshot 2021-01-31 at 22 19 54

Latest stable version 0.6.0 seems to report stdout fine:

apiurl="https://serveraddress/ping"; uuid="uuidstring"; /root/bin/runitor-v0.6.0-linux-amd64 -api-url=$apiurl -uuid=$uuid -- bash -c "(echo out; echo foo; echo err >&2) | grep -v foo"

Screenshot 2021-01-31 at 22 20 29

Linux environment: Debian buster running as LXC container on QNAP NAS (x64)
Healthchecks: Latest docker image from linuxserver/healthchecks

error: the input device is not a TTY

the input device is not a TTY

[runitor] Command exited with code 1.

Maybe this is me running the command wrong. It's a crontab that runs a docker exec.

/usr/local/bin/runitor-v0.8.0-linux-amd64 -uuid UUID -- /usr/bin/docker exec -it admin ./manage.py runcrons

Add GPG signatures or file hashes to released files

Hi,

Currently, each runitor release comes with source code and binaries for various platforms (thanks for that!). Unfortunately, people downloading those files have no way to check their integrity/authenticity.

Would you mind including GPG signatures (or at least files hashes) for every file in the next releases ?

Thank you

Feature request: Send command used on start

Is it possible upon /start also send the command that is going to run? Is useful for when working with multiple instances and servers and I want to know besides description and name what the command really looks like or if there was a change in between.

Windows: Trojan Detected

I imagine a false-positive...

Trojan:Win32/Commandrob.A!ml

CmdLine: C:\ASSETS\Tools\runitor-v1.2.0-build.2-windows-amd64.exe ...

Runitor unable to ping healthchecks but curl works fine

I am having a strange issue as of this morning. When I try to ping a self hosted healthchecks instance with runitor it fails:

root@Neon:/tmp/backup# runitor --api-url https://healthcheck.mydomain.com/ping  -uuid 3e5b2cea-7e7c-4eaa-be46-184f94d319e0 echo hello_world
2021/09/18 14:49:37 PingStart: max tries reached after try 3. last error: Post "https://healthcheck.mydomain.com/ping/3e5b2cea-7e7c-4eaa-be46-184f94d319e0/start": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
hello_world
2021/09/18 14:49:58 PingSuccess: max tries reached after try 3. last error: Post "https://healthcheck.mydomain.com/ping/3e5b2cea-7e7c-4eaa-be46-184f94d319e0": context deadline exceeded (Client.Timeout exceeded while awaiting headers)

If I try to do the same thing manually with curl it works just fine:

root@Neon:/tmp/backup# curl https://healthcheck.mydomain.com/ping/3e5b2cea-7e7c-4eaa-be46-184f94d319e0/start
OK
root@Neon:/tmp/backup# curl https://healthcheck.mydomain.com/ping/3e5b2cea-7e7c-4eaa-be46-184f94d319e0/
OK

Do you have any suggestions on how I could debug/resolve this? It has me totally stumped

Run chained commands?

It doesn't look like it is working for me, but wanted to double check. Is it possible (or can it be a feature request) to pass chained commands into runitor? An example would be something like this:

runitor -uuid my-uuid -- cd /my/script/directory && ./my_script.js

I imagine We'd potentially have to surround the entire command string with quotes, but would be useful as these are some of the entries in my current crontab.

HC_API_URL env variable doesn't work as expected

Method 1 - Works:

runitor -api-url="https://example.com/ping" -uuid 123-abc-456-def -- echo test

Method 2 - Works:

HC_API_URL="https://example.com/ping" runitor -uuid 123-abc-456-def -- echo test

Method 3 - Doesn't work:

HC_API_URL="https://example.com/ping"
runitor -uuid 123-abc-456-def -- echo test
runitor -uuid 789-ghi-012-jkl -- echo test2

Tested all sorts of combinations, can't get cron to execute method 3, which is the cleanest one for having multiple jobs, but only if I could set the HC_API_URL variable.

Explore Windows Compatibility

I use runitor on Linux, FreeBSD, and macOS but does it run under Windows too?

SIGARLM based triggering will likely not work. Maybe I can remove support for that on Windows.

AFAIK stdout and stderr concepts are similar/same on Windows. So redirection should work well.

Feature request: Update flag

Would it be possible to have an -update flag which either:

  1. Checks latest version and if there is a new version, grabs from github automatically.
  2. Failing 1, state that there is a new version, a clickable URL to download from github?
  3. A Docker image which can be run with latest/versioned tag (basically, official version of https://hub.docker.com/r/markcaudill/runitor).

This is more so that we can keep up to date with things, especially if we've missed a release notification.

What happened to the v1.2.0 tag in Docker Hub?

I just noticed that some personal automation were not running, and after investigating, it was due to the runitor/runitor:v1.2.0-ubuntu being unexistent in Docker Hub.

Was this intentional?

Feature Idea: Flag that only retrieves the last 10KB of logs?

Currently the health checks fail when logs gets bigger than 10KB even though everything ran successfully.

Would it be possible to add a flag that only includes the last 10KB of the logs so the healthchecks.io would access the payload.

The project is written in Go, which sadly rules me out. I'm hoping someone is willing to look at this feature request and make a PR.

See section: Handling More Than 10KB of Logs (https://healthchecks.io/docs/attaching_logs/)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.