├── .babelrc ├── .dockerignore ├── .gitignore ├── App.tsx ├── Dockerfile ├── LICENSE ├── README.md ├── __tests__ └── Example.js ├── client ├── GraphData.ts ├── assets │ ├── PulsarLogoSVG.svg │ ├── networkScreenshot.png │ ├── ppdemogif.gif │ ├── pulsarLogo.png │ └── space.jpg ├── components │ ├── Display.tsx │ ├── Graph.tsx │ ├── GraphMenu.tsx │ └── Navbar.tsx ├── index.html ├── styles │ └── styles.scss └── types.ts ├── compose.yml ├── imageConfigs ├── grafana │ ├── Dockerfile │ ├── grafana.ini │ └── provisioning │ │ ├── dashboards │ │ ├── backlog.json │ │ ├── countGauge.json │ │ ├── dashboard.yml │ │ ├── jetty.json │ │ ├── messageRateIn.json │ │ ├── messageRateOut.json │ │ ├── messagesin.json │ │ ├── messagesout.json │ │ ├── throughputin.json │ │ ├── throughputout.json │ │ ├── topicsandsubscriptions.json │ │ └── usageGauge.json │ │ └── datasources │ │ └── srcProm.yml └── prometheus │ ├── Dockerfile │ └── config │ └── prometheus.yml ├── index.html ├── index.tsx ├── package-lock.json ├── package.json ├── server └── server.ts ├── tsconfig.json └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-react", "@babel/preset-env", "@babel/preset-typescript"], 3 | "env": { 4 | "test": { 5 | "plugins": ["@babel/plugin-transform-modules-commonjs"] 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /imageConfigs/grafana/data 3 | /imageConfigs/prometheus/promData 4 | oggrafdata/ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .vscode 4 | /imageConfigs/grafana/data 5 | /imageConfigs/prometheus/promData 6 | oggrafdata/ -------------------------------------------------------------------------------- /App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Display from './client/components/Display'; 3 | import Navbar from './client/components/Navbar'; 4 | 5 | const App = () => { 6 | return ( 7 | <> 8 |

PulsarPortrait

9 |
10 |
11 | {' '} 12 | {' '} 13 |
14 |
15 | {' '} 16 | {' '} 17 |
18 |
19 | 20 | ); 21 | }; 22 | 23 | export default App; 24 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:latest 2 | 3 | WORKDIR /app 4 | 5 | COPY package*.json ./ 6 | 7 | RUN npm install 8 | 9 | COPY . . 10 | 11 | RUN npm run build 12 | 13 | ENV PORT=3333 14 | 15 | EXPOSE 3333 16 | 17 | ENTRYPOINT ["node", "./server/server.ts"] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 OSLabs Beta 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | logo 3 |

4 | 5 | # PulsarPortrait 6 | https://pulsarportrait.io/ 7 | 8 | ## About 9 | 10 |
11 | 12 | ![React](https://img.shields.io/badge/react-%2320232a.svg?style=for-the-badge&logo=react&logoColor=%2361DAFB) 13 | ![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white) 14 | ![Javascript](https://img.shields.io/badge/javascript-yellow?style=for-the-badge&logo=javascript) 15 | ![HTML5 Badge](https://img.shields.io/badge/HTML5-E34F26?logo=html5&logoColor=fff&style=for-the-badge) 16 | ![Sass Badge](https://img.shields.io/badge/Sass-C69?logo=sass&logoColor=fff&style=for-the-badge) 17 | ![node](https://img.shields.io/badge/nodejs-forestgreen?style=for-the-badge&logo=nodedotjs&logoColor=black) 18 | ![Express.js](https://img.shields.io/badge/express.js-%23404d59.svg?style=for-the-badge&logo=express&logoColor=%2361DAFB) 19 | ![Docker](https://img.shields.io/badge/docker-%230db7ed.svg?style=for-the-badge&logo=docker&logoColor=white) 20 | ![Prometheus](https://img.shields.io/badge/Prometheus-E6522C?style=for-the-badge&logo=Prometheus&logoColor=white) 21 | ![Grafana](https://img.shields.io/badge/grafana-%23F46800.svg?style=for-the-badge&logo=grafana&logoColor=white) 22 | ![Webpack](https://img.shields.io/badge/webpack-%238DD6F9.svg?style=for-the-badge&logo=webpack&logoColor=black) 23 | ![Jest](https://img.shields.io/badge/-jest-%23C21325?style=for-the-badge&logo=jest&logoColor=white) 24 | ![Apache Pulsar Badge](https://img.shields.io/badge/Apache%20Pulsar-188FFF?logo=apachepulsar&logoColor=fff&style=for-the-badge) 25 | 26 |
27 | 28 | PulsarPortrait is an open-source application that illustrates the current health of your Pulsar cluster. By scraping data from Prometheus metrics, the app can display a variety of graphs, gauges, and counters. From message data to jetty response times, users can choose from eleven visualizations and frame them in any of the six display slots. 29 | 30 |

31 | 32 |

33 | 34 |
35 | 36 | ## Getting Started 37 | 38 | ### Option 1 - Add PulsarPortrait to your compose.yml file 39 | 40 | Simply copy and paste the following code into the services dictionary of your compose.yml file. Please note that if your network is not pulsar, you will need to change it in the networks section of each service. 41 | 42 | ```yml 43 | prometheus: 44 | image: pulsarportrait/prometheus:latest 45 | container_name: prometheus 46 | networks: 47 | - pulsar 48 | ports: 49 | - '9090:9090' 50 | 51 | pulsarportrait: 52 | image: pulsarportrait/app:latest 53 | container_name: pulsarportrait 54 | networks: 55 | - pulsar 56 | ports: 57 | - '3333:3333' 58 | 59 | grafana: 60 | image: pulsarportrait/grafana:latest 61 | container_name: grafana 62 | networks: 63 | - pulsar 64 | ports: 65 | - '2222:3000' 66 | depends_on: 67 | - prometheus 68 | ``` 69 | 70 | ### Option 2 - Use this repo 71 | 72 | if you already have a project with Pulsar and do not wish to edit the compose.yml file, you can follow these steps: 73 | 74 | - Fork and clone this repo 75 | - Start your Pulsar culster 76 | - In this repo, add your Pulsar cluster's network to the compose.yml file, if you are unsure of the name of your network, you can run docker network ls 77 | 78 | logo 79 | 80 | - Lastly, run docker compose up -d, and PulsarPortrait will be available on http://localhost:3333/ 81 | 82 |
83 | 84 | ## Contributions 85 | We welcome feedback and contributions to this project. If you want to add a feature or fix a bug, please follow these steps: 86 | - Fork and clone this repo 87 | - Create your feature branch by running 88 | ```zsh 89 | git checkout -b your-feature-branch-name 90 | ``` 91 | - Add, commit, and push your changes up to GitHub 92 | - Lastly, make a pull request detailing your changes 93 | 94 |
95 | 96 | ## Authors 97 | 98 | - Grant Thomas [GitHub](https://github.com/GrantCT) | [LinkedIn](https://www.linkedin.com/in/grantcthomas/) 99 | - Cyrux Lam [GitHub](https://github.com/cyduckk) | [LinkedIn](https://www.linkedin.com/in/cyrux-lam/) 100 | - Anthony Le [GitHub](https://github.com/anthonyle910) | [LinkedIn](https://www.linkedin.com/in/anthony-le-616b4b101/) 101 | - Jordan Zolman [Github](https://github.com/PrincePuggo) | [LinkedIn](https://www.linkedin.com/in/jordanzolman) 102 | 103 |
104 | 105 | ## License 106 | - PulsarPortrait is MIT Licensed -------------------------------------------------------------------------------- /__tests__/Example.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import "@testing-library/jest-dom"; 3 | import { render, screen } from "@testing-library/react"; 4 | import {describe, expect, test} from '@jest/globals' 5 | import Example from '../client/components/Example' 6 | 7 | describe("example", () => { 8 | it("should have the text example", () => { 9 | render( 10 |
11 | 12 |
13 | ); 14 | expect(screen.getByTestId('testid')).toHaveTextContent('example'); 15 | }); 16 | }); 17 | 18 | describe('sum', () => { 19 | test('adds 1 + 2 to equal 3', () => { 20 | expect(1 + 2).toBe(3); 21 | }); 22 | }); -------------------------------------------------------------------------------- /client/GraphData.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | messagesIn: 3 | 'http://localhost:2222/d/c2ef0e4a-da28-4797-bd86-5c1957aa9039/newmessagesin?orgId=1&refresh=5s&viewPanel=1&viewPanel=1&kiosk', 4 | messagesOut: 5 | 'http://localhost:2222/d/b7cc76a7-51f0-4175-bbbc-dada7ec3fa2d/messagesout?orgId=1&refresh=5s&viewPanel=1&kiosk', 6 | backlog: 7 | 'http://localhost:2222/d/d20d409b-6974-4ca4-b16c-fc74c6aa7cd1/newbacklog?orgId=1&refresh=5s&viewPanel=1&kiosk', 8 | topicsAndSubscriptions: 9 | 'http://localhost:2222/d/c8268214-d094-46d5-9a25-7cce1192ae69/topicsandsubscriptions?orgId=1&refresh=5s&viewPanel=1&kiosk', 10 | memoryUsage: 11 | 'http://localhost:2222/d/a6f621d3-bb3c-4569-8315-2e0c4b2de35b/new-dashboard?orgId=1&refresh=5s&viewPanel=1&kiosk', 12 | activeConnections: 13 | 'http://localhost:2222/d/d79b197c-2abe-4e1b-b16e-0fa10b0656a4/test?orgId=1&refresh=5s&viewPanel=1&kiosk', 14 | jettyrequesttime: 15 | 'http://localhost:2222/d/e11221ec-7d82-47ec-a3b1-5356e4f63c6b/jettyrequesttime?orgId=1&refresh=5s&viewPanel=1&kiosk', 16 | throughputIn: 17 | 'http://localhost:2222/d/bdfb696f-55e4-46da-aa3d-381b5cf2f408/throughputin?orgId=1&refresh=5s&viewPanel=1&kiosk', 18 | throughputOut: 19 | 'http://localhost:2222/d/b1f5eb24-9c75-4ba3-a40b-7bf8e1ccdc94/throughtputout?orgId=1&refresh=5s&viewPanel=1&kiosk', 20 | messageRateIn: 21 | 'http://localhost:2222/d/a9961e9a-b44a-42c1-a855-427e3825b04c/broker-rate-in?orgId=1&refresh=5s&viewPanel=1&kiosk', 22 | messageRateOut: 23 | 'http://localhost:2222/d/b9031b09-082f-4dc6-9b82-766c5e543328/message-rate-out?orgId=1&refresh=5s&viewPanel=1&kiosk', 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /client/assets/networkScreenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/PulsarPortrait/9c89aa552eb662569dd5d401843c0b1f8d70163c/client/assets/networkScreenshot.png -------------------------------------------------------------------------------- /client/assets/ppdemogif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/PulsarPortrait/9c89aa552eb662569dd5d401843c0b1f8d70163c/client/assets/ppdemogif.gif -------------------------------------------------------------------------------- /client/assets/pulsarLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/PulsarPortrait/9c89aa552eb662569dd5d401843c0b1f8d70163c/client/assets/pulsarLogo.png -------------------------------------------------------------------------------- /client/components/Display.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Graph from './Graph' 3 | 4 | // move graph data to graph component, set an array of 6 graph data key's and assign that index to the key value of each graph being pushed. set initial state 5 | // to be equal to a position in that array. Have graph render new URL based on setUrl setState defined in graphMenu. 6 | 7 | export default function Display() { 8 | 9 | const graphArr: React.JSX.Element[] = []; 10 | 11 | for (let i = 0; i < 6; i++) { 12 | graphArr.push() 13 | } 14 | 15 | return ( 16 |
17 | {graphArr} 18 |
19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /client/components/Graph.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import GraphMenu from './GraphMenu'; 3 | import { useState } from 'react'; 4 | import GraphData from '../GraphData'; 5 | import { URLS } from '../types'; 6 | 7 | type GraphProps = { 8 | index: number; 9 | } 10 | 11 | export default function Graph({ index }: GraphProps) { 12 | const data: URLS = GraphData; 13 | 14 | const graphDataArray: string[] = [ 15 | data['messagesIn'], 16 | data['messagesOut'], 17 | data['backlog'], 18 | data['activeConnections'], 19 | data['memoryUsage'], 20 | data['topicsAndSubscriptions'], 21 | ]; 22 | const graphNameArray: string[] = [ 23 | 'Messages In', 24 | 'Messages Out', 25 | 'Backlog', 26 | 'Producer/Consumer Count', 27 | 'Memory Usage', 28 | 'Topics and Subscriptions', 29 | ] 30 | 31 | const [name, setName] = useState(graphNameArray[index]); 32 | const [url, setUrl] = useState(graphDataArray[index]); 33 | 34 | return ( 35 |
36 | 37 | 38 |
39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /client/components/GraphMenu.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import Button from '@mui/material/Button'; 3 | import Menu from '@mui/material/Menu'; 4 | import MenuItem from '@mui/material/MenuItem'; 5 | import Fade from '@mui/material/Fade'; 6 | import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; 7 | import GraphData from '../GraphData'; 8 | import { useState } from 'react'; 9 | import { URLS } from '../types'; 10 | 11 | 12 | interface GraphMenuProps { 13 | name: string; 14 | setName: Function; 15 | setUrl: Function 16 | } 17 | 18 | export default function GraphMenu({ name, setName, setUrl}: GraphMenuProps) { 19 | 20 | const data: URLS = GraphData//GraphData(); 21 | 22 | const [anchorEl, setAnchorEl] = React.useState(null); 23 | const open: boolean = Boolean(anchorEl); 24 | 25 | const handleClick = (event: React.MouseEvent): void => { 26 | setAnchorEl(event.currentTarget); 27 | }; 28 | 29 | const handleClose = (): void => { 30 | setAnchorEl(null); 31 | }; 32 | 33 | const changeGraph = (e: React.BaseSyntheticEvent) => { 34 | const { id } = e.target; 35 | let temp; 36 | 37 | switch(id) { 38 | case data['activeConnections']: temp = 'active Connections'; 39 | break; 40 | case data['backlog']: temp = 'backlog'; 41 | break; 42 | case data['jettyrequesttime']: temp = 'jetty request time'; 43 | break; 44 | case data['memoryUsage']: temp = 'memory Usage'; 45 | break; 46 | case data['messagesIn']: temp = 'messages In'; 47 | break; 48 | case data['messagesOut']: temp = 'messages Out'; 49 | break; 50 | case data['messageRateIn']: temp = 'message Rate In'; 51 | break; 52 | case data['messageRateOut']: temp = 'message Rate Out'; 53 | break; 54 | case data['throughputIn']: temp = 'throughput In'; 55 | break; 56 | case data['throughputOut']: temp = 'throughput Out'; 57 | break; 58 | case data['topicsAndSubscriptions']: temp = 'topics And Subscriptions'; 59 | break; 60 | } 61 | 62 | setUrl(id); 63 | setName(temp); 64 | setAnchorEl(null); 65 | }; 66 | 67 | return ( 68 |
69 | 80 | 96 | 97 | Active Connections 98 | 99 | 100 | Backlog 101 | 102 | 103 | Jetty Request Time 104 | 105 | 106 | Memory Usage 107 | 108 | 109 | Messages In 110 | 111 | 112 | Messages Out 113 | 114 | 115 | Message Rate In 116 | 117 | 118 | Message Rate Out 119 | 120 | 121 | Throughput in 122 | 123 | 124 | Throughput out 125 | 126 | 127 | Topics and Subscriptions 128 | 129 | 130 |
131 | ); 132 | } 133 | -------------------------------------------------------------------------------- /client/components/Navbar.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import HomeIcon from '@mui/icons-material/Home'; 3 | import SettingsIcon from '@mui/icons-material/Settings'; 4 | import InfoIcon from '@mui/icons-material/Info'; 5 | import { Button } from '@mui/material'; 6 | 7 | export default function Navbar() { 8 | return ( 9 |
10 | 11 | 12 | 13 |
14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Pulsar Portrait 8 | 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /client/styles/styles.scss: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Anonymous+Pro&family=Courier+Prime&family=Geologica:wght@300&family=Manrope:wght@300&family=Nunito+Sans&display=swap'); 2 | @import url('https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap'); 3 | @import url('https://fonts.googleapis.com/css2?family=Bebas+Neue&family=Russo+One&display=swap'); 4 | 5 | * { 6 | margin: 0; 7 | padding: 0; 8 | box-sizing: border-box; 9 | } 10 | 11 | #heading { 12 | color: white; 13 | text-align: center; 14 | margin-bottom: 0px; 15 | font-size: 50pt; 16 | } 17 | 18 | html, body { 19 | height: 100%; 20 | } 21 | 22 | body { 23 | background-color: grey; 24 | font-family: 'Russo One', sans-serif; 25 | // background-image: url("https://steamuserimages-a.akamaihd.net/ugc/1678120729579339650/40A46978EF29C7099912D8CA459BBC9FAC764F2E/?imw=5000&imh=5000&ima=fit&impolicy=Letterbox&imcolor=#000000&letterbox=false"); 26 | // background-image: url("https://media.discordapp.net/attachments/1120822627880144916/1126580577835954176/puggo_blue_and_purple_colored_background_with_purple_and_blue_l_0b542b64-a0ac-4990-8ccb-e3d89df2bc6a.png"); 27 | // background-repeat: no-repeat; 28 | background-size: cover; 29 | // background-position: 50% 50%; 30 | // image-rendering: pixelated; 31 | // background-size: cover; 32 | // height: 100vh; 33 | // width: 100vw; 34 | 35 | display: flex; 36 | flex-direction: column; 37 | 38 | // background-image: url("https://media.discordapp.net/attachments/1086022677422153820/1125576700042948709/puggo_an_image_in_the_style_of_a_graphic_designer_of_four_infor_1227d67b-eec8-460a-8d0e-35c0a7c029bc.png?width=1138&height=1138"); 39 | } 40 | 41 | #root { 42 | margin-top: 0px; 43 | display: flex; 44 | flex-direction: column; 45 | // justify-content: center; 46 | align-items: center; 47 | height: 100%; 48 | // min-height: 100%; 49 | // border: 1px solid pink; 50 | } 51 | .app-display { 52 | // margin: 2.5rem; 53 | // border: 1px solid blue; 54 | display: flex; 55 | flex-direction: row; 56 | flex-grow: 1; 57 | // border: 1px solid black; 58 | // min-height: 90vh; 59 | // width: 95vw; 60 | width: 95%; 61 | // height: 95%; 62 | border-radius: 5px; 63 | // margin-bottom: 20px; 64 | } 65 | 66 | .navbar { 67 | display: flex; 68 | justify-content: center; 69 | // border: 1px solid green; 70 | background-color: purple; 71 | border-radius: 5px; 72 | // width: 5rem; 73 | .nav-buttons { 74 | color: white; 75 | padding: 5px; 76 | margin-bottom: 10px; 77 | margin-top: 5px; 78 | } 79 | .nav-buttons:hover { 80 | background-color: rgba(158, 98, 190, 0.686); 81 | cursor: pointer; 82 | } 83 | // svg:hover { 84 | // width: 2.5rem; 85 | // cursor: pointer; 86 | // border-radius: 6px; 87 | // } 88 | // svg:hover { 89 | // width: 2.5rem; 90 | // cursor: pointer; 91 | // border-radius: 6px; 92 | // } 93 | } 94 | 95 | .body { 96 | // display: flex; 97 | // flex-direction: row; 98 | // border: 1px solid blue; 99 | // width: 99vw; 100 | // background-color: rgb(60, 60, 60); 101 | width: 100%; 102 | height: 100%; 103 | background: linear-gradient(91.7deg, rgb(50, 25, 79) -4.3%, rgb(50, 25, 83) 101.8%); 104 | border-top-right-radius: 5px; 105 | border-bottom-right-radius: 5px; 106 | border-radius: 5px; 107 | // border: 1px solid green; 108 | 109 | } 110 | 111 | // .display-container { 112 | // display: flex; 113 | // flex-direction: row; 114 | // flex-wrap: wrap; 115 | // justify-content: space-between; 116 | // // height: 90vh; 117 | // gap: 1rem; 118 | // border-radius: 5px; 119 | // padding-left: 3rem; 120 | // padding-right: 3rem; 121 | // padding-top: 2rem; 122 | // padding-bottom: 1rem; 123 | // // border: 2px solid pink; 124 | // } 125 | 126 | .display-container { 127 | display: grid; 128 | width: 100%; 129 | // flex-direction: row; 130 | // flex-wrap: wrap; 131 | // justify-content: space-between; 132 | // height: 90vh; 133 | // gap: 1rem; 134 | height:100%; 135 | 136 | grid-template-columns: 1fr 1fr; 137 | grid-template-rows: repeat(3, 1fr); 138 | 139 | // grid-template-columns: 1fr 1fr; 140 | // grid-template-rows: repeat(6, 1fr); 141 | border-radius: 5px; 142 | // padding-left: 3rem; 143 | // padding-right: 3rem; 144 | // padding-top: 2rem; 145 | // padding-bottom: 1rem; 146 | // border: 2px solid pink; 147 | } 148 | 149 | 150 | 151 | .graph-container { 152 | // border: 1px solid red; 153 | position: relative; 154 | // padding: 1rem; 155 | padding: .5rem; 156 | // width: 100%; 157 | } 158 | // .Graph { 159 | // // background-color: maroon; 160 | // // display: flex; 161 | // flex-grow: 1; 162 | // border-radius: 5px; 163 | // // display: grid; 164 | // // grid-row: auto; 165 | // color: white; 166 | // // margin: 1rem; 167 | // // height: 8vh; 168 | // // width: 90vw; 169 | // // width: 90%; 170 | // // border: 2px solid white; 171 | // // overflow-y: hidden; 172 | // } 173 | 174 | #home-button { 175 | // height: 200%; 176 | // width: 200% 177 | // size: 35; 178 | color: white; 179 | } 180 | 181 | .navbar-content { 182 | display: flex; 183 | flex-direction: column; 184 | justify-content: flex-start; 185 | align-items: center; 186 | border-top-left-radius: 5px; 187 | border-bottom-left-radius: 5px; 188 | // min-width: 3rem; 189 | // background: radial-gradient(circle at 24.1% 68.8%, rgb(24, 24, 24) 0%, rgb(0, 0, 0) 99.4%); 190 | background: radial-gradient(circle at 15% 25%, rgb(66, 66, 66) 0%, rgb(30, 30, 30) 99.4%); 191 | 192 | // background: linear-gradient(76.8deg, rgb(121, 45, 129) 3.6%, rgb(36, 31, 98) 90.4%); 193 | // height: 100%; 194 | } 195 | 196 | .chart { 197 | // height: 20vh; 198 | // width: 90vw; 199 | // height: 270px; 200 | min-height: 220px; 201 | // width: 55rem; 202 | // min-height: 250px; 203 | height: 100%; 204 | width: 100%; 205 | border-radius: 8px; 206 | overflow: hidden; 207 | } 208 | // @media screen and (max-width: 2012.5px) { 209 | // // .chart { 210 | // // width: 90vw; 211 | // // } 212 | // } 213 | 214 | @media screen and (max-width: 1100px) { 215 | // .chart { 216 | // width: 90vw; 217 | // } 218 | .display-container { 219 | grid-template-columns: 1fr; 220 | grid-template-rows: repeat(6, 1fr); 221 | 222 | } 223 | .app-display { 224 | // height: 100%; 225 | // margin-top: 10px; 226 | min-height: 1600px 227 | } 228 | #root { 229 | // height: 100vh; 230 | // min-height: 2000px; 231 | } 232 | 233 | } 234 | 235 | // @media screen and (min-width: 2000px) { 236 | // .graph-container { 237 | // padding: 20rem; 238 | // background-color: aqua; 239 | // } 240 | // } 241 | 242 | 243 | 244 | 245 | 246 | .graph-container { 247 | // border: 1px solid red; 248 | position: relative; 249 | // padding: 1rem; 250 | padding: .5rem; 251 | // width: 100%; 252 | } 253 | #fade-button { 254 | background-color: rgba(85, 85, 86, 0.775); 255 | color: white 256 | } 257 | 258 | .MuiList-root { 259 | // background-color: rgba(67, 67, 67, 0.775); 260 | // color: white; 261 | padding-left: 20px; 262 | } 263 | 264 | #graph-container1, 265 | #graph-container2 { 266 | position: relative; 267 | } 268 | 269 | .menu { 270 | // top: 5px; 271 | // right: 50px; 272 | position: absolute; 273 | 274 | } 275 | 276 | -------------------------------------------------------------------------------- /client/types.ts: -------------------------------------------------------------------------------- 1 | export type URLS = { 2 | [key: string]: string 3 | } -------------------------------------------------------------------------------- /compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | networks: 3 | pulsar-network: 4 | # Write the name of your pulsar-network here 5 | name: 6 | external: true 7 | 8 | services: 9 | prometheus: 10 | image: pulsarportrait/prometheus:latest 11 | container_name: prometheus 12 | networks: 13 | - pulsar-network 14 | ports: 15 | - '9090:9090' 16 | volumes: 17 | - ./imageConfigs/prometheus/promData:/prometheus 18 | 19 | grafana: 20 | image: pulsarportrait/grafana:latest 21 | container_name: grafana 22 | networks: 23 | - pulsar-network 24 | ports: 25 | - "2222:3000" 26 | depends_on: 27 | - prometheus 28 | 29 | pulsarportrait: 30 | image: pulsarportrait/app:latest 31 | container_name: pulsarportrait 32 | networks: 33 | - pulsar-network 34 | ports: 35 | - '3333:3333' -------------------------------------------------------------------------------- /imageConfigs/grafana/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM grafana/grafana 2 | 3 | COPY ./provisioning/dashboards /etc/grafana/provisioning/dashboards 4 | COPY ./provisioning/datasources /etc/grafana/provisioning/datasources 5 | COPY ./grafana.ini /etc/grafana/grafana.ini 6 | 7 | ENV GF_PATHS_CONFIG='/etc/grafana/grafana.ini' 8 | ENV GF_AUTH_ANONYMOUS_ENABLED='true' 9 | -------------------------------------------------------------------------------- /imageConfigs/grafana/grafana.ini: -------------------------------------------------------------------------------- 1 | [server] 2 | allow_embedding = true 3 | [security] 4 | allow_embedding = true 5 | [plugins] 6 | plugins = boomtheme-panel 7 | enable_alpha = true -------------------------------------------------------------------------------- /imageConfigs/grafana/provisioning/dashboards/backlog.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": { 7 | "type": "grafana", 8 | "uid": "-- Grafana --" 9 | }, 10 | "enable": true, 11 | "hide": true, 12 | "iconColor": "rgba(0, 211, 255, 1)", 13 | "name": "Annotations & Alerts", 14 | "type": "dashboard" 15 | } 16 | ] 17 | }, 18 | "editable": true, 19 | "fiscalYearStartMonth": 0, 20 | "graphTooltip": 0, 21 | "id": 12, 22 | "links": [], 23 | "liveNow": false, 24 | "panels": [ 25 | { 26 | "datasource": { 27 | "type": "prometheus", 28 | "uid": "PBFA97CFB590B2093" 29 | }, 30 | "fieldConfig": { 31 | "defaults": { 32 | "color": { 33 | "fixedColor": "dark-purple", 34 | "mode": "fixed" 35 | }, 36 | "custom": { 37 | "axisCenteredZero": false, 38 | "axisColorMode": "text", 39 | "axisLabel": "", 40 | "axisPlacement": "auto", 41 | "barAlignment": 0, 42 | "drawStyle": "line", 43 | "fillOpacity": 14, 44 | "gradientMode": "opacity", 45 | "hideFrom": { 46 | "legend": false, 47 | "tooltip": false, 48 | "viz": false 49 | }, 50 | "lineInterpolation": "smooth", 51 | "lineWidth": 1, 52 | "pointSize": 5, 53 | "scaleDistribution": { 54 | "type": "linear" 55 | }, 56 | "showPoints": "auto", 57 | "spanNulls": false, 58 | "stacking": { 59 | "group": "A", 60 | "mode": "none" 61 | }, 62 | "thresholdsStyle": { 63 | "mode": "off" 64 | } 65 | }, 66 | "mappings": [], 67 | "thresholds": { 68 | "mode": "absolute", 69 | "steps": [ 70 | { 71 | "color": "green", 72 | "value": null 73 | }, 74 | { 75 | "color": "red", 76 | "value": 80 77 | } 78 | ] 79 | } 80 | }, 81 | "overrides": [] 82 | }, 83 | "gridPos": { 84 | "h": 8, 85 | "w": 12, 86 | "x": 0, 87 | "y": 0 88 | }, 89 | "id": 1, 90 | "options": { 91 | "legend": { 92 | "calcs": [], 93 | "displayMode": "list", 94 | "placement": "bottom", 95 | "showLegend": false 96 | }, 97 | "tooltip": { 98 | "mode": "single", 99 | "sort": "none" 100 | } 101 | }, 102 | "targets": [ 103 | { 104 | "datasource": { 105 | "type": "prometheus", 106 | "uid": "PBFA97CFB590B2093" 107 | }, 108 | "editorMode": "builder", 109 | "expr": "pulsar_broker_msg_backlog", 110 | "instant": false, 111 | "range": true, 112 | "refId": "A" 113 | } 114 | ], 115 | "title": " ", 116 | "transparent": true, 117 | "type": "timeseries" 118 | } 119 | ], 120 | "refresh": "5s", 121 | "schemaVersion": 38, 122 | "style": "dark", 123 | "tags": [], 124 | "templating": { 125 | "list": [] 126 | }, 127 | "time": { 128 | "from": "now-5m", 129 | "to": "now" 130 | }, 131 | "timepicker": {}, 132 | "timezone": "", 133 | "title": "newbacklog", 134 | "uid": "d20d409b-6974-4ca4-b16c-fc74c6aa7cd1", 135 | "version": 9, 136 | "weekStart": "" 137 | } -------------------------------------------------------------------------------- /imageConfigs/grafana/provisioning/dashboards/countGauge.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": { 7 | "type": "grafana", 8 | "uid": "-- Grafana --" 9 | }, 10 | "enable": true, 11 | "hide": true, 12 | "iconColor": "rgba(0, 211, 255, 1)", 13 | "name": "Annotations & Alerts", 14 | "type": "dashboard" 15 | } 16 | ] 17 | }, 18 | "editable": true, 19 | "fiscalYearStartMonth": 0, 20 | "graphTooltip": 0, 21 | "id": 6, 22 | "links": [], 23 | "liveNow": false, 24 | "panels": [ 25 | { 26 | "datasource": { 27 | "type": "prometheus", 28 | "uid": "PBFA97CFB590B2093" 29 | }, 30 | "description": "", 31 | "fieldConfig": { 32 | "defaults": { 33 | "color": { 34 | "mode": "thresholds" 35 | }, 36 | "mappings": [], 37 | "thresholds": { 38 | "mode": "absolute", 39 | "steps": [ 40 | { 41 | "color": "dark-purple", 42 | "value": null 43 | } 44 | ] 45 | }, 46 | "unit": "short" 47 | }, 48 | "overrides": [ 49 | { 50 | "matcher": { 51 | "id": "byName", 52 | "options": "pulsar_broker_producers_count" 53 | }, 54 | "properties": [ 55 | { 56 | "id": "displayName", 57 | "value": "Producers" 58 | } 59 | ] 60 | }, 61 | { 62 | "matcher": { 63 | "id": "byName", 64 | "options": "pulsar_broker_consumers_count" 65 | }, 66 | "properties": [ 67 | { 68 | "id": "displayName", 69 | "value": "Consumers" 70 | } 71 | ] 72 | } 73 | ] 74 | }, 75 | "gridPos": { 76 | "h": 8, 77 | "w": 12, 78 | "x": 0, 79 | "y": 0 80 | }, 81 | "id": 1, 82 | "options": { 83 | "colorMode": "background", 84 | "graphMode": "none", 85 | "justifyMode": "center", 86 | "orientation": "auto", 87 | "reduceOptions": { 88 | "calcs": ["lastNotNull"], 89 | "fields": "", 90 | "values": false 91 | }, 92 | "textMode": "auto" 93 | }, 94 | "pluginVersion": "10.0.2", 95 | "targets": [ 96 | { 97 | "datasource": { 98 | "type": "prometheus", 99 | "uid": "PBFA97CFB590B2093" 100 | }, 101 | "editorMode": "builder", 102 | "expr": "pulsar_broker_producers_count", 103 | "format": "time_series", 104 | "instant": false, 105 | "legendFormat": "{{label_name}}", 106 | "range": true, 107 | "refId": "A" 108 | }, 109 | { 110 | "datasource": { 111 | "type": "prometheus", 112 | "uid": "PBFA97CFB590B2093" 113 | }, 114 | "editorMode": "builder", 115 | "exemplar": false, 116 | "expr": "pulsar_broker_consumers_count", 117 | "format": "time_series", 118 | "hide": false, 119 | "instant": false, 120 | "interval": "", 121 | "legendFormat": "", 122 | "range": true, 123 | "refId": "B" 124 | } 125 | ], 126 | "title": " ", 127 | "transparent": true, 128 | "type": "stat" 129 | } 130 | ], 131 | "refresh": "5s", 132 | "schemaVersion": 38, 133 | "style": "dark", 134 | "tags": [], 135 | "templating": { 136 | "list": [] 137 | }, 138 | "time": { 139 | "from": "now-6h", 140 | "to": "now" 141 | }, 142 | "timepicker": {}, 143 | "timezone": "", 144 | "title": "test", 145 | "uid": "d79b197c-2abe-4e1b-b16e-0fa10b0656a4", 146 | "version": 14, 147 | "weekStart": "" 148 | } 149 | -------------------------------------------------------------------------------- /imageConfigs/grafana/provisioning/dashboards/dashboard.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | providers: 4 | - name: 'Prometheus' 5 | orgId: 1 6 | folder: '' 7 | type: file 8 | disableDeletion: false 9 | editable: false 10 | allowUiUpdates: true 11 | options: 12 | path: /etc/grafana/provisioning/dashboards -------------------------------------------------------------------------------- /imageConfigs/grafana/provisioning/dashboards/jetty.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": { 7 | "type": "grafana", 8 | "uid": "-- Grafana --" 9 | }, 10 | "enable": true, 11 | "hide": true, 12 | "iconColor": "rgba(0, 211, 255, 1)", 13 | "name": "Annotations & Alerts", 14 | "type": "dashboard" 15 | } 16 | ] 17 | }, 18 | "editable": true, 19 | "fiscalYearStartMonth": 0, 20 | "graphTooltip": 0, 21 | "id": 5, 22 | "links": [], 23 | "liveNow": false, 24 | "panels": [ 25 | { 26 | "datasource": { 27 | "type": "prometheus", 28 | "uid": "PBFA97CFB590B2093" 29 | }, 30 | "fieldConfig": { 31 | "defaults": { 32 | "mappings": [], 33 | "thresholds": { 34 | "mode": "percentage", 35 | "steps": [ 36 | { 37 | "color": "green", 38 | "value": null 39 | }, 40 | { 41 | "color": "orange", 42 | "value": 70 43 | }, 44 | { 45 | "color": "red", 46 | "value": 85 47 | } 48 | ] 49 | }, 50 | "unit": "s" 51 | }, 52 | "overrides": [ 53 | { 54 | "matcher": { 55 | "id": "byName", 56 | "options": "jetty_request_time_seconds_total" 57 | }, 58 | "properties": [ 59 | { 60 | "id": "thresholds", 61 | "value": { 62 | "mode": "absolute", 63 | "steps": [ 64 | { 65 | "color": "green", 66 | "value": null 67 | }, 68 | { 69 | "color": "red", 70 | "value": 80 71 | } 72 | ] 73 | } 74 | }, 75 | { 76 | "id": "displayName", 77 | "value": "Total" 78 | } 79 | ] 80 | }, 81 | { 82 | "matcher": { 83 | "id": "byName", 84 | "options": "jetty_request_time_max_seconds" 85 | }, 86 | "properties": [ 87 | { 88 | "id": "displayName", 89 | "value": "Max" 90 | } 91 | ] 92 | } 93 | ] 94 | }, 95 | "gridPos": { 96 | "h": 6, 97 | "w": 9, 98 | "x": 0, 99 | "y": 0 100 | }, 101 | "id": 1, 102 | "options": { 103 | "orientation": "auto", 104 | "reduceOptions": { 105 | "calcs": [ 106 | "lastNotNull" 107 | ], 108 | "fields": "", 109 | "values": false 110 | }, 111 | "showThresholdLabels": false, 112 | "showThresholdMarkers": true 113 | }, 114 | "pluginVersion": "10.0.1", 115 | "targets": [ 116 | { 117 | "datasource": { 118 | "type": "prometheus", 119 | "uid": "PBFA97CFB590B2093" 120 | }, 121 | "editorMode": "builder", 122 | "expr": "jetty_request_time_max_seconds", 123 | "instant": false, 124 | "range": true, 125 | "refId": "A" 126 | }, 127 | { 128 | "datasource": { 129 | "type": "prometheus", 130 | "uid": "PBFA97CFB590B2093" 131 | }, 132 | "editorMode": "builder", 133 | "expr": "jetty_request_time_seconds_total", 134 | "hide": false, 135 | "instant": false, 136 | "range": true, 137 | "refId": "B" 138 | } 139 | ], 140 | "title": " ", 141 | "transparent": true, 142 | "type": "gauge" 143 | } 144 | ], 145 | "refresh": "5s", 146 | "schemaVersion": 38, 147 | "style": "dark", 148 | "tags": [], 149 | "templating": { 150 | "list": [] 151 | }, 152 | "time": { 153 | "from": "now-5m", 154 | "to": "now" 155 | }, 156 | "timepicker": {}, 157 | "timezone": "", 158 | "title": "jettyrequesttime", 159 | "uid": "e11221ec-7d82-47ec-a3b1-5356e4f63c6b", 160 | "version": 4, 161 | "weekStart": "" 162 | } -------------------------------------------------------------------------------- /imageConfigs/grafana/provisioning/dashboards/messageRateIn.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": { 7 | "type": "grafana", 8 | "uid": "-- Grafana --" 9 | }, 10 | "enable": true, 11 | "hide": true, 12 | "iconColor": "rgba(0, 211, 255, 1)", 13 | "name": "Annotations & Alerts", 14 | "type": "dashboard" 15 | } 16 | ] 17 | }, 18 | "editable": true, 19 | "fiscalYearStartMonth": 0, 20 | "graphTooltip": 0, 21 | "id": 10, 22 | "links": [], 23 | "liveNow": false, 24 | "panels": [ 25 | { 26 | "datasource": { 27 | "type": "prometheus", 28 | "uid": "PBFA97CFB590B2093" 29 | }, 30 | "description": "", 31 | "fieldConfig": { 32 | "defaults": { 33 | "color": { 34 | "fixedColor": "#cd10b3", 35 | "mode": "fixed" 36 | }, 37 | "custom": { 38 | "axisCenteredZero": false, 39 | "axisColorMode": "text", 40 | "axisLabel": "msg/sec", 41 | "axisPlacement": "auto", 42 | "barAlignment": 0, 43 | "drawStyle": "line", 44 | "fillOpacity": 14, 45 | "gradientMode": "none", 46 | "hideFrom": { 47 | "legend": false, 48 | "tooltip": false, 49 | "viz": false 50 | }, 51 | "lineInterpolation": "smooth", 52 | "lineWidth": 1, 53 | "pointSize": 5, 54 | "scaleDistribution": { 55 | "type": "linear" 56 | }, 57 | "showPoints": "auto", 58 | "spanNulls": false, 59 | "stacking": { 60 | "group": "A", 61 | "mode": "none" 62 | }, 63 | "thresholdsStyle": { 64 | "mode": "off" 65 | } 66 | }, 67 | "mappings": [], 68 | "thresholds": { 69 | "mode": "absolute", 70 | "steps": [ 71 | { 72 | "color": "semi-dark-blue", 73 | "value": null 74 | } 75 | ] 76 | } 77 | }, 78 | "overrides": [] 79 | }, 80 | "gridPos": { 81 | "h": 8, 82 | "w": 12, 83 | "x": 0, 84 | "y": 0 85 | }, 86 | "id": 1, 87 | "options": { 88 | "legend": { 89 | "calcs": [], 90 | "displayMode": "list", 91 | "placement": "bottom", 92 | "showLegend": false 93 | }, 94 | "tooltip": { 95 | "mode": "single", 96 | "sort": "none" 97 | } 98 | }, 99 | "targets": [ 100 | { 101 | "datasource": { 102 | "type": "prometheus", 103 | "uid": "PBFA97CFB590B2093" 104 | }, 105 | "editorMode": "builder", 106 | "expr": "pulsar_broker_rate_in", 107 | "instant": false, 108 | "range": true, 109 | "refId": "A" 110 | } 111 | ], 112 | "title": " ", 113 | "transparent": true, 114 | "type": "timeseries" 115 | } 116 | ], 117 | "refresh": "5s", 118 | "schemaVersion": 38, 119 | "style": "dark", 120 | "tags": [], 121 | "templating": { 122 | "list": [] 123 | }, 124 | "time": { 125 | "from": "now-5m", 126 | "to": "now" 127 | }, 128 | "timepicker": {}, 129 | "timezone": "", 130 | "title": "Broker rate in", 131 | "uid": "a9961e9a-b44a-42c1-a855-427e3825b04c", 132 | "version": 1, 133 | "weekStart": "" 134 | } 135 | -------------------------------------------------------------------------------- /imageConfigs/grafana/provisioning/dashboards/messageRateOut.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": { 7 | "type": "grafana", 8 | "uid": "-- Grafana --" 9 | }, 10 | "enable": true, 11 | "hide": true, 12 | "iconColor": "rgba(0, 211, 255, 1)", 13 | "name": "Annotations & Alerts", 14 | "type": "dashboard" 15 | } 16 | ] 17 | }, 18 | "editable": true, 19 | "fiscalYearStartMonth": 0, 20 | "graphTooltip": 0, 21 | "id": 10, 22 | "links": [], 23 | "liveNow": false, 24 | "panels": [ 25 | { 26 | "datasource": { 27 | "type": "prometheus", 28 | "uid": "PBFA97CFB590B2093" 29 | }, 30 | "fieldConfig": { 31 | "defaults": { 32 | "color": { 33 | "fixedColor": "#b70dc9", 34 | "mode": "fixed" 35 | }, 36 | "custom": { 37 | "axisCenteredZero": false, 38 | "axisColorMode": "text", 39 | "axisLabel": "msg/sec", 40 | "axisPlacement": "auto", 41 | "barAlignment": 0, 42 | "drawStyle": "line", 43 | "fillOpacity": 14, 44 | "gradientMode": "none", 45 | "hideFrom": { 46 | "legend": false, 47 | "tooltip": false, 48 | "viz": false 49 | }, 50 | "lineInterpolation": "smooth", 51 | "lineWidth": 1, 52 | "pointSize": 5, 53 | "scaleDistribution": { 54 | "type": "linear" 55 | }, 56 | "showPoints": "auto", 57 | "spanNulls": false, 58 | "stacking": { 59 | "group": "A", 60 | "mode": "none" 61 | }, 62 | "thresholdsStyle": { 63 | "mode": "off" 64 | } 65 | }, 66 | "mappings": [], 67 | "thresholds": { 68 | "mode": "absolute", 69 | "steps": [ 70 | { 71 | "color": "green", 72 | "value": null 73 | } 74 | ] 75 | } 76 | }, 77 | "overrides": [] 78 | }, 79 | "gridPos": { 80 | "h": 8, 81 | "w": 12, 82 | "x": 0, 83 | "y": 0 84 | }, 85 | "id": 1, 86 | "options": { 87 | "legend": { 88 | "calcs": [], 89 | "displayMode": "list", 90 | "placement": "bottom", 91 | "showLegend": false 92 | }, 93 | "tooltip": { 94 | "mode": "single", 95 | "sort": "none" 96 | } 97 | }, 98 | "targets": [ 99 | { 100 | "datasource": { 101 | "type": "prometheus", 102 | "uid": "PBFA97CFB590B2093" 103 | }, 104 | "editorMode": "builder", 105 | "expr": "pulsar_broker_rate_out", 106 | "instant": false, 107 | "range": true, 108 | "refId": "A" 109 | } 110 | ], 111 | "title": " ", 112 | "transparent": true, 113 | "type": "timeseries" 114 | } 115 | ], 116 | "refresh": "5s", 117 | "schemaVersion": 38, 118 | "style": "dark", 119 | "tags": [], 120 | "templating": { 121 | "list": [] 122 | }, 123 | "time": { 124 | "from": "now-5m", 125 | "to": "now" 126 | }, 127 | "timepicker": {}, 128 | "timezone": "", 129 | "title": "Message Rate out", 130 | "uid": "b9031b09-082f-4dc6-9b82-766c5e543328", 131 | "version": 2, 132 | "weekStart": "" 133 | } 134 | -------------------------------------------------------------------------------- /imageConfigs/grafana/provisioning/dashboards/messagesin.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": { 7 | "type": "grafana", 8 | "uid": "-- Grafana --" 9 | }, 10 | "enable": true, 11 | "hide": true, 12 | "iconColor": "rgba(0, 211, 255, 1)", 13 | "name": "Annotations & Alerts", 14 | "type": "dashboard" 15 | } 16 | ] 17 | }, 18 | "editable": true, 19 | "fiscalYearStartMonth": 0, 20 | "graphTooltip": 0, 21 | "id": 11, 22 | "links": [], 23 | "liveNow": false, 24 | "panels": [ 25 | { 26 | "datasource": { 27 | "type": "prometheus", 28 | "uid": "PBFA97CFB590B2093" 29 | }, 30 | "fieldConfig": { 31 | "defaults": { 32 | "color": { 33 | "mode": "palette-classic" 34 | }, 35 | "custom": { 36 | "axisCenteredZero": false, 37 | "axisColorMode": "text", 38 | "axisLabel": "", 39 | "axisPlacement": "auto", 40 | "barAlignment": 0, 41 | "drawStyle": "line", 42 | "fillOpacity": 14, 43 | "gradientMode": "opacity", 44 | "hideFrom": { 45 | "legend": false, 46 | "tooltip": false, 47 | "viz": false 48 | }, 49 | "lineInterpolation": "smooth", 50 | "lineWidth": 1, 51 | "pointSize": 5, 52 | "scaleDistribution": { 53 | "type": "linear" 54 | }, 55 | "showPoints": "auto", 56 | "spanNulls": false, 57 | "stacking": { 58 | "group": "A", 59 | "mode": "none" 60 | }, 61 | "thresholdsStyle": { 62 | "mode": "off" 63 | } 64 | }, 65 | "mappings": [], 66 | "thresholds": { 67 | "mode": "absolute", 68 | "steps": [ 69 | { 70 | "color": "green", 71 | "value": null 72 | }, 73 | { 74 | "color": "red", 75 | "value": 80 76 | } 77 | ] 78 | } 79 | }, 80 | "overrides": [ 81 | { 82 | "matcher": { 83 | "id": "byName", 84 | "options": "pulsar_in_messages_total{cluster=\"cluster-a\", instance=\"broker:8080\", job=\"pulsar\", namespace=\"public/default\", topic=\"persistent://public/default/my-topic\"}" 85 | }, 86 | "properties": [ 87 | { 88 | "id": "color", 89 | "value": { 90 | "fixedColor": "dark-purple", 91 | "mode": "fixed" 92 | } 93 | } 94 | ] 95 | }, 96 | { 97 | "matcher": { 98 | "id": "byName", 99 | "options": "pulsar_in_messages_total{cluster=\"cluster-a\", instance=\"broker:8080\", job=\"pulsar\", namespace=\"public/default\", topic=\"persistent://public/default/another-topic\"}" 100 | }, 101 | "properties": [ 102 | { 103 | "id": "color", 104 | "value": { 105 | "fixedColor": "dark-red", 106 | "mode": "fixed" 107 | } 108 | } 109 | ] 110 | } 111 | ] 112 | }, 113 | "gridPos": { 114 | "h": 8, 115 | "w": 12, 116 | "x": 0, 117 | "y": 0 118 | }, 119 | "id": 1, 120 | "options": { 121 | "legend": { 122 | "calcs": [], 123 | "displayMode": "list", 124 | "placement": "bottom", 125 | "showLegend": false 126 | }, 127 | "tooltip": { 128 | "mode": "single", 129 | "sort": "none" 130 | } 131 | }, 132 | "targets": [ 133 | { 134 | "datasource": { 135 | "type": "prometheus", 136 | "uid": "PBFA97CFB590B2093" 137 | }, 138 | "editorMode": "builder", 139 | "expr": "pulsar_in_messages_total{topic!=\"persistent://public/default/__change_events\"}", 140 | "instant": false, 141 | "range": true, 142 | "refId": "A" 143 | } 144 | ], 145 | "title": " ", 146 | "transparent": true, 147 | "type": "timeseries" 148 | } 149 | ], 150 | "refresh": "5s", 151 | "schemaVersion": 38, 152 | "style": "dark", 153 | "tags": [], 154 | "templating": { 155 | "list": [] 156 | }, 157 | "time": { 158 | "from": "now-5m", 159 | "to": "now" 160 | }, 161 | "timepicker": {}, 162 | "timezone": "", 163 | "title": "newmessagesin", 164 | "uid": "c2ef0e4a-da28-4797-bd86-5c1957aa9039", 165 | "version": 10, 166 | "weekStart": "" 167 | } -------------------------------------------------------------------------------- /imageConfigs/grafana/provisioning/dashboards/messagesout.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": { 7 | "type": "grafana", 8 | "uid": "-- Grafana --" 9 | }, 10 | "enable": true, 11 | "hide": true, 12 | "iconColor": "rgba(0, 211, 255, 1)", 13 | "name": "Annotations & Alerts", 14 | "type": "dashboard" 15 | } 16 | ] 17 | }, 18 | "editable": true, 19 | "fiscalYearStartMonth": 0, 20 | "graphTooltip": 0, 21 | "id": 10, 22 | "links": [], 23 | "liveNow": false, 24 | "panels": [ 25 | { 26 | "datasource": { 27 | "type": "prometheus", 28 | "uid": "PBFA97CFB590B2093" 29 | }, 30 | "fieldConfig": { 31 | "defaults": { 32 | "color": { 33 | "mode": "palette-classic" 34 | }, 35 | "custom": { 36 | "axisCenteredZero": false, 37 | "axisColorMode": "text", 38 | "axisLabel": "", 39 | "axisPlacement": "auto", 40 | "barAlignment": 0, 41 | "drawStyle": "line", 42 | "fillOpacity": 14, 43 | "gradientMode": "opacity", 44 | "hideFrom": { 45 | "legend": false, 46 | "tooltip": false, 47 | "viz": false 48 | }, 49 | "lineInterpolation": "smooth", 50 | "lineWidth": 1, 51 | "pointSize": 5, 52 | "scaleDistribution": { 53 | "type": "linear" 54 | }, 55 | "showPoints": "auto", 56 | "spanNulls": false, 57 | "stacking": { 58 | "group": "A", 59 | "mode": "none" 60 | }, 61 | "thresholdsStyle": { 62 | "mode": "off" 63 | } 64 | }, 65 | "mappings": [], 66 | "thresholds": { 67 | "mode": "absolute", 68 | "steps": [ 69 | { 70 | "color": "green", 71 | "value": null 72 | }, 73 | { 74 | "color": "red", 75 | "value": 80 76 | } 77 | ] 78 | } 79 | }, 80 | "overrides": [ 81 | { 82 | "matcher": { 83 | "id": "byName", 84 | "options": "pulsar_out_messages_total{cluster=\"cluster-a\", instance=\"broker:8080\", job=\"pulsar\", namespace=\"public/default\", subscription=\"my-subscription\", topic=\"persistent://public/default/another-topic\"}" 85 | }, 86 | "properties": [ 87 | { 88 | "id": "color", 89 | "value": { 90 | "fixedColor": "dark-red", 91 | "mode": "fixed" 92 | } 93 | } 94 | ] 95 | }, 96 | { 97 | "matcher": { 98 | "id": "byName", 99 | "options": "pulsar_out_messages_total{cluster=\"cluster-a\", instance=\"broker:8080\", job=\"pulsar\", namespace=\"public/default\", subscription=\"my-subscription\", topic=\"persistent://public/default/my-topic\"}" 100 | }, 101 | "properties": [ 102 | { 103 | "id": "color", 104 | "value": { 105 | "fixedColor": "dark-purple", 106 | "mode": "fixed" 107 | } 108 | } 109 | ] 110 | } 111 | ] 112 | }, 113 | "gridPos": { 114 | "h": 8, 115 | "w": 12, 116 | "x": 0, 117 | "y": 0 118 | }, 119 | "id": 1, 120 | "options": { 121 | "legend": { 122 | "calcs": [], 123 | "displayMode": "list", 124 | "placement": "bottom", 125 | "showLegend": false 126 | }, 127 | "tooltip": { 128 | "mode": "single", 129 | "sort": "none" 130 | } 131 | }, 132 | "targets": [ 133 | { 134 | "datasource": { 135 | "type": "prometheus", 136 | "uid": "PBFA97CFB590B2093" 137 | }, 138 | "editorMode": "builder", 139 | "expr": "pulsar_out_messages_total{topic!=\"persistent://public/default/__change_events\"}", 140 | "instant": false, 141 | "range": true, 142 | "refId": "A" 143 | } 144 | ], 145 | "title": " ", 146 | "transparent": true, 147 | "type": "timeseries" 148 | } 149 | ], 150 | "refresh": "5s", 151 | "schemaVersion": 38, 152 | "style": "dark", 153 | "tags": [], 154 | "templating": { 155 | "list": [] 156 | }, 157 | "time": { 158 | "from": "now-5m", 159 | "to": "now" 160 | }, 161 | "timepicker": {}, 162 | "timezone": "", 163 | "title": "messagesout", 164 | "uid": "b7cc76a7-51f0-4175-bbbc-dada7ec3fa2d", 165 | "version": 12, 166 | "weekStart": "" 167 | } -------------------------------------------------------------------------------- /imageConfigs/grafana/provisioning/dashboards/throughputin.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": { 7 | "type": "grafana", 8 | "uid": "-- Grafana --" 9 | }, 10 | "enable": true, 11 | "hide": true, 12 | "iconColor": "rgba(0, 211, 255, 1)", 13 | "name": "Annotations & Alerts", 14 | "type": "dashboard" 15 | } 16 | ] 17 | }, 18 | "editable": true, 19 | "fiscalYearStartMonth": 0, 20 | "graphTooltip": 0, 21 | "id": 8, 22 | "links": [], 23 | "liveNow": false, 24 | "panels": [ 25 | { 26 | "datasource": { 27 | "type": "prometheus", 28 | "uid": "PBFA97CFB590B2093" 29 | }, 30 | "fieldConfig": { 31 | "defaults": { 32 | "color": { 33 | "fixedColor": "semi-dark-blue", 34 | "mode": "fixed" 35 | }, 36 | "custom": { 37 | "axisCenteredZero": false, 38 | "axisColorMode": "text", 39 | "axisLabel": "", 40 | "axisPlacement": "auto", 41 | "barAlignment": 0, 42 | "drawStyle": "line", 43 | "fillOpacity": 14, 44 | "gradientMode": "opacity", 45 | "hideFrom": { 46 | "legend": false, 47 | "tooltip": false, 48 | "viz": false 49 | }, 50 | "lineInterpolation": "smooth", 51 | "lineWidth": 1, 52 | "pointSize": 5, 53 | "scaleDistribution": { 54 | "type": "linear" 55 | }, 56 | "showPoints": "auto", 57 | "spanNulls": false, 58 | "stacking": { 59 | "group": "A", 60 | "mode": "none" 61 | }, 62 | "thresholdsStyle": { 63 | "mode": "off" 64 | } 65 | }, 66 | "mappings": [], 67 | "thresholds": { 68 | "mode": "absolute", 69 | "steps": [ 70 | { 71 | "color": "green", 72 | "value": null 73 | } 74 | ] 75 | }, 76 | "unit": "Bps" 77 | }, 78 | "overrides": [] 79 | }, 80 | "gridPos": { 81 | "h": 8, 82 | "w": 12, 83 | "x": 0, 84 | "y": 0 85 | }, 86 | "id": 1, 87 | "options": { 88 | "legend": { 89 | "calcs": [], 90 | "displayMode": "list", 91 | "placement": "bottom", 92 | "showLegend": false 93 | }, 94 | "tooltip": { 95 | "mode": "single", 96 | "sort": "none" 97 | } 98 | }, 99 | "pluginVersion": "10.0.1", 100 | "targets": [ 101 | { 102 | "datasource": { 103 | "type": "prometheus", 104 | "uid": "PBFA97CFB590B2093" 105 | }, 106 | "editorMode": "builder", 107 | "expr": "pulsar_broker_throughput_in", 108 | "instant": false, 109 | "range": true, 110 | "refId": "A" 111 | } 112 | ], 113 | "title": " ", 114 | "transparent": true, 115 | "type": "timeseries" 116 | } 117 | ], 118 | "refresh": "5s", 119 | "schemaVersion": 38, 120 | "style": "dark", 121 | "tags": [], 122 | "templating": { 123 | "list": [] 124 | }, 125 | "time": { 126 | "from": "now-5m", 127 | "to": "now" 128 | }, 129 | "timepicker": {}, 130 | "timezone": "", 131 | "title": "throughputin", 132 | "uid": "bdfb696f-55e4-46da-aa3d-381b5cf2f408", 133 | "version": 5, 134 | "weekStart": "" 135 | } -------------------------------------------------------------------------------- /imageConfigs/grafana/provisioning/dashboards/throughputout.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": { 7 | "type": "grafana", 8 | "uid": "-- Grafana --" 9 | }, 10 | "enable": true, 11 | "hide": true, 12 | "iconColor": "rgba(0, 211, 255, 1)", 13 | "name": "Annotations & Alerts", 14 | "type": "dashboard" 15 | } 16 | ] 17 | }, 18 | "editable": true, 19 | "fiscalYearStartMonth": 0, 20 | "graphTooltip": 0, 21 | "id": 9, 22 | "links": [], 23 | "liveNow": false, 24 | "panels": [ 25 | { 26 | "datasource": { 27 | "type": "prometheus", 28 | "uid": "PBFA97CFB590B2093" 29 | }, 30 | "fieldConfig": { 31 | "defaults": { 32 | "color": { 33 | "fixedColor": "semi-dark-blue", 34 | "mode": "fixed" 35 | }, 36 | "custom": { 37 | "axisCenteredZero": false, 38 | "axisColorMode": "text", 39 | "axisLabel": "", 40 | "axisPlacement": "auto", 41 | "barAlignment": 0, 42 | "drawStyle": "line", 43 | "fillOpacity": 14, 44 | "gradientMode": "opacity", 45 | "hideFrom": { 46 | "legend": false, 47 | "tooltip": false, 48 | "viz": false 49 | }, 50 | "lineInterpolation": "smooth", 51 | "lineWidth": 1, 52 | "pointSize": 5, 53 | "scaleDistribution": { 54 | "type": "linear" 55 | }, 56 | "showPoints": "auto", 57 | "spanNulls": false, 58 | "stacking": { 59 | "group": "A", 60 | "mode": "none" 61 | }, 62 | "thresholdsStyle": { 63 | "mode": "off" 64 | } 65 | }, 66 | "mappings": [], 67 | "thresholds": { 68 | "mode": "percentage", 69 | "steps": [ 70 | { 71 | "color": "green", 72 | "value": null 73 | } 74 | ] 75 | }, 76 | "unit": "Bps" 77 | }, 78 | "overrides": [] 79 | }, 80 | "gridPos": { 81 | "h": 8, 82 | "w": 12, 83 | "x": 0, 84 | "y": 0 85 | }, 86 | "id": 1, 87 | "options": { 88 | "legend": { 89 | "calcs": [], 90 | "displayMode": "list", 91 | "placement": "bottom", 92 | "showLegend": false 93 | }, 94 | "tooltip": { 95 | "mode": "single", 96 | "sort": "none" 97 | } 98 | }, 99 | "targets": [ 100 | { 101 | "datasource": { 102 | "type": "prometheus", 103 | "uid": "PBFA97CFB590B2093" 104 | }, 105 | "editorMode": "builder", 106 | "expr": "pulsar_broker_throughput_out", 107 | "instant": false, 108 | "range": true, 109 | "refId": "A" 110 | } 111 | ], 112 | "title": " ", 113 | "transparent": true, 114 | "type": "timeseries" 115 | } 116 | ], 117 | "refresh": "5s", 118 | "schemaVersion": 38, 119 | "style": "dark", 120 | "tags": [], 121 | "templating": { 122 | "list": [] 123 | }, 124 | "time": { 125 | "from": "now-5m", 126 | "to": "now" 127 | }, 128 | "timepicker": {}, 129 | "timezone": "", 130 | "title": "throughtputout", 131 | "uid": "b1f5eb24-9c75-4ba3-a40b-7bf8e1ccdc94", 132 | "version": 5, 133 | "weekStart": "" 134 | } -------------------------------------------------------------------------------- /imageConfigs/grafana/provisioning/dashboards/topicsandsubscriptions.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": { 7 | "type": "grafana", 8 | "uid": "-- Grafana --" 9 | }, 10 | "enable": true, 11 | "hide": true, 12 | "iconColor": "rgba(0, 211, 255, 1)", 13 | "name": "Annotations & Alerts", 14 | "type": "dashboard" 15 | } 16 | ] 17 | }, 18 | "editable": true, 19 | "fiscalYearStartMonth": 0, 20 | "graphTooltip": 0, 21 | "id": 14, 22 | "links": [], 23 | "liveNow": false, 24 | "panels": [ 25 | { 26 | "datasource": { 27 | "type": "prometheus", 28 | "uid": "PBFA97CFB590B2093" 29 | }, 30 | "fieldConfig": { 31 | "defaults": { 32 | "color": { 33 | "fixedColor": "light-purple", 34 | "mode": "fixed" 35 | }, 36 | "mappings": [], 37 | "thresholds": { 38 | "mode": "absolute", 39 | "steps": [ 40 | { 41 | "color": "green", 42 | "value": null 43 | } 44 | ] 45 | }, 46 | "unit": "short" 47 | }, 48 | "overrides": [ 49 | { 50 | "matcher": { 51 | "id": "byName", 52 | "options": "pulsar_broker_topics_count" 53 | }, 54 | "properties": [ 55 | { 56 | "id": "displayName", 57 | "value": "Topics" 58 | } 59 | ] 60 | }, 61 | { 62 | "matcher": { 63 | "id": "byName", 64 | "options": "pulsar_broker_subscriptions_count" 65 | }, 66 | "properties": [ 67 | { 68 | "id": "displayName", 69 | "value": "Subscriptions" 70 | } 71 | ] 72 | } 73 | ] 74 | }, 75 | "gridPos": { 76 | "h": 8, 77 | "w": 12, 78 | "x": 0, 79 | "y": 0 80 | }, 81 | "id": 1, 82 | "options": { 83 | "colorMode": "background", 84 | "graphMode": "none", 85 | "justifyMode": "center", 86 | "orientation": "auto", 87 | "reduceOptions": { 88 | "calcs": [ 89 | "lastNotNull" 90 | ], 91 | "fields": "", 92 | "values": false 93 | }, 94 | "textMode": "auto" 95 | }, 96 | "pluginVersion": "10.0.1", 97 | "targets": [ 98 | { 99 | "datasource": { 100 | "type": "prometheus", 101 | "uid": "PBFA97CFB590B2093" 102 | }, 103 | "editorMode": "builder", 104 | "expr": "pulsar_broker_topics_count", 105 | "instant": false, 106 | "range": true, 107 | "refId": "Producers" 108 | }, 109 | { 110 | "datasource": { 111 | "type": "prometheus", 112 | "uid": "PBFA97CFB590B2093" 113 | }, 114 | "editorMode": "builder", 115 | "expr": "pulsar_broker_subscriptions_count", 116 | "hide": false, 117 | "instant": false, 118 | "range": true, 119 | "refId": "A" 120 | } 121 | ], 122 | "title": " ", 123 | "transparent": true, 124 | "type": "stat" 125 | } 126 | ], 127 | "refresh": "5s", 128 | "schemaVersion": 38, 129 | "style": "dark", 130 | "tags": [], 131 | "templating": { 132 | "list": [] 133 | }, 134 | "time": { 135 | "from": "now-5m", 136 | "to": "now" 137 | }, 138 | "timepicker": {}, 139 | "timezone": "", 140 | "title": "topicsandsubscriptions", 141 | "uid": "c8268214-d094-46d5-9a25-7cce1192ae69", 142 | "version": 8, 143 | "weekStart": "" 144 | } -------------------------------------------------------------------------------- /imageConfigs/grafana/provisioning/dashboards/usageGauge.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": { 7 | "type": "grafana", 8 | "uid": "-- Grafana --" 9 | }, 10 | "enable": true, 11 | "hide": true, 12 | "iconColor": "rgba(0, 211, 255, 1)", 13 | "name": "Annotations & Alerts", 14 | "type": "dashboard" 15 | } 16 | ] 17 | }, 18 | "editable": true, 19 | "fiscalYearStartMonth": 0, 20 | "graphTooltip": 0, 21 | "id": 5, 22 | "links": [], 23 | "liveNow": false, 24 | "panels": [ 25 | { 26 | "datasource": { 27 | "type": "prometheus", 28 | "uid": "PBFA97CFB590B2093" 29 | }, 30 | "fieldConfig": { 31 | "defaults": { 32 | "color": { 33 | "mode": "thresholds" 34 | }, 35 | "mappings": [], 36 | "thresholds": { 37 | "mode": "absolute", 38 | "steps": [ 39 | { 40 | "color": "dark-purple", 41 | "value": null 42 | }, 43 | { 44 | "color": "semi-dark-orange", 45 | "value": 70 46 | }, 47 | { 48 | "color": "semi-dark-red", 49 | "value": 85 50 | } 51 | ] 52 | }, 53 | "unit": "percent" 54 | }, 55 | "overrides": [ 56 | { 57 | "matcher": { 58 | "id": "byName", 59 | "options": "pulsar_lb_cpu_usage" 60 | }, 61 | "properties": [ 62 | { 63 | "id": "displayName", 64 | "value": "CPU Usage" 65 | } 66 | ] 67 | }, 68 | { 69 | "matcher": { 70 | "id": "byName", 71 | "options": "pulsar_lb_memory_usage" 72 | }, 73 | "properties": [ 74 | { 75 | "id": "displayName", 76 | "value": "Memory Usage" 77 | } 78 | ] 79 | } 80 | ] 81 | }, 82 | "gridPos": { 83 | "h": 8, 84 | "w": 12, 85 | "x": 0, 86 | "y": 0 87 | }, 88 | "id": 1, 89 | "options": { 90 | "orientation": "auto", 91 | "reduceOptions": { 92 | "calcs": ["lastNotNull"], 93 | "fields": "", 94 | "values": false 95 | }, 96 | "showThresholdLabels": false, 97 | "showThresholdMarkers": true 98 | }, 99 | "pluginVersion": "10.0.2", 100 | "targets": [ 101 | { 102 | "datasource": { 103 | "type": "prometheus", 104 | "uid": "PBFA97CFB590B2093" 105 | }, 106 | "editorMode": "builder", 107 | "expr": "pulsar_lb_cpu_usage", 108 | "instant": false, 109 | "range": true, 110 | "refId": "A" 111 | }, 112 | { 113 | "datasource": { 114 | "type": "prometheus", 115 | "uid": "PBFA97CFB590B2093" 116 | }, 117 | "editorMode": "builder", 118 | "expr": "pulsar_lb_memory_usage", 119 | "hide": false, 120 | "instant": false, 121 | "range": true, 122 | "refId": "B" 123 | } 124 | ], 125 | "title": " ", 126 | "transparent": true, 127 | "type": "gauge" 128 | } 129 | ], 130 | "refresh": "5s", 131 | "schemaVersion": 38, 132 | "style": "dark", 133 | "tags": [], 134 | "templating": { 135 | "list": [] 136 | }, 137 | "time": { 138 | "from": "now-6h", 139 | "to": "now" 140 | }, 141 | "timepicker": {}, 142 | "timezone": "", 143 | "title": "New dashboard", 144 | "uid": "a6f621d3-bb3c-4569-8315-2e0c4b2de35b", 145 | "version": 2, 146 | "weekStart": "" 147 | } 148 | -------------------------------------------------------------------------------- /imageConfigs/grafana/provisioning/datasources/srcProm.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | datasources: 4 | - name: Prometheus 5 | type: prometheus 6 | access: proxy 7 | orgId: 1 8 | # url: http://localhost:9090 9 | url: http://prometheus:9090 10 | basicAuth: false 11 | isDefault: true 12 | editable: true 13 | -------------------------------------------------------------------------------- /imageConfigs/prometheus/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM prom/prometheus 2 | 3 | COPY config/prometheus.yml /etc/prometheus/prometheus.yml 4 | 5 | ENV PULSAR_BROKER_PORT=8080 6 | 7 | CMD [ "--config.file=/etc/prometheus/prometheus.yml" ] -------------------------------------------------------------------------------- /imageConfigs/prometheus/config/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 5s 3 | evaluation_interval: 15s 4 | 5 | scrape_configs: 6 | - job_name: 'pulsar' 7 | scrape_interval: 5s 8 | metrics_path: '/metrics/' 9 | static_configs: 10 | - targets: ['host.docker.internal:8080'] 11 | # - targets: ['broker:8080'] -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Pulsar Portrait 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App' 4 | import './client/styles/styles.scss' 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')) 7 | root.render( 8 | <> 9 | 10 | 11 | ) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pulsarportrait", 3 | "version": "1.0.0", 4 | "description": "A pulsar visualizer", 5 | "main": "index.tsx", 6 | "scripts": { 7 | "test": "jest --verbose", 8 | "dockbuild": "docker build -t pulsarportrait .", 9 | "dockprom": "docker build -t pulsarproto .", 10 | "server": "nodemon ./server/server.js", 11 | "dev": "NODE_ENV=development nodemon server/server.js & NODE_ENV=development webpack serve --open", 12 | "start": "webpack-dev-server --mode development --open --hot", 13 | "build": "webpack --mode production" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/oslabs-beta/PulsarPortrait.git" 18 | }, 19 | "author": "Grant Thomas, Jordan Zolman, Cyrux Lam, Anthony Le", 20 | "license": "ISC", 21 | "bugs": { 22 | "url": "https://github.com/oslabs-beta/PulsarPortrait/issues" 23 | }, 24 | "homepage": "https://github.com/oslabs-beta/PulsarPortrait#readme", 25 | "jest": { 26 | "transform": { 27 | "^.+\\.[jt]sx?$": "babel-jest" 28 | }, 29 | "testEnvironment": "jest-environment-jsdom" 30 | }, 31 | "dependencies": { 32 | "@emotion/react": "^11.11.1", 33 | "@emotion/styled": "^11.11.0", 34 | "@mui/icons-material": "^5.13.7", 35 | "@mui/material": "^5.13.7", 36 | "cors-anywhere": "^0.4.4", 37 | "css-loader": "^6.8.1", 38 | "express": "^4.18.2", 39 | "express-session": "^1.17.3", 40 | "frameguard": "^4.0.0", 41 | "react": "^18.2.0", 42 | "react-dom": "^18.2.0", 43 | "react-icons": "^4.10.1", 44 | "sass": "^1.63.6", 45 | "sass-loader": "^13.3.2", 46 | "ts-loader": "^9.4.4", 47 | "ts-node": "^10.9.1", 48 | "typescript": "^5.1.6" 49 | }, 50 | "devDependencies": { 51 | "@babel/core": "^7.22.5", 52 | "@babel/plugin-transform-modules-commonjs": "^7.22.5", 53 | "@babel/preset-env": "^7.22.5", 54 | "@babel/preset-react": "^7.22.3", 55 | "@babel/preset-typescript": "^7.22.5", 56 | "@jest/globals": "^27.5.1", 57 | "@testing-library/jest-dom": "^5.16.5", 58 | "@testing-library/react": "^13.4.0", 59 | "@types/express": "^4.17.13", 60 | "@types/jest": "^29.2.3", 61 | "@types/node": "^17.0.8", 62 | "@types/react": "^18.2.8", 63 | "@types/react-dom": "^18.2.4", 64 | "babel-jest": "^29.5.0", 65 | "babel-loader": "^9.1.2", 66 | "babel-polyfill": "^6.26.0", 67 | "eslint": "^8.42.0", 68 | "html-webpack-plugin": "^5.5.1", 69 | "jest": "^28.1.3", 70 | "jest-environment-jsdom": "^28.1.0", 71 | "mongoose": "^7.2.2", 72 | "nodemon": "^1.14.9", 73 | "react-test-renderer": "^18.2.0", 74 | "style-loader": "^3.3.3", 75 | "webpack": "^5.85.1", 76 | "webpack-cli": "^5.1.3", 77 | "webpack-dev-server": "^4.15.0" 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /server/server.ts: -------------------------------------------------------------------------------- 1 | // const express = require('express'); 2 | import express, { Request, Response, NextFunction, RequestHandler } from 'express' 3 | // const {Request, Response, NextFunction, RequestHandles} = require('express') 4 | // const path = require('path'); 5 | import path from 'path'; 6 | const app = express(); 7 | const PORT = process.env.PORT || 3333; 8 | 9 | type ServerError = { 10 | log: string, 11 | status: number, 12 | message: {} 13 | } 14 | 15 | app.use(express.json()); 16 | app.use(express.urlencoded({ extended: true })); 17 | 18 | // statically serve the dist and client folder 19 | app.use(express.static(path.join(__dirname, '../dist'))); 20 | app.use(express.static(path.join(__dirname, '../client'))); 21 | 22 | app.get('/', (req: Request, res: Response) => { 23 | res.sendFile(path.join(__dirname, '../client/index.html')); 24 | }); 25 | 26 | //route error handler 27 | app.use((req: Request, res: Response) => 28 | res.status(404).send('Error, not the page you are looking for') 29 | ); 30 | 31 | // global error handler to handle erros within middleware 32 | app.use((err: ServerError, req: Request, res: Response, next: NextFunction) => { 33 | //Define a default error object 34 | const defaultErr: ServerError = { 35 | log: 'Express error handler caught unknown middleware error', 36 | status: 400, 37 | message: { err: 'An error occured' }, 38 | }; 39 | // define an errorObj to combine new errors 40 | const errObj: ServerError = Object.assign(defaultErr, err); 41 | console.log('Error: ', errObj.log); 42 | // return to the client the status and error message 43 | return res.status(errObj.status || 500).send(errObj.message); 44 | }); 45 | 46 | app.listen(PORT, () => console.log(`Listening on port ${PORT}...`)); 47 | 48 | module.exports = app; 49 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "module": "commonjs", 5 | "removeComments": true, 6 | "jsx": "react", 7 | "allowJs": true, 8 | "noImplicitAny": true, 9 | "esModuleInterop": true, 10 | "allowSyntheticDefaultImports": true, 11 | "strictNullChecks": false 12 | }, 13 | "include": ["client/**/*", "index.tsx", "server/server.ts"] 14 | } -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const HTMLWebpackPlugin = require('html-webpack-plugin'); 3 | 4 | 5 | module.exports = { 6 | entry: [ 7 | path.resolve(__dirname, './index.tsx'), 8 | 9 | ], 10 | output: { 11 | path: path.join(__dirname, '/dist'), 12 | filename: 'bundle.js', 13 | 14 | }, 15 | devServer: { 16 | host: 'localhost', 17 | port: 7080, 18 | static: { 19 | directory: path.resolve(__dirname, 'dist'), 20 | // match the output 'publicPath' 21 | publicPath: '/', 22 | }, 23 | // enable HMR on the devServer 24 | hot: true, 25 | // fallback to root for other urls 26 | historyApiFallback: true, 27 | headers: { 'Access-Control-Allow-Origin': '*' }, 28 | compress: true, 29 | proxy: { 30 | '/': 'http://localhost:3333' 31 | } 32 | }, 33 | 34 | plugins: [ 35 | new HTMLWebpackPlugin({ 36 | template: './client/index.html' 37 | }) 38 | ], 39 | 40 | module: { 41 | rules: [ 42 | { 43 | test: /.jsx?$/, 44 | exclude: /node_modules/, 45 | use: { 46 | loader: 'babel-loader', 47 | options: { 48 | presets: ['@babel/preset-env', '@babel/preset-react'] 49 | } 50 | } 51 | }, 52 | { 53 | test: /.tsx?$/, 54 | exclude: /node_modules/, 55 | use: { 56 | loader: 'ts-loader' 57 | } 58 | }, 59 | { 60 | test: /\.s[ac]ss$/, 61 | use: ["style-loader", "css-loader", 'sass-loader'] 62 | } 63 | ] 64 | }, 65 | resolve: { 66 | // Enable importing JS / JSX / TS / TSX files without specifying their extension 67 | extensions: ['.js', '.jsx', '.ts', '.tsx'], 68 | }, 69 | } --------------------------------------------------------------------------------