Skip to content

Commit

Permalink
feat: Implement prometheus plugin (adrien2p#13)
Browse files Browse the repository at this point in the history
* feat: Implement prrometheus plugin

* cleanup

* docs: Update readme

* docs: Update readme

* docs: Update readme
  • Loading branch information
adrien2p authored Oct 17, 2022
1 parent 354ef85 commit e8c2e47
Show file tree
Hide file tree
Showing 7 changed files with 388 additions and 6 deletions.
20 changes: 20 additions & 0 deletions packages/medusa-plugin-prometheus/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.idea

/api
/handlers
/utils
/types
/services

node_modules
.DS_store
**/.DS_Store

dist
coverage

tsconfig.tsbuildinfo
package-lock.json
yarn.json

.env.*
80 changes: 80 additions & 0 deletions packages/medusa-plugin-prometheus/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<p align="center">
<img src="https://github.com/adrien2p/medusa-plugins/blob/assets/assets/medusa-plugin-prometheus.png?raw=true" alt="Medusa-plugins logo" width="500" height="auto" />
</p>

<h1 align="center">medusa-plugin-prometheus</h1>

<p align="center">
<a href="https://www.npmjs.com/package/medusa-plugin-prometheus"><img alt="NPM Version" src="https://img.shields.io/npm/v/medusa-plugin-prometheus.svg" height="20"/></a>
<a href="https://github.com/adrien2p/medusa-plugins/graphs/contributors"><img alt="Contributors" src="https://img.shields.io/github/contributors/adrien2p/medusa-plugins.svg" height="20"/></a>
<a href="https://github.com/adrien2p/awesome-medusajs"><img alt="Awesome medusajs" src="https://awesome.re/badge.svg" height="20"/></a>
<a href="https://twitter.com/intent/tweet?text=Check%20this%20out!%20The%20new%20medusa%sentry%20plugin&url=https://github.com/adrien2p/medusa-plugins/tree/main/packages/medusa-plugin-prometheus"><img alt="Twitter" src="https://badgen.net/badge/icon/twitter?icon=twitter&label=Share%20it%20on" height="20"/></a>
<a href="https://discord.gg/xpCwq3Kfn8"><img alt="Discord" src="https://img.shields.io/badge/chat-on%20discord-7289DA.svg" height="20"/></a>
<a href="https://github.com/adrien2p/medusa-plugins/commits/main"><img alt="Activity" src="https://img.shields.io/github/commit-activity/m/adrien2p/medusa-plugins?style=flat" height="20"/></a>
<a href="https://github.com/adrien2p/medusa-plugins/issues"><img alt="Issues" src="https://img.shields.io/github/issues/adrien2p/medusa-plugins?style=flat" height="20"/></a>
</p>

## Description

swagger-stats traces REST API requests and responses in Node.js Microservices, and collects statistics per API Operation. swagger-stats detects API operations based on express routes. You may also provide Swagger (Open API) specification, and swagger-stats will match API requests with API Operations defined in swagger specification.

The data can be served to **kibana through ElasticSearch** or can also be consumed by **Grafana**

## Getting started

First of all, you need to install the plugin as follow `yarn add @medusa-plugins/medusa-plugnig-prometheus`

Then, go to your `medusa-config.js` file and in the plugins collection property add the following at the beginning to be registered first
```javascript
{
resolve: `medusa-plugin-prometheus`,
options: {
uriPath: "/monitoring",
authentication: true,
onAuthenticate: (req, username, password) => {
return username === process.env.PROM_USER_NAME && password = process.env.PROM_USER_PASS
},
},
},
```

### Output Dashboard

<p align="left">
<img src="https://github.com/adrien2p/medusa-plugins/blob/assets/assets/medusa-plugin-prom-dashboard-1.png?raw=true" alt="Medusa-plugin-prometheus-dashboard-1 logo" width="300" height="auto" />
<img src="https://github.com/adrien2p/medusa-plugins/blob/assets/assets/medusa-plugin-prom-dashboard-2.png?raw=true" alt="Medusa-plugin-prometheus-dashboard-2 logo" width="300" height="auto" style="margin-left: 1rem" />
<img src="https://github.com/adrien2p/medusa-plugins/blob/assets/assets/medusa-plugin-prom-dashboard-3.png?raw=true" alt="Medusa-plugin-prometheus-dashboard-3 logo" width="300" height="auto" style="margin-left: 1rem" />
</p>

## Configuration

You can see above some configuration for the plugin. To be able to know all the options available
you can have a look at
- [swagger-stats](https://swaggerstats.io/guide/conf.html#options)

And here are the plugin configuration types
```typescript
export type SwaggerStats = {
name?: string;
version?: string;
hostname?: string;
ip?: string;
timelineBucketDuration?: number;
swaggerSpec?: string | OpenAPI.Document;
uriPath: string;
durationBuckets?: number[];
requestSizeBuckets?: number[];
responseSizeBuckets?: number[];
apdexThreshold?: number;
onResponseFinish?: (req: Request, res: Response, next: NextFunction) => void | Promise<void>;
authentication?: boolean;
sessionMaxAge?: number;
elasticsearch?: string;
onAuthenticate?: (req: Request, username: string, password: string) => boolean | Promise<boolean>;
};

```

## Grafana

Get started quickly with that guide [here](https://prometheus.io/docs/visualization/grafana/)
46 changes: 46 additions & 0 deletions packages/medusa-plugin-prometheus/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "medusa-plugin-prometheus",
"version": "0.0.0",
"description": "Prometheus plugin for medusajs",
"keywords": [
"analytics",
"prom",
"prometheus",
"grafana",
"medusa",
"medusajs",
"e-commerce",
"performance",
"metrics"
],
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/adrien2p/medusa-plugins.git"
},
"author": "Adrien de Peretti <adrien.deperetti@gmail.com",
"files": [
"api",
"types"
],
"scripts": {
"build": "run-s clean build:tsc",
"build:tsc": "tsc -b",
"clean": "rimraf api handlers utils types coverage tsconfig.tsbuildinfo",
"test": "jest",
"test:ci": "yarn add @medusajs/medusa@${MEDUSAJS_VERSION} && yarn run test"
},
"peerDependencies": {
"@medusajs/medusa": "^1.4.1"
},
"devDependencies": {
"@types/express": "^4.17.14"
},
"dependencies": {
"express": "^4.18.1",
"openapi-types": "^12.0.2",
"prom-client": "^14.1.0",
"swagger-parser": "^10.0.3",
"swagger-stats": "^0.99.2"
}
}
24 changes: 24 additions & 0 deletions packages/medusa-plugin-prometheus/src/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { RequestHandler, Router } from 'express';
import * as swStats from 'swagger-stats';
import { SwaggerStats } from '../types';

export default function (rootDirectory, pluginOptions: SwaggerStats): RequestHandler[] {
const router = Router();

const { name = 'Medusa monitoring Dashboard', ...promOptions } = pluginOptions;
const options = { name, ...promOptions }

let globalMiddlewares = [swStats.getMiddleware(options)];
if (options.swaggerSpec && typeof options.swaggerSpec === 'string') {
const SwaggerParser = require('swagger-parser');
const parser = new SwaggerParser();
globalMiddlewares.push(
parser.validate(options.swaggerSpec, (err, api) => {
const swaggerSpec = api;
router.use(swStats.getMiddleware({ ...options, swaggerSpec }));
})
);
}

return globalMiddlewares;
}
21 changes: 21 additions & 0 deletions packages/medusa-plugin-prometheus/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { OpenAPI } from 'openapi-types';
import { NextFunction } from 'express';

export type SwaggerStats = {
name?: string;
version?: string;
hostname?: string;
ip?: string;
timelineBucketDuration?: number;
swaggerSpec?: string | OpenAPI.Document;
uriPath: string;
durationBuckets?: number[];
requestSizeBuckets?: number[];
responseSizeBuckets?: number[];
apdexThreshold?: number;
onResponseFinish?: (req: Request, res: Response, next: NextFunction) => void | Promise<void>;
authentication?: boolean;
sessionMaxAge?: number;
elasticsearch?: string;
onAuthenticate?: (req: Request, username: string, password: string) => boolean | Promise<boolean>;
};
17 changes: 17 additions & 0 deletions packages/medusa-plugin-prometheus/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"emitDecoratorMetadata": true,
"module": "commonjs",
"noEmit": false,
"resolveJsonModule": true,
"esModuleInterop": true,
"outDir": ".",
"rootDir": "src",
"baseUrl": "./"
},
"include": ["src"],
"exclude": ["**/node_modules", "**/__tests__/*", "**/__e2e__/*"],
}
Loading

0 comments on commit e8c2e47

Please sign in to comment.