Skip to content

Commit

Permalink
DEVPROD-14722 Embed app version in spans and fix missing route names (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
khelif96 authored Feb 7, 2025
1 parent d18db84 commit 5ddd2d2
Show file tree
Hide file tree
Showing 13 changed files with 97 additions and 60 deletions.
2 changes: 1 addition & 1 deletion apps/parsley/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="ui-version" content="%GIT_SHA%">
<meta name="package-version" content="%APP_VERSION%" />
<meta name="package-version" content="%REACT_APP_VERSION%" />
<meta name="node-env" content="%NODE_ENV%" />
<link rel="shortcut icon" href="/favicon.ico" />
<title>Parsley</title>
Expand Down
2 changes: 1 addition & 1 deletion apps/parsley/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"type": "module",
"scripts": {
"bootstrap-s3-logs": "../../scripts/bootstrap-s3-logs.sh",
"build": "tsc && GIT_SHA=`git rev-parse HEAD` APP_VERSION=$npm_package_version vite build",
"build": "tsc && GIT_SHA=`git rev-parse HEAD` REACT_APP_VERSION=$npm_package_version vite build",
"build:local": "env-cmd -e local yarn build",
"build:beta": "env-cmd -e beta yarn build",
"build:staging": "env-cmd -e staging yarn build",
Expand Down
10 changes: 8 additions & 2 deletions apps/parsley/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,22 @@ import {
isDevelopmentBuild,
} from "utils/environmentVariables";
import App from "./App";
import routes from "./constants/routes";
import routes, { slugs } from "./constants/routes";

const routeConfig = {
...routes,
// Override the testLogs route to include the groupID parameter so that we can easily identify routes with groupID slugs in Honeycomb.
testLogs: `${routes.testLogs}/:${slugs.groupID}?`,
};
initializeErrorHandling();
initializeHoneycomb({
appVersion: process.env.REACT_APP_VERSION || "",
backendURL: toEscapedRegex(evergreenURL || ""),
debug: isDevelopmentBuild(),
endpoint: process.env.REACT_APP_HONEYCOMB_ENDPOINT || "",
environment: getReleaseStage(),
ingestKey: process.env.REACT_APP_HONEYCOMB_INGEST_KEY || "",
routeConfig: routes,
routeConfig,
serviceName: "parsley",
});
injectOpenTelemetryAttributeStoreIntoWindow();
Expand Down
4 changes: 2 additions & 2 deletions apps/parsley/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useAnalyticAttributes } from "analytics";
import NavBar from "components/NavBar";
import { PageLayout } from "components/styles";
import { LogTypes } from "constants/enums";
import routes from "constants/routes";
import routes, { slugs } from "constants/routes";
import { useAuthContext } from "context/auth";
import { useUser } from "hooks";
import NotFound from "./404";
Expand Down Expand Up @@ -52,7 +52,7 @@ const Content: React.FC = () => {
element={<LogView logType={LogTypes.EVERGREEN_TEST_LOGS} />}
path={routes.testLogs}
>
<Route element={null} path=":groupId" />
<Route element={null} path={`:${slugs.groupID}`} />
</Route>
<Route
element={<LogView logType={LogTypes.EVERGREEN_TEST_LOGS} />}
Expand Down
2 changes: 1 addition & 1 deletion apps/parsley/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default defineConfig({
injectVariablesInHTML({
files: "dist/index.html",
variables: [
"%APP_VERSION%",
"%REACT_APP_VERSION%",
"%GIT_SHA%",
"%REACT_APP_RELEASE_STAGE%",
"%NODE_ENV%",
Expand Down
2 changes: 1 addition & 1 deletion apps/spruce/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<meta charset="utf-8" />
<meta name="theme-color" content="#000000" />
<meta name="git-hash" content="%GIT_SHA%" />
<meta name="package-version" content="%APP_VERSION%" />
<meta name="package-version" content="%REACT_APP_VERSION%" />
<meta name="node-env" content="%NODE_ENV%" />

<link rel="shortcut icon" href="/favicon.ico" />
Expand Down
2 changes: 1 addition & 1 deletion apps/spruce/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"build:local": "env-cmd -e local yarn build",
"build:prod": "env-cmd -e production yarn build",
"build:staging": "env-cmd -e staging yarn build",
"build": "GIT_SHA=`git rev-parse HEAD` APP_VERSION=$npm_package_version vite build",
"build": "GIT_SHA=`git rev-parse HEAD` REACT_APP_VERSION=$npm_package_version vite build",
"build:profiler:beta": "PROFILER=true PROFILE_HEAD=\"<script src=\"https://localhost:8097\"></script>\" yarn build:beta",
"build:profiler:local": "PROFILER=true PROFILE_HEAD=\"<script src=\"https://localhost:8097\"></script>\" yarn build:local",
"build:profiler:staging": "PROFILER=true PROFILE_HEAD=\"<script src=\"https://localhost:8097\"></script>\" yarn build:staging",
Expand Down
9 changes: 2 additions & 7 deletions apps/spruce/src/components/Content/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ export const Content: React.FC = () => {
element={<WaterfallCommitsRedirect />}
path={redirectRoutes.waterfall}
/>
<Route element={<ConfigurePatch />} path={routes.configurePatch}>
<Route element={null} path={`:${slugs.tab}`} />
</Route>
<Route element={<ConfigurePatch />} path={routes.configurePatch} />
<Route element={<Distro />} path={routes.distroSettings}>
<Route element={null} path={`:${slugs.tab}`} />
</Route>
Expand Down Expand Up @@ -88,10 +86,7 @@ export const Content: React.FC = () => {
</Route>
<Route element={<Task />} path={routes.task} />
<Route element={<TaskHistory />} path={routes.taskHistory} />
<Route
element={<TaskQueue />}
path={`${routes.taskQueue}/:${slugs.distroId}?`}
/>
<Route element={<TaskQueue />} path={routes.taskQueue} />
<Route element={<UserPatches />} path={routes.userPatches} />
<Route
element={<UserPatchesRedirect />}
Expand Down
70 changes: 31 additions & 39 deletions apps/spruce/src/constants/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export const redirectRoutes = {

export const routes = {
commits: `${paths.commits}/:${slugs.projectIdentifier}?`,
configurePatch: `${paths.patch}/:${slugs.patchId}/configure`,
configurePatch: `${paths.patch}/:${slugs.patchId}/configure/:${slugs.tab}?`,
container: `${paths.container}/:${slugs.podId}`,
distroSettings: `${paths.distro}/:${slugs.distroId}/${PageNames.Settings}`,
host: `${paths.host}/:${slugs.hostId}`,
Expand All @@ -137,7 +137,7 @@ export const routes = {
spawnVolume: `${paths.spawn}/${SpawnTab.Volume}`,
task: `${paths.task}/:${slugs.taskId}/:${slugs.tab}?`,
taskHistory: `${paths.taskHistory}/:${slugs.projectIdentifier}/:${slugs.taskName}`,
taskQueue: paths.taskQueue,
taskQueue: `${paths.taskQueue}/:${slugs.distroId}?`,
user: paths.user,
userPatches: `${paths.user}/:${slugs.userId}/${PageNames.Patches}`,
variantHistory: `${paths.variantHistory}/:${slugs.projectIdentifier}/:${slugs.variantName}`,
Expand All @@ -148,16 +148,15 @@ export const routes = {
export const getUserPatchesRoute = (userId: string): string =>
`${paths.user}/${userId}/${PageNames.Patches}`;

export interface GetVersionRouteOptions {
tab?: VersionPageTabs;
variant?: string;
page?: number;
statuses?: string[];
sorts?: string | string[];
}
export const getVersionRoute = (
versionId: string,
options?: GetVersionRouteOptions,
options?: {
tab?: VersionPageTabs;
variant?: string;
page?: number;
statuses?: string[];
sorts?: string | string[];
},
) => {
const { tab, ...rest } = options || {};
const queryParams = stringifyQuery({
Expand All @@ -168,14 +167,12 @@ export const getVersionRoute = (
}`;
};

interface GetPatchRouteOptions {
tab?: ConfigurePatchPageTabs;
configure: boolean;
}

export const getPatchRoute = (
patchId: string,
options: GetPatchRouteOptions,
options: {
tab?: ConfigurePatchPageTabs;
configure: boolean;
},
) => {
const { configure, tab, ...rest } = options || {};
const queryParams = stringifyQuery({
Expand All @@ -191,27 +188,25 @@ export const getHostRoute = (hostId: string) => `${paths.host}/${hostId}`;

export const getPodRoute = (podId: string) => `${paths.container}/${podId}`;

interface GetAllHostsRouteOptions {
export const getAllHostsRoute = (options?: {
hostId?: string;
distroId?: string;
statuses?: string[];
currentTaskId?: string;
startedBy?: string;
}

export const getAllHostsRoute = (options?: GetAllHostsRouteOptions) => {
}) => {
const { ...rest } = options || {};
const queryParams = stringifyQuery({
...rest,
});
return `${paths.hosts}?${queryParams}`;
};

export interface GetTaskRouteOptions {
export type GetTaskRouteOptions = {
tab?: TaskTab;
execution?: number;
[key: string]: any;
}
};
export const getTaskRoute = (taskId: string, options?: GetTaskRouteOptions) => {
const { tab, ...rest } = options || {};
const queryParams = stringifyQuery({
Expand All @@ -230,18 +225,17 @@ export const getTaskQueueRoute = (distro: string, taskId?: string) => {
});
return `${paths.taskQueue}/${distro}${taskId ? `?${queryParams}` : ""}`;
};
interface GetSpawnHostRouteParam {
distroId?: string;
host?: string;
taskId?: string;
spawnHost?: boolean;
}
export const getSpawnHostRoute = ({
distroId,
host,
spawnHost,
taskId,
}: GetSpawnHostRouteParam) => {
}: {
distroId?: string;
host?: string;
taskId?: string;
spawnHost?: boolean;
}) => {
const queryParams = stringifyQuery({
...(spawnHost && { spawnHost: "True" }),
distroId,
Expand Down Expand Up @@ -362,23 +356,21 @@ export const getTaskHistoryRoute = (
);
};

interface GetTriggerRouteParams {
triggerType: string;
upstreamTask: any;
upstreamVersion: any;
upstreamRevision: string;
upstreamOwner: string;
upstreamRepo: string;
}

export const getTriggerRoute = ({
triggerType,
upstreamOwner,
upstreamRepo,
upstreamRevision,
upstreamTask,
upstreamVersion,
}: GetTriggerRouteParams) => {
}: {
triggerType: string;
upstreamTask: any;
upstreamVersion: any;
upstreamRevision: string;
upstreamOwner: string;
upstreamRepo: string;
}) => {
if (triggerType === ProjectTriggerLevel.TASK) {
return getTaskRoute(upstreamTask.id);
}
Expand Down
17 changes: 15 additions & 2 deletions apps/spruce/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,26 @@ import {
} from "@evg-ui/lib/utils/observability";
import { toEscapedRegex } from "@evg-ui/lib/utils/string";
import { initializeErrorHandling } from "components/ErrorHandling";
import { routes } from "constants/routes";
import { redirectRoutes, routes, slugs } from "constants/routes";
import {
getAppVersion,
getReleaseStage,
getUiUrl,
isDevelopmentBuild,
} from "utils/environmentVariables";
import App from "./App";

const routeConfig = {
...routes,
projectSettings: `${routes.projectSettings}/:${slugs.tab}?`,
image: `${routes.image}/:${slugs.tab}?`,
distroSettings: `${routes.distroSettings}/:${slugs.tab}?`,
preferences: `${routes.preferences}/:${slugs.tab}?`,
spawn: `${routes.spawn}/:${slugs.tab}?`,
jobLogsLogkeeper: `${routes.jobLogs}/:${slugs.buildId}?/:${slugs.groupId}?`,
jobLogsEvergreen: `${routes.jobLogs}/:${slugs.taskId}/:${slugs.execution}/:${slugs.groupId}`,
patchRedirect: redirectRoutes.patch,
};
initializeErrorHandling();
initializeHoneycomb({
debug: isDevelopmentBuild(),
Expand All @@ -22,7 +34,8 @@ initializeHoneycomb({
backendURL: toEscapedRegex(getUiUrl() || ""),
serviceName: "spruce",
environment: getReleaseStage(),
routeConfig: routes,
appVersion: getAppVersion(),
routeConfig,
});
injectOpenTelemetryAttributeStoreIntoWindow();

Expand Down
2 changes: 1 addition & 1 deletion apps/spruce/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export default defineConfig({
injectVariablesInHTML({
files: "dist/index.html",
variables: [
"%APP_VERSION%",
"%REACT_APP_VERSION%",
"%GIT_SHA%",
"%REACT_APP_RELEASE_STAGE%",
"%NODE_ENV%",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import { Span } from "@opentelemetry/sdk-trace-base";
import ReactRouterSpanProcessor from ".";
import { RouteConfig } from "./types";

describe("ReactRouterSpanProcessor (without mocking calculateRouteName)", () => {
describe("ReactRouterSpanProcessor", () => {
let spanProcessor: ReactRouterSpanProcessor;
const mockRouteConfig: RouteConfig = {
upload: "/upload",
spawnHost: "/spawn/host",
versionPage: "/version/:id/:tab?",
taskHistory: "/task-history/:projectId/:taskId",
configurePatch: `/patch/:patchId/configure/:tab?`,
};

beforeEach(() => {
Expand Down Expand Up @@ -154,5 +155,30 @@ describe("ReactRouterSpanProcessor (without mocking calculateRouteName)", () =>

expect(mockSpan.setAttribute).not.toHaveBeenCalled();
});
it("should properly match long trailing routes", () => {
const mockSpan = {
setAttribute: vi.fn(),
} as unknown as Span;

Object.defineProperty(window, "location", {
value: { pathname: "/patch/123/configure/tasks" },
writable: true,
});

spanProcessor.onStart(mockSpan);

expect(mockSpan.setAttribute).toHaveBeenCalledWith(
"page.route_name",
"configurePatch",
);
expect(mockSpan.setAttribute).toHaveBeenCalledWith(
"page.route",
"/patch/:patchId/configure/:tab?",
);
expect(mockSpan.setAttribute).toHaveBeenCalledWith(
"page.route_param.patchId",
"123",
);
});
});
});
7 changes: 6 additions & 1 deletion packages/lib/src/utils/observability/honeycomb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ interface HoneycombConfig {
environment: string;
/** A config representing all routes the app can have */
routeConfig: RouteConfig;
/** A version number indicating which release this is */
appVersion: string;
}

/**
Expand All @@ -36,8 +38,10 @@ interface HoneycombConfig {
* @param config.endpoint - The endpoint for the Honeycomb SDK to send traces to if we are not using the default.
* @param config.environment - The environment we are running in.
* @param config.routeConfig - A config representing all routes the app can have.
* @param config.appVersion - A version number indicating which release this is.
*/
const initializeHoneycomb = ({
appVersion,
backendURL,
debug,
endpoint,
Expand Down Expand Up @@ -94,10 +98,11 @@ const initializeHoneycomb = ({
instrumentations: [
getWebAutoInstrumentations(webAutoInstrumentationConfig),
],
// Add user.id as an attribute to all traces.
// Add attributes to all traces.
resourceAttributes: {
"user.id": userId,
environment,
app_version: appVersion,
},
localVisualizations: debug,
serviceName,
Expand Down

0 comments on commit 5ddd2d2

Please sign in to comment.