├── .gitignore ├── Dockerfile ├── Dockerfile-dev ├── README.md ├── __tests__ ├── enzyme.ts ├── enzyme.tsx ├── supertest.ts └── tests.ts ├── docker-compose-dev-hot.yml ├── docker-compose.yml ├── dummydbreq.js ├── package-lock.json ├── package.json ├── server ├── controllers │ ├── cookieController.ts │ ├── kafkaController.ts │ └── userController.ts ├── dataStructures │ ├── queue.js │ └── test.js ├── kafkaApplication │ ├── consumer.js │ ├── mockData.js │ ├── producer.js │ └── topic.js ├── models │ └── userModel.ts ├── routes │ ├── dbRouter.ts │ ├── kafkaRouter.ts │ └── userRouter.ts └── server.ts ├── src ├── components │ ├── App.tsx │ ├── Base │ │ ├── About.tsx │ │ ├── Home.tsx │ │ ├── Login.tsx │ │ └── Signup.tsx │ ├── Dual.tsx │ ├── Line.tsx │ ├── Line2.tsx │ ├── Navbar.tsx │ ├── Testing.tsx │ ├── Testing2.tsx │ ├── UserPage │ │ ├── AccountInfo.tsx │ │ ├── AddTopicCard.tsx │ │ ├── BrokerCard.tsx │ │ ├── BrokerDetails.tsx │ │ ├── BrokerOverview.tsx │ │ ├── Gallery.tsx │ │ ├── LeadMetrics.tsx │ │ ├── LeftNav.tsx │ │ ├── MessageMetrics.tsx │ │ ├── SessionHistory.tsx │ │ ├── TopNav.tsx │ │ ├── UserPage.tsx │ │ ├── consumerMetrics.tsx │ │ └── producerMetrics.tsx │ ├── Vis.tsx │ ├── Vis2.tsx │ └── goodnessgracious │ │ ├── Library.tsx │ │ ├── Line.tsx │ │ ├── LineChart.tsx │ │ ├── Vis2.tsx │ │ └── types.ts ├── favicon.png ├── index.html ├── index.tsx └── styles.scss ├── tsconfig.json └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | # Extra ignores 107 | build/ 108 | package-lock 109 | 110 | # error log 111 | myapp.log 112 | 113 | #mock data 114 | mockData.js -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:14.17 2 | WORKDIR /usr/src/app 3 | COPY . . 4 | RUN npm install 5 | RUN npm run build 6 | EXPOSE 3000 7 | #CMD [ "node", "./server/server.js"] 8 | CMD ["npm", "start"] -------------------------------------------------------------------------------- /Dockerfile-dev: -------------------------------------------------------------------------------- 1 | FROM node:14.17 2 | RUN npm install webpack -g 3 | WORKDIR /usr/src/app 4 | COPY package*.json ./ 5 | RUN npm install 6 | EXPOSE 8080 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # deKaf 2 | 3 | ### What is it? 4 | 5 | 6 | As streaming grows increasingly common, data processing and real-time analytics become more of a necessity — but Kafka has no built-in functionality allowing users to view key performance metrics. deKaf bridges that gap: it's a web-based metrics visualization tool that monitors Kafka activity, focusing on performance and spread relevant metrics of the producers, topics, and consumers. 7 | 8 | ### How it works 9 | deKaf prides itself on simplicity. On the same server you have a kafka instance running, follow these steps. 10 | 1. In the browser navigate to deKaf.app. 11 | 2. Follow the prompts to create an account and log in. You will be redirected to the Broker Overview page. 12 | 3. Enter your port number the kafka instance is running on and click on **_Add Port_**. 13 | 4. Enter the topic you wish you to monitor, the number of partitions on the specified topic and the replication factor for your data. Click on **_Add Topic To Monitor_** 14 | 15 | *You may enter as many topics as you wish to monitor* 16 | 5. If you do not have any data being sent to your producer but you still want to test your kakfa cluster, simply click the **_generate random data_** check box. We will generate mock data and send it to your produce for you. 17 | 6. Once all the data has been enter, click **_View Metrics_** 18 | 19 | ![](https://i.imgur.com/NoIubOI.png) 20 | 21 | ### Our Metrics 22 | After entering the information you will be taken to our metrics overview page where live data will be rendered. Here we have seperated the metrics into four categories. 23 | 24 | ***Topic Data:*** 25 | Once topic tab is clicked you will see the following data: 26 | - Topic Names 27 | - Partitions in each topic 28 | - Quantity of messages within each partition 29 | 30 | [![Topic](https://i.imgur.com/176BayR.png)](https://i.imgur.com/kxPydsD.mp4) 31 | *Click on image to see live data rendering* 32 | 33 | ***Messages:*** 34 | Once the messages tab is clicked you will see the following data: 35 | - Latest message sent to the specified topic 36 | - Partition the message was sent to 37 | - Total messages within that consumer 38 | 39 | ***Consumer:*** 40 | Once the consumer tab is clicked you will see the following data: 41 | - Total messages recieved by that consumer 42 | - Message quantity over time 43 | - Message sizes 44 | 45 | [![Consumer](https://i.imgur.com/J9dlbp3.png)](https://i.imgur.com/PpvJQgY.mp4) 46 | *Click on image to see live data rendering* 47 | 48 | 49 | ***Producer:*** 50 | Once the producer tab is clicked you will see the following data: 51 | - Total messages sent by the producer 52 | - Message quantity over time 53 | - Message sizes 54 | 55 | [![Producer](https://i.imgur.com/LBGDuCA.png)](https://i.imgur.com/LZ52PHN.mp4) 56 | *Click on image to see live data rendering* 57 | 58 | 59 | % Focal Techs incorporated % 60 | 61 | React Hooks/Router, SCSS/CSS, D3, Typescript, Kafka w/ KafkaJS, Docker, AWS 62 | - Testing: Enzyme, Supertest 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /__tests__/enzyme.ts: -------------------------------------------------------------------------------- 1 | // import React from 'react' 2 | // import {shallow} from 'enzyme' 3 | 4 | // //================================================== 5 | // // @ts-ignore 6 | // import Vis from '../src/components/Vis.tsx' 7 | // // @ts-ignore 8 | // import Vis2 from '../src/components/Vis2.tsx' 9 | // // @ts-ignore 10 | // import Line from '../src/components/Line' 11 | // import { isExportDeclaration, textSpanContainsPosition } from 'typescript' 12 | 13 | //================================================== 14 | 15 | describe('', () => { 16 | let component 17 | 18 | beforeEach(() => { 19 | component = shallow() 20 | }) 21 | 22 | test('Should mount', () => { 23 | expect(component.length).toBe(1) 24 | }) 25 | 26 | }) 27 | 28 | describe('', () => { 29 | let component 30 | 31 | beforeEach(() => { 32 | component = shallow() 33 | }) 34 | 35 | test('Should mount', () => { 36 | expect(component.length).toBe(1) 37 | }) 38 | 39 | }) 40 | 41 | describe('', () => { 42 | let component 43 | 44 | beforeEach(() => { 45 | component = shallow() 46 | }) 47 | 48 | test('Should mount', () => { 49 | expect(component.length).toBe(1) 50 | }) 51 | 52 | }) -------------------------------------------------------------------------------- /__tests__/enzyme.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { configure, shallow, mount } from 'enzyme'; 3 | import MemoryRouter from 'react-router-dom'; 4 | import Adapter from '@wojtekmaj/enzyme-adapter-react-17'; 5 | import toJson from 'enzyme-to-json'; 6 | 7 | import UserPage from '../src/components/UserPage/UserPage'; 8 | import LeftNav from '../src/components/UserPage/LeftNav'; 9 | import Gallery from '../src/components/UserPage/Gallery'; 10 | import BrokerDetails from '../src/components/UserPage/BrokerDetails'; 11 | 12 | configure({ adapter: new Adapter() }); 13 | 14 | describe('Hello, Enzyme!', () => { 15 | it('renders', () => { 16 | const wrapper = shallow(
17 |

Hello, Enzyme!

18 |
); 19 | expect(wrapper.find('h1').html()).toMatch(/Hello, Enzyme/); 20 | }); 21 | }); 22 | 23 | describe('React unit tests', () => { 24 | describe('UserPage', () => { 25 | let wrapper; 26 | 27 | beforeAll(() => { 28 | wrapper = shallow() 29 | }); 30 | 31 | it('Renders a
tag with id user-wrapper', () => { 32 | expect(wrapper.type()).toEqual('div'); 33 | expect(wrapper.find('#user-wrapper')); 34 | }); 35 | }); 36 | 37 | describe('LeftNav', () => { 38 | let wrapper; 39 | 40 | beforeAll(() => { 41 | wrapper = shallow() 42 | }); 43 | 44 | it('Renders a