Browse Source

add logger to have more logs logged!

master
Gaëtan Renaudeau 7 years ago
parent
commit
fb41a3fdd1
  1. 2
      .eslintrc
  2. 5
      src/api/Ledger.js
  3. 5
      src/api/Ripple.js
  4. 8
      src/bridge/BridgeSyncContext.js
  5. 3
      src/bridge/LibcoreBridge.js
  6. 3
      src/bridge/makeMockBridge.js
  7. 1
      src/commands/isCurrencyAppOpened.js
  8. 3
      src/commands/listenDevices.js
  9. 11
      src/components/DashboardPage/AccountsOrder.js
  10. 3
      src/components/EnsureDeviceApp/index.js
  11. 8
      src/components/GenuineCheckModal/index.js
  12. 3
      src/components/ManagerPage/FirmwareUpdate.js
  13. 3
      src/components/QRCodeCameraPickerCanvas.js
  14. 3
      src/components/SelectExchange.js
  15. 10
      src/components/base/SideBar/SideBarListItem.js
  16. 3
      src/helpers/countervalues.js
  17. 9
      src/helpers/ipc.js
  18. 5
      src/helpers/libcore.js
  19. 4
      src/helpers/promise.js
  20. 3
      src/helpers/withLibcore.js
  21. 7
      src/internals/index.js
  22. 45
      src/logger.js
  23. 7
      src/main/bridge.js
  24. 8
      src/middlewares/logger.js
  25. 3
      src/reducers/accounts.js
  26. 3
      src/renderer/createStore.js
  27. 5
      src/renderer/events.js
  28. 17
      src/renderer/init.js

2
.eslintrc

@ -43,7 +43,7 @@
"no-return-assign": 0,
"no-shadow": 0,
"no-underscore-dangle": 0,
"no-console": [1, { "allow": [ "warn", "error" ] }],
"no-console": 2,
"no-unused-vars": ["error", { "argsIgnorePattern": "^_", "vars": "all", "args": "after-used", "ignoreRestSiblings": true }],
"no-use-before-define": 0,
"no-restricted-syntax": 0,

5
src/api/Ledger.js

@ -1,5 +1,6 @@
// @flow
import type { Currency } from '@ledgerhq/live-common/lib/types'
import logger from 'logger'
const BASE_URL = process.env.LEDGER_REST_API_BASE || 'https://api.ledgerwallet.com/'
@ -20,13 +21,13 @@ export const userFriendlyError = <A>(p: Promise<A>): Promise<A> =>
throw new Error(message)
}
} catch (e) {
console.log(e)
logger.warn("can't parse server result", e)
}
}
throw new Error(msg)
}
}
console.log('Ledger API: HTTP status', error.response.status, 'data: ', error.response.data)
logger.log('Ledger API: HTTP status', error.response.status, 'data: ', error.response.data)
throw new Error('A problem occurred with Ledger Servers. Please try again later.')
} else if (error.request) {
// The request was made but no response was received

5
src/api/Ripple.js

@ -1,4 +1,5 @@
// @flow
import logger from 'logger'
import { RippleAPI } from 'ripple-lib'
import type { CryptoCurrency } from '@ledgerhq/live-common/lib/types'
import {
@ -18,7 +19,7 @@ export const apiForCurrency = (currency: CryptoCurrency) => {
server: apiEndpoint[currency.id],
})
api.on('error', (errorCode, errorMessage) => {
console.warn(`Ripple API error: ${errorCode}: ${errorMessage}`)
logger.warn(`Ripple API error: ${errorCode}: ${errorMessage}`)
})
return api
}
@ -33,7 +34,7 @@ export const parseAPICurrencyObject = ({
value: string,
}) => {
if (currency !== 'XRP') {
console.warn(`RippleJS: attempt to parse unknown currency ${currency}`)
logger.warn(`RippleJS: attempt to parse unknown currency ${currency}`)
return 0
}
return parseAPIValue(value)

8
src/bridge/BridgeSyncContext.js

@ -1,4 +1,5 @@
// @flow
import logger from 'logger'
import React, { Component } from 'react'
import { connect } from 'react-redux'
import type { Account } from '@ledgerhq/live-common/lib/types'
@ -150,7 +151,7 @@ class Provider extends Component<BridgeSyncProviderOwnProps, BridgeSync> {
try {
await this.api.syncAll()
} catch (e) {
console.error('sync issues', e)
logger.error('sync issues', e)
}
setTimeout(syncLoop, 10 * 1000)
}
@ -170,6 +171,9 @@ class Provider extends Component<BridgeSyncProviderOwnProps, BridgeSync> {
}
}
export const BridgeSyncProvider = connect(mapStateToProps, actions)(Provider)
export const BridgeSyncProvider = connect(
mapStateToProps,
actions,
)(Provider)
export const BridgeSyncConsumer = BridgeSyncContext.Consumer

3
src/bridge/LibcoreBridge.js

@ -1,4 +1,5 @@
// @flow
import logger from 'logger'
import React from 'react'
import { map } from 'rxjs/operators'
import type { Account } from '@ledgerhq/live-common/lib/types'
@ -93,7 +94,7 @@ const LibcoreBridge: WalletBridge<Transaction> = {
})()
return {
unsubscribe() {
console.warn('LibcoreBridge: unsub sync not implemented')
logger.warn('LibcoreBridge: unsub sync not implemented')
},
}
},

3
src/bridge/makeMockBridge.js

@ -1,4 +1,5 @@
// @flow
import logger from 'logger'
import {
genAccount,
genAddingOperationsInAccount,
@ -45,7 +46,7 @@ function makeMockBridge(opts?: Opts): WalletBridge<*> {
const accountId = initialAccount.id
if (syncTimeouts[accountId]) {
// this is just for tests. we'll assume impl don't need to handle race condition on this function.
console.warn('synchronize was called multiple pending time for same accounts!!!')
logger.warn('synchronize was called multiple pending time for same accounts!!!')
}
syncTimeouts[accountId] = setTimeout(() => {
if (Math.random() < syncSuccessRate) {

1
src/commands/isCurrencyAppOpened.js

@ -43,7 +43,6 @@ const cmd: Command<Input, Result> = createCommand(
// in case of ETH / XRP, the address derivation is enough
return true
} catch (e) {
console.log(e)
// if anything failed, it does not pass
return false
}

3
src/commands/listenDevices.js

@ -1,5 +1,6 @@
// @flow
import logger from 'logger'
import { createCommand } from 'helpers/ipc'
import { Observable } from 'rxjs'
import CommNodeHid from '@ledgerhq/hw-transport-node-hid'
@ -16,7 +17,7 @@ const cmd = createCommand('listenDevices', () =>
case 'add': {
const pendingRemove = pendingRemovePerPath[e.descriptor]
if (pendingRemove) {
console.warn(`Skipping remove/add usb event for ${e.descriptor}`)
logger.warn(`Skipping remove/add usb event for ${e.descriptor}`)
// there where a recent "remove" event, we don't emit add because we didn't emit "remove" yet.
clearTimeout(pendingRemove)
delete pendingRemovePerPath[e.descriptor]

11
src/components/DashboardPage/AccountsOrder.js

@ -1,5 +1,6 @@
// @flow
import logger from 'logger'
import React, { Component } from 'react'
import styled from 'styled-components'
import { compose } from 'redux'
@ -63,7 +64,7 @@ function sortAccounts(accounts: Account[], orderAccounts: string, props: Props)
}
return ids
}
console.warn(`sortAccounts not implemented for ${orderAccounts}`)
logger.warn(`sortAccounts not implemented for ${orderAccounts}`)
return null
}
@ -220,4 +221,10 @@ class AccountsOrder extends Component<Props> {
}
}
export default compose(connect(mapStateToProps, mapDispatchToProps), translate())(AccountsOrder)
export default compose(
connect(
mapStateToProps,
mapDispatchToProps,
),
translate(),
)(AccountsOrder)

3
src/components/EnsureDeviceApp/index.js

@ -1,6 +1,7 @@
// @flow
import { PureComponent } from 'react'
import { connect } from 'react-redux'
import logger from 'logger'
import type { Account, CryptoCurrency } from '@ledgerhq/live-common/lib/types'
import type { Device } from 'types/common'
@ -125,7 +126,7 @@ class EnsureDeviceApp extends PureComponent<Props, State> {
.toPromise()
const { freshAddress } = account
if (account && freshAddress !== address) {
console.warn({ freshAddress, address })
logger.warn({ freshAddress, address })
throw new Error('Account address is different than device address')
}
} else if (currency) {

8
src/components/GenuineCheckModal/index.js

@ -1,5 +1,6 @@
// @flow
import logger from 'logger'
import React, { PureComponent } from 'react'
import { compose } from 'redux'
import { connect } from 'react-redux'
@ -42,7 +43,7 @@ class GenuineCheck extends PureComponent<Props, State> {
withGenuineCheck
onGenuineCheck={onGenuineCheck}
onStatusChange={status => {
console.log(`status changed to ${status}`)
logger.log(`status changed to ${status}`)
}}
render={({ appStatus, genuineCheckStatus, deviceSelected, errorMessage }) => (
<DeviceConnect
@ -68,4 +69,7 @@ class GenuineCheck extends PureComponent<Props, State> {
}
}
export default compose(connect(mapStateToProps), translate())(GenuineCheck)
export default compose(
connect(mapStateToProps),
translate(),
)(GenuineCheck)

3
src/components/ManagerPage/FirmwareUpdate.js

@ -1,5 +1,6 @@
// @flow
import logger from 'logger'
import React, { PureComponent } from 'react'
import isEqual from 'lodash/isEqual'
import isEmpty from 'lodash/isEmpty'
@ -82,7 +83,7 @@ class FirmwareUpdate extends PureComponent<Props, State> {
this.fetchLatestFirmware()
}
} catch (err) {
console.log(err)
logger.log(err)
}
}

3
src/components/QRCodeCameraPickerCanvas.js

@ -2,6 +2,7 @@
import React, { Component } from 'react'
import QrCode from 'qrcode-reader'
import logger from 'logger'
export default class QRCodeCameraPickerCanvas extends Component<
{
@ -88,7 +89,7 @@ export default class QRCodeCameraPickerCanvas extends Component<
try {
video.play()
} catch (e) {
console.error(e)
logger.error(e)
}
let lastCheck = 0
let raf

3
src/components/SelectExchange.js

@ -2,6 +2,7 @@
import React, { Component } from 'react'
import type { Currency } from '@ledgerhq/live-common/lib/types'
import type { Exchange } from '@ledgerhq/live-common/lib/countervalues/types'
import logger from 'logger'
import Select from 'components/base/Select'
import Spinner from 'components/base/Spinner'
@ -67,7 +68,7 @@ class ExchangeSelect extends Component<
this.setState({ exchanges })
}
} catch (error) {
console.error(error)
logger.error(error)
if (!this._unmounted && this._loadId === _loadId) {
this.setState({ error })
}

10
src/components/base/SideBar/SideBarListItem.js

@ -24,11 +24,17 @@ export type Props = {
class SideBarListItem extends PureComponent<Props> {
render() {
const {
item: { icon: Icon, label, desc, iconActiveColor, hasNotif, onClick },
item: { icon: Icon, label, desc, iconActiveColor, hasNotif, onClick, value },
isActive,
} = this.props
return (
<Container isActive={isActive} iconActiveColor={iconActiveColor} onClick={onClick}>
<Container
data-role="side-bar-item"
data-roledata={value}
isActive={isActive}
iconActiveColor={iconActiveColor}
onClick={onClick}
>
{!!Icon && <Icon size={16} />}
<Box grow shrink>
{typeof label === 'function' ? (

3
src/helpers/countervalues.js

@ -10,6 +10,7 @@ import {
currencySettingsSelector,
intermediaryCurrency,
} from 'reducers/settings'
import logger from 'logger'
const pairsSelector = createSelector(
currenciesSelector,
@ -49,7 +50,7 @@ const addExtraPollingHooks = (schedulePoll, cancelPoll) => {
}
const CounterValues = createCounterValues({
log: (...args) => console.log('CounterValues:', ...args), // eslint-disable-line no-console
log: (...args) => logger.log('CounterValues:', ...args),
getAPIBaseURL: () => 'https://ledger-countervalue-poc.herokuapp.com',
storeSelector: state => state.countervalues,
pairsSelector,

9
src/helpers/ipc.js

@ -1,4 +1,5 @@
// @flow
import logger from 'logger'
import { Observable } from 'rxjs'
import uuidv4 from 'uuid/v4'
@ -48,20 +49,20 @@ function ipcRendererSendCommand<In, A>(id: string, data: In): Observable<A> {
if (requestId !== msg.requestId) return
switch (msg.type) {
case 'NEXT':
console.log(`● CMD ${id}`, msg.data)
logger.log(`● CMD ${id}`, msg.data)
if (msg.data) {
o.next(msg.data)
}
break
case 'COMPLETE':
console.log(`✔ CMD ${id} finished in ${(Date.now() - startTime).toFixed(0)}ms`)
logger.log(`✔ CMD ${id} finished in ${(Date.now() - startTime).toFixed(0)}ms`)
o.complete()
ipcRenderer.removeListener('command-event', handleCommandEvent)
break
case 'ERROR':
console.warn(`✖ CMD ${id} error`, msg.data)
logger.warn(`✖ CMD ${id} error`, msg.data)
o.error(msg.data)
ipcRenderer.removeListener('command-event', handleCommandEvent)
break
@ -74,7 +75,7 @@ function ipcRendererSendCommand<In, A>(id: string, data: In): Observable<A> {
ipcRenderer.send('command', { id, data, requestId })
console.log(`CMD ${id}.send(`, data, ')')
logger.log(`CMD ${id}.send(`, data, ')')
return unsubscribe
})

5
src/helpers/libcore.js

@ -1,5 +1,6 @@
// @flow
import logger from 'logger'
import Btc from '@ledgerhq/hw-app-btc'
import { withDevice } from 'helpers/deviceAccess'
import { getCryptoCurrencyById } from '@ledgerhq/live-common/lib/helpers/currencies'
@ -216,12 +217,10 @@ async function buildAccountRaw({
}: {
njsAccount: NJSAccount,
isSegwit: boolean,
// $FlowFixMe
wallet: NJSWallet,
currencyId: string,
accountIndex: number,
core: *,
// $FlowFixMe
ops: NJSOperation[],
}): Promise<AccountRaw> {
const njsBalance = await njsAccount.getBalance()
@ -373,7 +372,7 @@ export async function syncAccount({
syncedRawAccount.balance = njsBalance.toLong()
console.log(`Synced account [${syncedRawAccount.name}]: ${syncedRawAccount.balance}`)
logger.log(`Synced account [${syncedRawAccount.name}]: ${syncedRawAccount.balance}`)
return syncedRawAccount
}

4
src/helpers/promise.js

@ -1,5 +1,5 @@
// @flow
import logger from 'logger'
// small utilities for Promises
export const delay = (ms: number): Promise<void> => new Promise(f => setTimeout(f, ms))
@ -21,7 +21,7 @@ export function retry<A>(f: () => Promise<A>, options?: $Shape<typeof defaults>)
}
// In case of failure, wait the interval, retry the action
return result.catch(e => {
console.warn('Promise#retry', e)
logger.warn('Promise#retry', e)
return delay(interval).then(() => rec(remainingTry - 1, interval * intervalMultiplicator))
})
}

3
src/helpers/withLibcore.js

@ -1,6 +1,7 @@
// @flow
import invariant from 'invariant'
import logger from 'logger'
const core = require('@ledgerhq/ledger-core')
@ -23,7 +24,7 @@ export default function withLibcore<A>(job: Job<A>): Promise<A> {
const p = queue.then(() => job(core, walletPool))
queue = p.catch(e => {
console.warn(`withLibCore: Error in job`, e)
logger.warn(`withLibCore: Error in job`, e)
})
return p

7
src/internals/index.js

@ -1,5 +1,6 @@
// @flow
import commands from 'commands'
import logger from 'logger'
require('../env')
require('../init-sentry')
@ -13,7 +14,7 @@ process.on('message', m => {
const { data, requestId, id } = m.command
const cmd = commands.find(cmd => cmd.id === id)
if (!cmd) {
console.warn(`command ${id} not found`)
logger.warn(`command ${id} not found`)
return
}
subscriptions[requestId] = cmd.impl(data).subscribe({
@ -32,7 +33,7 @@ process.on('message', m => {
})
},
error: error => {
console.warn('Command error:', error)
logger.warn('Command error:', error)
delete subscriptions[requestId]
process.send({
type: 'ERROR',
@ -55,4 +56,4 @@ process.on('message', m => {
}
})
console.log('Internal process is up!')
logger.log('Internal process is up!')

45
src/logger.js

@ -0,0 +1,45 @@
// @flow
/* eslint-disable no-console */
/**
* IDEA:
* logger is an alternative to use for console.log that will be used for many purposes:
* - provide useful data for debugging during dev (idea is to have opt-in env var)
* - enabled in prod to provide useful data to debug when sending to Sentry
* - for analytics in the future
*/
export default {
// tracks the user interactions (click, input focus/blur, what else?)
onClickElement: (role: string, roleData: ?Object) => {
if (!__DEV__ || process.env.DEBUG_CLICK_ELEMENT) {
const label = `👆 ${role}`
if (roleData) {
console.log(label, roleData)
} else {
console.log(label)
}
}
},
// tracks Redux actions (NB not all actions are serializable)
onReduxAction: (action: Object) => {
if (!__DEV__ || process.env.DEBUG_ACTION) {
console.log(`⚛️ ${action.type}`, action)
}
},
// General functions in case the hooks don't apply
log: (...args: any) => {
console.log(...args)
},
warn: (...args: any) => {
console.warn(...args)
},
error: (...args: any) => {
console.error(...args)
},
}

7
src/main/bridge.js

@ -6,6 +6,7 @@ import { fork } from 'child_process'
import { ipcMain, app } from 'electron'
import { ipcMainListenReceiveCommands } from 'helpers/ipc'
import path from 'path'
import logger from 'logger'
import setupAutoUpdater, { quitAndInstall } from './autoUpdate'
@ -16,7 +17,7 @@ let internalProcess
const killInternalProcess = () => {
if (internalProcess) {
console.log('killing internal process...')
logger.log('killing internal process...')
internalProcess.kill('SIGINT')
internalProcess = null
}
@ -25,12 +26,12 @@ const killInternalProcess = () => {
const forkBundlePath = path.resolve(__dirname, `${__DEV__ ? '../../' : './'}dist/internals`)
const bootInternalProcess = () => {
console.log('booting internal process...')
logger.log('booting internal process...')
internalProcess = fork(forkBundlePath, {
env: { ...process.env, LEDGER_LIVE_SQLITE_PATH },
})
internalProcess.on('exit', code => {
console.log(`Internal process ended with code ${code}`)
logger.warn(`Internal process ended with code ${code}`)
internalProcess = null
})
}

8
src/middlewares/logger.js

@ -0,0 +1,8 @@
// @flow
import logger from 'logger'
export default () => (next: *) => (action: *) => {
logger.onReduxAction(action)
return next(action)
}

3
src/reducers/accounts.js

@ -3,6 +3,7 @@
import { createSelector } from 'reselect'
import { handleActions } from 'redux-actions'
import { createAccountModel } from '@ledgerhq/live-common/lib/models/account'
import logger from 'logger'
import type { Account, AccountRaw } from '@ledgerhq/live-common/lib/types'
@ -25,7 +26,7 @@ const handlers: Object = {
{ payload: account }: { payload: Account },
): AccountsState => {
if (state.some(a => a.id === account.id)) {
console.warn('ADD_ACCOUNT attempt for an account that already exists!', account.id)
logger.warn('ADD_ACCOUNT attempt for an account that already exists!', account.id)
return state
}
return [...state, account]

3
src/renderer/createStore.js

@ -5,6 +5,7 @@ import { routerMiddleware } from 'react-router-redux'
import thunk from 'redux-thunk'
import createHistory from 'history/createHashHistory'
import type { HashHistory } from 'history'
import logger from 'middlewares/logger'
import reducers from 'reducers'
@ -19,7 +20,7 @@ export default ({ state, history, dbMiddleware }: Props) => {
if (!history) {
history = createHistory()
}
const middlewares = [routerMiddleware(history), thunk]
const middlewares = [routerMiddleware(history), thunk, logger]
if (dbMiddleware) {
middlewares.push(dbMiddleware)
}

5
src/renderer/events.js

@ -9,6 +9,7 @@
// events should all appear in the promise result / observer msgs as soon as they have this requestId
import 'commands'
import logger from 'logger'
import { ipcRenderer } from 'electron'
import debug from 'debug'
@ -64,12 +65,12 @@ export default ({ store }: { store: Object, locked: boolean }) => {
}
},
error => {
console.warn('listenDevices error', error)
logger.warn('listenDevices error', error)
store.dispatch(resetDevices())
syncDevices()
},
() => {
console.warn('listenDevices ended unexpectedly. restarting')
logger.warn('listenDevices ended unexpectedly. restarting')
store.dispatch(resetDevices())
syncDevices()
},

17
src/renderer/init.js

@ -1,5 +1,6 @@
// @flow
import logger from 'logger'
import React from 'react'
import { remote } from 'electron'
import { render } from 'react-dom'
@ -73,12 +74,24 @@ async function init() {
events({ store, locked })
const libcoreVersion = await libcoreGetVersion.send().toPromise()
console.log('libcore', libcoreVersion)
logger.log('libcore', libcoreVersion)
// DOM elements can have a data-role that identify the UI entity
// and that allow us to track interactions with this.
window.addEventListener('click', ({ target }) => {
const { dataset } = target
if (dataset) {
const { role, roledata } = dataset
if (role) {
logger.onClickElement(role, roledata)
}
}
})
}
}
init().catch(e => {
// for now we make the app crash instead of pending forever. later we can render the error OR try to recover, but probably this is unrecoverable cases.
console.error(e)
logger.error(e)
process.exit(1)
})

Loading…
Cancel
Save