From bff0f62d8f0fc98c83700096c7f53b551d147f3d Mon Sep 17 00:00:00 2001 From: AJ Date: Tue, 29 Sep 2020 11:40:44 -0700 Subject: [PATCH 01/20] EoF fix --- .../python/guides/aws-lambda/index.mdx | 24 ++++++++++--------- .../python/guides/gcp-functions/index.mdx | 5 +++- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/platforms/python/guides/aws-lambda/index.mdx b/src/platforms/python/guides/aws-lambda/index.mdx index 90444c4cee08ac..c41aaae4a1e26e 100644 --- a/src/platforms/python/guides/aws-lambda/index.mdx +++ b/src/platforms/python/guides/aws-lambda/index.mdx @@ -5,7 +5,7 @@ redirect_from: - /platforms/python/aws_lambda/ --- -_(New in version 0.3.5)_ +_(New in version 0.18.0)_ Create a deployment package on your local machine and install the required dependencies in the deployment package. For more information, see [AWS Lambda deployment package in Python](https://docs.aws.amazon.com/lambda/latest/dg/python-package.html). @@ -24,15 +24,24 @@ from sentry_sdk.integrations.aws_lambda import AwsLambdaIntegration sentry_sdk.init( dsn="___PUBLIC_DSN___", - integrations=[AwsLambdaIntegration()] + integrations=[AwsLambdaIntegration()], + traces_sample_rate=1.0, # adjust the sample rate in production as needed ) def my_function(event, context): # ... ``` +Set `send_default_pii` to `True` to capture function payload. + Check out Sentry's [AWS sample apps](https://github.com/getsentry/examples/tree/master/aws-lambda/python) for detailed examples. + + +If you are using another web framework inside of AWS Lambda, the framework might catch those exceptions before we get to see them. Make sure to enable the framework specific integration as well, if one exists. See [_Integrations_](/platforms/python/#integrations) for more information. + + + ## Timeout Warning _(New in version 0.16.3)_ @@ -52,19 +61,12 @@ sentry_sdk.init( The timeout warning is sent only if the timeout in the Lambda Function configuration is set to a value greater than one second. - - -If you are using another web framework inside of AWS Lambda, the framework might catch those exceptions before we get to see them. Make sure to enable the framework specific integration as well, if one exists. See [_Integrations_](/platforms/python/#integrations) for more information. - - - - - ## Behavior With the AWS Lambda integration enabled, the Python SDK will: -- Automatically report all exceptions from your Lambda Functions +- Automatically report all exceptions and transactions from your Lambda Functions +- You can control transactions sample rate using `traces_sample_rate`. You can learn more about transactions in [Distributed Tracing](/performance-monitoring/distributed-tracing/#traces-transactions-and-spans) - Issues reports automatically include: - A link to CloudWatch Logs diff --git a/src/platforms/python/guides/gcp-functions/index.mdx b/src/platforms/python/guides/gcp-functions/index.mdx index 451b20f39359bb..4fcaa14b9ec1b9 100644 --- a/src/platforms/python/guides/gcp-functions/index.mdx +++ b/src/platforms/python/guides/gcp-functions/index.mdx @@ -25,11 +25,13 @@ from sentry_sdk.integrations.gcp import GcpIntegration sentry_sdk.init( dsn="___PUBLIC_DSN___", integrations=[GcpIntegration()], + traces_sample_rate=1.0, # adjust the sample rate in production as needed ) def http_function_entrypoint(request): # ... ``` +Set `send_default_pii` to `True` to capture function payload. Check out Sentry's [GCP sample apps](https://github.com/getsentry/examples/tree/master/gcp-cloud-functions) for detailed examples. @@ -60,7 +62,8 @@ The timeout warning is sent only if the timeout in the GCP Function configuratio With the GCP Functions integration enabled, the Python SDK will: -- Automatically report all exceptions from your google cloud functions +- Automatically report all exceptions and transactions from your google cloud functions +- You can control transactions sample rate using `traces_sample_rate`. You can learn more about transactions in [Distributed Tracing](/performance-monitoring/distributed-tracing/#traces-transactions-and-spans) - Issues reports automatically include: - A link to the stackdriver logs From c0cbe1e1195408073dd56a8132eeba6d82fee0f2 Mon Sep 17 00:00:00 2001 From: ajjindal <55766763+ajjindal@users.noreply.github.com> Date: Tue, 29 Sep 2020 15:15:04 -0700 Subject: [PATCH 02/20] Update src/platforms/python/guides/aws-lambda/index.mdx Co-authored-by: Fiona <61481573+PeloWriter@users.noreply.github.com> --- src/platforms/python/guides/aws-lambda/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platforms/python/guides/aws-lambda/index.mdx b/src/platforms/python/guides/aws-lambda/index.mdx index c41aaae4a1e26e..bcba9d2594f36e 100644 --- a/src/platforms/python/guides/aws-lambda/index.mdx +++ b/src/platforms/python/guides/aws-lambda/index.mdx @@ -65,7 +65,7 @@ The timeout warning is sent only if the timeout in the Lambda Function configura With the AWS Lambda integration enabled, the Python SDK will: -- Automatically report all exceptions and transactions from your Lambda Functions +- Automatically report all events from your Lambda Functions - You can control transactions sample rate using `traces_sample_rate`. You can learn more about transactions in [Distributed Tracing](/performance-monitoring/distributed-tracing/#traces-transactions-and-spans) - Issues reports automatically include: From 9a9c3d9215ac4e4a077114c7b8a365938a2cdf11 Mon Sep 17 00:00:00 2001 From: ajjindal <55766763+ajjindal@users.noreply.github.com> Date: Tue, 29 Sep 2020 15:15:44 -0700 Subject: [PATCH 03/20] Update src/platforms/python/guides/gcp-functions/index.mdx Co-authored-by: Fiona <61481573+PeloWriter@users.noreply.github.com> --- src/platforms/python/guides/gcp-functions/index.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/platforms/python/guides/gcp-functions/index.mdx b/src/platforms/python/guides/gcp-functions/index.mdx index 4fcaa14b9ec1b9..01bee93fb19e11 100644 --- a/src/platforms/python/guides/gcp-functions/index.mdx +++ b/src/platforms/python/guides/gcp-functions/index.mdx @@ -25,7 +25,8 @@ from sentry_sdk.integrations.gcp import GcpIntegration sentry_sdk.init( dsn="___PUBLIC_DSN___", integrations=[GcpIntegration()], - traces_sample_rate=1.0, # adjust the sample rate in production as needed + traces_sample_rate=1.0, # We recommend adjusting this in production +}); ) def http_function_entrypoint(request): From 53516e09a3457630dbfe334daa498d03e3bfa152 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Tue, 29 Sep 2020 13:09:26 -0700 Subject: [PATCH 04/20] feat: Simplify Laravel instructions (#2388) --- src/components/pageGrid.tsx | 7 ++- .../configuration/other-versions/index.mdx | 5 ++ .../other-versions}/laravel4.mdx | 0 .../other-versions/laravel5-6.mdx | 63 +++++++++++++++++++ .../other-versions}/lumen.mdx | 0 src/platforms/php/guides/laravel/index.mdx | 33 ++-------- .../capture.mdx => usage/index.mdx} | 2 +- 7 files changed, 77 insertions(+), 33 deletions(-) create mode 100644 src/platforms/php/guides/laravel/configuration/other-versions/index.mdx rename src/platforms/php/guides/laravel/{ => configuration/other-versions}/laravel4.mdx (100%) create mode 100644 src/platforms/php/guides/laravel/configuration/other-versions/laravel5-6.mdx rename src/platforms/php/guides/laravel/{ => configuration/other-versions}/lumen.mdx (100%) rename src/platforms/php/guides/laravel/{configuration/capture.mdx => usage/index.mdx} (99%) diff --git a/src/components/pageGrid.tsx b/src/components/pageGrid.tsx index b384aec41fdb54..8f4c32df9499bb 100644 --- a/src/components/pageGrid.tsx +++ b/src/components/pageGrid.tsx @@ -43,9 +43,10 @@ export default ({ nextPages = false, header }: Props): JSX.Element => { ); if (nextPages) { - matches = matches.slice( - matches.indexOf(matches.find(n => n.path === currentPath)) - ); + const currentPage = matches.find(n => n.path === currentPath); + if (currentPage) { + matches = matches.slice(matches.indexOf(currentPage)); + } } else { matches = matches.filter(n => n.path !== currentPath); } diff --git a/src/platforms/php/guides/laravel/configuration/other-versions/index.mdx b/src/platforms/php/guides/laravel/configuration/other-versions/index.mdx new file mode 100644 index 00000000000000..67d9280d3ed924 --- /dev/null +++ b/src/platforms/php/guides/laravel/configuration/other-versions/index.mdx @@ -0,0 +1,5 @@ +--- +title: Other Versions +--- + + diff --git a/src/platforms/php/guides/laravel/laravel4.mdx b/src/platforms/php/guides/laravel/configuration/other-versions/laravel4.mdx similarity index 100% rename from src/platforms/php/guides/laravel/laravel4.mdx rename to src/platforms/php/guides/laravel/configuration/other-versions/laravel4.mdx diff --git a/src/platforms/php/guides/laravel/configuration/other-versions/laravel5-6.mdx b/src/platforms/php/guides/laravel/configuration/other-versions/laravel5-6.mdx new file mode 100644 index 00000000000000..4ecda00975a548 --- /dev/null +++ b/src/platforms/php/guides/laravel/configuration/other-versions/laravel5-6.mdx @@ -0,0 +1,63 @@ +--- +title: Laravel 5.x and 6.x +--- + +## Install + +Install the `sentry/sentry-laravel` package: + +```bash +$ composer require sentry/sentry-laravel +``` + +Add Sentry reporting to `App/Exceptions/Handler.php`. + +```php {filename:App/Exceptions/Handler.php} +public function report(Exception $exception) +{ + if ($this->shouldReport($exception) && app()->bound('sentry')) { + app('sentry')->captureException($exception); + } + + parent::report($exception); +} +``` + +If you're on Laravel 5.5 or later the package will be auto-discovered. Otherwise you will need to manually configure it in your `config/app.php`. + +```php {filename:config/app.php} +'providers' => array( + // ... + Sentry\Laravel\ServiceProvider::class, +), +'aliases' => array( + // ... + 'Sentry' => Sentry\Laravel\Facade::class, +), +``` + +## Configure + +Run: + +```shell +$ php artisan sentry:publish +``` + +that creates the Sentry configuration file (`config/sentry.php`). + +Afterwards, add your DSN to `.env`: + +```shell {filename:.env} +SENTRY_LARAVEL_DSN=___PUBLIC_DSN___ +``` + +## Verify Setup + +You can easily verify that Sentry is capturing errors in your Laravel application by creating a debug route that will throw an exception: + +```php +Route::get('/debug-sentry', function () { + throw new Exception('My first Sentry error!'); +}); +``` diff --git a/src/platforms/php/guides/laravel/lumen.mdx b/src/platforms/php/guides/laravel/configuration/other-versions/lumen.mdx similarity index 100% rename from src/platforms/php/guides/laravel/lumen.mdx rename to src/platforms/php/guides/laravel/configuration/other-versions/lumen.mdx diff --git a/src/platforms/php/guides/laravel/index.mdx b/src/platforms/php/guides/laravel/index.mdx index aa9f622be46779..d904bac72dc5b3 100644 --- a/src/platforms/php/guides/laravel/index.mdx +++ b/src/platforms/php/guides/laravel/index.mdx @@ -1,6 +1,7 @@ --- title: Laravel sdk: sentry.php.laravel +sidebar_order: 0 redirect_from: - /clients/php/integrations/laravel/ - /platforms/php/laravel/ @@ -8,7 +9,7 @@ redirect_from: Laravel is supported via a native package, [sentry-laravel](https://github.com/getsentry/sentry-laravel). -Sentry supports Laravel 5+. +This guide is for Laravel 7+. We also provide instructions for [other versions](configuration/other-versions/) as well as [Lumen-specific instructions](configuration/other-versions/lumen/). ## Install @@ -18,23 +19,8 @@ Install the `sentry/sentry-laravel` package: $ composer require sentry/sentry-laravel ``` -If you're on Laravel 5.5 or later the package will be auto-discovered. Otherwise you will need to manually configure it in your `config/app.php`. - -```php {filename:config/app.php} -'providers' => array( - // ... - Sentry\Laravel\ServiceProvider::class, -), -'aliases' => array( - // ... - 'Sentry' => Sentry\Laravel\Facade::class, -), -``` - Add Sentry reporting to `App/Exceptions/Handler.php`. -**For Laravel 7.x and later:** - ```php {filename:App/Exceptions/Handler.php} public function report(Throwable $exception) { @@ -46,19 +32,6 @@ public function report(Throwable $exception) } ``` -**For Laravel 5.x and 6.x:** - -```php {filename:App/Exceptions/Handler.php} -public function report(Exception $exception) -{ - if ($this->shouldReport($exception) && app()->bound('sentry')) { - app('sentry')->captureException($exception); - } - - parent::report($exception); -} -``` - ## Configure Run: @@ -118,3 +91,5 @@ Set `traces_sample_rate` to a value greater than `0.0` after that, Performance M Performance data is transmitted using a new event type called "transactions", which you can learn about in [Distributed Tracing](/performance-monitoring/distributed-tracing/#traces-transactions-and-spans). **To capture transactions, you must install and configure your SDK to set the `traces_sample_rate` option to a nonzero value.** The example configuration above will transmit 100% of captured traces. Be sure to lower this value in production otherwise you could burn through your quota quickly. Learn more about sampling in [Using Your SDK to Filter Events](configuration/filtering/). + + diff --git a/src/platforms/php/guides/laravel/configuration/capture.mdx b/src/platforms/php/guides/laravel/usage/index.mdx similarity index 99% rename from src/platforms/php/guides/laravel/configuration/capture.mdx rename to src/platforms/php/guides/laravel/usage/index.mdx index 5864fc703c7211..51734fd8656ee6 100644 --- a/src/platforms/php/guides/laravel/configuration/capture.mdx +++ b/src/platforms/php/guides/laravel/usage/index.mdx @@ -1,5 +1,5 @@ --- -title: Advanced Usage +title: Usage sidebar_order: 7 excerpt: "" description: "Learn more about automatically reporting errors, exceptions, and rejections as well as how to manually capture errors and enable message capture." From 120569f6cddd63ad8aba1609b83943706ee98779 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Tue, 29 Sep 2020 15:00:47 -0700 Subject: [PATCH 05/20] feat: Switch to fixed navs with scrolling (#2387) --- package.json | 2 +- .../__snapshots__/header.test.js.snap | 57 +++---- src/components/__tests__/header.test.js | 9 ++ src/components/header.tsx | 51 ++++--- src/components/layout.tsx | 54 +++---- src/components/navbar.tsx | 140 +++++++++--------- src/css/_includes/global-header.scss | 46 +++--- src/css/_includes/grid.scss | 69 +++++++-- src/css/_includes/sidebar.scss | 9 -- yarn.lock | 8 +- 10 files changed, 246 insertions(+), 199 deletions(-) diff --git a/package.json b/package.json index dcdb4f7d832a1e..8934f009bb5bf8 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "jsdom": "^16.3.0", "nginx-conf": "^1.5.0", "node-sass": "^4.14.1", - "platformicons": "^3.1.0", + "platformicons": "^3.1.1", "prismjs": "^1.20.0", "prop-types": "^15.7.2", "query-string": "^6.13.1", diff --git a/src/components/__tests__/__snapshots__/header.test.js.snap b/src/components/__tests__/__snapshots__/header.test.js.snap index 9c9201d55c6bc7..f66dc36f704cb1 100644 --- a/src/components/__tests__/__snapshots__/header.test.js.snap +++ b/src/components/__tests__/__snapshots__/header.test.js.snap @@ -1,36 +1,41 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Header renders correctly 1`] = ` -
- - - - - - -
- Docs -
-
+ + + + +
+ Docs +
+ +
+
-
+ `; diff --git a/src/components/__tests__/header.test.js b/src/components/__tests__/header.test.js index ed376580a1e456..aaa9a75182e5b5 100644 --- a/src/components/__tests__/header.test.js +++ b/src/components/__tests__/header.test.js @@ -2,6 +2,15 @@ import React from "react"; import renderer from "react-test-renderer"; import Header from "../header"; +jest.mock("../navbar", () => { + return { + __esModule: true, + default: () => { + return
; + }, + }; +}); + describe("Header", () => { it("renders correctly", () => { const tree = renderer.create(
).toJSON(); diff --git a/src/components/header.tsx b/src/components/header.tsx index e16a73f7c00389..6bfe1e938b2675 100644 --- a/src/components/header.tsx +++ b/src/components/header.tsx @@ -1,38 +1,43 @@ import React from "react"; +import Navbar from "./navbar"; import SmartLink from "./smartLink"; -export default (): JSX.Element => { +type Props = { + platforms?: string[]; +}; + +export default ({ platforms }: Props): JSX.Element => { return ( -
- - - - - - -
Docs
-
+
+
+ + + + + + +
Docs
+
+
+ + -
+
); }; diff --git a/src/components/layout.tsx b/src/components/layout.tsx index 118973b6112a2c..cf0b2b300acebd 100644 --- a/src/components/layout.tsx +++ b/src/components/layout.tsx @@ -3,7 +3,6 @@ import React from "react"; import Breadcrumbs from "./breadcrumbs"; import Header from "./header"; import Sidebar from "./sidebar"; -import Navbar from "./navbar"; import "~src/css/screen.scss"; @@ -23,41 +22,34 @@ export default ({ sidebar, pageContext = {}, }: Props): JSX.Element => { - return ( -
-
-
+ const hasSidebar = !!sidebar; -
); }; diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx index 168b2c99049b4c..453762724862d0 100644 --- a/src/components/navbar.tsx +++ b/src/components/navbar.tsx @@ -17,82 +17,80 @@ export default ({ platforms }: Props): JSX.Element => { const [currentPlatform] = usePlatform(null, false); return ( -
- -
+ ))} + + + Show all platforms + + + + + API + + + + + Sign In + + + + + + + ); }; diff --git a/src/css/_includes/global-header.scss b/src/css/_includes/global-header.scss index 961a1a481dab7b..ff146ff6da161a 100644 --- a/src/css/_includes/global-header.scss +++ b/src/css/_includes/global-header.scss @@ -1,6 +1,7 @@ .navbar { box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1), 0 3px 5px 0 rgba(0, 0, 0, 0.02); z-index: 1; + padding: 0 1.5rem; } .global-header { @@ -9,29 +10,36 @@ .navbar-brand { display: flex; - flex-direction: row; - justify-content: center; height: 100%; - margin-right: 0; - font-size: 0.5rem; - padding-bottom: 0.7em; - padding-top: 0.7em; - svg { - display: block; + a { + display: flex; + flex-direction: row; + align-items: center; + color: #333; height: 100%; - margin-right: 0.7rem; - } + margin-right: 0; + font-size: 0.5rem; + padding-bottom: 0.7em; + padding-top: 0.7em; + + svg { + display: block; + height: 75%; + color: inherit; + margin-right: 0.7rem; + } - h6 { - line-height: 32px; - font-size: 18px; - margin: 0; - font-weight: 300; - color: #666; - flex: 1; - white-space: nowrap; - overflow: hidden; + h6 { + line-height: 32px; + font-size: 18px; + margin: 0; + font-weight: 300; + color: inherit; + flex: 1; + white-space: nowrap; + overflow: hidden; + } } } } diff --git a/src/css/_includes/grid.scss b/src/css/_includes/grid.scss index bfd4b74f2ac22c..3a6578dd834e5a 100644 --- a/src/css/_includes/grid.scss +++ b/src/css/_includes/grid.scss @@ -20,29 +20,68 @@ body { height: 100%; } + .document-wrapper { - display: flex; - min-height: 100%; - flex-direction: column; - overflow: hidden; + display: grid; + grid-template-areas: + "header header" + "main main"; + grid-template-columns: 245px 1fr; + grid-template-rows: 64px 1fr; + + > header { + display: grid; + grid-area: header; + grid-template-columns: 245px 1fr; + grid-template-areas: + "brand navbar"; + position: fixed; + + > .navbar-brand { + grid-area: brand; + } + + > nav { + grid-area: navbar; + } + } > main { - display: flex; - flex-direction: column; - flex: 1 1 auto; - min-width: 0; + grid-area: main; + } + + > .sidebar { + grid-area: sidebar; + margin-top: 64px; + position: fixed; + overflow: auto; + height: 100%; + } + + &.with-sidebar { + grid-template-areas: + "header header" + "sidebar main"; } } -@include media-breakpoint-up(md) { +@media (max-width: 768px) { .document-wrapper { - flex-direction: row; - max-height: 100%; - } + grid-template-columns: 1fr; + grid-template-areas: + "header" + "main" + "sidebar" !important; + + &.with-sidebar { + } - .sidebar { - flex-basis: 270px; - flex-shrink: 0; + > .sidebar { + width: 100%; + background: #fff; + grid-column: 1; + grid-row: 2; + } } } diff --git a/src/css/_includes/sidebar.scss b/src/css/_includes/sidebar.scss index 5803aa1a87c9f9..36b79bdfa25f26 100644 --- a/src/css/_includes/sidebar.scss +++ b/src/css/_includes/sidebar.scss @@ -1,6 +1,4 @@ .sidebar { - position: relative; - min-height: 100%; flex-direction: column; display: flex; @@ -148,13 +146,6 @@ margin-bottom: 0.25rem; } -#sidebar { - // Work around Firefox bug - // https://moduscreate.com/blog/how-to-fix-overflow-issues-in-css-flex-layouts/ - min-height: 0; - margin-top: 2px; -} - .section-nav { list-style-type: none; padding-left: 0; diff --git a/yarn.lock b/yarn.lock index d84d90083f5f8a..d93cae4f1cc9c1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13872,10 +13872,10 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -platformicons@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/platformicons/-/platformicons-3.1.0.tgz#a3fa2fba83d3304c06a7c5b4502b34bbb0663505" - integrity sha512-HVjDjE/1M2yhL+wt2RHjgjo2g9Yo0y7sJdM4ZHISE7tuPwr43A9TSHOeRgocs1whNayQpIcnLPMCb6MS0/mwVg== +platformicons@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/platformicons/-/platformicons-3.1.1.tgz#ca50a544230b5656e012ed775957ffe88b6f938e" + integrity sha512-EdC6ig6jnOgx8Zx8Uw5LgALzX7EXCNGXzDO/eT2O1AXeJs+MTIpK3ULT3PT8HXDbPQ/1j3Fwh4CPctof9N0CvA== dependencies: "@types/node" "*" "@types/react" "^16 || ^17" From 84b8b09b1e06119485ff7402a628228e6853ad8e Mon Sep 17 00:00:00 2001 From: David Cramer Date: Tue, 29 Sep 2020 15:26:02 -0700 Subject: [PATCH 06/20] Revert "feat: Switch to fixed navs with scrolling (#2387)" This reverts commit a3a507cb7846df70c5d677b510af7d4230687548. --- package.json | 2 +- .../__snapshots__/header.test.js.snap | 57 ++++--- src/components/__tests__/header.test.js | 9 -- src/components/header.tsx | 51 +++---- src/components/layout.tsx | 54 ++++--- src/components/navbar.tsx | 140 +++++++++--------- src/css/_includes/global-header.scss | 46 +++--- src/css/_includes/grid.scss | 69 ++------- src/css/_includes/sidebar.scss | 9 ++ yarn.lock | 8 +- 10 files changed, 199 insertions(+), 246 deletions(-) diff --git a/package.json b/package.json index 8934f009bb5bf8..dcdb4f7d832a1e 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "jsdom": "^16.3.0", "nginx-conf": "^1.5.0", "node-sass": "^4.14.1", - "platformicons": "^3.1.1", + "platformicons": "^3.1.0", "prismjs": "^1.20.0", "prop-types": "^15.7.2", "query-string": "^6.13.1", diff --git a/src/components/__tests__/__snapshots__/header.test.js.snap b/src/components/__tests__/__snapshots__/header.test.js.snap index f66dc36f704cb1..9c9201d55c6bc7 100644 --- a/src/components/__tests__/__snapshots__/header.test.js.snap +++ b/src/components/__tests__/__snapshots__/header.test.js.snap @@ -1,41 +1,36 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Header renders correctly 1`] = ` -
- -
+ + + +
+ Docs +
+ -
+
`; diff --git a/src/components/__tests__/header.test.js b/src/components/__tests__/header.test.js index aaa9a75182e5b5..ed376580a1e456 100644 --- a/src/components/__tests__/header.test.js +++ b/src/components/__tests__/header.test.js @@ -2,15 +2,6 @@ import React from "react"; import renderer from "react-test-renderer"; import Header from "../header"; -jest.mock("../navbar", () => { - return { - __esModule: true, - default: () => { - return
; - }, - }; -}); - describe("Header", () => { it("renders correctly", () => { const tree = renderer.create(
).toJSON(); diff --git a/src/components/header.tsx b/src/components/header.tsx index 6bfe1e938b2675..e16a73f7c00389 100644 --- a/src/components/header.tsx +++ b/src/components/header.tsx @@ -1,43 +1,38 @@ import React from "react"; -import Navbar from "./navbar"; import SmartLink from "./smartLink"; -type Props = { - platforms?: string[]; -}; - -export default ({ platforms }: Props): JSX.Element => { +export default (): JSX.Element => { return ( -
-
- - - - - - -
Docs
-
-
- - +
+ + + + + + +
Docs
+
-
+
); }; diff --git a/src/components/layout.tsx b/src/components/layout.tsx index cf0b2b300acebd..118973b6112a2c 100644 --- a/src/components/layout.tsx +++ b/src/components/layout.tsx @@ -3,6 +3,7 @@ import React from "react"; import Breadcrumbs from "./breadcrumbs"; import Header from "./header"; import Sidebar from "./sidebar"; +import Navbar from "./navbar"; import "~src/css/screen.scss"; @@ -22,34 +23,41 @@ export default ({ sidebar, pageContext = {}, }: Props): JSX.Element => { - const hasSidebar = !!sidebar; - return ( -
-
-
-
-
- -
- {children} -
-
+
+
+
- +
); }; diff --git a/src/css/_includes/global-header.scss b/src/css/_includes/global-header.scss index ff146ff6da161a..961a1a481dab7b 100644 --- a/src/css/_includes/global-header.scss +++ b/src/css/_includes/global-header.scss @@ -1,7 +1,6 @@ .navbar { box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1), 0 3px 5px 0 rgba(0, 0, 0, 0.02); z-index: 1; - padding: 0 1.5rem; } .global-header { @@ -10,36 +9,29 @@ .navbar-brand { display: flex; + flex-direction: row; + justify-content: center; height: 100%; + margin-right: 0; + font-size: 0.5rem; + padding-bottom: 0.7em; + padding-top: 0.7em; - a { - display: flex; - flex-direction: row; - align-items: center; - color: #333; + svg { + display: block; height: 100%; - margin-right: 0; - font-size: 0.5rem; - padding-bottom: 0.7em; - padding-top: 0.7em; - - svg { - display: block; - height: 75%; - color: inherit; - margin-right: 0.7rem; - } + margin-right: 0.7rem; + } - h6 { - line-height: 32px; - font-size: 18px; - margin: 0; - font-weight: 300; - color: inherit; - flex: 1; - white-space: nowrap; - overflow: hidden; - } + h6 { + line-height: 32px; + font-size: 18px; + margin: 0; + font-weight: 300; + color: #666; + flex: 1; + white-space: nowrap; + overflow: hidden; } } } diff --git a/src/css/_includes/grid.scss b/src/css/_includes/grid.scss index 3a6578dd834e5a..bfd4b74f2ac22c 100644 --- a/src/css/_includes/grid.scss +++ b/src/css/_includes/grid.scss @@ -20,68 +20,29 @@ body { height: 100%; } - .document-wrapper { - display: grid; - grid-template-areas: - "header header" - "main main"; - grid-template-columns: 245px 1fr; - grid-template-rows: 64px 1fr; - - > header { - display: grid; - grid-area: header; - grid-template-columns: 245px 1fr; - grid-template-areas: - "brand navbar"; - position: fixed; - - > .navbar-brand { - grid-area: brand; - } - - > nav { - grid-area: navbar; - } - } + display: flex; + min-height: 100%; + flex-direction: column; + overflow: hidden; > main { - grid-area: main; - } - - > .sidebar { - grid-area: sidebar; - margin-top: 64px; - position: fixed; - overflow: auto; - height: 100%; - } - - &.with-sidebar { - grid-template-areas: - "header header" - "sidebar main"; + display: flex; + flex-direction: column; + flex: 1 1 auto; + min-width: 0; } } -@media (max-width: 768px) { +@include media-breakpoint-up(md) { .document-wrapper { - grid-template-columns: 1fr; - grid-template-areas: - "header" - "main" - "sidebar" !important; - - &.with-sidebar { - } + flex-direction: row; + max-height: 100%; + } - > .sidebar { - width: 100%; - background: #fff; - grid-column: 1; - grid-row: 2; - } + .sidebar { + flex-basis: 270px; + flex-shrink: 0; } } diff --git a/src/css/_includes/sidebar.scss b/src/css/_includes/sidebar.scss index 36b79bdfa25f26..5803aa1a87c9f9 100644 --- a/src/css/_includes/sidebar.scss +++ b/src/css/_includes/sidebar.scss @@ -1,4 +1,6 @@ .sidebar { + position: relative; + min-height: 100%; flex-direction: column; display: flex; @@ -146,6 +148,13 @@ margin-bottom: 0.25rem; } +#sidebar { + // Work around Firefox bug + // https://moduscreate.com/blog/how-to-fix-overflow-issues-in-css-flex-layouts/ + min-height: 0; + margin-top: 2px; +} + .section-nav { list-style-type: none; padding-left: 0; diff --git a/yarn.lock b/yarn.lock index d93cae4f1cc9c1..d84d90083f5f8a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13872,10 +13872,10 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -platformicons@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/platformicons/-/platformicons-3.1.1.tgz#ca50a544230b5656e012ed775957ffe88b6f938e" - integrity sha512-EdC6ig6jnOgx8Zx8Uw5LgALzX7EXCNGXzDO/eT2O1AXeJs+MTIpK3ULT3PT8HXDbPQ/1j3Fwh4CPctof9N0CvA== +platformicons@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/platformicons/-/platformicons-3.1.0.tgz#a3fa2fba83d3304c06a7c5b4502b34bbb0663505" + integrity sha512-HVjDjE/1M2yhL+wt2RHjgjo2g9Yo0y7sJdM4ZHISE7tuPwr43A9TSHOeRgocs1whNayQpIcnLPMCb6MS0/mwVg== dependencies: "@types/node" "*" "@types/react" "^16 || ^17" From 90ce36029cf3f2b0f5f82f93c8c0f490febd7a64 Mon Sep 17 00:00:00 2001 From: "Tien \"Mimi\" Nguyen" Date: Tue, 29 Sep 2020 16:16:23 -0700 Subject: [PATCH 07/20] updated links to route correctly (#2390) Docs has many broken/dead fragment URLs because an anchored section of a page moved or was renamed. --- src/docs/accounts/quotas/index.mdx | 6 +++--- src/docs/accounts/quotas/manage-event-stream-guide.mdx | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/docs/accounts/quotas/index.mdx b/src/docs/accounts/quotas/index.mdx index 4e459d1566f498..1f684da148ac95 100644 --- a/src/docs/accounts/quotas/index.mdx +++ b/src/docs/accounts/quotas/index.mdx @@ -26,7 +26,7 @@ Sentry completes a thorough evaluation of each event to determine if it counts t 1. **SDK configuration** - The SDK configuration either allows the event or filters the event out. For more information, see [Outbound Filters in our guide to Manage Your Event Stream](/accounts/quotas/manage-event-stream-guide/#outbound-filters) or [Filtering Events](/platform-redirect/?next=/configuration/filtering/). + The SDK configuration either allows the event or filters the event out. For more information, see [Manage Your Event Stream](/accounts/quotas/manage-event-stream-guide/) or [Filtering Events](/platform-redirect/?next=/configuration/filtering/). 2. **SDK sample rate** @@ -151,7 +151,7 @@ Per-key rate limits allow you to set the maximum volume of error events a key wi For example, you may have a project in production that generates a lot of noise. A rate limit allows you to set the maximum amount of data to “500 events per minute”. Additionally, you can create a second key for the same project for your staging environment, which is unlimited, ensuring your QA process is still untouched. -To set up rate limits, navigate to **[Project] » Client Keys » Configure**. Select an individual key or create a new one, then you’ll be able to define a rate limit as well as view a breakdown of events received by that key. For additional information and examples, see [Rate Limiting in our guide to Manage Your Event Stream](/accounts/quotas/manage-event-stream-guide/#4-rate-limiting). +To set up rate limits, navigate to **[Project] » Client Keys » Configure**. Select an individual key or create a new one, then you’ll be able to define a rate limit as well as view a breakdown of events received by that key. For additional information and examples, see [Rate Limiting in our guide to Manage Your Event Stream](/accounts/quotas/manage-event-stream-guide/#6-rate-limiting). Per-key rate limiting is available only for Business plans. @@ -213,7 +213,7 @@ _The 24 hour window ends at the beginning of the current hour, not at the curren What this means is that if you experience a spike, we will temporarily protect you, but if the increase in volume is sustained, the spike protection limit will gradually increase until Sentry finally accepts all events. -### How Does Spike Protection Help? {#how-does-spike-protection-help} +### How Does Spike Protection Help? Because Sentry bills on monthly event volume, spikes can consume your Sentry capacity for the rest of the month. If it really is a spike, spike protection drops events during the spike to try and conserve your capacity. We also send an email notification to the Owner when spike protection is activated. diff --git a/src/docs/accounts/quotas/manage-event-stream-guide.mdx b/src/docs/accounts/quotas/manage-event-stream-guide.mdx index 560320b4761b15..ecbd83f951690f 100644 --- a/src/docs/accounts/quotas/manage-event-stream-guide.mdx +++ b/src/docs/accounts/quotas/manage-event-stream-guide.mdx @@ -39,7 +39,7 @@ For more information and code samples check out: #### GlobalHandlers -The integration attaches global handlers to capture uncaught exceptions (`onerror`) and unhandled rejections (`onunhandledrejection`). Both handlers are enabled by default but can be disabled through configuration. For more information see [GlobalHandlers Integration](/platforms/javascript/#globalhandlers) +The integration attaches global handlers to capture uncaught exceptions (`onerror`) and unhandled rejections (`onunhandledrejection`). Both handlers are enabled by default but can be disabled through configuration. For more information see [GlobalHandlers Integration](/platforms/javascript/integrations/default/#globalhandlers) Check out additional configuration options with the [TryCatch](/platforms/javascript/integrations/default/#trycatch) and [ReportingObserver](/platforms/javascript/integrations/plugin/#reportingobserver) integrations. @@ -47,13 +47,13 @@ Check out additional configuration options with the [TryCatch](/platforms/javasc **Java** - Sentry SDK provides integrations with common Java loggers through implemented _Handlers_ and _Appenders_. The configuration allows you to set a logging threshold determining the level under which all errors will be filtered. For more information see Java Integrations [java.util.logging](/platforms/java/guides/logging/), [Log4j 1.x](/platforms/java/guides/log4j/), [Log4j 2.x](/platforms/java/guides/log4j2/), and [Logback](/platforms/java/guides/logback/). -**PHP** - The `error_types` configuration option allows you to set the error types you want Sentry to monitor. For more information see [PHP: error_types](/platforms/php/configuration/options/#error_types). +**PHP** - The `error_types` configuration option allows you to set the error types you want Sentry to monitor. For more information see [PHP: Common Options](/platforms/php/configuration/options/#common-options). **Ruby** - The `excluded_exceptions` configuration option allows you to set the exception types you wish to suppress. For more information see [Ruby Configuration](/platforms/ruby/configuration/options/#optional-settings) ## 3. Inbound Data Filters -While SDK configuration requires changes to your source code and depends on your next deployment, server-side filters can be easily configured per project under `[Project Settings] > Inbound Filters > Data Filters`. For more information, see [Inbound Filters](/accounts/quotas/#3-inbound-data-filters) and [Manage Your Flow of Errors Using Inbound Filters](https://blog.sentry.io/2017/11/27/setting-up-inbound-filters) +While SDK configuration requires changes to your source code and depends on your next deployment, server-side filters can be easily configured per project under `[Project Settings] > Inbound Filters > Data Filters`. For more information, see [Inbound Filters](/accounts/quotas/#inbound-data-filters) and [Manage Your Flow of Errors Using Inbound Filters](https://blog.sentry.io/2017/11/27/setting-up-inbound-filters) Once applied, you can track the filtered events (numbers and cause) using the graph provided at the top of the Inbound Data Filters view. @@ -63,7 +63,7 @@ Once applied, you can track the filtered events (numbers and cause) using the gr Proper event grouping is essential to maintain a meaningful Issue Stream and reduce redundant notifications. Sentry groups similar _Events_ into unique _Issues_ based on their _Fingerprint_. An event's fingerprint relies firstly on its **stack trace**. -With **JavaScript** errors, a minified source code might result in a nondeterministic stack trace that could mess up associated event grouping. Make sure Sentry has access to your `Source Maps` and minified artifacts. For more information see [Uploading Source Maps](/platforms/javascript/#source-maps). +With **JavaScript** errors, a minified source code might result in a nondeterministic stack trace that could mess up associated event grouping. Make sure Sentry has access to your `Source Maps` and minified artifacts. For more information see [Uploading Source Maps](/platforms/javascript/sourcemaps/). ![JavaScript stack trace without source maps](manage-event-stream-04.png) ![JavaScript stack trace with source maps](manage-event-stream-05.png) @@ -102,7 +102,7 @@ Under `[Project Settings] » Client Keys » Configure`, you can create multiple ![Per DSN Key rate limits](manage-event-stream-11.png) -For more information see [Rate Limiting Projects](/accounts/quotas/#id1) +For more information see [What Counts Toward My Quota](/accounts/quotas/#what-counts-toward-my-quota-table-view) ## 7. Spike Protection From e829624361346fce4f8295fb6a56fbef1b5939b1 Mon Sep 17 00:00:00 2001 From: Steven Lewis Date: Tue, 29 Sep 2020 17:03:19 -0700 Subject: [PATCH 08/20] bumping hero up b/c of what I think is aliasing cuasing weird space, also centering logo on mobile. (#2187) --- src/css/_includes/index.scss | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/css/_includes/index.scss b/src/css/_includes/index.scss index 056afac6645234..4e4466e6ecac83 100644 --- a/src/css/_includes/index.scss +++ b/src/css/_includes/index.scss @@ -72,9 +72,9 @@ a.hover-card-link { background: #f6f4f7; background-image: url("../pages/geo-back.svg"); background-size: cover; - background-position: center center; - padding: 1rem 0 2rem; - margin: 0 0 3rem; + background-position: center; + margin: -3px 0 3rem; + padding-bottom: 2rem; } .index-search { @@ -103,6 +103,7 @@ a.hover-card-link { transition: opacity 0.25s ease-out; flex: 1 0 100%; margin: 0.5rem auto; + text-align: center; img { height: 4rem; } From 14db801ca343a815af6487326ae3ca82b43b1f5d Mon Sep 17 00:00:00 2001 From: Ben Vinegar Date: Tue, 29 Sep 2020 21:42:30 -0700 Subject: [PATCH 09/20] fix(urls): Use relative URLs instead of linking to docs.sentry.io (#2382) * fix(urls): Use relative URLs instead of linking to docs.sentry.io * Revert relative URL change to api docs link * Fix grouping & fingerprinting link * Fix broken url on log4net docs --- src/docs/accounts/quotas/index.mdx | 2 +- src/docs/clients/javascript/usage.mdx | 2 +- src/docs/clients/node/index.mdx | 2 +- src/docs/product/integrations/gcp-cloud-run/index.mdx | 2 +- src/docs/product/sentry-basics/environments/index.mdx | 2 +- .../guides/integrate-frontend/upload-source-maps.mdx | 2 +- src/includes/getting-started-install/dotnet.mdx | 2 +- src/platforms/android/migration.mdx | 2 +- src/platforms/android/timber.mdx | 2 +- src/platforms/dotnet/guides/log4net/index.mdx | 4 ++-- src/platforms/dotnet/index.mdx | 2 +- src/platforms/javascript/common/sourcemaps/index.mdx | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/docs/accounts/quotas/index.mdx b/src/docs/accounts/quotas/index.mdx index 1f684da148ac95..c2f004d5be28dd 100644 --- a/src/docs/accounts/quotas/index.mdx +++ b/src/docs/accounts/quotas/index.mdx @@ -15,7 +15,7 @@ Sentry’s flexibility means you can exercise fine-grained control over which ev Let’s clarify a few terms to start: - Event - an event is one instance of you sending Sentry data. Generally, this data is an error. Every event has a set of characteristics, called its fingerprint. -- Issue - an issue is a grouping of similar events, which all share the same fingerprint. For example, Sentry groups events together when they are triggered by the same part of your code. For more information, see [Grouping & Fingerprinting](https://docs.sentry.io/data-management/event-grouping/). +- Issue - an issue is a grouping of similar events, which all share the same fingerprint. For example, Sentry groups events together when they are triggered by the same part of your code. For more information, see [Grouping & Fingerprinting](/product/sentry-basics/guides/grouping-and-fingerprints/). - Attachment - Attachments are files uploaded in the same request, such as log files. Unless the option to store crash reports is enabled, Sentry will use the files only to create the event, and then drop the files. - Transaction - A transaction represents a single instance of a service being called to support an operation you want to measure or track, like a page load. - Quota - your quota is the monthly number of events - errors, attachments, and transactions - you pay Sentry to track. diff --git a/src/docs/clients/javascript/usage.mdx b/src/docs/clients/javascript/usage.mdx index cfd8310b55baa2..68bf6dce763800 100644 --- a/src/docs/clients/javascript/usage.mdx +++ b/src/docs/clients/javascript/usage.mdx @@ -258,7 +258,7 @@ Raven.isSetup(); Raven and Sentry support [Source Maps](https://www.html5rocks.com/en/tutorials/developertools/sourcemaps/). For more information, please read the [Source Map -docs](https://docs.sentry.io/clients/javascript/sourcemaps/). Also, check +docs](/clients/javascript/sourcemaps/). Also, check out our [Gruntfile](https://github.com/getsentry/raven-js/blob/master/packages/raven-js/Gruntfile.js) for a good example of what we’re doing. diff --git a/src/docs/clients/node/index.mdx b/src/docs/clients/node/index.mdx index 442fe0a25a352a..2ac8933206aa5f 100644 --- a/src/docs/clients/node/index.mdx +++ b/src/docs/clients/node/index.mdx @@ -18,7 +18,7 @@ raven-node is the official Node.js client for Sentry. -If you’re using JavaScript in the browser, you’ll need [raven-js](https://docs.sentry.io/clients/javascript). +If you’re using JavaScript in the browser, you’ll need [raven-js](/clients/javascript). diff --git a/src/docs/product/integrations/gcp-cloud-run/index.mdx b/src/docs/product/integrations/gcp-cloud-run/index.mdx index ae026f18be12ae..5e098470d63ad3 100644 --- a/src/docs/product/integrations/gcp-cloud-run/index.mdx +++ b/src/docs/product/integrations/gcp-cloud-run/index.mdx @@ -9,7 +9,7 @@ Cloud Run helps developers save time in building and deploying their application ![Sentry Choose Platform](sentry-choose-platform.png) -3. Follow instructions to instrument your Cloud Run application. Detailed platform docs [here](http://docs.sentry.io/platforms/). +3. Follow instructions to instrument your Cloud Run application. Detailed platform docs [here](/platforms/). 4. Deploy your Cloud Run application with GCP. That's it! Sentry will now report all issues from your Cloud Run application. diff --git a/src/docs/product/sentry-basics/environments/index.mdx b/src/docs/product/sentry-basics/environments/index.mdx index 2294d10cf5f70a..36f9b5b3ed399e 100644 --- a/src/docs/product/sentry-basics/environments/index.mdx +++ b/src/docs/product/sentry-basics/environments/index.mdx @@ -31,7 +31,7 @@ Also, the environment filter affects all issue-related metrics, such as the coun A release by itself is not associated with an environment but can be deployed to different environments. When you select an environment on the releases page, it shows releases that were deployed to that environment. For example, a release deployed to the `QA` and `Prod` environment will appear in your view when filtering by `QA`, as well as `Prod`. All issue-related metrics within a given release will be affected by the environment filter. A deploy must have an environment. -For more details about configuring releases and deploys, see the [full documentation on Releases](https://docs.sentry.io/workflow/releases/). +For more details about configuring releases and deploys, see the [full documentation on Releases](/workflow/releases/). ## Hidden Environments diff --git a/src/docs/product/sentry-basics/guides/integrate-frontend/upload-source-maps.mdx b/src/docs/product/sentry-basics/guides/integrate-frontend/upload-source-maps.mdx index 7bada74dced58e..d0bf0790baa09a 100644 --- a/src/docs/product/sentry-basics/guides/integrate-frontend/upload-source-maps.mdx +++ b/src/docs/product/sentry-basics/guides/integrate-frontend/upload-source-maps.mdx @@ -16,7 +16,7 @@ In this section, we will: -As part of the **CI/CD workflow** for this app demo, we're using a `Makefile` to handle the `sentry-cli` related tasks through `make` targets. If you're using a different code base, you can still apply the settings and commands described below to your specific setup or run them directly in a command-line shell as part of your build process. For more information, see [Command Line Interface](https://docs.sentry.io/cli/). +As part of the **CI/CD workflow** for this app demo, we're using a `Makefile` to handle the `sentry-cli` related tasks through `make` targets. If you're using a different code base, you can still apply the settings and commands described below to your specific setup or run them directly in a command-line shell as part of your build process. For more information, see [Command Line Interface](/cli/). diff --git a/src/includes/getting-started-install/dotnet.mdx b/src/includes/getting-started-install/dotnet.mdx index 87921cd5a44b79..67a7073d40cbc2 100644 --- a/src/includes/getting-started-install/dotnet.mdx +++ b/src/includes/getting-started-install/dotnet.mdx @@ -10,4 +10,4 @@ dotnet add package Sentry **Using .NET Framework prior to 4.6.1?** -[Our legacy SDK](https://docs.sentry.io/clients/csharp/) supports .NET Framework as early as 3.5. +[Our legacy SDK](/clients/csharp/) supports .NET Framework as early as 3.5. diff --git a/src/platforms/android/migration.mdx b/src/platforms/android/migration.mdx index 8cb35f83f31bc4..76d86b859df6f3 100644 --- a/src/platforms/android/migration.mdx +++ b/src/platforms/android/migration.mdx @@ -56,7 +56,7 @@ Please note that the new SDK will send with each event a release version in a di If you are using the [GitHub](/workflow/integrations/github/) or [GitLab](/workflow/integrations/gitlab/) integrations, you need to do one of the following: -- Use the new format LINK: ([https://docs.sentry.io/platforms/android/#releases](https://docs.sentry.io/platforms/android/#releases)) +- Use the new format LINK: ([https://docs.sentry.io/platforms/android/#releases](/platforms/android/#releases)) - Set the release in your `AndroidManifest.xml` - Change your code as described in the configuration section diff --git a/src/platforms/android/timber.mdx b/src/platforms/android/timber.mdx index 5dbe4c49fbf8e4..ee247fdece028a 100644 --- a/src/platforms/android/timber.mdx +++ b/src/platforms/android/timber.mdx @@ -13,7 +13,7 @@ The source can be found [on GitHub](https://github.com/getsentry/sentry-android/ ### Installation -1. In order to add the Timber integration, you have to do a [manual initialization](https://docs.sentry.io/platforms/android/#manual-initialization) of the Android SDK. +1. In order to add the Timber integration, you have to do a [manual initialization](/platforms/android/#manual-initialization) of the Android SDK. 2. Add the `sentry-android-timber` dependency diff --git a/src/platforms/dotnet/guides/log4net/index.mdx b/src/platforms/dotnet/guides/log4net/index.mdx index 3ca1aa302ef45b..d5015deee22012 100644 --- a/src/platforms/dotnet/guides/log4net/index.mdx +++ b/src/platforms/dotnet/guides/log4net/index.mdx @@ -37,7 +37,7 @@ This can be done, for example, via the `app.config` for console and desktop apps -Only a subset of the options are exposed via the log4net appender configuration. If you wish to access an [SDK option](https://docs.sentry.io/platforms/dotnet/configuration/options/) which is not listed below, you'll need to initialize the SDK via [SentrySdk.Init](https://docs.sentry.io/platforms/dotnet/) instead of doing it via this integration as described below. +Only a subset of the options are exposed via the log4net appender configuration. If you wish to access an [SDK option](/platforms/dotnet/configuration/options/) which is not listed below, you'll need to initialize the SDK via [SentrySdk.Init](https://docs.sentry.io/platforms/dotnet/) instead of doing it via this integration as described below. @@ -50,7 +50,7 @@ In the example above, the `SendIdentity` flag was switched on. The SDK then will Also in the example above, you can find the DSN being set. That will instruct the `SentryAppender` to initialize the SDK. This is only one of the ways to initialize the SDK. If you wish to configure the SDK programatically, you could **leave the DSN out** from the appender configuration section. The SDK needs to be initialized only **once** and since other integrations (like ASP.NET) are also able to initialize the SDK, you only need to pass the DSN to one of these integrations. -One common case to not add the DSN to the XML configuration file (which would initialize it via the log4net integration) is to have full access to the [SDK option](https://docs.sentry.io/error-reporting/configuration/?platform=csharp). +One common case to not add the DSN to the XML configuration file (which would initialize it via the log4net integration) is to have full access to the [SDK option](/platforms/dotnet/guides/log4net/configuration/options/). ### Sample diff --git a/src/platforms/dotnet/index.mdx b/src/platforms/dotnet/index.mdx index 5692043351233a..a70e493f579323 100644 --- a/src/platforms/dotnet/index.mdx +++ b/src/platforms/dotnet/index.mdx @@ -23,7 +23,7 @@ Of those, we run our unit/integration tests against: -[Our legacy SDK](https://docs.sentry.io/clients/csharp/) supports .NET Framework as early as 3.5. +[Our legacy SDK](/clients/csharp/) supports .NET Framework as early as 3.5. diff --git a/src/platforms/javascript/common/sourcemaps/index.mdx b/src/platforms/javascript/common/sourcemaps/index.mdx index fd2d5767de4f58..ff5551c84907a5 100644 --- a/src/platforms/javascript/common/sourcemaps/index.mdx +++ b/src/platforms/javascript/common/sourcemaps/index.mdx @@ -38,7 +38,7 @@ $ npm install --save-dev @sentry/webpack-plugin $ yarn add --dev @sentry/webpack-plugin ``` -Next you need to generate an access token for our API. Within your organization's settings, navigate to Developer Settings, [create a new internal integration](https://docs.sentry.io/product/integrations/integration-platform/#internal-integrations), and provide a name appropriate to your organization. **Important:** Select **Releases -> Admin** for Permissions. +Next you need to generate an access token for our API. Within your organization's settings, navigate to Developer Settings, [create a new internal integration](/product/integrations/integration-platform/#internal-integrations), and provide a name appropriate to your organization. **Important:** Select **Releases -> Admin** for Permissions. From bc87873ede8ce84883d2ce025f52711f679c639c Mon Sep 17 00:00:00 2001 From: "Tien \"Mimi\" Nguyen" Date: Wed, 30 Sep 2020 00:12:15 -0700 Subject: [PATCH 10/20] fixed broken anchor tags (#2393) --- src/platforms/android/index.mdx | 6 +++--- .../common/data-management/event-grouping/index.mdx | 2 +- .../sensitive-data/advanced-datascrubbing.mdx | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/platforms/android/index.mdx b/src/platforms/android/index.mdx index de486c888c1c20..b58e0f45916afd 100644 --- a/src/platforms/android/index.mdx +++ b/src/platforms/android/index.mdx @@ -413,7 +413,7 @@ Most SDKs generally support configuring tags by configuring the scope: Sentry.setTag("tagKey", "tagValue"); ``` -For more information, see [Tagging Events](enriching-events/context/#tags) in Context. +For more information, see [Tagging Events](/platforms/android/enriching-events/tags/). ### Setting the Level @@ -430,7 +430,7 @@ Sentry uses a fingerprint to decide how to group errors into issues. For some very advanced use cases, you can override the Sentry default grouping using the `fingerprint` attribute. In supported SDKs, this attribute can be passed with the event information and should be a list of strings. -For code samples, see [Grouping & Fingerprints](data-management/event-grouping/#use-cases). +For more details, see [Issue Grouping](/platforms/android/data-management/event-grouping/). For more information, see [Aggregate Errors with Custom Fingerprints](https://blog.sentry.io/2018/01/18/setting-up-custom-fingerprints). @@ -775,7 +775,7 @@ Java_io_sentry_demo_NativeDemo_crash(JNIEnv *env, jclass cls) { } ``` -To symbolicate the stack trace from native code, we need to have access to the debug symbols of your application. Please check the full documentation on [uploading files](/workflow/debug-files/#uploading-files) to learn more about the upload of the debug symbols. +To symbolicate the stack trace from native code, we need to have access to the debug symbols of your application. Please check the full documentation on [Uploading Files](/platforms/android/data-management/debug-files/#uploading-files) to learn more about the upload of the debug symbols. Example of uploading all your .so files: diff --git a/src/platforms/common/data-management/event-grouping/index.mdx b/src/platforms/common/data-management/event-grouping/index.mdx index 800bb034707ce9..9dd64d5e472812 100644 --- a/src/platforms/common/data-management/event-grouping/index.mdx +++ b/src/platforms/common/data-management/event-grouping/index.mdx @@ -32,7 +32,7 @@ Depending on the information available, the following data can be used for each This grouping usually works well, but two specific situations can throw it off if not dealt with: -- Minimized JavaScript sourcecode will destroy the grouping in really bad ways. Because of this you should ensure that Sentry can access your [Source Maps](/platforms/javascript/#source-maps). +- Minimized JavaScript sourcecode will destroy the grouping in really bad ways. Because of this you should ensure that Sentry can access your [Source Maps](/platforms/javascript/sourcemaps/). - If you modify your stack trace by introducing a new level through the use of decorators, your stack trace will change and so will the grouping. To handle this, many SDKs support hiding irrelevant stack trace frames. (For example, the Python SDK will skip all stack frames with a local variable called `__traceback_hide__` set to _True_). ### Grouping By Exception diff --git a/src/platforms/common/data-management/sensitive-data/advanced-datascrubbing.mdx b/src/platforms/common/data-management/sensitive-data/advanced-datascrubbing.mdx index 311357efa34983..06096134571876 100644 --- a/src/platforms/common/data-management/sensitive-data/advanced-datascrubbing.mdx +++ b/src/platforms/common/data-management/sensitive-data/advanced-datascrubbing.mdx @@ -157,7 +157,7 @@ Select known parts of the schema using the following: - `$logentry`: Matches the `logentry` attribute of an event. Alias for `logentry` - `$thread`: Matches a single thread instance. Alias for `threads.values.*` - `$breadcrumb`: Matches a single breadcrumb. Alias for `breadcrumbs.values.*` -- `$span`: Matches a [trace span](/performance-monitoring/distributed-tracing/#traces-transactions-and-spans). Alias for `spans.*` +- `$span`: Matches a [trace span](/product/performance/distributed-tracing/#spans). Alias for `spans.*` - `$sdk`: Matches the SDK context. Alias for `sdk` ### Escaping Special Characters From 7c3608507817e14c53f2966c61656d91bcba1c74 Mon Sep 17 00:00:00 2001 From: Maciej Walkowiak Date: Wed, 30 Sep 2020 17:09:43 +0200 Subject: [PATCH 11/20] Update Java SDK docs to 3.0 (#2239) Co-authored-by: Fiona <61481573+PeloWriter@users.noreply.github.com> Co-authored-by: Bruno Garcia Co-authored-by: Manoel Aranda Neto <5731772+marandaneto@users.noreply.github.com> --- .../quotas/manage-event-stream-guide.mdx | 2 +- src/includes/capture-error/java.mdx | 11 + src/includes/capture-message/java.mdx | 5 + .../configuration/before-send/java.mdx | 17 + .../configuration/config-intro/java.mdx | 45 ++ .../configuration/decluttering/java.mdx | 3 + .../configuration/drain-example/java.mdx | 1 + .../configuration/sample-rate/java.mdx | 8 + src/includes/set-environment/java.mdx | 5 + src/includes/set-release/java.mdx | 7 + src/pages/index.tsx | 2 +- .../common/configuration/options.mdx | 16 +- .../common/configuration/releases.mdx | 2 +- .../java/common/configuration/index.mdx | 165 +++++++ .../java/common/configuration/options.mdx | 464 ----------------- src/platforms/java/common/context.mdx | 105 ---- .../common/legacy/configuration/index.mdx | 467 ++++++++++++++++++ .../legacy}/google-app-engine/index.mdx | 8 +- src/platforms/java/common/legacy/index.mdx | 24 + .../{guides => common/legacy}/log4j/index.mdx | 12 +- .../java/common/legacy/log4j2/index.mdx | 140 ++++++ .../java/common/legacy/logback/index.mdx | 187 +++++++ .../legacy}/logging/index.mdx | 12 +- .../java/common/{ => legacy}/migration.mdx | 2 +- .../java/common/legacy/spring/index.mdx | 79 +++ src/platforms/java/common/legacy/usage.mdx | 221 +++++++++ src/platforms/java/common/scope.mdx | 59 +++ src/platforms/java/guides/log4j2/index.mdx | 178 +++++-- src/platforms/java/guides/logback/index.mdx | 194 +++++--- .../java/guides/spring-boot/index.mdx | 261 ++++++++++ src/platforms/java/guides/spring/index.mdx | 105 ++-- src/platforms/java/usage.mdx | 444 +++++++++++------ 32 files changed, 2352 insertions(+), 899 deletions(-) create mode 100644 src/includes/capture-error/java.mdx create mode 100644 src/includes/capture-message/java.mdx create mode 100644 src/includes/configuration/before-send/java.mdx create mode 100644 src/includes/configuration/config-intro/java.mdx create mode 100644 src/includes/configuration/decluttering/java.mdx create mode 100644 src/includes/configuration/drain-example/java.mdx create mode 100644 src/includes/configuration/sample-rate/java.mdx create mode 100644 src/includes/set-environment/java.mdx create mode 100644 src/includes/set-release/java.mdx create mode 100644 src/platforms/java/common/configuration/index.mdx delete mode 100644 src/platforms/java/common/context.mdx create mode 100644 src/platforms/java/common/legacy/configuration/index.mdx rename src/platforms/java/{guides => common/legacy}/google-app-engine/index.mdx (87%) create mode 100644 src/platforms/java/common/legacy/index.mdx rename src/platforms/java/{guides => common/legacy}/log4j/index.mdx (91%) create mode 100644 src/platforms/java/common/legacy/log4j2/index.mdx create mode 100644 src/platforms/java/common/legacy/logback/index.mdx rename src/platforms/java/{guides => common/legacy}/logging/index.mdx (80%) rename src/platforms/java/common/{ => legacy}/migration.mdx (99%) create mode 100644 src/platforms/java/common/legacy/spring/index.mdx create mode 100644 src/platforms/java/common/legacy/usage.mdx create mode 100644 src/platforms/java/common/scope.mdx create mode 100644 src/platforms/java/guides/spring-boot/index.mdx diff --git a/src/docs/accounts/quotas/manage-event-stream-guide.mdx b/src/docs/accounts/quotas/manage-event-stream-guide.mdx index ecbd83f951690f..cc02249f014368 100644 --- a/src/docs/accounts/quotas/manage-event-stream-guide.mdx +++ b/src/docs/accounts/quotas/manage-event-stream-guide.mdx @@ -45,7 +45,7 @@ Check out additional configuration options with the [TryCatch](/platforms/javasc ### Other SDKs -**Java** - Sentry SDK provides integrations with common Java loggers through implemented _Handlers_ and _Appenders_. The configuration allows you to set a logging threshold determining the level under which all errors will be filtered. For more information see Java Integrations [java.util.logging](/platforms/java/guides/logging/), [Log4j 1.x](/platforms/java/guides/log4j/), [Log4j 2.x](/platforms/java/guides/log4j2/), and [Logback](/platforms/java/guides/logback/). +**Java** - Sentry SDK provides integrations with common Java loggers through implemented _Handlers_ and _Appenders_. The configuration allows you to set a logging threshold determining the level under which all errors will be filtered. For more information see Java Integrations [java.util.logging](/platforms/java/legacy/logging/), [Log4j 1.x](/platforms/java/legacy/log4j/), [Log4j 2.x](/platforms/java/guides/log4j2/), and [Logback](/platforms/java/guides/logback/). **PHP** - The `error_types` configuration option allows you to set the error types you want Sentry to monitor. For more information see [PHP: Common Options](/platforms/php/configuration/options/#common-options). diff --git a/src/includes/capture-error/java.mdx b/src/includes/capture-error/java.mdx new file mode 100644 index 00000000000000..6420827e642a3a --- /dev/null +++ b/src/includes/capture-error/java.mdx @@ -0,0 +1,11 @@ +In Java you can capture any exception object that you caught: + +```java +import io.sentry.Sentry; + +try { + aMethodThatMightFail(); +} catch(Exception e) { + Sentry.captureException(e); +} +``` diff --git a/src/includes/capture-message/java.mdx b/src/includes/capture-message/java.mdx new file mode 100644 index 00000000000000..e896fd5b9429f9 --- /dev/null +++ b/src/includes/capture-message/java.mdx @@ -0,0 +1,5 @@ +```java +import io.sentry.Sentry; + +Sentry.captureMessage("Something went wrong"); +``` diff --git a/src/includes/configuration/before-send/java.mdx b/src/includes/configuration/before-send/java.mdx new file mode 100644 index 00000000000000..8418050ceaa679 --- /dev/null +++ b/src/includes/configuration/before-send/java.mdx @@ -0,0 +1,17 @@ +A `BiFunction` can be used to mutate, discard (return null), or return a completely new event. + +```java +import io.sentry.Sentry; + +Sentry.init( + options -> { + options.setBeforeSend( + (event, hint) -> { + // Modify the event here: + event.setServerName(null); // Don't send server names. + return event; + }); + }); +``` + +When using [Spring Boot integration](/platforms/java/guides/spring-boot/), `beforeSend` can be registered simply by creating a Spring `bean` implementing `BeforeSendCallback`. See [Spring Boot integration](/platforms/java/guides/spring-boot/#registering-custom-before-send-callback) for more details. diff --git a/src/includes/configuration/config-intro/java.mdx b/src/includes/configuration/config-intro/java.mdx new file mode 100644 index 00000000000000..de753215640f49 --- /dev/null +++ b/src/includes/configuration/config-intro/java.mdx @@ -0,0 +1,45 @@ +Options can be set by passing a callback to the `init()` method which will +pass the option object along for modifications: + +```java {tabTitle:Java} +import io.sentry.Sentry; + +public class MyClass { + public static void main(String... args) { + Sentry.init( + options -> { + // your Sentry project/dashboard + options.setDsn("___PUBLIC_DSN___"); + options.setRelease("io.sentry.samples.console@3.0.0+1"); + options.setBeforeSend( + (event, hint) -> { + // Drop an event altogether: + if (event.getTag("SomeTag") != null) { + return null; + } + return event; + }); + }); + } +} +``` + +```kotlin {tabTitle:Kotlin} +import io.sentry.SentryOptions.BeforeSendCallback + +fun main() { + Sentry.init { + // your Sentry project/dashboard + it.dsn = "___PUBLIC_DSN___" + it.release = "io.sentry.samples.console@3.0.0+1" + it.beforeSend = BeforeSendCallback { event: SentryEvent, hint: Any? -> + // Drop an event altogether: + if (event.getTag("SomeTag") != null) { + null + } else { + event + } + } + } +} +``` diff --git a/src/includes/configuration/decluttering/java.mdx b/src/includes/configuration/decluttering/java.mdx new file mode 100644 index 00000000000000..2ddd4be51949e2 --- /dev/null +++ b/src/includes/configuration/decluttering/java.mdx @@ -0,0 +1,3 @@ +### Decluttering Sentry + +When used together with one of the logging framework integrations, the Java SDK captures all error logs as events. If you see a particular kind of error very often that has a `logger` tag, you can ignore that particular logger entirely. For more information see our Logback or Log4j 2.x integration. diff --git a/src/includes/configuration/drain-example/java.mdx b/src/includes/configuration/drain-example/java.mdx new file mode 100644 index 00000000000000..623b29c219b476 --- /dev/null +++ b/src/includes/configuration/drain-example/java.mdx @@ -0,0 +1 @@ +The Java SDK automatically shuts down on JVM exit and waits `shutdownTimeout` milliseconds before that happens. diff --git a/src/includes/configuration/sample-rate/java.mdx b/src/includes/configuration/sample-rate/java.mdx new file mode 100644 index 00000000000000..8b730abb1d0fdb --- /dev/null +++ b/src/includes/configuration/sample-rate/java.mdx @@ -0,0 +1,8 @@ +```java +import io.sentry.Sentry; + +Sentry.init( + options -> { + options.setSampleRate(0.25); + }); +``` diff --git a/src/includes/set-environment/java.mdx b/src/includes/set-environment/java.mdx new file mode 100644 index 00000000000000..b747b34e9178fa --- /dev/null +++ b/src/includes/set-environment/java.mdx @@ -0,0 +1,5 @@ +```java +Sentry.init(options -> { + options.setEnvironment("production"); +}); +``` diff --git a/src/includes/set-release/java.mdx b/src/includes/set-release/java.mdx new file mode 100644 index 00000000000000..91dbd8e0522fb4 --- /dev/null +++ b/src/includes/set-release/java.mdx @@ -0,0 +1,7 @@ +```java +Sentry.init(options -> { + options.setRelease("my-project-name@2.3.12"); +}); +``` + +When using Sentry in Spring Boot application, thanks to Spring Boot Starter the release field is set automatically. Read more in [Spring Boot Starter](/platforms/java/guides/spring-boot/#using-git-commit-id-as-the-release) guide. diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 9f6f151bc0415e..f73364f13f9223 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -25,7 +25,7 @@ const HIGHLIGHTED_PLATFORMS = [ "php.laravel", "android", "apple", - "java.spring", + "java.spring-boot", "ruby.rails", ]; diff --git a/src/platforms/common/configuration/options.mdx b/src/platforms/common/configuration/options.mdx index 88edd681ab4b99..e53654d59d7fe8 100644 --- a/src/platforms/common/configuration/options.mdx +++ b/src/platforms/common/configuration/options.mdx @@ -73,7 +73,7 @@ Grouping in Sentry is different for events with stack traces and without. As a r - + If this flag is enabled, certain personally identifiable information (PII) is added by active integrations. By default, no such data is sent. @@ -81,7 +81,7 @@ If possible, we recommended turning on this feature to send all such data by def - + This option can be used to supply a "server name." When provided, the name of the server is sent along and persisted in the event. For many integrations the server name actually corresponds to the device hostname, even in situations where the machine is not actually a server. Most SDKs will attempt to auto-discover this value. @@ -101,13 +101,13 @@ will be sent. This is a "contains" match to the entire file URL. As a result, if - + A list of string prefixes of module names that belong to the app. This option takes precedence over `in-app-exclude`. - + A list of string prefixes of module names that do not belong to the app, but rather to third-party packages. Modules considered not part of the app will be hidden from stack traces by default. @@ -177,19 +177,19 @@ The callback typically gets a second argument (called a "hint") which contains t - + ## Transport Options Transports are used to send events to Sentry. Transports can be customized to some degree to better support highly specific deployments. - + Switches out the transport used to send events. How this works depends on the SDK. It can, for instance, be used to capture events for unit-testing or to send it through some more complex setup that requires proxy authentication. - + When set, a proxy can be configured that should be used for outbound requests. This is also used for HTTPS requests unless a separate `https-proxy` is configured. However, not all SDKs support a separate HTTPS proxy. SDKs will attempt to default to the system-wide configured proxy, if possible. For instance, on Unix systems, the `http_proxy` environment variable will be picked up. @@ -201,7 +201,7 @@ Configures a separate proxy for outgoing HTTPS requests. This value might not be - + Controls how many seconds to wait before shutting down. Sentry SDKs send events from a background queue. This queue is given a certain amount to drain pending events. The default is SDK specific but typically around two seconds. Setting this value too low may cause problems for sending events from command line applications. Setting the value too high will cause the application to block for a long time for users experiencing network connectivity problems. diff --git a/src/platforms/common/configuration/releases.mdx b/src/platforms/common/configuration/releases.mdx index adb02e67b34011..80988babbecdcf 100644 --- a/src/platforms/common/configuration/releases.mdx +++ b/src/platforms/common/configuration/releases.mdx @@ -13,7 +13,7 @@ A release is a version of your code that is deployed to an environment. When you - Resolve issues by including the issue number in your commit message - Receive email notifications when your code gets deployed - + Additionally, releases are used for applying [source maps](/platforms/javascript/sourcemaps/) to minified JavaScript to view original, untransformed source code. diff --git a/src/platforms/java/common/configuration/index.mdx b/src/platforms/java/common/configuration/index.mdx new file mode 100644 index 00000000000000..ce6c9f59de767c --- /dev/null +++ b/src/platforms/java/common/configuration/index.mdx @@ -0,0 +1,165 @@ +--- +title: Configuration +sidebar_order: 10 +description: "Learn more about how to configure the SDK. These options are set when the SDK is first initialized, passed to the `init()` as an object." +--- + +## Setting the DSN (Data Source Name) {#setting-the-dsn} + +The DSN is the first and most important thing to configure because it tells the SDK where to send events. You can find your project’s DSN in the “Client Keys” section of your “Project Settings” in Sentry. It can be configured in multiple ways. Explanations of the [configuration methods are detailed below](#configuration-methods). + +In a properties file on your filesystem or classpath (defaults to `sentry.properties`): + +```text {tabTitle:Properties File} {filename:sentry.properties} +dsn=___PUBLIC_DSN___ +``` + +Via the Java System Properties _(not available on Android)_: + +```bash {tabTitle:Java System Properties} +java -Dsentry.dsn=___PUBLIC_DSN___ -jar app.jar +``` + +Via a System Environment Variable _(not available on Android)_: + +```bash {tabTitle:System Environment Variable} +SENTRY_DSN=___PUBLIC_DSN___ java -jar app.jar +``` + +In code: + +```java +import io.sentry.Sentry; + +Sentry.init(options -> { + options.setDsn("___PUBLIC_DSN___"); +}); +``` + +## Configuration methods {#configuration-methods} + +There are multiple ways to configure the Java SDK, but all of them take the same options. See below for how to use each configuration method and how the option names might differ between them. + +To enable loading configuration from the properties file, system properties or environment variables, `enableExternalConfiguration` has to be set to `true` on `SentryOptions`: + +```java +import io.sentry.Sentry; + +Sentry.init(options -> { + options.setEnableExternalConfiguration(true); +}); +``` + +### Configuration via properties file + +The Java SDK can be configured via a [.properties file](https://en.wikipedia.org/wiki/.properties) that is located on the filesystem or in your application’s classpath. By default the SDK will look for a `sentry.properties` file in the application’s current working directory or in the root of your classpath. In most server side applications the default directory to add resources to your classpath is `src/main/resources/`, and on Android the default is `app/src/main/resources/`. You can override the location of the properties file by using either the `sentry.properties.file` Java System Property or the `SENTRY_PROPERTIES_FILE` System Environment Variable. + +Because this file is often bundled with your application, the values cannot be changed easily once your application has been packaged. For this reason, the properties file is useful for setting defaults or options that you don’t expect to change often. The properties file is the last place checked for each option value, so runtime configuration (described below) will override it if available. + +Option names in the property file exactly match the examples given below. For example, to configure the environment, in your properties file: + +```properties +environment=production +``` + +### Configuration via the runtime environment + +This is the most flexible method for configuring the Sentry client because it can be easily changed based on the environment you run your application in. _Neither Java System Properties or System Environment Variables are available for Android applications. Please configure Sentry for Android via code or the properties file._ + +Two methods are available for runtime configuration, checked in this order: Java System Properties and System Environment Variables. + +Java System Property option names are exactly like the examples given below except that they are prefixed with `sentry.`. For example, to enable sampling: + +```bash +java -Dsentry.environment=production -jar app.jar +``` + +System Environment Variable option names require that you replace the `.` with `_`, capitalize them, and add a `SENTRY_` prefix. For example, to enable sampling: + +```bash +SENTRY_ENVIRONMENT=production java -jar app.jar +``` + +### Configuration via code + +The DSN itself can also be configured directly in code: + +```java +import io.sentry.Sentry; + +Sentry.init(options -> { + options.setDsn("___PUBLIC_DSN___"); +}); +``` + +By passing a hardcoded DSN you are no longer able to override the DSN at runtime via Java System Properties or System Environment Variables. + +## Options + +The following options can all be configured as described above: via a `sentry.properties` file, via Java System Properties, via System Environment variables, or via the DSN. + +### Release + +To set the application version that will be sent with each event, use the `release` option: + +``` +release=1.0.0 +``` + +#### Distribution + +To set the application distribution that will be sent with each event, use the `dist` option: + +``` +release=1.0.0 +dist=x86 +``` + +The distribution is only useful (and used) if the `release` is also set. + +### Environment + +To set the application environment that will be sent with each event, use the `environment` option: + +``` +environment=staging +``` + +### Server Name + +To set the server name that will be sent with each event, use the `servername` option: + +``` +servername=host1 +``` + +## Using a Proxy + +If your application needs to send outbound requests through an HTTP proxy, you can configure the proxy information via JVM networking properties or as a Sentry option. + +For example, using JVM networking properties (affects the entire JVM process), + +```bash +java \ + # if you are using the HTTP protocol \ + -Dhttp.proxyHost=proxy.example.com \ + -Dhttp.proxyPort=8080 \ + \ + # if you are using the HTTPS protocol \ + -Dhttps.proxyHost=proxy.example.com \ + -Dhttps.proxyPort=8080 \ + \ + # relevant to both HTTP and HTTPS + -Dhttp.nonProxyHosts=”localhost|host.example.com” \ + \ + MyApp +``` + +See [Java Networking and Proxies](http://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html) for more information about the proxy properties. + +Alternatively, using Sentry options (only affects the Sentry HTTP client, useful inside shared application containers), + +``` +http.proxy.host=proxy.example.com +http.proxy.port=8080 +``` diff --git a/src/platforms/java/common/configuration/options.mdx b/src/platforms/java/common/configuration/options.mdx index 6ea9bdb6fdc799..e69de29bb2d1d6 100644 --- a/src/platforms/java/common/configuration/options.mdx +++ b/src/platforms/java/common/configuration/options.mdx @@ -1,464 +0,0 @@ ---- -title: Basic Options -sidebar_order: 0 -description: "Learn more about how to configure the SDK. These options are set when the SDK is first initialized, passed to the `init()` as an object." -redirect_from: - - /clients/java/config/ ---- - -## Setting the DSN (Data Source Name) {#setting-the-dsn} - -The DSN is the first and most important thing to configure because it tells the SDK where to send events. You can find your project’s DSN in the “Client Keys” section of your “Project Settings” in Sentry. It can be configured in multiple ways. Explanations of the [configuration methods are detailed below](#configuration-methods). - -In a properties file on your filesystem or classpath (defaults to `sentry.properties`): - -```text {tabTitle:Properties File} {filename:sentry.properties} -dsn=___PUBLIC_DSN___ -``` - -Via the Java System Properties _(not available on Android)_: - -```bash {tabTitle:Java System Properties} -java -Dsentry.dsn=___PUBLIC_DSN___ -jar app.jar -``` - -Via a System Environment Variable _(not available on Android)_: - -```bash {tabTitle:System Environment Variable} -SENTRY_DSN=___PUBLIC_DSN___ java -jar app.jar -``` - -In code: - -```java -import io.sentry.Sentry; - -Sentry.init("___PUBLIC_DSN___"); -``` - -## Configuration methods {#configuration-methods} - -There are multiple ways to configure the Java SDK, but all of them take the same options. See below for how to use each configuration method and how the option names might differ between them. - -### Configuration via properties file - -The Java SDK can be configured via a [.properties file](https://en.wikipedia.org/wiki/.properties) that is located on the filesystem or in your application’s classpath. By default the SDK will look for a `sentry.properties` file in the application’s current working directory or in the root of your classpath. In most server side applications the default directory to add resources to your classpath is `src/main/resources/`, and on Android the default is `app/src/main/resources/`. You can override the location of the properties file by using either the `sentry.properties.file` Java System Property or the `SENTRY_PROPERTIES_FILE` System Environment Variable. - -Because this file is often bundled with your application, the values cannot be changed easily once your application has been packaged. For this reason, the properties file is useful for setting defaults or options that you don’t expect to change often. The properties file is the last place checked for each option value, so runtime configuration (described below) will override it if available. - -Option names in the property file exactly match the examples given below. For example, to enable sampling, in your properties file: - -```properties -sample.rate=0.75 -``` - -### Configuration via the runtime environment - -This is the most flexible method for configuring the Sentry client because it can be easily changed based on the environment you run your application in. _Neither Java System Properties or System Environment Variables are available for Android applications. Please configure Sentry for Android via code or the properties file._ - -Two methods are available for runtime configuration, checked in this order: Java System Properties and System Environment Variables. - -Java System Property option names are exactly like the examples given below except that they are prefixed with `sentry.`. For example, to enable sampling: - -```bash -java -Dsentry.sample.rate=0.75 -jar app.jar -``` - -System Environment Variable option names require that you replace the `.` with `_`, capitalize them, and add a `SENTRY_` prefix. For example, to enable sampling: - -```bash -SENTRY_SAMPLE_RATE=0.75 java -jar app.jar -``` - -### Configuration via code - -The DSN itself can also be configured directly in code: - -```java -import io.sentry.Sentry; - -Sentry.init("___PUBLIC_DSN___"); -``` - -Sentry **will not** be able to do anything with events until this line is run, so this method of configuration is not recommended if you might have errors occur during startup. In addition, by passing a hardcoded DSN you are no longer able to override the DSN at runtime via Java System Properties or System Environment Variables. - -### Configuration via the DSN - -The SDK can also be configured by setting querystring parameters on the DSN itself. This is a bit recursive because your DSN itself is an option that you must set somewhere (and not in the DSN!). - -Option names in the DSN exactly match the examples given below. For example, to enable sampling if you are setting your DSN via the environment: - -```bash -SENTRY_DSN={DSN}/1?sample.rate=0.75 java -jar app.jar -``` - -You can, of course, pass this DSN in using the other methods described above. - -## Options - -The following options can all be configured as described above: via a `sentry.properties` file, via Java System Properties, via System Environment variables, or via the DSN. - -### Release - -To set the application version that will be sent with each event, use the `release` option: - -``` -release=1.0.0 -``` - -#### Distribution - -To set the application distribution that will be sent with each event, use the `dist` option: - -``` -release=1.0.0 -dist=x86 -``` - -The distribution is only useful (and used) if the `release` is also set. - -### Environment - -To set the application environment that will be sent with each event, use the `environment` option: - -``` -environment=staging -``` - -### Server Name - -To set the server name that will be sent with each event, use the `servername` option: - -``` -servername=host1 -``` - -### Tags - -To set tags that will be sent with each event, use the `tags` option with comma separated pairs of keys and values that are joined by a colon: - -``` -tags=tag1:value1,tag2:value2 -``` - -### MDC Tags - -To set tag names that are extracted from the SLF4J MDC system, use the `mdctags` option with comma separated key names. This option is only useful when you're using one of the logging integrations. - -``` -mdctags=foo,bar -``` - -```java -import org.slf4j.MDC; - -MDC.put("foo", "value1"); -MDC.put("bar", "value2"); - -// This sends an event where the 'foo' and 'bar' MDC values are set as additional tags -logger.error("This is a test"); -``` - -### Extra Data - -To set extra data that will be sent with each event (but not as tags), use the `extra` option with comma separated pairs of keys and values that are joined by a colon: - -``` -extra=key1:value1,key2:value2 -``` - -### “In Application” Stack Frames - -Sentry differentiates stack frames that are directly related to your application (“in application”) from stack frames that come from other packages such as the standard library, frameworks, or other dependencies. The difference is visible in the Sentry web interface where only the “in application” frames are displayed by default. - -You can configure which package prefixes your application uses with the `stacktrace.app.packages` option, which takes a comma separated list. - -``` -stacktrace.app.packages=com.mycompany,com.other.name -``` - -If you don’t want to use this feature but want to disable the warning, simply set it to an empty string: - -``` -stacktrace.app.packages= -``` - -#### Same Frame as Enclosing Exception - -Sentry can use the “in application” system to hide frames in chained exceptions. Usually when a StackTrace is printed, the result looks like this: - -``` -HighLevelException: MidLevelException: LowLevelException - at Main.a(Main.java:13) - at Main.main(Main.java:4) -Caused by: MidLevelException: LowLevelException - at Main.c(Main.java:23) - at Main.b(Main.java:17) - at Main.a(Main.java:11) - ... 1 more -Caused by: LowLevelException - at Main.e(Main.java:30) - at Main.d(Main.java:27) - at Main.c(Main.java:21) - ... 3 more -``` - -Some frames are replaced by the `... N more` line as they are the same frames as in the enclosing exception. - -A similar behavior is enabled by default in Sentry. To disable it, use the `stacktrace.hidecommon` option. - -``` -stacktrace.hidecommon=false -``` - -### Event Sampling - -Sentry can be configured to sample events with the `sample.rate` option: - -``` -sample.rate=0.75 -``` - -This option takes a number from 0.0 to 1.0, representing the percent of events to allow through to server (from 0% to 100%). By default all events will be sent to the Sentry server. - -### Uncaught Exception Handler - -By default, an `UncaughtExceptionHandler` is configured that will attempt to send exceptions to Sentry. To disable it, use the `uncaught.handler.enabled` option. Exceptions are sent asynchronously by default, and there is **no guarantee** they will be sent before the JVM exits. This option is best used in conjunction with the disk buffering system described below. - -``` -uncaught.handler.enabled=false -``` - -### Buffering Events to Disk - -Sentry can be configured to write events to a specified directory on disk anytime communication with the Sentry server fails with the `buffer.dir` option. If the directory doesn’t exist, Sentry will attempt to create it on startup and may therefore need write permission on the parent directory. Sentry always requires write permission on the buffer directory itself. This is enabled by default if the `AndroidSentryClientFactory` is used. - -``` -buffer.dir=sentry-events -``` - -The maximum number of events that will be stored on disk defaults to 10, but can also be configured with the option `buffer.size`: - -``` -buffer.size=100 -``` - -If a buffer directory is provided, a background thread will periodically attempt to re-send the events that are found on disk. By default it will attempt to send events every 60 seconds. You can change this with the `buffer.flushtime` option (in milliseconds): - -``` -buffer.flushtime=10000 -``` - - - -The Java SDK currently uses the native Java serialization system to write out events to the filesystem when buffering is enabled. Due to weaknesses in the Java serialization system it is possible for users that have write access to the `buffer.dir` directory to cause the Java SDK to deserialize arbitrary Java classes. In extreme cases this might lead to the ability to execute code. - - - -#### Graceful Shutdown of Buffering (Advanced) - -In order to shutdown the buffer flushing thread gracefully, a `ShutdownHook` is created. By default, the buffer flushing thread is given 1 second to shutdown gracefully, but this can be adjusted via `buffer.shutdowntimeout` (represented in milliseconds): - -``` -buffer.shutdowntimeout=5000 -``` - -The special value `-1` can be used to disable the timeout and wait indefinitely for the executor to terminate. - -The `ShutdownHook` could lead to memory leaks in an environment where the life cycle of Sentry doesn’t match the life cycle of the JVM. - -An example would be in a JEE environment where the application using Sentry could be deployed and undeployed regularly. - -To avoid this behavior, it is possible to disable the graceful shutdown by setting the `buffer.gracefulshutdown` option: - -``` -buffer.gracefulshutdown=false -``` - -### Async Connection - -In order to avoid performance issues due to a large amount of logs being generated or a slow connection to the Sentry server, an asynchronous connection is set up, using a low priority thread pool to submit events to Sentry. - -To disable the async mode, add `async=false` to your options: - -``` -async=false -``` - -#### Graceful Shutdown of Async (Advanced) - -In order to shutdown the asynchronous connection gracefully, a `ShutdownHook` is created. By default, the asynchronous connection is given 1 second to shutdown gracefully, but this can be adjusted via `async.shutdowntimeout` (represented in milliseconds): - -``` -async.shutdowntimeout=5000 -``` - -The special value `-1` can be used to disable the timeout and wait indefinitely for the executor to terminate. - -The `ShutdownHook` could lead to memory leaks in an environment where the life cycle of Sentry doesn’t match the life cycle of the JVM. - -An example would be in a JEE environment where the application using Sentry could be deployed and undeployed regularly. - -To avoid this behavior, it is possible to disable the graceful shutdown. This might lead to some log entries being lost if the log application doesn’t shut down the `SentryClient` instance nicely. - -The option to do so is `async.gracefulshutdown`: - -``` -async.gracefulshutdown=false -``` - -#### Async Queue Size (Advanced) - -The default queue used to store unprocessed events is limited to 50 items. Additional items added once the queue is full are dropped and never sent to the Sentry server. Depending on the environment (if the memory is sparse) it is important to be able to control the size of that queue to avoid memory issues. - -It is possible to set a maximum with the option `async.queuesize`: - -``` -async.queuesize=100 -``` - -This means that if the connection to the Sentry server is down, only the 100 most recent events will be stored and processed as soon as the server is back up. - -The special value `-1` can be used to enable an unlimited queue. Beware that network connectivity or Sentry server issues could mean your process will run out of memory. - -#### Async Threads Count (Advanced) - -By default the thread pool used by the async connection contains one thread per processor available to the JVM. - -It’s possible to manually set the number of threads (for example if you want only one thread) with the option `async.threads`: - -``` -async.threads=1 -``` - -#### Async Threads Priority (Advanced) - -In most cases sending logs to Sentry isn’t as important as an application running smoothly, so the threads have a [minimal priority](https://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#MIN_PRIORITY). - -It is possible to customise this value to increase the priority of those threads with the option `async.priority`: - -``` -async.priority=10 -``` - -### Compression - -By default the content sent to Sentry is compressed before being sent. However, compressing and encoding the data adds a small CPU and memory hit which might not be useful if the connection to Sentry is fast and reliable. - -Depending on the limitations of the project (e.g. a mobile application with a limited connection, Sentry hosted on an external network), it can be useful to compress the data beforehand or not. - -It’s possible to manually enable/disable the compression with the option `compression` - -``` -compression=false -``` - -### Max Message Size - -By default only the first 1000 characters of a message will be sent to the server. This can be changed with the `maxmessagelength` option. - -``` -maxmessagelength=1500 -``` - -### Timeout (Advanced) - -A timeout is set to avoid blocking Sentry threads because establishing a connection is taking too long. - -It’s possible to manually set the timeout length with `timeout` (in milliseconds): - -``` -timeout=10000 -``` - -### Using a Proxy - -If your application needs to send outbound requests through an HTTP proxy, you can configure the proxy information via JVM networking properties or as a Sentry option. - -For example, using JVM networking properties (affects the entire JVM process), - -```bash -java \ - # if you are using the HTTP protocol \ - -Dhttp.proxyHost=proxy.example.com \ - -Dhttp.proxyPort=8080 \ - \ - # if you are using the HTTPS protocol \ - -Dhttps.proxyHost=proxy.example.com \ - -Dhttps.proxyPort=8080 \ - \ - # relevant to both HTTP and HTTPS - -Dhttp.nonProxyHosts=”localhost|host.example.com” \ - \ - MyApp -``` - -See [Java Networking and Proxies](https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html) for more information about the proxy properties. - -Alternatively, using Sentry options (only affects the Sentry HTTP client, useful inside shared application containers), - -``` -http.proxy.host=proxy.example.com -http.proxy.port=8080 -``` - -## Custom functionality - -At times, you may require custom functionality that is not included in the Java SDK already. The most common way to do this is to create your own `SentryClientFactory` instance as seen in the example below. - -### Implementation - -```java -public class MySentryClientFactory extends DefaultSentryClientFactory { - @Override - public SentryClient createSentryClient(Dsn dsn) { - SentryClient sentryClient = new SentryClient(createConnection(dsn), getContextManager(dsn)); - - /* - Create and use the ForwardedAddressResolver, which will use the - X-FORWARDED-FOR header for the remote address if it exists. - */ - ForwardedAddressResolver forwardedAddressResolver = new ForwardedAddressResolver(); - sentryClient.addBuilderHelper(new HttpEventBuilderHelper(forwardedAddressResolver)); - - sentryClient.addBuilderHelper(new ContextBuilderHelper(sentryClient)); - return configureSentryClient(sentryClient, dsn); - } -} -``` - -### Usage - -To use your custom `SentryClientFactory` implementation, use the `factory` option: - -``` -factory=my.company.MySentryClientFactory -``` - -Your factory class will need to be available on your classpath with a zero argument constructor or an error will be thrown. - -## Linter configuration - -Sometimes linters can warn about types used by the SDK that are not available in your app. This can happen, for example, when using the Android integration due to the base SDK having JNDI lookup that takes no effect in Android. - -To get rid of the warning, configure your `lint.xml` as follows: - -```xml - - - - - -``` - -And in your Gradle plugin: - -```groovy -android { - lintOptions { - lintConfig file("path/to/lint.xml") - } -} -``` - -Where `path/to/lint.xml` is the path to the linting configuration file mentioned above. diff --git a/src/platforms/java/common/context.mdx b/src/platforms/java/common/context.mdx deleted file mode 100644 index 6609192d5e0e67..00000000000000 --- a/src/platforms/java/common/context.mdx +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: Context & Breadcrumbs -sidebar_order: 3 -redirect_from: - - /clients/java/context/ ---- - -The Java SDK implements the idea of a “context” to support attaching additional information to events, such as breadcrumbs. A context may refer to a single request to a web framework, to the entire lifetime of an Android application, or something else that better suits your application’s needs. - -There is no single definition of context that applies to every application, for this reason a specific implementation must be chosen depending on what your application does and how it is structured. By default Sentry uses a `ThreadLocalContextManager` that maintains a single `Context` instance per thread. This is useful for frameworks that use one thread per user request such as those based on synchronous servlet APIs. Sentry also installs a `ServletRequestListener` that will clear the thread’s context after each servlet request finishes. - -Sentry defaults to the `SingletonContextManager` on Android, which maintains a single context instance for all threads for the lifetime of the application. - -To override the `ContextManager` you will need to override the `getContextManager` method in the `DefaultSentryClientFactory`. A simpler API will likely be provided in the future. - -## Usage - -Breadcrumbs can be used to describe actions that occurred in your application leading up to an event being sent. For example, whether external API requests were made, or whether a user clicked on something in an Android application. By default the last 100 breadcrumbs per context will be stored and sent with future events. - -The user can be set per context so that you know who was affected by each event. - -Once a `SentryClient` instance has been initialized you can begin setting state in the current context. - -```java -import io.sentry.Sentry; -import io.sentry.context.Context; -import io.sentry.event.BreadcrumbBuilder; -import io.sentry.event.UserBuilder; - -public class MyClass { - - /** - * Examples using the (recommended) static API. - */ - public void staticAPIExample() { - // Manually initialize the static client, you may also pass in a DSN and/or - // SentryClientFactory to use. Note that the client will attempt to automatically - // initialize on the first use of the static API, so this isn't strictly necessary. - Sentry.init(); - - // Note that all fields set on the context are optional. Context data is copied onto - // all future events in the current context (until the context is cleared). - - // Set the current user in the context. - Sentry.getContext().setUser( - new UserBuilder().setUsername("user1").build() - ); - - // Record a breadcrumb in the context. - Sentry.getContext().recordBreadcrumb( - new BreadcrumbBuilder().setMessage("User did something specific again!").build() - ); - - // Add extra data to future events in this context. - Sentry.getContext().addExtra("extra", "thing"); - - // Add an additional tag to future events in this context. - Sentry.getContext().addTag("tagName", "tagValue"); - - // Send an event with the context data attached. - Sentry.capture("New event message"); - - // Clear the context, useful if you need to add hooks in a framework - // to empty context between requests. - Sentry.clearContext(); - } - - /** - * Examples that use the SentryClient instance directly. - */ - public void instanceAPIExample() { - // Create a SentryClient instance that you manage manually. - SentryClient sentryClient = SentryClientFactory.sentryClient(); - - // Get the current context instance. - Context context = sentryClient.getContext(); - - // Note that all fields set on the context are optional. Context data is copied onto - // all future events in the current context (until the context is cleared). - - // Set the current user in the context. - context.setUser( - new UserBuilder().setUsername("user1").build() - ); - - // Record a breadcrumb in the context. - context.recordBreadcrumb( - new BreadcrumbBuilder().setMessage("User did something specific!").build() - ); - - // Add extra data to future events in this context. - context.addExtra("extra", "thing"); - - // Add an additional tag to future events in this context. - context.addTag("tagName", "tagValue"); - - // Send an event with the context data attached. - sentryClient.sendMessage("New event message"); - - // Clear the context, useful if you need to add hooks in a framework - // to empty context between requests. - context.clear(); - } -} -``` diff --git a/src/platforms/java/common/legacy/configuration/index.mdx b/src/platforms/java/common/legacy/configuration/index.mdx new file mode 100644 index 00000000000000..ea7cbf20a675de --- /dev/null +++ b/src/platforms/java/common/legacy/configuration/index.mdx @@ -0,0 +1,467 @@ +--- +title: Configuration +sidebar_order: 10 +description: "Learn more about how to configure the SDK. These options are set when the SDK is first initialized, passed to the `init()` as an object." +--- + + + +A new Java SDK has superseded this deprecated version. Sentry preserves this documentation for customers using the old client. We recommend using the [updated Java SDK](/platforms/java/) for new projects. + + +## Setting the DSN (Data Source Name) {#setting-the-dsn} + +The DSN is the first and most important thing to configure because it tells the SDK where to send events. You can find your project’s DSN in the “Client Keys” section of your “Project Settings” in Sentry. It can be configured in multiple ways. Explanations of the [configuration methods are detailed below](#configuration-methods). + +In a properties file on your filesystem or classpath (defaults to `sentry.properties`): + +```text {tabTitle:Properties File} {filename:sentry.properties} +dsn=___PUBLIC_DSN___ +``` + +Via the Java System Properties _(not available on Android)_: + +```bash {tabTitle:Java System Properties} +java -Dsentry.dsn=___PUBLIC_DSN___ -jar app.jar +``` + +Via a System Environment Variable _(not available on Android)_: + +```bash {tabTitle:System Environment Variable} +SENTRY_DSN=___PUBLIC_DSN___ java -jar app.jar +``` + +In code: + +```java +import io.sentry.Sentry; + +Sentry.init("___PUBLIC_DSN___"); +``` + +## Configuration methods {#configuration-methods} + +There are multiple ways to configure the Java SDK, but all of them take the same options. See below for how to use each configuration method and how the option names might differ between them. + +### Configuration via properties file + +The Java SDK can be configured via a [.properties file](https://en.wikipedia.org/wiki/.properties) that is located on the filesystem or in your application’s classpath. By default the SDK will look for a `sentry.properties` file in the application’s current working directory or in the root of your classpath. In most server side applications the default directory to add resources to your classpath is `src/main/resources/`, and on Android the default is `app/src/main/resources/`. You can override the location of the properties file by using either the `sentry.properties.file` Java System Property or the `SENTRY_PROPERTIES_FILE` System Environment Variable. + +Because this file is often bundled with your application, the values cannot be changed easily once your application has been packaged. For this reason, the properties file is useful for setting defaults or options that you don’t expect to change often. The properties file is the last place checked for each option value, so runtime configuration (described below) will override it if available. + +Option names in the property file exactly match the examples given below. For example, to enable sampling, in your properties file: + +```properties +sample.rate=0.75 +``` + +### Configuration via the runtime environment + +This is the most flexible method for configuring the Sentry client because it can be easily changed based on the environment you run your application in. _Neither Java System Properties or System Environment Variables are available for Android applications. Please configure Sentry for Android via code or the properties file._ + +Two methods are available for runtime configuration, checked in this order: Java System Properties and System Environment Variables. + +Java System Property option names are exactly like the examples given below except that they are prefixed with `sentry.`. For example, to enable sampling: + +```bash +java -Dsentry.sample.rate=0.75 -jar app.jar +``` + +System Environment Variable option names require that you replace the `.` with `_`, capitalize them, and add a `SENTRY_` prefix. For example, to enable sampling: + +```bash +SENTRY_SAMPLE_RATE=0.75 java -jar app.jar +``` + +### Configuration via code + +The DSN itself can also be configured directly in code: + +```java +import io.sentry.Sentry; + +Sentry.init("___PUBLIC_DSN___"); +``` + +Sentry **will not** be able to do anything with events until this line is run, so this method of configuration is not recommended if you might have errors occur during startup. In addition, by passing a hardcoded DSN you are no longer able to override the DSN at runtime via Java System Properties or System Environment Variables. + +### Configuration via the DSN + +The SDK can also be configured by setting querystring parameters on the DSN itself. This is a bit recursive because your DSN itself is an option that you must set somewhere (and not in the DSN!). + +Option names in the DSN exactly match the examples given below. For example, to enable sampling if you are setting your DSN via the environment: + +```bash +SENTRY_DSN={DSN}/1?sample.rate=0.75 java -jar app.jar +``` + +You can, of course, pass this DSN in using the other methods described above. + +## Options + +The following options can all be configured as described above: via a `sentry.properties` file, via Java System Properties, via System Environment variables, or via the DSN. + +### Release + +To set the application version that will be sent with each event, use the `release` option: + +``` +release=1.0.0 +``` + +#### Distribution + +To set the application distribution that will be sent with each event, use the `dist` option: + +``` +release=1.0.0 +dist=x86 +``` + +The distribution is only useful (and used) if the `release` is also set. + +### Environment + +To set the application environment that will be sent with each event, use the `environment` option: + +``` +environment=staging +``` + +### Server Name + +To set the server name that will be sent with each event, use the `servername` option: + +``` +servername=host1 +``` + +### Tags + +To set tags that will be sent with each event, use the `tags` option with comma separated pairs of keys and values that are joined by a colon: + +``` +tags=tag1:value1,tag2:value2 +``` + +### MDC Tags + +To set tag names that are extracted from the SLF4J MDC system, use the `mdctags` option with comma separated key names. This option is only useful when you're using one of the logging integrations. + +``` +mdctags=foo,bar +``` + +```java +import org.slf4j.MDC; + +MDC.put("foo", "value1"); +MDC.put("bar", "value2"); + +// This sends an event where the 'foo' and 'bar' MDC values are set as additional tags +logger.error("This is a test"); +``` + +### Extra Data + +To set extra data that will be sent with each event (but not as tags), use the `extra` option with comma separated pairs of keys and values that are joined by a colon: + +``` +extra=key1:value1,key2:value2 +``` + +### “In Application” Stack Frames + +Sentry differentiates stack frames that are directly related to your application (“in application”) from stack frames that come from other packages such as the standard library, frameworks, or other dependencies. The difference is visible in the Sentry web interface where only the “in application” frames are displayed by default. + +You can configure which package prefixes your application uses with the `stacktrace.app.packages` option, which takes a comma separated list. + +``` +stacktrace.app.packages=com.mycompany,com.other.name +``` + +If you don’t want to use this feature but want to disable the warning, simply set it to an empty string: + +``` +stacktrace.app.packages= +``` + +#### Same Frame as Enclosing Exception + +Sentry can use the “in application” system to hide frames in chained exceptions. Usually when a StackTrace is printed, the result looks like this: + +``` +HighLevelException: MidLevelException: LowLevelException + at Main.a(Main.java:13) + at Main.main(Main.java:4) +Caused by: MidLevelException: LowLevelException + at Main.c(Main.java:23) + at Main.b(Main.java:17) + at Main.a(Main.java:11) + ... 1 more +Caused by: LowLevelException + at Main.e(Main.java:30) + at Main.d(Main.java:27) + at Main.c(Main.java:21) + ... 3 more +``` + +Some frames are replaced by the `... N more` line as they are the same frames as in the enclosing exception. + +A similar behavior is enabled by default in Sentry. To disable it, use the `stacktrace.hidecommon` option. + +``` +stacktrace.hidecommon=false +``` + +### Event Sampling + +Sentry can be configured to sample events with the `sample.rate` option: + +``` +sample.rate=0.75 +``` + +This option takes a number from 0.0 to 1.0, representing the percent of events to allow through to server (from 0% to 100%). By default all events will be sent to the Sentry server. + +### Uncaught Exception Handler + +By default, an `UncaughtExceptionHandler` is configured that will attempt to send exceptions to Sentry. To disable it, use the `uncaught.handler.enabled` option. Exceptions are sent asynchronously by default, and there is **no guarantee** they will be sent before the JVM exits. This option is best used in conjunction with the disk buffering system described below. + +``` +uncaught.handler.enabled=false +``` + +### Buffering Events to Disk + +Sentry can be configured to write events to a specified directory on disk anytime communication with the Sentry server fails with the `buffer.dir` option. If the directory doesn’t exist, Sentry will attempt to create it on startup and may therefore need write permission on the parent directory. Sentry always requires write permission on the buffer directory itself. This is enabled by default if the `AndroidSentryClientFactory` is used. + +``` +buffer.dir=sentry-events +``` + +The maximum number of events that will be stored on disk defaults to 10, but can also be configured with the option `buffer.size`: + +``` +buffer.size=100 +``` + +If a buffer directory is provided, a background thread will periodically attempt to re-send the events that are found on disk. By default it will attempt to send events every 60 seconds. You can change this with the `buffer.flushtime` option (in milliseconds): + +``` +buffer.flushtime=10000 +``` + + + + The Java SDK currently uses the native Java serialization system to write out events to the filesystem when buffering is enabled. Due to weaknesses in the Java serialization system it is possible for users that have write access to the `buffer.dir` directory to cause the Java SDK to deserialize arbitrary Java classes. In extreme cases this might lead to the ability to execute code. + + + +#### Graceful Shutdown of Buffering (Advanced) + +In order to shutdown the buffer flushing thread gracefully, a `ShutdownHook` is created. By default, the buffer flushing thread is given 1 second to shutdown gracefully, but this can be adjusted via `buffer.shutdowntimeout` (represented in milliseconds): + +``` +buffer.shutdowntimeout=5000 +``` + +The special value `-1` can be used to disable the timeout and wait indefinitely for the executor to terminate. + +The `ShutdownHook` could lead to memory leaks in an environment where the life cycle of Sentry doesn’t match the life cycle of the JVM. + +An example would be in a JEE environment where the application using Sentry could be deployed and undeployed regularly. + +To avoid this behavior, it is possible to disable the graceful shutdown by setting the `buffer.gracefulshutdown` option: + +``` +buffer.gracefulshutdown=false +``` + +### Async Connection + +In order to avoid performance issues due to a large amount of logs being generated or a slow connection to the Sentry server, an asynchronous connection is set up, using a low priority thread pool to submit events to Sentry. + +To disable the async mode, add `async=false` to your options: + +``` +async=false +``` + +#### Graceful Shutdown of Async (Advanced) + +In order to shutdown the asynchronous connection gracefully, a `ShutdownHook` is created. By default, the asynchronous connection is given 1 second to shutdown gracefully, but this can be adjusted via `async.shutdowntimeout` (represented in milliseconds): + +``` +async.shutdowntimeout=5000 +``` + +The special value `-1` can be used to disable the timeout and wait indefinitely for the executor to terminate. + +The `ShutdownHook` could lead to memory leaks in an environment where the life cycle of Sentry doesn’t match the life cycle of the JVM. + +An example would be in a JEE environment where the application using Sentry could be deployed and undeployed regularly. + +To avoid this behavior, it is possible to disable the graceful shutdown. This might lead to some log entries being lost if the log application doesn’t shut down the `SentryClient` instance nicely. + +The option to do so is `async.gracefulshutdown`: + +``` +async.gracefulshutdown=false +``` + +#### Async Queue Size (Advanced) + +The default queue used to store unprocessed events is limited to 50 items. Additional items added once the queue is full are dropped and never sent to the Sentry server. Depending on the environment (if the memory is sparse) it is important to be able to control the size of that queue to avoid memory issues. + +It is possible to set a maximum with the option `async.queuesize`: + +``` +async.queuesize=100 +``` + +This means that if the connection to the Sentry server is down, only the 100 most recent events will be stored and processed as soon as the server is back up. + +The special value `-1` can be used to enable an unlimited queue. Beware that network connectivity or Sentry server issues could mean your process will run out of memory. + +#### Async Threads Count (Advanced) + +By default the thread pool used by the async connection contains one thread per processor available to the JVM. + +It’s possible to manually set the number of threads (for example if you want only one thread) with the option `async.threads`: + +``` +async.threads=1 +``` + +#### Async Threads Priority (Advanced) + +In most cases sending logs to Sentry isn’t as important as an application running smoothly, so the threads have a [minimal priority](http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#MIN_PRIORITY). + +It is possible to customise this value to increase the priority of those threads with the option `async.priority`: + +``` +async.priority=10 +``` + +### Compression + +By default the content sent to Sentry is compressed before being sent. However, compressing and encoding the data adds a small CPU and memory hit which might not be useful if the connection to Sentry is fast and reliable. + +Depending on the limitations of the project (e.g. a mobile application with a limited connection, Sentry hosted on an external network), it can be useful to compress the data beforehand or not. + +It’s possible to manually enable/disable the compression with the option `compression` + +``` +compression=false +``` + +### Max Message Size + +By default only the first 1000 characters of a message will be sent to the server. This can be changed with the `maxmessagelength` option. + +``` +maxmessagelength=1500 +``` + +### Timeout (Advanced) + +A timeout is set to avoid blocking Sentry threads because establishing a connection is taking too long. + +It’s possible to manually set the timeout length with `timeout` (in milliseconds): + +``` +timeout=10000 +``` + +### Using a Proxy + +If your application needs to send outbound requests through an HTTP proxy, you can configure the proxy information via JVM networking properties or as a Sentry option. + +For example, using JVM networking properties (affects the entire JVM process), + +```bash +java \ + # if you are using the HTTP protocol \ + -Dhttp.proxyHost=proxy.example.com \ + -Dhttp.proxyPort=8080 \ + \ + # if you are using the HTTPS protocol \ + -Dhttps.proxyHost=proxy.example.com \ + -Dhttps.proxyPort=8080 \ + \ + # relevant to both HTTP and HTTPS + -Dhttp.nonProxyHosts=”localhost|host.example.com” \ + \ + MyApp +``` + +See [Java Networking and Proxies](http://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html) for more information about the proxy properties. + +Alternatively, using Sentry options (only affects the Sentry HTTP client, useful inside shared application containers), + +``` +http.proxy.host=proxy.example.com +http.proxy.port=8080 +``` + +## Custom functionality + +At times, you may require custom functionality that is not included in the Java SDK already. The most common way to do this is to create your own `SentryClientFactory` instance as seen in the example below. + +### Implementation + +```java +public class MySentryClientFactory extends DefaultSentryClientFactory { + @Override + public SentryClient createSentryClient(Dsn dsn) { + SentryClient sentryClient = new SentryClient(createConnection(dsn), getContextManager(dsn)); + + /* + Create and use the ForwardedAddressResolver, which will use the + X-FORWARDED-FOR header for the remote address if it exists. + */ + ForwardedAddressResolver forwardedAddressResolver = new ForwardedAddressResolver(); + sentryClient.addBuilderHelper(new HttpEventBuilderHelper(forwardedAddressResolver)); + + sentryClient.addBuilderHelper(new ContextBuilderHelper(sentryClient)); + return configureSentryClient(sentryClient, dsn); + } +} +``` + +### Usage + +To use your custom `SentryClientFactory` implementation, use the `factory` option: + +``` +factory=my.company.MySentryClientFactory +``` + +Your factory class will need to be available on your classpath with a zero argument constructor or an error will be thrown. + +## Linter configuration + +Sometimes linters can warn about types used by the SDK that are not available in your app. This can happen, for example, when using the Android integration due to the base SDK having JNDI lookup that takes no effect in Android. + +To get rid of the warning, configure your `lint.xml` as follows: + +```xml + + + + + +``` + +And in your Gradle plugin: + +```groovy +android { + lintOptions { + lintConfig file("path/to/lint.xml") + } +} +``` + +Where `path/to/lint.xml` is the path to the linting configuration file mentioned above. diff --git a/src/platforms/java/guides/google-app-engine/index.mdx b/src/platforms/java/common/legacy/google-app-engine/index.mdx similarity index 87% rename from src/platforms/java/guides/google-app-engine/index.mdx rename to src/platforms/java/common/legacy/google-app-engine/index.mdx index d36a2dcb4c0e26..784c17814c05d3 100644 --- a/src/platforms/java/guides/google-app-engine/index.mdx +++ b/src/platforms/java/common/legacy/google-app-engine/index.mdx @@ -1,9 +1,13 @@ --- title: Google App Engine -redirect_from: - - /clients/java/modules/appengine/ +sidebar_order: 30 --- + + +An [updated Java SDK](/platforms/java/) Java SDK has superseded this deprecated version. Sentry preserves this documentation for customers using the old client. We recommend using the updated Java SDK for new projects. + + The `sentry-appengine` library provides [Google App Engine](https://cloud.google.com/appengine/) support for Sentry via the [Task Queue API](https://cloud.google.com/appengine/docs/java/taskqueue/). The source can be found [on GitHub](https://github.com/getsentry/sentry-java/tree/master/sentry-appengine). diff --git a/src/platforms/java/common/legacy/index.mdx b/src/platforms/java/common/legacy/index.mdx new file mode 100644 index 00000000000000..05a1010d229654 --- /dev/null +++ b/src/platforms/java/common/legacy/index.mdx @@ -0,0 +1,24 @@ +--- +title: Legacy SDK (1.7) +sidebar_order: 2000 +--- + +This section covers the legacy Sentry SDK for Java (1.7.x), which is no longer under active development. We **strongly encourage** updating to [the updated Java SDK](/platforms/java/). + +Find more details about how to set up, configure and use the Legacy SDK: + +- [Configuration](/platforms/java/legacy/configuration) +- [Manual Usage](/platforms/java/legacy/usage) + +## Integrations + +- [Google App Engine](/platforms/java/legacy/google-app-engine/) +- [java.util.logging](/platforms/java/legacy/logging/) +- [log4j 1.x](/platforms/java/legacy/log4j/) +- [log4j 2.x](/platforms/java/legacy/log4j2/) +- [Logback](/platforms/java/legacy/logback/) +- [Spring](/platforms/java/legacy/spring/) + +## Resources + +- [Code](https://github.com/getsentry/sentry-java/tree/v1.7.30) diff --git a/src/platforms/java/guides/log4j/index.mdx b/src/platforms/java/common/legacy/log4j/index.mdx similarity index 91% rename from src/platforms/java/guides/log4j/index.mdx rename to src/platforms/java/common/legacy/log4j/index.mdx index 93bc0a71f2c7d7..e380d865830e4d 100644 --- a/src/platforms/java/guides/log4j/index.mdx +++ b/src/platforms/java/common/legacy/log4j/index.mdx @@ -1,10 +1,14 @@ --- title: log4j 1.x -redirect_from: - - /clients/java/modules/log4j/ +sidebar_order: 30 --- -The `sentry-log4j` library provides [Log4j 1.x](https://logging.apache.org/log4j/1.2/) support for Sentry via an [Appender](https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Appender.html) that sends logged exceptions to Sentry. Once this integration is configured you can _also_ use Sentry’s static API, [as shown on the usage page](usage/), in order to do things like record breadcrumbs, set the current user, or manually send events. + + +An [updated Java SDK](/platforms/java/) supersedes this deprecated version. Sentry preserves this documentation for customers using the old client. We recommend using the updated Java SDK for new projects. + + +The `sentry-log4j` library provides [Log4j 1.x](https://logging.apache.org/log4j/1.2/) support for Sentry via an [Appender](https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Appender.html) that sends logged exceptions to Sentry. Once this integration is configured you can _also_ use Sentry’s static API, [as shown on the usage page](/platforms/java/legacy/usage/), in order to do things like record breadcrumbs, set the current user, or manually send events. The source can be found [on GitHub](https://github.com/getsentry/sentry-java/tree/master/sentry-log4j). @@ -81,7 +85,7 @@ Alternatively, using the `log4j.xml` format: ``` -Next, **you’ll need to configure your DSN** (client key) and optionally other values such as `environment` and `release`. [See the configuration page](configuration/options/) for ways you can do this. +Next, **you’ll need to configure your DSN** (client key) and optionally other values such as `environment` and `release`. [See the configuration page](/platforms/java/legacy/configuration/) for ways you can do this. diff --git a/src/platforms/java/common/legacy/log4j2/index.mdx b/src/platforms/java/common/legacy/log4j2/index.mdx new file mode 100644 index 00000000000000..1a55b3cb4f7730 --- /dev/null +++ b/src/platforms/java/common/legacy/log4j2/index.mdx @@ -0,0 +1,140 @@ +--- +title: log4j 2.x +sidebar_order: 30 +--- + + + +An [updated Java SDK](/platforms/java/) SDK supersedes this deprecated version. Sentry preserves this documentation for customers using the old client. We recommend using the updated Java SDK for new projects. + + +The `sentry-log4j2` library provides [Log4j 2.x](https://logging.apache.org/log4j/2.x/) support for Sentry via an [Appender](https://logging.apache.org/log4j/2.x/log4j-core/apidocs/org/apache/logging/log4j/core/Appender.html) that sends logged exceptions to Sentry. Once this integration is configured you can _also_ use Sentry’s static API, [as shown on the usage page](/platforms/java/legacy/usage), in order to do things like record breadcrumbs, set the current user, or manually send events. + +The source can be found [on GitHub](https://github.com/getsentry/sentry-java/tree/master/sentry-log4j2). + +### Installation + +```xml {tabTitle:Maven} + + io.sentry + sentry-log4j2 + {{ packages.version('sentry.java', '1.7.30') }} + +``` + +```groovy {tabTitle:Gradle} +implementation 'io.sentry:sentry-log4j2:{{ packages.version('sentry.java', '1.7.30') }}' +``` + +```scala {tabTitle: SBT} +libraryDependencies += "io.sentry" % "sentry-log4j2" % "{{ packages.version('sentry.java', '1.7.30') }}" +``` + +For other dependency managers see the [central Maven repository](https://search.maven.org/artifact/io.sentry/sentry-log4j2). + +### Usage + +The following example configures a `ConsoleAppender` that logs to standard out at the `INFO` level and a `SentryAppender` that logs to the Sentry server at the `WARN` level. The `ConsoleAppender` is only provided as an example of a non-Sentry appender that is set to a different logging threshold, like one you may already have in your project. + +Example configuration using the `log4j2.xml` format: + +```xml + + + + + + + + + + + + + + + + + + +``` + +Next, **you’ll need to configure your DSN** (client key) and optionally other values such as `environment` and `release`. [See the configuration page](/platforms/java/legacy/configuration/) for ways you can do this. + + + +### Additional Data + +It’s possible to add extra data to events thanks to [the marker system](https://logging.apache.org/log4j/2.x/manual/markers.html) provided by Log4j 2.x. + +#### Mapped Tags + +By default all MDC parameters are stored under the “Additional Data” tab in Sentry. By specifying the `mdctags` option in your configuration you can choose which MDC keys to send as tags instead, which allows them to be used as filters within the Sentry UI. + +```java +void logWithExtras() { + // ThreadContext ("MDC") extras + ThreadContext.put("Environment", "Development"); + ThreadContext.put("OS", "Linux"); + + // This sends an event where the Environment and OS MDC values are set as additional data + logger.error("This is a test"); +} +``` + +### In Practice + +```java +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; + +public class MyClass { + private static final Logger logger = LogManager.getLogger(MyClass.class); + private static final Marker MARKER = MarkerManager.getMarker("myMarker"); + + void logSimpleMessage() { + // This sends a simple event to Sentry + logger.error("This is a test"); + } + + void logWithBreadcrumbs() { + // Record a breadcrumb that will be sent with the next event(s), + // by default the last 100 breadcrumbs are kept. + Sentry.record( + new BreadcrumbBuilder().setMessage("User made an action").build() + ); + + // This sends a simple event to Sentry + logger.error("This is a test"); + } + + void logWithTag() { + // This sends an event with a tag named 'log4j2-Marker' to Sentry + logger.error(MARKER, "This is a test"); + } + + void logWithExtras() { + // MDC extras + ThreadContext.put("extra_key", "extra_value"); + // NDC extras are sent under 'log4j2-NDC' + ThreadContext.push("Extra_details"); + // This sends an event with extra data to Sentry + logger.error("This is a test"); + } + + void logException() { + try { + unsafeMethod(); + } catch (Exception e) { + // This sends an exception event to Sentry + logger.error("Exception caught", e); + } + } + + void unsafeMethod() { + throw new UnsupportedOperationException("You shouldn't call this!"); + } +} +``` diff --git a/src/platforms/java/common/legacy/logback/index.mdx b/src/platforms/java/common/legacy/logback/index.mdx new file mode 100644 index 00000000000000..5db6e76beff19c --- /dev/null +++ b/src/platforms/java/common/legacy/logback/index.mdx @@ -0,0 +1,187 @@ +--- +title: Logback +sidebar_order: 30 +--- + + + +A new Java SDK has superseded this deprecated version. Sentry preserves this documentation for customers using the old client. We recommend using the [updated Java SDK](/platforms/java/) for new projects. + + +The `sentry-logback` library provides [Logback](http://logback.qos.ch/) support for Sentry via an [Appender](http://logback.qos.ch/apidocs/ch/qos/logback/core/Appender.html) that sends logged exceptions to Sentry. Once this integration is configured you can _also_ use Sentry’s static API, [as shown on the usage page](/platforms/java/legacy/usage), in order to do things like record breadcrumbs, set the current user, or manually send events. + +The source can be found [on GitHub](https://github.com/getsentry/sentry-java/tree/master/sentry-logback). + +### Installation + +```xml {tabTitle:Maven} + + io.sentry + sentry-logback + {{ packages.version('sentry.java', '1.7.30') }} + +``` + +```groovy {tabTitle:Gradle} +implementation 'io.sentry:sentry-logback:{{ packages.version('sentry.java', '1.7.30') }}' +``` + +```scala {tabTitle: SBT} +libraryDependencies += "io.sentry" % "sentry-logback" % "{{ packages.version('sentry.java', '1.7.30') }}" +``` + +For other dependency managers see the [central Maven repository](https://search.maven.org/artifact/io.sentry/sentry-logback). + +### Usage + +The following example configures a `ConsoleAppender` that logs to standard out at the `INFO` level and a `SentryAppender` that logs to the Sentry server at the `WARN` level. The `ConsoleAppender` is only provided as an example of a non-Sentry appender that is set to a different logging threshold, like one you may already have in your project. + +Example configuration using the `logback.xml` format: + +```xml + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + WARN + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + +``` + +Next, **you’ll need to configure your DSN** (client key) and optionally other values such as `environment` and `release`. [See the configuration page](/platforms/java/legacy/configuration/#setting-the-dsn-data-source-name-setting-the-dsn) for ways you can do this. + + + +### Additional Data + +It’s possible to add extra data to events thanks to [the MDC system provided by Logback](http://logback.qos.ch/manual/mdc.html). + +#### Mapped Tags + +By default all MDC parameters are stored under the “Additional Data” tab in Sentry. By specifying the `mdctags` option in your configuration you can choose which MDC keys to send as tags instead, which allows them to be used as filters within the Sentry UI. + +```java +void logWithExtras() { + // MDC extras + MDC.put("Environment", "Development"); + MDC.put("OS", "Linux"); + + // This sends an event where the Environment and OS MDC values are set as additional data + logger.error("This is a test"); +} +``` + +#### Global Tags + +Sometimes it's useful to add tags and extra data to all log events. +You can add tags and extras to logs globally (not thread-bound) by adding entries to the LoggerContext. +Tags are distinguished by the existing mdcTags configuration property detailed above. + +```java + LoggerContext context = (LoggerContext)LoggerFactory.getILoggerFactory(); + context.putProperty("global", "value"); +``` + +Global log entries can also be added via third-party encoders +(_whether such entries can be distinguished as tags or entries, however, is encoder implementation-specific_). +The `net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder` for example has a `customFields` option: + +```java + + {"appname":"myWebservice","roles":["customerorder","auth"]} + +``` + +In the event of naming clashes, the more specific MDC tags will take precedence. + +### In Practice + +```java +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.slf4j.MarkerFactory; + +public class MyClass { + private static final Logger logger = LoggerFactory.getLogger(MyClass.class); + private static final Marker MARKER = MarkerFactory.getMarker("myMarker"); + + void logSimpleMessage() { + // This sends a simple event to Sentry + logger.error("This is a test"); + } + + void logWithBreadcrumbs() { + // Record a breadcrumb that will be sent with the next event(s), + // by default the last 100 breadcrumbs are kept. + Sentry.record( + new BreadcrumbBuilder().setMessage("User made an action").build() + ); + + // This sends a simple event to Sentry + logger.error("This is a test"); + } + + void logWithTag() { + // This sends an event with a tag named 'logback-Marker' to Sentry + logger.error(MARKER, "This is a test"); + } + + void logWithExtras() { + // MDC extras + MDC.put("extra_key", "extra_value"); + // This sends an event with extra data to Sentry + logger.error("This is a test"); + } + + void logWithGlobalTag() { + LoggerContext context = (LoggerContext)LoggerFactory.getILoggerFactory(); + // This adds a tag named 'logback-Marker' to every subsequent Sentry event + context.putProperty(MARKER, "This is a test"); + + // This sends an event to Sentry, and a tag named 'logback-Marker' will be added. + logger.info("This is a test"); + } + + void addGlobalExtras() { + LoggerContext context = (LoggerContext)LoggerFactory.getILoggerFactory(); + // This adds extra data to every subsequent Sentry event + context.putProperty("extra_key", "extra_value"); + + // This sends an event to Sentry, and extra data ("extra_key", "extra_value") will be added. + logger.info("This is a test"); + } + + void logException() { + try { + unsafeMethod(); + } catch (Exception e) { + // This sends an exception event to Sentry + logger.error("Exception caught", e); + } + } + + void unsafeMethod() { + throw new UnsupportedOperationException("You shouldn't call this!"); + } +} +``` diff --git a/src/platforms/java/guides/logging/index.mdx b/src/platforms/java/common/legacy/logging/index.mdx similarity index 80% rename from src/platforms/java/guides/logging/index.mdx rename to src/platforms/java/common/legacy/logging/index.mdx index 9a5008396f0d7e..9c906d090716dc 100644 --- a/src/platforms/java/guides/logging/index.mdx +++ b/src/platforms/java/common/legacy/logging/index.mdx @@ -1,10 +1,14 @@ --- title: java.util.logging -redirect_from: - - /clients/java/modules/jul/ +sidebar_order: 30 --- -The `sentry` library provides a [java.util.logging Handler](https://docs.oracle.com/javase/7/docs/api/java/util/logging/Handler.html) that sends logged exceptions to Sentry. Once this integration is configured you can _also_ use Sentry’s static API, [as shown on the usage page](usage/), in order to do things like record breadcrumbs, set the current user, or manually send events. + + +An [updated Java SDK](/platforms/java/) supersedes this deprecated version. Sentry preserves this documentation for customers using the old client. We recommend using the updated Java SDK for new projects. + + +The `sentry` library provides a [java.util.logging Handler](http://docs.oracle.com/javase/8/docs/api/java/util/logging/Handler.html) that sends logged exceptions to Sentry. Once this integration is configured you can _also_ use Sentry’s static API, [as shown on the usage page](/platforms/java/legacy/usage), in order to do things like record breadcrumbs, set the current user, or manually send events. The source for `sentry` can be found [on GitHub](https://github.com/getsentry/sentry-java/tree/master/sentry). @@ -51,7 +55,7 @@ When starting your application, add the `java.util.logging.config.file` to the s $ java -Djava.util.logging.config.file=/path/to/app.properties MyClass ``` -Next, **you’ll need to configure your DSN** (client key) and optionally other values such as `environment` and `release`. [See the configuration page](configuration/options/) for ways you can do this. +Next, **you’ll need to configure your DSN** (client key) and optionally other values such as `environment` and `release`. [See the configuration page](/platforms/java/legacy/configuration) for ways you can do this. diff --git a/src/platforms/java/common/migration.mdx b/src/platforms/java/common/legacy/migration.mdx similarity index 99% rename from src/platforms/java/common/migration.mdx rename to src/platforms/java/common/legacy/migration.mdx index 2f7f2ee5718172..9fa3857acc147c 100644 --- a/src/platforms/java/common/migration.mdx +++ b/src/platforms/java/common/legacy/migration.mdx @@ -1,5 +1,5 @@ --- -title: Migration Guide +title: Migrating Between Raven and Version 1.7 sidebar_order: 1000 redirect_from: - /clients/java/migration/ diff --git a/src/platforms/java/common/legacy/spring/index.mdx b/src/platforms/java/common/legacy/spring/index.mdx new file mode 100644 index 00000000000000..8dfa21c8001745 --- /dev/null +++ b/src/platforms/java/common/legacy/spring/index.mdx @@ -0,0 +1,79 @@ +--- +title: Spring +sidebar_order: 30 +--- + + + +An [updated Java SDK](/platforms/java/) supersedes this deprecated version. Sentry preserves this documentation for customers using the old client. We recommend using the updated Java SDK for new projects. + + +The `sentry-spring` library provides [Spring](https://spring.io/) support for Sentry via a [HandlerExceptionResolver](https://docs.spring.io/spring/docs/4.3.9.RELEASE/javadoc-api/org/springframework/web/servlet/HandlerExceptionResolver.html) that sends exceptions to Sentry. Once this integration is configured you can _also_ use Sentry’s static API, [as shown on the usage page](/platforms/java/legacy/usage), in order to do things like record breadcrumbs, set the current user, or manually send events. + +The source can be found [on GitHub](https://github.com/getsentry/sentry-java/tree/master/sentry-spring). + +### Installation + +```xml {tabTitle:Maven} + + io.sentry + sentry-spring + {{ packages.version('sentry.java', '1.7.30') }} + +``` + +```groovy {tabTitle:Gradle} +implementation 'io.sentry:sentry-spring:{{ packages.version('sentry.java', '1.7.30') }}' +``` + +```scala {tabTitle: SBT} +libraryDependencies += "io.sentry" % "sentry-spring" % "{{ packages.version('sentry.java', '1.7.30') }}" +``` + +For other dependency managers see the [central Maven repository](https://search.maven.org/artifact/io.sentry/sentry-spring). + +### Usage + +The `sentry-spring` library provides two classes that can be enabled by registering them as Beans in your Spring application. + +#### Recording Exceptions + +In order to record all exceptions thrown by your controllers, you can register `io.sentry.spring.SentryExceptionResolver` as a Bean in your application. Once registered, all exceptions will be sent to Sentry and then passed on to the default exception handlers. + +Configuration via `web.xml`: + +```xml + +``` + +Or via a configuration class: + +```java +@Bean +public HandlerExceptionResolver sentryExceptionResolver() { + return new io.sentry.spring.SentryExceptionResolver(); +} +``` + +Next, **you’ll need to configure your DSN** (client key) and optionally other values such as `environment` and `release`. [See the configuration page](/platforms/java/legacy/configuration) for ways you can do this. + +#### Spring Boot HTTP Data + +Spring Boot doesn’t automatically load any `javax.servlet.ServletContainerInitializer`, which means the Sentry SDK doesn’t have an opportunity to hook into the request cycle to collect information about the HTTP request. In order to add HTTP request data to your Sentry events in Spring Boot, you need to register the `io.sentry.spring.SentryServletContextInitializer` class as a Bean in your application. + +Configuration via `web.xml`: + +```xml + +``` + +Or via a configuration class: + +```java +@Bean +public ServletContextInitializer sentryServletContextInitializer() { + return new io.sentry.spring.SentryServletContextInitializer(); +} +``` + +After that, your Sentry events should contain information such as HTTP request headers. diff --git a/src/platforms/java/common/legacy/usage.mdx b/src/platforms/java/common/legacy/usage.mdx new file mode 100644 index 00000000000000..ee435eb0716e2d --- /dev/null +++ b/src/platforms/java/common/legacy/usage.mdx @@ -0,0 +1,221 @@ +--- +title: Manual Usage +sidebar_order: 15 +redirect_from: + - /clients/java/usage/ +--- + +## Installation + +```xml {tabTitle:Maven} + + io.sentry + sentry + 1.7.30 + +``` + +```groovy {tabTitle:Gradle} +implementation 'io.sentry:sentry:1.7.30' +``` + +```scala {tabTitle:SBT} +libraryDependencies += "io.sentry" % "sentry" % "1.7.30" +``` + +For other dependency managers see the [central Maven repository](https://search.maven.org/artifact/io.sentry/sentry-spring). + +## Capture an Error + +To report an event manually you need to initialize a `SentryClient`. It is recommended that you use the static API via the `Sentry` class, but you can also construct and manage your own `SentryClient` instance. An example of each style is shown below: + +```java +import io.sentry.context.Context; +import io.sentry.event.BreadcrumbBuilder; +import io.sentry.event.UserBuilder; + +public class MyClass { + private static SentryClient sentry; + + public static void main(String... args) { + /* + It is recommended that you use the DSN detection system, which + will check the environment variable "SENTRY_DSN", the Java + System Property "sentry.dsn", or the "sentry.properties" file + in your classpath. This makes it easier to provide and adjust + your DSN without needing to change your code. See the configuration + page for more information. + + For example, using an environment variable + + export SENTRY_DSN="___PUBLIC_DSN___" + */ + Sentry.init(); + + // You can also manually provide the DSN to the ``init`` method. + // Sentry.init("___PUBLIC_DSN___"); + + /* + It is possible to go around the static ``Sentry`` API, which means + you are responsible for making the SentryClient instance available + to your code. + */ + sentry = SentryClientFactory.sentryClient(); + + MyClass myClass = new MyClass(); + myClass.logWithStaticAPI(); + myClass.logWithInstanceAPI(); + } + + /** + * An example method that throws an exception. + */ + void unsafeMethod() { + throw new UnsupportedOperationException("You shouldn't call this!"); + } + + /** + * Examples using the (recommended) static API. + */ + void logWithStaticAPI() { + // Note that all fields set on the context are optional. Context data is copied onto + // all future events in the current context (until the context is cleared). + + // Record a breadcrumb in the current context. By default the last 100 breadcrumbs are kept. + Sentry.getContext().recordBreadcrumb( + new BreadcrumbBuilder().setMessage("User made an action").build() + ); + + // Set the user in the current context. + Sentry.getContext().setUser( + new UserBuilder().setEmail("hello@sentry.io").build() + ); + + // Add extra data to future events in this context. + Sentry.getContext().addExtra("extra", "thing"); + + // Add an additional tag to future events in this context. + Sentry.getContext().addTag("tagName", "tagValue"); + + /* + This sends a simple event to Sentry using the statically stored instance + that was created in the ``main`` method. + */ + Sentry.capture("This is a test"); + + try { + unsafeMethod(); + } catch (Exception e) { + // This sends an exception event to Sentry using the statically stored instance + // that was created in the ``main`` method. + Sentry.capture(e); + } + } + + /** + * Examples that use the SentryClient instance directly. + */ + void logWithInstanceAPI() { + // Retrieve the current context. + Context context = sentry.getContext(); + + // Record a breadcrumb in the current context. By default the last 100 breadcrumbs are kept. + context.recordBreadcrumb(new BreadcrumbBuilder().setMessage("User made an action").build()); + + // Set the user in the current context. + context.setUser(new UserBuilder().setEmail("hello@sentry.io").build()); + + // This sends a simple event to Sentry. + sentry.sendMessage("This is a test"); + + try { + unsafeMethod(); + } catch (Exception e) { + // This sends an exception event to Sentry. + sentry.sendException(e); + } + } +} +``` + +### Building More Complex Events + +For more complex messages, you’ll need to build an `Event` with the `EventBuilder` class: + +```java +import io.sentry.Sentry; + import io.sentry.event.Event; + import io.sentry.event.EventBuilder; + import io.sentry.event.interfaces.ExceptionInterface; + + public class MyClass { + public static void main(String... args) { + Sentry.init(); + } + + void unsafeMethod() { + throw new UnsupportedOperationException("You shouldn't call this!"); + } + + void logSimpleMessage() { + // This sends an event to Sentry. + EventBuilder eventBuilder = new EventBuilder() + .withMessage("This is a test") + .withLevel(Event.Level.INFO) + .withLogger(MyClass.class.getName()); + + // Note that the *unbuilt* EventBuilder instance is passed in so that + // EventBuilderHelpers are run to add extra information to your event. + Sentry.capture(eventBuilder); + } + + void logException() { + try { + unsafeMethod(); + } catch (Exception e) { + // This sends an exception event to Sentry. + EventBuilder eventBuilder = new EventBuilder() + .withMessage("Exception caught") + .withLevel(Event.Level.ERROR) + .withLogger(MyClass.class.getName()) + .withSentryInterface(new ExceptionInterface(e)); + + // Note that the *unbuilt* EventBuilder instance is passed in so that + // EventBuilderHelpers are run to add extra information to your event. + Sentry.capture(eventBuilder); + } + } +} +``` + +### Automatically Enhancing Events + +You can also implement an `EventBuilderHelper` that is able to automatically enhance outgoing events. + +```java +import io.sentry.Sentry; +import io.sentry.SentryClient; +import io.sentry.event.EventBuilder; +import io.sentry.event.helper.EventBuilderHelper; + +public class MyClass { + public void myMethod() { + SentryClient client = Sentry.getStoredClient(); + + EventBuilderHelper myEventBuilderHelper = new EventBuilderHelper() { + @Override + public void helpBuildingEvent(EventBuilder eventBuilder) { + eventBuilder.withMessage("Overwritten by myEventBuilderHelper!"); + } + }; + + // Add an ``EventBuilderHelper`` to the current client instance. Note that + // this helper will process *all* future events. + client.addBuilderHelper(myEventBuilderHelper); + + // Send an event to Sentry. During construction of the event the message + // body will be overwritten by ``myEventBuilderHelper``. + Sentry.capture("Hello, world!"); + } +} +``` diff --git a/src/platforms/java/common/scope.mdx b/src/platforms/java/common/scope.mdx new file mode 100644 index 00000000000000..b8cf8056e5ae6b --- /dev/null +++ b/src/platforms/java/common/scope.mdx @@ -0,0 +1,59 @@ +--- +title: Scope & Breadcrumbs +sidebar_order: 3 +redirect_from: + - /clients/java/context/ +--- + +The Java SDK implements the idea of a “scope” to support attaching additional information to events, such as breadcrumbs. A scope may refer to a single request to a web framework, to the entire lifetime of an Android application, or something else that better suits your application’s needs. + +## Usage + +Breadcrumbs can be used to describe actions that occurred in your application leading up to an event being sent. For example, whether external API requests were made, or whether a user clicked on something in an Android application. By default the last 100 breadcrumbs per scope will be stored and sent with future events. + +The user can be set per scope so that you know who was affected by each event. + +Once a `Sentry` instance has been initialized you can begin setting state in the current scope. + +```java +import io.sentry.Sentry; +import io.sentry.protocol.User; + +public class MyClass { + + public void example() { + // Manually initialize the static client, you must also pass in a DSN and/or + // SentryClientFactory to use. Note that the client will attempt to automatically + // initialize on the first use of the static API, so this isn't strictly necessary. + Sentry.init(options -> { + options.setDsn("___PUBLIC_DSN___"); + }); + + // Note that all fields set on the scope are optional. Scope data is copied onto + // all future events in the current scope (until the scope is cleared). + + // Set the current user in the scope. + Sentry.configureScope(scope -> { + User user = new User(); + user.setUsername("user1"); + scope.setUser(user); + }); + + // Record a breadcrumb in the scope. + Sentry.addBreadcrumb("User did something specific again!"); + + // Add extra data to future events in this scope. + Sentry.configureScope(scope -> { + scope.setExtra("extra", "thing"); + }); + + // Add an additional tag to future events in this scope. + Sentry.configureScope(scope -> { + scope.setTag("tagName", "tagValue"); + }); + + // Send an event with the scope data attached. + Sentry.captureMessage("New event message"); + } +} +``` diff --git a/src/platforms/java/guides/log4j2/index.mdx b/src/platforms/java/guides/log4j2/index.mdx index 7f5e8e8ef14286..1f71a42c20333b 100644 --- a/src/platforms/java/guides/log4j2/index.mdx +++ b/src/platforms/java/guides/log4j2/index.mdx @@ -14,123 +14,197 @@ The source can be found [on GitHub](https://github.com/getsentry/sentry-java/tre io.sentry sentry-log4j2 - {{ packages.version('sentry.java', '1.7.30') }} + {{ packages.version('sentry.java', '3.0.0') }} ``` ```groovy {tabTitle:Gradle} -implementation 'io.sentry:sentry-log4j2:{{ packages.version('sentry.java', '1.7.30') }}' +implementation 'io.sentry:sentry-log4j2:{{ packages.version('sentry.java', '3.0.0') }}' ``` ```scala {tabTitle: SBT} -libraryDependencies += "io.sentry" % "sentry-log4j2" % "{{ packages.version('sentry.java', '1.7.30') }}" +libraryDependencies += "io.sentry" % "sentry-log4j2" % "{{ packages.version('sentry.java', '3.0.0') }}" ``` For other dependency managers see the [central Maven repository](https://search.maven.org/artifact/io.sentry/sentry-log4j2). ### Usage -The following example configures a `ConsoleAppender` that logs to standard out at the `INFO` level and a `SentryAppender` that logs to the Sentry server at the `WARN` level. The `ConsoleAppender` is only provided as an example of a non-Sentry appender that is set to a different logging threshold, like one you may already have in your project. +The following example configures a `ConsoleAppender` that logs to standard out at the `INFO` level and a `SentryAppender` that logs to the Sentry server at the `ERROR` level. The `ConsoleAppender` is only provided as an example of a non-Sentry appender that is set to a different logging threshold, like one you may already have in your project. Example configuration using the `log4j2.xml` format: ```xml - - + + - + + + + + + + + + + +``` + +### DSN Configuration - - - - - - - - - - - +Note that **you need to configure your DSN** (client key). + +```xml + ``` -Next, **you’ll need to configure your DSN** (client key) and optionally other values such as `environment` and `release`. [See the configuration page](configuration/options/) for ways you can do this. +If the DSN is not present in the `log4j2.xml` configuration, Sentry will attempt to read it from the system property `sentry.dsn`, environment variable `SENTRY_DSN` or the `dsn` property in `sentry.properties` file. [See the configuration page](/platforms/java/configuration/) for more details on external configuration. - +### Minimum Log Level -### Additional Data +Two log levels are used to configure this integration (see options below). One will configure the lowest level required for a log message to become an event (`minimumEventLevel`) sent to Sentry. The other option (`minimumBreadcrumbLevel`) configures the lowest level a message has to be to become a breadcrumb. Breadcrumbs are kept in memory (by default the last 100 records) and are sent with events. For example, by default, if you log 100 entries with `logger.info` or `logger.warn`, no event is sent to Sentry. If you then log with `logger.error`, an event is sent to Sentry which includes those 100 `info` or `warn` messages. For this to work, `SentryAppender` needs to receive **all** log entries in order to decide what to keep as breadcrumb or sent as event. Make sure to set the `SentryAppender` log level configuration to a value lower than what you set for the `minimumBreadcrumbLevel` and `minimumEventLevel` to make sure `SentryAppender` receives these log messages. -It’s possible to add extra data to events thanks to [the marker system](https://logging.apache.org/log4j/2.x/manual/markers.html) provided by Log4j 2.x. +```xml + + + +``` #### Mapped Tags -By default all MDC parameters are stored under the “Additional Data” tab in Sentry. By specifying the `mdctags` option in your configuration you can choose which MDC keys to send as tags instead, which allows them to be used as filters within the Sentry UI. +By default all `ThreadContext` parameters are stored under the “Context Data” tab in Sentry. -```java +```java {tabTitle:Java} void logWithExtras() { // ThreadContext ("MDC") extras ThreadContext.put("Environment", "Development"); ThreadContext.put("OS", "Linux"); - // This sends an event where the Environment and OS MDC values are set as additional data + // This sends an event where the Environment and OS ThreadContext values are set as Context Data entries + logger.error("This is a test"); +} +``` + +```kotlin {tabTitle:Kotlin} +fun logWithExtras() { + // MDC extras + ThreadContext.put("Environment", "Development"); + ThreadContext.put("OS", "Linux"); + + // This sends an event where the Environment and OS ThreadContext values are set as Context Data entries logger.error("This is a test"); } ``` ### In Practice -```java +```java {tabTitle:Java} +import io.sentry.core.Sentry; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.Marker; -import org.apache.logging.log4j.MarkerManager; +import org.apache.logging.log4j.ThreadContext; public class MyClass { - private static final Logger logger = LogManager.getLogger(MyClass.class); - private static final Marker MARKER = MarkerManager.getMarker("myMarker"); + private static final Logger logger = LogManager.getLogger(MyClass.class); + + void logSimpleMessage() { + // This sends a simple event to Sentry + logger.error("This is a test"); + } - void logSimpleMessage() { + void logWithBreadcrumbs() { + // Record a breadcrumb that will be sent with the next event(s), + // by default the last 100 breadcrumbs are kept. + Sentry.addBreadcrumb("User made an action"); + + // Log entries below `minimumEventLevel` and above or equal to `minimumBreadcrumbLevel` + // are recorded as breadcrumbs + logger.info("User made another action"); + + // This sends a simple event to Sentry + logger.error("This is a test"); + } + + void logWithExtras() { + // MDC extras + ThreadContext.put("extra_key", "extra_value"); + // NDC extras are sent under 'log4j2-NDC' + ThreadContext.push("Extra_details"); + // This sends an event with extra data to Sentry + logger.error("This is a test"); + } + + void logException() { + try { + unsafeMethod(); + } catch (Exception e) { + // This sends an exception event to Sentry + logger.error("Exception caught", e); + } + } + + void unsafeMethod() { + throw new UnsupportedOperationException("You shouldn't call this!"); + } +} +``` + +```kotlin {tabTitle:Kotlin} +import io.sentry.core.Sentry +import org.apache.logging.log4j.LogManager +import org.apache.logging.log4j.ThreadContext + +class MyClass { + companion object { + private val logger = LogManager.getLogger(MyClass::class.java) + } + + fun logSimpleMessage() { // This sends a simple event to Sentry - logger.error("This is a test"); + logger.error("This is a test") } - void logWithBreadcrumbs() { + fun logWithBreadcrumbs() { // Record a breadcrumb that will be sent with the next event(s), // by default the last 100 breadcrumbs are kept. - Sentry.record( - new BreadcrumbBuilder().setMessage("User made an action").build() - ); + Sentry.addBreadcrumb("User made an action") - // This sends a simple event to Sentry - logger.error("This is a test"); - } + // Log entries below `minimumEventLevel` and above or equal to `minimumBreadcrumbLevel` + // are recorded as breadcrumbs + logger.info("User made another action") - void logWithTag() { - // This sends an event with a tag named 'log4j2-Marker' to Sentry - logger.error(MARKER, "This is a test"); + // This sends a simple event to Sentry + logger.error("This is a test") } - void logWithExtras() { + fun logWithExtras() { // MDC extras - ThreadContext.put("extra_key", "extra_value"); + ThreadContext.put("extra_key", "extra_value") // NDC extras are sent under 'log4j2-NDC' - ThreadContext.push("Extra_details"); + ThreadContext.push("Extra_details") // This sends an event with extra data to Sentry - logger.error("This is a test"); + logger.error("This is a test") } - void logException() { + fun logException() { try { - unsafeMethod(); - } catch (Exception e) { + unsafeMethod() + } catch (e: Exception) { // This sends an exception event to Sentry - logger.error("Exception caught", e); + logger.error("Exception caught", e) } } - void unsafeMethod() { - throw new UnsupportedOperationException("You shouldn't call this!"); + fun unsafeMethod() { + throw UnsupportedOperationException("You shouldn't call this!") } } ``` diff --git a/src/platforms/java/guides/logback/index.mdx b/src/platforms/java/guides/logback/index.mdx index 9c405868cdad73..01e06bb1a22898 100644 --- a/src/platforms/java/guides/logback/index.mdx +++ b/src/platforms/java/guides/logback/index.mdx @@ -15,12 +15,12 @@ The source can be found [on GitHub](https://github.com/getsentry/sentry-java/tre io.sentry sentry-logback - {{ packages.version('sentry.java', '1.7.30') }} + {{ packages.version('sentry.java', '3.0.0') }} ``` ```groovy {tabTitle:Gradle} -implementation 'io.sentry:sentry-logback:{{ packages.version('sentry.java', '1.7.30') }}' +implementation 'io.sentry:sentry-logback:{{ packages.version('sentry.java', '3.0.0') }}' ``` ```scala {tabTitle: SBT} @@ -31,7 +31,7 @@ For other dependency managers see the [central Maven repository](https://search. ### Usage -The following example configures a `ConsoleAppender` that logs to standard out at the `INFO` level and a `SentryAppender` that logs to the Sentry server at the `WARN` level. The `ConsoleAppender` is only provided as an example of a non-Sentry appender that is set to a different logging threshold, like one you may already have in your project. +The following example configures a `ConsoleAppender` that logs to standard out at the `INFO` level and a `SentryAppender` that logs to the Sentry server at the `ERROR` level. The `ConsoleAppender` is only provided as an example of a non-Sentry appender that is set to a different logging threshold, like one you may already have in your project. Example configuration using the `logback.xml` format: @@ -46,13 +46,10 @@ Example configuration using the `logback.xml` format: - - WARN - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - + + + ___PUBLIC_DSN___ + + ___PUBLIC_DSN___ + + +``` + +If the DSN is not present in the `logback.xml` configuration, Sentry will attempt to read it from the system property `sentry.dsn`, environment variable `SENTRY_DSN` or the `dsn` property in `sentry.properties` file. [See the configuration page](/platforms/java/configuration/) for more details on external configuration. + +### Advanced Configuration + + +Optionally you can configure other values such as `environment` and `release`. [See the configuration page](configuration/options/#setting-the-dsn) for the in-depth explanation of each property. + +```xml + + + + ___PUBLIC_DSN___ + 2000 + 15000 + false + 100 + 1.0.0 + production + 1.0 + false + false + host-4 + 5000 + 5000 + + +``` + +### Minimum log level + +Two log levels are used to configure this integration (see options below). One will configure the lowest level required for a log message to become an event (`minimumEventLevel`) sent to Sentry. The other option (`minimumBreadcrumbLevel`) configures the lowest level a message has to be to become a breadcrumb. Breadcrumbs are kept in memory (by default the last 100 records) and are sent with events. For example, by default, if you log 100 entries with `logger.info` or `logger.warn`, no event is sent to Sentry. If you then log with `logger.error`, an event is sent to Sentry which includes those 100 `info` or `warn` messages. For this to work, `SentryAppender` needs to receive **all** log entries in order to decide what to keep as breadcrumb or sent as event. Make sure to set the `SentryAppender` log level configuration to a value lower than what you set for the `minimumBreadcrumbLevel` and `minimumEventLevel` to make sure `SentryAppender` receives these log messages. - +```xml + + + + ___PUBLIC_DSN___ + + + WARN + + DEBUG + +``` ### Additional Data @@ -74,53 +125,39 @@ It’s possible to add extra data to events thanks to [the MDC system provided b #### Mapped Tags -By default all MDC parameters are stored under the “Additional Data” tab in Sentry. By specifying the `mdctags` option in your configuration you can choose which MDC keys to send as tags instead, which allows them to be used as filters within the Sentry UI. +By default all MDC parameters are stored under the “MDC” tab in Sentry. -```java +```java {tabTitle:Java} void logWithExtras() { // MDC extras MDC.put("Environment", "Development"); MDC.put("OS", "Linux"); - // This sends an event where the Environment and OS MDC values are set as additional data + // This sends an event where the Environment and OS MDC values are set as MDC entries logger.error("This is a test"); } ``` -#### Global Tags - -Sometimes it's useful to add tags and extra data to all log events. -You can add tags and extras to logs globally (not thread-bound) by adding entries to the LoggerContext. -Tags are distinguished by the existing mdcTags configuration property detailed above. - -```java - LoggerContext context = (LoggerContext)LoggerFactory.getILoggerFactory(); - context.putProperty("global", "value"); -``` - -Global log entries can also be added via third-party encoders -(_whether such entries can be distinguished as tags or entries, however, is encoder implementation-specific_). -The `net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder` for example has a `customFields` option: +```kotlin {tabTitle:Kotlin} +fun logWithExtras() { + // MDC extras + MDC.put("Environment", "Development"); + MDC.put("OS", "Linux"); -```java - - {"appname":"myWebservice","roles":["customerorder","auth"]} - + // This sends an event where the Environment and OS MDC values are set as MDC entries + logger.error("This is a test"); +} ``` -In the event of naming clashes, the more specific MDC tags will take precedence. - ### In Practice -```java +```java {tabTitle:Java} import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC; -import org.slf4j.MarkerFactory; public class MyClass { private static final Logger logger = LoggerFactory.getLogger(MyClass.class); - private static final Marker MARKER = MarkerFactory.getMarker("myMarker"); void logSimpleMessage() { // This sends a simple event to Sentry @@ -130,19 +167,16 @@ public class MyClass { void logWithBreadcrumbs() { // Record a breadcrumb that will be sent with the next event(s), // by default the last 100 breadcrumbs are kept. - Sentry.record( - new BreadcrumbBuilder().setMessage("User made an action").build() - ); + Sentry.addBreadcrumb("User made an action"); + + // Log entries below `minimumEventLevel` and above or equal to `minimumBreadcrumbLevel` + // are recorded as breadcrumbs + logger.info("User made another action"); // This sends a simple event to Sentry logger.error("This is a test"); } - void logWithTag() { - // This sends an event with a tag named 'logback-Marker' to Sentry - logger.error(MARKER, "This is a test"); - } - void logWithExtras() { // MDC extras MDC.put("extra_key", "extra_value"); @@ -150,24 +184,6 @@ public class MyClass { logger.error("This is a test"); } - void logWithGlobalTag() { - LoggerContext context = (LoggerContext)LoggerFactory.getILoggerFactory(); - // This adds a tag named 'logback-Marker' to every subsequent Sentry event - context.putProperty(MARKER, "This is a test"); - - // This sends an event to Sentry, and a tag named 'logback-Marker' will be added. - logger.info("This is a test"); - } - - void addGlobalExtras() { - LoggerContext context = (LoggerContext)LoggerFactory.getILoggerFactory(); - // This adds extra data to every subsequent Sentry event - context.putProperty("extra_key", "extra_value"); - - // This sends an event to Sentry, and extra data ("extra_key", "extra_value") will be added. - logger.info("This is a test"); - } - void logException() { try { unsafeMethod(); @@ -182,3 +198,53 @@ public class MyClass { } } ``` + +```kotlin {tabTitle:Kotlin} +import io.sentry.core.Sentry +import org.slf4j.LoggerFactory +import org.slf4j.MDC + +class Main { + companion object { + private val logger = LoggerFactory.getLogger(Main::class.java) + } + + fun logSimpleMessage() { + // This sends a simple event to Sentry + logger.error("This is a test") + } + + fun logWithBreadcrumbs() { + // Record a breadcrumb that will be sent with the next event(s), + // by default the last 100 breadcrumbs are kept. + Sentry.addBreadcrumb("User made an action") + + // Log entries below `minimumEventLevel` and above or equal to `minimumBreadcrumbLevel` + // are recorded as breadcrumbs + logger.info("User made another action") + + // This sends a simple event to Sentry + logger.error("This is a test") + } + + fun logWithExtras() { + // MDC extras + MDC.put("extra_key", "extra_value") + // This sends an event with extra data to Sentry + logger.error("This is a test") + } + + fun logException() { + try { + unsafeMethod() + } catch (e: Exception) { + // This sends an exception event to Sentry + logger.error("Exception caught", e) + } + } + + fun unsafeMethod() { + throw UnsupportedOperationException("You shouldn't call this!") + } +} +``` diff --git a/src/platforms/java/guides/spring-boot/index.mdx b/src/platforms/java/guides/spring-boot/index.mdx new file mode 100644 index 00000000000000..1d89ab8c5a534a --- /dev/null +++ b/src/platforms/java/guides/spring-boot/index.mdx @@ -0,0 +1,261 @@ +--- +title: Spring Boot +--- + +The `sentry-spring-boot-starter` library enhances [Sentry Spring](/platforms/java/guides/spring/) support with an auto-configuration for [Spring Boot](https://spring.io/projects/spring-boot) providing following features: + +- fine-grained configuration via `application.properties` +- automatically setting the release on `SentryEvent` when [Spring Boot Git integration is configured](https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-git-info) +- automatically registering `BeforeSendCallback`, `BeforeBreadcrumbCallback`, `EventProcessor`, `Integration` beans + +For the best experience we recommend using Sentry Spring Boot integration together with one of the logging framework integrations as they seamlessly work together: + +- [Logback](/platforms/java/guides/logback/) +- [Log4j2](/platforms/java/guides/log4j2/) + +Once this integration is configured you can _also_ use Sentry’s static API, [as shown on the usage page](usage/), in order to do things like record breadcrumbs, set the current user, or manually send events. + + + To use Sentry without Spring Boot, we recommend using Sentry Spring integration. + + +The source can be found [on GitHub](https://github.com/getsentry/sentry-java/tree/master/sentry-spring). + +### Installation + +```xml {tabTitle:Maven} + + io.sentry + sentry-spring-boot-starter + {{ packages.version('sentry.java', '3.0.0') }} + +``` + +```groovy {tabTitle:Gradle} +implementation 'io.sentry:sentry-spring-boot-starter:{{ packages.version('sentry.java', '3.0.0') }}' +``` + +For other dependency managers see the [central Maven repository](https://search.maven.org/artifact/io.sentry/sentry-spring). + +### Usage + +The `sentry-spring-boot-starter` must be provided with a `sentry.dsn` property via `application.properties` or `application.yml`: + +```properties {tabTitle:application.properties} +# NOTE: Replace the test DSN below with YOUR OWN DSN to see the events from this app in your Sentry project/dashboard +sentry.dsn=___PUBLIC_DSN___ +``` + +```yaml {tabTitle:application.yml} +# NOTE: Replace the test DSN below with YOUR OWN DSN to see the events from this app in your Sentry project/dashboard +sentry: + dsn: ___PUBLIC_DSN___ +``` + +#### Recording User Information From HTTP Request + +In order to record user's IP address and `Principal#name` as the username, sending personal information flag has to be set to `true`. + +```properties {tabTitle:application.properties} +sentry.send-default-pii=true +``` + +```yaml {tabTitle:application.yml} +sentry: + send-default-pii: true +``` + +#### Recording Custom User Information + +In order to record custom user information, you care register a bean that implements `SentryUserProvider` interface. + +```java {tabTitle:Java} +import org.springframework.stereotype.Component; +import io.sentry.core.protocol.User; +import io.sentry.spring.SentryUserProvider; + +@Component +class CustomSentryUserProvider implements SentryUserProvider { + public User provideUser() { + User user = User(); + // ... set user information + return user + } +} +``` + +```kotlin {tabTitle:Kotlin} +import org.springframework.stereotype.Component +import io.sentry.core.protocol.User +import io.sentry.spring.SentryUserProvider + +@Component +class CustomSentryUserProvider : SentryUserProvider { + override fun provideUser(): User? { + val user = User() + // ... set user information + return user + } +} +``` + +#### Using Git Commit ID As The Release + +When Spring Boot is [configured to generate Git information](https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-git-info) every event triggered by Sentry will have a `release` field set to the current Git commit ID that will enable [Monitor Release Health](/product/releases/health/) Sentry feature. + +This feature can be disabled in `application.properties` file: + +```properties {tabTitle:application.properties} +sentry.use-git-commit-id-as-release=false +``` + +```yaml {tabTitle:application.yml} +sentry: + use-git-commit-id-as-release: false +``` + +#### Registering Custom Event Processor + +A Spring bean implementing `EventProcessor` will be automatically set on `SentryOptions` during Sentry SDK auto-configuration. There can be multiple event processors registered in single application. + +```java +import io.sentry.SentryEvent; +import io.sentry.EventProcessor; +import org.springframework.stereotype.Component; + +@Component +public class CustomEventProcessor implements EventProcessor { + @Override + public SentryEvent process(SentryEvent event, Object hint) { + // modify the event or return null to drop it + return event; + } +} +``` + +#### Registering Custom Before Send Callback + +A Spring bean implementing `BeforeSendCallback` will be automatically set on `SentryOptions` during Sentry SDK auto-configuration. Note that there can be only single bean like that. + +```java +import io.sentry.SentryEvent; +import io.sentry.SentryOptions; +import org.springframework.stereotype.Component; + +@Component +public class CustomBeforeSendCallback implements SentryOptions.BeforeSendCallback { + @Override + public SentryEvent execute(SentryEvent event, Object hint) { + event.setServerName(null); + return event; + } +} +``` + +#### Registering Custom Before Breadcrumb Callback + +A Spring bean implementing `BeforeBreadcrumbCallback` will be automatically set on `SentryOptions` during Sentry SDK auto-configuration. Note that there can be only single bean like that. + +```java +import io.sentry.Breadcrumb; +import io.sentry.SentryOptions; +import org.springframework.stereotype.Component; + +@Component +public class CustomBeforeBreadcrumbCallback implements SentryOptions.BeforeBreadcrumbCallback { + + @Override + public Breadcrumb execute(Breadcrumb breadcrumb, Object hint) { + // Don't add breadcrumbs with message containing: + if (breadcrumb.getMessage() != null + && breadcrumb.getMessage().contains("bad breadcrumb")) { + return null; + } + return breadcrumb; + } +} +``` + +## Using With Logging Framework Integration + +For the best experience we recommend using Sentry Spring Boot integration together with one of the logging framework integrations as they seamlessly work together. + +### Logback + +To use Sentry Logback integration in Spring Boot application you must include a dependency to `sentry-logback` module and Sentry Spring Boot Starter will auto-configure `SentryAppender`: + +```xml {tabTitle:Maven} + + io.sentry + sentry-logback + {{ packages.version('sentry.java', '3.0.0') }} + +``` + +```groovy {tabTitle:Gradle} +implementation 'io.sentry:sentry-logback:{{ packages.version('sentry.java', '3.0.0') }}' +``` + +Minimum logging levels for `SentryAppender` can be configured in `application.properties` or `application.yml` file. + +```properties +sentry.logging.minimum-event-level=info +sentry.logging.minimum-breadcrumb-level=debug +``` + +When `SentryAppender` auto-configuration does not suit your needs it can be turned off by setting: + +```properties +sentry.logging.enabled=false +``` + +If you decide to opt-out from `application.properties` based Spring Boot logging configuration and configure logging in `logback-spring.xml` file, `SentryAppender` can be configured in the following way: + +```xml + + + + + + + + + + + + +``` + + +Note that there is no need to configure DSN in Logback configuration file as Sentry gets configured via Spring Boot integration. + +However, if potential errors that appear during the startup are meant to be sent to Sentry, the DSN must be provided to both Logback and Spring Boot configuration. + + +### Log4j2 + +To use Sentry Log4j2 integration in Spring Boot application, [follow the guide on configuring Log4j2 with Spring Boot](https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-configure-log4j-for-logging) and configure `SentryAppender` in `log4j2.xml` file: + +```xml + + + + + + + + + + + + + + + +``` + + +Note that there is no need to configure DSN in Log4j2 configuration file as Sentry gets configured via Spring Boot integration. + +However, if potential errors that appear during the startup are meant to be sent to Sentry, the DSN must be provided to both Log4j2 and Spring Boot configuration. + diff --git a/src/platforms/java/guides/spring/index.mdx b/src/platforms/java/guides/spring/index.mdx index 4018e3ea53cf56..2d13c8cedfb558 100644 --- a/src/platforms/java/guides/spring/index.mdx +++ b/src/platforms/java/guides/spring/index.mdx @@ -4,7 +4,18 @@ redirect_from: - /platforms/java/guides/spring/config/ --- -The `sentry-spring` library provides [Spring](https://spring.io/) support for Sentry via a [HandlerExceptionResolver](https://docs.spring.io/spring/docs/4.3.9.RELEASE/javadoc-api/org/springframework/web/servlet/HandlerExceptionResolver.html) that sends exceptions to Sentry. Once this integration is configured you can _also_ use Sentry’s static API, [as shown on the usage page](usage/), in order to do things like record breadcrumbs, set the current user, or manually send events. +The `sentry-spring` library provides [Spring MVC](https://spring.io/) support for Sentry via: + +- a [HandlerExceptionResolver](https://docs.spring.io/spring/docs/4.3.9.RELEASE/javadoc-api/org/springframework/web/servlet/HandlerExceptionResolver.html) that sends unhandled exceptions to Sentry. +- attaches HTTP request information to all `SentryEvent`s recorded within the scope of the request +- adds option to attach user information retrieved from HTTP request to all `SentryEvent`s recorded within the scope of the request +- adds a `SentryUserProvider` hook that can be used to provide additional user information + +Once this integration is configured you can _also_ use Sentry’s static API, [as shown on the usage page](usage/), in order to do things like record breadcrumbs, set the current user, or manually send events. + + + To use Sentry with Spring Boot, we recommend using Sentry Spring Boot integration as it provides richer configuration capabilities. + The source can be found [on GitHub](https://github.com/getsentry/sentry-java/tree/master/sentry-spring). @@ -14,62 +25,96 @@ The source can be found [on GitHub](https://github.com/getsentry/sentry-java/tre io.sentry sentry-spring - {{ packages.version('sentry.java', '1.7.30') }} + {{ packages.version('sentry.java', '3.0.0') }} ``` ```groovy {tabTitle:Gradle} -implementation 'io.sentry:sentry-spring:{{ packages.version('sentry.java', '1.7.30') }}' +implementation 'io.sentry:sentry-spring:{{ packages.version('sentry.java', '3.0.0') }}' ``` ```scala {tabTitle: SBT} -libraryDependencies += "io.sentry" % "sentry-spring" % "{{ packages.version('sentry.java', '1.7.30') }}" +libraryDependencies += "io.sentry" % "sentry-spring" % "{{ packages.version('sentry.java', '3.0.0') }}" ``` For other dependency managers see the [central Maven repository](https://search.maven.org/artifact/io.sentry/sentry-spring). ### Usage -The `sentry-spring` library provides two classes that can be enabled by registering them as Beans in your Spring application. +The `sentry-spring` library provides `@EnableSentry` annotation that registers all required Spring beans. `@EnableSentry` can be places on any class annotated with [@Configuration](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html) including main entry class in Spring Boot applications annotated with [@SpringBootApplication](https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/SpringBootApplication.html). -#### Recording Exceptions +```java {tabTitle:Java} +import io.sentry.spring.EnableSentry; +// NOTE: Replace the test DSN below with YOUR OWN DSN to see the events from this app in your Sentry +// project/dashboard +@EnableSentry(dsn = "___PUBLIC_DSN___") +@Configuration +class SentryConfiguration { +} +``` -In order to record all exceptions thrown by your controllers, you can register `io.sentry.spring.SentryExceptionResolver` as a Bean in your application. Once registered, all exceptions will be sent to Sentry and then passed on to the default exception handlers. +```kotlin {tabTitle:Kotlin} +import io.sentry.spring.EnableSentry +// NOTE: Replace the test DSN below with YOUR OWN DSN to see the events from this app in your Sentry +// project/dashboard +@EnableSentry(dsn = "___PUBLIC_DSN___") +@Configuration +class SentryConfiguration +``` -Configuration via `web.xml`: +The DSN can be also proided through the system property `sentry.dsn`, environment variable `SENTRY_DSN` or the `dsn` property in `sentry.properties` file. [See the configuration page](/platforms/java/configuration/) for more details on external configuration. -```xml - -``` +#### Recording User Information From HTTP Request -Or via a configuration class: +In order to record user's IP address and `Principal#name` as the username, sending personal information flag has to be set to `true`. -```java -@Bean -public HandlerExceptionResolver sentryExceptionResolver() { - return new io.sentry.spring.SentryExceptionResolver(); +```Java {tabTitle:Java} +import io.sentry.spring.EnableSentry; + +@EnableSentry(dsn = "___PUBLIC_DSN___", sendDefaultPii = true) +@Configuration +class SentryConfiguration { } ``` -Next, **you’ll need to configure your DSN** (client key) and optionally other values such as `environment` and `release`. [See the configuration page](configuration/options/#setting-the-dsn) for ways you can do this. - -#### Spring Boot HTTP Data +```kotlin {tabTitle:Kotlin} +import io.sentry.spring.EnableSentry -Spring Boot doesn’t automatically load any `javax.servlet.ServletContainerInitializer`, which means the Sentry SDK doesn’t have an opportunity to hook into the request cycle to collect information about the HTTP request. In order to add HTTP request data to your Sentry events in Spring Boot, you need to register the `io.sentry.spring.SentryServletContextInitializer` class as a Bean in your application. +@EnableSentry(dsn = "...", sendDefaultPii = true) +@Configuration +class SentryConfiguration +``` -Configuration via `web.xml`: +#### Recording Custom User Information -```xml - -``` +In order to record custom user information, you care register a bean that implements `SentryUserProvider` interface. -Or via a configuration class: +```java {tabTitle:Java} +import org.springframework.stereotype.Component; +import io.sentry.core.protocol.User; +import io.sentry.spring.SentryUserProvider; -```java -@Bean -public ServletContextInitializer sentryServletContextInitializer() { - return new io.sentry.spring.SentryServletContextInitializer(); +@Component +class CustomSentryUserProvider implements SentryUserProvider { + public User provideUser() { + User user = User(); + // ... set user information + return user + } } ``` -After that, your Sentry events should contain information such as HTTP request headers. +```kotlin {tabTitle:Kotlin} +import org.springframework.stereotype.Component +import io.sentry.core.protocol.User +import io.sentry.spring.SentryUserProvider + +@Component +class CustomSentryUserProvider : SentryUserProvider { + override fun provideUser(): User? { + val user = User() + // ... set user information + return user + } +} +``` diff --git a/src/platforms/java/usage.mdx b/src/platforms/java/usage.mdx index 4da37453ed0ae4..bd91ba93912332 100644 --- a/src/platforms/java/usage.mdx +++ b/src/platforms/java/usage.mdx @@ -11,211 +11,331 @@ redirect_from: io.sentry sentry - 1.7.30 + 3.0.0 ``` ```groovy {tabTitle:Gradle} -implementation 'io.sentry:sentry:1.7.30' +implementation 'io.sentry:sentry:3.0.0' ``` ```scala {tabTitle:SBT} -libraryDependencies += "io.sentry" % "sentry" % "1.7.30" +libraryDependencies += "io.sentry" % "sentry" % "3.0.0" ``` For other dependency managers see the [central Maven repository](https://search.maven.org/artifact/io.sentry/sentry-spring). -## Capture an Error +## Configuration -To report an event manually you need to initialize a `SentryClient`. It is recommended that you use the static API via the `Sentry` class, but you can also construct and manage your own `SentryClient` instance. An example of each style is shown below: +When Sentry is used in manual way, configuration options must be passed to a static `Sentry#init` method: -```java -import io.sentry.context.Context; -import io.sentry.event.BreadcrumbBuilder; -import io.sentry.event.UserBuilder; +```java {tabTitle:Java} +import io.sentry.Sentry; public class MyClass { - private static SentryClient sentry; - - public static void main(String... args) { - /* - It is recommended that you use the DSN detection system, which - will check the environment variable "SENTRY_DSN", the Java - System Property "sentry.dsn", or the "sentry.properties" file - in your classpath. This makes it easier to provide and adjust - your DSN without needing to change your code. See the configuration - page for more information. - - For example, using an environment variable - - export SENTRY_DSN="___PUBLIC_DSN___" - */ - Sentry.init(); - - // You can also manually provide the DSN to the ``init`` method. - // Sentry.init("___PUBLIC_DSN___"); - - /* - It is possible to go around the static ``Sentry`` API, which means - you are responsible for making the SentryClient instance available - to your code. - */ - sentry = SentryClientFactory.sentryClient(); - - MyClass myClass = new MyClass(); - myClass.logWithStaticAPI(); - myClass.logWithInstanceAPI(); - } + public static void main(String... args) { + Sentry.init( + options -> { + // NOTE: Replace the test DSN below with YOUR OWN DSN to see the events from this app in + // your Sentry project/dashboard + options.setDsn("https://f7f320d5c3a54709be7b28e0f2ca7081@sentry.io/1808954"); + + // All events get assigned to the release. See more at + // https://docs.sentry.io/workflow/releases/ + options.setRelease("io.sentry.samples.console@3.0.0+1"); + + // Modifications to event before it goes out. Could replace the event altogether + options.setBeforeSend( + (event, hint) -> { + // Drop an event altogether: + if (event.getTag("SomeTag") != null) { + return null; + } + return event; + }); + + // Allows inspecting and modifying, returning a new or simply rejecting (returning null) + options.setBeforeBreadcrumb( + (breadcrumb, hint) -> { + // Don't add breadcrumbs with message containing: + if (breadcrumb.getMessage() != null + && breadcrumb.getMessage().contains("bad breadcrumb")) { + return null; + } + return breadcrumb; + }); + + // Configure the background worker which sends events to sentry: + // Wait up to 5 seconds before shutdown while there are events to send. + options.setShutdownTimeout(5000); + + // Enable SDK logging with Debug level + options.setDebug(true); + // To change the verbosity, use: + // By default it's DEBUG. + options.setDiagnosticLevel( + SentryLevel + .ERROR); // A good option to have SDK debug log in prod is to use only level + // ERROR here. + + // Exclude frames from some packages from being "inApp" so are hidden by default in Sentry + // UI: + options.addInAppExclude("org.jboss"); + }); + } +} +``` - /** - * An example method that throws an exception. - */ - void unsafeMethod() { - throw new UnsupportedOperationException("You shouldn't call this!"); - } +```kotlin {tabTitle:Kotlin} +import io.sentry.SentryOptions.BeforeBreadcrumbCallback +import io.sentry.SentryOptions.BeforeSendCallback + +fun main() { + Sentry.init { + // NOTE: Replace the test DSN below with YOUR OWN DSN to see the events from this app in + // your Sentry project/dashboard + it.dsn = "https://f7f320d5c3a54709be7b28e0f2ca7081@sentry.io/1808954" + + // All events get assigned to the release. See more at + // https://docs.sentry.io/workflow/releases/ + it.release = "io.sentry.samples.console@3.0.0+1" + + // Modifications to event before it goes out. Could replace the event altogether + it.beforeSend = BeforeSendCallback { event: SentryEvent, hint: Any? -> + // Drop an event altogether: + if (event.getTag("SomeTag") != null) { + null + } else { + event + } + } - /** - * Examples using the (recommended) static API. - */ - void logWithStaticAPI() { - // Note that all fields set on the context are optional. Context data is copied onto - // all future events in the current context (until the context is cleared). - - // Record a breadcrumb in the current context. By default the last 100 breadcrumbs are kept. - Sentry.getContext().recordBreadcrumb( - new BreadcrumbBuilder().setMessage("User made an action").build() - ); - - // Set the user in the current context. - Sentry.getContext().setUser( - new UserBuilder().setEmail("hello@sentry.io").build() - ); - - // Add extra data to future events in this context. - Sentry.getContext().addExtra("extra", "thing"); - - // Add an additional tag to future events in this context. - Sentry.getContext().addTag("tagName", "tagValue"); - - /* - This sends a simple event to Sentry using the statically stored instance - that was created in the ``main`` method. - */ - Sentry.capture("This is a test"); - - try { - unsafeMethod(); - } catch (Exception e) { - // This sends an exception event to Sentry using the statically stored instance - // that was created in the ``main`` method. - Sentry.capture(e); + // Allows inspecting and modifying, returning a new or simply rejecting (returning null) + it.beforeBreadcrumb = BeforeBreadcrumbCallback { breadcrumb: Breadcrumb, hint: Any? -> + // Don't add breadcrumbs with message containing: + val message = breadcrumb.message + if (message != null && message.contains("bad breadcrumb")) { + null + } else { + breadcrumb + } } + + // Configure the background worker which sends events to sentry: + // Wait up to 5 seconds before shutdown while there are events to send. + it.shutdownTimeout = 5000 + + // Enable SDK logging with Debug level + it.isDebug = true + // To change the verbosity, use: + // By default it's DEBUG. + it.setDiagnosticLevel( + SentryLevel.ERROR) // A good option to have SDK debug log in prod is to use only level + // ERROR here. + + // Exclude frames from some packages from being "inApp" so are hidden by default in Sentry + // UI: + it.addInAppExclude("org.jboss") } +} +``` - /** - * Examples that use the SentryClient instance directly. - */ - void logWithInstanceAPI() { - // Retrieve the current context. - Context context = sentry.getContext(); +Find more configuration options in the [Configuration](/platforms/java/configuration/) section. - // Record a breadcrumb in the current context. By default the last 100 breadcrumbs are kept. - context.recordBreadcrumb(new BreadcrumbBuilder().setMessage("User made an action").build()); +## Capture an Error - // Set the user in the current context. - context.setUser(new UserBuilder().setEmail("hello@sentry.io").build()); +To report an event manually you need to initialize a `Sentry` class. It is recommended that you use the static API via the `Sentry` class, but you can also construct and manage your own `IHub` instance. An example of each style is shown below: - // This sends a simple event to Sentry. - sentry.sendMessage("This is a test"); +```java +import io.sentry.HubAdapter; +import io.sentry.IHub; +import io.sentry.Sentry; +import io.sentry.protocol.User; - try { - unsafeMethod(); - } catch (Exception e) { - // This sends an exception event to Sentry. - sentry.sendException(e); - } +public class MyClass { + private static IHub hub; + + public static void main(String... args) { + // NOTE: Replace the test DSN below with YOUR OWN DSN + Sentry.init(options -> { + options.setDsn("https://f7f320d5c3a54709be7b28e0f2ca7081@sentry.io/1808954"); + }); + + /* + It is possible to go around the static Sentry API, which means + you are responsible for making the IHub instance available + to your code. + */ + hub = HubAdapter.getInstance(); + + MyClass myClass = new MyClass(); + myClass.logWithStaticAPI(); + myClass.logWithInstanceAPI(); + } + + /** + * An example method that throws an exception. + */ + void unsafeMethod() { + throw new UnsupportedOperationException("You shouldn't call this!"); + } + + /** + * Examples using the (recommended) static API. + */ + void logWithStaticAPI() { + // Note that all fields set on the scope are optional. Scope data is copied onto + // all future events in the current scope (until the scope is cleared). + + // Record a breadcrumb in the current scope. By default the last 100 breadcrumbs are kept. + Sentry.addBreadcrumb("User made an action"); + + // Set the user in the current scope. + Sentry.configureScope(scope -> { + User user = new User(); + user.setEmail("hello@sentry.io"); + scope.setUser(user); + }); + + // Add extra data to future events in this scope. + Sentry.configureScope(scope -> { + scope.setExtra("extra", "thing"); + }); + + // Add an additional tag to future events in this scope. + Sentry.configureScope(scope -> { + scope.setTag("tagName", "tagValue"); + }); + + /* + This sends a simple event to Sentry using the statically stored instance + that was created in the ``main`` method. + */ + Sentry.captureMessage("This is a test"); + + try { + unsafeMethod(); + } catch (Exception e) { + // This sends an exception event to Sentry using the statically stored instance + // that was created in the ``main`` method. + Sentry.captureException(e); } + } + + /** + * Examples that use the SentryClient instance directly. + */ + void logWithInstanceAPI() { + + // Record a breadcrumb in the current scope. By default the last 100 breadcrumbs are kept. + hub.addBreadcrumb("User made an action"); + + // Set the user in the current scope. + hub.configureScope(scope -> { + User user = new User(); + user.setEmail("hello@sentry.io"); + scope.setUser(user); + }); + + // This sends a simple event to Sentry. + hub.captureMessage("This is a test"); + + try { + unsafeMethod(); + } catch (Exception e) { + // This sends an exception event to Sentry. + hub.captureException(e); + } + } } ``` ### Building More Complex Events -For more complex messages, you’ll need to build an `Event` with the `EventBuilder` class: +For more complex messages, you’ll need to build an `SentryEvent` object: ```java import io.sentry.Sentry; - import io.sentry.event.Event; - import io.sentry.event.EventBuilder; - import io.sentry.event.interfaces.ExceptionInterface; - - public class MyClass { - public static void main(String... args) { - Sentry.init(); - } - - void unsafeMethod() { - throw new UnsupportedOperationException("You shouldn't call this!"); - } - - void logSimpleMessage() { - // This sends an event to Sentry. - EventBuilder eventBuilder = new EventBuilder() - .withMessage("This is a test") - .withLevel(Event.Level.INFO) - .withLogger(MyClass.class.getName()); - - // Note that the *unbuilt* EventBuilder instance is passed in so that - // EventBuilderHelpers are run to add extra information to your event. - Sentry.capture(eventBuilder); - } - - void logException() { - try { - unsafeMethod(); - } catch (Exception e) { - // This sends an exception event to Sentry. - EventBuilder eventBuilder = new EventBuilder() - .withMessage("Exception caught") - .withLevel(Event.Level.ERROR) - .withLogger(MyClass.class.getName()) - .withSentryInterface(new ExceptionInterface(e)); - - // Note that the *unbuilt* EventBuilder instance is passed in so that - // EventBuilderHelpers are run to add extra information to your event. - Sentry.capture(eventBuilder); - } - } +import io.sentry.SentryEvent; +import io.sentry.SentryLevel; +import io.sentry.protocol.Message; + +public class MyClass { + public static void main(String... args) { + // NOTE: Replace the test DSN below with YOUR OWN DSN + Sentry.init(options -> { + options.setDsn("https://f7f320d5c3a54709be7b28e0f2ca7081@sentry.io/1808954"); + }); + } + + void unsafeMethod() { + throw new UnsupportedOperationException("You shouldn't call this!"); + } + + void logSimpleMessage() { + // This sends an event to Sentry. + SentryEvent event = new SentryEvent(); + Message message = new Message(); + message.setMessage("This is a test"); + event.setMessage(message); + event.setLevel(SentryLevel.INFO); + event.setLogger(MyClass.class.getName()); + + Sentry.captureEvent(event); + } + + void logException() { + try { + unsafeMethod(); + } catch (Exception e) { + // This sends an exception event to Sentry. + SentryEvent event = new SentryEvent(); + Message message = new Message(); + message.setMessage("Exception caught"); + event.setMessage(message); + event.setLevel(SentryLevel.INFO); + event.setLogger(MyClass.class.getName()); + event.setThrowable(e); + + Sentry.captureEvent(event); + } + } } ``` ### Automatically Enhancing Events -You can also implement an `EventBuilderHelper` that is able to automatically enhance outgoing events. +You can also implement an `EventProcesor` that is able to automatically enhance outgoing events. ```java +import io.sentry.EventProcessor; +import io.sentry.HubAdapter; +import io.sentry.IHub; import io.sentry.Sentry; -import io.sentry.SentryClient; -import io.sentry.event.EventBuilder; -import io.sentry.event.helper.EventBuilderHelper; +import io.sentry.SentryEvent; +import io.sentry.protocol.Message; public class MyClass { - public void myMethod() { - SentryClient client = Sentry.getStoredClient(); - - EventBuilderHelper myEventBuilderHelper = new EventBuilderHelper() { - @Override - public void helpBuildingEvent(EventBuilder eventBuilder) { - eventBuilder.withMessage("Overwritten by myEventBuilderHelper!"); - } - }; - - // Add an ``EventBuilderHelper`` to the current client instance. Note that - // this helper will process *all* future events. - client.addBuilderHelper(myEventBuilderHelper); + public void myMethod() { + IHub hub = HubAdapter.getInstance(); + + // Add an `EventProcessor` to the current scope. Note that + // this helper will process *all* future events in this scope. + hub.configureScope(scope -> { + scope.addEventProcessor(new EventProcessor() { + @Override + public SentryEvent process(SentryEvent event, Object hint) { + Message message = new Message(); + message.setMessage("Overwritten by myEventBuilderHelper!"); + event.setMessage(message); + return event; + } + }); + }); - // Send an event to Sentry. During construction of the event the message - // body will be overwritten by ``myEventBuilderHelper``. - Sentry.capture("Hello, world!"); - } + // Send an event to Sentry. During construction of the event the message + // body will be overwritten by `myEventBuilderHelper`. + hub.captureMessage("Hello, world!"); + } } ``` From 1ae53c746626321898b2490afab6662e300301d8 Mon Sep 17 00:00:00 2001 From: Bruno Garcia Date: Wed, 30 Sep 2020 11:19:14 -0400 Subject: [PATCH 12/20] Android: Current migration on top (#2396) --- src/platforms/android/migration.mdx | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/platforms/android/migration.mdx b/src/platforms/android/migration.mdx index 76d86b859df6f3..afe98213444b26 100644 --- a/src/platforms/android/migration.mdx +++ b/src/platforms/android/migration.mdx @@ -3,6 +3,19 @@ title: Migration Guide sidebar_order: 1000 --- +## Migrating from `sentry-android 2.x` to `sentry-android 3.x` + +**Package changes** + +The package `io.sentry.core` has been renamed to `io.sentry`. To compile correctly, replace the strings on all the usages from `io.sentry.core.` to `io.sentry.` + +Other than that, the APIs didn't change. Release Heath sets by default. If you prefer not to track the health of your releases, disable it with: + +```xml + + + + ## Migrating from `sentry-android 1.x` to `sentry-android 2.x` With Sentry Android, we've updated the API to resemble the [Unified API](https://develop.sentry.dev/sdk/unified-api/) more closely. And now that the SDK isn't built on top of `sentry-java`, Sentry Android has more Android-specific features. @@ -160,16 +173,3 @@ _New_: ```java Sentry.setExtra("extra", "thing"); ``` - -## Migrating from `sentry-android 2.x` to `sentry-android 3.x` - -**Package changes** - -The package `io.sentry.core` has been renamed to `io.sentry`. To compile correctly, replace the strings on all the usages from `io.sentry.core.` to `io.sentry.` - -Other than that, the APIs didn't change. Release Heath sets by default. If you prefer not to track the health of your releases, disable it with: - -```xml - - - From ab4c50b27aa6e3369ad15e71e6d6ddb1386eaaa9 Mon Sep 17 00:00:00 2001 From: Anton Ovchinnikov Date: Wed, 30 Sep 2020 19:23:40 +0200 Subject: [PATCH 13/20] relay: Next iteration of refactoring (#2365) --- src/docs/product/relay/getting-started.mdx | 98 +++++++++---------- src/docs/product/relay/index.mdx | 4 +- src/docs/product/relay/metrics.mdx | 55 ----------- .../relay/monitoring/collected-metrics.mdx | 11 +++ src/docs/product/relay/monitoring/index.mdx | 71 ++++++++++++++ ...practices.mdx => operating-guidelines.mdx} | 64 +++++++++++- src/docs/product/relay/options.mdx | 3 +- 7 files changed, 193 insertions(+), 113 deletions(-) delete mode 100644 src/docs/product/relay/metrics.mdx create mode 100644 src/docs/product/relay/monitoring/collected-metrics.mdx create mode 100644 src/docs/product/relay/monitoring/index.mdx rename src/docs/product/relay/{best-practices.mdx => operating-guidelines.mdx} (50%) diff --git a/src/docs/product/relay/getting-started.mdx b/src/docs/product/relay/getting-started.mdx index 9b8abb21c9bb7d..114843b3220c77 100644 --- a/src/docs/product/relay/getting-started.mdx +++ b/src/docs/product/relay/getting-started.mdx @@ -21,7 +21,7 @@ Releases](https://github.com/getsentry/relay/releases). A Docker image is provid To create the initial configuration, use Relay's `relay config init` command, which puts configuration files in the `.relay` folder under the current working -directory. +directory. @@ -33,6 +33,14 @@ container and copying in the files. ```shell {tabTitle:Run in Docker} +# Adjust permissions for the configuration directory +docker run --rm -it \ + -v $(pwd)/config/:/work/.relay/ \ + --entrypoint bash \ + getsentry/relay \ + -c 'chown -R relay:relay /work/.relay' + +# Generate the configuration docker run --rm -it \ -v $(pwd)/config/:/work/.relay/ \ getsentry/relay \ @@ -66,7 +74,18 @@ _"create custom config"_ and customizing these parameters: Settings are recorded in `.relay/config.yml`. Note that all configuration values are optional and default to these settings: -```yaml +```yaml {tabTitle:Run in Docker} +relay: + mode: managed + upstream: "https://sentry.io/" + host: 0.0.0.0 + port: 3000 + tls_port: ~ + tls_identity_path: ~ + tls_identity_password: ~ +``` + +```yaml {tabTitle:Run Executable} relay: mode: managed upstream: "https://sentry.io/" @@ -96,7 +115,7 @@ A typical credentials file is similar to this example: ```json { "secret_key": "5gkTAfwOrJ0lMy9aOAOmHKO1k6gd8ApYkAInmg5VfWk", - "public_key": "fQzvlvqLM2pJwLDwM_sXD2Lk5swzx-Oml4WhsOquon4", + "public_key": "nDJI79SbEYH9-8NEJAI7ezrgYfoIPW3Bnkg00k1z0fA", "id": "cde0d72e-0c4e-4550-a934-c1867d8a177c" } ``` @@ -144,10 +163,6 @@ This process registers Relay with Sentry so it is ready to send messages. See ## Running Relay -You can either run the Relay binary directly or using a Docker image. - -### Running Relay Directly - After registering Relay with Sentry, it is ready to run: ```shell {tabTitle:Run in Docker} @@ -167,17 +182,19 @@ Under default configuration, Relay emits log output similar to: ``` INFO relay::setup > launching relay from config folder .relay INFO relay::setup > relay mode: managed - INFO relay::setup > relay id: f2119bc9-9a9b-4531-826b-24e9794902f2 - INFO relay::setup > public key: QPBITKKtKUuEZGGbPke8iufEXAcVrEv6nmWrkRtc3l8 + INFO relay::setup > relay id: cde0d72e-0c4e-4550-a934-c1867d8a177c + INFO relay::setup > public key: nDJI79SbEYH9-8NEJAI7ezrgYfoIPW3Bnkg00k1z0fA ... INFO relay_server::actors::upstream > relay successfully registered with upstream ``` +Refer to the [Logging](/product/relay/monitoring/#logging) page for more information on how to configure Relay's logging. + If you moved your config folder (for example, for security reasons), use the `--config` option to specify the location: ```shell {tabTitle:Run in Docker} docker run --rm -it \ - -v $(pwd)/config/:/work/.relay/ \ + -v $(pwd)/config/:/etc/relay/ \ -p 3000:3000 \ getsentry/relay \ run --config /etc/relay/ @@ -187,66 +204,41 @@ docker run --rm -it \ ./relay run --config /etc/relay/ ``` -## Logging - -Once Relay is running, you will receive `INFO` messages, such as: - -``` -INFO relay::setup > launching relay from config folder .relay -INFO relay::setup > relay mode: managed -INFO relay::setup > relay id: f2119bc9-9a9b-4531-826b-24e9794902f2 -INFO relay::setup > log level: INFO -``` - -This example displays the default logging level, which you can modify so it displays either more or less information. For details about configuring logging please see [Logging](/product/relay/options/#logging) on the options page. - -## Health Checks - -Relay provides two URLs for checking system status: - -- `GET /api/relay/healthcheck/live/`: Tests if Relay is running and listening to - HTTP requests. -- `GET /api/relay/healthcheck/ready/`: Tests if Relay is authenticated with the - upstream and operating normally. - -In case of success, both endpoints return a _200 OK_ response: - -```json -{ - "is_healthy": true -} -``` - ## Sending a Test Event -Once Relay is running and authenticated with Sentry, send a test event. +Once Relay is running and authenticated with Sentry, send a test event to one of the projects in your organization. -Get the DSN of your project by navigating to _Project Settings > Client Keys -(DSN)_, which looks similar to: +Get the DSN of your project by navigating to your project settings at _Settings > Projects > {YOUR_PROJECT_NAME} > Client Keys (DSN)_, and select one of the existing DSNs, which looks similar to: -``` -https://12345abcdb1e4c123490ecec89c1f199@o1.ingest.sentry.io/2244 -``` +`https://12345abcdef10111213141516171819@o1.ingest.sentry.io/2345` Next, replace parts of the DSN to match the address at which Relay is reachable. For instance, if Relay listens at `http://localhost:3000`, change the protocol and host of the DSN to: -``` -http://12345abcdb1e4c123490ecec89c1f199@localhost:3000/2244 -``` +

+ + http + ://12345abcdef10111213141516171819@ + localhost:3000 + /2345 + +

Use the new DSN in your SDK configuration. To test this, you can send a message -with `sentry-cli`: +with `sentry-cli` ([installation instructions](/cli/installation/)): ```shell -export SENTRY_DSN='http://12345abcdb1e4c123490ecec89c1f199@127.0.0.1:3000/2244' +export SENTRY_DSN='http://12345abcdef10111213141516171819@127.0.0.1:3000/2345' sentry-cli send-event -m 'A test event' ``` In a few seconds, the event should appear in the issues stream in your project. -## Advanced Configuration - +## Next Steps + +- **[Learn more about our Operating Guidelines](/product/relay/operating-guidelines/)** + +With a working Relay instance, you can both monitor and scale your Relay setup. diff --git a/src/docs/product/relay/index.mdx b/src/docs/product/relay/index.mdx index db9a1487bb82f3..c49638112350ea 100644 --- a/src/docs/product/relay/index.mdx +++ b/src/docs/product/relay/index.mdx @@ -10,7 +10,7 @@ Sentry Relay offers enterprise-grade data security by providing a standalone ser Relay is specifically designed to: -- Scrub personal information in a central place prior to sending it to Sentry, adding to the places Sentry already scrubs PII +- Scrub personally identifiable information (PII) in a central place prior to sending it to Sentry - Improve event response time in regions with low bandwidth or limited connectivity - Act as an opaque proxy for organizations that restrict all HTTP communication to a custom domain name @@ -63,6 +63,6 @@ Relay responds very quickly to requests. Installing Relay close to your infrastr By default, SDKs need to be configured with a Data Source Name (DSN) that points to `sentry.io`. If you need to restrict all HTTP communication to a custom domain name, Relay can act as an opaque proxy that reliably forwards events to Sentry. -## Configuration +## Next Steps diff --git a/src/docs/product/relay/metrics.mdx b/src/docs/product/relay/metrics.mdx deleted file mode 100644 index 528dbccc071355..00000000000000 --- a/src/docs/product/relay/metrics.mdx +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: Errors and Metrics -description: "Enable error reporting to your project in Sentry." -sidebar_order: 3 -redirect_from: - - /meta/relay/metrics/ ---- -By default, Relay logs errors to the configured logger. You can enable error -reporting to your project in Sentry in the Relay configuration file: - -```yaml -sentry: - enabled: true - dsn: -``` - -## Configuration - -Stats can be submitted to a StatsD server by configuring the `metrics` key. The key -can be set to an `ip:port` tuple: - -```yaml -metrics: - statsd: 127.0.0.1:8126 - prefix: mycompany.relay -``` - -`statsd` - -: Configures the host and port of the StatsD client. We recommend running a - StatsD client on the same host as Relay for performance reasons. - -`prefix` - -: Configures a prefix that is prepended to all reported metrics. By default, all - metrics are reported with a `"sentry.relay"` prefix. - -`hostname_tag` - -: Adds a tag of the given name and sets it to the hostname of the machine that - is running Relay. This configuration is useful to separate multiple Relays. For example, setting this to: - - ```yaml - metrics: - hostname_tag: pod_name - ``` - - The above example adds a `"pod_name"` tag set to the host name for - every metric. - -## Metrics - -Relay emits the following metrics: - - diff --git a/src/docs/product/relay/monitoring/collected-metrics.mdx b/src/docs/product/relay/monitoring/collected-metrics.mdx new file mode 100644 index 00000000000000..43914f96d7b7f5 --- /dev/null +++ b/src/docs/product/relay/monitoring/collected-metrics.mdx @@ -0,0 +1,11 @@ +--- +title: Collected Metrics +description: "Learn what metrics Relay produces." +sidebar_order: 3 +redirect_from: + - /meta/relay/metrics/ +--- + +Relay collects the following metrics: + + diff --git a/src/docs/product/relay/monitoring/index.mdx b/src/docs/product/relay/monitoring/index.mdx new file mode 100644 index 00000000000000..4042c6befb408c --- /dev/null +++ b/src/docs/product/relay/monitoring/index.mdx @@ -0,0 +1,71 @@ +--- +title: Monitoring +description: "Configure logging, metrics, and error reporting for your Relay installation." +sidebar_order: 3 +redirect_from: + - /meta/relay/logging/ +--- +## Logging + +Relay produces logs to the standard error stream (`stderr`), with `INFO` logging level by default. +For example, after starting Relay you may see output such as this: + +``` +INFO relay::setup > launching relay from config folder .relay +INFO relay::setup > relay mode: managed +INFO relay::setup > relay id: cde0d72e-0c4e-4550-a934-c1867d8a177c +INFO relay::setup > log level: INFO +``` + +This example displays the messages with the default logging level (`INFO`), which you can modify so it displays either more or less information. For details about configuring logging please see the [Logging](/product/relay/options/#logging) section on the options page. + +## Error Reporting + +By default, Relay logs errors to the configured logger. You can enable error +reporting to your project in Sentry in the Relay configuration file: + +```yaml +sentry: + enabled: true + dsn: +``` + +More information about available options and their meaning can be found [on the options page](/product/relay/options/#internal-error-reporting). + +## Health Checks + +Relay provides two URLs for checking system status: + +- `GET /api/relay/healthcheck/live/`: Tests if Relay is running and listening to + HTTP requests. +- `GET /api/relay/healthcheck/ready/`: Tests if Relay is authenticated with the + upstream and operating normally. + +Both endpoints return a _200 OK_ response when successful: + +```json +{ + "is_healthy": true +} +``` + +## Metrics + +You can submit stats to a StatsD server by configuring the `metrics.statsd` key to an `ip:port` tuple. +can be set to an `ip:port` tuple. + +### Example Configuration + +```yaml +metrics: + # Endpoint of your StatsD server + statsd: 127.0.0.1:8126 + # Prefix all metric names with this string + prefix: mycompany.relay +``` + +The options for configuring metrics reporting are documented on the [options page](/product/relay/options/#statsd-metrics). + +## Learn More + + diff --git a/src/docs/product/relay/best-practices.mdx b/src/docs/product/relay/operating-guidelines.mdx similarity index 50% rename from src/docs/product/relay/best-practices.mdx rename to src/docs/product/relay/operating-guidelines.mdx index 8b72bf08bb58bd..465ebc45aa488d 100644 --- a/src/docs/product/relay/best-practices.mdx +++ b/src/docs/product/relay/operating-guidelines.mdx @@ -4,6 +4,7 @@ description: "Learn about our guidelines for operation when self-hosting externa sidebar_order: 5 redirect_from: - /meta/relay/best-practices/ + - /product/relay/best-practices/ --- This page reviews our guidelines for operation when self-hosting external Relays, that is, Relays that run on your hardware and forward events to `sentry.io`. @@ -14,7 +15,7 @@ This page reviews our guidelines for operation when self-hosting external Relays - We recommend running at least two Relay instances (containers) with a reverse proxy (such as [HAProxy](https://www.haproxy.org/) or [Nginx](https://nginx.org)) in front of them for both improved availability and simplified Relay updates. -- To monitor your Relay setup, configure [Logging](/product/relay/#logging-and-healthcheck), [Metrics](/product/relay/metrics/), and [Health Checks](/product/relay/getting-started/#health-checks). +- To monitor your Relay setup, configure [Logging](/product/relay/monitoring/#logging), [Metrics](/product/relay/monitoring/#metrics), and [Health Checks](/product/relay/monitoring/#health-checks). ## System Requirements and Recommendations @@ -97,7 +98,7 @@ This example configuration sets up basic logging and metrics settings, as well a --- relay: # The upstream hostname is taken from any of your DSNs. - # Go to project Settings, and then to "Client Keys (DSN)" to see them. + # Go to your Project Settings, and then to "Client Keys (DSN)" to see them. upstream: https://o.ingest.sentry.io. host: 0.0.0.0 port: 3000 @@ -113,3 +114,62 @@ limits: ``` See the [Configuration Options](/product/relay/options/) page for detailed descriptions of all available options. + +## Performance Tuning + +Relay provides a variety of [Configuration Options](/product/relay/options/). Changing some of the options has more impact on Relay's behavior than others. +The following list identifies a few options you should check first when you want to tune Relay to your organization's environment and workload: + +- `limits.max_concurrent_requests` (default: 100) + + Number of concurrent requests your Relay instance can send to + the upstream (Sentry). If your event volume or connection latency to Sentry are high, you can increase this value to gain additional throughput, though that increase will be at the expense of additional network connections. + +- `cache.event_buffer_size` (default: 1000) + + How many events Relay can buffer in its local queue before it starts rejecting new events. + Increasing this value will also increase Relay's potential memory consumption when, for + example, network issues prevent Relay from forwarding the received messages to Sentry. + +- `cache.event_expiry` (in seconds, default: 600) + + How long Relay can keep buffered events in memory before dropping them. You can increase this value if you anticipate when your Relay may need to keep events in memory for longer than the default value. + +- `cache.project_expiry` (in seconds, default: 300) + +To stay operational, Relay regularly fetches project configurations from the Sentry upstream. This setting controls how often Relay fetches that configuration. You can decrease this value to make the configuration propagation more frequent. For example, if you later change data scrubbing options in your project settings in Sentry, your Relay instance will become aware of those changes faster. + +- `cache.project_grace_period` (in seconds, default: 0) + + How long a project configuration can still be used after having expired. + Increasing this value may help when the upstream is unreachable; for example, due to network issues. + +## Request Routing + +SDKs communicate with Sentry on a set of endpoints. Relay provides the same API to become a seamless drop-in replacement. This requires a set of endpoints to be accessible: + +- `/api//envelope/` +- `/api//minidump/` +- `/api//security/` +- `/api//store/` +- `/api//unreal/` + +Depending on the SDK or client, requests to these endpoints are performed with compressed content-encoding or chunked transfer-encoding. Depending on the infrastructure in front of Relay, please check the following HTTP headers are set correctly: + +- `Host`: to the public host name of this Relay +- `X-Forwarded-For`: to the client IP address +- `X-Sentry-Auth`: to the value provided by the client + + + +Proxies often set a default maximum body size for requests. Especially native crash reports and attachments can exceed these limits. We recommend to configure a maximum client body size of _100MB_. + + + +Internally, Relay makes requests to the configured upstream to forward data and retrieve project configuration. We **highly recommend against** constraining these requests. At present, Relay makes requests to the following endpoints for basic operation: + +- All of the above endpoints +- `/api/0/relays/projectconfigs/` +- `/api/0/relays/publickeys/` +- `/api/0/relays/register/challenge/` +- `/api/0/relays/register/response/` diff --git a/src/docs/product/relay/options.mdx b/src/docs/product/relay/options.mdx index 6e61716d7218b1..2b05e8574c7491 100644 --- a/src/docs/product/relay/options.mdx +++ b/src/docs/product/relay/options.mdx @@ -371,7 +371,8 @@ human-readable strings of a number and a human-readable unit, such as: : _String, optional_ - If set, reports the current hostname under the given tag name for all metrics. + If set, adds a tag of the given name and sets it to the hostname of the machine that + is running Relay. This configuration is useful to distinguish multiple Relays. ## Internal Error Reporting From 78c2e86e2e4cb253538d81898cc29b74dbed1ea6 Mon Sep 17 00:00:00 2001 From: AJ Date: Wed, 30 Sep 2020 13:20:17 -0700 Subject: [PATCH 14/20] version update --- src/platforms/python/guides/aws-lambda/index.mdx | 4 +--- src/platforms/python/guides/gcp-functions/index.mdx | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/platforms/python/guides/aws-lambda/index.mdx b/src/platforms/python/guides/aws-lambda/index.mdx index bcba9d2594f36e..c9caae1d28f4f8 100644 --- a/src/platforms/python/guides/aws-lambda/index.mdx +++ b/src/platforms/python/guides/aws-lambda/index.mdx @@ -5,7 +5,7 @@ redirect_from: - /platforms/python/aws_lambda/ --- -_(New in version 0.18.0)_ +_(New in version 0.3.5)_ Create a deployment package on your local machine and install the required dependencies in the deployment package. For more information, see [AWS Lambda deployment package in Python](https://docs.aws.amazon.com/lambda/latest/dg/python-package.html). @@ -32,8 +32,6 @@ def my_function(event, context): # ... ``` -Set `send_default_pii` to `True` to capture function payload. - Check out Sentry's [AWS sample apps](https://github.com/getsentry/examples/tree/master/aws-lambda/python) for detailed examples. diff --git a/src/platforms/python/guides/gcp-functions/index.mdx b/src/platforms/python/guides/gcp-functions/index.mdx index 01bee93fb19e11..6d1470df757dcf 100644 --- a/src/platforms/python/guides/gcp-functions/index.mdx +++ b/src/platforms/python/guides/gcp-functions/index.mdx @@ -4,7 +4,7 @@ redirect_from: - /platforms/python/gcp_functions/ --- -_(New in version 0.17.1)_ +_(New in version 0.17.0)_ ## Install @@ -32,7 +32,6 @@ sentry_sdk.init( def http_function_entrypoint(request): # ... ``` -Set `send_default_pii` to `True` to capture function payload. Check out Sentry's [GCP sample apps](https://github.com/getsentry/examples/tree/master/gcp-cloud-functions) for detailed examples. From 0d6f5b05abe21a181cd7a93d71cd976c5a0067fd Mon Sep 17 00:00:00 2001 From: David Cramer Date: Wed, 30 Sep 2020 13:30:53 -0700 Subject: [PATCH 15/20] feat: Add example of how to sample rrweb (#2398) Co-authored-by: Fiona <61481573+PeloWriter@users.noreply.github.com> --- .../javascript/common/integrations/rrweb.mdx | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/platforms/javascript/common/integrations/rrweb.mdx b/src/platforms/javascript/common/integrations/rrweb.mdx index 1ea505f494d960..0a227fad1255f4 100644 --- a/src/platforms/javascript/common/integrations/rrweb.mdx +++ b/src/platforms/javascript/common/integrations/rrweb.mdx @@ -48,3 +48,26 @@ For more information on configuration, see the [@sentry/rrweb project on GitHub]
Once a replay is captured with an event, you'll find it visible within Issue Details under the Replay section of the event. + +## Sampling + +To suit your organization's needs, you may prefer to sample replays. The easiest way to do this is to make the sampling decision when you initialize the Sentry SDK. For example, here's how Sentry itself uses sampling to capture these for only employees: + +```javascript +const hasReplays = getCurrentUser().isStaff; + +let integrations = []; +if (hasReplays) { + console.log("[sentry] Instrumenting session with rrweb"); + integrations.push(new SentryRRWeb()); +} + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + integrations, +}); + +Sentry.setTag("rrweb.active", hasReplays ? "yes" : "no"); +``` + +You'll note we also set the `rrweb.active` tag, which helps us identify events that have a replay attached, since otherwise we'd not be able to find them. Once configured, you'll be able simply use `rrweb.active:yes` in your search queries. From c5f52c65dc25ea866956872cbba976cc7d96830f Mon Sep 17 00:00:00 2001 From: David Cramer Date: Wed, 30 Sep 2020 13:33:16 -0700 Subject: [PATCH 16/20] feat: Improve Product Guides structure (#2399) - Expose dropdown for Product navigation - Move all product pages into /product/ - Re-order sidebar to push relevant (vs marketing/discovery) docs to the top --- src/api/permissions.mdx | 4 +- src/components/navbar.tsx | 10 ++-- src/components/navbarProductDropdown.tsx | 45 ++++++++++++++++++ src/components/sidebar.tsx | 23 +++++++-- src/docs/cli/index.mdx | 40 ---------------- src/docs/clients/javascript/sourcemaps.mdx | 2 +- src/docs/clients/react-native/codepush.mdx | 2 +- src/docs/enriching-error-data/breadcrumbs.mdx | 35 -------------- src/docs/product/accounts/index.mdx | 6 +++ .../accounts/membership-toggle.png | Bin .../{ => product}/accounts/membership.mdx | 0 src/docs/{ => product}/accounts/pricing.mdx | 4 +- .../{ => product}/accounts/quotas/index.mdx | 18 +++---- .../quotas/manage-event-stream-01.png | Bin .../quotas/manage-event-stream-02.png | Bin .../quotas/manage-event-stream-03.png | Bin .../quotas/manage-event-stream-04.png | Bin .../quotas/manage-event-stream-05.png | Bin .../quotas/manage-event-stream-06.png | Bin .../quotas/manage-event-stream-07.png | Bin .../quotas/manage-event-stream-08.png | Bin .../quotas/manage-event-stream-09.png | Bin .../quotas/manage-event-stream-10.png | Bin .../quotas/manage-event-stream-11.png | Bin .../quotas/manage-event-stream-12.png | Bin .../quotas/manage-event-stream-13.png | Bin .../quotas/manage-event-stream-14.png | Bin .../quotas/manage-event-stream-15.png | Bin .../quotas/manage-event-stream-16.png | Bin .../quotas/manage-event-stream-17.png | Bin .../quotas/manage-event-stream-guide.mdx | 6 +-- .../accounts/quotas/spike-email.jpg | Bin .../accounts/require-2fa-add-auth.png | Bin .../accounts/require-2fa-audit-log.png | Bin .../accounts/require-2fa-email.png | Bin .../accounts/require-2fa-members.png | Bin .../accounts/require-2fa-rejoin.png | Bin .../accounts/require-2fa-resend-invite.png | Bin .../accounts/require-2fa-switch.png | Bin .../{ => product}/accounts/require-2fa.mdx | 0 .../sso/azure-basic-saml-configuration.png | Bin ...azure-map-identity-provider-attributes.png | Bin .../sso/azure-saml-signing-certificate.png | Bin .../accounts/sso/azure-sentry-overview.png | Bin .../{ => product}/accounts/sso/azure-sso.mdx | 0 src/docs/{ => product}/accounts/sso/index.mdx | 2 +- .../accounts/sso/saml2-map-attributes.png | Bin .../accounts/sso/saml2-metadata-url.png | Bin .../accounts/sso/saml2-provider-data.png | Bin .../accounts/sso/saml2-provider-xml.png | Bin .../accounts/sso/saml2-success.png | Bin src/docs/{ => product}/accounts/sso/saml2.mdx | 0 .../accounts/user-settings/index.mdx | 0 .../accounts/user-settings/us-2fact.png | Bin .../accounts/user-settings/us-alert.png | Bin .../accounts/user-settings/us-apps.png | Bin .../accounts/user-settings/us-avatar.png | Bin .../accounts/user-settings/us-close.png | Bin .../accounts/user-settings/us-deploy.png | Bin .../accounts/user-settings/us-epanellink.png | Bin .../accounts/user-settings/us-eprime.png | Bin .../accounts/user-settings/us-ereport.png | Bin .../accounts/user-settings/us-eroute.png | Bin .../accounts/user-settings/us-id.png | Bin .../accounts/user-settings/us-lang.png | Bin .../accounts/user-settings/us-myact.png | Bin .../accounts/user-settings/us-name.png | Bin .../accounts/user-settings/us-npanellink.png | Bin .../accounts/user-settings/us-pass.png | Bin .../accounts/user-settings/us-rec.png | Bin .../accounts/user-settings/us-sess.png | Bin .../accounts/user-settings/us-shistory.png | Bin .../accounts/user-settings/us-sto.png | Bin .../accounts/user-settings/us-subs.png | Bin .../accounts/user-settings/us-time.png | Bin .../accounts/user-settings/us-token.png | Bin .../accounts/user-settings/us-work.png | Bin .../accounts/user-settings/us-wrfield.png | Bin .../product/alerts-notifications/alerts.mdx | 2 +- src/docs/{ => product}/cli/configuration.mdx | 0 src/docs/{ => product}/cli/dif.mdx | 6 +-- src/docs/product/cli/index.mdx | 41 ++++++++++++++++ src/docs/{ => product}/cli/installation.mdx | 0 src/docs/{ => product}/cli/releases.mdx | 2 +- src/docs/{ => product}/cli/send-event.mdx | 0 .../integrations/azure-devops/index.mdx | 2 +- .../product/integrations/bitbucket/index.mdx | 14 +++--- .../product/integrations/github/index.mdx | 8 ++-- .../product/integrations/gitlab/index.mdx | 4 +- src/docs/product/integrations/index.mdx | 37 +++++++------- src/docs/product/integrations/jira/index.mdx | 6 +-- .../performance/distributed-tracing.mdx | 2 +- src/docs/product/relay/getting-started.mdx | 21 ++++---- src/docs/product/relay/index.mdx | 2 +- src/docs/product/releases/index.mdx | 8 ++-- .../release-automation/circleci/index.mdx | 2 +- .../release-automation/jenkins/index.mdx | 2 +- .../release-automation/travis-ci/index.mdx | 2 +- src/docs/{meta => product/security}/index.md | 10 ++-- .../{meta => product/security}/ip-ranges.mdx | 0 .../security}/legal-and-compliance.png | Bin src/docs/{meta => product/security}/soc2.md | 0 src/docs/{meta => product/security}/ssl.mdx | 0 src/docs/{meta => product/security}/terms.md | 0 .../sentry-basics/guides/discover/index.mdx | 4 +- .../guides/getting-started/index.mdx | 8 ++-- .../configuration-options.mdx | 2 +- .../integrate-backend/getting-started.mdx | 4 +- .../integrate-frontend/upload-source-maps.mdx | 2 +- src/pages/index.tsx | 4 +- src/platforms/android/index.mdx | 6 +-- src/platforms/apple/common/dsym.mdx | 2 +- .../common/configuration/filtering.mdx | 2 +- .../common/configuration/options.mdx | 2 +- .../common/data-management/debug-files.mdx | 10 ++-- .../enriching-events/attachments/index.mdx | 2 +- .../common/sourcemaps/hosting-publicly.mdx | 2 +- .../javascript/common/sourcemaps/index.mdx | 4 +- .../common/sourcemaps/tools/webpack.mdx | 2 +- .../common/sourcemaps/uploading.mdx | 2 +- .../common/sourcemaps/validating.mdx | 2 +- .../javascript/guides/electron/index.mdx | 2 +- .../javascript/guides/react/index.mdx | 2 +- src/platforms/react-native/codepush.mdx | 2 +- vercel.json | 12 +++++ 125 files changed, 244 insertions(+), 202 deletions(-) create mode 100644 src/components/navbarProductDropdown.tsx delete mode 100644 src/docs/cli/index.mdx delete mode 100644 src/docs/enriching-error-data/breadcrumbs.mdx create mode 100644 src/docs/product/accounts/index.mdx rename src/docs/{ => product}/accounts/membership-toggle.png (100%) rename src/docs/{ => product}/accounts/membership.mdx (100%) rename src/docs/{ => product}/accounts/pricing.mdx (97%) rename src/docs/{ => product}/accounts/quotas/index.mdx (93%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-01.png (100%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-02.png (100%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-03.png (100%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-04.png (100%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-05.png (100%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-06.png (100%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-07.png (100%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-08.png (100%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-09.png (100%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-10.png (100%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-11.png (100%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-12.png (100%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-13.png (100%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-14.png (100%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-15.png (100%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-16.png (100%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-17.png (100%) rename src/docs/{ => product}/accounts/quotas/manage-event-stream-guide.mdx (97%) rename src/docs/{ => product}/accounts/quotas/spike-email.jpg (100%) rename src/docs/{ => product}/accounts/require-2fa-add-auth.png (100%) rename src/docs/{ => product}/accounts/require-2fa-audit-log.png (100%) rename src/docs/{ => product}/accounts/require-2fa-email.png (100%) rename src/docs/{ => product}/accounts/require-2fa-members.png (100%) rename src/docs/{ => product}/accounts/require-2fa-rejoin.png (100%) rename src/docs/{ => product}/accounts/require-2fa-resend-invite.png (100%) rename src/docs/{ => product}/accounts/require-2fa-switch.png (100%) rename src/docs/{ => product}/accounts/require-2fa.mdx (100%) rename src/docs/{ => product}/accounts/sso/azure-basic-saml-configuration.png (100%) rename src/docs/{ => product}/accounts/sso/azure-map-identity-provider-attributes.png (100%) rename src/docs/{ => product}/accounts/sso/azure-saml-signing-certificate.png (100%) rename src/docs/{ => product}/accounts/sso/azure-sentry-overview.png (100%) rename src/docs/{ => product}/accounts/sso/azure-sso.mdx (100%) rename src/docs/{ => product}/accounts/sso/index.mdx (98%) rename src/docs/{ => product}/accounts/sso/saml2-map-attributes.png (100%) rename src/docs/{ => product}/accounts/sso/saml2-metadata-url.png (100%) rename src/docs/{ => product}/accounts/sso/saml2-provider-data.png (100%) rename src/docs/{ => product}/accounts/sso/saml2-provider-xml.png (100%) rename src/docs/{ => product}/accounts/sso/saml2-success.png (100%) rename src/docs/{ => product}/accounts/sso/saml2.mdx (100%) rename src/docs/{ => product}/accounts/user-settings/index.mdx (100%) rename src/docs/{ => product}/accounts/user-settings/us-2fact.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-alert.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-apps.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-avatar.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-close.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-deploy.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-epanellink.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-eprime.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-ereport.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-eroute.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-id.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-lang.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-myact.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-name.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-npanellink.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-pass.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-rec.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-sess.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-shistory.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-sto.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-subs.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-time.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-token.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-work.png (100%) rename src/docs/{ => product}/accounts/user-settings/us-wrfield.png (100%) rename src/docs/{ => product}/cli/configuration.mdx (100%) rename src/docs/{ => product}/cli/dif.mdx (97%) create mode 100644 src/docs/product/cli/index.mdx rename src/docs/{ => product}/cli/installation.mdx (100%) rename src/docs/{ => product}/cli/releases.mdx (99%) rename src/docs/{ => product}/cli/send-event.mdx (100%) rename src/docs/{meta => product/security}/index.md (66%) rename src/docs/{meta => product/security}/ip-ranges.mdx (100%) rename src/docs/{meta => product/security}/legal-and-compliance.png (100%) rename src/docs/{meta => product/security}/soc2.md (100%) rename src/docs/{meta => product/security}/ssl.mdx (100%) rename src/docs/{meta => product/security}/terms.md (100%) diff --git a/src/api/permissions.mdx b/src/api/permissions.mdx index 54cd24f6b376a9..58c606dcc53a4b 100644 --- a/src/api/permissions.mdx +++ b/src/api/permissions.mdx @@ -7,7 +7,7 @@ If you're building on top of Sentry's API (i.e using [Auth Tokens](/api/auth/)), different API endpoints. If you're looking for information on membership roles please visit the -[membership](/accounts/membership/) documentation. +[membership](/product/accounts/membership/) documentation. ### Organizations @@ -72,6 +72,6 @@ Events in sentry are immutable and can only be deleted by deleting the whole iss -Be aware that if you're using `sentry-cli` to [manage your releases](/cli/releases/), you'll need a token which also has `org:read` scope. +Be aware that if you're using `sentry-cli` to [manage your releases](/product/cli/releases/), you'll need a token which also has `org:read` scope. diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx index 168b2c99049b4c..2e7ea7abcc4f63 100644 --- a/src/components/navbar.tsx +++ b/src/components/navbar.tsx @@ -7,6 +7,8 @@ import Search from "./search"; import SmartLink from "./smartLink"; import usePlatform, { usePlatformList } from "./hooks/usePlatform"; +import NavbarProductDropdown from "./navbarProductDropdown"; + type Props = { platforms?: string[]; }; @@ -21,11 +23,7 @@ export default ({ platforms }: Props): JSX.Element => { @@ -191,7 +191,7 @@ const IndexPage = () => {
  • - + Organization and User Management
  • diff --git a/src/platforms/android/index.mdx b/src/platforms/android/index.mdx index b58e0f45916afd..16158bd1d77183 100644 --- a/src/platforms/android/index.mdx +++ b/src/platforms/android/index.mdx @@ -184,7 +184,7 @@ public class DemoClass { ## ProGuard -To use ProGuard with Sentry, upload the ProGuard mapping files by using our Gradle integration (**recommended**) or manually by using [sentry-cli](/cli/dif/#proguard-mapping-upload). +To use ProGuard with Sentry, upload the ProGuard mapping files by using our Gradle integration (**recommended**) or manually by using [sentry-cli](/product/cli/dif/#proguard-mapping-upload). ### Gradle Integration @@ -211,7 +211,7 @@ buildscript { The plugin will automatically generate appropriate ProGuard mapping files and upload them when you run `gradle assemble{BuildVariant}`. For example, `assembleRelease` — Release is the default, but the plugin works for others if you have enabled ProGuard/R8. The credentials for the upload step are loaded via environment variables or from a `sentry.properties` file in your project root. -For more information, see the [full sentry-cli documentation](/cli/configuration/#configuration-values). +For more information, see the [full sentry-cli documentation](/product/cli/configuration/#configuration-values). At the very minimum you will need something like this: @@ -221,7 +221,7 @@ defaults.org=your-org auth.token=YOUR_AUTH_TOKEN ``` -You can find your authentication token [on the Sentry API page](https://sentry.io/api/). For more information about the available configuration options, see the [full sentry-cli documentation](/cli/configuration/#configuration-values). +You can find your authentication token [on the Sentry API page](https://sentry.io/api/). For more information about the available configuration options, see the [full sentry-cli documentation](/product/cli/configuration/#configuration-values). ### Gradle Configuration diff --git a/src/platforms/apple/common/dsym.mdx b/src/platforms/apple/common/dsym.mdx index 78171afd35fc02..851889698edc88 100644 --- a/src/platforms/apple/common/dsym.mdx +++ b/src/platforms/apple/common/dsym.mdx @@ -95,7 +95,7 @@ Your project’s dSYM can be upload during the build phase as a “Run Script” You need to have an Auth Token for this to work. You can [create an Auth Token here](https://sentry.io/api/). -1. Download and install [sentry-cli](https://github.com/getsentry/sentry-cli#installation) +1. Download and install [sentry-cli](/product/cli/installation/) 2. You will need to copy the script below into a new _Run Script_ and set your _AUTH_TOKEN_, _ORG_SLUG_, and _PROJECT_SLUG_ ```bash diff --git a/src/platforms/common/configuration/filtering.mdx b/src/platforms/common/configuration/filtering.mdx index 60f16df611f1ca..1f055a164b60dc 100644 --- a/src/platforms/common/configuration/filtering.mdx +++ b/src/platforms/common/configuration/filtering.mdx @@ -44,7 +44,7 @@ When you enable sampling in your SDK, you choose a percentage of collected error -For Sentry's Performance Monitoring, we recommend sampling your data for two reasons. First, though capturing a single trace involves minimal overhead, capturing traces for every single page load, or every single API request, has the potential to add an undesirable amount of load to your system. Second, by enabling sampling you’ll more easily prevent yourself from exceeding your organization’s [event quota](/accounts/quotas/). +For Sentry's Performance Monitoring, we recommend sampling your data for two reasons. First, though capturing a single trace involves minimal overhead, capturing traces for every single page load, or every single API request, has the potential to add an undesirable amount of load to your system. Second, by enabling sampling you’ll more easily prevent yourself from exceeding your organization’s [event quota](/product/accounts/quotas/). When choosing a sampling rate, the goal is not to collect *too* much data, but to collect sufficient data so you can draw meaningful conclusions. If you’re not sure what rate to choose, start with a low value and gradually increase it as you learn more about your traffic patterns and volume, until you’ve found a rate that balances performance and cost concerns with data accuracy. diff --git a/src/platforms/common/configuration/options.mdx b/src/platforms/common/configuration/options.mdx index e53654d59d7fe8..f085c879d4b879 100644 --- a/src/platforms/common/configuration/options.mdx +++ b/src/platforms/common/configuration/options.mdx @@ -11,7 +11,7 @@ initialized. ## Common Options -The list of common options across SDKs. These work more or less the same in all SDKs, but some subtle differences will exist to better support the platform. Options that can be read from an environment variable or your `~/.sentryclirc` file (`SENTRY_DSN`, `SENTRY_ENVIRONMENT`, `SENTRY_RELEASE`) are read automatically. See [Working with Projects](/cli/configuration/#sentry-cli-working-with-projects) for more information. +The list of common options across SDKs. These work more or less the same in all SDKs, but some subtle differences will exist to better support the platform. Options that can be read from an environment variable or your `~/.sentryclirc` file (`SENTRY_DSN`, `SENTRY_ENVIRONMENT`, `SENTRY_RELEASE`) are read automatically. See [Working with Projects](/product/cli/configuration/#sentry-cli-working-with-projects) for more information. diff --git a/src/platforms/common/data-management/debug-files.mdx b/src/platforms/common/data-management/debug-files.mdx index 3a7b1308530386..9f18072d9e37ed 100644 --- a/src/platforms/common/data-management/debug-files.mdx +++ b/src/platforms/common/data-management/debug-files.mdx @@ -31,7 +31,7 @@ the following formats: Source maps, while also being debug information files, are handled -in Sentry. For more information see [Source Maps in sentry-cli](/cli/releases/#sentry-cli-sourcemaps). +in Sentry. For more information see [Source Maps in sentry-cli](/product/cli/releases/#sentry-cli-sourcemaps). differently @@ -82,7 +82,7 @@ Sentry might not need all of the above information to process crash reports. Still, it is always a good idea to provide all available debug information. `sentry-cli` can be used to list properties of supported debug files and -validate their contents. See [_Debug Information Files in sentry-cli_](/cli/dif/) for more information. +validate their contents. See [_Debug Information Files in sentry-cli_](/product/cli/dif/) for more information. The remainder of this section describes the file formats in detail. @@ -254,7 +254,7 @@ their debug identifiers. You can copy this identifier and search for the exact files that match it in the _Debug Files_ settings screen. `sentry-cli` can help to print properties of debug information files like their -debug identifier. See [_Checking Debug Information Files_](/cli/dif/#checking-files) for more information. +debug identifier. See [_Checking Debug Information Files_](/product/cli/dif/#checking-files) for more information. ### GNU Build Identifiers @@ -340,7 +340,7 @@ $ sentry-cli upload-dif -o -p /path/to/files ``` For all available options and more information refer to [_Uploading Debug -Information_](/cli/dif/#uploading-files). +Information_](/product/cli/dif/#uploading-files). Always ensure that debug files are uploaded before deploying or releasing your application so that crash reports can be processed. For manual testing, use the @@ -644,7 +644,7 @@ unobfuscated source code at runtime. To get source context for native applications, source code needs to be uploaded alongside the debug information files. The recommended way to do this is by -using `sentry-cli`. See [Creating Source Bundles](/cli/dif/#creating-source-bundles) for more information. +using `sentry-cli`. See [Creating Source Bundles](/product/cli/dif/#creating-source-bundles) for more information. Source bundles show up as regular debug files on the _Debug Files_ settings page. They are designated as "source bundle" and feature a `sources` tag. To diff --git a/src/platforms/common/enriching-events/attachments/index.mdx b/src/platforms/common/enriching-events/attachments/index.mdx index eb062bf092d42c..e8d95cd5692554 100644 --- a/src/platforms/common/enriching-events/attachments/index.mdx +++ b/src/platforms/common/enriching-events/attachments/index.mdx @@ -40,7 +40,7 @@ Usually, native crash reports range from a few kilobytes to a few megabytes. Thi Attachments persist for 30 days; if your total storage included in your quota is exceeded, attachments will not be stored. You can delete attachments or their containing events at any time. Deleting an attachment does not affect your quota - Sentry counts an attachment toward your quota as soon as it is stored. -Learn more about how attachments impact your [quota](/accounts/quotas/). +Learn more about how attachments impact your [quota](/product/accounts/quotas/). diff --git a/src/platforms/javascript/common/sourcemaps/hosting-publicly.mdx b/src/platforms/javascript/common/sourcemaps/hosting-publicly.mdx index 6ace7c6007f2c1..6bc4db62f523f3 100644 --- a/src/platforms/javascript/common/sourcemaps/hosting-publicly.mdx +++ b/src/platforms/javascript/common/sourcemaps/hosting-publicly.mdx @@ -34,7 +34,7 @@ For these reasons, it is best practice to upload source maps to Sentry beforehan ## Working Behind a Firewall -While the recommended solution is to upload your source artifacts to Sentry, sometimes it’s necessary to allow communication from Sentry’s internal IPs. For more information on Sentry’s public IPs see: [IP Ranges](/meta/ip-ranges/). +While the recommended solution is to upload your source artifacts to Sentry, sometimes it’s necessary to allow communication from Sentry’s internal IPs. For more information on Sentry’s public IPs see: [IP Ranges](/product/security/ip-ranges/). ## Secure Access to Source Maps diff --git a/src/platforms/javascript/common/sourcemaps/index.mdx b/src/platforms/javascript/common/sourcemaps/index.mdx index ff5551c84907a5..edf85b2c7c9564 100644 --- a/src/platforms/javascript/common/sourcemaps/index.mdx +++ b/src/platforms/javascript/common/sourcemaps/index.mdx @@ -46,7 +46,7 @@ The Releases -> Admin permission is also known as 'project:releases' in other AP -You may configure [sentry-cli](/cli/configuration/) through it's documented mechanisms, or instead simply bind required parameters when initializing the plugin: +You may configure [sentry-cli](/product/cli/configuration/) through it's documented mechanisms, or instead simply bind required parameters when initializing the plugin: ```javascript {filename:webpack.config.js} const SentryWebpackPlugin = require("@sentry/webpack-plugin"); @@ -100,7 +100,7 @@ From here, you can [upload your source maps](uploading/) to Sentry. ## Additional Resources -- [Using sentry-cli to Upload Source Maps](/cli/releases/#sentry-cli-sourcemaps) +- [Using sentry-cli to Upload Source Maps](/product/cli/releases/#sentry-cli-sourcemaps) - [Debuggable JavaScript with Source Maps](https://blog.sentry.io/2015/10/29/debuggable-javascript-with-source-maps.html) - [4 Reasons Why Your Source Maps Are Broken](https://blog.sentry.io/2018/10/18/4-reasons-why-your-source-maps-are-broken) - [Debug Your Node.js Projects with Source Maps](https://blog.sentry.io/2019/02/20/debug-node-source-maps) diff --git a/src/platforms/javascript/common/sourcemaps/tools/webpack.mdx b/src/platforms/javascript/common/sourcemaps/tools/webpack.mdx index 09bfe92bc50259..4d71ca7a47f845 100644 --- a/src/platforms/javascript/common/sourcemaps/tools/webpack.mdx +++ b/src/platforms/javascript/common/sourcemaps/tools/webpack.mdx @@ -15,7 +15,7 @@ $ npm install --save-dev @sentry/webpack-plugin $ yarn add --dev @sentry/webpack-plugin ``` -You may configure [sentry-cli](/cli/configuration/) through it's documented mechanisms, or instead simply bind required parameters when initializing the plugin: +You may configure [sentry-cli](/product/cli/configuration/) through it's documented mechanisms, or instead simply bind required parameters when initializing the plugin: ```javascript {filename:webpack.config.js} const SentryWebpackPlugin = require("@sentry/webpack-plugin"); diff --git a/src/platforms/javascript/common/sourcemaps/uploading.mdx b/src/platforms/javascript/common/sourcemaps/uploading.mdx index b6e1d5024620c3..bae9f5f6e88091 100644 --- a/src/platforms/javascript/common/sourcemaps/uploading.mdx +++ b/src/platforms/javascript/common/sourcemaps/uploading.mdx @@ -6,7 +6,7 @@ We recommend uploading source maps as part of your build process, but you can al -The recommended way to upload source maps is using [sentry-cli](/cli/). If you have used [_Sentry Wizard_](https://github.com/getsentry/sentry-wizard) to set up your project, it has already created all necessary configuration to upload source maps. Otherwise, follow the [CLI configuration docs](/cli/configuration/) to set up your project. +The recommended way to upload source maps is using [sentry-cli](/product/cli/). If you have used [_Sentry Wizard_](https://github.com/getsentry/sentry-wizard) to set up your project, it has already created all necessary configuration to upload source maps. Otherwise, follow the [CLI configuration docs](/product/cli/configuration/) to set up your project. diff --git a/src/platforms/javascript/common/sourcemaps/validating.mdx b/src/platforms/javascript/common/sourcemaps/validating.mdx index bf78130ff4ef32..6ac2d9931f662e 100644 --- a/src/platforms/javascript/common/sourcemaps/validating.mdx +++ b/src/platforms/javascript/common/sourcemaps/validating.mdx @@ -4,7 +4,7 @@ title: Validating Files It can be quite challenging to ensure that source maps are actually valid themselves and uploaded correctly. To help with this, we maintain an online validation tool that can be used to test your source maps against your **hosted** source: [sourcemaps.io](https://sourcemaps.io). -Additionally, you can use the `--validate` flag within when uploading source maps with [sentry-cli](/cli/), which will attempt to locally parse the source map and look up the references. Note that there are known cases where the validate flag will indicate failures when the setup is correct (if you have references to external source maps, then the validation tool will indicate a failure). +Additionally, you can use the `--validate` flag within when uploading source maps with [sentry-cli](/product/cli/), which will attempt to locally parse the source map and look up the references. Note that there are known cases where the validate flag will indicate failures when the setup is correct (if you have references to external source maps, then the validation tool will indicate a failure). You can also check these, in addition to the validation step: diff --git a/src/platforms/javascript/guides/electron/index.mdx b/src/platforms/javascript/guides/electron/index.mdx index 847c91b9539897..7e0227359f9eb3 100644 --- a/src/platforms/javascript/guides/electron/index.mdx +++ b/src/platforms/javascript/guides/electron/index.mdx @@ -183,7 +183,7 @@ If your application contains custom native extensions or you wish to symbolicate crashes from a spawned child process, upload their debug information manually during your build or release process. See [_Debug Information Files_](/workflow/debug-files/) for a detailed description of how to set up Sentry for native development. Additionally, see [_Uploading Debug -Information_](/cli/dif/) for the upload process. +Information_](/product/cli/dif/) for the upload process. ### Child Processes diff --git a/src/platforms/javascript/guides/react/index.mdx b/src/platforms/javascript/guides/react/index.mdx index 7a6f784a6e9d6b..bb7d1c57f27c88 100644 --- a/src/platforms/javascript/guides/react/index.mdx +++ b/src/platforms/javascript/guides/react/index.mdx @@ -119,7 +119,7 @@ We **highly recommend** you incorporate source maps to receive the full benefit When you’re using the Sentry React SDK, the SDK automatically fetches the source code and source maps by scraping the URLs within the stack trace. If you need to disable the JavaScript source fetching, log in to Sentry and toggle off `Allow JavaScript source fetching` in your organization's settings for Security & Privacy. See our [source maps documentation](/platforms/javascript/guides/react/sourcemaps/) to learn more. -Upload source maps using either our [Webpack plugin](/platforms/javascript/guides/react/sourcemaps/tools/webpack/) or the [Sentry CLI](/cli/). Sourcemaps can be generated by [Uglify JS](/platforms/javascript/guides/react/sourcemaps/tools/uglifyjs/), [System JS](/platforms/javascript/guides/react/sourcemaps/tools/systemjs/), or [TypeScript](/platforms/javascript/guides/react/sourcemaps/tools/typescript/). +Upload source maps using either our [Webpack plugin](/platforms/javascript/guides/react/sourcemaps/tools/webpack/) or the [Sentry CLI](/product/cli/). Sourcemaps can be generated by [Uglify JS](/platforms/javascript/guides/react/sourcemaps/tools/uglifyjs/), [System JS](/platforms/javascript/guides/react/sourcemaps/tools/systemjs/), or [TypeScript](/platforms/javascript/guides/react/sourcemaps/tools/typescript/). ## Monitor Performance diff --git a/src/platforms/react-native/codepush.mdx b/src/platforms/react-native/codepush.mdx index 22348f55432ba7..251448afd2cddd 100644 --- a/src/platforms/react-native/codepush.mdx +++ b/src/platforms/react-native/codepush.mdx @@ -46,7 +46,7 @@ When making the release with CodePush, make sure to output the bundle and source $ appcenter codepush release-react -a {APP} -d {DEPLOYMENT} --sourcemap-output --output-dir ./build ``` -Exporting the `SENTRY_PROPERTIES` will tell sentry-cli to use the properties in your project. The sentry-wizard install step should have generated this file for you. Alternatively, you can either pass it via parameters or a global settings file. To find more about this refer to [Working with Projects](/cli/configuration/#sentry-cli-working-with-projects). +Exporting the `SENTRY_PROPERTIES` will tell sentry-cli to use the properties in your project. The sentry-wizard install step should have generated this file for you. Alternatively, you can either pass it via parameters or a global settings file. To find more about this refer to [Working with Projects](/product/cli/configuration/#sentry-cli-working-with-projects). ```bash $ export SENTRY_PROPERTIES=./ios/sentry.properties diff --git a/vercel.json b/vercel.json index 44ba2f7b13ed5d..a17338c2dce893 100644 --- a/vercel.json +++ b/vercel.json @@ -24,6 +24,18 @@ ], "trailingSlash": true, "redirects": [ + { + "source": "/meta/(.*)", + "destination": "/product/security/$1" + }, + { + "source": "/cli/(.*)", + "destination": "/product/cli/$1" + }, + { + "source": "/accounts/(.*)", + "destination": "/product/accounts/$1" + }, { "source": "/(hosted|on-premise)/(.*)", "destination": "/$2" }, { "source": "/internal/(.*)", "destination": "https://develop.sentry.dev" }, { From ec8d6fe6c1a7932b216abdac697bde3c345552e6 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Wed, 30 Sep 2020 14:24:19 -0700 Subject: [PATCH 17/20] feat(performance): Add `tracesSampleRate` and `tracesSampler` to JS docs (#2376) Also a bunch of reorganization, and reworking of some (but not all) of the JS performance docs. --- src/components/platformSidebar.tsx | 4 +- .../performance/distributed-tracing.mdx | 4 +- .../configuration/decluttering/javascript.mdx | 2 +- .../custom-sampling-context/javascript.mdx | 20 ++ .../custom-sampling-context/node.mdx | 22 ++ .../default-sampling-context/javascript.mdx | 14 + .../default-sampling-context/node.mdx | 13 + .../common/configuration/filtering.mdx | 78 +++-- .../common/configuration/options.mdx | 14 +- .../javascript/common/install/cdn.mdx | 5 +- .../common/performance/automatic.mdx | 141 ++++++++ .../javascript/common/performance/index.mdx | 329 +++++++----------- .../javascript/common/performance/manual.mdx | 71 ++++ .../common/performance/sampling.mdx | 140 ++++++++ .../javascript/guides/angular/index.mdx | 5 +- .../javascript/guides/react/index.mdx | 5 +- .../react/integrations/react-router.mdx | 27 +- src/platforms/javascript/guides/vue/index.mdx | 5 +- .../guides/vue/integrations/components.mdx | 5 +- src/platforms/javascript/index.mdx | 9 +- .../node/common/performance/index.mdx | 5 +- src/platforms/node/guides/express/index.mdx | 5 +- src/platforms/node/guides/koa/index.mdx | 44 +-- src/platforms/node/index.mdx | 10 +- src/wizard/javascript/angular.md | 3 + src/wizard/javascript/index.md | 3 + src/wizard/javascript/react.md | 3 + src/wizard/javascript/vue.md | 10 +- src/wizard/node/express.md | 3 + src/wizard/node/index.md | 3 + 30 files changed, 720 insertions(+), 282 deletions(-) create mode 100644 src/includes/performance/custom-sampling-context/javascript.mdx create mode 100644 src/includes/performance/custom-sampling-context/node.mdx create mode 100644 src/includes/performance/default-sampling-context/javascript.mdx create mode 100644 src/includes/performance/default-sampling-context/node.mdx create mode 100644 src/platforms/javascript/common/performance/automatic.mdx create mode 100644 src/platforms/javascript/common/performance/manual.mdx create mode 100644 src/platforms/javascript/common/performance/sampling.mdx diff --git a/src/components/platformSidebar.tsx b/src/components/platformSidebar.tsx index 02a78aa1bf8d28..ca9012103f52fd 100644 --- a/src/components/platformSidebar.tsx +++ b/src/components/platformSidebar.tsx @@ -83,7 +83,9 @@ export const PlatformSidebar = ({ diff --git a/src/docs/product/performance/distributed-tracing.mdx b/src/docs/product/performance/distributed-tracing.mdx index 7dd2cc70b47f5b..361d5d67561402 100644 --- a/src/docs/product/performance/distributed-tracing.mdx +++ b/src/docs/product/performance/distributed-tracing.mdx @@ -233,9 +233,9 @@ Individual spans aren't sent to Sentry; rather, the entire transaction is sent a When you enable sampling in your tracing setup, you choose a percentage of collected transactions to send to Sentry. For example, if you had an endpoint that received 1000 requests per minute, a sampling rate of `0.25` would result in approximately 250 transactions (25%) being sent to Sentry each minute. (The number is approximate because each request is either tracked or not, independently and pseudorandomly, with a 25% probability. So in the same way that 100 fair coins, when flipped, result in approximately 50 heads, the SDK will "decide" to collect a trace in approximately 250 cases.) Because you know the sampling percentage, you can then extrapolate your total traffic volume. -When collecting traces, we **strongly recommend** sampling your data, for two reasons. First, though capturing a single trace involves minimal overhead, capturing traces for every single page load, or every single API request, has the potential to add an undesirable amount of load to your system. Second, by enabling sampling you'll more easily prevent yourself from exceeding your organization's [event quota](/product/accounts/quotas/), which will help you manage costs. +When collecting traces, we recommend sampling your data, for two reasons. First, though capturing a single trace involves minimal overhead, capturing traces for every single page load, or every single API request, has the potential to add an undesirable amount of load to your system. Second, enabling sampling allows you to better manage the number of events sent to Sentry, so you can tailor it to your organization's needs. -When choosing a sampling rate, the goal is to not collect _too_ much data (given the reasons above) but also to collect enough data that you are able to draw meaningful conclusions. If you're not sure what rate to choose, we recommend starting with a low value and gradually increasing it as you learn more about your traffic patterns and volume, until you've found a rate which lets you balance performance and cost concerns with data accuracy. +When choosing a sampling rate, the goal is to not collect _too_ much data (given the reasons above) but also to collect enough data that you are able to draw meaningful conclusions. If you're not sure what rate to choose, we recommend starting with a low value and gradually increasing it as you learn more about your traffic patterns and volume, until you've found a rate which lets you balance performance and volume concerns with data accuracy. ### Consistency Within a Trace diff --git a/src/includes/configuration/decluttering/javascript.mdx b/src/includes/configuration/decluttering/javascript.mdx index 36af79a822cd3d..f4da6c8608d0a1 100644 --- a/src/includes/configuration/decluttering/javascript.mdx +++ b/src/includes/configuration/decluttering/javascript.mdx @@ -6,7 +6,7 @@ You can also use `denyUrls` if you want to block specific URLs forever. -Prior to version 5.17.0, `allowUrls` and `denyUrls` were called `whitelistUrls` and `blacklistUrls` respectively. These options are still supported due to backward compatibility reasons; however, they will be removed in version 6.0. For more information, please see our [Inclusive Language Policy](https://develop.sentry.dev/inclusion/). +Prior to version 5.17.0, `allowUrls` and `denyUrls` were called `whitelistUrls` and `blacklistUrls` respectively. These options are still supported for backwards compatibility reasons, but they will be removed in version 6.0. For more information, please see our [Inclusive Language Policy](https://develop.sentry.dev/inclusion/). diff --git a/src/includes/performance/custom-sampling-context/javascript.mdx b/src/includes/performance/custom-sampling-context/javascript.mdx new file mode 100644 index 00000000000000..788b6bef311204 --- /dev/null +++ b/src/includes/performance/custom-sampling-context/javascript.mdx @@ -0,0 +1,20 @@ +```javascript +Sentry.startTransaction( + { + // `transactionContext` - will be recorded on transaction + name: 'Search from navbar', + op: 'search', + tags: { + testGroup: 'A3', + treatmentName: 'eager load', + }, + }, + // `customSamplingContext` - won't be recorded + { + // PII + userId: '12312012', + // too big to send + resultsFromLastSearch: { ... } + }, +); +``` diff --git a/src/includes/performance/custom-sampling-context/node.mdx b/src/includes/performance/custom-sampling-context/node.mdx new file mode 100644 index 00000000000000..6e5747a87bb762 --- /dev/null +++ b/src/includes/performance/custom-sampling-context/node.mdx @@ -0,0 +1,22 @@ +```javascript +Sentry.startTransaction( + { + // `transactionContext` - will be recorded on transaction + name: 'GET /search', + op: 'search', + data: { + queryParams: { + animal: "dog", + type: "very good" + } + }, + }, + // `customSamplingContext` - won't be recorded + { + // PII + userId: '12312012', + // too big to send + searchResults: { ... } + }, +); +``` diff --git a/src/includes/performance/default-sampling-context/javascript.mdx b/src/includes/performance/default-sampling-context/javascript.mdx new file mode 100644 index 00000000000000..368d778963dd38 --- /dev/null +++ b/src/includes/performance/default-sampling-context/javascript.mdx @@ -0,0 +1,14 @@ +For browser-based SDKs, it includes the following: + +```javascript +// contents of `samplingContext` +{ + transactionContext: { + name: string; // human-readable identifier, like "GET /users" + op: string; // short description of transaction type, like "pageload" + } + parentSampled: boolean; // if this transaction has a parent, its sampling decision + location: Location | WorkerLocation; // the window.location or self.location object + ... // custom context as passed to `startTransaction` +} +``` diff --git a/src/includes/performance/default-sampling-context/node.mdx b/src/includes/performance/default-sampling-context/node.mdx new file mode 100644 index 00000000000000..d2b2f17fbf29a3 --- /dev/null +++ b/src/includes/performance/default-sampling-context/node.mdx @@ -0,0 +1,13 @@ +The information contained in the `samplingContext` object passed to the `tracesSampler` when a transaction is created varies by platform. For node-based SDKs, it includes the following: + +```javascript +{ + transactionContext: { + name: string; // human-readable identifier, like "GET /users" + op: string; // short description of transaction type, like "pageload" + } + parentSampled: boolean; // if this transaction has a parent, its sampling decision + request: object // in server contexts, information about the incoming request + ... // custom context as passed to `startTransaction` +} +``` diff --git a/src/platforms/common/configuration/filtering.mdx b/src/platforms/common/configuration/filtering.mdx index 1f055a164b60dc..96a142bb1c3d2e 100644 --- a/src/platforms/common/configuration/filtering.mdx +++ b/src/platforms/common/configuration/filtering.mdx @@ -1,20 +1,24 @@ --- -title: Filtering Events +title: Filtering and Sampling Events sidebar_order: 5 -description: "Learn more about how to filter events reported to Sentry, using either the SDK, product filtering options, or both." +description: "Learn more about how to configure your SDK to filter and sample events reported to Sentry." notSupported: - perl --- -While sending all application errors to Sentry ensures you’ll be notified in real-time when errors occur in your code, often applications generate many errors, thus many notifications. The Sentry SDKs have several configuration options you can use to filter unwanted errors from leaving your application’s runtime. In addition, sentry.io also [offers methods to filter events](/product/error-monitoring/filtering/). +Adding Sentry to your app gives you a great deal of very valuable information about errors and performance you wouldn't otherwise get. And lots of information is good -- as long as it's the right information, at a reasonable volume. -## Configure your SDK to Filter Events +The Sentry SDKs have several configuration options to help you control this, allowing you to both filter out events you don't want and to take a representative sample of those you do. -Configure your SDK to filter events by using the `beforeSend` callback method and configuring, enabling, or disabling integrations. +**Note:**: The Sentry UI also offers methods to filter events, by using [Inbound Filters](/product/error-monitoring/filtering/). We recommend filtering at the client level though, because it removes the overhead of sending events you don't actually want. -### Using `before-send` +## Filtering Error Events -All Sentry SDKs support the `beforeSend` callback method. `before-send` is called immediately before the event is sent to the server, so it’s the final place where you can edit its data. It receives the event object as a parameter, so you can use that to modify the event’s data or drop it completely (by returning `null`) based on custom logic and the data available on the event. +Configure your SDK to filter error events by using the `beforeSend` callback method and configuring, enabling, or disabling integrations. + +### Using `beforeSend` + +All Sentry SDKs support the `beforeSend` callback method. `beforeSend` is called immediately before the event is sent to the server, so it’s the final place where you can edit its data. It receives the event object as a parameter, so you can use that to modify the event’s data or drop it completely (by returning `null`) based on custom logic and the data available on the event. @@ -28,25 +32,7 @@ Typically a `hint` holds the original exception so that additional data can be e -When the SDK creates an event or breadcrumb for transmission, that transmission is typically created from some sort of source object. For instance, an error event is typically created from a log record or exception instance. For better customization, SDKs send these objects to certain callbacks (`before-send`, `before-breadcrumb` or the event processor system in the SDK). - -#### Sampling - -If a sample rate is defined for the SDK, the SDK evaluates whether this event should be sent as a representative fraction of events. - - - -The SDK sample rate is not dynamic; changing it requires re-deployment. In addition, setting an SDK sample rate limits visibility into the source of events. Setting a rate limit for your project may better suit your needs. - - - -When you enable sampling in your SDK, you choose a percentage of collected errors to send to Sentry. For example, to sample 25% of your events: - - - -For Sentry's Performance Monitoring, we recommend sampling your data for two reasons. First, though capturing a single trace involves minimal overhead, capturing traces for every single page load, or every single API request, has the potential to add an undesirable amount of load to your system. Second, by enabling sampling you’ll more easily prevent yourself from exceeding your organization’s [event quota](/product/accounts/quotas/). - -When choosing a sampling rate, the goal is not to collect *too* much data, but to collect sufficient data so you can draw meaningful conclusions. If you’re not sure what rate to choose, start with a low value and gradually increase it as you learn more about your traffic patterns and volume, until you’ve found a rate that balances performance and cost concerns with data accuracy. +When the SDK creates an event or breadcrumb for transmission, that transmission is typically created from some sort of source object. For instance, an error event is typically created from a log record or exception instance. For better customization, SDKs send these objects to certain callbacks (`beforeSend`, `beforeBreadcrumb` or the event processor system in the SDK). ### Using Hints @@ -98,3 +84,43 @@ In this example, the fingerprint is forced to a common value if an exception of : For breadcrumbs created from HTTP requests done via the legacy `XMLHttpRequest` API. This holds the original xhr object. + +## Sampling Error Events + +To send a representative sample of your errors to Sentry, set the `sampleRate` option in your SDK configuration to a number between `0` (0% of errors sent) and `1` (100% of errors sent). This is a static rate, which will apply equally to all errors. For example, to sample 25% of your errors: + + + +**Note:** The error sample rate is not dynamic; changing it requires re-deployment. In addition, setting an SDK sample rate limits visibility into the source of events. Setting a rate limit for your project (which only drops events when volume is high) may better suit your needs. + + + +## Filtering Transaction Events + +To prevent certain transactions from being reported to Sentry, use the `tracesSampler` configuration option, which allows you to provide a function to evaluate the current transaction and drop it if it's not one you want. (It also allows you to sample different transactions at different rates.) + +**Note:** The `tracesSampler` and `tracesSampleRate` config options are mutually exclusive. If you define a `tracesSampler` to filter out certain transactions, you must also handle the case of non-filtered transactions by returning the rate at which you'd like them sampled. + +In its simplest form, used just for filtering, it looks like this: + +```javascript +tracesSampler: samplingContext => { + if ("...") { + return 0; // Drop this transaction, by setting its sample rate to 0% + } else { + return 0.2; // Default sample rate for all others (replaces tracesSampleRate ) + } +}; +``` + +To learn more about the `tracesSampler` option, please see [Sampling Transactions](/platforms/javascript/performance/sampling/). + + + +## Sampling Transaction Events + +For Sentry's Performance Monitoring, we recommend sampling your data for two reasons. First, though capturing a single trace involves minimal overhead, capturing traces for every single page load, or every single API request, has the potential to add an undesirable amount of load to your system. Second, enabling sampling allows you to better manage the number of events sent to Sentry, so you can tailor it to your organization's needs. + +When choosing a sampling rate, the goal is not to collect *too* much data, but to collect sufficient data so you can draw meaningful conclusions. If you’re not sure what rate to choose, start with a low value and gradually increase it as you learn more about your traffic patterns and volume, until you’ve found a rate that balances performance and volume concerns with data accuracy. + +To set a sample rate for your transactions, provide a number between `0` (0% of transactions sent) and `1` (100% of transactions sent) to the `tracesSampleRate` configuration option. For example, including `tracesSampleRate: 0.2` in your SDK config will cause the SDK to only send 20% of possible transaction events. diff --git a/src/platforms/common/configuration/options.mdx b/src/platforms/common/configuration/options.mdx index f085c879d4b879..f848e27e9a8f17 100644 --- a/src/platforms/common/configuration/options.mdx +++ b/src/platforms/common/configuration/options.mdx @@ -53,7 +53,7 @@ By default all types of errors are be reported (equivalent to `E_ALL`). -Configures the sample rate as a percentage of events to be sent in the range of `0.0` to `1.0`. The default is `1.0` which means that 100% of events are sent. If set to `0.1` only 10% of events will be sent. Events are picked randomly. +Configures the sample rate for error events, in the range of `0.0` to `1.0`. The default is `1.0` which means that 100% of error events are sent. If set to `0.1` only 10% of error events will be sent. Events are picked randomly. @@ -208,3 +208,15 @@ Controls how many seconds to wait before shutting down. Sentry SDKs send events + +## Tracing Options + + + +A number between 0 and 1, controlling the percentage chance a given transaction will be sent to Sentry. (0 represents 0% while 1 represents 100%.) Applies equally to all transactions created in the app. Either this or `tracesSampler` must be defined to enable tracing. + + + + +A function responsible for determining the percentage chance a given transaction will be sent to Sentry. It will automatically be passed information about the transaction and the context in which it's being created, and must return a number between 0 (0% chance of being sent) and 1 (100% chance of being sent). Can also be used for filtering transactions, by returning 0 for those that are unwanted. Either this or `tracesSampleRate` must be defined to enable tracing. + diff --git a/src/platforms/javascript/common/install/cdn.mdx b/src/platforms/javascript/common/install/cdn.mdx index 02f9507c4c5e47..1cd80bda5601b5 100644 --- a/src/platforms/javascript/common/install/cdn.mdx +++ b/src/platforms/javascript/common/install/cdn.mdx @@ -40,7 +40,10 @@ Sentry.init({ dsn: "___PUBLIC_DSN___", release: "my-project-name@" + process.env.npm_package_version, integrations: [new Sentry.Integrations.BrowserTracing()], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/common/performance/automatic.mdx b/src/platforms/javascript/common/performance/automatic.mdx new file mode 100644 index 00000000000000..b30e3907c841c9 --- /dev/null +++ b/src/platforms/javascript/common/performance/automatic.mdx @@ -0,0 +1,141 @@ +--- +title: Capturing Transactions Automatically +sidebar_order: 20 +description: "Learn how to configure what performance data is automatically captured." +--- + +The `@sentry/tracing` package provides a `BrowserTracing` integration to add automatic instrumentation for monitoring the performance of browser applications. By default, this integration will create a new transaction for each pageload and navigation event, and will create a child span for every `XMLHttpRequest` or `fetch` request which occurs while those transactions are open. + +To enable this automatic tracing, include the `BrowserTracing` integration in your SDK configuration options. (Note that when using ESM modules, the main `@sentry/*` import must come before the `@sentry/tracing` import.) + +```javascript {tabTitle: ESM} +// If you're using one of our integration packages, like `@sentry/react` or `@sentry/angular`, +// substitute its name for `@sentry/browser` here +import * as Sentry from "@sentry/browser"; +import { Integrations as TracingIntegrations } from "@sentry/tracing"; // Must import second + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + + integrations: [ + new Integrations.BrowserTracing({ + tracingOrigins: ["localhost", "my-site-url.com", /^\//], + // ... other options + }), + ], + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, +}); +``` + +```javascript {tabTitle: CDN} +Sentry.init({ + dsn: "___PUBLIC_DSN___", + + integrations: [ + new Sentry.Integrations.BrowserTracing({ + tracingOrigins: ["localhost", "my-site-url.com", /^\//], + // ... other options + }), + ], + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, +}); +``` + +After configuration, you should see both `pageload` and `navigation` transactions show up in your Sentry UI. + +## Options + +You can pass many different options to the `BrowserTracing` integration (as an object of the form `{optionName: value}`), but it comes with reasonable defaults out of the box. For all possible options, see [TypeDocs](https://getsentry.github.io/sentry-javascript/interfaces/tracing.browsertracingoptions.html). + +### tracingOrigins + +Usage: + +```javascript +Sentry.init({ + dsn: "___PUBLIC_DSN___", + integrations: [ + new Integrations.BrowserTracing({ + tracingOrigins: ["localhost", "my-site-url.com"], + }), + ], + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, +}); +``` + +The default value of `tracingOrigins` is `['localhost', /^\//]`. The JavaScript SDK will attach the `sentry-trace` header to all outgoing XHR/fetch requests whose destination contains a string in the list or matches a regex in the list. If your frontend is making requests to a different domain, you will need to add it there to propagate the `sentry-trace` header to the backend services, which is required to link transactions together as part of a single trace. **One important thing to note is that the `tracingOrigins` option matches against the whole request URL, not just the domain. Using stricter regex to match certain parts of the URL can help make sure that requests do not unnecessarily have the `sentry-trace` header attached.** + +_Example:_ + +- A frontend application is served from `example.com` +- A backend service is served from `api.example.com` +- The frontend application makes API calls to the backend +- Therefore, the option needs to be configured like this: `new Integrations.BrowserTracing({tracingOrigins: ['api.example.com']})` +- Now outgoing XHR/fetch requests to `api.example.com` will get the `sentry-trace` header attached + +_NOTE:_ You need to make sure your web server CORS is configured to allow the `sentry-trace` header. The configuration might look like `"Access-Control-Allow-Headers: sentry-trace"`, but the configuration depends on your set up. If you do not allow the `sentry-trace` header, the request might be blocked. + +### beforeNavigate + +For `pageload` and `navigation` transactions, the `BrowserTracing` integration uses the browser's `window.location` API to generate a transaction name. To customize the name of the `pageload` and `navigation` transactions, you can supply a `beforeNavigate` option to the `BrowserTracing` integration. This option allows you to modify the transaction name to make it more generic, so that, for example, transactions named `GET /users/12312012` and `GET /users/11212012` can both be renamed `GET /users/:userid`, so that they'll group together. + +```javascript +import * as Sentry from "@sentry/browser"; +import { Integrations } from "@sentry/tracing"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + integrations: [ + new Integrations.BrowserTracing({ + beforeNavigate: context => { + return { + ...context, + // You could use your UI's routing library to find the matching + // route template here. We don't have one right now, so do some basic + // parameter replacements. + name: location.pathname + .replace(/\d+/g, "") + .replace(/[a-f0-9]{32}/g, ""), + }; + }, + }), + ], + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, +}); +``` + +### shouldCreateSpanForRequest + +This function can be used to filter out unwanted spans such as XHR's running health checks or something similar. By default `shouldCreateSpanForRequest` already filters out everything but what was defined in `tracingOrigins`. + +```javascript +import * as Sentry from "@sentry/browser"; +import { Integrations } from "@sentry/tracing"; +Sentry.init({ + dsn: "___PUBLIC_DSN___", + integrations: [ + new Integrations.BrowserTracing({ + shouldCreateSpanForRequest: url => { + // Do not create spans for outgoing requests to a `/health/` endpoint + return !url.match(/\/health\/?$/); + }, + }), + ], + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, +}); +``` diff --git a/src/platforms/javascript/common/performance/index.mdx b/src/platforms/javascript/common/performance/index.mdx index 35ce2c3e5d3b71..1dd344960d03a0 100644 --- a/src/platforms/javascript/common/performance/index.mdx +++ b/src/platforms/javascript/common/performance/index.mdx @@ -1,218 +1,188 @@ --- title: Performance Monitoring sidebar_order: 20 -description: "Learn more about how to configure our Performance integrations to get the best experience out of it." +description: "Learn how to enable performance monitoring in your app." redirect_from: - /platforms/javascript/performance/apm-to-tracing/ --- -The `@sentry/tracing` package provides a `BrowserTracing` integration to add automatic instrumentation for monitoring the performance of browser applications. +Sentry allows you to monitor the performance of your application, showing you how latency in one service may affect another service, and letting you pinpoint exactly which parts of a given operation may be responsible. To do this, it captures distributed traces consisting of transactions and spans, which measure individual services and individual operations within those services, respectively. You can learn more about this model in our [Distributed Tracing](/product/performance/distributed-tracing/) docs. + +Once tracing is enabled, certain types of operations will be measured automatically, and you can also choose to manually measure any operation you like. To learn more, see [Capturing Transactions Automatically](/platforms/javascript/performance/automatic/) and [Capturing Transactions Manually](/platforms/javascript/performance/manual/). + +## Enabling Tracing + +The first step is to install the tracing package, if you haven't done so already: + +```bash {tabTitle: ESM} +# Using yarn +$ yarn add @sentry/tracing + +# Using npm +$ npm install @sentry/tracing +``` + +```html {tabTitle: CDN} + +``` + +Once you've installed the package, there are two ways to enable tracing in your app: + +- Set a uniform sample rate for all transactions, by setting the `tracesSampleRate` option in your SDK config to a number between `0` and `1`. (For example, to send 20% of transactions, set `tracesSampleRate` to `0.2`.) +- Control the sample rate dynamically, based on the transaction itself and the context in which it's captured, by providing a function to the `tracesSampler` config option. ```javascript {tabTitle: ESM} -// Substitude `@sentry/browser` for the integration you're using (if applicable) +// If you're using one of our integration packages, like `@sentry/react` or +// `@sentry/angular`, substitute its name for `@sentry/browser` here import * as Sentry from "@sentry/browser"; -// Pull in the additional tracing integration +// If taking advantage of automatic instrumentation (highly recommended) import { Integrations as TracingIntegrations } from "@sentry/tracing"; +// Or, if only doing manual tracing +// import * as _ from "@sentry/tracing" +// Note: You MUST import the package in some way for tracing to work Sentry.init({ dsn: "___PUBLIC_DSN___", + + // This enables automatic instrumentation (highly recommeneded), but is not + // necessary for purely manual usage integrations: [new TracingIntegrations.BrowserTracing()], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // To set a uniform sample rate + tracesSampleRate: 0.2 + + // Alternatively, to control sampling dynamically + tracesSampler: samplingContext => { ... } }); ``` ```javascript {tabTitle: CDN} Sentry.init({ dsn: "___PUBLIC_DSN___", - integrations: [new Sentry.Integrations.BrowserTracing()], - tracesSampleRate: 1.0, // Be sure to lower this in production -}); -``` -After configuration, you should see both `pageload` and `navigation` transactions show up in your Sentry UI. - -You can pass many different options to the `BrowserTracing` integration (as an object of the form `{optionName: value}`), but it comes with reasonable defaults out of the box. For all possible options, see [TypeDocs](https://getsentry.github.io/sentry-javascript/interfaces/tracing.browsertracingoptions.html). - -### tracingOrigins + // This enables automatic instrumentation (highly recommeneded), but is not + // necessary for purely manual usage + integrations: [new Sentry.Integrations.BrowserTracing()], -Usage: + // To set a uniform sample rate + tracesSampleRate: 0.2 -```javascript -Sentry.init({ - dsn: "___PUBLIC_DSN___", - integrations: [ - new Integrations.BrowserTracing({ - tracingOrigins: ["localhost", "my-site-url.com"], - }), - ], - tracesSampleRate: 1.0, // Be sure to lower this in production + // Alternatively, to control sampling dynamically + tracesSampler: samplingContext => { ... } }); ``` -The default value of `tracingOrigins` is `['localhost', /^\//]`. The JavaScript SDK will attach the `sentry-trace` header to all outgoing XHR/fetch requests whose destination contains a string in the list or matches a regex in the list. If your frontend is making requests to a different domain, you will need to add it there to propagate the `sentry-trace` header to the backend services, which is required to link transactions together as part of a single trace. **One important thing to note is that the `tracingOrigins` option matches against the whole request URL, not just the domain. Using stricter regex to match certain parts of the URL can help make sure that requests do not unnecessarily have the `sentry-trace` header attached.** +If either of these options is set, tracing will be enabled in your app. (They are meant to be mutually exclusive, but if you do set both, `tracesSampler` will take precedence.) You can learn more about how they work in [Sampling Transactions](/platforms/javascript/performance/sampling/). -_Example:_ + -- A frontend application is served from `example.com` -- A backend service is served from `api.example.com` -- The frontend application makes API calls to the backend -- Therefore, the option needs to be configured like this: `new Integrations.BrowserTracing({tracingOrigins: ['api.example.com']})` -- Now outgoing XHR/fetch requests to `api.example.com` will get the `sentry-trace` header attached +When you first enable tracing, the easiest thing to do to test it is to set `tracesSampleRate` to `1.0`, because that guarantees that every transaction will be sent to Sentry for you to see. -_NOTE:_ You need to make sure your web server CORS is configured to allow the `sentry-trace` header. The configuration might look like `"Access-Control-Allow-Headers: sentry-trace"`, but the configuration depends on your set up. If you do not allow the `sentry-trace` header, the request might be blocked. +Once you're done with testing, however, we recommend that you either **lower your `tracesSampleRate` value, or switch to using `tracesSampler` to dynamically sample and filter your transactions**. -### Connecting Backend and Frontend Transactions +Without sampling, our atomatic instrumenation will send a transaction any time any user loads any page or navigates anywhere in your app. That's a lot of transactions! Sampling allows you to get representative data without overwhelming either your system or your Sentry transaction quota. -When instrumenting both frontend and backend with Sentry, you can connect the -`pageload` transaction on the frontend with the request transaction that rendered the page on the backend. + + +## Connecting Backend and Frontend Transactions + +To connect backend and frontend transactions into a single choherent trace, Sentry uses a `trace_id` value which is propagated between frontend and backend. Depending on the circumstance, this id is transmitted either in a request/response header or in an HTML `` tag. Linking transactions in this way makes it possible for you to navigate between them in the Sentry UI, so you can better understand how the different parts of your system are affecting each other. -Once connected, the backend and frontend transactions will share the same `trace_id`, allowing you to navigate from one transaction to the other in Sentry. +### Pageload -In your backend code, include a `` tag in the `` of the rendered HTML document as in this example: +When enabling tracing in both frontend and backend and taking advantage of the automatic frontend instrumentation, you can connect the automatically-generated `pageload` transaction on the frontend with the request transaction that serves the page on the backend. Because JavaScript code running in a browser cannot read the response headers of the current page, the `trace_id` must be transmitted in the response itself, specifically in a `` tag in the `` of the HTML sent from your backend. ```html - - - + + + + + ``` -The `name` attribute must be the string `"sentry-trace"` and the `content` attribute must be generated by your backend's Sentry SDK using `span.toTraceparent()` (or equivalent, depending on the backend platform). +The `name` attribute must be the string `"sentry-trace"` and the `content` attribute must be generated by your backend's Sentry SDK using `span.toTraceparent()` (or equivalent, depending on the backend platform). This guarantees that a new and unique value will be generated for each request. -The `span` reference is either the transaction that rendered the page or any of its child spans. It defines the parent of the `pageload` transaction. +The `span` reference is either the transaction that serves the HTML, or any of its child spans. It defines the parent of the `pageload` transaction. -For the correct association of transactions in a trace, make sure your backend will render a new and unique value for the `content` attribute for every request. Reusing the same value will cause unrelated traces to incorrectly share the same `trace_id`. +Once the data is included in the `` tag, our `BrowserTracing` integration will pick it up automatically and link it to the transaction generated on pageload. (Note that it will not get linked to automatically-generated `navigation` transactions, that is, those which don't require a full page reload. Each of those will be the result of a different request transaction on the backend, and therefore should have a unique `trace_id`.) - +### Navigation and Other XHR Requests -JavaScript code running on a browser cannot read the response headers of the current page. Therefore, the `` tag is used to propagate tracing metadata from the backend instead of the `sentry-trace` HTTP header described earlier. +Once a page is loaded, any requests it makes and any responses your backend generates as a result are linked through a request/response header. - +As is the case with the `` tag discussed above, the header's name is `sentry-trace` and its value is obtained by calling `span.toTraceparent()` (or the equivalent), where `span` is either the relevant transaction or any of its children. -### beforeNavigate +All of Sentry's tracing-related integrations (`BrowserTracing`, `Http`, and `Express`) either generate or pick up and propagate this header automatically as appropriate, for all transactions and spans which they generate. You can also attach and read the header yourself, in any case in which you've manually created either a transaction or a span and it makes sense to do so. -For `pageload` and `navigation` transactions, the `BrowserTracing` integration uses the browser's `window.location` API to generate a transaction name. To customize the name of the `pageload` and `navigation` transactions, you can supply a `beforeNavigate` option to the `BrowserTracing` integration. This option allows you to pass in a function that takes in the location at the time of navigation and returns a new transaction name. +## Retrieving an Active Transaction -`beforeNavigate` is useful if you would like to leverage the routes from a custom routing library like `React Router` or if you want to reduce the cardinality of particular transactions. +In cases where you want to attach Spans to an already ongoing transaction you can use `Sentry.getCurrentHub().getScope().getTransaction()`. This function will return a `Transaction` object when there is a running transaction on the scope, otherwise it returns `undefined`. If you are using our BrowserTracing integration, by default we attach the transaction to the Scope, so you could do something like this: ```javascript -import * as Sentry from "@sentry/browser"; -import { Integrations } from "@sentry/tracing"; - -Sentry.init({ - dsn: "___PUBLIC_DSN___", - integrations: [ - new Integrations.BrowserTracing({ - beforeNavigate: context => { - return { - ...context, - // You could use your UI's routing library to find the matching - // route template here. We don't have one right now, so do some basic - // parameter replacements. - name: location.pathname - .replace(/\d+/g, "") - .replace(/[a-f0-9]{32}/g, ""), - }; - }, - }), - ], - tracesSampleRate: 1.0, // Be sure to lower this in production -}); +function myJsFunction() { + const transaction = Sentry.getCurrentHub() + .getScope() + .getTransaction(); + if (transaction) { + let span = transaction.startChild({ + op: "encode", + description: "parseAvatarImages", + }); + // Do something + span.finish(); + } +} ``` -### shouldCreateSpanForRequest +## Adding Query Information and Parameters to Spans -This function can be used to filter our unwanted Spans like XHR's running health checks or something similar. By default `shouldCreateSpanForRequest` is already filtering out what was defined in `tracingOrigins`. +Currently, every tag has a maximum character limit of 200 characters. Tags over the 200 character limit will become truncated, losing potentially important information. To retain this data, you can split data over several tags instead. -```javascript -import * as Sentry from "@sentry/browser"; -import { Integrations } from "@sentry/tracing"; -Sentry.init({ - dsn: "___PUBLIC_DSN___", - integrations: [ - new Integrations.BrowserTracing({ - shouldCreateSpanForRequest: url => { - // Example of filter out spans that contain `health` - if (url.match(/health/)) { - return false; - } - return true; - }, - }), - ], - tracesSampleRate: 1.0, // Be sure to lower this in production -}); -``` +For example, a 200+ character tagged request: -### Manual Instrumentation +`https://empowerplant.io/api/0/projects/ep/setup_form/?user_id=314159265358979323846264338327&tracking_id=EasyAsABC123OrSimpleAsDoReMi&product_name=PlantToHumanTranslator&product_id=161803398874989484820458683436563811772030917980576` -To manually instrument certain regions of your code, you can create a transaction to capture them. -This is valid for both JavaScript Browser and Node and works independently of the `BrowserTracing` integration. +The 200+ character request above will become truncated to: -```javascript -const transaction = Sentry.startTransaction({ name: "test-transaction" }); -const span = transaction.startChild({ op: "functionX" }); // This function returns a Span -// functionCallX -span.finish(); // Remember that only finished spans will be sent with the transaction -transaction.finish(); // Finishing the transaction will send it to Sentry -``` +`https://empowerplant.io/api/0/projects/ep/setup_form/?user_id=314159265358979323846264338327&tracking_id=EasyAsABC123OrSimpleAsDoReMi&product_name=PlantToHumanTranslator&product_id=1618033988749894848` -Here is a different example. If you want to create a transaction for a user interaction on your page, you need to do the following: +Instead, using `span.set_tag` and `span.set_data` preserves the details of this query using structured metadata. This could be done over `baseUrl`, `endpoint`, and `parameters`: ```javascript -// Let's say this function is invoked when a user clicks on the checkout button of your shop -shopCheckout() { - // This will create a new Transaction for you - const transaction = Sentry.startTransaction('shopCheckout'); - // set the transaction on the scope so it picks up any errors - hub.configureScope(scope => scope.setSpan(transaction)); - - // Assume this function makes an xhr/fetch call - const result = validateShoppingCartOnServer(); - - const span = transaction.startChild({ - data: { - result - }, - op: 'task', - description: `processing shopping cart result`, - }); - processAndValidateShoppingCart(result); - span.finish(); - - transaction.finish(); -} -``` - -This example will send a transaction `shopCheckout` to Sentry. The transaction will contain a `task` span that measures how long `processAndValidateShoppingCart` took. Finally, the call to `transaction.finish()` will finish the transaction and send it to Sentry. - -#### Adding Additional Spans to the Transaction +const baseUrl = "https://empowerplant.io"; +const endpoint = "/api/0/projects/ep/setup_form"; +const parameters = { + user_id: 314159265358979323846264338327, + tracking_id: "EasyAsABC123OrSimpleAsDoReMi", + product_name: PlantToHumanTranslator, + product_id: 161803398874989484820458683436563811772030917980576, +}; -The next example contains the implementation of the hypothetical `processItem` function called from the code snippet in the previous section. Our SDK can determine if there is currently an open transaction and add to it all newly created spans as child operations. Keep in mind that each individual span needs to be manually finished; otherwise, that span will not show up in the transaction. +const span = transaction.startChild({ + op: "request", + description: "setup form", +}); -```javascript -function processItem(item, transaction) { - const span = transaction.startChild({ - op: "http", - description: "GET /", - }); - - return new Promise((resolve, reject) => { - http.get(`/items/${item.id}`, response => { - response.on("data", () => {}); - response.on("end", () => { - span.setTag("http.status_code", response.statusCode); - span.setData("http.foobarsessionid", getFoobarSessionid(response)); - span.finish(); - resolve(response); - }); - }); - }); -} +span.setTag("baseUrl", baseUrl); +span.setTag("endpoint", endpoint); +span.setData("parameters", parameters); +// you may also find some parameters to be valuable as tags +span.setData("user_id", parameters.user_id); +http.get(`${base_url}/${endpoint}/`, (data = parameters)); ``` -### Grouping Transactions +## Grouping Transactions When Sentry captures transactions, they are assigned a transaction name. This name is generally auto-generated by the Sentry SDK based on the framework integrations you are using. If you can't leverage the automatic transaction generation (or want to customize how transaction names are generated) you can use a global event processor that is registered when you initialize the SDK with your configuration. @@ -255,60 +225,3 @@ Sentry.init({ ], }); ``` - -### Retrieving a Transaction - -In cases where you want to attach Spans to an already ongoing Transaction you can use `Sentry.getCurrentHub().getScope().getTransaction()`. This function will return a `Transaction` in case there is a running Transaction on the scope, otherwise it returns `undefined`. If you are using our BrowserTracing integration by default we attach the Transaction to the Scope. So you could do something like this: - -```javascript -function myJsFunction() { - const transaction = Sentry.getCurrentHub() - .getScope() - .getTransaction(); - if (transaction) { - let span = transaction.startChild({ - op: "encode", - description: "parseAvatarImages", - }); - // Do something - span.finish(); - } -} -``` - -### Adding Query Information and Parameters to Spans - -Currently, every tag has a maximum character limit of 200 characters. Tags over the 200 character limit will become truncated, losing potentially important information. To retain this data, you can split data over several tags instead. - -For example, a 200+ character tagged request: - -`https://empowerplant.io/api/0/projects/ep/setup_form/?user_id=314159265358979323846264338327&tracking_id=EasyAsABC123OrSimpleAsDoReMi&product_name=PlantToHumanTranslator&product_id=161803398874989484820458683436563811772030917980576` - -The 200+ character request above will become truncated to: - -`https://empowerplant.io/api/0/projects/ep/setup_form/?user_id=314159265358979323846264338327&tracking_id=EasyAsABC123OrSimpleAsDoReMi&product_name=PlantToHumanTranslator&product_id=1618033988749894848` - -Instead, using `span.set_tag` and `span.set_data` preserves the details of this query using structured metadata. This could be done over `baseUrl`, `endpoint`, and `parameters`: - -```javascript -const baseUrl = "https://empowerplant.io"; -const endpoint = "/api/0/projects/ep/setup_form"; -const parameters = { - user_id: 314159265358979323846264338327, - tracking_id: "EasyAsABC123OrSimpleAsDoReMi", - product_name: PlantToHumanTranslator, - product_id: 161803398874989484820458683436563811772030917980576, -}; - -const span = transaction.startChild({ - op: "request", - description: "setup form", -}); - -span.setTag("baseUrl", baseUrl); -span.setTag("endpoint", endpoint); -span.setData("parameters", parameters); -// you may also find some parameters to be valuable as tags -span.setData("user_id", parameters.user_id); -http.get(`${base_url}/${endpoint}/`, (data = parameters)); -``` diff --git a/src/platforms/javascript/common/performance/manual.mdx b/src/platforms/javascript/common/performance/manual.mdx new file mode 100644 index 00000000000000..da51e1b104d7e7 --- /dev/null +++ b/src/platforms/javascript/common/performance/manual.mdx @@ -0,0 +1,71 @@ +--- +title: Capturing Transactions Manually +sidebar_order: 20 +description: "Learn how to capture performance data on any action in your app." +--- + +### Manual Instrumentation + +To manually instrument certain regions of your code, you can create transactions to capture them. This is valid for all JavaScript SDKs (both backend and frontend) and works independently of the `Express`, `Http`, and `BrowserTracing` integrations. + +```javascript +const transaction = Sentry.startTransaction({ name: "test-transaction" }); +const span = transaction.startChild({ op: "functionX" }); // This function returns a Span +// functionCallX +span.finish(); // Remember that only finished spans will be sent with the transaction +transaction.finish(); // Finishing the transaction will send it to Sentry +``` + +For example, if you want to create a transaction for a user interaction on your page, you can do this: + +```javascript +// Let's say this function is invoked when a user clicks on the checkout button of your shop +shopCheckout() { + // This will create a new Transaction for you + const transaction = Sentry.startTransaction('shopCheckout'); + // set the transaction on the scope so it picks up any errors + hub.configureScope(scope => scope.setSpan(transaction)); + + // Assume this function makes an xhr/fetch call + const result = validateShoppingCartOnServer(); + + const span = transaction.startChild({ + data: { + result + }, + op: 'task', + description: `processing shopping cart result`, + }); + processAndValidateShoppingCart(result); + span.finish(); + + transaction.finish(); +} +``` + +This example will send a transaction `shopCheckout` to Sentry. The transaction will contain a `task` span that measures how long `processAndValidateShoppingCart` took. Finally, the call to `transaction.finish()` will finish the transaction and send it to Sentry. + +You can also take advantage of promises when creating spans for async operations. Keep in mind, though, that a span must finish before `transaction.finish()` is called in order to be included in the transaction. + +For example: + +```javascript +function processItem(item, transaction) { + const span = transaction.startChild({ + op: "http", + description: `GET /items/:item-id`, + }); + + return new Promise((resolve, reject) => { + http.get(`/items/${item.id}`, response => { + response.on("data", () => {}); + response.on("end", () => { + span.setTag("http.status_code", response.statusCode); + span.setData("http.foobarsessionid", getFoobarSessionid(response)); + span.finish(); + resolve(response); + }); + }); + }); +} +``` diff --git a/src/platforms/javascript/common/performance/sampling.mdx b/src/platforms/javascript/common/performance/sampling.mdx new file mode 100644 index 00000000000000..8d7cdb17951dab --- /dev/null +++ b/src/platforms/javascript/common/performance/sampling.mdx @@ -0,0 +1,140 @@ +--- +title: Sampling Transactions +sidebar_order: 20 +description: "Learn how to configure the volume of transactions sent to Sentry." +--- + +You can control the volume of transactions sent to Sentry in two ways. + +## Uniform Sample Rate + +Setting a uniform sample rate is a good option if you want an even cross-section of transactions, no matter where in your app or under what circumstances they occur, and are happy with the default inheritance and precedence behavior described below. + +To do this, set the `tracesSampleRate` option in your `Sentry.init()` to a number between 0 and 1. With this option set, every transaction created will have that percentage chance of being sent to Sentry. (So, for example, if you set `tracesSampleRate` to `0.2`, approximately 20% of your transactions will get recorded and sent.) That looks like this: + +```javascript {tabTitle: ESM} +// If you're using one of our integration packages, like `@sentry/react` or `@sentry/angular`, +// substitute its name for `@sentry/browser` here +import * as Sentry from "@sentry/browser"; + +// If taking advantage of automatic instrumentation (highly recommended) +import { Integrations as TracingIntegrations } from "@sentry/tracing"; +// Or, if only doing manual tracing +// import * as _ from "@sentry/tracing" +// Note: You MUST import the package in some way for tracing to work + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + + // This enables automatic instrumentation (highly recommeneded), but is not + // necessary for purely manual usage + integrations: [new TracingIntegrations.BrowserTracing()], + + // Each transaction has a 20% chance of being sent to Sentry + tracesSampleRate: 0.2, +}); +``` + +```javascript {tabTitle: CDN} +Sentry.init({ + dsn: "___PUBLIC_DSN___", + + // This enables automatic instrumentation (highly recommeneded), but is not + // necessary for purely manual usage + integrations: [new Sentry.Integrations.BrowserTracing()], + + // Each transaction has a 20% chance of being sent to Sentry + tracesSampleRate: 0.2, +}); +``` + +## Dynamic Sampling Function + +Providing a sampling function is a good option if you: + +- want to sample different transactions at different rates +- want to filer out some transactions entirely +- want to modify the default precedence and inheritance behavior described below + +To sample dynamically, set the `tracesSampler` option in your `Sentry.init()` to a function that will accept a `samplingContext` object and return a sample rate between 0 and 1. For example: + +```javascript +tracesSampler: samplingContext => { + // Examine provided context data (including parent decision, if any) along with anything + // in the global namespace to compute the sample rate or sampling decision for this transaction. + + if ("...") { + return 0.5; // These are important - take a big sample + } else if ("...") { + return 0.01; // These are less important or happen much more frequently - only take 1% of them + } else if ("...") { + return 0; // These aren't something worth tracking - drop all transactions like this + } else { + return 0.1; // Default sample rate + } +}; +``` + +For convenience, the function can also return a boolean. Returning `true` is equivalent to returning `1`, and will guarantee the transaction will be sent to Sentry. Returning `false` is equivalent to returning `0` and will guarantee the transaction will **not** be sent to Sentry. + +### Default Sampling Context Data + +The information contained in the `samplingContext` object passed to the `tracesSampler` when a transaction is created varies by platform. + + + +### Custom Sampling Context Data + +When manually creating a transaction, you can add data to the `samplingContext` by passing it as an optional second argument to `startTransaction()`. This is useful if there's data to which you want the sampler to have access but which you don't want to attach to the transaction as `tags` or `data`, such as information that's sensitive or that’s too large to send with the transaction. For example: + + + +## Inheritance + +Whatever a transaction's sampling decision, that decision will be passed to its child spans and from there to any transactions they subsequently cause in other services. (See [Connecting Backend and Frontend Transactions](/platforms/javascript/performance/) for more about how that propogation is done.) + +If the transaction currently being created is one of those subsequent transactions (in other words, if it has a parent transaction), the upstream (parent) sampling decision will always be included in the sampling context data, so that your `tracesSampler` can choose whether and when to inherit that decision. (In most cases, inheritance is the right choice, so that you don't end up with partial traces.) + +For convenience, the `tracesSampler` function can return a boolean, so that a parent's decision can be returned directly if that's the desired behavior. + +```javascript +tracesSampler: samplingContext => { + // always inherit + if (samplingContext.parentSampled !== undefined) { + return samplingContext.parentSampled + } + + ... + // rest of sampling logic here +} +``` + +If you're using a `tracesSampleRate` rather than a `tracesSampler`, the decision will always be inherited. + +## Forcing a Sampling Decision + +If you know at transaction creation time whether or not you want the transaction sent to Sentry, you also have the option of passing a sampling decision directly to the transaction in the `transactionContext` object (note, not the `customSamplingContext` object). If you do that, the transaction won't be subject to the `tracesSampleRate`, nor will `tracesSampler` be run, so you can count on the decision that's passed not to be overwritten. + +```javascript +Sentry.startTransaction({ + name: "Search from navbar", + sampled: true, +}); +``` + +## Precedence + +There are multiple ways for a transaction to end up with a sampling decision. + +- Random sampling according to a static sample rate set in `tracesSampleRate` +- Random sampling according to a dynamic sample rate returned by `tracesSampler` +- Absolute decision (100% chance or 0% chance) returned by `tracesSampler` +- If the transaction has a parent, inheriting its parent's sampling decision +- Absolute decision passed to `startTransaction` + +When there's the potential for more than one of these to come into play, the following precedence rules apply: + +1. If a sampling decision is passed to `startTransaction` (`startTransaction({name: "my transaction", sampled: true})`), that decision will be used, regardlesss of anything else +2. If `tracesSampleRate` is defined, its decision will be used. It can choose to keep or ignore any parent sampling decision, or use the sampling context data to make its own decision or choose a sample rate for the transaction. +3. If `tracesSampler` is not defined, but there's a parent sampling decision, the parent sampling decision will be used. +4. If `tracesSampler` is not defined and there's no parent sampling decision, `tracesSampleRate` will be used. diff --git a/src/platforms/javascript/guides/angular/index.mdx b/src/platforms/javascript/guides/angular/index.mdx index 26e3b58611bc45..3f707134510564 100644 --- a/src/platforms/javascript/guides/angular/index.mdx +++ b/src/platforms/javascript/guides/angular/index.mdx @@ -104,7 +104,10 @@ Sentry.init({ routingInstrumentation: Sentry.routingInstrumentation, }), ], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/guides/react/index.mdx b/src/platforms/javascript/guides/react/index.mdx index bb7d1c57f27c88..ff677e5978a61c 100644 --- a/src/platforms/javascript/guides/react/index.mdx +++ b/src/platforms/javascript/guides/react/index.mdx @@ -144,7 +144,10 @@ Sentry.init({ dsn: "___PUBLIC_DSN___", release: "my-project-name@" + process.env.npm_package_version, integrations: [new Integrations.BrowserTracing()], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/guides/react/integrations/react-router.mdx b/src/platforms/javascript/guides/react/integrations/react-router.mdx index 9e9769f0fcfa0c..df2cb0f6d1ba9e 100644 --- a/src/platforms/javascript/guides/react/integrations/react-router.mdx +++ b/src/platforms/javascript/guides/react/integrations/react-router.mdx @@ -29,14 +29,16 @@ import { Integrations } from '@sentry/tracing'; const history = createBrowserHistory(); Sentry.init({ - tracesSampleRate: 1, integrations: [ new Integrations.BrowserTracing({ // Can also use reactRouterV4Instrumentation routingInstrumentation: Sentry.reactRouterV5Instrumentation(history), }); ], - // ... + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, }); // ... @@ -75,12 +77,15 @@ const history = createBrowserHistory(); const routes = [{ path: '/users/:userid' }, { path: '/users' }, { path: '/' }]; Sentry.init({ - tracesSampleRate: 1, integrations: [ new Integrations.BrowserTracing({ routingInstrumentation: Sentry.reactRouterV5Instrumentation(history, routes, matchPath), }); - ] + ], + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, }); // In your App render: @@ -114,12 +119,15 @@ const SentryRoute = Sentry.withSentryRouting(Route); const history = createBrowserHistory(); Sentry.init({ - tracesSampleRate: 1, integrations: [ new Integrations.BrowserTracing({ routingInstrumentation: Sentry.reactRouterV5Instrumentation(history), }); - ] + ], + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, }); render() { @@ -156,7 +164,6 @@ const routes = ( ); Sentry.init({ - tracesSampleRate: 1, integrations: [ new Integrations.BrowserTracing({ routingInstrumentation: Sentry.reactRouterV3Instrumentation( @@ -166,7 +173,11 @@ Sentry.init({ Router.match, ), }); - ] + ], + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/guides/vue/index.mdx b/src/platforms/javascript/guides/vue/index.mdx index ef7a5371c0e649..42ab6cdc6a4b85 100644 --- a/src/platforms/javascript/guides/vue/index.mdx +++ b/src/platforms/javascript/guides/vue/index.mdx @@ -100,7 +100,10 @@ Sentry.init({ tracing: true, }), ], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/guides/vue/integrations/components.mdx b/src/platforms/javascript/guides/vue/integrations/components.mdx index 348c490486c6b6..bc8ec32b2ad978 100644 --- a/src/platforms/javascript/guides/vue/integrations/components.mdx +++ b/src/platforms/javascript/guides/vue/integrations/components.mdx @@ -34,7 +34,10 @@ Sentry.init({ tracing: true, }), ], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/index.mdx b/src/platforms/javascript/index.mdx index af9454f25955db..a29652cc486a8d 100644 --- a/src/platforms/javascript/index.mdx +++ b/src/platforms/javascript/index.mdx @@ -118,13 +118,16 @@ Sentry.init({ dsn: "___PUBLIC_DSN___", release: "my-project-name@" + process.env.npm_package_version, integrations: [new Integrations.BrowserTracing()], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, }); ``` -Performance data is transmitted using a new event type called “transactions”, which you can learn about in [Distributed Tracing](/product/performance/distributed-tracing/). To capture transactions, install the performance package and configure your SDK to set the `tracesSampleRate` configuration to a nonzero value. The example configuration above will transmit 100% of captured transactions; lower this value in production to avoid consuming your quota too quickly. +Performance data is transmitted using a new event type called “transactions,” which you can learn about in [Distributed Tracing](/product/performance/distributed-tracing/). To begin capturing transactions, install the tracing package and set either `tracesSampleRate` or `tracesSampler` in your [SDK configuration](/platforms/javascript/configuration/options/#common-options). These determine what percentage of potential transactions get sent to Sentry; we recommend capturing only a sample, as one way to adjust your overall Sentry volume to meet your needs. -Learn more about sampling in [Filtering Events Reported to Sentry](configuration/filtering). +Learn more about `tracesSampleRate` and `tracesSampler` in [Sampling Transactions](/performance/sampling). ## Next Steps diff --git a/src/platforms/node/common/performance/index.mdx b/src/platforms/node/common/performance/index.mdx index af489e8ec4422b..b6326bdd3746b3 100644 --- a/src/platforms/node/common/performance/index.mdx +++ b/src/platforms/node/common/performance/index.mdx @@ -13,11 +13,14 @@ const http = require("http"); Sentry.init({ dsn: "___PUBLIC_DSN___", - tracesSampleRate: 1.0, integrations: [ // enable HTTP calls tracing new Sentry.Integrations.Http({ tracing: true }), ], + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, }); const transaction = Sentry.startTransaction({ diff --git a/src/platforms/node/guides/express/index.mdx b/src/platforms/node/guides/express/index.mdx index 261018439a7879..f7aad34a954394 100644 --- a/src/platforms/node/guides/express/index.mdx +++ b/src/platforms/node/guides/express/index.mdx @@ -166,7 +166,10 @@ Sentry.init({ // enable Express.js middleware tracing new Tracing.Integrations.Express({ app }), ], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, }); // RequestHandler creates a separate execution context using domains, so that every diff --git a/src/platforms/node/guides/koa/index.mdx b/src/platforms/node/guides/koa/index.mdx index 315ac26f7151de..cb72b484197ba8 100644 --- a/src/platforms/node/guides/koa/index.mdx +++ b/src/platforms/node/guides/koa/index.mdx @@ -51,18 +51,25 @@ $ npm install --save @sentry/node @sentry/tracing $ yarn add @sentry/node @sentry/tracing ``` -Creates and attaches a transaction to each context +Create and attach a transaction to each request: ```javascript const Sentry = require("@sentry/node"); -const { Span } = require("@sentry/tracing"); +const { + extractTraceparentData, + Span, + stripUrlQueryAndFragment, +} = require("@sentry/tracing"); const Koa = require("koa"); const app = new Koa(); const domain = require("domain"); Sentry.init({ dsn: "___PUBLIC_DSN___", - tracesSampleRate: 1.0, // Be sure to lower this in production + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, }); // not mandatory, but adding domains does help a lot with breadcrumbs @@ -89,33 +96,28 @@ const requestHandler = (ctx, next) => { // this tracing middleware creates a transaction per request const tracingMiddleWare = async (ctx, next) => { - // captures span of upstream app - const sentryTraceId = ctx.request.get("sentry-trace"); - let traceId; - let parentSpanId; - let sampled; - if (sentryTraceId) { - const span = Span.fromTraceparent(sentryTraceId); - if (span) { - traceId = span.traceId; - parentSpanId = span.parentSpanId; - sampled = span.sampled; - } + const reqMethod = (ctx.method || "").toUpperCase(); + const reqUrl = ctx.url && stripUrlQueryAndFragment(ctx.url); + + // connect to trace of upstream app + let traceparentData; + if (ctx.request.get("sentry-trace")) { + traceparentData = extractTraceparentData(ctx.request.get("sentry-trace")); } - const transaction = Sentry.startTransaction({ - name: `${ctx.method} ${ctx.url}`, + + const transaction = startTransaction({ + name: `${reqMethod} ${reqUrl}`, op: "http.server", - parentSpanId, - traceId, - sampled, + ...traceparentData, }); + ctx.__sentry_transaction = transaction; await next(); // if using koa router, a nicer way to capture transaction using the matched route if (ctx._matchedRoute) { const mountPath = ctx.mountPath || ""; - transaction.setName(`${ctx.method} ${mountPath}${ctx._matchedRoute}`); + transaction.setName(`${reqMethod} ${mountPath}${ctx._matchedRoute}`); } transaction.setHttpStatus(ctx.status); transaction.finish(); diff --git a/src/platforms/node/index.mdx b/src/platforms/node/index.mdx index 7ef1acf3053e89..a5d8ef89b44037 100644 --- a/src/platforms/node/index.mdx +++ b/src/platforms/node/index.mdx @@ -70,7 +70,10 @@ const Tracing = require("@sentry/tracing"); Sentry.init({ dsn: "___PUBLIC_DSN___", - tracesSampleRate: 1.0, // Be sure to lower this in production + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, }); ``` @@ -80,7 +83,10 @@ import * as Tracing from "@sentry/tracing"; Sentry.init({ dsn: "___PUBLIC_DSN___", - tracesSampleRate: 1.0, // Be sure to lower this in production + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/wizard/javascript/angular.md b/src/wizard/javascript/angular.md index 13bf9b6237936d..47a95592e6b3a5 100644 --- a/src/wizard/javascript/angular.md +++ b/src/wizard/javascript/angular.md @@ -35,6 +35,9 @@ Sentry.init({ routingInstrumentation: Sentry.routingInstrumentation, }), ], + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); diff --git a/src/wizard/javascript/index.md b/src/wizard/javascript/index.md index 7ab5c1791a57f5..596d91764416f3 100644 --- a/src/wizard/javascript/index.md +++ b/src/wizard/javascript/index.md @@ -26,6 +26,9 @@ Sentry.init({ integrations: [ new Integrations.BrowserTracing(), ], + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` diff --git a/src/wizard/javascript/react.md b/src/wizard/javascript/react.md index 72af152fc05eaf..8be3dd94df14ae 100644 --- a/src/wizard/javascript/react.md +++ b/src/wizard/javascript/react.md @@ -36,6 +36,9 @@ Sentry.init({ integrations: [ new Integrations.BrowserTracing(), ], + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); diff --git a/src/wizard/javascript/vue.md b/src/wizard/javascript/vue.md index abf32c6a166c9e..3c442db4362dd5 100644 --- a/src/wizard/javascript/vue.md +++ b/src/wizard/javascript/vue.md @@ -44,7 +44,10 @@ Sentry.init({ }), new Integrations.BrowserTracing(), ], - tracesSampleRate: 1, + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, }); ``` @@ -79,7 +82,10 @@ Sentry.init({ }), new Sentry.Integrations.BrowserTracing(), ], - tracesSampleRate: 1, + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/wizard/node/express.md b/src/wizard/node/express.md index 5f0ad6c0a3cd3a..b50d79b8c23ed9 100644 --- a/src/wizard/node/express.md +++ b/src/wizard/node/express.md @@ -37,6 +37,9 @@ Sentry.init({ // enable Express.js middleware tracing new Tracing.Integrations.Express({ app }), ], + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); diff --git a/src/wizard/node/index.md b/src/wizard/node/index.md index ecd5568b084801..ef50cdefcf6ed0 100644 --- a/src/wizard/node/index.md +++ b/src/wizard/node/index.md @@ -28,6 +28,9 @@ const Tracing = require("@sentry/tracing"); Sentry.init({ dsn: "___PUBLIC_DSN___", + + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); From 5056fae7e754278e7efd33d0ed7d9bd38a5d47e0 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Wed, 30 Sep 2020 14:42:37 -0700 Subject: [PATCH 18/20] fix: Language --- src/platforms/javascript/common/integrations/rrweb.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platforms/javascript/common/integrations/rrweb.mdx b/src/platforms/javascript/common/integrations/rrweb.mdx index 0a227fad1255f4..e3ea73200cadac 100644 --- a/src/platforms/javascript/common/integrations/rrweb.mdx +++ b/src/platforms/javascript/common/integrations/rrweb.mdx @@ -14,7 +14,7 @@ Sentry provides a proof-of-concept integration with [rrweb](https://www.rrweb.io -Replays utilize the [Attachments](../../enriching-events/attachments/), which are billed separately from errors. +Replays utilize [Attachments](../../enriching-events/attachments/), which are billed separately from errors. From de38d62d1684ca3ebc46d0cc4742ab08936dfc17 Mon Sep 17 00:00:00 2001 From: Colleen O'Rourke Date: Wed, 30 Sep 2020 14:55:28 -0700 Subject: [PATCH 19/20] feat(api-docs): Remove old unused API docs files (#2400) --- Dockerfile.apidocs | 75 ------------------ bin/update-api-docs | 11 --- scripts/build-api-docs | 26 ------- src/api/events/delete-group-details.json | 20 ----- .../events/delete-project-group-index.json | 31 -------- src/api/events/get-group-details.json | 20 ----- src/api/events/get-group-events-latest.json | 20 ----- src/api/events/get-group-events-oldest.json | 20 ----- src/api/events/get-group-events.json | 26 ------- src/api/events/get-group-hashes.json | 20 ----- src/api/events/get-group-tag-key-details.json | 25 ------ src/api/events/get-group-tag-key-values.json | 25 ------ src/api/events/get-project-event-details.json | 30 -------- src/api/events/get-project-events.json | 31 -------- src/api/events/get-project-group-index.json | 41 ---------- src/api/events/index.mdx | 5 -- src/api/events/put-group-details.json | 51 ------------ src/api/events/put-project-group-index.json | 77 ------------------- .../delete-organization-details.json | 20 ----- .../organizations/get-event-id-lookup.json | 26 ------- .../get-organization-details.json | 20 ----- .../organizations/get-organization-index.json | 25 ------ .../get-organization-projects.json | 20 ----- .../get-organization-repositories.json | 20 ----- .../get-organization-repository-commits.json | 25 ------ .../organizations/get-organization-stats.json | 41 ---------- .../organizations/get-organization-users.json | 26 ------- .../organizations/get-short-id-lookup.json | 25 ------ src/api/organizations/index.mdx | 5 -- .../post-organization-index.json | 30 -------- .../put-organization-details.json | 31 -------- src/api/projects/delete-debug-files.json | 31 -------- src/api/projects/delete-project-details.json | 25 ------ .../projects/delete-project-key-details.json | 30 -------- .../delete-project-service-hook-details.json | 30 -------- src/api/projects/get-debug-files.json | 36 --------- src/api/projects/get-project-details.json | 25 ------ src/api/projects/get-project-index.json | 14 ---- src/api/projects/get-project-keys.json | 25 ------ .../get-project-service-hook-details.json | 30 -------- .../projects/get-project-service-hooks.json | 25 ------ src/api/projects/get-project-stats.json | 46 ----------- .../projects/get-project-tag-key-values.json | 30 -------- .../projects/get-project-user-reports.json | 25 ------ src/api/projects/get-project-users.json | 36 --------- src/api/projects/index.mdx | 5 -- src/api/projects/post-debug-files.json | 31 -------- src/api/projects/post-project-keys.json | 31 -------- .../projects/post-project-service-hooks.json | 36 --------- .../projects/post-project-user-reports.json | 46 ----------- src/api/projects/put-project-details.json | 61 --------------- src/api/projects/put-project-key-details.json | 36 --------- .../put-project-service-hook-details.json | 41 ---------- .../delete-organization-release-details.json | 25 ------ ...ete-organization-release-file-details.json | 30 -------- .../delete-project-release-file-details.json | 35 --------- src/api/releases/get-commit-file-change.json | 25 ------ .../get-organization-release-commits.json | 25 ------ .../get-organization-release-details.json | 25 ------ ...get-organization-release-file-details.json | 30 -------- .../get-organization-release-files.json | 25 ------ .../releases/get-organization-releases.json | 26 ------- ...et-project-issues-resolved-in-release.json | 30 -------- .../releases/get-project-release-commits.json | 30 -------- .../get-project-release-file-details.json | 35 --------- .../releases/get-project-release-files.json | 30 -------- src/api/releases/get-release-deploys.json | 25 ------ src/api/releases/index.mdx | 5 -- .../post-organization-release-files.json | 46 ----------- .../releases/post-organization-releases.json | 56 -------------- .../releases/post-project-release-files.json | 51 ------------ src/api/releases/post-release-deploys.json | 51 ------------ .../put-organization-release-details.json | 51 ------------ ...put-organization-release-file-details.json | 41 ---------- .../put-project-release-file-details.json | 41 ---------- src/api/teams/delete-team-details.json | 14 ---- src/api/teams/get-organization-teams.json | 20 ----- src/api/teams/get-team-details.json | 25 ------ src/api/teams/get-team-projects.json | 25 ------ src/api/teams/get-team-stats.json | 46 ----------- src/api/teams/index.mdx | 5 -- src/api/teams/post-organization-teams.json | 31 -------- src/api/teams/post-team-projects.json | 36 --------- src/api/teams/put-team-details.json | 36 --------- 84 files changed, 2539 deletions(-) delete mode 100644 Dockerfile.apidocs delete mode 100755 bin/update-api-docs delete mode 100755 scripts/build-api-docs delete mode 100644 src/api/events/delete-group-details.json delete mode 100644 src/api/events/delete-project-group-index.json delete mode 100644 src/api/events/get-group-details.json delete mode 100644 src/api/events/get-group-events-latest.json delete mode 100644 src/api/events/get-group-events-oldest.json delete mode 100644 src/api/events/get-group-events.json delete mode 100644 src/api/events/get-group-hashes.json delete mode 100644 src/api/events/get-group-tag-key-details.json delete mode 100644 src/api/events/get-group-tag-key-values.json delete mode 100644 src/api/events/get-project-event-details.json delete mode 100644 src/api/events/get-project-events.json delete mode 100644 src/api/events/get-project-group-index.json delete mode 100644 src/api/events/index.mdx delete mode 100644 src/api/events/put-group-details.json delete mode 100644 src/api/events/put-project-group-index.json delete mode 100644 src/api/organizations/delete-organization-details.json delete mode 100644 src/api/organizations/get-event-id-lookup.json delete mode 100644 src/api/organizations/get-organization-details.json delete mode 100644 src/api/organizations/get-organization-index.json delete mode 100644 src/api/organizations/get-organization-projects.json delete mode 100644 src/api/organizations/get-organization-repositories.json delete mode 100644 src/api/organizations/get-organization-repository-commits.json delete mode 100644 src/api/organizations/get-organization-stats.json delete mode 100644 src/api/organizations/get-organization-users.json delete mode 100644 src/api/organizations/get-short-id-lookup.json delete mode 100644 src/api/organizations/index.mdx delete mode 100644 src/api/organizations/post-organization-index.json delete mode 100644 src/api/organizations/put-organization-details.json delete mode 100644 src/api/projects/delete-debug-files.json delete mode 100644 src/api/projects/delete-project-details.json delete mode 100644 src/api/projects/delete-project-key-details.json delete mode 100644 src/api/projects/delete-project-service-hook-details.json delete mode 100644 src/api/projects/get-debug-files.json delete mode 100644 src/api/projects/get-project-details.json delete mode 100644 src/api/projects/get-project-index.json delete mode 100644 src/api/projects/get-project-keys.json delete mode 100644 src/api/projects/get-project-service-hook-details.json delete mode 100644 src/api/projects/get-project-service-hooks.json delete mode 100644 src/api/projects/get-project-stats.json delete mode 100644 src/api/projects/get-project-tag-key-values.json delete mode 100644 src/api/projects/get-project-user-reports.json delete mode 100644 src/api/projects/get-project-users.json delete mode 100644 src/api/projects/index.mdx delete mode 100644 src/api/projects/post-debug-files.json delete mode 100644 src/api/projects/post-project-keys.json delete mode 100644 src/api/projects/post-project-service-hooks.json delete mode 100644 src/api/projects/post-project-user-reports.json delete mode 100644 src/api/projects/put-project-details.json delete mode 100644 src/api/projects/put-project-key-details.json delete mode 100644 src/api/projects/put-project-service-hook-details.json delete mode 100644 src/api/releases/delete-organization-release-details.json delete mode 100644 src/api/releases/delete-organization-release-file-details.json delete mode 100644 src/api/releases/delete-project-release-file-details.json delete mode 100644 src/api/releases/get-commit-file-change.json delete mode 100644 src/api/releases/get-organization-release-commits.json delete mode 100644 src/api/releases/get-organization-release-details.json delete mode 100644 src/api/releases/get-organization-release-file-details.json delete mode 100644 src/api/releases/get-organization-release-files.json delete mode 100644 src/api/releases/get-organization-releases.json delete mode 100644 src/api/releases/get-project-issues-resolved-in-release.json delete mode 100644 src/api/releases/get-project-release-commits.json delete mode 100644 src/api/releases/get-project-release-file-details.json delete mode 100644 src/api/releases/get-project-release-files.json delete mode 100644 src/api/releases/get-release-deploys.json delete mode 100644 src/api/releases/index.mdx delete mode 100644 src/api/releases/post-organization-release-files.json delete mode 100644 src/api/releases/post-organization-releases.json delete mode 100644 src/api/releases/post-project-release-files.json delete mode 100644 src/api/releases/post-release-deploys.json delete mode 100644 src/api/releases/put-organization-release-details.json delete mode 100644 src/api/releases/put-organization-release-file-details.json delete mode 100644 src/api/releases/put-project-release-file-details.json delete mode 100644 src/api/teams/delete-team-details.json delete mode 100644 src/api/teams/get-organization-teams.json delete mode 100644 src/api/teams/get-team-details.json delete mode 100644 src/api/teams/get-team-projects.json delete mode 100644 src/api/teams/get-team-stats.json delete mode 100644 src/api/teams/index.mdx delete mode 100644 src/api/teams/post-organization-teams.json delete mode 100644 src/api/teams/post-team-projects.json delete mode 100644 src/api/teams/put-team-details.json diff --git a/Dockerfile.apidocs b/Dockerfile.apidocs deleted file mode 100644 index 1287ccbcdff1ed..00000000000000 --- a/Dockerfile.apidocs +++ /dev/null @@ -1,75 +0,0 @@ -# Sentry api documentation generation environment -# -# Instructions: -# -# Build the container: -# $ docker build -t sentry:apidocs -f Dockerfile.apidocs . -# Run the container: -# $ docker run --rm -v $(pwd):/usr/src/output sentry:apidocs -# -# The container will dump the generated documentation in markdown and JSON -# formats into the /usr/src/output directory which you should mount as a volume -# -FROM python:2.7.15-slim-stretch - -RUN mkdir -p /usr/share/man/man1 \ - /usr/share/man/man2 \ - /usr/share/man/man3 \ - /usr/share/man/man4 \ - /usr/share/man/man5 \ - /usr/share/man/man6 \ - /usr/share/man/man7 - -RUN groupadd -r redis --gid=998 \ - && useradd -r -g redis --uid=998 redis \ - && groupadd -r postgres --gid=999 \ - && useradd -r -g postgres --uid=999 postgres - -ENV PG_MAJOR 9.6 -ENV PATH /usr/lib/postgresql/$PG_MAJOR/bin:$PATH - -RUN apt-get update && apt-get install -y --no-install-recommends \ - ca-certificates \ - clang \ - curl \ - g++ \ - gcc \ - git \ - libffi-dev \ - libjpeg-dev \ - libpq-dev \ - libxml2-dev \ - libxmlsec1-dev \ - libxslt-dev \ - libyaml-dev \ - llvm \ - bzip2 \ - make \ - postgresql-$PG_MAJOR \ - postgresql-contrib-$PG_MAJOR \ - redis-server \ - unzip \ - && rm -rf /var/lib/apt/lists/* - -# Sane defaults for pip -ENV PIP_NO_CACHE_DIR off -ENV PIP_DISABLE_PIP_VERSION_CHECK on -ENV PYTHONUNBUFFERED 1 - -# Disable yarn installation -ENV SENTRY_LIGHT_BUILD=1 - -# Update postgres configuration to allow local access -RUN rm "/etc/postgresql/$PG_MAJOR/main/pg_hba.conf" \ - && touch "/etc/postgresql/$PG_MAJOR/main/pg_hba.conf" \ - && chown -R postgres "/etc/postgresql/$PG_MAJOR/main/pg_hba.conf" \ - && { echo; echo "host all all 0.0.0.0/0 trust"; } >> "/etc/postgresql/$PG_MAJOR/main/pg_hba.conf" \ - && { echo; echo "local all all trust"; } >> "/etc/postgresql/$PG_MAJOR/main/pg_hba.conf" - -RUN mkdir -p /usr/src/bin -COPY scripts/build-api-docs /usr/bin - -WORKDIR /usr/src -VOLUME /usr/src/output - -CMD [ "/usr/bin/build-api-docs" ] diff --git a/bin/update-api-docs b/bin/update-api-docs deleted file mode 100755 index 60ddfc03b92c96..00000000000000 --- a/bin/update-api-docs +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash -echo "--> Building docker image" -docker build -t sentry:apidocs -f Dockerfile.apidocs . - -echo "--> Building API docs" -mkdir -p apidocs -docker run -v $(pwd)/apidocs:/usr/src/output sentry:apidocs - -echo "--> Moving API docs in-place" -rm -rf src/collections/_documentation/api/{events,organizations,projects,releases,teams} -cp -R apidocs/markdown/{events,organizations,projects,releases,teams} src/collections/_documentation/api diff --git a/scripts/build-api-docs b/scripts/build-api-docs deleted file mode 100755 index c4a06c05cb7300..00000000000000 --- a/scripts/build-api-docs +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -branch=master - -echo "--> Starting postgres" -su postgres -c 'mkdir -p /var/lib/postgresql/data' -su postgres -c '/usr/lib/postgresql/9.6/bin/initdb -D /var/lib/postgresql/data' -su postgres -c '/usr/lib/postgresql/9.6/bin/pg_ctl -D /var/lib/postgresql/data start' & -su postgres -c 'createdb -U postgres -E utf8 --template template0 sentry_api_docs' -su postgres -c 'psql -U postgres -h 127.0.0.1 -c "CREATE EXTENSION IF NOT EXISTS citext WITH SCHEMA public;"' - -echo "--> Fetching sentry source" -curl -Ls https://github.com/getsentry/sentry/archive/${branch}.zip --output sentry.zip -unzip sentry.zip - -echo "--> Installing sentry dependencies" -cd sentry-${branch} - -export SENTRY_LIGHT_BUILD=1 -pip install -U setuptools -pip install -e '.[dev]' - -echo "--> Starting Redis" -redis-server & - -echo "--> Building API docs" -python api-docs/generator.py --output-path=/usr/src/output --output-format=both diff --git a/src/api/events/delete-group-details.json b/src/api/events/delete-group-details.json deleted file mode 100644 index 267e169ce4fa6f..00000000000000 --- a/src/api/events/delete-group-details.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "api_path": "/api/0/issues/{issue_id}/", - "authentication": "required", - "description": "Removes an individual issue.", - "example_request": "DELETE /api/0/issues/5/ HTTP/1.1\nHost: sentry.io\nAuthorization: Bearer ", - "example_response": "HTTP/1.1 202 ACCEPTED\nContent-Length: 0\nX-XSS-Protection: 1; mode=block\nContent-Language: en\nX-Content-Type-Options: nosniff\nVary: Accept-Language, Cookie\nAllow: GET, PUT, DELETE, HEAD, OPTIONS\nX-Frame-Options: deny", - "method": "DELETE", - "parameters": null, - "path_parameters": [ - { - "description": "the ID of the issue to delete.", - "name": "issue_id", - "type": "string" - } - ], - "query_parameters": null, - "sidebar_order": 8, - "title": "Remove an Issue", - "warning": null -} diff --git a/src/api/events/delete-project-group-index.json b/src/api/events/delete-project-group-index.json deleted file mode 100644 index c8d692887d89e9..00000000000000 --- a/src/api/events/delete-project-group-index.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "api_path": "/api/0/projects/{organization_slug}/{project_slug}/issues/", - "authentication": "required", - "description": "Permanently remove the given issues. The list of issues to\nmodify is given through the `id` query parameter. It is repeated\nfor each issue that should be removed.\n\nOnly queries by 'id' are accepted.\n\nIf any ids are out of scope this operation will succeed without\nany data mutation.", - "example_request": "DELETE /api/0/projects/the-interstellar-jurisdiction/amazing-plumbing/issues/?id=5&id=6 HTTP/1.1\nHost: sentry.io\nAuthorization: Bearer ", - "example_response": "HTTP/1.1 204 NO CONTENT\nContent-Length: 0\nX-XSS-Protection: 1; mode=block\nContent-Language: en\nX-Content-Type-Options: nosniff\nVary: Accept-Language, Cookie\nAllow: GET, PUT, DELETE, HEAD, OPTIONS\nX-Frame-Options: deny", - "method": "DELETE", - "parameters": null, - "path_parameters": [ - { - "description": "the slug of the organization the issues belong to.", - "name": "organization_slug", - "type": "string" - }, - { - "description": "the slug of the project the issues belong to.", - "name": "project_slug", - "type": "string" - } - ], - "query_parameters": [ - { - "description": "a list of IDs of the issues to be removed. This parameter shall be repeated for each issue.", - "name": "id", - "type": "int" - } - ], - "sidebar_order": 5, - "title": "Bulk Remove a List of Issues", - "warning": null -} diff --git a/src/api/events/get-group-details.json b/src/api/events/get-group-details.json deleted file mode 100644 index ad20875585e3aa..00000000000000 --- a/src/api/events/get-group-details.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "api_path": "/api/0/issues/{issue_id}/", - "authentication": "required", - "description": "Return details on an individual issue. This returns the basic stats for\nthe issue (title, last seen, first seen), some overall numbers (number\nof comments, user reports) as well as the summarized event data.", - "example_request": "GET /api/0/issues/1/ HTTP/1.1\nHost: sentry.io\nAuthorization: Bearer ", - "example_response": "HTTP/1.1 200 OK\nContent-Length: 2741\nX-XSS-Protection: 1; mode=block\nContent-Language: en\nX-Content-Type-Options: nosniff\nVary: Accept-Language, Cookie\nAllow: GET, PUT, DELETE, HEAD, OPTIONS\nX-Frame-Options: deny\nContent-Type: application/json\n\n{\n \"activity\": [\n {\n \"data\": {}, \n \"dateCreated\": \"2018-11-06T21:19:55Z\", \n \"id\": \"0\", \n \"type\": \"first_seen\", \n \"user\": null\n }\n ], \n \"annotations\": [], \n \"assignedTo\": null, \n \"count\": \"1\", \n \"culprit\": \"raven.scripts.runner in main\", \n \"firstRelease\": {\n \"authors\": [], \n \"commitCount\": 0, \n \"data\": {}, \n \"dateCreated\": \"2018-11-06T21:19:55.146Z\", \n \"dateReleased\": null, \n \"deployCount\": 0, \n \"firstEvent\": \"2018-11-06T21:19:55.271Z\", \n \"lastCommit\": null, \n \"lastDeploy\": null, \n \"lastEvent\": \"2018-11-06T21:19:55.271Z\", \n \"newGroups\": 0, \n \"owner\": null, \n \"projects\": [\n {\n \"name\": \"Pump Station\", \n \"slug\": \"pump-station\"\n }\n ], \n \"ref\": null, \n \"shortVersion\": \"1764232\", \n \"url\": null, \n \"version\": \"17642328ead24b51867165985996d04b29310337\"\n }, \n \"firstSeen\": \"2018-11-06T21:19:55Z\", \n \"hasSeen\": false, \n \"id\": \"1\", \n \"isBookmarked\": false, \n \"isPublic\": false, \n \"isSubscribed\": true, \n \"lastRelease\": null, \n \"lastSeen\": \"2018-11-06T21:19:55Z\", \n \"level\": \"error\", \n \"logger\": null, \n \"metadata\": {\n \"title\": \"This is an example Python exception\"\n }, \n \"numComments\": 0, \n \"participants\": [], \n \"permalink\": \"https://sentry.io/the-interstellar-jurisdiction/pump-station/issues/1/\", \n \"pluginActions\": [], \n \"pluginContexts\": [], \n \"pluginIssues\": [], \n \"project\": {\n \"id\": \"2\", \n \"name\": \"Pump Station\", \n \"slug\": \"pump-station\"\n }, \n \"seenBy\": [], \n \"shareId\": null, \n \"shortId\": \"PUMP-STATION-1\", \n \"stats\": {\n \"24h\": [\n [\n 1541451600.0, \n 557\n ], \n [\n 1541455200.0, \n 473\n ], \n [\n 1541458800.0, \n 914\n ], \n [\n 1541462400.0, \n 991\n ], \n [\n 1541466000.0, \n 925\n ], \n [\n 1541469600.0, \n 881\n ], \n [\n 1541473200.0, \n 182\n ], \n [\n 1541476800.0, \n 490\n ], \n [\n 1541480400.0, \n 820\n ], \n [\n 1541484000.0, \n 322\n ], \n [\n 1541487600.0, \n 836\n ], \n [\n 1541491200.0, \n 565\n ], \n [\n 1541494800.0, \n 758\n ], \n [\n 1541498400.0, \n 880\n ], \n [\n 1541502000.0, \n 677\n ], \n [\n 1541505600.0, \n 381\n ], \n [\n 1541509200.0, \n 814\n ], \n [\n 1541512800.0, \n 329\n ], \n [\n 1541516400.0, \n 446\n ], \n [\n 1541520000.0, \n 731\n ], \n [\n 1541523600.0, \n 111\n ], \n [\n 1541527200.0, \n 926\n ], \n [\n 1541530800.0, \n 772\n ], \n [\n 1541534400.0, \n 400\n ], \n [\n 1541538000.0, \n 943\n ]\n ], \n \"30d\": [\n [\n 1538870400.0, \n 565\n ], \n [\n 1538956800.0, \n 12862\n ], \n [\n 1539043200.0, \n 15617\n ], \n [\n 1539129600.0, \n 10809\n ], \n [\n 1539216000.0, \n 15065\n ], \n [\n 1539302400.0, \n 12927\n ], \n [\n 1539388800.0, \n 12994\n ], \n [\n 1539475200.0, \n 13139\n ], \n [\n 1539561600.0, \n 11838\n ], \n [\n 1539648000.0, \n 12088\n ], \n [\n 1539734400.0, \n 12338\n ], \n [\n 1539820800.0, \n 12768\n ], \n [\n 1539907200.0, \n 12816\n ], \n [\n 1539993600.0, \n 15356\n ], \n [\n 1540080000.0, \n 10910\n ], \n [\n 1540166400.0, \n 12306\n ], \n [\n 1540252800.0, \n 12912\n ], \n [\n 1540339200.0, \n 14700\n ], \n [\n 1540425600.0, \n 11890\n ], \n [\n 1540512000.0, \n 11684\n ], \n [\n 1540598400.0, \n 13510\n ], \n [\n 1540684800.0, \n 12625\n ], \n [\n 1540771200.0, \n 12811\n ], \n [\n 1540857600.0, \n 13180\n ], \n [\n 1540944000.0, \n 14651\n ], \n [\n 1541030400.0, \n 14161\n ], \n [\n 1541116800.0, \n 12612\n ], \n [\n 1541203200.0, \n 14316\n ], \n [\n 1541289600.0, \n 14742\n ], \n [\n 1541376000.0, \n 12505\n ], \n [\n 1541462400.0, \n 14180\n ]\n ]\n }, \n \"status\": \"unresolved\", \n \"statusDetails\": {}, \n \"subscriptionDetails\": null, \n \"tags\": [], \n \"title\": \"This is an example Python exception\", \n \"type\": \"default\", \n \"userCount\": 0, \n \"userReportCount\": 0\n}", - "method": "GET", - "parameters": null, - "path_parameters": [ - { - "description": "the ID of the issue to retrieve.", - "name": "issue_id", - "type": "string" - } - ], - "query_parameters": null, - "sidebar_order": 6, - "title": "Retrieve an Issue", - "warning": null -} diff --git a/src/api/events/get-group-events-latest.json b/src/api/events/get-group-events-latest.json deleted file mode 100644 index eea0b8a58fe218..00000000000000 --- a/src/api/events/get-group-events-latest.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "api_path": "/api/0/issues/{issue_id}/events/latest/", - "authentication": "", - "description": "Retrieves the details of the latest event for an issue.", - "example_request": "GET /api/0/issues/1/events/latest/ HTTP/1.1\nHost: sentry.io\nAuthorization: Bearer ", - "example_response": "HTTP/1.1 200 OK\nContent-Length: 9366\nX-XSS-Protection: 1; mode=block\nContent-Language: en\nX-Content-Type-Options: nosniff\nVary: Accept-Language, Cookie\nAllow: GET, HEAD, OPTIONS\nX-Frame-Options: deny\nContent-Type: application/json\n\n{\n \"_meta\": {\n \"context\": null, \n \"contexts\": null, \n \"entries\": {}, \n \"message\": null, \n \"packages\": null, \n \"sdk\": null, \n \"tags\": {}, \n \"user\": null\n }, \n \"context\": {\n \"emptyList\": [], \n \"emptyMap\": {}, \n \"length\": 10837790, \n \"results\": [\n 1, \n 2, \n 3, \n 4, \n 5\n ], \n \"session\": {\n \"foo\": \"bar\"\n }, \n \"unauthorized\": false, \n \"url\": \"http://example.org/foo/bar/\"\n }, \n \"contexts\": {}, \n \"dateCreated\": \"2018-11-06T21:19:55Z\", \n \"dateReceived\": \"2018-11-06T21:19:55Z\", \n \"dist\": null, \n \"entries\": [\n {\n \"data\": {\n \"message\": \"This is an example Python exception\"\n }, \n \"type\": \"message\"\n }, \n {\n \"data\": {\n \"frames\": [\n {\n \"absPath\": \"/home/ubuntu/.virtualenvs/getsentry/src/raven/raven/base.py\", \n \"colNo\": null, \n \"context\": [\n [\n 298, \n \" frames = stack\"\n ], \n [\n 299, \n \"\"\n ], \n [\n 300, \n \" data.update({\"\n ], \n [\n 301, \n \" 'sentry.interfaces.Stacktrace': {\"\n ], \n [\n 302, \n \" 'frames': get_stack_info(frames,\"\n ], \n [\n 303, \n \" transformer=self.transform)\"\n ], \n [\n 304, \n \" },\"\n ], \n [\n 305, \n \" })\"\n ], \n [\n 306, \n \"\"\n ], \n [\n 307, \n \" if 'sentry.interfaces.Stacktrace' in data:\"\n ], \n [\n 308, \n \" if self.include_paths:\"\n ]\n ], \n \"errors\": null, \n \"filename\": \"raven/base.py\", \n \"function\": \"build_msg\", \n \"inApp\": false, \n \"instructionAddr\": null, \n \"lineNo\": 303, \n \"module\": \"raven.base\", \n \"package\": null, \n \"platform\": null, \n \"symbol\": null, \n \"symbolAddr\": null, \n \"trust\": null, \n \"vars\": {\n \"'culprit'\": null, \n \"'data'\": {\n \"'message'\": \"u'This is a test message generated using ``raven test``'\", \n \"'sentry.interfaces.Message'\": {\n \"'message'\": \"u'This is a test message generated using ``raven test``'\", \n \"'params'\": []\n }\n }, \n \"'date'\": \"datetime.datetime(2013, 8, 13, 3, 8, 24, 880386)\", \n \"'event_id'\": \"'54a322436e1b47b88e239b78998ae742'\", \n \"'event_type'\": \"'raven.events.Message'\", \n \"'extra'\": {\n \"'go_deeper'\": [\n [\n {\n \"'bar'\": [\n \"'baz'\"\n ], \n \"'foo'\": \"'bar'\"\n }\n ]\n ], \n \"'loadavg'\": [\n 0.37255859375, \n 0.5341796875, \n 0.62939453125\n ], \n \"'user'\": \"'dcramer'\"\n }, \n \"'frames'\": \"\", \n \"'handler'\": \"\", \n \"'k'\": \"'sentry.interfaces.Message'\", \n \"'kwargs'\": {\n \"'level'\": 20, \n \"'message'\": \"'This is a test message generated using ``raven test``'\"\n }, \n \"'public_key'\": null, \n \"'result'\": {\n \"'message'\": \"u'This is a test message generated using ``raven test``'\", \n \"'sentry.interfaces.Message'\": {\n \"'message'\": \"u'This is a test message generated using ``raven test``'\", \n \"'params'\": []\n }\n }, \n \"'self'\": \"\", \n \"'stack'\": true, \n \"'tags'\": null, \n \"'time_spent'\": null, \n \"'v'\": {\n \"'message'\": \"u'This is a test message generated using ``raven test``'\", \n \"'params'\": []\n }\n }\n }, \n {\n \"absPath\": \"/home/ubuntu/.virtualenvs/getsentry/src/raven/raven/base.py\", \n \"colNo\": null, \n \"context\": [\n [\n 454, \n \" if not self.is_enabled():\"\n ], \n [\n 455, \n \" return\"\n ], \n [\n 456, \n \"\"\n ], \n [\n 457, \n \" data = self.build_msg(\"\n ], \n [\n 458, \n \" event_type, data, date, time_spent, extra, stack, tags=tags,\"\n ], \n [\n 459, \n \" **kwargs)\"\n ], \n [\n 460, \n \"\"\n ], \n [\n 461, \n \" self.send(**data)\"\n ], \n [\n 462, \n \"\"\n ], \n [\n 463, \n \" return (data.get('event_id'),)\"\n ], \n [\n 464, \n \"\"\n ]\n ], \n \"errors\": null, \n \"filename\": \"raven/base.py\", \n \"function\": \"capture\", \n \"inApp\": false, \n \"instructionAddr\": null, \n \"lineNo\": 459, \n \"module\": \"raven.base\", \n \"package\": null, \n \"platform\": null, \n \"symbol\": null, \n \"symbolAddr\": null, \n \"trust\": null, \n \"vars\": {\n \"'data'\": null, \n \"'date'\": null, \n \"'event_type'\": \"'raven.events.Message'\", \n \"'extra'\": {\n \"'go_deeper'\": [\n [\n {\n \"'bar'\": [\n \"'baz'\"\n ], \n \"'foo'\": \"'bar'\"\n }\n ]\n ], \n \"'loadavg'\": [\n 0.37255859375, \n 0.5341796875, \n 0.62939453125\n ], \n \"'user'\": \"'dcramer'\"\n }, \n \"'kwargs'\": {\n \"'level'\": 20, \n \"'message'\": \"'This is a test message generated using ``raven test``'\"\n }, \n \"'self'\": \"\", \n \"'stack'\": true, \n \"'tags'\": null, \n \"'time_spent'\": null\n }\n }, \n {\n \"absPath\": \"/home/ubuntu/.virtualenvs/getsentry/src/raven/raven/base.py\", \n \"colNo\": null, \n \"context\": [\n [\n 572, \n \" \\\"\\\"\\\"\"\n ], \n [\n 573, \n \" Creates an event from ``message``.\"\n ], \n [\n 574, \n \"\"\n ], \n [\n 575, \n \" >>> client.captureMessage('My event just happened!')\"\n ], \n [\n 576, \n \" \\\"\\\"\\\"\"\n ], \n [\n 577, \n \" return self.capture('raven.events.Message', message=message, **kwargs)\"\n ], \n [\n 578, \n \"\"\n ], \n [\n 579, \n \" def captureException(self, exc_info=None, **kwargs):\"\n ], \n [\n 580, \n \" \\\"\\\"\\\"\"\n ], \n [\n 581, \n \" Creates an event from an exception.\"\n ], \n [\n 582, \n \"\"\n ]\n ], \n \"errors\": null, \n \"filename\": \"raven/base.py\", \n \"function\": \"captureMessage\", \n \"inApp\": false, \n \"instructionAddr\": null, \n \"lineNo\": 577, \n \"module\": \"raven.base\", \n \"package\": null, \n \"platform\": null, \n \"symbol\": null, \n \"symbolAddr\": null, \n \"trust\": null, \n \"vars\": {\n \"'kwargs'\": {\n \"'data'\": null, \n \"'extra'\": {\n \"'go_deeper'\": [\n [\n {\n \"'bar'\": [\n \"'baz'\"\n ], \n \"'foo'\": \"'bar'\"\n }\n ]\n ], \n \"'loadavg'\": [\n 0.37255859375, \n 0.5341796875, \n 0.62939453125\n ], \n \"'user'\": \"'dcramer'\"\n }, \n \"'level'\": 20, \n \"'stack'\": true, \n \"'tags'\": null\n }, \n \"'message'\": \"'This is a test message generated using ``raven test``'\", \n \"'self'\": \"\"\n }\n }, \n {\n \"absPath\": \"/home/ubuntu/.virtualenvs/getsentry/src/raven/raven/scripts/runner.py\", \n \"colNo\": null, \n \"context\": [\n [\n 72, \n \" level=logging.INFO,\"\n ], \n [\n 73, \n \" stack=True,\"\n ], \n [\n 74, \n \" tags=options.get('tags', {}),\"\n ], \n [\n 75, \n \" extra={\"\n ], \n [\n 76, \n \" 'user': get_uid(),\"\n ], \n [\n 77, \n \" 'loadavg': get_loadavg(),\"\n ], \n [\n 78, \n \" },\"\n ], \n [\n 79, \n \" ))\"\n ], \n [\n 80, \n \"\"\n ], \n [\n 81, \n \" if client.state.did_fail():\"\n ], \n [\n 82, \n \" print('error!')\"\n ]\n ], \n \"errors\": null, \n \"filename\": \"raven/scripts/runner.py\", \n \"function\": \"send_test_message\", \n \"inApp\": false, \n \"instructionAddr\": null, \n \"lineNo\": 77, \n \"module\": \"raven.scripts.runner\", \n \"package\": null, \n \"platform\": null, \n \"symbol\": null, \n \"symbolAddr\": null, \n \"trust\": null, \n \"vars\": {\n \"'client'\": \"\", \n \"'data'\": null, \n \"'k'\": \"'secret_key'\", \n \"'options'\": {\n \"'data'\": null, \n \"'tags'\": null\n }\n }\n }, \n {\n \"absPath\": \"/home/ubuntu/.virtualenvs/getsentry/src/raven/raven/scripts/runner.py\", \n \"colNo\": null, \n \"context\": [\n [\n 107, \n \" print(\\\"Using DSN configuration:\\\")\"\n ], \n [\n 108, \n \" print(\\\" \\\", dsn)\"\n ], \n [\n 109, \n \" print()\"\n ], \n [\n 110, \n \"\"\n ], \n [\n 111, \n \" client = Client(dsn, include_paths=['raven'])\"\n ], \n [\n 112, \n \" send_test_message(client, opts.__dict__)\"\n ]\n ], \n \"errors\": null, \n \"filename\": \"raven/scripts/runner.py\", \n \"function\": \"main\", \n \"inApp\": false, \n \"instructionAddr\": null, \n \"lineNo\": 112, \n \"module\": \"raven.scripts.runner\", \n \"package\": null, \n \"platform\": null, \n \"symbol\": null, \n \"symbolAddr\": null, \n \"trust\": null, \n \"vars\": {\n \"'args'\": [\n \"'test'\", \n \"'https://ebc35f33e151401f9deac549978bda11:f3403f81e12e4c24942d505f086b2cad@sentry.io/1'\"\n ], \n \"'client'\": \"\", \n \"'dsn'\": \"'https://ebc35f33e151401f9deac549978bda11:f3403f81e12e4c24942d505f086b2cad@sentry.io/1'\", \n \"'opts'\": \"\", \n \"'parser'\": \"\", \n \"'root'\": \"\"\n }\n }\n ], \n \"framesOmitted\": null, \n \"hasSystemFrames\": false, \n \"registers\": null\n }, \n \"type\": \"stacktrace\"\n }, \n {\n \"data\": {\n \"context\": [\n [\n 11, \n \"{% endif %}\\n\"\n ], \n [\n 12, \n \"\\n\"\n ], \n [\n 13, \n \"