Sentry Integration (#221)
* BE sentry setup w/ user scope * FE sentry integration + user scope * FE env adjustments * FE: use NODE_ENV for Sentry * BE: use FLASK_ENV for Sentry * BE: remove email, acct & ip from Sentry user scope * comment .env.example SENTRY* for CI * fix merge artifact
This commit is contained in:
parent
968974d8d7
commit
7abeac7bd7
|
@ -11,6 +11,7 @@ SENDGRID_API_KEY="optional, but emails won't send without it"
|
|||
ETHEREUM_ENDPOINT_URI = "http://localhost:8545"
|
||||
CROWD_FUND_URL = "https://eip-712.herokuapp.com/contract/crowd-fund"
|
||||
CROWD_FUND_FACTORY_URL = "https://eip-712.herokuapp.com/contract/factory"
|
||||
# SENTRY_DSN="https://PUBLICKEY@sentry.io/PROJECTID"
|
||||
# SENTRY_RELEASE="optional, overrides git hash"
|
||||
UPLOAD_DIRECTORY = "/tmp"
|
||||
UPLOAD_URL = "http://localhost:5000" # for constructing download url
|
||||
|
||||
|
|
|
@ -2,9 +2,12 @@
|
|||
"""The app module, containing the app factory function."""
|
||||
from flask import Flask
|
||||
from flask_cors import CORS
|
||||
from sentry_sdk.integrations.flask import FlaskIntegration
|
||||
import sentry_sdk
|
||||
|
||||
from grant import commands, proposal, user, comment, milestone, admin, email
|
||||
from grant.extensions import bcrypt, migrate, db, ma, mail, web3
|
||||
from grant.settings import SENTRY_RELEASE, ENV
|
||||
|
||||
|
||||
def create_app(config_object="grant.settings"):
|
||||
|
@ -15,6 +18,11 @@ def create_app(config_object="grant.settings"):
|
|||
register_blueprints(app)
|
||||
register_shellcontext(app)
|
||||
register_commands(app)
|
||||
sentry_sdk.init(
|
||||
environment=ENV,
|
||||
release=SENTRY_RELEASE,
|
||||
integrations=[FlaskIntegration()]
|
||||
)
|
||||
return app
|
||||
|
||||
|
||||
|
|
|
@ -6,8 +6,11 @@ Most configuration is set via environment variables.
|
|||
For local development, use a .env file to set
|
||||
environment variables.
|
||||
"""
|
||||
import subprocess
|
||||
from environs import Env
|
||||
|
||||
git_revision_short_hash = subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD'])
|
||||
|
||||
env = Env()
|
||||
env.read_env()
|
||||
|
||||
|
@ -29,6 +32,8 @@ SENDGRID_API_KEY = env.str("SENDGRID_API_KEY", default="")
|
|||
SENDGRID_DEFAULT_FROM = "noreply@grant.io"
|
||||
ETHEREUM_PROVIDER = "http"
|
||||
ETHEREUM_ENDPOINT_URI = env.str("ETHEREUM_ENDPOINT_URI")
|
||||
SENTRY_DSN = env.str("SENTRY_DSN", default=None)
|
||||
SENTRY_RELEASE = env.str("SENTRY_RELEASE", default=git_revision_short_hash)
|
||||
UPLOAD_DIRECTORY = env.str("UPLOAD_DIRECTORY")
|
||||
UPLOAD_URL = env.str("UPLOAD_URL")
|
||||
MAX_CONTENT_LENGTH = 5 * 1024 * 1024 # 5MB (limits file uploads, raises RequestEntityTooLarge)
|
||||
|
|
|
@ -6,6 +6,7 @@ import requests
|
|||
from flask import request, g, jsonify
|
||||
from itsdangerous import SignatureExpired, BadSignature
|
||||
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
|
||||
import sentry_sdk
|
||||
|
||||
from grant.settings import SECRET_KEY, AUTH_URL
|
||||
from ..proposal.models import Proposal
|
||||
|
@ -69,6 +70,10 @@ def requires_sm(f):
|
|||
return jsonify(message="No user exists with address: {}".format(auth_address)), 401
|
||||
|
||||
g.current_user = user
|
||||
with sentry_sdk.configure_scope() as scope:
|
||||
scope.user = {
|
||||
"id": user.id,
|
||||
}
|
||||
return f(*args, **kwargs)
|
||||
|
||||
return jsonify(message="Authentication is required to access this resource"), 401
|
||||
|
|
|
@ -60,3 +60,6 @@ flask-yolo2API==0.2.6
|
|||
#web3
|
||||
flask-web3==0.1.1
|
||||
web3==4.8.1
|
||||
|
||||
#sentry
|
||||
sentry-sdk[flask]==0.5.5
|
|
@ -7,5 +7,11 @@ NO_DEV_TS_CHECK=true
|
|||
# Set the public host url (no trailing slash)
|
||||
PUBLIC_HOST_URL=https://demo.grant.io
|
||||
|
||||
|
||||
# sentry
|
||||
SENTRY_DSN="https://PUBLICKEY@sentry.io/PROJECTID"
|
||||
SENTRY_RELEASE="optional, overrides git hash"
|
||||
|
||||
CROWD_FUND_URL = "https://eip-712.herokuapp.com/contract/crowd-fund"
|
||||
CROWD_FUND_FACTORY_URL = "https://eip-712.herokuapp.com/contract/factory"
|
||||
CROWD_FUND_FACTORY_URL = "https://eip-712.herokuapp.com/contract/factory"
|
||||
|
||||
|
|
|
@ -6,12 +6,19 @@ import { loadComponents } from 'loadable-components';
|
|||
import { Provider } from 'react-redux';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import { PersistGate } from 'redux-persist/integration/react';
|
||||
import * as Sentry from '@sentry/browser';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
import { configureStore } from 'store/configure';
|
||||
import { massageSerializedState } from 'utils/api';
|
||||
import Routes from './Routes';
|
||||
import i18n from './i18n';
|
||||
|
||||
|
||||
Sentry.init({
|
||||
dsn: process.env.SENTRY_DSN,
|
||||
release: process.env.SENTRY_RELEASE,
|
||||
environment: process.env.NODE_ENV,
|
||||
});
|
||||
const initialState =
|
||||
window && massageSerializedState((window as any).__PRELOADED_STATE__);
|
||||
const { store, persistor } = configureStore(initialState);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import types from './types';
|
||||
import { Dispatch } from 'redux';
|
||||
import * as Sentry from '@sentry/browser';
|
||||
import { sleep } from 'utils/helpers';
|
||||
import { generateAuthSignatureData } from 'utils/auth';
|
||||
import { AppState } from 'store/reducers';
|
||||
|
@ -37,7 +38,13 @@ export function authUser(address: string, authSignature?: Falsy | AuthSignatureD
|
|||
signedMessage: authSignature.signedMessage,
|
||||
rawTypedData: JSON.stringify(authSignature.rawTypedData),
|
||||
});
|
||||
|
||||
// sentry user scope
|
||||
Sentry.configureScope(scope => {
|
||||
scope.setUser({
|
||||
email: res.data.emailAddress,
|
||||
accountAddress: res.data.ethAddress,
|
||||
});
|
||||
});
|
||||
dispatch({
|
||||
type: types.AUTH_USER_FULFILLED,
|
||||
payload: {
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const paths = require('./paths');
|
||||
const childProcess = require('child_process');
|
||||
|
||||
delete require.cache[require.resolve('./paths')];
|
||||
|
||||
const gitRevisionShortHash = childProcess
|
||||
.execSync('git rev-parse --short HEAD')
|
||||
.toString()
|
||||
.trim();
|
||||
|
||||
if (!process.env.NODE_ENV) {
|
||||
throw new Error(
|
||||
'The process.env.NODE_ENV environment variable is required but was not specified.',
|
||||
|
@ -54,6 +60,10 @@ if (!process.env.BACKEND_URL) {
|
|||
process.env.BACKEND_URL = 'http://localhost:5000';
|
||||
}
|
||||
|
||||
if (!process.env.SENTRY_RELEASE) {
|
||||
process.env.SENTRY_RELEASE = gitRevisionShortHash;
|
||||
}
|
||||
|
||||
const appDirectory = fs.realpathSync(process.cwd());
|
||||
process.env.NODE_PATH = (process.env.NODE_PATH || '')
|
||||
.split(path.delimiter)
|
||||
|
@ -67,6 +77,8 @@ module.exports = () => {
|
|||
NODE_ENV: process.env.NODE_ENV || 'development',
|
||||
PORT: process.env.PORT || 3000,
|
||||
PUBLIC_HOST_URL: process.env.PUBLIC_HOST_URL,
|
||||
SENTRY_DSN: process.env.SENTRY_DSN || null,
|
||||
SENTRY_RELEASE: process.env.SENTRY_RELEASE,
|
||||
};
|
||||
|
||||
// Stringify all values so we can feed into Webpack DefinePlugin
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
"@babel/register": "^7.0.0",
|
||||
"@ledgerhq/hw-app-eth": "4.23.0",
|
||||
"@ledgerhq/hw-transport-u2f": "4.21.0",
|
||||
"@sentry/browser": "^4.3.2",
|
||||
"@sentry/node": "^4.3.2",
|
||||
"@svgr/webpack": "^2.4.0",
|
||||
"@types/classnames": "^2.2.6",
|
||||
"@types/cors": "^2.8.4",
|
||||
|
|
|
@ -6,6 +6,7 @@ import manifestHelpers from 'express-manifest-helpers';
|
|||
import * as bodyParser from 'body-parser';
|
||||
import expressWinston from 'express-winston';
|
||||
import i18nMiddleware from 'i18next-express-middleware';
|
||||
import * as Sentry from '@sentry/node';
|
||||
|
||||
import '../config/env';
|
||||
// @ts-ignore
|
||||
|
@ -17,8 +18,17 @@ import i18n from './i18n';
|
|||
process.env.SERVER_SIDE_RENDER = 'true';
|
||||
const isDev = process.env.NODE_ENV === 'development';
|
||||
|
||||
Sentry.init({
|
||||
dsn: process.env.SENTRY_DSN,
|
||||
release: process.env.SENTRY_RELEASE,
|
||||
environment: process.env.NODE_ENV,
|
||||
});
|
||||
|
||||
const app = express();
|
||||
|
||||
// sentry
|
||||
app.use(Sentry.Handlers.requestHandler());
|
||||
|
||||
// log requests
|
||||
app.use(expressWinston.logger({ winstonInstance: log }));
|
||||
|
||||
|
@ -59,6 +69,7 @@ app.use(
|
|||
|
||||
app.use(serverRender());
|
||||
|
||||
app.use(Sentry.Handlers.errorHandler());
|
||||
app.use(expressWinston.errorLogger({ winstonInstance: log }));
|
||||
|
||||
app.listen(process.env.PORT || 3000, () => {
|
||||
|
|
|
@ -1612,6 +1612,60 @@
|
|||
dependencies:
|
||||
any-observable "^0.3.0"
|
||||
|
||||
"@sentry/browser@^4.3.2":
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-4.3.2.tgz#430b83583c5c25d33041dd80bf6ed19216086f70"
|
||||
dependencies:
|
||||
"@sentry/core" "4.3.2"
|
||||
"@sentry/types" "4.3.2"
|
||||
"@sentry/utils" "4.3.2"
|
||||
|
||||
"@sentry/core@4.3.2":
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-4.3.2.tgz#e8a2850a11316d865ed7d3030ee2c4a1608bb1d8"
|
||||
dependencies:
|
||||
"@sentry/hub" "4.3.2"
|
||||
"@sentry/minimal" "4.3.2"
|
||||
"@sentry/types" "4.3.2"
|
||||
"@sentry/utils" "4.3.2"
|
||||
|
||||
"@sentry/hub@4.3.2":
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-4.3.2.tgz#1ea10038e2080035d2bc09f5f26829cd106a1516"
|
||||
dependencies:
|
||||
"@sentry/types" "4.3.2"
|
||||
"@sentry/utils" "4.3.2"
|
||||
|
||||
"@sentry/minimal@4.3.2":
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-4.3.2.tgz#c0958e5858b2105a6a0b523787e459a03af603cc"
|
||||
dependencies:
|
||||
"@sentry/hub" "4.3.2"
|
||||
"@sentry/types" "4.3.2"
|
||||
|
||||
"@sentry/node@^4.3.2":
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/node/-/node-4.3.2.tgz#3c7cd3aff238f3b1eb3252147b963cbdf520aa45"
|
||||
dependencies:
|
||||
"@sentry/core" "4.3.2"
|
||||
"@sentry/hub" "4.3.2"
|
||||
"@sentry/types" "4.3.2"
|
||||
"@sentry/utils" "4.3.2"
|
||||
cookie "0.3.1"
|
||||
lsmod "1.0.0"
|
||||
md5 "2.2.1"
|
||||
stack-trace "0.0.10"
|
||||
|
||||
"@sentry/types@4.3.2":
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-4.3.2.tgz#28b143979482fcbc9f9e520250482dde015b13fa"
|
||||
|
||||
"@sentry/utils@4.3.2":
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-4.3.2.tgz#de14046eba972af9d62508f78cd998b0352d634a"
|
||||
dependencies:
|
||||
"@sentry/types" "4.3.2"
|
||||
|
||||
"@storybook/addons@4.0.0-alpha.22":
|
||||
version "4.0.0-alpha.22"
|
||||
resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-4.0.0-alpha.22.tgz#08d89396fff216c0d5aa305f7ac851b6bc34b6cf"
|
||||
|
@ -4105,6 +4159,10 @@ chardet@^0.7.0:
|
|||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
|
||||
|
||||
charenc@~0.0.1:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
|
||||
|
||||
check-error@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
|
||||
|
@ -4812,6 +4870,10 @@ cross-spawn@^3.0.0:
|
|||
lru-cache "^4.0.1"
|
||||
which "^1.2.9"
|
||||
|
||||
crypt@~0.0.1:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
|
||||
|
||||
cryptiles@3.x.x:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe"
|
||||
|
@ -8082,7 +8144,7 @@ is-boolean-object@^1.0.0:
|
|||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93"
|
||||
|
||||
is-buffer@^1.0.2, is-buffer@^1.1.5:
|
||||
is-buffer@^1.0.2, is-buffer@^1.1.5, is-buffer@~1.1.1:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
||||
|
||||
|
@ -9658,6 +9720,10 @@ lru-cache@^4.1.1, lru-cache@^4.1.2, lru-cache@^4.1.3:
|
|||
pseudomap "^1.0.2"
|
||||
yallist "^2.1.2"
|
||||
|
||||
lsmod@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/lsmod/-/lsmod-1.0.0.tgz#9a00f76dca36eb23fa05350afe1b585d4299e64b"
|
||||
|
||||
make-dir@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.1.0.tgz#19b4369fe48c116f53c2af95ad102c0e39e85d51"
|
||||
|
@ -9751,6 +9817,14 @@ md5.js@^1.3.4:
|
|||
hash-base "^3.0.0"
|
||||
inherits "^2.0.1"
|
||||
|
||||
md5@2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9"
|
||||
dependencies:
|
||||
charenc "~0.0.1"
|
||||
crypt "~0.0.1"
|
||||
is-buffer "~1.1.1"
|
||||
|
||||
mdn-data@~1.1.0:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01"
|
||||
|
@ -14230,7 +14304,7 @@ stable@~0.1.6:
|
|||
version "0.1.8"
|
||||
resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
|
||||
|
||||
stack-trace@0.0.x:
|
||||
stack-trace@0.0.10, stack-trace@0.0.x:
|
||||
version "0.0.10"
|
||||
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
|
||||
|
||||
|
|
Loading…
Reference in New Issue