mirror of
https://github.com/strapi/strapi.git
synced 2025-12-25 14:14:10 +00:00
Add readme and apply feedback
This commit is contained in:
parent
c43e9b21bb
commit
5484afe817
@ -1,3 +1,70 @@
|
||||
# Strapi plugin sentry
|
||||
# Strapi plugin Sentry
|
||||
|
||||
A quick description of sentry.
|
||||
The official plugin to track Strapi errors with Sentry.
|
||||
|
||||
## Features
|
||||
|
||||
- Initialize a Sentry instance when your Strapi app starts
|
||||
- Send errors encountered in your application's end API to Sentry
|
||||
- Attach useful metadata to Sentry events, to help you with debugging
|
||||
- Expose a global Sentry service
|
||||
|
||||
## Configuration
|
||||
|
||||
| property | type (default) | description |
|
||||
| -------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `dsn` | string (null) | Your Sentry data source name ([see Sentry docs](https://docs.sentry.io/product/sentry-basics/dsn-explainer/)). Omitting it will disable the plugin. |
|
||||
| `sendMetadata` | boolean (true) | Whether the plugin should attach additional information (like OS, browser, etc.) to the events sent to Sentry. |
|
||||
|
||||
**Example**
|
||||
|
||||
`./config/plugins.js`
|
||||
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
// ...
|
||||
sentry: {
|
||||
dsn: env('SENTRY_DSN'),
|
||||
sendMetadata: true,
|
||||
},
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
## Global Sentry service
|
||||
|
||||
You can access a Sentry service throughout your app.
|
||||
|
||||
```js
|
||||
const sentryService = strapi.plugins.sentry.services.sentry;
|
||||
```
|
||||
|
||||
This service exposes the following methods:
|
||||
|
||||
### `sendError(error, configureScope)`
|
||||
|
||||
Use it to manually send errors to Sentry. The `configureScope` is optional, it allows you to customize the error event. Read more about Sentry's scope system [on their docs](https://docs.sentry.io/platforms/node/enriching-events/scopes/#configuring-the-scope).
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
try {
|
||||
// Your code here
|
||||
} catch (error) {
|
||||
strapi.plugins.sentry.services.sentry.sendError(error, (scope, sentryInstance) => {
|
||||
// Customize the scope here
|
||||
scope.setTag('my_custom_tag', 'Tag value');
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
```
|
||||
|
||||
### `sendError(error, configureScope)`
|
||||
|
||||
Use it if you need direct access to the Sentry instance, which should already already be initialized. It's useful if `sendError` doesn't suit your needs.
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
const sentryInstance = strapi.plugins.sentry.services.sentry.getInstance();
|
||||
```
|
||||
|
||||
@ -5,24 +5,19 @@ module.exports = async () => {
|
||||
const { sentry } = strapi.plugins.sentry.services;
|
||||
sentry.init();
|
||||
|
||||
// Only send errors to Sentry if a valid DSN was entered and the plugin isn't disabled
|
||||
const shouldSendSentryEvents = sentry.isReady;
|
||||
|
||||
// Create a middleware to intercept API errors
|
||||
strapi.app.use(async (ctx, next) => {
|
||||
try {
|
||||
await next();
|
||||
} catch (error) {
|
||||
if (shouldSendSentryEvents) {
|
||||
sentry.sendError(error, (scope, sentryInstance) => {
|
||||
scope.addEventProcessor(event => {
|
||||
// Parse Koa context to add error metadata
|
||||
return sentryInstance.Handlers.parseRequest(event, ctx.request);
|
||||
});
|
||||
// Manually add Strapi version
|
||||
scope.setTag('strapi_version', strapi.config.info.strapi);
|
||||
sentry.sendError(error, (scope, sentryInstance) => {
|
||||
scope.addEventProcessor(event => {
|
||||
// Parse Koa context to add error metadata
|
||||
return sentryInstance.Handlers.parseRequest(event, ctx.request);
|
||||
});
|
||||
}
|
||||
// Manually add Strapi version
|
||||
scope.setTag('strapi_version', strapi.config.info.strapi);
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
@ -1,12 +1,3 @@
|
||||
{
|
||||
"routes": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/",
|
||||
"handler": "sentry.index",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
}
|
||||
]
|
||||
"routes": []
|
||||
}
|
||||
|
||||
@ -6,19 +6,4 @@
|
||||
* @description: A set of functions called "actions" of the `sentry` plugin.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Default action.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
index: async ctx => {
|
||||
// Add your own logic here.
|
||||
|
||||
// Send 200 `ok`
|
||||
ctx.send({
|
||||
message: 'ok',
|
||||
});
|
||||
},
|
||||
};
|
||||
module.exports = {};
|
||||
|
||||
@ -3,81 +3,85 @@
|
||||
const Sentry = require('@sentry/node');
|
||||
const defaultSettings = require('../config/settings.json');
|
||||
|
||||
module.exports = {
|
||||
isReady: false,
|
||||
_instance: null,
|
||||
settings: {},
|
||||
const createSentryService = () => {
|
||||
let isReady = false;
|
||||
let instance = null;
|
||||
let settings = {};
|
||||
|
||||
/**
|
||||
* Initialize Sentry service
|
||||
*/
|
||||
init() {
|
||||
// Make sure there isn't a Sentry instance already running
|
||||
if (this._instance != null) {
|
||||
strapi.log.warn('Sentry has already been initialized');
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve user settings and merge them with the default ones
|
||||
this.settings = {
|
||||
...defaultSettings,
|
||||
...strapi.plugins.sentry.config,
|
||||
};
|
||||
|
||||
try {
|
||||
// Don't init Sentry if no DSN was provided
|
||||
if (this.settings.dsn) {
|
||||
Sentry.init({
|
||||
dsn: this.settings.dsn,
|
||||
environment: strapi.config.environment,
|
||||
});
|
||||
// Store the successfully initialized Sentry instance
|
||||
this._instance = Sentry;
|
||||
this.isReady = true;
|
||||
} else {
|
||||
strapi.log.info('strapi-plugin-sentry is disabled because no Sentry DSN was provided');
|
||||
return {
|
||||
/**
|
||||
* Initialize Sentry service
|
||||
*/
|
||||
init() {
|
||||
// Make sure there isn't a Sentry instance already running
|
||||
if (instance != null) {
|
||||
strapi.log.warn('Sentry has already been initialized');
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
strapi.log.warn('Could not set up Sentry, make sure you entered a valid DSN');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Expose Sentry instance through a getter
|
||||
* @returns {Sentry}
|
||||
*/
|
||||
getInstance() {
|
||||
return this._instance;
|
||||
},
|
||||
// Retrieve user settings and merge them with the default ones
|
||||
settings = {
|
||||
...defaultSettings,
|
||||
...strapi.plugins.sentry.config,
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to [configure an instance of Sentry's scope]{@link https://docs.sentry.io/platforms/node/enriching-events/scopes/#configuring-the-scope}
|
||||
* @callback configureScope
|
||||
* @param {Sentry.scope} scope
|
||||
* @param {Sentry=} instance An initialized Sentry instance
|
||||
*/
|
||||
|
||||
/**
|
||||
* Higher level method to send exception events to Sentry
|
||||
* @param {Error} error An error object
|
||||
* @param {configureScope=} configureScope
|
||||
*/
|
||||
sendError(error, configureScope) {
|
||||
// Make sure Sentry is ready
|
||||
if (!this.isReady) {
|
||||
strapi.log.warn("Sentry wasn't properly initialized, cannot send event");
|
||||
return;
|
||||
}
|
||||
|
||||
this._instance.withScope(scope => {
|
||||
// Configure the Sentry scope using the provided callback
|
||||
if (this.settings.sendMetadata) {
|
||||
configureScope(scope, this._instance);
|
||||
try {
|
||||
// Don't init Sentry if no DSN was provided
|
||||
if (settings.dsn) {
|
||||
Sentry.init({
|
||||
dsn: settings.dsn,
|
||||
environment: strapi.config.environment,
|
||||
});
|
||||
// Store the successfully initialized Sentry instance
|
||||
instance = Sentry;
|
||||
isReady = true;
|
||||
} else {
|
||||
strapi.log.info('strapi-plugin-sentry is disabled because no Sentry DSN was provided');
|
||||
}
|
||||
} catch (error) {
|
||||
strapi.log.warn('Could not set up Sentry, make sure you entered a valid DSN');
|
||||
}
|
||||
// Actually send the Error to Sentry
|
||||
this._instance.captureException(error);
|
||||
});
|
||||
},
|
||||
|
||||
strapi.log.info('An error was sent to Sentry');
|
||||
},
|
||||
/**
|
||||
* Expose Sentry instance through a getter
|
||||
* @returns {Sentry}
|
||||
*/
|
||||
getInstance() {
|
||||
return instance;
|
||||
},
|
||||
|
||||
/**
|
||||
* Callback to [configure an instance of Sentry's scope]{@link https://docs.sentry.io/platforms/node/enriching-events/scopes/#configuring-the-scope}
|
||||
* @callback configureScope
|
||||
* @param {Sentry.scope} scope
|
||||
* @param {Sentry=} instance An initialized Sentry instance
|
||||
*/
|
||||
|
||||
/**
|
||||
* Higher level method to send exception events to Sentry
|
||||
* @param {Error} error An error object
|
||||
* @param {configureScope=} configureScope
|
||||
*/
|
||||
sendError(error, configureScope) {
|
||||
// Make sure Sentry is ready
|
||||
if (!isReady) {
|
||||
strapi.log.warn("Sentry wasn't properly initialized, cannot send event");
|
||||
return;
|
||||
}
|
||||
|
||||
instance.withScope(scope => {
|
||||
// Configure the Sentry scope using the provided callback
|
||||
if (settings.sendMetadata) {
|
||||
configureScope(scope, instance);
|
||||
}
|
||||
// Actually send the Error to Sentry
|
||||
instance.captureException(error);
|
||||
});
|
||||
|
||||
strapi.log.info('An error was sent to Sentry');
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = createSentryService();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user