Skip to content

Commit 98a9450

Browse files
authored
Merge pull request #15 from oslabs-beta/elena/updatingToDB
Elena/updating to db
2 parents 964efce + f7a1caf commit 98a9450

File tree

17 files changed

+596
-585
lines changed

17 files changed

+596
-585
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/components/Occupied.tsx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,9 @@ const Occupied = React.memo(() => {
121121
selectedService === 'AWS/EKS'
122122
) {
123123
setAppIndex(i);
124-
// setApp is never invoked, function is not established?
125124
setApp(selectedApp);
126125
navigate(`/aws/:${app}`, { state: { typeOfService: selectedService } });
127126
} else {
128-
console.log('In handleClick Method (local) in Occupied.tsx');
129-
console.log('The following are the new values for appIndex, app, servicesData, and serviceModalOpen:');
130-
console.log(i, ' ', selectedApp, ' ', 'N/A ', serviceModalOpen );
131-
132127
setAppIndex(i);
133128
setApp(selectedApp);
134129
setServicesData([]);

app/components/SignUp.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ 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>(<></>);
1313
const [username, setUsername] = useState('');
1414
const [email, setEmail] = useState('');
1515
const [password, setPassword] = useState('');

app/context/ApplicationContext.tsx

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const { ipcRenderer } = window.require('electron');
99
* @property {Array} servicesData The microservices of that application
1010
* @method fetchServicesNames
1111
* @method connectToDB
12+
* @method getSavedMetrics
1213
*/
1314

1415
interface AppContextProps {
@@ -20,60 +21,35 @@ export const ApplicationContext = React.createContext<any>(null);
2021
const ApplicationContextProvider: React.FC<AppContextProps> = React.memo(props => {
2122
const children = props.children;
2223
const [servicesData, setServicesData] = useState([]);
23-
// v10 note: there is not function for setApp so app is never updated.
2424
const [app, setApp] = useState<string>('');
2525
const [savedMetrics, setSavedMetrics] = useState({});
2626
const [appIndex, setAppIndex] = useState<number>(0);
2727
const [intervalID, setIntervalID] = useState<NodeJS.Timeout | null>(null);
2828

29-
/**
30-
* @function tryParseJson - a function that will parse the JSON data into an object. If there is any error during parsing (a.k.a there is a circular inside the JSON data), console log the error
31-
* @param jsonString - JSON data that is received from backend
32-
* @return an object with all information from backend
33-
*/
34-
function tryParseJSON(jsonString: string) {
35-
try {
36-
const o = JSON.parse(jsonString);
37-
38-
if (o && typeof o === 'object') {
39-
return o;
40-
}
41-
} catch (e) {
42-
console.log({ error: e });
43-
}
44-
return false;
45-
}
4629

4730
/**
4831
* @function fetchServicesNames - a function that will take an application name and update the state of `serviceData` based on backend response
4932
* 1. Take in an application name
50-
*
5133
* 2. Send a `servicesRequest` to backend
52-
*
5334
* 3. Upon `servicesResponse`, parse the received JSON data and assign it to `servicesData`
54-
*
5535
* 4. Remove the listener for `servicesResponse`
5636
* @param application - application name
5737
*/
5838
// v10: Invoked by connectToDB, passing in app (card title)
5939
const fetchServicesNames = useCallback((application: string) => {
60-
console.log('Hi, inside ApplicationConext - fetchServicesNames callback. Sending servicesRequest to ipcMain.');
61-
console.log('app when fetch services name: ', application);
62-
// setApp(application);
63-
40+
// console.log('Hi, inside ApplicationConext - fetchServicesNames callback. Sending servicesRequest to ipcMain.');
41+
// console.log('app when fetch services name: ', application);
6442
ipcRenderer.send('servicesRequest');
65-
6643
ipcRenderer.on('servicesResponse', (event: Electron.Event, data: any) => {
6744
let result: any;
68-
// Parse JSON data into object
69-
// if (tryParseJSON(data)) result = JSON.parse(data);
7045
result = JSON.parse(data);
71-
console.log('result from ipcrenderer services response is: ', result);
72-
console.log('Calling setServicesData passing in above result. Current servicesData is the following: ', servicesData);
46+
// console.log('result from ipcrenderer services response is: ', result);
47+
// console.log('Calling setServicesData passing in above result. Current servicesData is the following: ', servicesData);
7348
setServicesData(result);
74-
console.log('Leaving fetchedServicesNames function.');
49+
// console.log('Leaving fetchedServicesNames function.');
7550
ipcRenderer.removeAllListeners('servicesResponse');
7651
});
52+
7753
}, []);
7854

7955
/**
@@ -88,7 +64,11 @@ const ApplicationContextProvider: React.FC<AppContextProps> = React.memo(props =
8864
ipcRenderer.removeAllListeners('databaseConnected');
8965
ipcRenderer.send('connect', username, index, URI, databaseType);
9066
ipcRenderer.on('databaseConnected', (event: Electron.Event, data: any) => {
91-
fetchServicesNames(application);
67+
if(data === true) {
68+
fetchServicesNames(application);
69+
} else {
70+
alert('Database connection is not valid.');
71+
}
9272
});
9373
}, []);
9474

@@ -132,3 +112,22 @@ const ApplicationContextProvider: React.FC<AppContextProps> = React.memo(props =
132112
});
133113

134114
export default ApplicationContextProvider;
115+
116+
117+
// /**
118+
// * @function tryParseJson - a function that will parse the JSON data into an object. If there is any error during parsing (a.k.a there is a circular inside the JSON data), console log the error
119+
// * @param jsonString - JSON data that is received from backend
120+
// * @return an object with all information from backend
121+
// */
122+
// function tryParseJSON(jsonString: string) {
123+
// try {
124+
// const o = JSON.parse(jsonString);
125+
126+
// if (o && typeof o === 'object') {
127+
// return o;
128+
// }
129+
// } catch (e) {
130+
// console.log({ error: e });
131+
// }
132+
// return false;
133+
// }

app/modals/ServicesModal.tsx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ const ServicesModal: React.FC<ServicesModalProps> = React.memo(({ i, app }) => {
2424
console.log('ServicesModal current props (index, app): ', i, ' ', app);
2525

2626
const { user, applications } = useContext(DashboardContext);
27-
console.log('user from Dashboard Context:', user);
28-
console.log('applications from Dashboard Context: ', applications);
29-
console.log('applications[i][2]: ', applications[i][2]);
3027
const { servicesData, connectToDB } = useContext(ApplicationContext);
3128
const [services, setServices] = useState<Array<string>>([]);
3229

@@ -45,8 +42,6 @@ const ServicesModal: React.FC<ServicesModalProps> = React.memo(({ i, app }) => {
4542
// adding database type to make connection and fetchServiceNames more efficient
4643
useEffect(() => {
4744
console.log('Hi, inside useEffect in ServicesModal. Calling connectToDB function.');
48-
console.log("Passing the following parameters for user, i, app, applications, ");
49-
console.log(user, ' ', i, ' ', app, ' ', applications, applications[i][1]);
5045
connectToDB(user, i, app, applications[i][2], applications[i][1]);
5146
}, [i]);
5247

electron/Main.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { app, BrowserWindow, ipcMain } from 'electron';
22
import './routes/dashboard';
33
import { clearGuestSettings } from './routes/dashboard';
44
import './routes/data';
5+
import './routes/cloudbased';
56
import path from 'path';
67

78
// Declare variable to be used as the application window

electron/databases/mongo.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import mongoose from 'mongoose';
22
// import { MongoError } from 'mongodb';
3-
const testURL = 'mongodb+srv://seconddbtest:[email protected]/?retryWrites=true&w=majority';
43
// Mongoose connection wrapped in function that takes the index of the selected database as the parameter. This index is used to target the correct database for querying.
54
const connectMongoose = async (i:number, URI: string) => {
65
try {
7-
// await mongoose.connection.close();
6+
await mongoose.connection.close();
87
const db = await mongoose.connect(URI);
98

109
return db;
@@ -13,14 +12,4 @@ const connectMongoose = async (i:number, URI: string) => {
1312
}
1413
};
1514

16-
// const connectMongoose = async (i: number, URI: string) => {
17-
// try {
18-
// const db2 = mongoose.createConnection(testURL);
19-
// console.log('connection to user provided db established..');
20-
// return db2;
21-
// } catch (error) {
22-
// console.log('Error connecting to second db... ', error);
23-
// }
24-
// }
25-
2615
export default connectMongoose;

electron/models/UserModel.ts

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,24 @@
1+
// INSERT URI TO MONGODB TO SET UP USER DATABASE
12
const MONGO_URI = 'mongodb+srv://seconddbtest:[email protected]/?retryWrites=true&w=majority';
2-
// import mongoose, { Schema, Document } from 'mongoose';
3-
4-
// export interface IService extends Document {
5-
// microservice: string;
6-
// interval: number;
7-
// }
83
const mongoose = require('mongoose')
94

10-
const db2 = mongoose.createConnection(MONGO_URI);
11-
console.log('establishing connection to database');
12-
// const connectToUserDB = async (URI: string) => {
13-
// console.log('connecting to user info db...')
14-
// return await mongoose.createConnection(URI);
15-
// }
5+
const db2 = mongoose.createConnection(MONGO_URI)
6+
// .then(() => {
7+
// console.log('Connected to User database...');
8+
// })
9+
// .catch(err => {
10+
// console.log('Error connecting to User database: ', err);
11+
// })
12+
// console.log('establishing connection to database');
1613

1714

1815
const userSchema = new mongoose.Schema({
19-
// User: {
2016
username: {type: String, required:true, unique: true},
2117
password: {type: String, required:true},
2218
email: String,
2319
services: [],
2420
mode: {type: String, default: 'light'}
25-
// },
2621
});
2722

28-
// export default mongoose.model<IService>('services', ServicesSchema);
29-
30-
// export default mongoose.model('User', userSchema);
3123
const UserModel = db2.model('users', userSchema);
32-
3324
module.exports = UserModel;

0 commit comments

Comments
 (0)