Skip to content

Commit 5f79b63

Browse files
authored
Merge pull request #259 from oslabs-beta/master
v10 finalized version
2 parents 0575b5d + 069d041 commit 5f79b63

File tree

85 files changed

+37116
-4992
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+37116
-4992
lines changed

README.md

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,38 +23,44 @@ Chronos is a comprehensive developer tool that monitors the health and web traff
2323

2424
## What's New?
2525

26+
- Chronos is now able to work out of the box, addressing previous bugs that prevented Chronos to work as intended. File structure, dependencies, and webpack entry point have been updated, allowing Chronos Electron desktop application to run on multiple platforms.
27+
- User's account information and services can now be stored and saved in MongoDB User database.
28+
- Bug fixes and UI tweaks — Chronos is now a faster and more seamless experience than ever.
29+
- Updated step-by-step instructions to learn how to deploy local services such as dockerized containers, microservices, and gRPC examples, as well as monitor them using the chronosmicro/tracker npm package.
30+
- Steamlined approach to access and dynamically displayed grafana dashboards for deployed EKS cluster (utilizing Prometheus data scraping and generated grafana dashboards) using the Grafana API.
31+
32+
Previously implemented updates:
2633
- Option to choose between cloud hosted services and local services, now giving Chronos the ability to monitor instances and clusters on AWS' EC2, ECS, and EKS platforms.
2734
- An updated AWS Graphs Container to dynamically render plots for EC2 or ECS data fetched with Electron using event listeners connecting to AWS CloudWatch w/ the aws-sdk package, as well as utilizing Prometheus data scraping and Grafana integration to fetch and render EKS data.
2835
- A step-by-step instruction on setting up a new, functional EC2 instance, ECS cluster, and EKS cluster, ready to be monitored and tested by the app.
29-
- Bug fixes and UI tweaks — Chronos is now a more seamless experience than ever.
3036

3137
## Features
3238

33-
- Distributed tracing enabled across microservices applications
34-
- Kubernetes monitoring via Prometheus server
35-
- Compatible with <img src="assets/graphql-logo-color.png" alt="GraphQL" title="GraphQL" align="center" height="20" /></a>
36-
- Supports <a href="#"><img src="assets/postgres-logo-color.png" alt="PostgreSQL" title="PostgreSQL" align="center" height="20" /></a> and <img src="assets/mongo-logo-color.png" alt="MongoDB" title="MongoDB" align="center" height="20" /></a> databases
37-
- Displays real-time temperature, speed, latency, and memory statistics
38-
- Display and compare multiple microservice metrics in a single graph
39-
- Monitor an <a href="#"><img src="assets/pngwing.com.png" alt="Apache Kafka" title="Apache Kafka" align="center" height="20" /></a> cluster via the JMX Prometheus Exporter
40-
- Monitor a Kubernetes cluster via a Prometheus monitoring server
41-
- Monitor Amazon Web Services (AWS) instances and clusters <img src="assets/aws-logo-color.png" alt="AWS" title="AWS" align="center" height="20" /></a>
39+
- Cloud-Based Instances:
40+
- Option to choose between cloud hosted services and local services, now giving Chronos the ability to monitor instances and clusters on AWS' EC2, ECS, and EKS platforms <img src="assets/aws-logo-color.png" alt="AWS" title="AWS" align="center" height="20" /></a>
41+
- Local Instances utilitizing @chronosmicro/tracker NPM package:
42+
- Distributed tracing enabled across microservices applications
43+
- Displays real-time temperature, speed, latency, and memory statistics for local services
44+
- Display and compare multiple microservice metrics in a single graph
45+
- Kubernetes monitoring via Prometheus server
46+
- Compatible with <img src="assets/graphql-logo-color.png" alt="GraphQL" title="GraphQL" align="center" height="20" /></a>
47+
- Monitor an <a href="#"><img src="assets/pngwing.com.png" alt="Apache Kafka" title="Apache Kafka" align="center" height="20" /></a> cluster via the JMX Prometheus Exporter
48+
- Supports <a href="#"><img src="assets/postgres-logo-color.png" alt="PostgreSQL" title="PostgreSQL" align="center" height="20" /></a> and <img src="assets/mongo-logo-color.png" alt="MongoDB" title="MongoDB" align="center" height="20" /></a> databases
4249

4350
#
4451

4552
## Installation
4653

47-
This is for the latest Chronos **version 9 release**.
54+
This is for the latest Chronos **version 10 release**.
4855

4956
**NOTE:** The Chronos tracker code is included in the _chronos_npm_package_ folder for ease of development, but the published npm package can be downloaded by running `npm install @chronosmicro/tracker`
5057

5158
<br>
5259

53-
### Node Version
54-
55-
Make sure you're running version 16.17.1 of <img src="assets/node-logo-color.png" alt="Node" title="Node" align="center" height="20" />, to align with the <img src="assets/node-logo-color.png" alt="Node" title="Node" align="center" height="20" /> version used by <img src="assets/electron-logo-color.png" alt="Electron" title="Electron" align="center" height="20" /> version 22.
56-
57-
<br>
60+
<!-- ### Node Version -->
61+
<!-- v10 notes: Our team never reverted to version 16.17.1 and had no issues running Node 18 and Electron 22 together. Commenting this out for future iteration teams' reference. -->
62+
<!-- Make sure you're running version 16.17.1 of <img src="assets/node-logo-color.png" alt="Node" title="Node" align="center" height="20" />, to align with the <img src="assets/node-logo-color.png" alt="Node" title="Node" align="center" height="20" /> version used by <img src="assets/electron-logo-color.png" alt="Electron" title="Electron" align="center" height="20" /> version 22. -->
63+
<!-- <br> -->
5864

5965
### WSL2 Environment
6066

@@ -79,8 +85,9 @@ export DISPLAY="`sed -n 's/nameserver //p' /etc/resolv.conf`:0"
7985
### Running the Chronos Desktop App in Development Mode
8086

8187
1. From the root directory, run `npm install`
82-
2. Open a terminal and run `npm run dev:app` to start the Webpack development server
83-
3. Open another terminal and run `npm run dev:electron` to start the Electron UI in development mode
88+
2. Run 'npm run build'
89+
3. Open a new terminal and run `npm run dev:app` to start the Webpack development server
90+
4. Open a new terminal and run `npm run dev:electron` to start the Electron UI in development mode
8491

8592
### Packing the Chronos App into an Executable
8693

app/App.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import './stylesheets/scrollBar.scss';
55

66

77
// this is the fitness gram pacer test
8+
// React memo helps with rendering optimization. The components within React memo will only be rerendered if prompt has changed
89
const App: React.FC = React.memo(() => {
910
return (
1011
<div>

app/components/Login.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ const Login = React.memo(() => {
1414
* Function that will be called when the form button is clicked
1515
* It handles submitting the login information
1616
*/
17-
17+
// v10: ipcRenderer returning a string with the response of user mode (light or dark).
18+
// There is currently no redirection after failed login.
1819
const handleSubmit = (e: any) => {
1920
e.preventDefault();
2021
const inputFields: HTMLInputElement[] = e.currentTarget.querySelectorAll('input');
@@ -23,7 +24,9 @@ const Login = React.memo(() => {
2324
// eslint-disable-next-line no-return-assign
2425
// inputFields.forEach(input => (input.value = ''));
2526
const response: boolean | string = ipcRenderer.sendSync('login', { username, password });
26-
if (typeof(response) === 'string') {
27+
if (typeof (response) === 'string') {
28+
console.log('Hi, login successful and response string (mode) is:', response);
29+
console.log('Redirected to Occupied from Login.');
2730
setUser(username);
2831
setMode(response);
2932
navigate('/');

app/components/Occupied.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,18 @@ interface StyleProps {
5555
}
5656
type ClickEvent = React.MouseEvent<HTMLElement>;
5757

58+
// type OccupiedProps = {
59+
// switch: any;
60+
// setSwitch: any;
61+
// };
62+
63+
//v10: Memoized function, witouth any props. Should theoretically be called only once.
5864
const Occupied = React.memo(() => {
65+
console.log('Hi, inside Occupied. Memoize function invoked');
66+
5967
const { awsData, fetchAwsData, fetchAwsAppInfo, setLoadingState } = useContext(AwsContext);
6068
const { setServicesData, app, setApp } = useContext(ApplicationContext);
69+
// const { user, getApplications, deleteApp, mode } = useContext(DashboardContext);
6170
const { user, applications, getApplications, deleteApp, mode } = useContext(DashboardContext);
6271
const { commsData } = useContext(CommsContext);
6372
const [serviceModalOpen, setServiceModalOpen] = useState<boolean>(false);
@@ -75,12 +84,16 @@ const Occupied = React.memo(() => {
7584
// const [showAwsContainer, setShowAwsContainer] = useState(false);
7685
const navigate = useNavigate();
7786

87+
7888
// Grab services and applications whenever the user changes
89+
// v10: Runs once when Occupied is memoized, and subsequently when user is updated.
7990
useEffect(() => {
91+
console.log('Hi, inside Occupied.ts useEffect function.');
8092
setServicesData([]);
8193
getApplications();
8294
}, [user]);
8395

96+
8497
// Dynamic refs
8598
const delRef = useRef<any>([]);
8699

@@ -91,6 +104,8 @@ const Occupied = React.memo(() => {
91104
};
92105

93106
// Handle clicks on Application cards
107+
// v10 info: when card is clicked (not on the delete button) if the service is an AWS instance,
108+
// you are redirected to AWSGraphsContainer passing in the state object containing typeOfService
94109
const handleClick = (
95110
event: ClickEvent,
96111
selectedApp: string,

app/components/SignUp.tsx

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ const { ipcRenderer } = window.require('electron');
99
const SignUp:React.FC = React.memo(() => {
1010
const navigate = useNavigate();
1111
const { setUser } = useContext(DashboardContext);
12-
const [failedSignUp, setFailedSignUp] = useState<JSX.Element>(<>hey</>);
12+
const [failedSignUp, setFailedSignUp] = useState<JSX.Element>(<></>);
13+
const [username, setUsername] = useState('');
14+
const [email, setEmail] = useState('');
15+
const [password, setPassword] = useState('');
16+
const [confirmPassword, setConfirmPassword] = useState('');
1317

1418
function handleSubmit(e: any) {
1519
e.preventDefault();
@@ -18,23 +22,37 @@ const SignUp:React.FC = React.memo(() => {
1822
const email = inputFields[1].value;
1923
const password = inputFields[2].value;
2024
const confirmPassword = inputFields[3].value;
25+
// setUsername(inputFields[0].value);
26+
// setEmail(inputFields[1].value);
27+
// setPassword(inputFields[2].value);
28+
// setConfirmPassword(inputFields[3].value);
29+
30+
2131

2232
// eslint-disable-next-line no-return-assign
2333
inputFields.forEach(input => (input.value = ''));
2434

35+
if (!password) {
36+
setFailedSignUp(<p>Please enter valid password</p>)
37+
return;
38+
}
2539
if (password !== confirmPassword) {
2640
setFailedSignUp(<p>Entered passwords do not match</p>);
2741
return;
2842
}
2943

3044
ipcRenderer.invoke('addUser', { username, email, password})
31-
.then(validSignUp => {
32-
if (validSignUp) {
33-
setUser(username);
34-
navigate('/');
35-
} else
36-
setFailedSignUp(<p>Sorry, your sign up failed. Please try a different username or email</p>);
37-
}).catch(error => {
45+
.then((message) => {
46+
console.log('message', message)
47+
if (message === false) {
48+
setFailedSignUp(<p>Sorry, your sign up failed. Please try a different username or email</p>)
49+
} else {
50+
console.log('in frontend', username)
51+
// setUser(username);
52+
navigate('/login');
53+
alert('USER CREATED: PLEASE LOG IN')
54+
}
55+
}).catch(error => {
3856
console.error('Failed to sign up:', error);
3957
setFailedSignUp(<p>Sorry, your sign up failed. Please try again later</p>);
4058
});
@@ -49,13 +67,13 @@ const SignUp:React.FC = React.memo(() => {
4967

5068
<form className="form" onSubmit={handleSubmit}>
5169
<label className="username">
52-
<input type="text" name="username" id="username" placeholder="enter username" />
70+
<input type="text" name="username" id="username" minLength={4} placeholder="enter username" />
5371
</label>
5472
<label className="email">
5573
<input type="email" name="email" id="email" placeholder="[email protected]" />
5674
</label>
5775
<label className="password">
58-
<input type="password" name="password" id="password" placeholder="enter password" />
76+
<input type="password" name="password" id="password" minLength={9} placeholder="enter password" />
5977
</label>
6078
<label className="passwordConfirm">
6179
<input type="password" name="passwordConfirm" id="passwordConfirm" placeholder="confirm password" />

app/components/Splash.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import React, { useState, useEffect } from 'react';
22
import '../stylesheets/Splash.scss';
33

4+
//Chronos logo when first starting the electron app. Has the picture for 4 seconds.
45
const Splash: React.FC = React.memo(props => {
56
const [visible, setVisible] = useState(true);
67

78
useEffect(() => {
8-
setTimeout(() => setVisible(false), 4000);
9+
setTimeout(() => setVisible(false), 1000);
910
}, []);
1011

1112
return (

app/containers/AWSGraphsContainer.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,7 @@ const AwsGraphsContainer: React.FC = React.memo(props => {
125125
)}
126126
{typeOfService === 'AWS/EKS' && (
127127
<div>
128-
{/* <iframe src={`${awsUrl}/d/8jYcvsBVz/kubernetes-cluster-monitoring-via-prometheus?orgId=1&refresh=10s&theme=light&kiosk`} width="1300" height="1300" ></iframe> */}
129-
{/* <iframe src={`${awsUrl}/d/jPEGwyfVk/opencost?orgId=1&theme=light&kiosk`} width="1300" height="1300" ></iframe> */}
130-
131-
<iframe src={`http://a9921cff905094aa0a45e6e330684283-98913978.us-east-2.elb.amazonaws.com/d/8jYcvsBVz/kubernetes-cluster-monitoring-via-prometheus?orgId=1&refresh=10s&theme=light&kiosk`} width="1300" height="1300" ></iframe>
132-
<iframe src={`http://a9921cff905094aa0a45e6e330684283-98913978.us-east-2.elb.amazonaws.com/d/jPEGwyfVk/opencost?orgId=1&theme=light&kiosk`} width="1300" height="1300" ></iframe>
133-
134-
{/* <GrafanaIFrame {...awsAppInfo}/> */}
128+
<iframe src={`${awsEksData}?orgId=1&refresh=10s&theme=light&kiosk`} width="1300" height="1300" ></iframe>
135129
</div>
136130
)}
137131
</div>

app/containers/DashboardContainer.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,22 @@ import AwsContextProvider from '../context/AwsContext';
1313
import '../stylesheets/Dashboard.scss';
1414

1515
const DashboardContainer = React.memo(() => {
16+
1617
const [visible, setVisible] = useState(false);
1718

19+
/**
20+
* When DashBoard Container first mounted, visible is default to false, so that the Splash component can be stay visible.
21+
* After 4 seconds, set the DashBoard Container visibility to true
22+
*/
1823
useEffect(() => {
1924
setTimeout(() => setVisible(true), 4000);
2025
}, []);
2126

27+
/**
28+
* 1. Provide access to use ReactRouter
29+
* 2. Provide access to serveral Context Providers (a.k.a Data Bank), including Application, Dashboard, Comms, Docker, Health, Event, Query, Aws
30+
* 3. Child Component: SidebarContainer and MainContainer
31+
*/
2232
return (
2333
<>
2434
{visible && (

app/containers/GraphsContainer.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ const GraphsContainer: React.FC = React.memo(props => {
156156
};
157157

158158
const HealthAndEventButtons: JSX.Element[] = getHealthAndEventComponents();
159-
159+
console.log({GraphsContainer: selectedMetrics})
160+
console.log({GraphsContainer: chart});
160161
return (
161162
<>
162163
<nav id="navigationBar">

app/containers/HealthContainer.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ const HealthContainer: React.FC<HealthContainerProps> = React.memo(props => {
5151
const metric: string = Object.keys(serviceMetric)[0];
5252
const valueList = Object.values(serviceMetric)[0];
5353
const newTimeList: any = getTime(timelist, serviceName, metric, categoryName);
54-
// console.log('valueList is', valueList); -> 50 values in an array
55-
// console.log('newTimeList array is:', newTimeList); -> 50 values in an array
54+
// console.log('valueList is', valueList); //-> 50 values in an array
55+
// console.log('newTimeList array is:', newTimeList); //-> 50 values in an array
5656
if (selectedMetricsList.includes(metric)) {
5757
const re = /_/g;
5858
const newHealthChart = (

0 commit comments

Comments
 (0)