Skip to content

Commit

Permalink
Upgrade from raven-js to sentry/browser (#2509)
Browse files Browse the repository at this point in the history
## Which problem is this PR solving?
- Resolves #2412
- Replaced and closes #2417 

## Description of the changes
This PR is a continuation of the migration from `raven-js` to
`@sentry/browser`.
- The final step involves testing the implementation with a real Google
Analytics account.
- The google tags are displayed correctly in [Tag
Hound](https://chromewebstore.google.com/detail/taghound-analyticsgtmpixe/canpneabbfipaelecfibpmmjbdkiaolf?hl=en)
chrome extension.
- Here is the screenshot of logging tag managers details and event data.
![Events from TagHound](https://i.imgur.com/1fyHg2n.png)



## How was this change tested?
- Placed the GA Measurement ID in `default-config.tsx`.
- Varified navigation events using TagHound. Screenshots of the events
been tracked are attached
- **Note**: Ensure GTM tracking is enabled in TagHound, otherwise the
Google tags will not be tracked.
- This test works in the local environment, but I am unable to see data
logs in Google Analytics. This may be because the GA dashboard doesn’t
collect data from localhost.

## Checklist
- [x] I have read
https://github.com/jaegertracing/jaeger/blob/master/CONTRIBUTING_GUIDELINES.md
- [x] I have signed all commits
- [x] I have added unit tests for the new functionality
- [x] I have run lint and test steps successfully
  - for `jaeger`: `make lint test`
  - for `jaeger-ui`: `npm test`

---------

Signed-off-by: Muthukumar <[email protected]>
Signed-off-by: Yuri Shkuro <[email protected]>
Signed-off-by: Yuri Shkuro <[email protected]>
Signed-off-by: Avinash <[email protected]>
Signed-off-by: avinash <[email protected]>
Co-authored-by: Muthukumar <[email protected]>
Co-authored-by: Yuri Shkuro <[email protected]>
Co-authored-by: Yuri Shkuro <[email protected]>
  • Loading branch information
4 people authored Dec 12, 2024
1 parent c780c37 commit 1f101a2
Show file tree
Hide file tree
Showing 9 changed files with 183 additions and 84 deletions.
86 changes: 77 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/jaeger-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"@ant-design/compatible": "^5.1.3",
"@jaegertracing/plexus": "0.2.0",
"@pyroscope/flamegraph": "0.21.4",
"@sentry/browser": "^8.18.0",
"antd": "^5.21.3",
"chance": "^1.0.10",
"classnames": "^2.5.1",
Expand All @@ -68,7 +69,6 @@
"object-hash": "^3.0.0",
"prop-types": "^15.5.10",
"query-string": "^9.0.0",
"raven-js": "^3.22.1",
"react": "^18.3.1",
"react-circular-progressbar": "^2.1.0",
"react-dom": "^18.3.1",
Expand Down
4 changes: 2 additions & 2 deletions packages/jaeger-ui/src/types/tracking.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import { RavenStatic } from 'raven-js';
import { BrowserClient } from '@sentry/browser';
import { TNil } from '.';
import { Config } from './config';

Expand All @@ -22,7 +22,7 @@ export interface IWebAnalyticsFunc {

export default interface IWebAnalytics {
init: () => void;
context: boolean | RavenStatic | null;
context: boolean | typeof BrowserClient | null;
isEnabled: () => boolean;
trackPageView: (pathname: string, search: string | TNil) => void;
trackError: (description: string) => void;
Expand Down
20 changes: 20 additions & 0 deletions packages/jaeger-ui/src/utils/tracking/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,23 @@ You get a lot for free when using Raven.js:
- Some global handlers are added

Implementing the above from scratch would require substantial effort. Meanwhile, Raven.js is well tested.

### Steps to Verify the gaID Integration

Setup:

- Ensure you have the repository cloned and all dependencies installed. Run the following command in the terminal
- `npm install`
- Start the local development server

- `npm start` This will open the application in your default browser

Steps to put gaID:

- Place the GA Measurement ID in `default-config.tsx`.

- Verify navigation events using **TagHound**. Screenshots of the events being tracked are attached.

- **Note**: Ensure GTM tracking is enabled in **TagHound**, otherwise the Google tags will not be tracked.

- This test works in the local environment, but data logs may not appear in Google Analytics. This is likely because the GA dashboard doesn’t collect data from `localhost`.
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import convRavenToGa from './conv-raven-to-ga';
import { RAVEN_PAYLOAD, RAVEN_TO_GA } from './fixtures';
import convSentryToGa from './conv-sentry-to-ga';
import { SENTRY_PAYLOAD, SENTRY_TO_GA } from './fixtures';

describe('convRavenToGa()', () => {
it('converts the raven-js payload to { category, action, label, value }', () => {
const data = convRavenToGa(RAVEN_PAYLOAD);
expect(data).toEqual(RAVEN_TO_GA);
describe('convSentryToGa()', () => {
it('converts the sentry payload to { category, action, label, value }', () => {
const data = convSentryToGa(SENTRY_PAYLOAD);
expect(data).toEqual(SENTRY_TO_GA);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.

/* eslint-disable camelcase */
import { RavenTransportOptions } from 'raven-js';
import { Exception, Breadcrumb } from '@sentry/browser';

import prefixUrl from '../prefix-url';

Expand Down Expand Up @@ -116,20 +116,11 @@ function convErrorMessage(message: string, maxLen = 0) {
// cFn
// dFn
//
interface IConvException {
type: string;
value: number;
stacktrace: {
frames: {
filename: string;
function: string;
}[];
};
}
function convException(errValue: IConvException) {

function convException(errValue: Exception) {
const message = convErrorMessage(`${errValue.type}: ${errValue.value}`, 149);
const frames = errValue.stacktrace.frames.map(fr => {
const filename = fr.filename.replace(origin, '').replace(/^\/static\/js\//i, '');
const frames = (errValue.stacktrace?.frames ?? []).map(fr => {
const filename = (fr.filename ?? '').replace(origin, '').replace(/^\/static\/js\//i, '');
const fn = collapseWhitespace(fr.function || '??');
return { filename, fn };
});
Expand Down Expand Up @@ -169,9 +160,7 @@ function convNav(to: string) {
// "dp" - fetch the dependency data
// And, "NNN" is a non-200 status code.
type TCrumbData = {
url: string;
status_code: number;
to: string;
[key: string]: any;
};
function convFetch(data: TCrumbData) {
const { url, status_code } = data;
Expand Down Expand Up @@ -247,20 +236,14 @@ function compressCssSelector(selector: string) {
// The chronological ordering of the breadcrumbs is older events precede newer
// events. This ordering was kept because it's easier to see which page events
// occurred on.
interface ICrumb {
category: string;
data: TCrumbData;
message: string;
selector: string;
}
function convBreadcrumbs(crumbs: ICrumb[]) {
function convBreadcrumbs(crumbs: Breadcrumb[]) {
if (!Array.isArray(crumbs) || !crumbs.length) {
return '';
}
// the last UI breadcrumb has the CSS selector included
let iLastUi = -1;
for (let i = crumbs.length - 1; i >= 0; i--) {
if (crumbs[i].category.slice(0, 2) === 'ui') {
if (crumbs[i]?.category?.slice(0, 2) === 'ui') {
iLastUi = i;
break;
}
Expand All @@ -270,10 +253,10 @@ function convBreadcrumbs(crumbs: ICrumb[]) {
let onNewLine = true;
for (let i = 0; i < crumbs.length; i++) {
const c = crumbs[i];
const cStart = c.category.split('.')[0];
const cStart = c.category?.split('.')[0];
switch (cStart) {
case 'fetch': {
const fetched = convFetch(c.data);
const fetched = c.data ? convFetch(c.data) : null;
if (fetched) {
joiner.push(fetched);
onNewLine = false;
Expand All @@ -282,25 +265,25 @@ function convBreadcrumbs(crumbs: ICrumb[]) {
}

case 'navigation': {
const nav = `${onNewLine ? '' : '\n'}\n${convNav(c.data.to)}\n`;
const nav = `${onNewLine ? '' : '\n'}\n${convNav(c.data?.to)}\n`;
joiner.push(nav);
onNewLine = true;
break;
}

case 'ui': {
if (i === iLastUi) {
const selector = compressCssSelector(c.message);
if (c.category && i === iLastUi) {
const selector = c.message ? compressCssSelector(c.message) : null;
joiner.push(`${c.category[3]}{${selector}}`);
} else {
} else if (c.category) {
joiner.push(c.category[3]);
}
onNewLine = false;
break;
}

case 'sentry': {
const msg = convErrorMessage(c.message, 58);
const msg = c.message ? convErrorMessage(c.message, 58) : null;
joiner.push(`${onNewLine ? '' : '\n'}${msg}\n`);
onNewLine = true;
break;
Expand Down Expand Up @@ -343,24 +326,32 @@ function convBreadcrumbs(crumbs: ICrumb[]) {

// Create the GA label value from the message, page, duration, git info, and
// breadcrumbs. See <./README.md> for details.
function getLabel(message: string, page: string, duration: number, git: string, breadcrumbs: ICrumb[]) {
function getLabel(message: string, page: string, duration: number, git: string, breadcrumbs: Breadcrumb[]) {
const header = [message, page, duration, git, ''].filter(v => v != null).join('\n');
const crumbs = convBreadcrumbs(breadcrumbs);
return `${header}\n${truncate(crumbs, 498 - header.length, true)}`;
}

// Convert the Raven exception data to something that can be sent to Google
// Convert the exception data to something that can be sent to Google
// Analytics. See <./README.md> for details.
export default function convRavenToGa({ data }: RavenTransportOptions) {
export default function convSentryToGa({ data }: { url: string; data: any }) {
const { breadcrumbs, exception, extra, request, tags } = data;
const { message, stack } = convException(exception.values[0]);
const url = truncate(request.url.replace(origin, ''), 50);
const { message, stack } = convException(exception?.values?.[0] ?? {});

const url = truncate((request?.url ?? '').replace(origin, ''), 50);
const { word: page } = getSym(NAV_SYMBOLS, url);
const value = Math.round(extra['session:duration'] / 1000);
const duration = extra?.['session:duration'];
const value = typeof duration === 'number' ? Math.round(duration / 1000) : 0;
const category = `jaeger/${page}/error`;
let action = [message, tags && tags.git, url, '', stack].filter(v => v != null).join('\n');
action = truncate(action, 499);
const label = getLabel(message, page, value, tags && tags.git, breadcrumbs && breadcrumbs.values);
const label = getLabel(
message,
page,
value,
(tags && tags.git) as string,
(breadcrumbs && Array.isArray(breadcrumbs.values) ? breadcrumbs.values : []) as Breadcrumb[]
);
return {
message,
category,
Expand Down
4 changes: 2 additions & 2 deletions packages/jaeger-ui/src/utils/tracking/fixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ And the cloud that took the form
Of a demon in my view—"
3/17/1829`;

export const RAVEN_PAYLOAD = deepFreeze({
export const SENTRY_PAYLOAD = deepFreeze({
data: {
request: {
url: 'http://localhost/trace/565c1f00385ebd0b',
Expand Down Expand Up @@ -212,7 +212,7 @@ tr
! Type! A very long message that will be truncated and re~
cic2i2i{.LabeledList.TracePageHeader--overviewItems}`;

export const RAVEN_TO_GA = deepFreeze({
export const SENTRY_TO_GA = deepFreeze({
action,
label,
message: '! test-sentry',
Expand Down
4 changes: 2 additions & 2 deletions packages/jaeger-ui/src/utils/tracking/ga.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import * as GA from './ga';
import { getAppEnvironment } from '../constants';

jest.mock('./conv-raven-to-ga', () => () => ({
jest.mock('./conv-sentry-to-ga', () => () => ({
category: 'jaeger/a',
action: 'some-action',
message: 'jaeger/a',
Expand Down Expand Up @@ -166,7 +166,7 @@ describe('google analytics tracking', () => {
});
});

it('converting raven-js errors', () => {
it('converting sentry errors', () => {
window.onunhandledrejection({
reason: new Error('abc'),
});
Expand Down
Loading

0 comments on commit 1f101a2

Please sign in to comment.