Giter Club home page Giter Club logo

healthchecks's Introduction

Healthchecks

Tests Coverage Status

Healthchecks is a cron job monitoring service. It listens for HTTP requests and email messages ("pings") from your cron jobs and scheduled tasks ("checks"). When a ping does not arrive on time, Healthchecks sends out alerts.

Healthchecks comes with a web dashboard, API, 25+ integrations for delivering notifications, monthly email reports, WebAuthn 2FA support, team management features: projects, team members, read-only access.

The building blocks are:

  • Python 3.10+
  • Django 5
  • PostgreSQL or MySQL

Healthchecks is licensed under the BSD 3-clause license.

Healthchecks is available as a hosted service at https://healthchecks.io/.

A Dockerfile and pre-built Docker images are available.

Screenshots:

The "My Checks" screen. Shows the status of all your cron jobs in a live-updating dashboard.

Screenshot of My Checks page

Each check has configurable Period and Grace Time parameters. Period is the expected time between pings. Grace Time specifies how long to wait before sending out alerts when a job is running late.

Screenshot of Period/Grace dialog

Alternatively, you can define the expected schedules using a cron expressions. Healthchecks uses the cronsim library to parse and evaluate cron expressions.

Screenshot of Cron dialog

Check details page, with a live-updating event log.

Screenshot of Check Details page

Healthchecks provides status badges with public but hard-to-guess URLs. You can use them in your READMEs, dashboards, or status pages.

Screenshot of Badges page

Setting Up for Development

To set up Healthchecks development environment:

  • Install dependencies (Debian/Ubuntu):

    sudo apt update
    sudo apt install -y gcc python3-dev python3-venv libpq-dev libcurl4-openssl-dev libssl-dev
  • Prepare directory for project code and virtualenv. Feel free to use a different location:

    mkdir -p ~/webapps
    cd ~/webapps
  • Prepare virtual environment (with virtualenv you get pip, we'll use it soon to install requirements):

    python3 -m venv hc-venv
    source hc-venv/bin/activate
    pip3 install wheel # make sure wheel is installed in the venv
  • Check out project code:

    git clone https://github.com/healthchecks/healthchecks.git
  • Install requirements (Django, ...) into virtualenv:

    pip install -r healthchecks/requirements.txt
  • macOS only - pycurl needs to be reinstalled using the following method (assumes OpenSSL was installed using brew):

    export PYCURL_VERSION=`cat requirements.txt | grep pycurl | cut -d '=' -f3`
    export OPENSSL_LOCATION=`brew --prefix openssl`
    export PYCURL_SSL_LIBRARY=openssl
    export LDFLAGS=-L$OPENSSL_LOCATION/lib
    export CPPFLAGS=-I$OPENSSL_LOCATION/include
    pip uninstall -y pycurl
    pip install pycurl==$PYCURL_VERSION --compile --no-cache-dir
  • Create database tables and a superuser account:

    cd ~/webapps/healthchecks
    ./manage.py migrate
    ./manage.py createsuperuser

    With the default configuration, Healthchecks stores data in a SQLite file hc.sqlite in the checkout directory (~/webapps/healthchecks).

  • Run tests:

    ./manage.py test
  • Run development server:

    ./manage.py runserver

The site should now be running at http://localhost:8000. To access Django administration site, log in as a superuser, then visit http://localhost:8000/admin/

Configuration

Healthchecks reads configuration from environment variables.

Full list of configuration parameters.

Accessing Administration Panel

Healthchecks comes with Django's administration panel where you can manually view and modify user accounts, projects, checks, integrations etc. To access it,

  • if you haven't already, create a superuser account: ./manage.py createsuperuser
  • log into the site using superuser credentials
  • in the top navigation, "Account" dropdown, select "Site Administration"

Sending Emails

Healthchecks must be able to send email messages, so it can send out login links and alerts to users. Specify your SMTP credentials using the following environment variables:

  • Implicit TLS (recommended):

    DEFAULT_FROM_EMAIL = "[email protected]"
    EMAIL_HOST = "your-smtp-server-here.com"
    EMAIL_PORT = 465
    EMAIL_HOST_USER = "smtp-username"
    EMAIL_HOST_PASSWORD = "smtp-password"
    EMAIL_USE_TLS = False
    EMAIL_USE_SSL = True

    Port 465 should be the preferred method according to RFC8314 Section 3.3: Implicit TLS for SMTP Submission. Be sure to use a TLS certificate and not an SSL one.

  • Explicit TLS:

    DEFAULT_FROM_EMAIL = "[email protected]"
    EMAIL_HOST = "your-smtp-server-here.com"
    EMAIL_PORT = 587
    EMAIL_HOST_USER = "smtp-username"
    EMAIL_HOST_PASSWORD = "smtp-password"
    EMAIL_USE_TLS = True

For more information, have a look at Django documentation, Sending Email section.

Receiving Emails

Healthchecks comes with a smtpd management command, which starts up a SMTP listener service. With the command running, you can ping your checks by sending email messages to [email protected] email addresses.

Start the SMTP listener on port 2525:

./manage.py smtpd --port 2525

Send a test email:

curl --url 'smtp://127.0.0.1:2525' \
    --mail-from '[email protected]' \
    --mail-rcpt '[email protected]' \
    -F '='

Sending Alerts and Reports

Healthchecks comes with a sendalerts management command, which continuously polls database for any checks changing state, and sends out notifications as needed. Within an activated virtualenv, you can manually run the sendalerts command like so:

./manage.py sendalerts

In a production setup, you will want to run this command from a process manager like systemd or supervisor.

Healthchecks also comes with a sendreports management command which sends out monthly reports, weekly reports, and the daily or hourly reminders.

Run sendreports without arguments to run any due reports and reminders and then exit:

./manage.py sendreports

Run it with the --loop argument to make it run continuously:

./manage.py sendreports --loop

Database Cleanup

Healthchecks deletes old entries from api_ping and api_notification tables automatically. By default, Healthchecks keeps the 100 most recent pings for every check. You can set the limit higher to keep a longer history: go to the Administration Panel, look up user's Profile and modify its "Ping log limit" field.

For each check, Healthchecks removes notifications that are older than the oldest stored ping for same check.

Healthchecks also provides management commands for cleaning up auth_user, api_tokenbucket and api_flip tables.

  • Remove user accounts that match either of these conditions:

    • Account was created more than 6 months ago, and user has never logged in. These can happen when user enters invalid email address when signing up.
    • Last login was more than 6 months ago, and the account has no checks. Assume the user doesn't intend to use the account any more and would probably want it removed.
    ./manage.py pruneusers
  • Remove old records from the api_tokenbucket table. The TokenBucket model is used for rate-limiting login attempts and similar operations. Any records older than one day can be safely removed.

    ./manage.py prunetokenbucket
  • Remove old records from the api_flip table. The Flip objects are used to track status changes of checks, and to calculate downtime statistics month by month. Flip objects from more than 3 months ago are not used and can be safely removed.

    ./manage.py pruneflips
  • Remove old objects from external object storage. When an user removes a check, removes a project, or closes their account, Healthchecks does not remove the associated objects from the external object storage on the fly. Instead, you should run pruneobjects occasionally (for example, once a month). This command first takes an inventory of all checks in the database, and then iterates over top-level keys in the object storage bucket, and deletes any that don't also exist in the database.

    ./manage.py pruneobjects

When you first try these commands on your data, it is a good idea to test them on a copy of your database, not on the live database right away. In a production setup, you should also have regular, automated database backups set up.

Two-factor Authentication

Healthchecks optionally supports two-factor authentication using the WebAuthn standard. To enable WebAuthn support, set the RP_ID (relying party identifier ) setting to a non-null value. Set its value to your site's domain without scheme and without port. For example, if your site runs on https://my-hc.example.org, set RP_ID to my-hc.example.org.

Note that WebAuthn requires HTTPS, even if running on localhost. To test WebAuthn locally with a self-signed certificate, you can use the runsslserver command from the django-sslserver package.

External Authentication

Healthchecks supports external authentication by means of HTTP headers set by reverse proxies or the WSGI server. This allows you to integrate it into your existing authentication system (e.g., LDAP or OAuth) via an authenticating proxy. When this option is enabled, healthchecks will trust the header's value implicitly, so it is very important to ensure that attackers cannot set the value themselves (and thus impersonate any user). How to do this varies by your chosen proxy, but generally involves configuring it to strip out headers that normalize to the same name as the chosen identity header.

To enable this feature, set the REMOTE_USER_HEADER value to a header you wish to authenticate with. HTTP headers will be prefixed with HTTP_ and have any dashes converted to underscores. Headers without that prefix can be set by the WSGI server itself only, which is more secure.

When REMOTE_USER_HEADER is set, Healthchecks will:

  • assume the header contains user's email address
  • look up and automatically log in the user with a matching email address
  • automatically create an user account if it does not exist
  • disable the default authentication methods (login link to email, password)

External Object Storage

Healthchecks can optionally store large ping bodies in S3-compatible object storage. To enable this feature, you will need to:

  • ensure you have the MinIO Python library installed:

    pip install minio
  • configure the credentials for accessing object storage: S3_ACCESS_KEY, S3_SECRET_KEY, S3_ENDPOINT, S3_REGION and S3_BUCKET.

Healthchecks will use external object storage for storing any request bodies that exceed 100 bytes. If the size of a request body is 100 bytes or below, Healthchecks will still store it in the database.

Healthchecks automatically removes old stored ping bodies from object storage while uploading new data. However, Healthchecks does not automatically clean up data when you delete checks, projects or entire user accounts. Use the pruneobjects management command to remove data for checks that don't exist any more.

When external object storage is not enabled (the credentials for accessing object storage are not set), Healthchecks stores all ping bodies in the database. If you enable external object storage, Healthchecks will still be able to access the ping bodies already stored in the database. You don't need to migrate them to the object storage. On the other hand, if you later decide to disable external object storage, Healthchecks will not have access to the externally stored ping bodies any more. And there is currently no script or management command for migrating ping bodies from external object storage back to the database.

Integrations

Slack

Healthchecks supports two Slack integration setup flows: legacy and app-based.

The legacy flow does not require additional configuration and is used by default. In this flow the user creates an incoming webhook URL on the Slack side, and pastes the webhook URL in a form on the Healthchecks side.

In the app-based flow the user clicks an "Add to Slack" button in Healthchecks, and gets transferred to a Slack-hosted dialog where they select the channel to post notifications to. This flow uses OAuth2 behind the scenes. To enable this flow, you will need to set up a Slack OAuth2 app:

  • Create a new Slack app on https://api.slack.com/apps/
  • Add at least one scope in the permissions section to be able to deploy the app in your workspace (By example incoming-webhook for the Bot Token Scopes).
  • Add a redirect url in the format SITE_ROOT/integrations/add_slack_btn/. For example, if your SITE_ROOT is https://my-hc.example.org then the redirect URL would be https://my-hc.example.org/integrations/add_slack_btn/.
  • Look up your Slack app for the Client ID and Client Secret. Put them in SLACK_CLIENT_ID and SLACK_CLIENT_SECRET environment variables. Once these variables are set, Healthchecks will switch from using the legacy flow to using the app-based flow.

The legacy and app-based flows only affect the user experience during the initial setup of Slack integrations. The contents of notifications posted to Slack are the same regardless of the setup flow used.

Discord

To enable Discord integration, you will need to:

  • register a new application on https://discord.com/developers/applications/me
  • add a redirect URI to your Discord application. The URI format is SITE_ROOT/integrations/add_discord/. For example, if you are running a development server on localhost:8000 then the redirect URI would be http://localhost:8000/integrations/add_discord/
  • Look up your Discord app's Client ID and Client Secret. Put them in DISCORD_CLIENT_ID and DISCORD_CLIENT_SECRET environment variables.

Pushover

Pushover integration works by creating an application on Pushover.net which is then subscribed to by Healthchecks users. The registration workflow is as follows:

  • On Healthchecks, the user adds a "Pushover" integration to a project
  • Healthchecks redirects user's browser to a Pushover.net subscription page
  • User approves adding the Healthchecks subscription to their Pushover account
  • Pushover.net HTTP redirects back to Healthchecks with a subscription token
  • Healthchecks saves the subscription token and uses it for sending Pushover notifications

To enable the Pushover integration, you will need to:

  • Register a new application on Pushover via https://pushover.net/apps/build.
  • Within the Pushover 'application' configuration, enable subscriptions. Make sure the subscription type is set to "URL". Also make sure the redirect URL is configured to point back to the root of the Healthchecks instance (e.g., http://healthchecks.example.com/).
  • Put the Pushover application API Token and the Pushover subscription URL in PUSHOVER_API_TOKEN and PUSHOVER_SUBSCRIPTION_URL environment variables. The Pushover subscription URL should look similar to https://pushover.net/subscribe/yourAppName-randomAlphaNumericData.

Signal

Healthchecks uses signal-cli to send Signal notifications. Healthcecks interacts with signal-cli over UNIX or TCP socket. Healthchecks requires signal-cli version 0.11.2 or later.

To enable the Signal integration via UNIX socket:

  • Set up and configure signal-cli to expose JSON RPC on an UNIX socket (instructions). Example: signal-cli -a +xxxxxx daemon --socket /tmp/signal-cli-socket
  • Put the socket's location in the SIGNAL_CLI_SOCKET environment variable.

To enable the Signal integration via TCP socket:

  • Set up and configure signal-cli to expose JSON RPC on a TCP socket. Example: signal-cli -a +xxxxxx daemon --tcp 127.0.0.1:7583
  • Put the socket's hostname and port in the SIGNAL_CLI_SOCKET environment variable using "hostname:port" syntax, example: 127.0.0.1:7583.

Telegram

  • Create a Telegram bot by talking to the BotFather. Set the bot's name, description, user picture, and add a "/start" command. To avoid user confusion, please do not use the Healthchecks.io logo as your bot's user picture, use your own logo.

  • After creating the bot you will have the bot's name and token. Put them in TELEGRAM_BOT_NAME and TELEGRAM_TOKEN environment variables.

  • Run settelegramwebhook management command. This command tells Telegram where to forward channel messages by invoking Telegram's setWebhook API call:

    ./manage.py settelegramwebhook
    Done, Telegram's webhook set to: https://my-monitoring-project.com/integrations/telegram/bot/

For this to work, your SITE_ROOT must be correct and must use the "https://" scheme.

Apprise

To enable Apprise integration, you will need to:

  • ensure you have apprise installed in your local environment:

    pip install apprise
  • enable the apprise functionality by setting the APPRISE_ENABLED environment variable.

Shell Commands

The "Shell Commands" integration runs user-defined local shell commands when checks go up or down. This integration is disabled by default, and can be enabled by setting the SHELL_ENABLED environment variable to True.

Note: be careful when using "Shell Commands" integration, and only enable it when you fully trust the users of your Healthchecks instance. The commands will be executed by the manage.py sendalerts process, and will run with the same system permissions as the sendalerts process.

Matrix

To enable the Matrix integration you will need to:

  • Register a bot user (for posting notifications) in your preferred homeserver.
  • Use the Login API call to retrieve bot user's access token. You can run it as shown in the documentation, using curl in command shell.
  • Set the MATRIX_ environment variables. Example:
MATRIX_HOMESERVER=https://matrix.org
MATRIX_USER_ID=@mychecks:matrix.org
MATRIX_ACCESS_TOKEN=[a long string of characters returned by the login call]

PagerDuty Simple Install Flow

To enable PagerDuty Simple Install Flow,

  • Register a PagerDuty app at PagerDuty › Developer Mode › My Apps
  • In the newly created app, add the "Events Integration" functionality
  • Specify a Redirect URL: https://your-domain.com/integrations/add_pagerduty/
  • Copy the displayed app_id value (PXXXXX) and put it in the PD_APP_ID environment variable

Running in Production

Here is a non-exhaustive list of pointers and things to check before launching a Healthchecks instance in production.

  • Environment variables, settings.py and local_settings.py.
    • DEBUG. Make sure it is set to False.
    • ALLOWED_HOSTS. Make sure it contains the correct domain name you want to use.
    • Server Errors. When DEBUG=False, Django will not show detailed error pages, and will not print exception tracebacks to standard output. To receive exception tracebacks in email, review and edit the ADMINS and SERVER_EMAIL settings. Consider setting up exception logging with Sentry.
  • Management commands that need to be run during each deployment.
    • manage.py compress – creates combined JS and CSS bundles and places them in the static-collected directory.
    • manage.py collectstatic – collects static files in the static-collected directory.
    • manage.py migrate – applies any pending database schema changes and data migrations.
  • Processes that need to be running constantly.
    • manage.py runserver is intended for development only. Do not use it in production, instead consider using uWSGI or gunicorn.
    • manage.py sendalerts is the process that monitors checks and sends out monitoring alerts. It must be always running, it must be started on reboot, and it must be restarted if it itself crashes. On modern linux systems, a good option is to define a systemd service for it.
  • Static files. Healthchecks serves static files on its own, no configuration required. It uses the Whitenoise library for this.
  • General
    • Make sure the database is secured well and is getting backed up regularly
    • Make sure the TLS certificates are secured well and are getting refreshed regularly
    • Have monitoring in place to be sure the Healthchecks instance itself is operational (is accepting pings, is sending out alerts, is not running out of resources).

Docker Image

Healthchecks provides a reference Dockerfile and prebuilt Docker images for every release. The Dockerfile lives in the /docker/ directory, and Docker images for amd64, arm/v7 and arm64 architectures are available on Docker Hub.

The Docker images:

  • Use uWSGI as the web server. uWSGI is configured to perform database migrations on startup, and to run sendalerts, sendreports, and smtpd in the background. You do not need to run them separately.
  • Ship with both PostgreSQL and MySQL database drivers.
  • Serve static files using the whitenoise library.
  • Have the apprise library preinstalled.
  • Do not handle TLS termination. In a production setup, you will want to put the Healthchecks container behind a reverse proxy or load balancer that handles TLS termination.

healthchecks's People

Contributors

armiiller avatar bdd avatar caronc avatar carson0321 avatar cocide avatar cuu508 avatar dependabot[bot] avatar diwu1989 avatar furchin avatar henrywhitaker3 avatar issmirnov avatar jameskirsop avatar jamespanic avatar mkelley82 avatar mmomjian avatar mounirmesselmeni avatar omurbekjk avatar phyxius avatar realorangeone avatar sairam avatar samyerkes avatar schnouki avatar seidnerj avatar snyk-bot avatar someposer avatar supersandro2000 avatar swoga avatar szepeviktor avatar umitakkaya avatar zonito 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  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

healthchecks's Issues

period 1 month

Hi,

I want to healthchecking some scripts monthly executed, is possible to modify period for this?

Thanks

Dynamic HCs for ephemeral nodes for a service

First of all, thank you for this great software and making it available.
I would like to perform health checks for services and batch jobs which should run always, but are run from different servers/nodes by autoscaling them.
For example:

  • serviceA:instance1
  • serviceA:instance2
  • serviceA:instance3
  • serviceB:instance1

The service should be always on, but instance count and name would vary with time. The service list is always the same and would be fine to maintain it by hand. But instances aren't always the same and names/identifiers can't be known in advance.
Would be great if instances could self-register themselves for a specific service kind to start being monitored. For those temporary instances, a single alert about each one leaving would suffice.
As of now, uuids have to be created ahead of time, but:

  • Can pings to an uuid have added any kind of info with the instance name that could work?
  • Can uuids be created dynamically via an API?
  • Is there any way to remove the need to create uuids beforehand (on the fly)?

IMHO, this kind of usage makes a lot of sense in the age of cloud.
Thanks in advance.

Some errors CentOS 6

Hello guy,

I try to install your amazing project, but have some issue.

Do you have any requirement to install all needed packages with dependencies ? Do i need to use a sort of linux distribution?

Do you think that we can have a docker version of your application ?

Regards

Server error for second time login link used

Steps to reproduce:

  1. request a login link at https://healthchecks.io/accounts/login/
  2. Click on the login link in the email.
  3. I'm logged in as expected
  4. Click the link again, page returns error: Server Error Something bad happened and you should feel bad.
    (If I logout first and then click the link I get the same error message.)

Expected result:
An error message stating that I can use the link only once.

Disable Alert

We use Chef as our configuration management tool, and provide the healthchecks.io url for a particular server instance as part of the config for that machine (it's an attribute in a node file).

The problem is we will bring machines up and down periodically, so if a machine is up, a cron job will run and then hit the healthcheck.io url, but if we then shut the machine down we continually get alerts for that machine until we boot it up again.

It'd be nice if you could disable (not delete) a healthcheck.io url, as deleting it means that you'll have to create a new url and change the config for that node in your config management tool.

An option to keep nagging the user until they resolve issues

When a check goes down we notify the user once and that's it. PagerDuty, VictorOps and PushOver (with Emergency setting) will in fact keep alerting user until they acknowledge the issue. It would be nice to have a similar option for the regular email notifications as well.

Alternatively this could be account-wide, similar to monthly reports, and be called "Daily Digest".

Feature Request: Logging

I use graylog to capture all of my application logs at the debug level almost and also use it to ensure certain things are still running.

So, for instance, it looks like the "sendalerts" process has failed on my a few time, once or twice I'm not exactly sure why, the other time because the MySQL connection went away while I was doing an upgrade and I didn't notice.

Usually in graylog I would capture all the logs and baseline the rate. So I have health checks pinging a few every minute and the check for alert sending runs basically once every minute which I can see from the -- MARK 2016-04-29T15:28:36.779584+00:00 -- line, I should be able to have graylog send me an alert if the rate of those lines drops below say 8 times in a given 10 minute window.

Would it be possible to add a disk logging, syslog, or even better the option to use the python logging module so I could use something like the GELF library or AMPQ GELF library and send logs direct to my local RabbitMQ server?

P.S. Awesome job on the variable in webhooks, I moved that into production today and so far my tests show that it's working perfectly. Now I've got that much LESS email clutter! Thanks!!

Outage

Was there an outage?
I've got only "red exclamation marks".

Time display text in a check log

On the screen where you view the log of a check, there is a note that says:

Note: Dates and times are displayed in UTC.

However, my system is set to EST. I think the log view should show the timezone it's displaying in.

screen shot 2016-04-10 at 12 58 27 pm

Checks move to "pause" state but receive their ping normally

Hi,
we are seeing quite a lot of checks in a pause state but we have no idea, how the pause state is defined and what it means. (Isn't mentioned in the docs) The checks get their ping regularly though.

Thanks for the help in advance.

best regards,

Daniel

user has no profile

for some reason on a fresh local install following the readme and testing with ./manage.py runserver I get "user has no profile" when logging in for the first time.

am I missing something or is this a bug?

Environment:


Request Method: GET
Request URL: http://healthchecks.***.**/

Django Version: 1.9
Python Version: 3.4.3
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.humanize',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'compressor',
 'djmail',
 'hc.accounts',
 'hc.api',
 'hc.front',
 'hc.payments')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware',
 'hc.accounts.middleware.TeamAccessMiddleware')



Traceback:

File "/www/sites/healthchecks.telsys.no/hc-venv/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
  123.                 response = middleware_method(request)

File "/www/sites/healthchecks.telsys.no/healthchecks/hc/accounts/middleware.py" in process_request
  13.         profile = request.user.profile

File "/www/sites/healthchecks.telsys.no/hc-venv/lib/python3.4/site-packages/django/utils/functional.py" in inner
  205.         return func(self._wrapped, *args)

File "/www/sites/healthchecks.telsys.no/hc-venv/lib/python3.4/site-packages/django/db/models/fields/related_descriptors.py" in __get__
  355.                     self.related.get_accessor_name()

Exception Type: RelatedObjectDoesNotExist at /
Exception Value: User has no profile.

Support for other DBs

Hi,

first: thanks for this project. Was just looking for cronitor.io alternatives and thought to create something similar, but I guess you already did the job. ;)

One question though: Is it possible, not to use Postgresql but use MySQL instead?

Production setup

I've been following the "Setting Up for Development" guide to try to come up with a setup that's better adapted to actually running a production server. I think I've got most things right, but I'm stumbling somewhere. My plan is to run this behind Caddy (https://caddyserver.com/). Are there any instructions anywhere for how to set up a "production" server to run healthchecks? If not, I'm happy to contribute one, but might need some pointers.

Concurrent sendalerts

I've been thinking and experimenting with HA stuff quite a bit recently. One of the pieces of the puzzle is being able to run two "sendalerts" worker processes concurrently. So if one goes away, the other one picks up the slack. Obviously they must not send the notifications twice so there needs to be some kind of a locking mechanism.

Assume the database (PostgreSQL) is beefy, can take the load, has automatic failover, etc. Assume there's no separate message broker. Here's what I'm considering:

  1. Assign an unique name to each worker process running the "sendalerts" command
  2. Add two new fields to api_check table: alert_worker (varchar) and alert_date (date).
  3. Each worker polls the api_check table and looks for alerts that need to be sent–same as now. But when it finds one:
  • it updates alert_worker and alert_date columns with worker's name and current date, and commits
  • it reads both values back
  • if either of the values has changed, it does nothing and goes back to polling for more work
  • if both values are unchanged, it goes ahead and sends the alert
  • after the alert is sent, it clears out alert_worker and alert_date fields

My thinking is, if the database supports at least "read commited" isolation level, this should prevent multiple workers from sending duplicate alerts. The alert_worker field is effectively an application-level lock, and the alert_date can be used for calculating its expiry date (in case a worker dies before it blanks out the the two fields).

Alternatively, with PostgreSQL, the advisory locks could be used, and would likely perform better. But then MySQL would still need a separate mechanism like the above.

"sendalerts" dies on MySQL interruption

First of all, freaking amazing job with the app so far... I love it and use it for all kinds of stuff now!! The webhook variable are awesome and tie into my notification service perfectly!! Thanks!!

Since then I've expanded my setup on my cloud servers to include a 2 node MariaDB Galera cluster with MaxScale as the front end to help balance the load between DB servers... there's a lot of stuff running on there now.

Sometimes it take MaxScale a few seconds to see a node is dead, mark it as such and reroute the connections to another working node, what I noticed in that int he "manage.py runserver" function, this works great... if a ping happens to come in while it still hasn't rerouted, it shows some error info, but attempts to reconnect to the database which is does without a problem and keeps on tuckin'

HOWEVER, the "sendalerts" function does not. When it noticed the DB connection has gone away, even for just a brief second, it throws out a very similar error message to the "runserver" function, but does NOT attempt to reconnect. The thread just dies and exits.

Is there any way to make the sendalert function attempt to reconnect just like the runserver function does?

(I forgot to grab the debug error output from my testing before posting this, but I'm happy to force the failure in my dev environment and post it if you need it)

Get notified if a job is run too often

Hey, thanks for a really neat project & service!

It would be nice to have the possibility to get notified if a job is run too often.

Unfortunately, I don't have the time to dig in and implement it myself, and I'm sorry in case you don't want feature requests as Github issues.

Dependency: braintree should be add to requirements.txt

Start the server with error

Unhandled exception in thread started by <function wrapper at 0x7ff38fabe320>
Traceback (most recent call last):
  File "/home/liushaohui/workspace/opensource/healthchecks/hc-venv/local/lib/python2.7/site-packages/django/utils/autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)
  File "/home/liushaohui/workspace/opensource/healthchecks/hc-venv/local/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 116, in inner_run
    self.check(display_num_errors=True)
  File "/home/liushaohui/workspace/opensource/healthchecks/hc-venv/local/lib/python2.7/site-packages/django/core/management/base.py", line 426, in check
    include_deployment_checks=include_deployment_checks,
  File "/home/liushaohui/workspace/opensource/healthchecks/hc-venv/local/lib/python2.7/site-packages/django/core/checks/registry.py", line 75, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/home/liushaohui/workspace/opensource/healthchecks/hc-venv/local/lib/python2.7/site-packages/django/core/checks/urls.py", line 10, in check_url_config
    return check_resolver(resolver)
  File "/home/liushaohui/workspace/opensource/healthchecks/hc-venv/local/lib/python2.7/site-packages/django/core/checks/urls.py", line 19, in check_resolver
    for pattern in resolver.url_patterns:
  File "/home/liushaohui/workspace/opensource/healthchecks/hc-venv/local/lib/python2.7/site-packages/django/utils/functional.py", line 33, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/liushaohui/workspace/opensource/healthchecks/hc-venv/local/lib/python2.7/site-packages/django/core/urlresolvers.py", line 417, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/home/liushaohui/workspace/opensource/healthchecks/hc-venv/local/lib/python2.7/site-packages/django/utils/functional.py", line 33, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/liushaohui/workspace/opensource/healthchecks/hc-venv/local/lib/python2.7/site-packages/django/core/urlresolvers.py", line 410, in urlconf_module
    return import_module(self.urlconf_name)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/home/liushaohui/workspace/opensource/healthchecks/hc/urls.py", line 9, in <module>
    url(r'^',          include('hc.payments.urls'))
  File "/home/liushaohui/workspace/opensource/healthchecks/hc-venv/local/lib/python2.7/site-packages/django/conf/urls/__init__.py", line 52, in include
    urlconf_module = import_module(urlconf_module)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/home/liushaohui/workspace/opensource/healthchecks/hc/payments/urls.py", line 3, in <module>
    from . import views
  File "/home/liushaohui/workspace/opensource/healthchecks/hc/payments/views.py", line 1, in <module>
    import braintree
ImportError: No module named braintree

local_settings.py seems to ignore site_root and host

I was trying to move all my configs over to a proper local_settings.py file to make it easier to do "git pull" for updates, but when I leave the settings.py set for HOST = "localhost" and SITE_ROOT = "hs.mydomain.com" it doesn't work.

The main checks page in the web interface ends up showing http://localhost:8000/ping/xyz.... and if I comment out the HOST and SITE_ROOT from settings.py to try to make use the values from local_settings.py, the app errors out and won't start.

NoReverseMatch at /checks/ after latest git pull

NoReverseMatch at /checks/
Reverse for 'hc-pause' with arguments '(UUID('52416f5d-ccc3-4b14-94f0-0869d1398473'),)' and keyword arguments '{}' not found. 0 pattern(s) tried: []
Request Method: GET
Request URL:    http://*************/checks/
Django Version: 1.9
Exception Type: NoReverseMatch
Exception Value:    
Reverse for 'hc-pause' with arguments '(UUID('52416f5d-ccc3-4b14-94f0-0869d1398473'),)' and keyword arguments '{}' not found. 0 pattern(s) tried: []
Exception Location: /usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py in _reverse_with_prefix, line 508
Python Executable:  /usr/bin/python
Python Version: 2.7.6
Python Path:    
['/mnt/gluster/volume_gen001/apps/healthchecks',
 '/usr/local/lib/python2.7/dist-packages/paypalrestsdk-1.11.3-py2.7.egg',
 '/usr/local/lib/python2.7/dist-packages/pyOpenSSL-0.15.1-py2.7.egg',
 '/usr/lib/python2.7',
 '/usr/lib/python2.7/plat-x86_64-linux-gnu',
 '/usr/lib/python2.7/lib-tk',
 '/usr/lib/python2.7/lib-old',
 '/usr/lib/python2.7/lib-dynload',
 '/usr/local/lib/python2.7/dist-packages',
 '/usr/lib/python2.7/dist-packages']
Server time:    Sat, 6 Aug 2016 09:33:32 -0500

Traceback:

Environment:


Request Method: GET
Request URL: http://hc.casta.no/checks/

Django Version: 1.9
Python Version: 2.7.6
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.humanize',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'compressor',
 'djmail',
 'hc.accounts',
 'hc.api',
 'hc.front',
 'hc.payments')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware',
 'hc.accounts.middleware.TeamAccessMiddleware')


Template error:
In template /mnt/gluster/volume_gen001/apps/healthchecks/templates/front/my_checks.html, error at line 94
   Reverse for 'hc-pause' with arguments '(UUID('52416f5d-ccc3-4b14-94f0-0869d1398473'),)' and keyword arguments '{}' not found. 0 pattern(s) tried: []   84 :                         <div class="form-group">
   85 :                             <label for="update-tags-input" class="col-sm-2 control-label">
   86 :                                 Tags
   87 :                             </label>
   88 :                             <div class="col-sm-9">
   89 :                                 <input
   90 :                                     id="update-tags-input"
   91 :                                     name="tags"
   92 :                                     type="text"
   93 :                                     value=""
   94 :                                      placeholder="production  www"
   95 :                                     class="form-control" />
   96 : 
   97 :                                 <span class="help-block">
   98 :                                     Optionally, assign tags for easy filtering.
   99 :                                     Separate multiple tags with spaces.
   100 :                                 </span>
   101 :                             </div>
   102 :                         </div>
   103 :                 </div>
   104 :                 <div class="modal-footer">


Traceback:

File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
  149.                     response = self.process_exception_by_middleware(e, request)

File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
  147.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/contrib/auth/decorators.py" in _wrapped_view
  23.                 return view_func(request, *args, **kwargs)

File "/mnt/gluster/volume_gen001/apps/healthchecks/hc/front/views.py" in my_checks
  58.     }

File "/usr/local/lib/python2.7/dist-packages/django/shortcuts.py" in render
  67.             template_name, context, request=request, using=using)

File "/usr/local/lib/python2.7/dist-packages/django/template/loader.py" in render_to_string
  97.         return template.render(context, request)

File "/usr/local/lib/python2.7/dist-packages/django/template/backends/django.py" in render
  95.             return self.template.render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render
  206.                     return self._render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in _render
  197.         return self.nodelist.render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render
  988.                 bit = node.render_annotated(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render_annotated
  955.             return self.render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/loader_tags.py" in render
  173.         return compiled_parent._render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in _render
  197.         return self.nodelist.render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render
  988.                 bit = node.render_annotated(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render_annotated
  955.             return self.render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/loader_tags.py" in render
  69.                 result = block.nodelist.render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render
  988.                 bit = node.render_annotated(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render_annotated
  955.             return self.render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/loader_tags.py" in render
  69.                 result = block.nodelist.render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render
  988.                 bit = node.render_annotated(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render_annotated
  955.             return self.render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/defaulttags.py" in render
  326.                 return nodelist.render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render
  988.                 bit = node.render_annotated(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render_annotated
  955.             return self.render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/loader_tags.py" in render
  209.                 return template.render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render
  208.                 return self._render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in _render
  197.         return self.nodelist.render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render
  988.                 bit = node.render_annotated(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render_annotated
  955.             return self.render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/defaulttags.py" in render
  220.                     nodelist.append(node.render_annotated(context))

File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render_annotated
  955.             return self.render(context)

File "/usr/local/lib/python2.7/dist-packages/django/template/defaulttags.py" in render
  513.                         six.reraise(*exc_info)

File "/usr/local/lib/python2.7/dist-packages/django/template/defaulttags.py" in render
  499.             url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)

File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py" in reverse
  600.     return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))

File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py" in _reverse_with_prefix
  508.                              (lookup_view_s, args, kwargs, len(patterns), patterns))

Exception Type: NoReverseMatch at /checks/
Exception Value: Reverse for 'hc-pause' with arguments '(UUID('52416f5d-ccc3-4b14-94f0-0869d1398473'),)' and keyword arguments '{}' not found. 0 pattern(s) tried: []

I'm dead in the water... it seems like pings are working, I see them coming in and being issued 200 responses when running the server is debug mode... but everything else is dead.

Be able to setup/register a user account

Or at minimum, let me tie two emails to a single account.

I signed up using my work email, because it made sense. But it sometimes can take 10-20 minutes for my work email address to process emails (we have a weird server set up that pulls it to a gmail instance for me).

So anytime I want to log into the site, I put in my email. Then wait 10 minutes. It's a pain, and a username/password would be much much much easier.

powershell howto

Please consider including it.

  1. Create a powershell script: healthchecks.ps1
  2. Its content should be: Invoke-RestMethod https://hchk.io/YOUR-CHECK-UUID
  3. Start it as powershell.exe -ExecutionPolicy bypass -File path\to\healthchecks.ps1

Thanks.

Request: Flexible Schedules beyond X timeframe

In my use case, there are a few tasks that are paused off-hours. This creates quite a bit of downtime alerts for tasks that only run between certain times.

For example, we have a batch of tasks that run from 2:00 AM to 11:59pm. These tasks are scheduled like this to allow for maintenance related tasks to be run in that Midnight to 1:59 AM period.

Because of this, we receive quite a few downtime alerts which are actually false positives. This can cause legitimate downtimes to be missed.

Cron output

Hello!

This is a very nice project.
Have you been thinking about receiving script output?

./my-backup-script.sh > output.file 2>&1 || curl -X POST -d @output.file https://hchk.io/**************

All the best!

Cron example should suppress stdout

https://healthchecks.io/docs/ recommends

# m h dom mon dow   command
  8 6 *   *   *     /home/user/tasks/backup_all.sh && curl https://hchk.io/53770999-ffd4-4c9b-a62e-013e62bb3368

But curl prints the response string (OK) to stdout, which will cause cron to send an email. I suggest that you change the example to redirect the output to /dev/null.

Notifications not being sent.

I've added a little bit of code and got healthchecks to the a local postfix install via an GMail smarthost to send emails, config here:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'localhost' 
EMAIL_PORT = 25  
EMAIL_USE_TLS = False

I've got a check purposefully set VERY small, set to come in every 1 minute with a 1 minute grace. The web interface shows the checks late, then it shows them missing, but the email never goes out.

I know the email config works because when I entered my email it correctly sent the confirmation email. Is there something I need to change somewhere?

Add tags to integrations. Match checks and integrations using tags

Would be nice if the hchk tool can indicate which integrations should be used. By default all integrations are selected when a new check is created, and I have to manually go in and uncheck the integrations which are not needed.

I use the integrations to route information to different entities/organisations: example: http://instituut.net/~job/screenshots/42bb5441933ced72b96e4a73.png - the results of checks with tagcoloclue should go to the coloclue integrations, not to peeringdb.

login expired

Hi,

The login link is only valid for doing one login (next ones it says is invalid or expired), is this correct? Do I have to resend the link every time I want to login?

It is possible to save the login link in bookmarks?

Kind regards

Store ping logs in flat files

I'm considering moving ping logs (the api_ping table) out of database and into flat files.
Before I go ahead I want to gather people's opinions, there might be good arguments against doing this, or good ideas on how to do this in a smart way.

The motivation: ping logs currently take up the bulk of space in database, and in daily database backups. The number of stored pings is growing steadily and predictably. I could just prune old logs, but would rather like to keep them around for as long as is practical. I could exclude pings from backups but that's not ideal either.

The idea I'm considering is to write ping logs to flat files. Each check would get its own separate file. Each log entry would be a fixed width (say, 1024 bytes for easy maths). This makes some common operations easy:

  • tell the number of log entries in file: look up file size, divide by 1024
  • read last 100 entries of the log file: open file, fseek to (size - 100 * 1024), and read till end

Space is cheap and readability is important, so dates would be written in readable form (as opposed to compact binary format), and lines would terminate with newline. We would not be trying to save every last byte.

A good question is then–what about concurrent writes? Since each check gets its own file, these should be rare but in any case, looks like concurrent append writes should be fine: http://article.gmane.org/gmane.linux.kernel/43445

There would be a management command to migrate existing ping logs from database to flat files.

Drawbacks:

  • state of the system is now split up in database an the log files. A database export alone is not a complete, consistent snapshot of system's state any more
  • certain operations that would have been easy with SQL queries become hard with flat files. For example: "get a list of distinct User Agents for a given check", or "get the 100 most recent ping logs across all checks". Having the data in flat files, with no indexes and no SQL goodies can limit us in what we can do in the future. But I think it's worth it. It's also possible to migrate back in the future :-)

Thoughts?

Timezone setting in settings.py

Currently I have my settings.py file set for "EST" for Eastern Standard Time an all the times report 1 hour early because we're actually "EDT" for Eastern Daylight Time, but when entering "EDT" is errors out the server. I even tried forcing it with UTC-4 or UTC-5, neither of those worked either.

sendalerts doesn't work with new failures

Keep getting this stacktrace while testing notifications.

Sending alert, status=grace, code=11f7ef3e-bc25-4d85-8930-80090aab7418
Traceback (most recent call last):
  File "/app/manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/lib/python3.5/site-packages/django/core/management/__init__.py", line 350, in execute_from_command_line
    utility.execute()
  File "/usr/lib/python3.5/site-packages/django/core/management/__init__.py", line 342, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/lib/python3.5/site-packages/django/core/management/base.py", line 348, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/lib/python3.5/site-packages/django/core/management/base.py", line 399, in execute
    output = self.handle(*args, **options)
  File "/app/hc/api/management/commands/sendalerts.py", line 62, in handle
    if self.handle_many():
  File "/app/hc/api/management/commands/sendalerts.py", line 31, in handle_many
    future.result()
  File "/usr/lib/python3.5/concurrent/futures/_base.py", line 405, in result
    return self.__get_result()
  File "/usr/lib/python3.5/concurrent/futures/_base.py", line 357, in __get_result
    raise self._exception
  File "/usr/lib/python3.5/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/app/hc/api/management/commands/sendalerts.py", line 50, in handle_one
    errors = check.send_alert()
  File "/app/hc/api/models.py", line 72, in send_alert
    raise NotImplementedError("Unexpected status: %s" % self.status)

Notifications seem to work when ./manage.py sendalerts is invoked manually after 'check failure'. But when I start sendalerts in background I always get this stacktrace.

pushover integrations and ping logs

running healthchecks with uwsgi/emperor and there's 2 problems that I can't seem to find a cause for:

  1. checking the ping logs only shows:
Log is empty. This check has not received any pings yet.
  1. tried enabling pushover notifications and ended up with a 404


Using the URLconf defined in hc.urls, Django tried these URL patterns, in this order:

    ^admin/
    ^accounts/
    ^ ^ping/([\w-]+)/$ [name='hc-ping-slash']
    ^ ^ping/([\w-]+)$ [name='hc-ping']
    ^ ^api/v1/checks/$
    ^ ^api/v1/checks/([\w-]+)/pause$ [name='hc-api-pause']
    ^ ^badge/([\w-]+)/([\w-]{8})/([\w-]+).svg$ [name='hc-badge']
    ^ ^$ [name='hc-index']
    ^ ^checks/$ [name='hc-checks']
    ^ ^checks/add/$ [name='hc-add-check']
    ^ ^checks/([\w-]+)/
    ^ ^integrations/ ^$ [name='hc-channels']
    ^ ^integrations/ ^add/$ [name='hc-add-channel']
    ^ ^integrations/ ^add_email/$ [name='hc-add-email']
    ^ ^integrations/ ^add_webhook/$ [name='hc-add-webhook']
    ^ ^integrations/ ^add_pd/$ [name='hc-add-pd']
    ^ ^integrations/ ^add_slack/$ [name='hc-add-slack']
    ^ ^integrations/ ^add_slack_btn/$ [name='hc-add-slack-btn']
    ^ ^integrations/ ^add_hipchat/$ [name='hc-add-hipchat']
    ^ ^integrations/ ^add_pushbullet/$ [name='hc-add-pushbullet']
    ^ ^integrations/ ^add_pushover/$ [name='hc-add-pushover']
    ^ ^integrations/ ^add_victorops/$ [name='hc-add-victorops']
    ^ ^integrations/ ^([\w-]+)/checks/$ [name='hc-channel-checks']
    ^ ^integrations/ ^([\w-]+)/remove/$ [name='hc-remove-channel']
    ^ ^integrations/ ^([\w-]+)/verify/([\w-]+)/$ [name='hc-verify-email']
    ^ ^docs/$ [name='hc-docs']
    ^ ^docs/api/$ [name='hc-docs-api']
    ^ ^about/$ [name='hc-about']
    ^ ^privacy/$ [name='hc-privacy']
    ^ ^terms/$ [name='hc-terms']
    ^ ^pricing/$ [name='hc-pricing']
    ^ ^billing/$ [name='hc-billing']
    ^ ^invoice/([\w-]+)/$ [name='hc-invoice']
    ^ ^pricing/create_plan/$ [name='hc-create-plan']
    ^ ^pricing/update_payment_method/$ [name='hc-update-payment-method']
    ^ ^pricing/cancel_plan/$ [name='hc-cancel-plan']
    ^ ^pricing/get_client_token/$ [name='hc-get-client-token']

The current URL, integrations/add_pushover/healthchecks.****.no, didn't match any of these.

anything I can do to test/provide more logs, let me know.

and thanks for fixing the profile not found error :)

Feature Request: Webhook Variables

Based on our previous conversation:

Possibly writing web hooks with variable in them?

Can you please open a separate issue for this? I'm guessing the interesting variables would be check's status (up/down) and its name and code.

Yes, exactly what you suggested would be great, I basically have a service that's got TONS of notification options built into it including a pretty easy to hit http/https REST API.

So, if I wanted to send a message out, I'd do it like this:

http://notificationcentral.mydomain.com/api/v3.0/send?subject=Health Check Down&message=Check Backup Cron Job has missed a ping&priority=1&selectcode=xpg

Basically, the stuff that's a little more static, I'd love to make it so a "DOWN" notification gets a variable called maybe 'severity' and it's '1' for down '0' for up, that way services can actually use different sounds and styles... my app supports everything from '-5' up to '5' meaning '-5' send me a message but don't make a noise and it can be quick, or '0' hey this is info look at it, then finally '5' "OMG OMG OMG, I'm going to beep, buzz and play EVERYTHING until you acknowledge this!

The "selectcode" is something that can by typed into the webhook when that make it like 'x' sends the messages to XBMC/Kodi, 'p' for Pushover. 'b' for PushBullet, 'e' for email, 'g' for Growl or 'a' for "all services".

So basically I would love to have a variable for the "subject", "message" and "priority", and maybe a setting for each check for the priority level of the up and down values, if not 1 for down, 0 for up.

Does that sound possible?

Make the server listen to outside of localhost

Hey,

Recently came to know your tool. A very sincere work from your side. Congrats!

I'm trying to set it up in my system (centos 6.5 64 bit). I have started the development server:

System check identified no issues (0 silenced).
September 11, 2015 - 16:24:15
Django version 1.8.2, using settings 'hc.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

How to make it listen to server's public IP address instead of localhost?

Thank you.

Cron syntax

It would be great if one could just insert the cron syntax. Got any ideas about that?

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.