Files
kener/docs.md
Raj Nandan Sharma b9fe4f069f new build
2023-12-25 22:13:27 +05:30

15 KiB

Quick Start

Kener has been tested from Node18.

Clone the repository

git clone https://github.com/rajnandan1/kener.git
cd kener

Install Dependencies

npm install

Configs

  • Rename config/site.example.yaml -> config/site.yaml
  • Rename config/monitors.example.yaml -> config/monitors.yaml
mv config/site.example.yaml config/site.yaml
mv config/monitors.example.yaml config/monitors.yaml

Start Kener Dev

npm run kener:dev

Kener Development Server would be running at PORT 5173. Go to http://localhost:5173

alt text

Concepts

Kener has two parts. One is a svelte app which you can find in the src folder and there are code for monitors which you would find in scripts folder. If you want to update the frontend application then you should modify the src folder.

Folder structure

├── src (svelte frontend files)
├── static (things put here can be referenced directly example static/logo.png -> /logo.png)
├── scripts (nodejs server files)
├── prod.js(starts an express server, runs the scripts and serves the svelte site)
├── dev.js (starts the dev server)

Environment Vairable

PUBLIC_KENER_FOLDER (Required)

export PUBLIC_KENER_FOLDER=./build/client/kener

PORT

Defaults to 3000 if not specified

export PORT=4242

GH_TOKEN

A github token to read issues and create labels

export GH_TOKEN=your-github-token

API_TOKEN

To talk to kener apis you will need to set up a token. It uses Bearer Authorization

export API_TOKEN=sometoken

API_IP

export API_IP=127.0.0.1

MONITOR_YAML_PATH

export MONITOR_YAML_PATH=/your/path/monitors.yaml

SITE_YAML_PATH

export SITE_YAML_PATH=/your/path/site.yaml

Production Deployment

Once you have added the config/site.yaml or config/monitors.yaml or changed anything in src/

Kener should be run using prod.js script.

export NODE_ENV=production
npm i
npm run build
npm run serve

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 
npm i
npm run kener:build
node prod.js

Github Setup

Kener uses github for incident management. Issues created in github using certain tags go to kener as incidents.

Step 1: Github Repositiory

Create a Github Repositiory. It can be either public or private

Step 2: Create Github Token

You can create either a classic token or personal access token

Creating Personal Access Token

  • Go to Personal Access Token
  • Token Name: kener
  • Expiration: Use custom to select a calendar date
  • Description: My Kener
  • Repository access: Check Only Selected Repositories. Select your github repository
  • Repository Permission: Select Issues Read Write
  • Click on generate token

Creating Classic Token

  • Go to Tokens
  • Note: kener
  • Expiration: No Expiration
  • Scopes: write:packages
  • Click on generate Token

Set the 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"
home: "/"
logo: "/logo.svg"
github:
  owner: "rajnandan1"
  repo: "kener"
  incidentSince: 72
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
...

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: "respository"
  incidentSince: 72

incidentSince is in hours. It means if an issue is created before 72 hours then kener would not honor it. Default is 24

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.

alt text

nav

You can add more links to your navbar.

nav:
  - name: "Home"
    url: "/home"

alt text

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.

Understanding monitors

Each monitor runs at 1 minute interval by default. Monitor runs in below priorty order.

  • defaultStatus Data
  • API call Data overrides above data(if specified)
  • Push Status Data overrides API Data
  • Manual Incident Data overrides Pushed data

Sample

- name: Google Search
  description: Search the world's information, including webpages, images, videos and more.
  tag: "google-search"
  image: "/google.png"
  cron: "* * * * *"
  defaultStatus: "UP"
  api:
	timeout: 4000
	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,
		}
		})
name Required This will be shown in the UI to your users. Keep it short and unique
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 Optinal Use cron expression to specify the interval to run the monitors. Defaults to * * * * * i.e every minute
api.method Optional HTTP Method
api.url Optional HTTP URL
api.headers Optional HTTP headers
api.body Optional HTTP Body as string
api.eval Optional Evaluator written in JS, to parse HTTP response and calculate uptime and latency
defaultStatus Optional If no API is given this will be the default status. can be UP/DOWN/DEGRADED

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,
	}
})
  • statusCode REQUIRED is a number. It is the HTTP status code
  • responseTime REQUIREDis a number. It is the latency in milliseconds
  • responseDataBase64 REQUIRED 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"
  api:
  	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"
  image: "/google.png"
  api:
  	method: GET
  	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 * * * *"
  api:
  	method: GET
  	url: https://www.google.com/webhp

Post Monitor With Body

- name: Google Search
  description: Google Search
  tag: "google-search-post"
  api:
  	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"
  api:
  	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"
  api:
  	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"
  api:
  	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 using labels

Labels

Kener auto creates labels for your monitors using the tag parameter

  • incident: If an issue is marked as incident it will show up in kener home page
  • incident-down: If an issue is marked as incident-down and incident kener would make that monitor down
  • incident-degraded: If an issue is marked as incident-degraded and incident then kener would make the monitor degraded

Creating your first incident

  • Go to your github repo of kener
  • Go to issues
  • Create an issue. Give it a title
  • In the body add [start_datetime:1702651340] and [end_datetime:1702651140] and add some description. Time is UTC
  • Add incident, incident-down and the monitor tag. This will make the monitor down for 4 minutes

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

Update Status

curl --request POST \
  --url http://your-kener.com/api/status \
  --header 'Authorization: Bearer some-token-set-by-you' \
  --header 'Content-Type: application/json' \
  --data '{
	"status": "UP",
	"latency": 1213,
	"timestampInSeconds": 1702405860,
	"tag": "google-search"
}'

Badge

There are two types of badges

Status

Shows the last health check was UP/DOWN/DEGRADED Earth Status -> https://kener.ing/badge/earth/status

![Status Badge](https://your.kener.host/badge/[monitor.tag]/status)

Uptime

Shows the 90 Day uptime Earth Uptime -> https://kener.ing/badge/earth/uptime

![Uptime Badge](https://your.kener.host/badge/[monitor.tag]/uptime)