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.
import { Observable } from 'rxjs'
import { createCommand, Command } from 'helpers/ipc'
type Input = void
type Result = void
const cmd: Command<Input, Result> = createCommand('testCrash', () =>
Observable.create(() => {
process.exit(1)
}),
)
const cmd: Command<Input, Result> = createCommand('testCrash', () => {
// $FlowFixMe
crashTest() // eslint-disable-line
throw new Error()
})
export default cmd

13
src/components/modals/Debug.js

@ -31,12 +31,16 @@ class Debug extends Component<*, *> {
)
}
onCrash = () => {
onInternalCrash = () => {
testCrash.send().subscribe({
error: this.error,
})
}
onCrashHere = () => {
throw new Error('CrashTest')
}
onClickStressDevice = (device: *) => async () => {
try {
const currency = getCryptoCurrencyById('bitcoin')
@ -142,8 +146,11 @@ class Debug extends Component<*, *> {
</Box>
)}
<Box horizontal style={{ padding: 10 }}>
<Button onClick={this.onCrash} danger>
crash process
<Button mr={2} onClick={this.onInternalCrash} danger>
crash internal
</Button>
<Button onClick={this.onCrashHere} danger>
crash here
</Button>
</Box>
<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 Transport from 'winston-transport'
import resolveLogsDirectory, { RotatingLogFileParameters } from 'helpers/resolveLogsDirectory'
import anonymizer from 'helpers/anonymizer'
import {
DEBUG_NETWORK,
@ -85,13 +86,6 @@ const logger = winston.createLogger({
transports,
})
const anonymousMode = !__DEV__
function anonymizeURL(url) {
if (!anonymousMode) return url
return url.replace(/\/addresses\/[^/]+/g, '/addresses/<HIDDEN>')
}
const logCmds = !__DEV__ || DEBUG_COMMANDS
const logDb = !__DEV__ || DEBUG_DB
const logRedux = !__DEV__ || DEBUG_ACTION
@ -165,7 +159,7 @@ export default {
},
network: ({ method, url }: { method: string, url: string }) => {
const log = `➡📡 ${method} ${anonymizeURL(url)}`
const log = `➡📡 ${method} ${anonymizer.url(url)}`
if (logNetwork) {
logger.log('info', log, { type: 'network' })
}
@ -182,7 +176,7 @@ export default {
status: number,
responseTime: number,
}) => {
const log = `✔📡 HTTP ${status} ${method} ${anonymizeURL(
const log = `✔📡 HTTP ${status} ${method} ${anonymizer.url(
url,
)} finished in ${responseTime.toFixed(0)}ms`
if (logNetwork) {
@ -203,7 +197,7 @@ export default {
error: string,
responseTime: number,
}) => {
const log = `✖📡 HTTP ${status} ${method} ${anonymizeURL(
const log = `✖📡 HTTP ${status} ${method} ${anonymizer.url(
url,
)} ${error} failed after ${responseTime.toFixed(0)}ms`
if (logNetwork) {
@ -220,9 +214,9 @@ export default {
url: string,
responseTime: number,
}) => {
const log = `✖📡 NETWORK DOWN – ${method} ${anonymizeURL(url)} – after ${responseTime.toFixed(
0,
)}ms`
const log = `✖📡 NETWORK DOWN – ${method} ${anonymizer.url(
url,
)} after ${responseTime.toFixed(0)}ms`
if (logNetwork) {
logger.log('info', log, { type: 'network-down' })
}

56
src/sentry/install.js

@ -1,4 +1,6 @@
// @flow
import anonymizer from 'helpers/anonymizer'
/* eslint-disable no-continue */
require('../env')
@ -11,6 +13,60 @@ export default (Raven: any, shouldSendCallback: () => boolean, userId: string) =
tags: { git_commit: __GIT_REVISION__ },
environment: __DEV__ ? 'development' : 'production',
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 = {
ip_address: null,

Loading…
Cancel
Save