Skip to content

Commit 402392b

Browse files
committed
feat: debug instrumentation
1 parent a30d6f9 commit 402392b

File tree

12 files changed

+163
-26
lines changed

12 files changed

+163
-26
lines changed

web/.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@ parcel-bundle-reports
2222
.env.development.local
2323
.env.test.local
2424
.env.production.local
25+
26+
# generated code
2527
src/hooks/contracts
2628
src/graphql
29+
generatedGitInfo.json
2730

31+
# logs
2832
npm-debug.log*
2933
yarn-debug.log*
3034
yarn-error.log*

web/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"start": "scripts/runEnv.sh devnet 'yarn generate && parcel'",
2828
"start-testnet": "scripts/runEnv.sh testnet 'yarn generate && parcel'",
2929
"start-local": "scripts/runEnv.sh local 'yarn generate && parcel'",
30-
"build": "yarn generate && parcel build",
30+
"build": "node scripts/gitInfo.js && yarn generate && parcel build",
3131
"build-devnet": "scripts/runEnv.sh devnet 'yarn generate && parcel build'",
3232
"build-testnet": "scripts/runEnv.sh testnet 'yarn generate && parcel build'",
3333
"check-style": "eslint 'src/**/*.{js,jsx,ts,tsx}'",

web/scripts/gitInfo.js

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/* eslint-disable max-len */
2+
const fs = require("fs");
3+
const path = require("path");
4+
const { execSync } = require("child_process");
5+
const packageJson = require("../package.json");
6+
7+
const execSyncWrapper = (command) => {
8+
let stdout = null;
9+
try {
10+
stdout = execSync(command).toString().trim();
11+
} catch (error) {
12+
console.error(error);
13+
}
14+
return stdout;
15+
};
16+
17+
const main = () => {
18+
let version = packageJson.version;
19+
let gitCommitHash = execSyncWrapper("git rev-parse HEAD");
20+
let gitCommitShortHash = execSyncWrapper("git rev-parse --short=7 HEAD");
21+
let gitBranch = execSyncWrapper("git rev-parse --abbrev-ref HEAD");
22+
let clean =
23+
execSyncWrapper(`[ -z "$(git status --short | ggrep -v '^??')" ] && echo clean || echo dirty`) === "clean";
24+
25+
const obj = {
26+
version,
27+
gitCommitHash,
28+
gitCommitShortHash,
29+
gitBranch,
30+
clean,
31+
};
32+
33+
const filePath = path.resolve("src", "generatedGitInfo.json");
34+
const fileContents = JSON.stringify(obj, null, 2);
35+
36+
fs.writeFileSync(filePath, fileContents);
37+
// console.log(`Wrote the following contents to ${filePath}\n${fileContents}`);
38+
};
39+
40+
main();

web/scripts/runEnv.sh

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ if [[ ! " ${valid_deployments[@]} " =~ " ${deployment} " ]]; then
1717
exit 1
1818
fi
1919

20+
node $SCRIPT_DIR/gitInfo.js
2021
. $SCRIPT_DIR/../.env.${deployment}.public
2122
. $SCRIPT_DIR/../.env.${deployment}
2223
eval "$commands"

web/src/app.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from "react";
2-
import { Routes, Route } from "react-router-dom";
2+
import { Route } from "react-router-dom";
3+
import { SentryRoutes } from "./utils/sentry";
34
import "react-loading-skeleton/dist/skeleton.css";
45
import "react-toastify/dist/ReactToastify.css";
56
import Web3Provider from "context/Web3Provider";
@@ -19,7 +20,7 @@ const App: React.FC = () => {
1920
<QueryClientProvider>
2021
<RefetchOnBlock />
2122
<Web3Provider>
22-
<Routes>
23+
<SentryRoutes>
2324
<Route path="/" element={<Layout />}>
2425
<Route index element={<Home />} />
2526
<Route path="cases/*" element={<Cases />} />
@@ -28,7 +29,7 @@ const App: React.FC = () => {
2829
<Route path="disputeTemplate" element={<DisputeTemplateView />} />
2930
<Route path="*" element={<h1>Justice not found here ¯\_( ͡° ͜ʖ ͡°)_/¯</h1>} />
3031
</Route>
31-
</Routes>
32+
</SentryRoutes>
3233
</Web3Provider>
3334
</QueryClientProvider>
3435
</StyledComponentsProvider>

web/src/consts/index.ts

+8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1+
import { version, gitCommitHash, gitCommitShortHash, gitBranch, clean } from "../generatedGitInfo.json";
2+
13
export const ONE_BASIS_POINT = 10000n;
24

35
export const KLEROS_CONTRACT_ADDRESS = "ethereum:0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d";
46
export const WETH_CONTRACT_ADDRESS = "ethereum:0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
57
export const PNK_FAUCET_CONTRACT_ADDRESS = "0x05648Ee14941630a649082e0dA5cb80D29cC9002";
68

79
export const IPFS_GATEWAY = process.env.REACT_APP_IPFS_GATEWAY || "https://cdn.kleros.link";
10+
11+
export const GIT_BRANCH = gitBranch;
12+
export const GIT_HASH = gitCommitShortHash;
13+
export const GIT_DIRTY = clean ? "" : "-dirty";
14+
export const GIT_URL = `https://github.com/kleros/kleros-v2/tree/${gitCommitHash}/web`;
15+
export const RELEASE_VERSION = version;

web/src/hooks/queries/usePhase.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { useQuery } from "@tanstack/react-query";
2+
import { getSortitionModule } from "hooks/contracts/generated";
3+
import { isUndefined } from "utils/index";
4+
5+
export const usePhase = () => {
6+
const sortitionModule = getSortitionModule({});
7+
const isEnabled = !isUndefined(sortitionModule);
8+
return useQuery({
9+
queryKey: [`Phase`],
10+
enabled: isEnabled,
11+
staleTime: 20 * 1000, // 20 seconds
12+
queryFn: async () => {
13+
if (!sortitionModule) return;
14+
return await sortitionModule.read.phase();
15+
},
16+
});
17+
};

web/src/index.tsx

+3-16
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,16 @@
11
import React from "react";
22
import { createRoot } from "react-dom/client";
3-
import * as Sentry from "@sentry/react";
4-
import { BrowserTracing } from "@sentry/tracing";
53
import App from "./app";
64
import Modal from "react-modal";
7-
import { HashRouter as Router } from "react-router-dom";
8-
9-
Sentry.init({
10-
dsn: process.env.REACT_APP_SENTRY_ENDPOINT,
11-
environment: process.env.REACT_APP_CONTEXT,
12-
integrations: [new BrowserTracing()],
13-
14-
// Set tracesSampleRate to 1.0 to capture 100%
15-
// of transactions for performance monitoring.
16-
// We recommend adjusting this value in production
17-
tracesSampleRate: 1.0,
18-
});
5+
import { HashRouter } from "react-router-dom";
196

207
const container = document.getElementById("app");
218
Modal.setAppElement(container!);
229
const root = createRoot(container!);
2310
root.render(
2411
<React.StrictMode>
25-
<Router>
12+
<HashRouter>
2613
<App />
27-
</Router>
14+
</HashRouter>
2815
</React.StrictMode>
2916
);

web/src/layout/Footer/index.tsx

+1-6
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,7 @@ const Container = styled.div`
3636
`;
3737

3838
const SecuredByKleros: React.FC = () => (
39-
<a
40-
className="secured-by-kleros"
41-
href="https://kleros.io"
42-
target="_blank"
43-
rel="noreferrer"
44-
>
39+
<a className="secured-by-kleros" href="https://kleros.io" target="_blank" rel="noreferrer">
4540
<SecuredByKlerosLogo />
4641
</a>
4742
);
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import React from "react";
2+
import styled from "styled-components";
3+
import { GIT_BRANCH, GIT_DIRTY, GIT_HASH, GIT_URL, RELEASE_VERSION } from "../../../consts";
4+
import { usePhase } from "~src/hooks/queries/usePhase";
5+
6+
const Container = styled.div`
7+
label,
8+
a {
9+
font-family: "Roboto Mono", monospace;
10+
line-height: 10px;
11+
font-size: 10px;
12+
color: ${({ theme }) => theme.stroke};
13+
}
14+
`;
15+
16+
const Version = () => (
17+
<label>
18+
v{RELEASE_VERSION}{" "}
19+
<a href={GIT_URL} target="_blank" rel="noreferrer">
20+
#{GIT_HASH}
21+
</a>{" "}
22+
{GIT_BRANCH}
23+
{GIT_DIRTY && " dirty"}
24+
</label>
25+
);
26+
27+
const Phase = () => {
28+
const { data: phase } = usePhase();
29+
return <label>phase: {phase}</label>;
30+
};
31+
32+
const Debug: React.FC = () => {
33+
return (
34+
<Container>
35+
<Version />
36+
<label>{", "}</label>
37+
<Phase />
38+
</Container>
39+
);
40+
};
41+
42+
export default Debug;

web/src/layout/Header/navbar/index.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { useOpenContext } from "../index";
88
import DappList from "./DappList";
99
import Explore from "./Explore";
1010
import Menu from "./Menu";
11+
import Debug from "./Debug";
1112

1213
const Container = styled.div<{ isOpen: boolean }>`
1314
position: absolute;
@@ -54,6 +55,8 @@ const NavBar: React.FC = () => {
5455
<ConnectWallet />
5556
<hr />
5657
<Menu />
58+
<br />
59+
<Debug />
5760
</Container>
5861
);
5962
};

web/src/utils/sentry.ts

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from "react";
2+
import * as Sentry from "@sentry/react";
3+
import { Routes, createRoutesFromChildren, matchRoutes, useLocation, useNavigationType } from "react-router-dom";
4+
import { GIT_DIRTY, GIT_HASH, RELEASE_VERSION } from "../consts";
5+
6+
Sentry.init({
7+
dsn: process.env.REACT_APP_SENTRY_ENDPOINT,
8+
environment: process.env.REACT_APP_CONTEXT,
9+
release: `court-v2@${RELEASE_VERSION}-${GIT_HASH}${GIT_DIRTY}`,
10+
integrations: [
11+
new Sentry.BrowserProfilingIntegration(),
12+
new Sentry.BrowserTracing({
13+
routingInstrumentation: Sentry.reactRouterV6Instrumentation(
14+
React.useEffect,
15+
useLocation,
16+
useNavigationType,
17+
createRoutesFromChildren,
18+
matchRoutes
19+
),
20+
}),
21+
],
22+
23+
// Set tracesSampleRate to 1.0 to capture 100%
24+
// of transactions for performance monitoring.
25+
// We recommend adjusting this value in production
26+
tracesSampleRate: 1.0,
27+
28+
// Set `tracePropagationTargets` to control for which URLs distributed tracing should be enabled
29+
tracePropagationTargets: ["localhost", /^https:\/\/.*--kleros-v2\.netlify\.app/],
30+
31+
// Set profilesSampleRate to 1.0 to profile every transaction.
32+
// Since profilesSampleRate is relative to tracesSampleRate,
33+
// the final profiling rate can be computed as tracesSampleRate * profilesSampleRate
34+
// For example, a tracesSampleRate of 0.5 and profilesSampleRate of 0.5 would
35+
// results in 25% of transactions being profiled (0.5*0.5=0.25)
36+
profilesSampleRate: 1.0,
37+
});
38+
39+
export const SentryRoutes = Sentry.withSentryReactRouterV6Routing(Routes);

0 commit comments

Comments
 (0)