Skip to content

Commit 24761bd

Browse files
committed
Merge branch 'dev' of https://github.com/Chronos2-0/Chronos into dev
2 parents c9d97c1 + 4304d7c commit 24761bd

18 files changed

Lines changed: 1275 additions & 960 deletions

.DS_Store

6 KB
Binary file not shown.

Main.js

Lines changed: 68 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
const { app, BrowserWindow, ipcMain } = require('electron');
1+
//node requirements
2+
const { dialog, app, BrowserWindow, ipcMain } = require('electron');
23
const fs = require('fs');
34
const path = require('path');
45
const connectSQL = require('./model/sql-connect');
@@ -8,132 +9,165 @@ const HealthInfoSchema = require('./model/mongoose-healthInfoSchema');
89

910
//declare a variable pool for SQL connection
1011
let pool;
12+
13+
//declare win variable ---> Ousman
1114
let win;
15+
16+
//declaring a createWindow function ---> Ousman
1217
function createWindow() {
18+
//assign win to an instance of a new browser window.
1319
win = new BrowserWindow({
20+
//giving our window its width
1421
width: 900,
22+
//giving our window its hieght
1523
height: 800,
24+
//specify the path of the icon -- Which icon is this?.. note too tsure --> Ousman
1625
icon: path.join(__dirname, 'app/assets/icons/icon.png'),
26+
//enable node inegreation --> node intgeration, default is usally false --> Ousman
1727
webPreferences: {
1828
nodeIntegration: true,
1929
},
2030
});
2131

2232
// Development
33+
//loads our application window to localHost 8080, application will not render without this loadUrl --> Ousman
2334
win.loadURL('http://localhost:8080/');
2435

2536
// Production
2637
// win.loadURL(`file://${path.join(__dirname, './dist/index.html')}`);
27-
38+
39+
//assign window to null on close
2840
win.on('closed', () => {
2941
win = null;
3042
});
3143
}
44+
45+
//invoke createWindow function on Electron application load --> Ousman
3246
app.on('ready', createWindow);
3347

48+
// quits the application when all windows are closed --> Ousman
3449
app.on('window-all-closed', () => {
50+
//process platform is a property that return a string identifying the OS platform on which NodeJs process is running --> Ousman
3551
if (process.platform !== 'darwin') {
52+
//quits application
3653
app.quit();
3754
}
3855
});
3956

57+
//event 'activate' emmitted upon application starting
4058
app.on('activate', () => {
59+
//if there is no window present invoke the create window function --> Ousman
4160
if (win === null) {
4261
createWindow();
4362
}
4463
});
4564

4665
// Load settings JSON and returns current setup status back to the render process.
66+
//ipc 'setup' route --> Ousman
4767
ipcMain.on('setup', (message) => {
68+
//assigns state to the returned the object returned from settings.json --> Ousman
4869
const state = JSON.parse(
70+
//read json from settings.json
4971
fs.readFileSync(path.resolve(__dirname, './user/settings.json'), {
5072
encoding: 'UTF-8',
5173
}),
5274
);
53-
const { setupRequired } = state;
75+
//destructure setupRequired from state constant ---> Ousman
76+
const { setupRequired } = state;
77+
//assigning message object a property of return value and assigning it the setupRequired from state destructuring --> Ousman
5478
message.returnValue = setupRequired;
5579
});
5680

5781
// Loads existing settings JSON and update settings to include new services entered by the user.
82+
//on ipc 'submit' request --> Ousman
5883
ipcMain.on('submit', (message, newService) => {
59-
// set the variable 'state' to the contents of /user/settings.json
60-
// contents => "setupRequired" (boolean),"services" (Array)
61-
// setupRequired- toggle the page for adding database
62-
// services - name of DB stores dbType, and uri
84+
//assigning state to the parsed return of setting
6385
const state = JSON.parse(
6486
fs.readFileSync(path.resolve(__dirname, './user/settings.json'), {
6587
encoding: 'UTF-8',
6688
}),
6789
);
68-
// if statement is used to replace hard coded data. Hard coded data is needed to avoid a load error caused by Electron querying the database before a user has added or selected a database.
90+
// if statement is used to replace hard coded data. Hard coded data and the michelleWasHere key is needed to avoid a load error caused by Electron querying the database before a user has added or selected a database.
91+
92+
//*** What is happening here --> Ousman */
6993
if (state.setupRequired) {
7094
state.setupRequired = false;
7195
state.services = [JSON.parse(newService)];
72-
//is updating the /user/settings.json file with the first new service
7396
fs.writeFileSync(path.resolve(__dirname, './user/settings.json'), JSON.stringify(state));
7497
} else {
75-
//what is the new service?
7698
state.setupRequired = false;
7799
state.services.push(JSON.parse(newService));
78-
//is updating the /user/settings.json file with the new service
79100
fs.writeFileSync(path.resolve(__dirname, './user/settings.json'), JSON.stringify(state));
80101
}
81102
});
82103

83104
// Load settings JSON and returns updated state back to the render process.
105+
//on ipc 'dashboard' request --> Ousman
84106
ipcMain.on('dashboard', (message) => {
107+
//assign state to the parsed return of setting --> Ousman
85108
const state = JSON.parse(
86109
fs.readFileSync(path.resolve(__dirname, './user/settings.json'), {
87110
encoding: 'UTF-8',
88111
}),
89112
);
90-
//getting the array of databases [name, dbType, uri]
113+
//destructure services from state... what is services? --> Ousman
91114
const { services } = state;
92-
//creates an array of the database names
93115
const dashboardList = services.reduce((acc, curVal) => {
94116
acc.push(curVal[0]);
95117
return acc;
96118
}, []);
97-
//returns the array of the database names
98119
message.returnValue = dashboardList;
99120
});
100121

101122
// Queries the database for communications information and returns it back to the render process.
102123
ipcMain.on('overviewRequest', (message, index) => {
103-
//acquires the services from user settings.json file
104124
const services = JSON.parse(
105125
fs.readFileSync(path.resolve(__dirname, './user/settings.json'), { encoding: 'UTF-8' }),
106-
).services
126+
).services;
127+
107128
const databaseType = services[index][1];
108129
const URI = services[index][2];
109130

110131
if (databaseType === 'MongoDB') {
111-
connectMongoose(index,URI);
132+
connectMongoose(index, URI);
112133
CommunicationSchema.find({}, (err, data) => {
113134
if (err) {
114135
console.log(`An error occured while querying the database: ${err}`);
115-
return message.sender.send('overviewResponse', JSON.stringify(err));
116-
}
117-
//queryResults is an array of objects with the following keys {"_id","currentMicroservice","targetedEndpoint","reqType","timeSent","resStatus","resMessage","__v"}
118-
const queryResults = JSON.stringify(data);
119-
120-
// Asynchronous event emitter used to transmit query results back to the render process.
121-
return message.sender.send('overviewResponse', queryResults);
136+
message.sender.send('overviewResponse', JSON.stringify(err));
137+
}
138+
139+
const queryResults = JSON.stringify(data);
140+
// Asynchronous event emitter used to transmit query results back to the render process.
141+
message.sender.send('overviewResponse', queryResults);
142+
122143
});
123144
}
124-
145+
125146
if (databaseType === 'SQL') {
126-
pool = connectSQL(index,URI);
147+
pool = connectSQL(index, URI);
127148
const getCommunications = 'SELECT * FROM communications';
128149
pool.query(getCommunications, (err, result) => {
129150
if (err) {
130-
return message.sender.send(JSON.stringify('Database info could not be retrieved.'));
151+
152+
//error object to log to Electron GUI ---> Ousman
153+
const errorAlert = {
154+
type: "error",
155+
title: "Error in Main process",
156+
message: "Database information could not be retreived. Check that table exists."
157+
};
158+
159+
//after requiring dialog in the topmost section of main. We invoke the method showMessagebox passing the error object we created --> Ousman
160+
dialog.showMessageBox(errorAlert);
161+
162+
163+
message.sender.send(JSON.stringify('Database info could not be retreived.'));
164+
165+
} else {
166+
console.log('Connected to SQL Database')
167+
const queryResults = JSON.stringify(result.rows);
168+
// Asynchronous event emitter used to transmit query results back to the render process.
169+
message.sender.send('overviewResponse', queryResults);
131170
}
132-
console.log('Connected to SQL Database')
133-
//queryResults is an array of objects with the following keys {"id","currentmicroservice","targetedendpoint","reqtype","resstatus","resmessage","timesent"}
134-
const queryResults = JSON.stringify(result.rows);
135-
// Asynchronous event emitter used to transmit query results back to the render process.
136-
return message.sender.send('overviewResponse', queryResults);
137171
});
138172
}
139173
});
@@ -151,21 +185,19 @@ ipcMain.on('detailsRequest', (message, index) => {
151185
}
152186
const queryResults = JSON.stringify(data);
153187
// Asynchronous event emitter used to transmit query results back to the render process.
154-
return message.sender.send('detailsResponse', queryResults);
188+
message.sender.send('detailsResponse', queryResults);
155189
});
156190
}
157191

158192
if (databaseType === 'SQL') {
159-
160-
// const pool = connectSQL(index);
161193
const getHealth = 'SELECT * FROM healthInfo';
162194
pool.query(getHealth, (err, result) => {
163195
if (err) {
164196
message.sender.send('detailsResponse', JSON.stringify('Database info could not be retreived.'));
165197
}
166198
const queryResults = JSON.stringify(result.rows);
167199
// Asynchronous event emitter used to transmit query results back to the render process.
168-
return message.sender.send('detailsResponse', queryResults);
200+
message.sender.send('detailsResponse', queryResults);
169201
});
170202
}
171203
});

README.md

Lines changed: 51 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,76 @@
1-
# Chronos
2-
Chronos consists of an NPM package to be required into a user’s microservices that intercepts all http and gRPC microservice communications, as well as monitors the health of each microservice over time. This information is written to a user-owned database (PostgreSQL or NoSQL) where it is queried and rendered by the frontend utilizing Node in conjunction with a native, cross-platform Electron desktop application with React components to ensure agreement between the frontend and database.
1+
## Chronos Microservice Debugger
2+
Chronos Microservice Debugger consists of an npm package with an optional Electron front end to visualize information collected through use of npm package.
33

4-
## Why was Chronos created?
5-
As companies grow larger and begin to scale, they have a tendency to move from a monolithic code architecture and microservices and distributed systems architecture in order to build faster, more maintainable code.
6-
7-
The process of modularizing a code bases and breaking a monolith into individual services can be a daunting task. How do you break apart and re-connect these services? There is often a transitional period where valuable time is spent debugging these connections between services.
8-
9-
Chronos is deigned to meet the needs of companies and developers working to break down their monoliths into distributed systems by combining an NPM package together with an Electron application to monitor and assist in the debugging of their services.
10-
11-
## How to Install Chronos
12-
The Chronos-Microservice-Debugger Express Middleware can be found on npm: https://www.npmjs.com/package/chronos-microservice-debugger
13-
14-
To install the NPM package:
4+
## Install
155
```javascript
16-
npm install chronos-microservice-debugger
6+
npm install chronos-microservice-debugger3
177
```
18-
19-
The Chronos Electron application is in progress and will soon be availble for public download for all platforms. Please stay tuned.
20-
21-
## How to Use Chronos
8+
## Usage
229
There are two main aspects to Chronos-Microservice-Debugger
2310
1. Communication Monitor: Listens in on all microservice-microservice and microservice-client communication and monitors the response statuses and messages to ensure communications are making it to the correct destination successfully.
24-
2. Health Monitor: The health monitor checks the status of your microservice every second and sends this health information to an optional electron frontend where it is visualized for easier use.
2511

26-
To use the npm package, there are three required parameters and an optional fourth parameter. You can enter the items as individual strings or as an array containing the three required parameters and one optional parameter.
12+
2. Health Monitor: The health monitor checks the status of your microservice every second and sends this health information to an optional electron frontend where it is visualized for easier use.
13+
To use the npm package, there are four required parameters and an optional fifth parameter. You can enter the items as individual strings or as an array containing the three required parameters and one optional parameter.
2714

2815
The parameters are:
2916
1. microserviceName: What do you want to name the current microservice
30-
2. databaseType: We currently support PostgreSQL and Mongo. Enter "mongo" or "sql"
17+
2. databaseType: We currently support PostgreSQL and Mongo. Enter mongo or sql
3118
3. databaseURL: Where would you like to store your information? Enter the URL to your database
32-
4. queryFrequency: How often do you want microHealth to monitor the health of your database? It defaults to every second, but you can choose:
33-
* "s" : The default, monitors every second
34-
* "m" : Monitors every minute
35-
* "h" : Monitors every hour
36-
* "d" : Monitors once per day
37-
* "w" : Monitors once per week
38-
19+
4. wantMicroHealth: Do you want the microHealth of your microservice to be monitor? Enter “yes” or “no”
20+
5. queryFrequency: How often do you want microHealth to monitor the health of your database? It defaults to every minute, but you can choose:
21+
* “s” : Monitors every second
22+
* “m” : The default, monitors every minute
23+
* “h” : Monitors every hour
24+
* “d” : Monitors once per day
25+
* “w” : Monitors once per week
26+
3927
String parameter example:
4028
```javascript
41-
// How to use chronos-microservice-debugger
42-
app.use('/', chronos-microservice-debgugger.microCom('microserviceName', 'databaseType', 'databaseURL'))
43-
44-
chronos-microservice-debugger.microHealth('microserviceName', 'databaseType', 'databaseURL', 'queryFrequency'))
45-
29+
// How to use chronos-microservice-debugger3
30+
// Place the following two lines before requiring express
31+
const cmd = require(‘chronos-microservice-debugger3’);
32+
cmd.propagate();
33+
// Place the following line of code before the microservice re-routes the request (for string parameters)
34+
app.use(‘/’, cmd.microCom(‘microserviceName’, ‘databaseType’, ‘databaseURL’,‘wantMicroHealth’,‘queryFrequency’))
35+
// Or place the following line of code before the microservice re-routes the request (for array parameter)
36+
app.use(‘/’, cmd.microCom([‘microserviceName’, ‘databaseType’, ‘databaseURL’,‘wantMicroHealth’,‘queryFrequency’]))
4637
// Example using string parameters
47-
app.use('/', chronos-microservice-debugger.microCom('books', 'sql', 'thisIsMyURL'))
48-
// Note: microCom does not utilize queryFreq because it logs all communication when an endpoint is hit
49-
50-
chronos-microservice-debugger.microHealth('books', 'sql', 'thisIsMyURL', 'h')
38+
app.use(‘/’, cmd.microCom(‘books’, ‘sql’, ‘thisIsMyURL’,‘yes’, ‘m’))
5139
```
52-
5340
Array parameter example:
5441
```javascript
5542
let values = [
56-
'microserviceName',
57-
'databaseType',
58-
'databaseURL',
59-
'queryFrequency'
43+
‘microserviceName’,
44+
‘databaseType’,
45+
‘databaseURL’,
46+
‘wantMicroHealth’,
47+
‘queryFrequency’
6048
]
61-
// How to use chronos-micrservice-debugger with an array parameter
62-
app.use('/', chronos-microservice-debgugger.microCom(values)
63-
64-
chronos-microservice-debugger.microHealth(values)
65-
49+
// How to use chronos-micrservice-debugger2 with an array parameter
50+
app.use(‘/’, cmd.microCom(values)
6651
// Example using an array parameter
6752
let values = [
68-
'books',
69-
'mongo',
70-
'thisIsMyNewURL',
71-
'w'
53+
‘books’,
54+
‘mongo’,
55+
‘thisIsMyNewURL’,
56+
‘yes’,
57+
‘w’
7258
]
59+
app.use(‘/’, cmd.microCom(values)
60+
```
61+
Chronos uses a user-owned and provided database to ensure that your private data stays private. We currently support MongoDB and SQL/PostgreSQL databases.
7362
74-
app.use('/', chronos-microservice-debgugger.microCom(values)
75-
// Note: microCom does not utilize queryFreq because it logs all communication when an endpoint is hit
76-
77-
chronos-microservice-debugger.microHealth(values)
63+
## Things in the Works
64+
1. gRPC support
65+
3. ‘Time Travel’ to see how your microservices have changed over time
66+
4. Docker health information for containerized microservices
67+
5. Implement additional unit testing
68+
6. Published Electron application with cross-browser compatibility
69+
7. Microservice Architecture Visualizer
7870
79-
```
71+
## Links
72+
1. Gitub Page: https://github.com/Chronos2-0/Chronos
8073
81-
## How to Contribute to Chronos
82-
Chronos hopes to inspire an active community of both users and developers. For questions, comments, suggestions, please contact us at teammicronos@gmail.com or submit a pull request.
74+
## Contact Us
75+
For questions, requests, or more information, please contact us at chronosjobtc@gmail.com
8376
84-
## Created By
85-
* Duane McFarlane
86-
* Michelle Herrera
87-
* Mohtasim Chowdhury
88-
* Natalie Umanzor

app/.DS_Store

6 KB
Binary file not shown.

app/charts/latency-chart.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { useContext } from 'react';
22
import { Line } from 'react-chartjs-2';
33
import HealthContext from '../context/DetailsContext';
44

5-
const LatencyChart = (props) => {
5+
const LatencyChart = (props) => {
66
const xAxis = [];
77
const yAxis = [];
88
const healthData = useContext(HealthContext).detailData;

app/charts/response-code-chart.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import CommunicationsContext from '../context/OverviewContext';
44

55
const ResponseCodeChart = (props) => {
66
const communicationsData = useContext(CommunicationsContext).overviewData;
7+
8+
79

810
const createChart = () => {
911
const responseCodes = {

0 commit comments

Comments
 (0)