Skip to content

Commit f08c29d

Browse files
committed
Merge branch 'abhi/ref/other-sentry-tracing' into abhi/ref/add-sentry-tracing
2 parents eb225dd + 1e8f77a commit f08c29d

21 files changed

+2768
-0
lines changed

packages/tracing/.npmignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*
2+
!/dist/**/*
3+
!/esm/**/*
4+
*.tsbuildinfo

packages/tracing/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<p align="center">
2+
<a href="https://sentry.io" target="_blank" align="center">
3+
<img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" width="280">
4+
</a>
5+
<br />
6+
</p>
7+
8+
# Sentry APM Extensions
9+
10+
[![npm version](https://img.shields.io/npm/v/@sentry/apm.svg)](https://www.npmjs.com/package/@sentry/apm)
11+
[![npm dm](https://img.shields.io/npm/dm/@sentry/apm.svg)](https://www.npmjs.com/package/@sentry/apm)
12+
[![npm dt](https://img.shields.io/npm/dt/@sentry/apm.svg)](https://www.npmjs.com/package/@sentry/apm)
13+
[![typedoc](https://img.shields.io/badge/docs-typedoc-blue.svg)](http://getsentry.github.io/sentry-javascript/)
14+
15+
## Links
16+
17+
- [Official SDK Docs](https://docs.sentry.io/quickstart/)
18+
- [TypeDoc](http://getsentry.github.io/sentry-javascript/)
19+
20+
## General
21+
22+
This package contains extensions to the `@sentry/hub` to enable APM related functionality. It also provides integrations for Browser and Node that provide a good experience out of the box.

packages/tracing/package.json

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
{
2+
"name": "@sentry/apm",
3+
"version": "5.19.0",
4+
"description": "Extensions for APM",
5+
"repository": "git://github.com/getsentry/sentry-javascript.git",
6+
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/apm",
7+
"author": "Sentry",
8+
"license": "BSD-3-Clause",
9+
"engines": {
10+
"node": ">=6"
11+
},
12+
"main": "dist/index.js",
13+
"module": "esm/index.js",
14+
"types": "dist/index.d.ts",
15+
"publishConfig": {
16+
"access": "public"
17+
},
18+
"dependencies": {
19+
"@sentry/browser": "5.19.0",
20+
"@sentry/hub": "5.19.0",
21+
"@sentry/minimal": "5.19.0",
22+
"@sentry/types": "5.19.0",
23+
"@sentry/utils": "5.19.0",
24+
"tslib": "^1.9.3"
25+
},
26+
"devDependencies": {
27+
"@types/express": "^4.17.1",
28+
"jest": "^24.7.1",
29+
"npm-run-all": "^4.1.2",
30+
"prettier": "^1.17.0",
31+
"prettier-check": "^2.0.0",
32+
"rimraf": "^2.6.3",
33+
"rollup": "^1.10.1",
34+
"rollup-plugin-commonjs": "^9.3.4",
35+
"rollup-plugin-license": "^0.8.1",
36+
"rollup-plugin-node-resolve": "^4.2.3",
37+
"rollup-plugin-terser": "^4.0.4",
38+
"rollup-plugin-typescript2": "^0.21.0",
39+
"tslint": "^5.16.0",
40+
"typescript": "^3.4.5"
41+
},
42+
"scripts": {
43+
"build": "run-p build:es5 build:esm build:bundle",
44+
"build:bundle": "rollup --config",
45+
"build:bundle:watch": "rollup --config --watch",
46+
"build:es5": "tsc -p tsconfig.build.json",
47+
"build:esm": "tsc -p tsconfig.esm.json",
48+
"build:watch": "run-p build:watch:es5 build:watch:esm",
49+
"build:watch:es5": "tsc -p tsconfig.build.json -w --preserveWatchOutput",
50+
"build:watch:esm": "tsc -p tsconfig.esm.json -w --preserveWatchOutput",
51+
"clean": "rimraf dist coverage build esm",
52+
"link:yarn": "yarn link",
53+
"lint": "run-s lint:prettier lint:tslint",
54+
"lint:prettier": "prettier-check \"{src,test}/**/*.ts\"",
55+
"lint:tslint": "tslint -t stylish -p .",
56+
"lint:tslint:json": "tslint --format json -p . | tee lint-results.json",
57+
"fix": "run-s fix:tslint fix:prettier",
58+
"fix:prettier": "prettier --write \"{src,test}/**/*.ts\"",
59+
"fix:tslint": "tslint --fix -t stylish -p .",
60+
"test": "jest",
61+
"test:watch": "jest --watch"
62+
},
63+
"jest": {
64+
"collectCoverage": true,
65+
"transform": {
66+
"^.+\\.ts$": "ts-jest"
67+
},
68+
"moduleFileExtensions": [
69+
"js",
70+
"ts"
71+
],
72+
"testEnvironment": "node",
73+
"testMatch": [
74+
"**/*.test.ts"
75+
],
76+
"globals": {
77+
"ts-jest": {
78+
"tsConfig": "./tsconfig.json",
79+
"diagnostics": false
80+
}
81+
}
82+
},
83+
"sideEffects": false
84+
}

packages/tracing/rollup.config.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { terser } from 'rollup-plugin-terser';
2+
import typescript from 'rollup-plugin-typescript2';
3+
import license from 'rollup-plugin-license';
4+
import resolve from 'rollup-plugin-node-resolve';
5+
import commonjs from 'rollup-plugin-commonjs';
6+
7+
const commitHash = require('child_process')
8+
.execSync('git rev-parse --short HEAD', { encoding: 'utf-8' })
9+
.trim();
10+
11+
const terserInstance = terser({
12+
mangle: {
13+
// captureExceptions and captureMessage are public API methods and they don't need to be listed here
14+
// as mangler doesn't touch user-facing thing, however sentryWrapped is not, and it would be mangled into a minified version.
15+
// We need those full names to correctly detect our internal frames for stripping.
16+
// I listed all of them here just for the clarity sake, as they are all used in the frames manipulation process.
17+
reserved: ['captureException', 'captureMessage', 'sentryWrapped'],
18+
properties: {
19+
regex: /^_[^_]/,
20+
},
21+
},
22+
});
23+
24+
const paths = {
25+
'@sentry/utils': ['../utils/src'],
26+
'@sentry/core': ['../core/src'],
27+
'@sentry/hub': ['../hub/src'],
28+
'@sentry/types': ['../types/src'],
29+
'@sentry/minimal': ['../minimal/src'],
30+
};
31+
32+
const plugins = [
33+
typescript({
34+
tsconfig: 'tsconfig.build.json',
35+
tsconfigOverride: {
36+
compilerOptions: {
37+
declaration: false,
38+
declarationMap: false,
39+
module: 'ES2015',
40+
paths,
41+
},
42+
},
43+
include: ['*.ts+(|x)', '**/*.ts+(|x)', '../**/*.ts+(|x)'],
44+
}),
45+
resolve({
46+
mainFields: ['module'],
47+
}),
48+
commonjs(),
49+
];
50+
51+
const bundleConfig = {
52+
input: 'src/index.ts',
53+
output: {
54+
format: 'iife',
55+
name: 'Sentry',
56+
sourcemap: true,
57+
strict: false,
58+
},
59+
context: 'window',
60+
plugins: [
61+
...plugins,
62+
license({
63+
sourcemap: true,
64+
banner: `/*! @sentry/apm & @sentry/browser <%= pkg.version %> (${commitHash}) | https://github.com/getsentry/sentry-javascript */`,
65+
}),
66+
],
67+
};
68+
69+
export default [
70+
// ES5 Browser APM Bundle
71+
{
72+
...bundleConfig,
73+
input: 'src/index.bundle.ts',
74+
output: {
75+
...bundleConfig.output,
76+
file: 'build/bundle.apm.js',
77+
},
78+
plugins: bundleConfig.plugins,
79+
},
80+
{
81+
...bundleConfig,
82+
input: 'src/index.bundle.ts',
83+
output: {
84+
...bundleConfig.output,
85+
file: 'build/bundle.apm.min.js',
86+
},
87+
// Uglify has to be at the end of compilation, BUT before the license banner
88+
plugins: bundleConfig.plugins
89+
.slice(0, -1)
90+
.concat(terserInstance)
91+
.concat(bundleConfig.plugins.slice(-1)),
92+
},
93+
];

packages/tracing/src/hubextensions.ts

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import { getMainCarrier, Hub } from '@sentry/hub';
2+
import { SpanContext, TransactionContext } from '@sentry/types';
3+
import { logger } from '@sentry/utils';
4+
5+
import { Span } from './span';
6+
import { Transaction } from './transaction';
7+
8+
/** Returns all trace headers that are currently on the top scope. */
9+
function traceHeaders(this: Hub): { [key: string]: string } {
10+
const scope = this.getScope();
11+
if (scope) {
12+
const span = scope.getSpan();
13+
if (span) {
14+
return {
15+
'sentry-trace': span.toTraceparent(),
16+
};
17+
}
18+
}
19+
return {};
20+
}
21+
22+
/**
23+
* {@see Hub.startTransaction}
24+
*/
25+
function startTransaction(this: Hub, context: TransactionContext): Transaction {
26+
const transaction = new Transaction(context, this);
27+
28+
const client = this.getClient();
29+
// Roll the dice for sampling transaction, all child spans inherit the sampling decision.
30+
if (transaction.sampled === undefined) {
31+
const sampleRate = (client && client.getOptions().tracesSampleRate) || 0;
32+
// if true = we want to have the transaction
33+
// if false = we don't want to have it
34+
// Math.random (inclusive of 0, but not 1)
35+
transaction.sampled = Math.random() < sampleRate;
36+
}
37+
38+
// We only want to create a span list if we sampled the transaction
39+
// If sampled == false, we will discard the span anyway, so we can save memory by not storing child spans
40+
if (transaction.sampled) {
41+
const experimentsOptions = (client && client.getOptions()._experiments) || {};
42+
transaction.initSpanRecorder(experimentsOptions.maxSpans as number);
43+
}
44+
45+
return transaction;
46+
}
47+
48+
/**
49+
* {@see Hub.startSpan}
50+
*/
51+
function startSpan(this: Hub, context: SpanContext): Transaction | Span {
52+
/**
53+
* @deprecated
54+
* TODO: consider removing this in a future release.
55+
*
56+
* This is for backwards compatibility with releases before startTransaction
57+
* existed, to allow for a smoother transition.
58+
*/
59+
{
60+
// The `TransactionContext.name` field used to be called `transaction`.
61+
const transactionContext = context as Partial<TransactionContext & { transaction: string }>;
62+
if (transactionContext.transaction !== undefined) {
63+
transactionContext.name = transactionContext.transaction;
64+
}
65+
// Check for not undefined since we defined it's ok to start a transaction
66+
// with an empty name.
67+
if (transactionContext.name !== undefined) {
68+
logger.warn('Deprecated: Use startTransaction to start transactions and Transaction.startChild to start spans.');
69+
return this.startTransaction(transactionContext as TransactionContext);
70+
}
71+
}
72+
73+
const scope = this.getScope();
74+
if (scope) {
75+
// If there is a Span on the Scope we start a child and return that instead
76+
const parentSpan = scope.getSpan();
77+
if (parentSpan) {
78+
return parentSpan.startChild(context);
79+
}
80+
}
81+
82+
// Otherwise we return a new Span
83+
return new Span(context);
84+
}
85+
86+
/**
87+
* This patches the global object and injects the APM extensions methods
88+
*/
89+
export function addExtensionMethods(): void {
90+
const carrier = getMainCarrier();
91+
if (carrier.__SENTRY__) {
92+
carrier.__SENTRY__.extensions = carrier.__SENTRY__.extensions || {};
93+
if (!carrier.__SENTRY__.extensions.startTransaction) {
94+
carrier.__SENTRY__.extensions.startTransaction = startTransaction;
95+
}
96+
if (!carrier.__SENTRY__.extensions.startSpan) {
97+
carrier.__SENTRY__.extensions.startSpan = startSpan;
98+
}
99+
if (!carrier.__SENTRY__.extensions.traceHeaders) {
100+
carrier.__SENTRY__.extensions.traceHeaders = traceHeaders;
101+
}
102+
}
103+
}

packages/tracing/src/index.bundle.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
export {
2+
Breadcrumb,
3+
Request,
4+
SdkInfo,
5+
Event,
6+
Exception,
7+
Response,
8+
Severity,
9+
StackFrame,
10+
Stacktrace,
11+
Status,
12+
Thread,
13+
User,
14+
} from '@sentry/types';
15+
16+
export {
17+
addGlobalEventProcessor,
18+
addBreadcrumb,
19+
captureException,
20+
captureEvent,
21+
captureMessage,
22+
configureScope,
23+
getHubFromCarrier,
24+
getCurrentHub,
25+
Hub,
26+
Scope,
27+
setContext,
28+
setExtra,
29+
setExtras,
30+
setTag,
31+
setTags,
32+
setUser,
33+
Transports,
34+
withScope,
35+
} from '@sentry/browser';
36+
37+
export { BrowserOptions } from '@sentry/browser';
38+
export { BrowserClient, ReportDialogOptions } from '@sentry/browser';
39+
export {
40+
defaultIntegrations,
41+
forceLoad,
42+
init,
43+
lastEventId,
44+
onLoad,
45+
showReportDialog,
46+
flush,
47+
close,
48+
wrap,
49+
} from '@sentry/browser';
50+
export { SDK_NAME, SDK_VERSION } from '@sentry/browser';
51+
52+
import { Integrations as BrowserIntegrations } from '@sentry/browser';
53+
import { getGlobalObject } from '@sentry/utils';
54+
55+
import { addExtensionMethods } from './hubextensions';
56+
import * as ApmIntegrations from './integrations';
57+
58+
export { Span, TRACEPARENT_REGEXP } from './span';
59+
60+
let windowIntegrations = {};
61+
62+
// This block is needed to add compatibility with the integrations packages when used with a CDN
63+
// tslint:disable: no-unsafe-any
64+
const _window = getGlobalObject<Window>();
65+
if (_window.Sentry && _window.Sentry.Integrations) {
66+
windowIntegrations = _window.Sentry.Integrations;
67+
}
68+
// tslint:enable: no-unsafe-any
69+
70+
const INTEGRATIONS = {
71+
...windowIntegrations,
72+
...BrowserIntegrations,
73+
Tracing: ApmIntegrations.Tracing,
74+
};
75+
76+
export { INTEGRATIONS as Integrations };
77+
78+
// We are patching the global object with our hub extension methods
79+
addExtensionMethods();

0 commit comments

Comments
 (0)