Giter Site home page Giter Site logo

brotandgames / ciao Goto Github PK

View Code? Open in Web Editor NEW
1.8K 1.8K 98.0 1008 KB

HTTP checks & tests (private & public) monitoring - check the status of your URL

Home Page: https://brotandgames.com/ciao/

License: MIT License

Dockerfile 1.36% Ruby 74.57% JavaScript 3.29% HTML 17.58% Shell 1.63% SCSS 0.30% Mustache 1.27%
alerting application-monitoring http monitoring prometheus uptime website-monitor

ciao's People

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

ciao's Issues

Bootstrap from Configuration file

Can this be deployed using a config file and put into a 'read-only' mode so that it may be deployed as part of a CI/CD flow onto infrastructure without needing to worry about managing state and backups etc.

I'd like to deploy this service onto a Kubernetes environment where we declare the endpoints using a configuration file (eg yaml) for all the endpoints, then changes to sites etc would be a redeployment of the services ConfigMap.

Ideally the service would then recognise the configfile change and reload without losing existing state data.

Running on M1 fails to start

Describe the bug
Run the command on a MacBook M1 (Max)

docker run --name ciao -p 8090:3000 brotandgames/ciao

To Reproduce
Steps to reproduce the behavior:

  1. Ensure Docker is running
  2. Execute docker run --name ciao -p 8090:3000 brotandgames/ciao
  3. See error

Expected behavior
No error and running

Desktop (please complete the following information):

  • OS: MacOS 12.3

Additional context
Log: https://gist.github.com/JKetelaar/5c3dc81ebfc40e6b9517281212ac9a36

Unable to run ciao on raspberry pi using docker

Describe the bug
When I try to run ciao on a raspberry pi using docker, I see a linux error. I did not encounter the same problem on OSX

To Reproduce
After installing docker on a raspberry pi and then running ciao with
docker run --name ciao -p 8090:3000 brotandgames/ciao
I see the following error:
standard_init_linuz.go:211 eexec user process caused "exec format error"

Expected behavior
When I ran the same command on OSX, ciao started as requested, and I found it so useful, that I want to run it 24/7 on a rapsberry pi.

Desktop (please complete the following information):
The operating system is Raspbian GNU/Linux, version 10 (buster).
It is running on a raspberry pi 3 model B

Docker build on linux/arm* fails

Describe the bug

Docker build on linux/arm* fails

#29 [linux/arm64 8/9] COPY . ./
#29 DONE 0.3s

#30 [linux/arm64 9/9] RUN set -x     && apk add --no-cache xz-libs     && SECRET_KEY_BASE=foo bundle exec rake assets:precompile     && rm -rf         /tmp/*         app/assets         lib/assets         node_modules         spec         tmp/cache         vendor/assets
#30 0.097 + apk add --no-cache xz-libs
#30 0.154 fetch https://dl-cdn.alpinelinux.org/alpine/v3.15/main/aarch64/APKINDEX.tar.gz
#30 0.712 fetch https://dl-cdn.alpinelinux.org/alpine/v3.15/community/aarch64/APKINDEX.tar.gz
#30 1.710 (1/1) Installing xz-libs (5.2.5-r0)
#30 1.762 OK: 69 MiB in 45 packages
#30 1.875 + SECRET_KEY_BASE=foo bundle exec rake assets:precompile
#30 18.72 rake aborted!
#30 18.72 LoadError: cannot load such file -- nokogiri/nokogiri
#30 18.72 /usr/local/bundle/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:27:in `require'
#30 18.72 /usr/local/bundle/gems/activesupport-6.1.4.7/lib/active_support/dependencies.rb:332:in `block in require'

Build for arm is currently disabled: Build only for linux/amd64 because linux/arm* currently broken

To Reproduce

See GitHub Action run https://github.com/brotandgames/ciao/runs/5795452795?check_suite_focus=true

Expected behavior

Docker build on linux/arm* succeeds

Favicon proposition

Hey :)

Thanks for ciao, it's really simple and i love to use it ! :D
The only thing is I can't identify quickly ciao in a browser since there's no favicon :/ So i propose this favicon :) (I can send you the svg version if you'd like ;) )
favicon-32x32

cheerz :)

multiple checks

Hello, can you add several checks, for example, in a minute and only if the statuses match - send an alert, because there are a lot of false positives ?

Docker-compose webhooks issue

Describe the bug
I don't get any notifications from TG webhooks set as env variables in docker-compose.yml

CIAO_WEBHOOK_ENDPOINT_TELEGRAM="https://api.telegram.org/bot<TG-bot-auth-tocken>/sendMessage"
CIAO_WEBHOOK_PAYLOAD_TELEGRAM='{"chat_id":<chat-room-id>,"disable_web_page_preview":1,"text": "[__name__] Status changed from (__status_before__) to (__status_after__)"}'

When checked with curl I found

{"ok":false,"error_code":400,"description":"Bad Request: message text is empty"} response.

The command was pretty plain:

curl -X POST https://api.telegram.org/bot<TG-bot-auth-tocken>/sendMessage"  -d '{"chat_id":<chat-room-id>,"disable_web_page_preview":1,"text": "[__name__] Status changed from (__status_before__) to (__status_after__)"}'

The messages are sending correctly when specify the json-content Header:

curl -X POST https://api.telegram.org/bot<TG-bot-auth-tocken>/sendMessage"  -d '{"chat_id":<chat-room-id>,"disable_web_page_preview":1,"text": "[__name__] Status changed from (__status_before__) to (__status_after__)"}' -H 'Content-Type: application/json'

Could it be that I was needed to specify more params in docker-compose file to make notifications working?

Logs for email notification failure

Is there any way to get logs on the email notifications ?

My email configuration isn't working and the logs aren't showing anything so it's difficult to fix.

can't send mail

Describe the bug
I start the service use docker-compose

[root@docker-t1 soft]# cat docker-compose.yml
version: "2"
services:
  ciao:
    image: brotandgames/ciao
    container_name: ciao
    ports:
      - '8090:3000'
    environment:
      #- SECRET_KEY_BASE=sensitive_secret_key_base
      - SMTP_ADDRESS=smtp.qq.com
      - SMTP_EMAIL_FROM="[email protected]"
      - SMTP_EMAIL_TO="[email protected]"
      - SMTP_PORT=465
      - SMTP_AUTHENTICATION=login
      - SMTP_DOMAIN=smtp.qq.com
      - SMTP_ENABLE_STARTTLS_AUTO=true
      - SMTP_USERNAME="[email protected]"
      - SMTP_PASSWORD="xxxxxxx"
    volumes:
      - /opt/ciao/data:/app/db/sqlite/
      - /etc/localtime:/etc/localtime

then I start the service,but can't send mail. I use python script use this mail config can send mail

ciao    | D, [2020-05-27T17:09:03.064004 #1] DEBUG -- : CheckMailer#change_status_mail: processed outbound mail in 1.6ms
ciao    | I, [2020-05-27T17:09:33.082877 #1]  INFO -- : Delivered mail [email protected] (30018.5ms)
ciao    | D, [2020-05-27T17:09:33.083080 #1] DEBUG -- : Date: Wed, 27 May 2020 17:09:03 +0800
ciao    | From: "[email protected]"
ciao    | To: "[email protected]"
ciao    | Message-ID: <[email protected]>
ciao    | Subject: [ciao] cpa_center-87: Status changed (200)
ciao    | Mime-Version: 1.0
ciao    | Content-Type: text/plain;
ciao    |  charset=UTF-8
ciao    | Content-Transfer-Encoding: 7bit
ciao    |
ciao    | ciao
ciao    |
ciao    | The status of 'cpa_center-87' check changed
ciao    |
ciao    | from: Failed to open TCP connection to 172.10.13.9:5000 (Connection refused - connect(2) for "172.10.13.9" port 5000)
ciao    | to: 200
ciao    |
ciao    | E, [2020-05-27T17:09:33.103392 #1] ERROR -- : err47171798803180 rufus-scheduler intercepted #<EOFError: end of file reached> in job #<Rufus::Scheduler::CronJob:0x000055ce14a08998 @scheduler=#<Rufus::Scheduler:0x000055ce141d4560 @opts={}, @started_at=#<EtOrbi::EoTime:0x000055ce141d4218 @seconds=1590566233.4757986, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @paused=false, @jobs=#<Rufus::Scheduler::JobArray:0x000055ce141d4538 @mutex=#<Thread::Mutex:0x000055ce141d44e8>, @array=[#<Rufus::Scheduler::CronJob:0x000055ce141eb8c8 @scheduler=#<Rufus::Scheduler:0x000055ce141d4560 ...>, @original="* * * * *", @opts={:job=>true}, @handler=#<Proc:0x000055ce141eb990@/app/app/models/check.rb:53>, @callable=#<Proc:0x000055ce141eb990@/app/app/models/check.rb:53>, @scheduled_at=#<EtOrbi::EoTime:0x000055ce141eb850 @seconds=1590566233.4759426, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @unscheduled_at=nil, @last_time=#<EtOrbi::EoTime:0x000055ce13c2d7b0 @seconds=1590570540.2767475, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @locals={}, @local_mutex=#<Thread::Mutex:0x000055ce141eb7d8>, @id="cron_1590566233.4759426_47171794590820", @tags=[], @count=72, @last_work_time=0.09134125709533691, @mean_work_time=0.08705019619729783, @paused_at=nil, @times=nil, @first_at=nil, @last_at=nil,@cron_line=#<Fugit::Cron:0x000055ce145ea410 @original="* * * * *", @cron_s=nil, @seconds=[0], @minutes=nil, @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil, @zone=nil, @timezone=nil>, @next_time=#<EtOrbi::EoTime:0x000055ce1405d790 @seconds=1590570600.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @previous_time=#<EtOrbi::EoTime:0x000055ce16a036f8 @seconds=1590570540.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>>, #<Rufus::Scheduler::CronJob:0x000055ce146a44a0 @scheduler=#<Rufus::Scheduler:0x000055ce141d4560 ...>, @original="* * * * *", @opts={:job=>true}, @handler=#<Proc:0x000055ce146a4540@/app/app/models/check.rb:53>, @callable=#<Proc:0x000055ce146a4540@/app/app/models/check.rb:53>, @scheduled_at=#<EtOrbi::EoTime:0x000055ce146a4450 @seconds=1590566233.4833448, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @unscheduled_at=nil, @last_time=#<EtOrbi::EoTime:0x000055ce13c2d5a8 @seconds=1590570540.2768044, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @locals={}, @local_mutex=#<Thread::Mutex:0x000055ce146a43d8>, @id="cron_1590566233.4833448_47171797066320", @tags=[], @count=72, @last_work_time=0.2022993564605713, @mean_work_time=0.1849403977394104, @paused_at=nil, @times=nil, @first_at=nil, @last_at=nil, @cron_line=#<Fugit::Cron:0x000055ce146dece0 @original="* * * * *", @cron_s=nil, @seconds=[0], @minutes=nil, @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil, @zone=nil, @timezone=nil>, @next_time=#<EtOrbi::EoTime:0x000055ce1488fc38 @seconds=1590570600.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @previous_time=#<EtOrbi::EoTime:0x000055ce16a56128 @seconds=1590570540.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>>, #<Rufus::Scheduler::CronJob:0x000055ce146eb288 @scheduler=#<Rufus::Scheduler:0x000055ce141d4560 ...>, @original="* * * * *", @opts={:job=>true}, @handler=#<Proc:0x000055ce146eb300@/app/app/models/check.rb:53>, @callable=#<Proc:0x000055ce146eb300@/app/app/models/check.rb:53>, @scheduled_at=#<EtOrbi::EoTime:0x000055ce146eb238 @seconds=1590566233.4876938, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @unscheduled_at=nil, @last_time=#<EtOrbi::EoTime:0x000055ce13c6ecb0 @seconds=1590570540.2774732, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @locals={}, @local_mutex=#<Thread::Mutex:0x000055ce146eb1c0>, @id="cron_1590566233.4876938_47171797211460", @tags=[], @count=72, @last_work_time=0.12115478515625, @mean_work_time=0.1659698353873359, @paused_at=nil, @times=nil, @first_at=nil, @last_at=nil, @cron_line=#<Fugit::Cron:0x000055ce146fc010 @original="* * * * *", @cron_s=nil, @seconds=[0], @minutes=nil, @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil, @zone=nil, @timezone=nil>, @next_time=#<EtOrbi::EoTime:0x000055ce146f3fa0 @seconds=1590570600.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @previous_time=#<EtOrbi::EoTime:0x000055ce16a3c3e0 @seconds=1590570540.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>>, #<Rufus::Scheduler::CronJob:0x000055ce1470f408 @scheduler=#<Rufus::Scheduler:0x000055ce141d4560 ...>, @original="* * * * *", @opts={:job=>true}, @handler=#<Proc:0x000055ce1470f480@/app/app/models/check.rb:53>, @callable=#<Proc:0x000055ce1470f480@/app/app/models/check.rb:53>, @scheduled_at=#<EtOrbi::EoTime:0x000055ce1470f3b8 @seconds=1590566233.4922304, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @unscheduled_at=nil, @last_time=#<EtOrbi::EoTime:0x000055ce13c9d7e0 @seconds=1590570540.2780707, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @locals={}, @local_mutex=#<Thread::Mutex:0x000055ce1470f340>, @id="cron_1590566233.4922304_47171797285380", @tags=[], @count=72, @last_work_time=0.12085676193237305, @mean_work_time=0.1337959170341491, @paused_at=nil, @times=nil, @first_at=nil, @last_at=nil, @cron_line=#<Fugit::Cron:0x000055ce14736e90 @original="* * * * *", @cron_s=nil, @seconds=[0], @minutes=nil, @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil, @zone=nil, @timezone=nil>, @next_time=#<EtOrbi::EoTime:0x000055ce146f1e08 @seconds=1590570600.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @previous_time=#<EtOrbi::EoTime:0x000055ce16a37a20 @seconds=1590570540.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>>, #<Rufus::Scheduler::CronJob:0x000055ce14755e80 @scheduler=#<Rufus::Scheduler:0x000055ce141d4560 ...>, @original="* * * * *", @opts={:job=>true}, @handler=#<Proc:0x000055ce14755ef8@/app/app/models/check.rb:53>, @callable=#<Proc:0x000055ce14755ef8@/app/app/models/check.rb:53>, @scheduled_at=#<EtOrbi::EoTime:0x000055ce14755e30 @seconds=1590566233.4967785, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @unscheduled_at=nil, @last_time=#<EtOrbi::EoTime:0x000055ce13ccb410 @seconds=1590570540.278577, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @locals={}, @local_mutex=#<Thread::Mutex:0x000055ce14755db8>,@id="cron_1590566233.4967785_47171797430080", @tags=[], @count=72, @last_work_time=0.19220876693725586, @mean_work_time=0.15794450706905785, @paused_at=nil, @times=nil, @first_at=nil, @last_at=nil, @cron_line=#<Fugit::Cron:0x000055ce1479ff08 @original="* * * * *", @cron_s=nil, @seconds=[0],@minutes=nil, @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil, @zone=nil, @timezone=nil>, @next_time=#<EtOrbi::EoTime:0x000055ce1487ed48 @seconds=1590570600.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @previous_time=#<EtOrbi::EoTime:0x000055ce12e2ac58 @seconds=1590570540.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>>, #<Rufus::Scheduler::CronJob:0x000055ce147b3dc8 @scheduler=#<Rufus::Scheduler:0x000055ce141d4560 ...>, @original="* * * * *", @opts={:job=>true}, @handler=#<Proc:0x000055ce147b3e40@/app/app/models/check.rb:53>, @callable=#<Proc:0x000055ce147b3e40@/app/app/models/check.rb:53>, @scheduled_at=#<EtOrbi::EoTime:0x000055ce147b3d78 @seconds=1590566233.50178, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @unscheduled_at=nil, @last_time=#<EtOrbi::EoTime:0x000055ce13ce97f8 @seconds=1590570540.2792532, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @locals={}, @local_mutex=#<Thread::Mutex:0x000055ce147b3d00>, @id="cron_1590566233.50178_47171797622500", @tags=[], @count=72, @last_work_time=0.17959380149841309, @mean_work_time=0.17012638515896267, @paused_at=nil, @times=nil, @first_at=nil, @last_at=nil, @cron_line=#<Fugit::Cron:0x000055ce147d4eb0 @original="* * * * *", @cron_s=nil, @seconds=[0], @minutes=nil, @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil, @zone=nil, @timezone=nil>, @next_time=#<EtOrbi::EoTime:0x000055ce14847578 @seconds=1590570600.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @previous_time=#<EtOrbi::EoTime:0x000055ce16957dd0 @seconds=1590570540.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>>, #<Rufus::Scheduler::CronJob:0x000055ce147ebc28 @scheduler=#<Rufus::Scheduler:0x000055ce141d4560 ...>, @original="* * * * *", @opts={:job=>true}, @handler=#<Proc:0x000055ce147ebd40@/app/app/models/check.rb:53>, @callable=#<Proc:0x000055ce147ebd40@/app/app/models/check.rb:53>, @scheduled_at=#<EtOrbi::EoTime:0x000055ce147ebbd8 @seconds=1590566233.506718, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @unscheduled_at=nil, @last_time=#<EtOrbi::EoTime:0x000055ce13cf8a50 @seconds=1590570540.2799325, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @locals={}, @local_mutex=#<Thread::Mutex:0x000055ce147ebb60>, @id="cron_1590566233.506718_47171797736980", @tags=[], @count=72, @last_work_time=0.1285414695739746, @mean_work_time=0.18830695417192247, @paused_at=nil, @times=nil, @first_at=nil, @last_at=nil, @cron_line=#<Fugit::Cron:0x000055ce1480b118 @original="* * * * *", @cron_s=nil, @seconds=[0], @minutes=nil, @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil, @zone=nil, @timezone=nil>, @next_time=#<EtOrbi::EoTime:0x000055ce14755340 @seconds=1590570600.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @previous_time=#<EtOrbi::EoTime:0x000055ce16a644f8 @seconds=1590570540.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>>, #<Rufus::Scheduler::CronJob:0x000055ce14812850 @scheduler=#<Rufus::Scheduler:0x000055ce141d4560 ...>, @original="* * * * *", @opts={:job=>true}, @handler=#<Proc:0x000055ce148128c8@/app/app/models/check.rb:53>, @callable=#<Proc:0x000055ce148128c8@/app/app/models/check.rb:53>, @scheduled_at=#<EtOrbi::EoTime:0x000055ce14812800 @seconds=1590566233.5120916, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @unscheduled_at=nil, @last_time=#<EtOrbi::EoTime:0x000055ce13d10df8 @seconds=1590570540.2804615, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @locals={}, @local_mutex=#<Thread::Mutex:0x000055ce14812788>, @id="cron_1590566233.5120916_47171797816360", @tags=[], @count=72, @last_work_time=0.15210294723510742, @mean_work_time=0.21825869546996224, @paused_at=nil, @times=nil, @first_at=nil, @last_at=nil, @cron_line=#<Fugit::Cron:0x000055ce1482fd38 @original="* * * * *", @cron_s=nil, @seconds=[0], @minutes=nil, @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil, @zone=nil, @timezone=nil>, @next_time=#<EtOrbi::EoTime:0x000055ce147fff48 @seconds=1590570600.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @previous_time=#<EtOrbi::EoTime:0x000055ce129ebed0 @seconds=1590570540.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>>, #<Rufus::Scheduler::CronJob:0x000055ce148378f8 @scheduler=#<Rufus::Scheduler:0x000055ce141d4560 ...>, @original="* * * * *", @opts={:job=>true}, @handler=#<Proc:0x000055ce14837970@/app/app/models/check.rb:53>, @callable=#<Proc:0x000055ce14837970@/app/app/models/check.rb:53>, @scheduled_at=#<EtOrbi::EoTime:0x000055ce148378a8 @seconds=1590566233.5165186, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @unscheduled_at=nil, @last_time=#<EtOrbi::EoTime:0x000055ce13d18850 @seconds=1590570540.2808912, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @locals={}, @local_mutex=#<Thread::Mutex:0x000055ce14837790>, @id="cron_1590566233.5165186_47171797892220", @tags=[], @count=72, @last_work_time=0.1221168041229248, @mean_work_time=0.21060854527685377, @paused_at=nil, @times=nil, @first_at=nil, @last_at=nil, @cron_line=#<Fugit::Cron:0x000055ce14844350 @original="* * * * *", @cron_s=nil, @seconds=[0], @minutes=nil, @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil, @zone=nil, @timezone=nil>, @next_time=#<EtOrbi::EoTime:0x000055ce14747358 @seconds=1590570600.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @previous_time=#<EtOrbi::EoTime:0x000055ce12c63348 @seconds=1590570540.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>>, #<Rufus::Scheduler::CronJob:0x000055ce14850330 @scheduler=#<Rufus::Scheduler:0x000055ce141d4560 ...>, @original="* * * * *", @opts={:job=>true}, @handler=#<Proc:0x000055ce148503a8@/app/app/models/check.rb:53>, @callable=#<Proc:0x000055ce148503a8@/app/app/models/check.rb:53>, @scheduled_at=#<EtOrbi::EoTime:0x000055ce148502e0 @seconds=1590566233.521028, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @unscheduled_at=nil, @last_time=#<EtOrbi::EoTime:0x000055ce13d340c8 @seconds=1590570540.2813013, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @locals={}, @local_mutex=#<Thread::Mutex:0x000055ce14850268>, @id="cron_1590566233.521028_47171797942680", @tags=[], @count=72, @last_work_time=0.18425583839416504, @mean_work_time=0.18475720948643148, @paused_at=nil, @times=nil, @first_at=nil, @last_at=nil, @cron_line=#<Fugit::Cron:0x000055ce1486b478 @original="* * * * *", @cron_s=nil, @seconds=[0], @minutes=nil, @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil, @zone=nil, @timezone=nil>, @next_time=#<EtOrbi::EoTime:0x000055ce14863840 @seconds=1590570600.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @previous_time=#<EtOrbi::EoTime:0x000055ce12d0dd20 @seconds=1590570540.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>>, #<Rufus::Scheduler::CronJob:0x000055ce14877340 @scheduler=#<Rufus::Scheduler:0x000055ce141d4560 ...>, @original="* * * * *", @opts={:job=>true}, @handler=#<Proc:0x000055ce148773b8@/app/app/models/check.rb:53>, @callable=#<Proc:0x000055ce148773b8@/app/app/models/check.rb:53>, @scheduled_at=#<EtOrbi::EoTime:0x000055ce148772f0 @seconds=1590566233.525345, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @unscheduled_at=nil, @last_time=#<EtOrbi::EoTime:0x000055ce13d40fa8 @seconds=1590570540.2816942, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @locals={}, @local_mutex=#<Thread::Mutex:0x000055ce14877278>, @id="cron_1590566233.525345_47171798022560", @tags=[], @count=72, @last_work_time=0.16895341873168945, @mean_work_time=0.1577569444974263, @paused_at=nil, @times=nil, @first_at=nil, @last_at=nil, @cron_line=#<Fugit::Cron:0x000055ce14885e90 @original="* * * * *", @cron_s=nil, @seconds=[0], @minutes=nil, @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil, @zone=nil, @timezone=nil>, @next_time=#<EtOrbi::EoTime:0x000055ce1482dd30 @seconds=1590570600.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @previous_time=#<EtOrbi::EoTime:0x000055ce12177650 @seconds=1590570540.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>>, #<Rufus::Scheduler::CronJob:0x000055ce1488de88 @scheduler=#<Rufus::Scheduler:0x000055ce141d4560 ...>, @original="* * * * *", @opts={:job=>true}, @handler=#<Proc:0x000055ce1488df28@/app/app/models/check.rb:53>, @callable=#<Proc:0x000055ce1488df28@/app/app/models/check.rb:53>, @scheduled_at=#<EtOrbi::EoTime:0x000055ce1488dde8 @seconds=1590566233.5304112, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @unscheduled_at=nil, @last_time=#<EtOrbi::EoTime:0x000055ce13d58810 @seconds=1590570540.2821667, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @locals={}, @local_mutex=#<Thread::Mutex:0x000055ce1488dcf8>, @id="cron_1590566233.5304112_47171798069060", @tags=[], @count=72, @last_work_time=0.14934992790222168, @mean_work_time=0.2064667377207014, @paused_at=nil, @times=nil, @first_at=nil, @last_at=nil, @cron_line=#<Fugit::Cron:0x000055ce148ac180 @original="* * * * *", @cron_s=nil, @seconds=[0], @minutes=nil, @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil, @zone=nil, @timezone=nil>, @next_time=#<EtOrbi::EoTime:0x000055ce147d52e8 @seconds=1590570600.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @previous_time=#<EtOrbi::EoTime:0x000055ce16a5e940 @seconds=1590570540.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>>, #<Rufus::Scheduler::CronJob:0x000055ce148d3488 @scheduler=#<Rufus::Scheduler:0x000055ce141d4560 ...>, @original="* * * * *", @opts={:job=>true}, @handler=#<Proc:0x000055ce148d3500@/app/app/models/check.rb:53>, @callable=#<Proc:0x000055ce148d3500@/app/app/models/check.rb:53>, @scheduled_at=#<EtOrbi::EoTime:0x000055ce148d33e8 @seconds=1590566233.535351, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @unscheduled_at=nil, @last_time=#<EtOrbi::EoTime:0x000055ce13d806a8 @seconds=1590570540.2826202, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @locals={}, @local_mutex=#<Thread::Mutex:0x000055ce148d3348>, @id="cron_1590566233.535351_47171798211140", @tags=[], @count=72, @last_work_time=0.19681644439697266, @mean_work_time=0.19685286283493036, @paused_at=nil, @times=nil, @first_at=nil, @last_at=nil, @cron_line=#<Fugit::Cron:0x000055ce14922a10 @original="* * * * *", @cron_s=nil, @seconds=[0], @minutes=nil, @hours=nil, @monthdays=nil,@months=nil, @weekdays=nil, @zone=nil, @timezone=nil>, @next_time=#<EtOrbi::EoTime:0x000055ce1488d230 @seconds=1590570600.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @previous_time=#<EtOrbi::EoTime:0x000055ce1696c0a0 @seconds=1590570540.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>>, #<Rufus::Scheduler::CronJob:0x000055ce14941708 @scheduler=#<Rufus::Scheduler:0x000055ce141d4560 ...>, @original="* * * * *", @opts={:job=>true}, @handler=#<Proc:0x000055ce14941780@/app/app/models/check.rb:53>, @callable=#<Proc:0x000055ce14941780@/app/app/models/check.rb:53>, @scheduled_at=#<EtOrbi::EoTime:0x000055ce149416b8 @seconds=1590566233.5400794, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @unscheduled_at=nil, @last_time=#<EtOrbi::EoTime:0x000055ce13da3978 @seconds=1590570540.2832, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @locals={}, @local_mutex=#<Thread::Mutex:0x000055ce14941618>, @id="cron_1590566233.5400794_47171798436740", @tags=[], @count=72, @last_work_time=0.15997934341430664, @mean_work_time=0.19504914349979827, @paused_at=nil, @times=nil, @first_at=nil, @last_at=nil, @cron_line=#<Fugit::Cron:0x000055ce14950c58 @original="* * * * *", @cron_s=nil, @seconds=[0], @minutes=nil, @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil, @zone=nil, @timezone=nil>, @next_time=#<EtOrbi::EoTime:0x000055ce1481ab90 @seconds=1590570600.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @previous_time=#<EtOrbi::EoTime:0x000055ce16a75c30 @seconds=1590570540.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>>, #<Rufus::Scheduler::CronJob:0x000055ce149abec8 @scheduler=#<Rufus::Scheduler:0x000055ce141d4560 ...>, @original="* * * * *", @opts={:job=>true}, @handler=#<Proc:0x000055ce149aba68@/app/app/models/check.rb:53>, @callable=#<Proc:0x000055ce149aba68@/app/app/models/check.rb:53>, @scheduled_at=#<EtOrbi::EoTime:0x000055ce149bbf80 @seconds=1590566233.5449774, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @unscheduled_at=nil, @last_time=#<EtOrbi::EoTime:0x000055ce13da0e08 @seconds=1590570540.283694, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @locals={}, @local_mutex=#<Thread::Mutex:0x000055ce149bbeb8>, @id="cron_1590566233.5449774_47171798654820", @tags=[], @count=72, @last_work_time=0.15435528755187988, @mean_work_time=0.16118721167246503, @paused_at=nil, @times=nil, @first_at=nil, @last_at=nil, @cron_line=#<Fugit::Cron:0x000055ce149ef6f0 @original="* * * * *", @cron_s=nil, @seconds=[0], @minutes=nil, @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil, @zone=nil, @timezone=nil>, @next_time=#<EtOrbi::EoTime:0x000055ce147f1150 @seconds=1590570600.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @previous_time=#<EtOrbi::EoTime:0x000055ce16a44fe0 @seconds=1590570540.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>>, #<Rufus::Scheduler::CronJob:0x000055ce149f6ef0 @scheduler=#<Rufus::Scheduler:0x000055ce141d4560 ...>, @original="* * * * *", @opts={:job=>true}, @handler=#<Proc:0x000055ce149f6f68@/app/app/models/check.rb:53>, @callable=#<Proc:0x000055ce149f6f68@/app/app/models/check.rb:53>, @scheduled_at=#<EtOrbi::EoTime:0x000055ce149f6ea0 @seconds=1590566233.5492826, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @unscheduled_at=nil, @last_time=#<EtOrbi::EoTime:0x000055ce13dc5f00 @seconds=1590570540.2841837, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @locals={}, @local_mutex=#<Thread::Mutex:0x000055ce149f6e28>, @id="cron_1590566233.5492826_47171798808440", @tags=[], @count=72, @last_work_time=0.14121365547180176, @mean_work_time=0.1471932000584073, @paused_at=nil, @times=nil, @first_at=nil, @last_at=nil, @cron_line=#<Fugit::Cron:0x000055ce14a21740 @original="* * * * *", @cron_s=nil, @seconds=[0], @minutes=nil, @hours=nil, @monthdays=nil, @months=nil, @weekdays=nil, @zone=nil, @timezone=nil>, @next_time=#<EtOrbi::EoTime:0x000055ce147b1ac8 @seconds=1590570600.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @previous_time=#<EtOrbi::EoTime:0x000055ce1696f4a8 @seconds=1590570540.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>>, #<Rufus::Scheduler::CronJob:0x000055ce14a08998 ...>]>, @frequency=0.3, @mutexes={}, @work_queue=#<Thread::Queue:0x000055ce141d43d0>, @max_work_threads=28, @stderr=#<IO:<STDERR>>, @thread_key="rufus_scheduler_47171794543280", @scheduler_lock=#<Rufus::Scheduler::NullLock:0x000055ce141d4330>, @trigger_lock=#<Rufus::Scheduler::NullLock:0x000055ce141d4308>, @thread=#<Thread:0x000055ce141d4178@/usr/local/bundle/gems/rufus-scheduler-3.6.0/lib/rufus/scheduler.rb:545 sleep>>, @original="* * * * *", @opts={:job=>true}, @handler=#<Proc:0x000055ce14a08a60@/app/app/models/check.rb:53>, @callable=#<Proc:0x000055ce14a08a60@/app/app/models/check.rb:53>, @scheduled_at=#<EtOrbi::EoTime:0x000055ce14a08948 @seconds=1590566233.5540376, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @unscheduled_at=nil, @last_time=#<EtOrbi::EoTime:0x000055ce13dfc460 @seconds=1590570540.2851627, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @locals={}, @local_mutex=#<Thread::Mutex:0x000055ce14a088a8>, @id="cron_1590566233.5540376_47171798844620", @tags=[], @count=72, @last_work_time=0.006174802780151367, @mean_work_time=0.4366497187547283, @paused_at=nil, @times=nil, @first_at=nil, @last_at=nil, @cron_line=#<Fugit::Cron:0x000055ce14a73c20 @original="* * * * *", @cron_s=nil, @seconds=[0], @minutes=nil, @hours=nil, @monthdays=nil, @months=nil,@weekdays=nil, @zone=nil, @timezone=nil>, @next_time=#<EtOrbi::EoTime:0x000055ce13c2e110 @seconds=1590570600.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>, @previous_time=#<EtOrbi::EoTime:0x000055ce169a9388 @seconds=1590570540.0, @zone=#<TZInfo::DataTimezone: Etc/UTC>, @time=nil>>
ciao    | E, [2020-05-27T17:09:33.103706 #1] ERROR -- : err47171798803180 0: /usr/local/lib/ruby/2.6.0/net/protocol.rb:225:in `rbuf_fill'
ciao    | E, [2020-05-27T17:09:33.103858 #1] ERROR -- : err47171798803180 1: /usr/local/lib/ruby/2.6.0/net/protocol.rb:191:in `readuntil'
ciao    | E, [2020-05-27T17:09:33.103991 #1] ERROR -- : err47171798803180 2: /usr/local/lib/ruby/2.6.0/net/protocol.rb:201:in `readline'
ciao    | E, [2020-05-27T17:09:33.104267 #1] ERROR -- : err47171798803180 3: /usr/local/lib/ruby/2.6.0/net/smtp.rb:950:in `recv_response'
ciao    | E, [2020-05-27T17:09:33.104425 #1] ERROR -- : err47171798803180 4: /usr/local/lib/ruby/2.6.0/net/smtp.rb:553:in `block in do_start'
ciao    | E, [2020-05-27T17:09:33.104560 #1] ERROR -- : err47171798803180 5: /usr/local/lib/ruby/2.6.0/net/smtp.rb:960:in `critical'
ciao    | E, [2020-05-27T17:09:33.104697 #1] ERROR -- : err47171798803180 6: /usr/local/lib/ruby/2.6.0/net/smtp.rb:553:in `do_start'
ciao    | E, [2020-05-27T17:09:33.104829 #1] ERROR -- : err47171798803180 7: /usr/local/lib/ruby/2.6.0/net/smtp.rb:518:in `start'
ciao    | E, [2020-05-27T17:09:33.104963 #1] ERROR -- : err47171798803180 8: /usr/local/bundle/gems/mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb:109:in `start_smtp_session'
ciao    | E, [2020-05-27T17:09:33.105380 #1] ERROR -- : err47171798803180 9: /usr/local/bundle/gems/mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb:100:in `deliver!'
ciao    | E, [2020-05-27T17:09:33.105584 #1] ERROR -- : err47171798803180 10: /usr/local/bundle/gems/mail-2.7.1/lib/mail/message.rb:2159:in `do_delivery'
ciao    | E, [2020-05-27T17:09:33.105744 #1] ERROR -- : err47171798803180 11: /usr/local/bundle/gems/mail-2.7.1/lib/mail/message.rb:260:in `blockin deliver'
ciao    | E, [2020-05-27T17:09:33.105897 #1] ERROR -- : err47171798803180 12: /usr/local/bundle/gems/actionmailer-6.0.3.1/lib/action_mailer/base.rb:589:in `block in deliver_mail'
ciao    | E, [2020-05-27T17:09:33.106524 #1] ERROR -- : err47171798803180 13: /usr/local/bundle/gems/activesupport-6.0.3.1/lib/active_support/notifications.rb:180:in `block in instrument'
ciao    | E, [2020-05-27T17:09:33.106742 #1] ERROR -- : err47171798803180 14: /usr/local/bundle/gems/activesupport-6.0.3.1/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
ciao    | E, [2020-05-27T17:09:33.106894 #1] ERROR -- : err47171798803180 15: /usr/local/bundle/gems/activesupport-6.0.3.1/lib/active_support/notifications.rb:180:in `instrument'
ciao    | E, [2020-05-27T17:09:33.107367 #1] ERROR -- : err47171798803180 16: /usr/local/bundle/gems/actionmailer-6.0.3.1/lib/action_mailer/base.rb:587:in `deliver_mail'
ciao    | E, [2020-05-27T17:09:33.107569 #1] ERROR -- : err47171798803180 17: /usr/local/bundle/gems/mail-2.7.1/lib/mail/message.rb:260:in `deliver'
ciao    | E, [2020-05-27T17:09:33.107698 #1] ERROR -- : err47171798803180 18: /usr/local/lib/ruby/2.6.0/delegate.rb:83:in `method_missing'
ciao    | E, [2020-05-27T17:09:33.107808 #1] ERROR -- : err47171798803180 19: /app/app/lib/ciao/notifications/mail_notification.rb:7:in `notify'
ciao    | E, [2020-05-27T17:09:33.107911 #1] ERROR -- : err47171798803180 20: /app/app/models/check.rb:73:in `block (2 levels) in create_job'
ciao    | E, [2020-05-27T17:09:33.108256 #1] ERROR -- : err47171798803180 21: /app/app/models/check.rb:72:in `each'
ciao    | E, [2020-05-27T17:09:33.108413 #1] ERROR -- : err47171798803180 22: /app/app/models/check.rb:72:in `block in create_job'
ciao    | E, [2020-05-27T17:09:33.108521 #1] ERROR -- : err47171798803180 23: /usr/local/bundle/gems/rufus-scheduler-3.6.0/lib/rufus/scheduler/jobs.rb:223:in `do_call'
ciao    | E, [2020-05-27T17:09:33.108625 #1] ERROR -- : err47171798803180 24: /usr/local/bundle/gems/rufus-scheduler-3.6.0/lib/rufus/scheduler/jobs.rb:267:in `trigger_now'
ciao    | E, [2020-05-27T17:09:33.108727 #1] ERROR -- : err47171798803180 25: /usr/local/bundle/gems/rufus-scheduler-3.6.0/lib/rufus/scheduler/jobs.rb:312:in `block (3 levels) in start_work_thread'
ciao    | E, [2020-05-27T17:09:33.108828 #1] ERROR -- : err47171798803180 26: /usr/local/bundle/gems/rufus-scheduler-3.6.0/lib/rufus/scheduler/jobs.rb:315:in `block (2 levels) in start_work_thread'
ciao    | E, [2020-05-27T17:09:33.108931 #1] ERROR -- : err47171798803180 27: /usr/local/bundle/gems/rufus-scheduler-3.6.0/lib/rufus/scheduler/jobs.rb:301:in `loop'
ciao    | E, [2020-05-27T17:09:33.109259 #1] ERROR -- : err47171798803180 28: /usr/local/bundle/gems/rufus-scheduler-3.6.0/lib/rufus/scheduler/jobs.rb:301:in `block in start_work_thread'

Support for Basic Auth

Hi @brotandgames, I suggest to natively support Basic Auth using env vars. So for example, if BASIC_AUTH_USERNAME is defined then we enable basic auth authentication otherwise the application will be publicly available.

Something like:

class ApplicationController < ActionController::Base
  before_filter :authenticate
  protect_from_forgery unless: -> { request.format.json? }

  def authenticate
    basic_auth_username = ENV.fetch('BASIC_AUTH_USERNAME', '')
    basic_auth_password = ENV.fetch('BASIC_AUTH_PASSWORD', '')

    return true if basic_auth_username.empty?

    authenticate_or_request_with_http_basic('Ciao Application') do |username, password|
      username == basic_auth_username && password == basic_auth_password
    end
  end
end

Should be sufficient, simple and nice :) what do you think?

Feature Request - Dashboard for multiple environments

First of this is a really great tool. Thank you for creating it. I am using it for some time now and I have ~ 100 urls. We have 20 end points for 1 environment and total 5 environments. Is there any possibility of implementing a dashboard feature where we can have tabs for each environment?

SMTP over SSL is not working

I tried to run Ciao and integrate it with Sendgrid. It did work perfectly but I got Timeout errors when the ActiveMailer tried to communicate with Sendgrid SMTP server.

After some investigations, I found that I need to set ssl: true in action_mailer.smtp_settings to support SMTP over SSL which is required by Sendgrid and probably any other reliable and save SMTP server.

Relative Path

Is your feature request related to a problem? Please describe.
I am currently hosting Ciao at xxx.com/yyyy/ . The /checks (and other page links in the page) and links to css/js/woff/tiff seems not relative. Because even though I am able to make the page load at xxx.com/yyyy/ but the /checks and css/js/woff/tiff still refers to xxx.com/checks for example.

Describe the solution you'd like
Make the paths relative so that it can be hosted in domain subdir

Can it support monitoring of specified URLs through http or socks proxy?

Is your feature request related to a problem? Please describe.
Some of the URLs I want to monitor can only be accessed through a proxy

Describe the solution you'd like
such as an undisclosed company internal website

Describe alternatives you've considered
No alternatives found yet

Additional context
none

[helm] Liveness probe fails when basic auth is enabled

Describe the bug
k8s tries to reach pod via http get method and gets 401 unathorized, then pod is killed by k8s.

To Reproduce
enable basic auth variables in env

Expected behavior
pod is ready to serve

Additional context
what should u do: (there may be some mistakes in code below, it is untested)

  1. fix liveness probes in deployment
          livenessProbe:
            httpGet:
              path: /
              port: http
              {{- if .Values.basic_auth.enabled }}
              httpHeaders:
              - name: Authorization
                 value: Basic {{ BasicAuthSecret }}
              {{- end }}
          readinessProbe:
            httpGet:
              path: /
              port: http
              {{- if .Values.basic_auth.enabled }}
              httpHeaders:
              - name: Authorization
                 value: Basic {{ BasicAuthSecret }}
              {{- end }}

P.S. u should avoid using liveness and readiness together if they are exact copy of each other

  1. fix env variable in deployment
          env:
            {{- range $key, $value := .Values.env }}
            - name: "{{ $key }}"
              value: "{{ $value }}"
            {{- end }}
            {{- if .Values.basic_auth.enabled }}
            - name: BASIC_AUTH_USERNAME
              value: "{{ .Values.basic_auth.username }}"
            - name: BASIC_AUTH_PASSWORD
              value: "{{ .Values.basic_auth.password }}"
            {{- end }}
  1. create a helper template variable BasicAuthSecret using smth like
{{- define "BasicAuthSecret" }}
{{- (printf "%s:%s" .Values.basic_auth.username .Values.basic_auth.password) | b64enc }}
{{- end }}
  1. add auth block in values.yaml
basic_auth: 
  enabled: false
  # username: example
  # password: mysecreto
  1. Add in docs info about enabling basic auth (not putting them in env variable)

Rails Engine

Hi,

Very good work!

Would be sick if we could mount this as a rails engine as well.

Regards

Response time

Describe the solution you'd like
Display Response time by link checked. (Average 5min / 1h / 1d / 7d)

Describe alternatives you've considered
Only showed in prometheus metrics

Additional context
Add any other context or screenshots about the feature request here.

error converting YAML to JSON: yaml: line 12: did not find expected key

Hello im having trouble running the YAML file. Everytime i run the file, i get an error stating that it did not find expected key.

`apiVersion: v1

kind: Namespace
metadata:
name: monitoring

apiVersion: v1
kind: Secret
metadata:
name: ciao
namespace: monitoring
data:
BASIC_AUTH_USERNAME: YWRtaW4=
BASIC_AUTH_PASSWORD: cGFzc3dvcmQ=

apiVersion: apps/v1
kind: Deployment
metadata:
name: ciao
namespace: monitoring
spec:
replicas: 1
template:
metadata:
selector:
labels:
app: ciao
spec:
containers:
- image: brotandgames/ciao:latest
imagePullPolicy: IfNotPresent
name: ciao
volumeMounts: # Emit if you do not have persistent volumes
- mountPath: /app/db/sqlite/
name: persistent-volume
subPath: ciao
ports:
- containerPort: 3000
resources:
requests:
memory: 256Mi
cpu: 200m
limits:
memory: 512Mi
cpu: 400m
envFrom:
- secretRef:
name: ciao

apiVersion: v1
kind: Service
metadata:
name: ciao
namespace: monitoring
spec:
ports:
- port: 80
targetPort: 3000
protocol: TCP
type: NodePort
selector:
app: ciao`

URI.parse(@endpoint) gets error when using docker-compose

$ cat docker-compose.yml
version: "3"
services:
  ciao:
    image: brotandgames/ciao
    container_name: ciao
    ports:
      - '8090:3000'
    environment:
      - CIAO_WEBHOOK_ENDPOINT_1="https://hooks.slack.com/****/****"
      - CIAO_WEBHOOK_PAYLOAD_1='{"text":"[ciao] __name__ Status changed (__status_after__)"}'
    volumes:
      - /opt/ciao/data:/app/db/sqlite/

E, [2019-08-21T07:07:01.102033 #1] ERROR -- : err46945276638420 0: /usr/local/lib/ruby/2.6.0/uri/rfc3986_parser.rb:67:in split' E, [2019-08-21T07:07:01.102106 #1] ERROR -- : err46945276638420 1: /usr/local/lib/ruby/2.6.0/uri/rfc3986_parser.rb:73:in parse'
E, [2019-08-21T07:07:01.102158 #1] ERROR -- : err46945276638420 2: /usr/local/lib/ruby/2.6.0/uri/common.rb:234:in parse' E, [2019-08-21T07:07:01.102308 #1] ERROR -- : err46945276638420 3: /app/app/lib/ciao/notifications/webhook_notification.rb:7:in notify'
E, [2019-08-21T07:07:01.102395 #1] ERROR -- : err46945276638420 4: /app/app/models/check.rb:73:in block (2 levels) in create_job' E, [2019-08-21T07:07:01.102479 #1] ERROR -- : err46945276638420 5: /app/app/models/check.rb:72:in each'
E, [2019-08-21T07:07:01.102564 #1] ERROR -- : err46945276638420 6: /app/app/models/check.rb:72:in block in create_job' E, [2019-08-21T07:07:01.102650 #1] ERROR -- : err46945276638420 7: /usr/local/bundle/gems/rufus-scheduler-3.6.0/lib/rufus/scheduler/jobs.rb:223:in do_call'
E, [2019-08-21T07:07:01.102736 #1] ERROR -- : err46945276638420 8: /usr/local/bundle/gems/rufus-scheduler-3.6.0/lib/rufus/scheduler/jobs.rb:267:in trigger_now' E, [2019-08-21T07:07:01.102803 #1] ERROR -- : err46945276638420 9: /usr/local/bundle/gems/rufus-scheduler-3.6.0/lib/rufus/scheduler/jobs.rb:312:in block (3 levels) in start_work_thread'
E, [2019-08-21T07:07:01.102866 #1] ERROR -- : err46945276638420 10: /usr/local/bundle/gems/rufus-scheduler-3.6.0/lib/rufus/scheduler/jobs.rb:315:in block (2 levels) in start_work_thread' E, [2019-08-21T07:07:01.102922 #1] ERROR -- : err46945276638420 11: /usr/local/bundle/gems/rufus-scheduler-3.6.0/lib/rufus/scheduler/jobs.rb:301:in loop'
E, [2019-08-21T07:07:01.102979 #1] ERROR -- : err46945276638420 12: /usr/local/bundle/gems/rufus-scheduler-3.6.0/lib/rufus/scheduler/jobs.rb:301:in `block in start_work_thread'

The response is Bad operation

I had to remove the " and ' in the environment and it worked

    environment:
      - CIAO_WEBHOOK_ENDPOINT_1=https://hooks.slack.com/****/****
      - CIAO_WEBHOOK_PAYLOAD_1={"text":"[ciao] __name__ Status changed (__status_after__)"}

Should it support to remove "" or '' at @endpoint before sending to URI.parse

Add option to turn off endpoint SSL/TLS certificate verification

Thanks for making this available, it is a nice replacement for my homebrew Go-based pinger that I have been using.

I run some services that are for internal use and are either self-signed certified or signed by a local certificate authority and I would like to have the option to turn off certificate verification. Right now the endpoint check fails when it is unable to verify. It would be nice to have a checkbox that disables certificate verification per endpoint.

The error I encounter is as follows which causes the check to fail:
SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate)

remove quotes in placeholders

Hi, ^_^
I'm using docker-compose, and here is my yml file

version: "3"
services:
  ciao:
    image: brotandgames/ciao
    container_name: ciao
    ports:
      - '8300:3000'
    environment:
      [...]
      - CIAO_WEBHOOK_PAYLOAD_MONITOR={ "status_before":"__status_before__", "status_after":"__status_after__"}
      - CIAO_WEBHOOK_ENDPOINT_MONITOR=http://host.com/xxx

my webhook will parse request payload to json object, but [status_before] and [status_after] will contains quotes when my web-proxy is shutting down , for example: "Failed to open TCP connection to 200.1.3.19:8200 (Connection refused - connect(2) for "200.1.3.19" port 8200)", and this causes parsing failed.

Add a metric with service level and it's response

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

We plan to use ciao in our project and its metrics in prometheus, to create alerts. There is a number of unhealthy services in metrics, but it's impossible to understand which service is faulty.

Describe the solution you'd like
A clear and concise description of what you want to happen.

Add a metric which would return the status code per each service, like this:

ciao_checks_statuses{label="service1"} 200
ciao_checks_statuses{label="service2"} 503

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

I don't know about such ones

Additional context
Add any other context or screenshots about the feature request here.

As this is my feature request I can implement it myself (I have relevant RoR experience), this issue is mostly for the discussion.

Quick Docker deploy error

I try to deploy ciao 1.6.2 in Docker 18.06.0-ce but i receive the error:

"You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: https://www.ruby-lang.org/bugreport.html
Aborted (core dumped)"

Steps to reproduce the behavior:

  1. Execute docker run --name ciao -p 8090:3000 brotandgames/ciao
  2. See error
  • OS: CentOS Linux release 7.5.1804 (Core)
  • Docker: 18.06.0-ce

After see the error in version 1.6.2 then i try to run the ciao 1.5.0 and works normally.

Access via SSL HTTPS

Is your feature request related to a problem? Please describe.
I can only access Ciao via HTTP.

Describe the solution you'd like
I can access Ciao via HTTPS and give it a certificate to use.

Describe alternatives you've considered
A reverse proxy maybe, but that seems excessive.

webhook is no work

Describe the bug
webhook is no work

To Reproduce
my docker-compose file
version: "3"
services:
ciao:
image: brotandgames/ciao
container_name: status_ciao
ports:
- '8090:3000'
environment:
- SECRET_KEY_BASE=seth
- TIME_ZONE=PRC
- BASIC_AUTH_USERNAME=xxxx
- BASIC_AUTH_PASSWORD=xxxxx
- CIAO_WEBHOOK_ENDPOINT_1=http://172.27.0.13:9000/wecomchan
- CIAO_WEBHOOK_PAYLOAD_1={"sendkey":"5660bcd256ba0012c41d3d6f22c17472","msg_type":"text","msg":"name{check_url} Status changed from (status_before) to (status_after)"}
- CIAO_LOG_LEVEL=DEBUG
volumes:
- ./data:/app/db/sqlite/


after do no work, fail site status, no WEBHOOK request send

Timezone

How we configure the timezone ?

I try to map with a volume "/etc/localtime" but is not working.

socks5 proxy

Describe the solution you'd like
Please add ability to send outcoming requests via [socks5] proxy

my workaround was to modify start.sh to run proxychains-ng, and it works fine

SMTP_ENABLE_STARTTLS_AUTO should be a boolean

Hi! I'm trying to setup ciao on a homelab kubernetes cluster - where I already have an in-house open mail relay that's just doing doing raw port 25, no-ssl (and in turn relays to an actual authenticated provider).

As far as I'm aware, the Action Mailer 'enable_starttls_auto' should be a boolean value - the docs indicate 'auto' which I don't think is valid (and thereby it just defaults to true in action_mailer). Setting it to false in the environment values (or helm values) just has it end up as a "false" string in the actual rails configuration.

I'm guessing it needs the same ActiveModel::Type::Boolean.new.cast casting that ENV['SMTP_SSL'] received.

I can submit a PR - but haven't set up a ciao development environment - and figured this might just be easier as a quick issue report.

Timeout setting for checking

i'm often recived message from ciao like below while the service is not broken
`domain checker, [07.05.20 08:46]
[test.domain.com] Status changed from (200) to (execution expired)}

domain checker, [07.05.20 08:46]
[test.domain.com] Status changed from (execution expired) to (200)}`

I assume that this is due to the remoteness of the web server from the ciao service

I would like to set the connection timeout setting

In last 1 day i recived 500+ messages from 4 services in monitoring. They were all false positives

Add an option to mark redirects as healthy

For a lot of the services I run they redirect you to a login page or a dashboard if you're logged in etc, a feature to set redirects as a "healthy" option, hopefully per-check so that they don't appear as unhealthy in the overview would be greatly appreciated; if not just for reducing the heart attacks I have.

1564869749

Loving the project, it's entirely possible I'm missing a config option or something though.

Disable certificate verification

I want to monitor things on my home network and some devices use self-signed certificates.

It would be nice to be able to disable certificate validation per check.

[helm] Fix liveness and readiness probes

Describe the bug
U shoud add some variables to values.yaml, so we can manage liveness adnd readiness probes:

  1. deployment.yaml
          livenessProbe:
            httpGet:
              path: /
              port: http
          initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
          timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
          periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
          failureThreshold: {{ .Values.livenessProbe.failureThreshold }}
          successThreshold: {{ .Values..livenessProbe.successThreshold }}

... repeat for readiness ...
  1. set defaults in values.yaml
livenessProbe:
  initialDelaySeconds: 60
  periodSeconds: 10
  successThreshold: 1
  failureThreshold: 4
  timeoutSeconds: 10
... repeat for readiness ...

Gotify Notification not sending.

When i try to add gotify as a webhook it doesn't send any messages and I don't see any info about in the logs

here are env settings I used:
CIAO_WEBHOOK_ENDPOINT_GOTIFY=http://gotify.me/message
CIAO_WEBHOOK_PAYLOAD_GOTIFY='{"Content Type":"application/json", "message": "[ciao] name: Status changed (status_after)", "priority": 2, "title": "Service Check", "token": "token" }'

I'm running docker, not docker compose.

Openshift Yaml

Yaml file for Openshift
It is a yaml file for RedHat Openshift which you can add to your repository to be used.


apiVersion: v1
items:
- apiVersion: v1
  kind: Service
  metadata:
    annotations:
      openshift.io/generated-by: OpenShiftWebConsole
    creationTimestamp: null
    labels:
      app: ciao
    name: ciao
  spec:
    ports:
    - name: 3000-tcp
      port: 3000
      protocol: TCP
      targetPort: 3000
    selector:
      deploymentconfig: ciao
    sessionAffinity: None
    type: ClusterIP
  status:
    loadBalancer: {}
- apiVersion: apps.openshift.io/v1
  kind: DeploymentConfig
  metadata:
    annotations:
      openshift.io/generated-by: OpenShiftWebConsole
    creationTimestamp: null
    generation: 10
    labels:
      app: ciao
    name: ciao
  spec:
    replicas: 1
    selector:
      app: ciao
      deploymentconfig: ciao
    strategy:
      activeDeadlineSeconds: 21600
      resources: {}
      rollingParams:
        intervalSeconds: 1
        maxSurge: 25%
        maxUnavailable: 25%
        timeoutSeconds: 600
        updatePeriodSeconds: 1
      type: Rolling
    template:
      metadata:
        annotations:
          openshift.io/generated-by: OpenShiftWebConsole
        creationTimestamp: null
        labels:
          app: ciao
          deploymentconfig: ciao
      spec:
        containers:
        - env:
          - name: PORT
            value: "3000"
          - name: SMTP_ADDRES
            value: smtp.blabla.com
          - name: SMTP_EMAIL_FROM
            value: [email protected]
          - name: SMTP_EMAIL_TO
            value: [email protected]
          - name: CIAO_WEBHOOK_ENDPOINT_OFFICE_365
            value: https://outlook.office.com/webhook/changehere
          - name: CIAO_WEBHOOK_PAYLOAD_OFFICE_365
            value: 'payload'
          image: brotandgames/ciao
          imagePullPolicy: Always
          name: ciao
          ports:
          - containerPort: 3000
            protocol: TCP
          resources: {}
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          volumeMounts:
          - mountPath: /app/db/sqlite
            name: ciao-1
        dnsPolicy: ClusterFirst
        restartPolicy: Always
        schedulerName: default-scheduler
        securityContext: {}
        terminationGracePeriodSeconds: 30
        volumes:
        - name: ciao-1
          persistentVolumeClaim:
            claimName: ciao
    test: false
    triggers:
    - type: ConfigChange
    - imageChangeParams:
        automatic: true
        containerNames:
        - ciao
        from:
          kind: ImageStreamTag
          name: ciao:latest
          namespace: CURRENT_NAMESPACE
        lastTriggeredImage: brotandgames/ciao
      type: ImageChange
  status:
    availableReplicas: 0
    latestVersion: 0
    observedGeneration: 0
    replicas: 0
    unavailableReplicas: 0
    updatedReplicas: 0
- apiVersion: image.openshift.io/v1
  kind: ImageStream
  metadata:
    annotations:
      openshift.io/image.dockerRepositoryCheck: 2019-09-05T14:51:40Z
    creationTimestamp: null
    generation: 2
    labels:
      app: ciao
    name: ciao
  spec:
    lookupPolicy:
      local: false
    tags:
    - annotations:
        openshift.io/generated-by: OpenShiftWebConsole
        openshift.io/imported-from: brotandgames/ciao
      from:
        kind: DockerImage
        name: docker-registry.default.svc:5000/CURRENT_NAMESPACE/ciao:latest
      generation: 2
      importPolicy: {}
      name: latest
      referencePolicy:
        type: Source
  status:
    dockerImageRepository: ""

Persistent Storage Setup with Docker

Currently the Database is stored withing the Container itself which means you loose all Data if your Container dies and the Orchestrator creates a new one.
This also prevents all Users from updating without loosing all Data.

Please move the Production SQLite into a Volume or provide an easy way to use MySQL/PostgreSQL

ciao-scheduler still checks the deleted job

Describe the bug
ciao-scheduler still checks status of destroyed job
To Reproduce
Steps to reproduce the behavior:

1. Create job to listen to a fake website https://www.brotandgames.com/ciaos/, ciao sent notification of status change to '404'

I, [2019-08-30T17:48:42.059041 #1] INFO -- : [aa51d8d0-17e6-489c-afe4-bfd555d37a7b] ciao-scheduler Created job 'cron_1567187322.0564888_47382620780640' D, [2019-08-30T17:48:42.060153 #1] DEBUG -- : [aa51d8d0-17e6-489c-afe4-bfd555d37a7b] Check Update (0.2ms) UPDATE "checks" SET "job" = ?, "next_contact_at" = ? WHERE "checks"."id" = ? [["job", "cron_1567187322.0564888_47382620780640"], ["next_contact_at", "2019-08-30 17:49:00"], ["id", 1]] D, [2019-08-30T17:48:42.074029 #1] DEBUG -- : [aa51d8d0-17e6-489c-afe4-bfd555d37a7b] (13.7ms) commit transaction I, [2019-08-30T17:48:42.074750 #1] INFO -- : [aa51d8d0-17e6-489c-afe4-bfd555d37a7b] Redirected to http://localhost:8090/checks/1 I, [2019-08-30T17:48:42.074931 #1] INFO -- : [aa51d8d0-17e6-489c-afe4-bfd555d37a7b] Completed 302 Found in 26ms (ActiveRecord: 15.0ms | Allocations: 3810) I, [2019-08-30T17:48:42.078510 #1] INFO -- : [1ebd7531-2894-4b19-8228-f5e4dd0e4ed4] Started GET "/checks/1" for 172.19.0.1 at 2019-08-30 17:48:42 +0000 I, [2019-08-30T17:48:42.079181 #1] INFO -- : [1ebd7531-2894-4b19-8228-f5e4dd0e4ed4] Processing by ChecksController#show as HTML I, [2019-08-30T17:48:42.079248 #1] INFO -- : [1ebd7531-2894-4b19-8228-f5e4dd0e4ed4] Parameters: {"id"=>"1"} D, [2019-08-30T17:48:42.080663 #1] DEBUG -- : [1ebd7531-2894-4b19-8228-f5e4dd0e4ed4] Check Load (0.2ms) SELECT "checks".* FROM "checks" WHERE "checks"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] I, [2019-08-30T17:48:42.081500 #1] INFO -- : [1ebd7531-2894-4b19-8228-f5e4dd0e4ed4] Rendering checks/show.html.erb within layouts/application I, [2019-08-30T17:48:42.083150 #1] INFO -- : [1ebd7531-2894-4b19-8228-f5e4dd0e4ed4] Rendered checks/show.html.erb within layouts/application (Duration: 1.6ms | Allocations: 737) I, [2019-08-30T17:48:42.083956 #1] INFO -- : [1ebd7531-2894-4b19-8228-f5e4dd0e4ed4] Completed 200 OK in 5ms (Views: 2.6ms | ActiveRecord: 0.2ms | Allocations: 2035) I, [2019-08-30T17:48:43.790431 #1] INFO -- : [4621b832-7e9b-40c8-a708-4a7f95f22bdf] Started GET "/checks" for 172.19.0.1 at 2019-08-30 17:48:43 +0000 I, [2019-08-30T17:48:43.793506 #1] INFO -- : [4621b832-7e9b-40c8-a708-4a7f95f22bdf] Processing by ChecksController#index as HTML I, [2019-08-30T17:48:43.800384 #1] INFO -- : [4621b832-7e9b-40c8-a708-4a7f95f22bdf] Rendering checks/index.html.erb within layouts/application D, [2019-08-30T17:48:43.811135 #1] DEBUG -- : [4621b832-7e9b-40c8-a708-4a7f95f22bdf] Check Load (1.1ms) SELECT "checks".* FROM "checks" I, [2019-08-30T17:48:43.815240 #1] INFO -- : [4621b832-7e9b-40c8-a708-4a7f95f22bdf] Rendered checks/index.html.erb within layouts/application (Duration: 14.5ms | Allocations: 1078) I, [2019-08-30T17:48:43.820324 #1] INFO -- : [4621b832-7e9b-40c8-a708-4a7f95f22bdf] Completed 200 OK in 25ms (Views: 19.1ms | ActiveRecord: 1.1ms | Allocations: 2049) I, [2019-08-30T17:49:06.002335 #1] INFO -- : ciao-scheduler Checked 'https://www.brotandgames.com/ciaos/' at '2019-08-31 00:49:06 +0700' and got '404' D, [2019-08-30T17:49:06.021063 #1] DEBUG -- : Check Update (17.1ms) UPDATE "checks" SET "status" = ?, "last_contact_at" = ?, "next_contact_at" = ? WHERE "checks"."id" = ? [["status", "404"], ["last_contact_at", "2019-08-30 17:49:06.002080"], ["next_contact_at", "2019-08-30 17:50:00"], ["id", 1]] I, [2019-08-30T17:49:06.021264 #1] INFO -- : ciao-scheduler Check 'ciao': Status changed from '' to '404'

Selection_003

2. Delete the job

I, [2019-08-30T17:49:26.031284 #1] INFO -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] Started DELETE "/checks/1" for 172.19.0.1 at 2019-08-30 17:49:26 +0000 I, [2019-08-30T17:49:26.034254 #1] INFO -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] Processing by ChecksController#destroy as HTML I, [2019-08-30T17:49:26.034523 #1] INFO -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] Parameters: {"authenticity_token"=>"sdQSsoIKtOud7EGrr4r8CrikbGyqflEb5pEJQajIcKQydTpTFouvG0JUtzTHK1m8/zwK+WElOAiZjFbmz4jZ8A==", "id"=>"1"} D, [2019-08-30T17:49:26.039458 #1] DEBUG -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] Check Load (0.6ms) SELECT "checks".* FROM "checks" WHERE "checks"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] D, [2019-08-30T17:49:26.042323 #1] DEBUG -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] (0.2ms) begin transaction D, [2019-08-30T17:49:26.043908 #1] DEBUG -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] Check Destroy (0.8ms) DELETE FROM "checks" WHERE "checks"."id" = ? [["id", 1]] D, [2019-08-30T17:49:26.063461 #1] DEBUG -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] (18.2ms) commit transaction I, [2019-08-30T17:49:26.065355 #1] INFO -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] Redirected to http://localhost:8090/checks I, [2019-08-30T17:49:26.065914 #1] INFO -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] Completed 302 Found in 31ms (ActiveRecord: 19.9ms | Allocations: 741) I, [2019-08-30T17:49:26.080387 #1] INFO -- : [0d69b06d-9aa5-4373-bc56-da166a5df0d2] Started GET "/checks" for 172.19.0.1 at 2019-08-30 17:49:26 +0000 I, [2019-08-30T17:49:26.083450 #1] INFO -- : [0d69b06d-9aa5-4373-bc56-da166a5df0d2] Processing by ChecksController#index as HTML I, [2019-08-30T17:49:26.088332 #1] INFO -- : [0d69b06d-9aa5-4373-bc56-da166a5df0d2] Rendering checks/index.html.erb within layouts/application D, [2019-08-30T17:49:26.091333 #1] DEBUG -- : [0d69b06d-9aa5-4373-bc56-da166a5df0d2] Check Load (0.5ms) SELECT "checks".* FROM "checks" I, [2019-08-30T17:49:26.091917 #1] INFO -- : [0d69b06d-9aa5-4373-bc56-da166a5df0d2] Rendered checks/index.html.erb within layouts/application (Duration: 3.2ms | Allocations: 191) I, [2019-08-30T17:49:26.093838 #1] INFO -- : [0d69b06d-9aa5-4373-bc56-da166a5df0d2] Completed 200 OK in 10ms (Views: 6.3ms | ActiveRecord: 0.5ms | Allocations: 1023)

3. Check logs and see that job was being checked

I, [2019-08-30T17:49:26.031284 #1] INFO -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] Started DELETE "/checks/1" for 172.19.0.1 at 2019-08-30 17:49:26 +0000 I, [2019-08-30T17:49:26.034254 #1] INFO -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] Processing by ChecksController#destroy as HTML I, [2019-08-30T17:49:26.034523 #1] INFO -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] Parameters: {"authenticity_token"=>"sdQSsoIKtOud7EGrr4r8CrikbGyqflEb5pEJQajIcKQydTpTFouvG0JUtzTHK1m8/zwK+WElOAiZjFbmz4jZ8A==", "id"=>"1"} D, [2019-08-30T17:49:26.039458 #1] DEBUG -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] Check Load (0.6ms) SELECT "checks".* FROM "checks" WHERE "checks"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] D, [2019-08-30T17:49:26.042323 #1] DEBUG -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] (0.2ms) begin transaction D, [2019-08-30T17:49:26.043908 #1] DEBUG -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] Check Destroy (0.8ms) DELETE FROM "checks" WHERE "checks"."id" = ? [["id", 1]] D, [2019-08-30T17:49:26.063461 #1] DEBUG -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] (18.2ms) commit transaction I, [2019-08-30T17:49:26.065355 #1] INFO -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] Redirected to http://localhost:8090/checks I, [2019-08-30T17:49:26.065914 #1] INFO -- : [af213b8c-6cc6-40c3-8fe6-da53e2d22185] Completed 302 Found in 31ms (ActiveRecord: 19.9ms | Allocations: 741) I, [2019-08-30T17:49:26.080387 #1] INFO -- : [0d69b06d-9aa5-4373-bc56-da166a5df0d2] Started GET "/checks" for 172.19.0.1 at 2019-08-30 17:49:26 +0000 I, [2019-08-30T17:49:26.083450 #1] INFO -- : [0d69b06d-9aa5-4373-bc56-da166a5df0d2] Processing by ChecksController#index as HTML I, [2019-08-30T17:49:26.088332 #1] INFO -- : [0d69b06d-9aa5-4373-bc56-da166a5df0d2] Rendering checks/index.html.erb within layouts/application D, [2019-08-30T17:49:26.091333 #1] DEBUG -- : [0d69b06d-9aa5-4373-bc56-da166a5df0d2] Check Load (0.5ms) SELECT "checks".* FROM "checks" I, [2019-08-30T17:49:26.091917 #1] INFO -- : [0d69b06d-9aa5-4373-bc56-da166a5df0d2] Rendered checks/index.html.erb within layouts/application (Duration: 3.2ms | Allocations: 191) I, [2019-08-30T17:49:26.093838 #1] INFO -- : [0d69b06d-9aa5-4373-bc56-da166a5df0d2] Completed 200 OK in 10ms (Views: 6.3ms | ActiveRecord: 0.5ms | Allocations: 1023) **I, [2019-08-30T17:50:01.367594 #1] INFO -- : ciao-scheduler Checked 'https://www.brotandgames.com/ciaos/' at '2019-08-31 00:50:01 +0700' and got '404' D, [2019-08-30T17:50:01.368662 #1] DEBUG -- : Check Update (0.2ms) UPDATE "checks" SET "status" = ?, "last_contact_at" = ?, "next_contact_at" = ? WHERE "checks"."id" = ? [["status", "404"], ["last_contact_at", "2019-08-30 17:50:01.367424"], ["next_contact_at", "2019-08-30 17:51:00"], ["id", 1]] I, [2019-08-30T17:51:07.340141 #1] INFO -- : ciao-scheduler Checked 'https://www.brotandgames.com/ciaos/' at '2019-08-31 00:51:07 +0700' and got '404' D, [2019-08-30T17:51:07.342188 #1] DEBUG -- : Check Update (0.4ms) UPDATE "checks" SET "status" = ?, "last_contact_at" = ?, "next_contact_at" = ? WHERE "checks"."id" = ? [["status", "404"], ["last_contact_at", "2019-08-30 17:51:07.339910"], ["next_contact_at", "2019-08-30 17:52:00"], ["id", 1]]**

Expected behavior
Job should be deleted completely from cron-job

Add documentation for the cron format

Nice project, thanks!

The fugit library supports cron with seconds precision - and I think it would be useful if Ciao officially supported it.

Format: */15 * * * * *

Minimal demo, similar to the way it's used by ciao here

require 'fugit'

value = "*/15 * * * * *"
c = Fugit::Cron.do_parse(value)
puts "Next time"
puts c.next_time      # => 2019-08-01 01:11:00 +0000

puts "Previous time"
puts c.previous_time  # => 2019-08-01 01:10:45 +0000

Verify content of response body

When server responded with 200, it will help to verify the content that is served, such as a text within the HTML or JSON.

This is quite common in most website uptime checks.

Thanks for sharing such project.

Feature Request ICMP (Ping) to IP or hostname.

Is your feature request related to a problem? Please describe.
Right now this is only able to monitor HTTP status, I have plenty of services I would like to monitor that do not have HTTP pages.

Describe the solution you'd like
Would like the ability to monitor just if a host is alive with ICMP ping commands, either up if it returns a reponse (perhaps also documenting latency) or down/failed check.

Describe alternatives you've considered
I have tried various other selfhosted options like StatPing (buggy and unstable) and Cachet (confusing and frustrating to configure this type of check), and keep coming back to Ciao, but it doesn't support this feature at all.

Additional context
I do understand in #37 that it was noted to be outside the scope of this project, just checking back in to see if this might be re-considered at any point.

Thank you for your time.

Ciao::Notifications::WebhookNotification#notify Could not notify webhook(https://hooks.slack.com/****/****) - Failed to open TCP connection to hooks.slack.com:443 (getaddrinfo: Try again)

I, [2019-08-21T09:07:05.188353 #1]  INFO -- : ciao-scheduler Check 'https://web-test.com/': Status changed from '302' to 'Failed to open TCP connection to web-test.com:443 (getaddrinfo: Try again)'
E, [2019-08-21T09:07:10.196003 #1] ERROR -- : Ciao::Notifications::WebhookNotification#notify Could not notify webhook(https://hooks.slack.com/****/****) - Failed to open TCP connection to hooks.slack.com:443 (getaddrinfo: Try again)

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.