11 KiB
Getting Started
Requirement
- Node 18
Clone the repository
git clone https://github.com/rajnandan1/kener.git
Install Dependencies
npm install
Configs
- Rename
config/site.example.yaml->config/site.yaml - Rename
config/monitors.example.yaml->config/monitors.yaml
Start Kener Dev
npm run kener:dev
Kener would be running at PORT 3000. Go to http://localhost:3000
Folder structure
├── src (svelte frontend files)
├── static (things put here can be referenced directly example static/logo.png -> /logo.png)
├── scripts (nodejs server files)
├── config
│ ├── site.yaml (to personalize your kener instance)
│ ├── monitors.yaml (to add monitors)
Production Deployment
Once you have added the config/site.yaml or config/monitors.yaml or changed anything in src/
npm i
npm run kener
Changing files inside src/
npm i
npm run kener:build
npm run kener
Custom Deployment
Kener should be run using prod.js script. It needs minimum two environment variables
PUBLIC_KENER_FOLDER=./build/client/kenertz=UTC
We recommend not to change these variables
It also needs to yaml files to work
- site.yaml
- monitors.yaml
By default these are present in config/. However you can use different location either passing them as argument or having the path as enviorment variable
Add as Enviroment variables
export MONITOR_YAML_PATH=/your/path/monitors.yaml
export SITE_YAML_PATH=/your/path/site.yaml
Add as argument to prod.js
node prod.js --monitors /your/path/monitors.yaml --site /your/path/site.yaml
export PUBLIC_KENER_FOLDER=./build/client/kener
export tz=UTC
npm i
npm run build
node prod.js
Github Setup
- Create a Github Repositiory
- Go to Personal Access Token
- Create a Fine-grained token
- If your repository is private then give Read-Write access to issues
- Add the access token as an environment variable
export GH_TOKEN=github_pat_11AD3ZA3Y0
Modify Site
There is a folder called /config. Inside which there is a site.yaml file. You can modify this file to have your own branding.
title: "Kener"
siteURL: "https://kener.netlify.app"
home: "/"
logo: "/logo.svg"
github:
owner: "rajnandan1"
repo: "kener"
visible: true
metaTags:
description: "Your description"
keywords: "keyword1, keyword2"
nav:
- name: "Documentation"
url: "/docs"
hero:
title: Kener is a Open-Source Status Page System
subtitle: Let your users know what's going on.
title
This translates to
<title>Your Title</title>
theme
It can be set by modifying the <html> class in src/app.html file
Dark Theme
<!DOCTYPE html>
<html lang="en" class="dark dark:bg-background">
Light theme
<!DOCTYPE html>
<html lang="en" >
Can be light or dark. Defaults to light
siteURL
Root URL where you are hosting kenner
...
siteURL: https://status.example.com
...
home
Location when someone clicks on the your brand in the top nav bar
...
home: "https://www.example.com
...
logo
URL of the logo that will be shown in the nav bar. You can also add your logo in the static folder
...
logo: "https://www.example.com/logo.png
...
favicon
It can be set by modifying the <head> tag in src/app.html file.
Example add a png called logo.png file in static/ and then
...
<link rel="icon" href="/logo.png" />
...
github
For incident kener uses github comments. Create an empty github repo and add them to site.yaml
github:
owner: "username"
repo: "your-reponame"
refer: true
metaTags
Meta tags are nothing but html <meta>. You can use them for SEO purposes
metaTags:
description: "Your description"
keywords: "keyword1, keyword2"
og:image: "https://example.com/og.png"
will become
<head>
<meta name="description" content="Your description">
<meta name="keywords" content="keyword1, keyword2">
<meta name="og:image" content="https://example.com/og.png">
</head>
hero
Use hero to add a banner to your kener page
hero:
title: Kener is a Open-Source Status Page System
subtitle: Let your users know what's going on.
nav
You can add more links to your navbar.
nav:
- name: "Home"
url: "/home"
Add Monitors
Inside config/ folder there is a file called monitors.yaml. We will be adding our monitors here. Please note that your yaml must be valid. It is an array.
Sample
- name: Google Search
description: Search the world's information, including webpages, images, videos and more.
tag: "google-search"
image: "/google.png"
cron: "* * * * *"
method: POST
url: https://www.google.com/webhp
headers:
Content-Type: application/json
body: '{"order_amount":1,"order_currency":"INR"}'
eval: |
(function(statusCode, responseTime, responseDataBase64){
const resp = JSON.parse(atob(responseDataBase64));
return {
status: statusCode == 200 ? 'UP':'DOWN',
latency: responseTime,
}
})
| Parameter Name | Usage | Description |
|---|---|---|
| name | Required + Unique | This will be shown in the UI to your users. Keep it short and unique |
| description | Optional | This will be show below your name |
| tag | Required + Unique | This is used to tag incidents created in Github using comments |
| image | Optional | To show a logo before the name |
| cron | Optional | Use cron expression to specify the interval to run the monitors. Defaults to * * * * * i.e every minute |
| timeout | Optional | Timeout in milliseconds to cancel HTTP call. Default is 5000 |
| method | Optional | HTTP Method |
| url | Optional | HTTP URL |
| headers | Optional | HTTP headers |
| body | Optional | HTTP Body as string |
| eval | Optional | Evaluator written in JS, to parse HTTP response and calculate uptime and latency |
cron
Kener fills data every minute in UTC so if you give an expression that is not per minute, kener will backfill data using the latest status.
Example for cron: "*/15 * * * *"
- First run at "2023-12-02T18:00:00.000Z" - Status DOWN
- Second run at "2023-12-02T18:15:00.000Z" - Status UP
Kener will fill data from 18:01:00 to 18:14:00 as UP
eval
This is a anonymous JS function, by default it looks like this.
NOTE: The eval function should always return a json object. The json object can have only status(UP/DOWN/DEGRADED) and lantecy(number)
{status:"DEGRADED", latency: 200}.
(function (statusCode, responseTime, responseDataBase64) {
let statusCodeShort = Math.floor(statusCode/100);
let status = 'DOWN'
if(statusCodeShort >=2 && statusCodeShort <= 3) {
status = 'UP',
}
return {
status: 'DOWN',
latency: responseTime,
}
})
statusCodeREQUIRED is a number. It is the HTTP status coderesponseTimeREQUIREDis a number. It is the latency in millisecondsresponseDataBase64REQUIRED is a string. It is the base64 encoded response data. To use it you will have to decode it
let decodedResp = atob(responseDataBase64);
//let jsonResp = JSON.parse(decodedResp)
Monitor Examples
Here are some exhaustive examples for monitors
A Simple GET Monitor
- name: Google Search
tag: "google-search"
method: GET
url: https://www.google.com/webhp
A GET Monitor with image
google.png is in the static folder
- name: Google Search
tag: "google-search"
method: GET
image: "/google.png"
url: https://www.google.com/webhp
Get Monitor 15 Minute
- name: Google Search
description: Search the world's information, including webpages, images, videos and more.
tag: "google-search"
cron: "*/15 * * * *"
method: GET
url: https://www.google.com/webhp
Post Monitor With Body
- name: Google Search
description: Google Search
tag: "google-search-post"
method: POST
url: https://www.google.com/webhp
headers:
Content-Type: application/json
body: '{"order_amount":22222.1,"order_currency":"INR"}'
Secrets in Header
You can set ENV variables in your machine and use them in your monitors. Example below has GH_TOKEN as an environment variable. It uses process.env.GH_TOKEN.
export GH_TOKEN=some.token.for.github
NOTE: DO NOT forget the
$sign in your monitor
- name: Github Issues
description: Github Issues Fetch
tag: "gh-search-issue"
method: GET
url: https://api.github.com/repos/rajnandan1/kener/issues
headers:
Authorization: Bearer $GH_TOKEN
Secrets in Body
Assuming ORDER_ID is present in env
- name: Github Issues
description: Github Issues Fetch
tag: "gh-search-issue"
method: POST
url: https://api.github.com/repos/rajnandan1/kener/issues
headers:
Content-Type: application/json
body: '{"order_amount":22222.1,"order_currency":"INR", "order_id": "$ORDER_ID"}'
Eval Body
- name: Github Issues
description: Github Issues Fetch
tag: "gh-search-issue"
method: GET
url: https://api.github.com/repos/rajnandan1/kener/issues
eval: |
(function(statusCode, responseTime, responseDataBase64){
const resp = JSON.parse(atob(responseDataBase64));
let status = 'DOWN'
if(statusCode == 200) status = 'UP';
if(resp.length == 0) status = 'DOWN';
if(statusCode == 200 && responseTime > 2000) status = 'DEGRADED';
return {
status: status,
latency: responseTime,
}
})
Incident Management
Kener uses Github to power incident management. We encourage you to create public repositores so that others can subscribe to updates to issues
How to create
Create an issue with two labels your-monitor-tag and status

- Open issues are considered as live incidents.
- Add comments and it will show up in kener.
API
Kener also gives APIs to push data and create incident. Before you use kener apis you will have to set an authorization token called API_TOKEN. This also has to be set as an environment variable.
export API_TOKEN=some-token-set-by-you
Additonally you can set IP whitelisting by setting another environment token called API_IP
export API_IP=127.0.0.1


