Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Add tags to custom traces #11623

Merged
merged 39 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
3071e27
feat: Add custom traces
MarioAslau Oct 2, 2024
f2c4baf
feat: add custom operation name
MarioAslau Oct 2, 2024
e13f650
feat: revert integrations hardcode
MarioAslau Oct 3, 2024
ece30ea
Merge branch 'main' into feat/1940-add-custom-sentry-span
MarioAslau Oct 3, 2024
8e423eb
add tags file and folder
tommasini Oct 4, 2024
401c6ff
add selectAllTokens and selectAllNfts selectors
tommasini Oct 4, 2024
cfc0143
sentry tags completed without the tag for opening by data, if it was …
tommasini Oct 7, 2024
67efec1
mimic extension on adding measurements to the spans
tommasini Oct 7, 2024
7faddb9
feat: updated Spans
MarioAslau Oct 11, 2024
1e01700
Merge branch 'feat/1940-add-custom-sentry-span' into chore/custom-spa…
tommasini Oct 11, 2024
d204e06
feat: add op for Load Scripts trace
MarioAslau Oct 11, 2024
92eac78
Merge branch 'feat/1940-add-custom-sentry-span' into chore/custom-spa…
tommasini Oct 14, 2024
13f9704
Merge branch 'main' into feat/1940-add-custom-sentry-span
MarioAslau Oct 14, 2024
a405e11
feat: fix main merge
MarioAslau Oct 14, 2024
7bf0951
merge custom span branch
tommasini Oct 14, 2024
2607a95
remove comment and rmeove log
tommasini Oct 14, 2024
adc9bb9
feat: add custom span for biometrics
MarioAslau Oct 15, 2024
6ecba9e
feat: trace file lint
MarioAslau Oct 15, 2024
c13b801
Merge branch 'main' into feat/1940-add-custom-sentry-span
MarioAslau Oct 15, 2024
62dd6e7
feat: remove console.log
MarioAslau Oct 15, 2024
b1f17cb
Merge branch 'feat/1940-add-custom-sentry-span' of https://github.com…
MarioAslau Oct 15, 2024
92d0d16
Merge branch 'main' into feat/1940-add-custom-sentry-span
MarioAslau Oct 15, 2024
82a324c
merge custom span branch
tommasini Oct 15, 2024
01563c2
fix unit test
tommasini Oct 15, 2024
3dbdbdd
feat: onboarding tweak
MarioAslau Oct 15, 2024
363c9d0
Merge branch 'feat/1940-add-custom-sentry-span' of https://github.com…
MarioAslau Oct 15, 2024
7813162
feat: engine tweak
MarioAslau Oct 15, 2024
2e8439b
Merge branch 'main' into feat/1940-add-custom-sentry-span
MarioAslau Oct 15, 2024
28bb5b9
feat: triggerLogIn tweak
MarioAslau Oct 15, 2024
13f7674
Merge branch 'feat/1940-add-custom-sentry-span' of https://github.com…
MarioAslau Oct 15, 2024
a08894a
Merge branch 'feat/1940-add-custom-sentry-span' into chore/custom-spa…
tommasini Oct 15, 2024
a385d44
fix duplicated import
tommasini Oct 15, 2024
907d093
merge main and solve conflicts
tommasini Oct 15, 2024
cd0386d
Merge branch 'main' into chore/custom-span-sentry-tags
tommasini Oct 16, 2024
b862276
fix tags at fresh install
tommasini Oct 16, 2024
ab262ee
Merge branch 'main' into chore/custom-span-sentry-tags
tommasini Oct 16, 2024
ccceec1
fix lint issue
tommasini Oct 16, 2024
6c8ac83
NotificationServicesController default state added to fixture builder
tommasini Oct 16, 2024
6e701cd
Merge branch 'main' into chore/custom-span-sentry-tags
tommasini Oct 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion app/selectors/nftController.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createSelector } from 'reselect';
import { NftControllerState } from '@metamask/assets-controllers';
import { Nft, NftControllerState } from '@metamask/assets-controllers';
import { RootState } from '../reducers';

const selectNftControllerState = (state: RootState) =>
Expand All @@ -15,3 +15,14 @@ export const selectAllNfts = createSelector(
selectNftControllerState,
(nftControllerState: NftControllerState) => nftControllerState.allNfts,
);

export const selectAllNftsFlat = createSelector(
selectAllNfts,
(nftsByChainByAccount) => {
const nftsByChainArray = Object.values(nftsByChainByAccount);
return nftsByChainArray.reduce((acc, nftsByChain) => {
const nftsArrays = Object.values(nftsByChain);
return acc.concat(...nftsArrays);
}, [] as Nft[]);
},
);
21 changes: 21 additions & 0 deletions app/selectors/tokensController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,24 @@ export const selectDetectedTokens = createSelector(
(tokensControllerState: TokensControllerState) =>
tokensControllerState?.detectedTokens,
);

const selectAllTokens = createSelector(
selectTokensControllerState,
(tokensControllerState: TokensControllerState) =>
tokensControllerState?.allTokens,
);

export const selectAllTokensFlat = createSelector(
selectAllTokens,
(tokensByAccountByChain) => {
if (Object.values(tokensByAccountByChain).length === 0) {
return [];
}
const tokensByAccountArray = Object.values(tokensByAccountByChain);

return tokensByAccountArray.reduce((acc, tokensByAccount) => {
const tokensArray = Object.values(tokensByAccount);
return acc.concat(...tokensArray);
}, [] as Token[]);
},
);
2 changes: 2 additions & 0 deletions app/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import thunk from 'redux-thunk';

import persistConfig from './persistConfig';
import { AppStateEventProcessor } from '../core/AppStateEventListener';
import { getTraceTags } from '../util/sentry/tags';

// TODO: Improve type safety by using real Action types instead of `any`
// TODO: Replace "any" with type
Expand Down Expand Up @@ -119,6 +120,7 @@ const createStoreAndPersistor = async (appStartTime: number) => {
{
name: TraceName.EngineInitialization,
op: TraceOperation.EngineInitialization,
tags: getTraceTags(store.getState?.()),
},
() => {
EngineService.initalizeEngine(store);
Expand Down
229 changes: 229 additions & 0 deletions app/util/sentry/tags/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
import { RootState } from '../../../reducers';
import { getTraceTags } from './';
import initialRootState, {
backgroundState,
} from '../../../util/test/initial-root-state';
import { userInitialState } from '../../../reducers/user';
import { createMockAccountsControllerState } from '../../../util/test/accountsControllerTestUtils';

describe('Tags Utils', () => {
beforeEach(() => {
jest.resetAllMocks();
});

describe('getTraceTags', () => {
it('includes if unlocked', () => {
const state = {
...initialRootState,
user: { ...userInitialState, userLoggedIn: true },
};

const tags = getTraceTags(state);

expect(tags?.['wallet.unlocked']).toStrictEqual(true);
});

it('includes if not unlocked', () => {
const state = {
...initialRootState,
user: { ...userInitialState, userLoggedIn: false },
};

const tags = getTraceTags(state);

expect(tags?.['wallet.unlocked']).toStrictEqual(false);
});

it('includes pending approval type', () => {
const state = {
...initialRootState,
engine: {
backgroundState: {
...backgroundState,
ApprovalController: {
...backgroundState.ApprovalController,
pendingApprovals: {
1: {
type: 'eth_sendTransaction',
},
},
},
},
},
} as unknown as RootState;

const tags = getTraceTags(state);

expect(tags?.['wallet.pending_approval']).toStrictEqual(
'eth_sendTransaction',
);
});

it('includes first pending approval type if multiple', () => {
const state = {
...initialRootState,
engine: {
backgroundState: {
...backgroundState,

ApprovalController: {
...backgroundState.ApprovalController,
pendingApprovals: {
1: {
type: 'eth_sendTransaction',
},
2: {
type: 'personal_sign',
},
},
},
},
},
} as unknown as RootState;

const tags = getTraceTags(state);

expect(tags?.['wallet.pending_approval']).toStrictEqual(
'eth_sendTransaction',
);
});

it('includes account count', () => {
const state = {
...initialRootState,
engine: {
backgroundState: {
...backgroundState,
AccountsController: createMockAccountsControllerState([
'0x1234',
'0x4321',
]),
},
},
} as unknown as RootState;

const tags = getTraceTags(state);

expect(tags?.['wallet.account_count']).toStrictEqual(2);
});

it('includes nft count', () => {
const state = {
...initialRootState,
engine: {
backgroundState: {
...backgroundState,
NftController: {
...backgroundState.NftController,
allNfts: {
'0x1234': {
'0x1': [
{
tokenId: '1',
},
{
tokenId: '2',
},
],
'0x2': [
{
tokenId: '3',
},
{
tokenId: '4',
},
],
},
'0x4321': {
'0x3': [
{
tokenId: '5',
},
],
},
},
},
},
},
} as unknown as RootState;

const tags = getTraceTags(state);

expect(tags?.['wallet.nft_count']).toStrictEqual(5);
});

it('includes notification count', () => {
const state = {
...initialRootState,
engine: {
backgroundState: {
...backgroundState,
NotificationServicesController: {
metamaskNotificationsList: [{}, {}, {}],
},
},
},
} as unknown as RootState;

const tags = getTraceTags(state);

expect(tags?.['wallet.notification_count']).toStrictEqual(3);
});

it('includes token count', () => {
const state = {
...initialRootState,
engine: {
backgroundState: {
...backgroundState,
TokensController: {
allTokens: {
'0x1': {
'0x1234': [{}, {}],
'0x4321': [{}],
},
'0x2': {
'0x5678': [{}],
},
},
},
},
},
} as unknown as RootState;

const tags = getTraceTags(state);

expect(tags?.['wallet.token_count']).toStrictEqual(4);
});

it('includes transaction count', () => {
const state = {
...initialRootState,
engine: {
backgroundState: {
...backgroundState,
TransactionController: {
transactions: [
{
id: 1,
chainId: '0x1',
},
{
id: 2,
chainId: '0x1',
},
{
id: 3,
chainId: '0x2',
},
],
},
},
},
} as unknown as RootState;
const tags = getTraceTags(state);

expect(tags?.['wallet.transaction_count']).toStrictEqual(3);
});
});
});
30 changes: 30 additions & 0 deletions app/util/sentry/tags/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { RootState } from '../../../reducers';
import { selectAllNftsFlat } from '../../../selectors/nftController';
import { selectInternalAccounts } from '../../../selectors/accountsController';
import { selectAllTokensFlat } from '../../../selectors/tokensController';
import { getNotificationsList } from '../../../selectors/notifications';
import { selectTransactions } from '../../../selectors/transactionController';
import { selectPendingApprovals } from '../../../selectors/approvalController';

export function getTraceTags(state: RootState) {
if (!Object.keys(state?.engine?.backgroundState).length) return;
const unlocked = state.user.userLoggedIn;
const accountCount = selectInternalAccounts(state).length;
const nftCount = selectAllNftsFlat(state).length;
const notificationCount = getNotificationsList(state).length;
const tokenCount = selectAllTokensFlat(state).length;
const transactionCount = selectTransactions(state).length;
const pendingApprovals = Object.values(selectPendingApprovals(state));

const firstApprovalType = pendingApprovals?.[0]?.type;

return {
tommasini marked this conversation as resolved.
Show resolved Hide resolved
'wallet.account_count': accountCount,
'wallet.nft_count': nftCount,
'wallet.notification_count': notificationCount,
'wallet.pending_approval': firstApprovalType,
'wallet.token_count': tokenCount,
'wallet.transaction_count': transactionCount,
'wallet.unlocked': unlocked,
};
}
Loading
Loading