service outages and use nws api
This commit is contained in:
parent
025e993700
commit
22129d5268
|
@ -2,9 +2,10 @@
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="03fafda4-e2c1-4602-a731-a2f96e84badd" name="Default Changelist" comment="">
|
<list default="true" id="03fafda4-e2c1-4602-a731-a2f96e84badd" name="Default Changelist" comment="">
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/nws-api/calls.ts" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/nws-api/types.ts" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/package-lock.json" beforeDir="false" afterPath="$PROJECT_DIR$/package-lock.json" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/App.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/App.css" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/App.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/App.tsx" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/App.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/App.tsx" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
@ -12,6 +13,13 @@
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="FileTemplateManagerImpl">
|
||||||
|
<option name="RECENT_TEMPLATES">
|
||||||
|
<list>
|
||||||
|
<option value="TypeScript File" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
<component name="Git.Settings">
|
<component name="Git.Settings">
|
||||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||||
</component>
|
</component>
|
||||||
|
@ -60,6 +68,7 @@
|
||||||
<workItem from="1643936709048" duration="547000" />
|
<workItem from="1643936709048" duration="547000" />
|
||||||
<workItem from="1648500425230" duration="246000" />
|
<workItem from="1648500425230" duration="246000" />
|
||||||
<workItem from="1658028513357" duration="2964000" />
|
<workItem from="1658028513357" duration="2964000" />
|
||||||
|
<workItem from="1666469240565" duration="3204000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
|
|
19
src/App.css
19
src/App.css
|
@ -1,6 +1,23 @@
|
||||||
.App {
|
.App {
|
||||||
text-align: center;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.low-severity {
|
||||||
|
background-color: #98fb98
|
||||||
|
}
|
||||||
|
|
||||||
|
.med-severity {
|
||||||
|
background-color: #eee8aa
|
||||||
|
}
|
||||||
|
|
||||||
|
.high-severity {
|
||||||
|
background-color: #f08080
|
||||||
|
}
|
||||||
|
|
||||||
|
.incident {
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: .75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
106
src/App.tsx
106
src/App.tsx
|
@ -2,52 +2,28 @@ import React, {useEffect, useState} from 'react';
|
||||||
import NWSLogo from './static/images/NWS_Logo.png';
|
import NWSLogo from './static/images/NWS_Logo.png';
|
||||||
import './App.css';
|
import './App.css';
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
import {Incident, UptimeResponse} from "./nws-api/types";
|
||||||
|
import {getIncidents, getUptime} from "./nws-api/calls";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const today = new Date();
|
const [uptime, setUptime] = useState<UptimeResponse>({datacenters: [], services:[]});
|
||||||
const setup_time = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate());
|
const [incidents, setIncidents] = useState<Incident[]>([]);
|
||||||
const [monitors, setMonitors] = useState(new Array<any>());
|
|
||||||
|
const fetchUptime = async () => {
|
||||||
|
let resp: UptimeResponse = await getUptime();
|
||||||
|
setUptime(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchIncidents = async () => {
|
||||||
|
let resp: Incident[] = await getIncidents();
|
||||||
|
setIncidents(resp);
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
var myHeaders = new Headers();
|
fetchUptime();
|
||||||
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
|
fetchIncidents();
|
||||||
|
|
||||||
var urlencoded = new URLSearchParams();
|
|
||||||
urlencoded.append("api_key", "ur1612363-492fa5df2a31fab5b52171b4");
|
|
||||||
|
|
||||||
urlencoded.append("custom_uptime_ranges", (setup_time.valueOf() / 1000) + "_" + (today.valueOf() / 1000));
|
|
||||||
urlencoded.append("all_time_uptime_ratio", "1");
|
|
||||||
|
|
||||||
var requestOptions = {
|
|
||||||
method: 'POST',
|
|
||||||
headers: myHeaders,
|
|
||||||
body: urlencoded,
|
|
||||||
redirect: 'follow'
|
|
||||||
};
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
fetch("https://api.uptimerobot.com/v2/getMonitors", requestOptions)
|
|
||||||
.then(response => response.json().then(json => {
|
|
||||||
setMonitors(json.monitors);
|
|
||||||
}))
|
|
||||||
.then(result => console.log(result))
|
|
||||||
.catch(error => console.log('error', error));
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
let diff = new Date().getTime() - setup_time.getTime();
|
|
||||||
|
|
||||||
let days = Math.floor(diff / (1000 * 60 * 60 * 24));
|
|
||||||
diff -= days * (1000 * 60 * 60 * 24);
|
|
||||||
|
|
||||||
let hours = Math.floor(diff / (1000 * 60 * 60));
|
|
||||||
diff -= hours * (1000 * 60 * 60);
|
|
||||||
|
|
||||||
let mins = Math.floor(diff / (1000 * 60));
|
|
||||||
diff -= mins * (1000 * 60);
|
|
||||||
|
|
||||||
let seconds = Math.floor(diff / (1000));
|
|
||||||
diff -= seconds * (1000);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<div className={"row w-100"}>
|
<div className={"row w-100"}>
|
||||||
|
@ -71,17 +47,13 @@ function App() {
|
||||||
<th>Uptime (All Time)</th>
|
<th>Uptime (All Time)</th>
|
||||||
<th>Current Status</th>
|
<th>Current Status</th>
|
||||||
</tr>
|
</tr>
|
||||||
{monitors.map((e) => {
|
{uptime.datacenters.map((e) => {
|
||||||
let name_parts = e.friendly_name.split('.');
|
|
||||||
if (name_parts[0] === 'datacenter') {
|
|
||||||
return (<tr>
|
return (<tr>
|
||||||
<td>{name_parts[1]}</td>
|
<td>{e.name}</td>
|
||||||
<td>{e.custom_uptime_ranges}%</td>
|
<td>{e.uptimeMonth}%</td>
|
||||||
<td>{e.all_time_uptime_ratio}%</td>
|
<td>{e.uptimeAllTime}%</td>
|
||||||
<td>{e.status === 2 ? 'Up' : 'Down'}</td>
|
<td>{e.isUp ? 'Up' : 'Down'}</td>
|
||||||
</tr>);
|
</tr>);
|
||||||
|
|
||||||
}
|
|
||||||
})}
|
})}
|
||||||
</table>
|
</table>
|
||||||
</p>
|
</p>
|
||||||
|
@ -95,21 +67,41 @@ function App() {
|
||||||
<th>Uptime (All Time)</th>
|
<th>Uptime (All Time)</th>
|
||||||
<th>Current Status</th>
|
<th>Current Status</th>
|
||||||
</tr>
|
</tr>
|
||||||
{monitors.map((e) => {
|
{uptime.services.map((e) => {
|
||||||
let name_parts = e.friendly_name.split('.');
|
|
||||||
if (name_parts[0] === 'service') {
|
|
||||||
return (<tr>
|
return (<tr>
|
||||||
<td><a href={e.url}>{name_parts[1]}</a></td>
|
<td><a href={e.url}>{e.name}</a></td>
|
||||||
<td>{e.custom_uptime_ranges}%</td>
|
<td>{e.uptimeMonth}%</td>
|
||||||
<td>{e.all_time_uptime_ratio}%</td>
|
<td>{e.uptimeAllTime}%</td>
|
||||||
<td>{e.status === 2 ? 'Up' : 'Down'}</td>
|
<td>{e.isUp ? 'Up' : 'Down'}</td>
|
||||||
</tr>);
|
</tr>);
|
||||||
|
|
||||||
}
|
|
||||||
})}
|
})}
|
||||||
</table>
|
</table>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div style={{width: '75vw'}}>
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3>Service Alerts</h3>
|
||||||
|
{incidents.map((e) => {
|
||||||
|
let severityClass: string = e.severity == 0 ? 'low' : (e.severity == 1 ? 'med' : 'high');
|
||||||
|
let severityString: string = e.severity == 0 ? 'Low' : (e.severity == 1 ? 'Medium' : 'High');
|
||||||
|
return (
|
||||||
|
<div className={`row text-left incident ${severityClass}-severity`} style={{width: '75vw'}}>
|
||||||
|
<p className={"col-10"}><b>{e.title}</b></p>
|
||||||
|
<p className={"col-2"}><b>{severityString} Severity</b></p>
|
||||||
|
<p className={"mb-0"}>{e.description}</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
{incidents.length == 0 && <div className={`row text-center`} style={{width: '75vw'}}>
|
||||||
|
<h5 className={"col-12"}>No service alerts.</h5>
|
||||||
|
</div>}
|
||||||
</div>
|
</div>
|
||||||
<footer style={{margin: 25}}>
|
<footer style={{margin: 25}}>
|
||||||
NWS is owned and operated by <a href={"http://nickorlow.com"}>Nicholas Orlowsky</a>.
|
NWS is owned and operated by <a href={"http://nickorlow.com"}>Nicholas Orlowsky</a>.
|
||||||
|
|
14
src/nws-api/calls.ts
Normal file
14
src/nws-api/calls.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import {Incident, UptimeResponse} from "./types";
|
||||||
|
|
||||||
|
export async function getUptime(): Promise<UptimeResponse> {
|
||||||
|
let response: Response = await fetch('https://api-nws.nickorlow.com/uptime');
|
||||||
|
let uptime: UptimeResponse = await response.json();
|
||||||
|
return uptime;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getIncidents(): Promise<Incident[]> {
|
||||||
|
let response: Response = await fetch('https://api-nws.nickorlow.com/incidents');
|
||||||
|
let incidents: Incident[] = await response.json();
|
||||||
|
return incidents;
|
||||||
|
}
|
||||||
|
|
34
src/nws-api/types.ts
Normal file
34
src/nws-api/types.ts
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
export type UptimeRecord = {
|
||||||
|
name: string,
|
||||||
|
url: string,
|
||||||
|
uptimeMonth: number,
|
||||||
|
uptimeAllTime: number,
|
||||||
|
isUp: boolean,
|
||||||
|
undergoingMaintenance: boolean
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UptimeResponse = {
|
||||||
|
datacenters: UptimeRecord[],
|
||||||
|
services: UptimeRecord[]
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Blog = {
|
||||||
|
id: number,
|
||||||
|
title: string,
|
||||||
|
author: string,
|
||||||
|
content: string,
|
||||||
|
imageUrl: string
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Incident = {
|
||||||
|
id: number,
|
||||||
|
severity: IncidentSeverity,
|
||||||
|
title: string,
|
||||||
|
description: string
|
||||||
|
};
|
||||||
|
|
||||||
|
enum IncidentSeverity {
|
||||||
|
LOW,
|
||||||
|
MEDIUM,
|
||||||
|
HIGH
|
||||||
|
};
|
Loading…
Reference in a new issue