Browse Source

Anonymize Sentry

master
Gaëtan Renaudeau 7 years ago
parent
commit
75c7e34f90
  1. 11
      src/commands/testCrash.js
  2. 13
      src/components/modals/Debug.js
  3. 16
      src/helpers/anonymizer.js
  4. 20
      src/logger.js
  5. 56
      src/sentry/install.js

11
src/commands/testCrash.js

@ -2,16 +2,15 @@
// This is a test example for dev testing purpose. // This is a test example for dev testing purpose.
import { Observable } from 'rxjs'
import { createCommand, Command } from 'helpers/ipc' import { createCommand, Command } from 'helpers/ipc'
type Input = void type Input = void
type Result = void type Result = void
const cmd: Command<Input, Result> = createCommand('testCrash', () => const cmd: Command<Input, Result> = createCommand('testCrash', () => {
Observable.create(() => { // $FlowFixMe
process.exit(1) crashTest() // eslint-disable-line
}), throw new Error()
) })
export default cmd export default cmd

13
src/components/modals/Debug.js

@ -31,12 +31,16 @@ class Debug extends Component<*, *> {
) )
} }
onCrash = () => { onInternalCrash = () => {
testCrash.send().subscribe({ testCrash.send().subscribe({
error: this.error, error: this.error,
}) })
} }
onCrashHere = () => {
throw new Error('CrashTest')
}
onClickStressDevice = (device: *) => async () => { onClickStressDevice = (device: *) => async () => {
try { try {
const currency = getCryptoCurrencyById('bitcoin') const currency = getCryptoCurrencyById('bitcoin')
@ -142,8 +146,11 @@ class Debug extends Component<*, *> {
</Box> </Box>
)} )}
<Box horizontal style={{ padding: 10 }}> <Box horizontal style={{ padding: 10 }}>
<Button onClick={this.onCrash} danger> <Button mr={2} onClick={this.onInternalCrash} danger>
crash process crash internal
</Button>
<Button onClick={this.onCrashHere} danger>
crash here
</Button> </Button>
</Box> </Box>
<Box horizontal style={{ padding: 10 }}> <Box horizontal style={{ padding: 10 }}>

16
src/helpers/anonymizer.js

@ -0,0 +1,16 @@
// @flow
export default {
url: (url: string): string =>
url
.replace(/\/addresses\/[^/]+/g, '/addresses/<HIDDEN>')
.replace(/blockHash=[^&]+/g, 'blockHash=<HIDDEN>'),
appURI: (uri: string): string => uri.replace(/account\/[^/]/g, 'account/<HIDDEN>'),
filepath: (filepath: string): string => {
const i = filepath.indexOf('/node_modules')
if (i !== -1) return `.${filepath.slice(i)}`
return filepath
},
}

20
src/logger.js

@ -3,6 +3,7 @@
import winston from 'winston' import winston from 'winston'
import Transport from 'winston-transport' import Transport from 'winston-transport'
import resolveLogsDirectory, { RotatingLogFileParameters } from 'helpers/resolveLogsDirectory' import resolveLogsDirectory, { RotatingLogFileParameters } from 'helpers/resolveLogsDirectory'
import anonymizer from 'helpers/anonymizer'
import { import {
DEBUG_NETWORK, DEBUG_NETWORK,
@ -85,13 +86,6 @@ const logger = winston.createLogger({
transports, transports,
}) })
const anonymousMode = !__DEV__
function anonymizeURL(url) {
if (!anonymousMode) return url
return url.replace(/\/addresses\/[^/]+/g, '/addresses/<HIDDEN>')
}
const logCmds = !__DEV__ || DEBUG_COMMANDS const logCmds = !__DEV__ || DEBUG_COMMANDS
const logDb = !__DEV__ || DEBUG_DB const logDb = !__DEV__ || DEBUG_DB
const logRedux = !__DEV__ || DEBUG_ACTION const logRedux = !__DEV__ || DEBUG_ACTION
@ -165,7 +159,7 @@ export default {
}, },
network: ({ method, url }: { method: string, url: string }) => { network: ({ method, url }: { method: string, url: string }) => {
const log = `➡📡 ${method} ${anonymizeURL(url)}` const log = `➡📡 ${method} ${anonymizer.url(url)}`
if (logNetwork) { if (logNetwork) {
logger.log('info', log, { type: 'network' }) logger.log('info', log, { type: 'network' })
} }
@ -182,7 +176,7 @@ export default {
status: number, status: number,
responseTime: number, responseTime: number,
}) => { }) => {
const log = `✔📡 HTTP ${status} ${method} ${anonymizeURL( const log = `✔📡 HTTP ${status} ${method} ${anonymizer.url(
url, url,
)} finished in ${responseTime.toFixed(0)}ms` )} finished in ${responseTime.toFixed(0)}ms`
if (logNetwork) { if (logNetwork) {
@ -203,7 +197,7 @@ export default {
error: string, error: string,
responseTime: number, responseTime: number,
}) => { }) => {
const log = `✖📡 HTTP ${status} ${method} ${anonymizeURL( const log = `✖📡 HTTP ${status} ${method} ${anonymizer.url(
url, url,
)} ${error} failed after ${responseTime.toFixed(0)}ms` )} ${error} failed after ${responseTime.toFixed(0)}ms`
if (logNetwork) { if (logNetwork) {
@ -220,9 +214,9 @@ export default {
url: string, url: string,
responseTime: number, responseTime: number,
}) => { }) => {
const log = `✖📡 NETWORK DOWN – ${method} ${anonymizeURL(url)} – after ${responseTime.toFixed( const log = `✖📡 NETWORK DOWN – ${method} ${anonymizer.url(
0, url,
)}ms` )} after ${responseTime.toFixed(0)}ms`
if (logNetwork) { if (logNetwork) {
logger.log('info', log, { type: 'network-down' }) logger.log('info', log, { type: 'network-down' })
} }

56
src/sentry/install.js

@ -1,4 +1,6 @@
// @flow // @flow
import anonymizer from 'helpers/anonymizer'
/* eslint-disable no-continue */
require('../env') require('../env')
@ -11,6 +13,60 @@ export default (Raven: any, shouldSendCallback: () => boolean, userId: string) =
tags: { git_commit: __GIT_REVISION__ }, tags: { git_commit: __GIT_REVISION__ },
environment: __DEV__ ? 'development' : 'production', environment: __DEV__ ? 'development' : 'production',
shouldSendCallback, shouldSendCallback,
dataCallback: (data: mixed) => {
// We are mutating the data to anonymize everything.
if (typeof data !== 'object' || !data) return data
delete data.server_name // hides the user machine name
if (typeof data.request === 'object' && data.request) {
const { request } = data
if (typeof request.url === 'string') {
request.url = anonymizer.appURI(request.url)
}
}
if (data.breadcrumbs && typeof data.breadcrumbs === 'object') {
const { breadcrumbs } = data
if (Array.isArray(breadcrumbs.values)) {
const { values } = breadcrumbs
for (const b of values) {
if (!b || typeof b !== 'object') continue
if (b.category === 'xhr' && b.data && typeof b.data === 'object') {
const { data } = b
if (typeof data.url === 'string') {
data.url = anonymizer.url(data.url)
}
}
}
}
}
if (data.exception && typeof data.exception === 'object') {
const { exception } = data
if (Array.isArray(exception.values)) {
const { values } = exception
for (const value of values) {
if (value && typeof value === 'object') {
const { stacktrace } = value
if (stacktrace && typeof stacktrace === 'object') {
if (Array.isArray(stacktrace.frames)) {
const { frames } = stacktrace
for (const frame of frames) {
if (frame && typeof frame === 'object' && typeof frame.filename === 'string') {
frame.filename = anonymizer.filepath(frame.filename)
}
}
}
}
}
}
}
}
console.log('Sentry=>', data) // eslint-disable-line
return data
},
}) })
const user = { const user = {
ip_address: null, ip_address: null,

Loading…
Cancel
Save