Skip to content

Commit

Permalink
Merge pull request #250 from rajnandan1/release/3.0.10
Browse files Browse the repository at this point in the history
Release/3.0.10
  • Loading branch information
rajnandan1 authored Feb 7, 2025
2 parents 3b1d95b + e3e59b7 commit c7376b4
Show file tree
Hide file tree
Showing 16 changed files with 621 additions and 275 deletions.
17 changes: 6 additions & 11 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,17 @@ Steps to reproduce the behavior:
3. Scroll down to '....'
4. See error

**Version**
Which version of kener you are using.

**Environment**
Which environment you are using or where is it deployed. `docker`, `kubernetes`, `bare-metal`, `development`, `pm2` etc

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]

**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]

**Additional context**
Add any other context about the problem here.
19 changes: 19 additions & 0 deletions docs/changelogs.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,25 @@ description: Changelogs for Kener

Here are the changelogs for Kener. Changelogs are only published when there are new features or breaking changes.

## v3.0.10

<picture>
<source srcset="https://fonts.gstatic.com/s/e/notoemoji/latest/1f680/512.webp" type="image/webp">
<img src="https://fonts.gstatic.com/s/e/notoemoji/latest/1f680/512.gif" alt="🚀" width="32" height="32">
</picture>

### Features

- Added TCP monitors

### Breaking Changes

- Ping monitors will break.

### Fixes

- Bug fixes in the UI

## v3.0.9

<picture>
Expand Down
1 change: 1 addition & 0 deletions docs/home.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ cheaply available domain.
### Monitoring and Tracking

- Advanced application performance monitoring tools
- Types of Monitors: HTTP, TCP, DNS, ICMP etc
- Real-time network monitor software capabilities
- Polls HTTP endpoint or Push data to monitor using Rest APIs
- Handles Timezones for visitors
Expand Down
106 changes: 49 additions & 57 deletions docs/monitors-ping.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,14 @@ Ping monitors are used to monitor livenees of your servers. You can use Ping mon

</div>

## Host V4
## Hosts

You can add as many IP addresses as you want to monitor. The IP address should be a valid IPv4 address.
You can add as many hosts as you want to monitor. The host can be an IP(IP4 and IP6) address or a domain name.

Example of IP4 address is `106.12.43.232`, with the port number `80`. The port number is optional and defaults to `80`.

Example of IP4 address with port number is `66.51.120.219:465`.

Example of domain name with port number is `www.rajnandan.com:80`.

## Host V6

You can add as many IP addresses as you want to monitor. The IP address should be a valid IPv6 address. Example of IP6 address is `2001:0db8:85a3:0000:0000:8a2e:0370`.

Example of IP6 address with port number is `2606:50c0:8000::153:443`.

<p class="note danger">
Please note that at least one of the Host V4 or Host V6 is required.
<p>
- Type: Choose the type of host you want to monitor. It can be either `IP4` or `IP6` or `DOMAIN`.
- Host: Enter the IP address or domain name of the host you want to monitor.
- Timeout: Enter the timeout in milliseconds for each ping request of each host. For IP6 timeout is not supported.
- Count: The number of pings you want to do for each host. The average latency of all the pings will be used to evaluate the response.

## Eval

Expand All @@ -50,16 +39,12 @@ This is an anonymous JS function, it should return a **Promise**, that resolves
}, 0);

let alive = arrayOfPings.reduce((acc, ping) => {
if (ping.status === "open") {
return acc && true;
} else {
return false;
}
return acc && ping.alive;
}, true);

return {
status: alive ? "UP" : "DOWN",
latency: parseInt(latencyTotal / arrayOfPings.length)
latency: latencyTotal / arrayOfPings.length
};
});
```
Expand All @@ -72,41 +57,52 @@ let jsonResp = JSON.parse(decodedResp);
console.log(jsonResp);
/*
[
{
"host": "smtp.resend.com",
"port": 587,
"type": "IP4",
"status": "open",
"latency": 36.750917
},
{
"host": "66.51.120.219",
"port": 465,
"type": "IP4",
"status": "open",
"latency": 27.782792
},
{
"host": "2606:4700:4700::1111",
"port": 443,
"status": "open",
"type": "IP6",
"latency": 5.684375
}
{
alive: true,
min: '145.121',
max: '149.740',
avg: '147.430',
latencies: [ 145.121, 149.74 ],
latency: 145.121,
host: '45.91.169.49',
type: 'IP4'
},
{
alive: true,
min: '145.348',
max: '149.143',
avg: '147.245',
latencies: [ 145.348, 149.143 ],
latency: 145.348,
host: 'kener.ing',
type: 'DOMAIN'
},
{
alive: true,
min: '57.696',
max: '58.330',
avg: '58.013',
latencies: [ 57.696, 58.33 ],
latency: 57.696,
host: '2404:6800:4003:c1c::66',
type: 'IP6'
}
]
*/
```

### Understanding the Input

- `host`: The host that was pinged.
- `port`: The port that was pinged. Defaults to 80 if not provided.
- `type`: The type of IP address. Can be `IP4` or `IP6`.
- `status`: The status of the ping. Can be `open` , `error` or `timeout`.
- `open`: The host is reachable.
- `error`: There was an error while pinging the host.
- `timeout`: The host did not respond in time.
- `latency`: The time taken to ping the host. This is in milliseconds.
The input to the eval function is a base64 encoded string. You will have to decode it and then parse it to get the array of objects. Each object in the array represents the ping response of a host.

- `alive` is a boolean. It is true if the host is alive and false if the host is down.
- `min` is a string. It is the minimum latency of the pings.
- `max` is a string. It is the maximum latency of the pings.
- `avg` is a string. It is the average latency of the pings.
- `latencies` is an array of numbers. It is the latency of each ping.
- `latency` is a number. It is the average latency of the pings.
- `host` is a string. It is the host that was pinged.
- `type` is a string. It is the type of the host. It can be either `IP4` or `IP6` or `DOMAIN`.

### Example

Expand All @@ -120,11 +116,7 @@ The following example shows how to use the eval function to evaluate the respons
}, 0);

let areAllOpen = arrayOfPings.reduce((acc, ping) => {
if (ping.status === "open") {
return acc && true;
} else {
return false;
}
return acc && ping.alive;
}, true);

let avgLatency = latencyTotal / arrayOfPings.length;
Expand Down
135 changes: 135 additions & 0 deletions docs/monitors-tcp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
---
title: TCP Monitors | Kener
description: Learn how to set up and work with TCP monitors in kener.
---

# TCP Monitors

TCP monitors are used to monitor the livenees of your servers. You can use TCP monitors to monitor the uptime of your servers and get notified when they are down.

<div class="border rounded-md">

![Monitors TCP](/m_tcp.png)

</div>

## Hosts

You can add as many hosts as you want to monitor. The host can be an IP(IP4 and IP6) address or a domain name.

- Type: Choose the type of host you want to monitor. It can be either `IP4` or `IP6` or `DOMAIN`.
- Host: Enter the IP address or domain name of the host you want to monitor.
- Port: Enter the port number of the host you want to monitor.
- Timeout: Enter the timeout in milliseconds for each ping request of each host

## Eval

The eval is used to define the JavaScript code that should be used to evaluate the response. It is optional and has be a valid JavaScript code.

This is an anonymous JS function, it should return a **Promise**, that resolves or rejects to `{status, latency}`, 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 latency(number)
> `{status:"DEGRADED", latency: 200}`.
```javascript
(async function (responseDataBase64) {
let arrayOfPings = JSON.parse(atob(responseDataBase64));
let latencyTotal = arrayOfPings.reduce((acc, ping) => {
return acc + ping.latency;
}, 0);

let alive = arrayOfPings.reduce((acc, ping) => {
if (ping.status === "open") {
return acc && true;
} else {
return false;
}
}, true);

return {
status: alive ? "UP" : "DOWN",
latency: latencyTotal / arrayOfPings.length
};
});
```

- `responseDataBase64` **REQUIRED** is a string. It is the base64 encoded response data. To use it you will have to decode it and the JSON parse it. Once parse it will be an array of objects.

```js
let decodedResp = atob(responseDataBase64);
let jsonResp = JSON.parse(decodedResp);
console.log(jsonResp);
/*
[
{
status: 'open',
latency: 31.93,
host: '66.51.120.219',
port: 465,
type: 'IP4'
},
{
status: 'open',
latency: 47.041417,
host: '2404:6800:4003:c1c::66',
port: 80,
type: 'IP6'
},
{
status: 'open',
latency: 82.1865,
host: 'rajnandan.com',
port: 80,
type: 'DOMAIN'
}
]
*/
```

### Understanding the Input

The input to the eval function is a base64 encoded string. You will have to decode it and then parse it to get the array of objects. Each object in the array represents the ping response of a host.

- `host`: The host that was pinged.
- `port`: The port that was pinged. Defaults to 80 if not provided.
- `type`: The type of IP address. Can be `IP4` or `IP6`.
- `status`: The status of the ping. Can be `open` , `error` or `timeout`.
- `open`: The host is reachable.
- `error`: There was an error while pinging the host.
- `timeout`: The host did not respond in time.
- `latency`: The time taken to ping the host. This is in milliseconds.

### Example

The following example shows how to use the eval function to evaluate the response. The function checks if the combined latency is more 10ms then returns `DEGRADED`.

```javascript
(async function (responseDataBase64) {
let arrayOfPings = JSON.parse(atob(responseDataBase64));
let latencyTotal = arrayOfPings.reduce((acc, ping) => {
return acc + ping.latency;
}, 0);

let areAllOpen = arrayOfPings.reduce((acc, ping) => {
if (ping.status === "open") {
return acc && true;
} else {
return false;
}
}, true);

let avgLatency = latencyTotal / arrayOfPings.length;

if (areAllOpen && avgLatency > 10) {
return {
status: "DEGRADED",
latency: avgLatency
};
}

return {
status: areAllOpen ? "UP" : "DOWN",
latency: avgLatency
};
});
```
5 changes: 5 additions & 0 deletions docs/structure.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@
"link": "/docs/monitors-ping",
"file": "/monitors-ping.md"
},
{
"title": "TCP Monitor",
"link": "/docs/monitors-tcp",
"file": "/monitors-tcp.md"
},
{
"title": "DNS Monitor",
"link": "/docs/monitors-dns",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "kener",
"version": "3.0.9",
"version": "3.0.10",
"private": false,
"license": "MIT",
"description": "Kener: An open-source Node.js status page application for real-time service monitoring, incident management, and customizable reporting. Simplify service outage tracking, enhance incident communication, and ensure a seamless user experience.",
Expand Down
12 changes: 6 additions & 6 deletions src/lib/clientTools.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,22 +115,22 @@ const allRecordTypes = {
};
const ValidateIpAddress = function (input) {
// Check if input is a valid IPv4 address with an optional port
const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}(:\d{1,5})?$/;
const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
if (ipv4Regex.test(input)) {
return "IPv4";
return "IP4";
}

// Improved IPv6 regex that better handles compressed notation
const ipv6Regex =
/^(?:(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){0,7}:|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){6}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|(?:[0-9a-fA-F]{1,4}:){1,7}(?::|:[0-9a-fA-F]{1,4})|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:))(?::\d{1,5})?$/;
/^(?:(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){0,7}:|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){6}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|(?:[0-9a-fA-F]{1,4}:){1,7}(?::|:[0-9a-fA-F]{1,4})|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:))$/;
if (ipv6Regex.test(input)) {
return "IPv6";
return "IP6";
}

// Check if input is a valid domain name with an optional port
const domainRegex = /^[a-zA-Z0-9]+([\-\.]{1}[a-zA-Z0-9]+)*\.[a-zA-Z]{2,}(:\d{1,5})?$/;
const domainRegex = /^[a-zA-Z0-9]+([\-\.]{1}[a-zA-Z0-9]+)*\.[a-zA-Z]{2,}$/;
if (domainRegex.test(input)) {
return "Domain Name";
return "DOMAIN";
}

// If none of the above conditions match, the input is invalid
Expand Down
Loading

0 comments on commit c7376b4

Please sign in to comment.