From 68bac3dd4348e96ed30aad9ac42723073990fda3 Mon Sep 17 00:00:00 2001 From: HazA Date: Wed, 29 Aug 2018 10:16:40 +0200 Subject: [PATCH 001/171] feat: Move files from temp docs repo --- .../_includes/platform-specific-content.scss | 10 ++ src/_assets/css/_includes/type.scss | 6 + src/_data/platforms.yml | 30 ++++ src/_includes/components/config_key.html | 1 + src/_includes/head.html | 6 +- src/_js/lib/PlatformContent.js | 53 ++++++ src/_js/lib/User.js | 2 +- src/_plugins/case_variations.rb | 31 ++++ src/_plugins/make_map_by.rb | 13 ++ src/_plugins/select_filters.rb | 17 ++ src/_plugins/unsupported.rb | 29 ++++ .../platform-content/index.md | 36 +--- .../learn/breadcrumbs-example/browser.md | 7 + .../learn/breadcrumbs-example/electron.md | 9 + .../learn/breadcrumbs-example/node.md | 9 + .../learn/breadcrumbs-example/python.md | 9 + .../learn/breadcrumbs-example/rust.md | 10 ++ .../_documentation/learn/breadcrumbs.md | 65 ++++--- .../learn/capture-error/browser.md | 11 ++ .../learn/capture-error/cordova.md | 13 ++ .../learn/capture-error/csharp.md | 11 ++ .../learn/capture-error/electron.md | 13 ++ .../learn/capture-error/node.md | 13 ++ .../learn/capture-error/python.md | 12 ++ .../learn/capture-error/rust.md | 14 ++ .../learn/capture-message/browser.md | 3 + .../learn/capture-message/cordova.md | 5 + .../learn/capture-message/csharp.md | 5 + .../learn/capture-message/electron.md | 5 + .../learn/capture-message/node.md | 5 + .../learn/capture-message/python.md | 5 + .../learn/capture-message/rust.md | 5 + .../_documentation/learn/capturing.md | 37 ++++ .../learn/config-intro/browser.md | 11 ++ .../learn/config-intro/cordova.md | 12 ++ .../learn/config-intro/csharp.md | 16 ++ .../learn/config-intro/electron.md | 11 ++ .../_documentation/learn/config-intro/node.md | 11 ++ .../learn/config-intro/python.md | 11 ++ .../_documentation/learn/config-intro/rust.md | 11 ++ .../learn/config-keys/max_breadcrumbs.md | 3 + .../_documentation/learn/configuration.md | 162 ++++++++++++++++++ .../learn/configure-scope/browser.md | 9 + .../learn/configure-scope/csharp.md | 11 ++ .../learn/configure-scope/electron.md | 11 ++ .../learn/configure-scope/node.md | 11 ++ .../learn/configure-scope/python.md | 7 + .../learn/configure-scope/rust.md | 12 ++ .../getting-started-config/aspnetcore.md | 10 ++ .../learn/getting-started-config/browser.md | 1 + .../learn/getting-started-config/cordova.md | 9 + .../learn/getting-started-config/csharp.md | 8 + .../learn/getting-started-config/electron.md | 7 + .../learn/getting-started-config/node.md | 7 + .../learn/getting-started-config/python.md | 4 + .../learn/getting-started-config/rust.md | 4 + .../getting-started-install/aspnetcore.md | 11 ++ .../learn/getting-started-install/browser.md | 11 ++ .../learn/getting-started-install/cordova.md | 5 + .../learn/getting-started-install/csharp.md | 11 ++ .../learn/getting-started-install/electron.md | 11 ++ .../learn/getting-started-install/node.md | 11 ++ .../learn/getting-started-install/python.md | 5 + .../learn/getting-started-install/rust.md | 6 + .../_documentation/learn/getting-started.md | 36 ++++ .../_documentation/learn/scopes.md | 65 +++++++ 66 files changed, 967 insertions(+), 64 deletions(-) create mode 100644 src/_includes/components/config_key.html create mode 100644 src/_plugins/case_variations.rb create mode 100644 src/_plugins/make_map_by.rb create mode 100644 src/_plugins/select_filters.rb create mode 100644 src/_plugins/unsupported.rb create mode 100644 src/collections/_documentation/learn/breadcrumbs-example/browser.md create mode 100644 src/collections/_documentation/learn/breadcrumbs-example/electron.md create mode 100644 src/collections/_documentation/learn/breadcrumbs-example/node.md create mode 100644 src/collections/_documentation/learn/breadcrumbs-example/python.md create mode 100644 src/collections/_documentation/learn/breadcrumbs-example/rust.md create mode 100644 src/collections/_documentation/learn/capture-error/browser.md create mode 100644 src/collections/_documentation/learn/capture-error/cordova.md create mode 100644 src/collections/_documentation/learn/capture-error/csharp.md create mode 100644 src/collections/_documentation/learn/capture-error/electron.md create mode 100644 src/collections/_documentation/learn/capture-error/node.md create mode 100644 src/collections/_documentation/learn/capture-error/python.md create mode 100644 src/collections/_documentation/learn/capture-error/rust.md create mode 100644 src/collections/_documentation/learn/capture-message/browser.md create mode 100644 src/collections/_documentation/learn/capture-message/cordova.md create mode 100644 src/collections/_documentation/learn/capture-message/csharp.md create mode 100644 src/collections/_documentation/learn/capture-message/electron.md create mode 100644 src/collections/_documentation/learn/capture-message/node.md create mode 100644 src/collections/_documentation/learn/capture-message/python.md create mode 100644 src/collections/_documentation/learn/capture-message/rust.md create mode 100644 src/collections/_documentation/learn/capturing.md create mode 100644 src/collections/_documentation/learn/config-intro/browser.md create mode 100644 src/collections/_documentation/learn/config-intro/cordova.md create mode 100644 src/collections/_documentation/learn/config-intro/csharp.md create mode 100644 src/collections/_documentation/learn/config-intro/electron.md create mode 100644 src/collections/_documentation/learn/config-intro/node.md create mode 100644 src/collections/_documentation/learn/config-intro/python.md create mode 100644 src/collections/_documentation/learn/config-intro/rust.md create mode 100644 src/collections/_documentation/learn/config-keys/max_breadcrumbs.md create mode 100644 src/collections/_documentation/learn/configuration.md create mode 100644 src/collections/_documentation/learn/configure-scope/browser.md create mode 100644 src/collections/_documentation/learn/configure-scope/csharp.md create mode 100644 src/collections/_documentation/learn/configure-scope/electron.md create mode 100644 src/collections/_documentation/learn/configure-scope/node.md create mode 100644 src/collections/_documentation/learn/configure-scope/python.md create mode 100644 src/collections/_documentation/learn/configure-scope/rust.md create mode 100644 src/collections/_documentation/learn/getting-started-config/aspnetcore.md create mode 100644 src/collections/_documentation/learn/getting-started-config/browser.md create mode 100644 src/collections/_documentation/learn/getting-started-config/cordova.md create mode 100644 src/collections/_documentation/learn/getting-started-config/csharp.md create mode 100644 src/collections/_documentation/learn/getting-started-config/electron.md create mode 100644 src/collections/_documentation/learn/getting-started-config/node.md create mode 100644 src/collections/_documentation/learn/getting-started-config/python.md create mode 100644 src/collections/_documentation/learn/getting-started-config/rust.md create mode 100644 src/collections/_documentation/learn/getting-started-install/aspnetcore.md create mode 100644 src/collections/_documentation/learn/getting-started-install/browser.md create mode 100644 src/collections/_documentation/learn/getting-started-install/cordova.md create mode 100644 src/collections/_documentation/learn/getting-started-install/csharp.md create mode 100644 src/collections/_documentation/learn/getting-started-install/electron.md create mode 100644 src/collections/_documentation/learn/getting-started-install/node.md create mode 100644 src/collections/_documentation/learn/getting-started-install/python.md create mode 100644 src/collections/_documentation/learn/getting-started-install/rust.md create mode 100644 src/collections/_documentation/learn/getting-started.md create mode 100644 src/collections/_documentation/learn/scopes.md diff --git a/src/_assets/css/_includes/platform-specific-content.scss b/src/_assets/css/_includes/platform-specific-content.scss index 02d4552493aab..0d35013a624af 100644 --- a/src/_assets/css/_includes/platform-specific-content.scss +++ b/src/_assets/css/_includes/platform-specific-content.scss @@ -5,3 +5,13 @@ display: block; } } + +.unsupported.is-unsupported { + opacity: 0.5; + + .unsupported-hint { + font-size: 0.9rem; + font-weight: bold; + margin-bottom: 0.3rem; + } +} diff --git a/src/_assets/css/_includes/type.scss b/src/_assets/css/_includes/type.scss index 538011274851b..6ff6890d9add0 100644 --- a/src/_assets/css/_includes/type.scss +++ b/src/_assets/css/_includes/type.scss @@ -60,6 +60,12 @@ } } +// Config keys +h3.config-key { + font-family: $font-family-monospace; + font-size: 1.3rem; +} + // Remove the bottom margin from the final direct child. // // Example: diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index 866aff419f121..629b556b26330 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -12,6 +12,7 @@ name: Node.js doc_link: /clients/node/ wizard: ['_documentation/clients/node/index.md#installation', '_documentation/clients/node/index.md#configuring-the-client', '_documentation/clients/node/index.md#reporting-errors'] + case_style: camelCase - slug: express support_level: production @@ -33,6 +34,20 @@ name: Cordova doc_link: /clients/cordova/ wizard: ['_documentation/clients/cordova/index.md#installation', '_documentation/clients/cordova/index.md#configuration'] + case_style: camelCase +- + slug: csharp + support_level: production + type: language + name: C# + doc_link: /clients/ + case_style: snake_case +- + slug: aspnetcore + support_level: production + type: framework + name: ASP.NET Core + doc_link: /clients/ - slug: java support_level: production @@ -89,6 +104,7 @@ name: Python doc_link: /clients/python/ wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/usage.md#capture-an-error', '_documentation/clients/python/usage.md#reporting-an-event'] + case_style: snake_case - slug: pyramid support_level: production @@ -96,6 +112,7 @@ name: Pyramid doc_link: /clients/python/integrations/pyramid/ wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/pyramid.md#pastedeploy-filter', '_documentation/clients/python/integrations/pyramid.md#logger-setup'] + case_style: camelCase - slug: rq support_level: production @@ -154,6 +171,14 @@ wizard: ['_documentation/clients/cocoa/index.md#installation', '_documentation/clients/cocoa/index.md#configuration', '_documentation/clients/cocoa/index.md#debug-symbols', '_documentation/clients/cocoa/dsym.md#upload-symbols-with-sentry-cli'] version: 4.1.0 version_key: SENTRY_COCOA_TAG +- + slug: browser + support_level: production + type: language + name: Browser + doc_link: /clients/javascript/ + wizard: [] + case_style: camelCase - slug: javascript support_level: production @@ -163,6 +188,7 @@ wizard: ['_documentation/clients/javascript/index.md#installation', '_documentation/clients/javascript/index.md#configuring-the-client', '_documentation/clients/javascript/index.md#manually-reporting-errors'] version: 3.26.4 version_key: RAVEN_VERSION + case_style: camelCase - slug: vue support_level: production @@ -224,6 +250,7 @@ name: Electron doc_link: /clients/electron/ wizard: ['_documentation/clients/electron/index.md#installation', '_documentation/clients/electron/index.md#configuring-the-client'] + case_style: camelCase - slug: elixir support_level: production @@ -231,6 +258,7 @@ name: Elixir doc_link: /clients/elixir/ wizard: ['_documentation/clients/elixir/index.md#installation', '_documentation/clients/elixir/index.md#configuration', '_documentation/clients/elixir/usage.md#capturing-errors'] + case_style: PascalCase - slug: cocoa support_level: beta @@ -254,6 +282,7 @@ name: 'C#' doc_link: /clients/csharp/ wizard: ['_documentation/clients/csharp/index.md#installation', '_documentation/clients/csharp/index.md#capturing-exceptions'] + case_style: PascalCase - slug: go support_level: in-development @@ -326,6 +355,7 @@ wizard: ['_documentation/clients/rust/index.md#installation', '_documentation/clients/rust/index.md#configuring-the-client', '_documentation/clients/rust/index.md#reporting-errors', '_documentation/clients/rust/index.md#catching-panics'] version: 0.6.0 version_key: SENTRY_VERSION + case_style: snake_case - slug: minidump support_level: production diff --git a/src/_includes/components/config_key.html b/src/_includes/components/config_key.html new file mode 100644 index 0000000000000..0fae5dd6553c5 --- /dev/null +++ b/src/_includes/components/config_key.html @@ -0,0 +1 @@ +{{ include.key }} diff --git a/src/_includes/head.html b/src/_includes/head.html index f01dcecba5765..0d12fb8ad41e3 100644 --- a/src/_includes/head.html +++ b/src/_includes/head.html @@ -35,8 +35,10 @@ {% asset screen.css %} diff --git a/src/_js/lib/PlatformContent.js b/src/_js/lib/PlatformContent.js index 1f782c9e29bb6..c3e25c4d02ac2 100644 --- a/src/_js/lib/PlatformContent.js +++ b/src/_js/lib/PlatformContent.js @@ -32,6 +32,53 @@ const updateUrlPlatform = function(url, slug) { return `${origin}?${qs.stringify(query)}`; }; +const initRelatedElements = function() { + $('.config-key').each(function() { + this.setAttribute('data-config-key', $(this).text()); + }); + + $('.unsupported').each(function() { + $('
').prependTo(this); + }); +}; + +const syncRelatedElements = function() { + let platform = window.platformData[window.activePlatform]; + let style = platform && platform.case_style || 'canonical'; + + $('.config-key').each(function() { + let canonical = this.getAttribute('data-config-key'); + let intended = canonical; + switch (style) { + case 'snake_case': intended = canonical.replace(/-/g, '_'); break; + case 'camelCase': intended = canonical.split(/-/g).map((val, idx) => + idx == 0 ? val : val.charAt(0).toUpperCase() + val.substr(1) + ).join(''); break; + case 'PascalCase': intended = canonical.split(/-/g).map((val) => + val.charAt(0).toUpperCase() + val.substr(1) + ).join(''); break; + } + let elements = $(this).children(); + $(this).text(intended).prepend(elements); + }); + + $('.unsupported').each(function() { + let slugs = this.getAttribute('data-unsupported-platforms'); + let inverse = false; + if (!slugs) { + slugs = this.getAttribute('data-supported-platforms'); + inverse = true; + } + slugs = slugs.split(/\s+/g); + if ((slugs.indexOf(window.activePlatform) >= 0) != inverse) { + $(this).addClass('is-unsupported'); + $('div.unsupported-hint', this).text(`Not available for ${platform.name || 'this platform'}.`); + } else { + $(this).removeClass('is-unsupported'); + } + }); +}; + // Update UI state to show content for a given platform. If the platform does // not exist, // @@ -41,6 +88,8 @@ const updateUrlPlatform = function(url, slug) { const showPlatform = function(slug) { if (!verifyPlatformSlug(slug)) return; + window.activePlatform = slug; + $('[data-platform-specific-content]').each((i, el) => { const $block = $(el); const $dropdownItems = $block.find('[data-toggle="platform"]'); @@ -70,6 +119,8 @@ const showPlatform = function(slug) { // Update dropdown target title $block.find('[data-toggle="dropdown"]').text($active.text()); }); + + syncRelatedElements(); }; // Add the current platform to all links on the page. @@ -95,6 +146,8 @@ const addPlatformToLinks = function(slug) { // // Returns nothing. const init = function() { + initRelatedElements(); + $(document).on('click', '[data-toggle="platform"]', function(event) { event.preventDefault(); const $target = $(event.target); diff --git a/src/_js/lib/User.js b/src/_js/lib/User.js index fb520dc61a10d..e3b7a0b8cf879 100644 --- a/src/_js/lib/User.js +++ b/src/_js/lib/User.js @@ -58,7 +58,7 @@ const formatDsn = function( opts = { public: false } ) { const auth = opts.public ? publicKey : `${publicKey}:${secretKey}`; - return `${scheme}${auth}@${host}${pathSection}${project}`; + return `${scheme}${auth}@${host}${pathSection}`; }; const formatMinidumpURL = function(dsn) { diff --git a/src/_plugins/case_variations.rb b/src/_plugins/case_variations.rb new file mode 100644 index 0000000000000..5688fa6bafa7d --- /dev/null +++ b/src/_plugins/case_variations.rb @@ -0,0 +1,31 @@ +module Jekyll + class CaseVariationsTag < Liquid::Tag + + def initialize(tag_name, key, options) + super + @key = key + end + + def render_variation(variation, value) + %Q( + #{value} + ) + end + + def render(context) + parts = @key.split(/-/) + snake_case = @key.gsub('-', '_') + camel_case = parts.each_with_index { |val, idx| + idx == 0 ? val : val.capitalize! + }.join('') + pascal_case = parts.map { |v| v.capitalize }.join('') + [ + render_variation("canonical", @key), + render_variation("snake_case", snake_case), + render_variation("camelCase", camel_case), + render_variation("PascalCase", pascal_case), + ].join("\n") + end + end +end +Liquid::Template.register_tag('case_variations'.freeze, Jekyll::CaseVariationsTag) diff --git a/src/_plugins/make_map_by.rb b/src/_plugins/make_map_by.rb new file mode 100644 index 0000000000000..d3bcaad3fefbb --- /dev/null +++ b/src/_plugins/make_map_by.rb @@ -0,0 +1,13 @@ +module Jekyll + module MakeMapByFilters + def make_map_by(input, key) + rv = {} + input.each do |item| + rv[item[key]] = item + end + rv + end + end +end + +Liquid::Template.register_filter(Jekyll::MakeMapByFilters) diff --git a/src/_plugins/select_filters.rb b/src/_plugins/select_filters.rb new file mode 100644 index 0000000000000..2e4ddd5a90ae7 --- /dev/null +++ b/src/_plugins/select_filters.rb @@ -0,0 +1,17 @@ +module Jekyll + module SelectFilters + def map_select(input, arg) + keys = arg.split(/\s*,\s*/) + input.map do |x| + x.select { |k| keys.include? k.to_s } + end + end + + def select(input, arg) + keys = arg.split(/\s*,\s*/) + input.select { |k| keys.include? k.to_s } + end + end +end + +Liquid::Template.register_filter(Jekyll::SelectFilters) diff --git a/src/_plugins/unsupported.rb b/src/_plugins/unsupported.rb new file mode 100644 index 0000000000000..84f38b8842538 --- /dev/null +++ b/src/_plugins/unsupported.rb @@ -0,0 +1,29 @@ +module Jekyll + class UnsupportedTag < Liquid::Block + + def initialize(tag_name, text, tokens) + super + @slugs = text.split(/\s+/) + end + + def platform_attr + "unsupported-platforms" + end + + def render(context) + site = context.registers[:site] + converter = site.find_converter_instance(::Jekyll::Converters::Markdown) + content = converter.convert(super(context)) + %Q(
#{content}
) + end + end + + class SupportedTag < UnsupportedTag + def platform_attr + "supported-platforms" + end + end +end + +Liquid::Template.register_tag('unsupported', Jekyll::UnsupportedTag) +Liquid::Template.register_tag('supported', Jekyll::SupportedTag) diff --git a/src/collections/_dev_components/layout-components/platform-content/index.md b/src/collections/_dev_components/layout-components/platform-content/index.md index b0d5d8824f11a..71aff98441e68 100644 --- a/src/collections/_dev_components/layout-components/platform-content/index.md +++ b/src/collections/_dev_components/layout-components/platform-content/index.md @@ -1,39 +1,7 @@ --- title: Platform Content source: components/platform_content.html -example_string: Hello world - -example_1: - JavaScript: | - ``` javascript - console.log("{{ page.example_string }}") - ``` - Python: | - ``` python - print("{{ page.example_string }}") - ``` - Ruby: | - ``` ruby - puts "{{ page.example_string }}" - ``` - -example_2: - JavaScript: | - ## I am an example about JavaScript - - Did you know 0 == false but 0 !== false? - Python: | - ``` - # This is a Python example. A python is a snake. - ``` - Ruby: | - - In Ruby - - You have to - - Say `end` a lot. - -example_3: - Python: Python Example - Ruby: Ruby Example +example_string: Hello world!!!111 --- You can customize content by platform. Within a folder in the same directory as your document, add a file for each platform you would like to include, ensuring that name of the file matches a slug in *src/data/platforms.yml*, then use the include to specify which folder to include examples from. @@ -46,8 +14,6 @@ You may force the platform that is displayed on the page by appending a `platfor - `content=[]` _(required)_ A unique key to identify the switcher -
- ### Basic use #### File structure diff --git a/src/collections/_documentation/learn/breadcrumbs-example/browser.md b/src/collections/_documentation/learn/breadcrumbs-example/browser.md new file mode 100644 index 0000000000000..febb1afa3bd63 --- /dev/null +++ b/src/collections/_documentation/learn/breadcrumbs-example/browser.md @@ -0,0 +1,7 @@ +```javascript +Sentry.addBreadcrumb({ + category: 'auth', + message: 'Authenticated user ' + user.email, + level: 'info' +}); +``` diff --git a/src/collections/_documentation/learn/breadcrumbs-example/electron.md b/src/collections/_documentation/learn/breadcrumbs-example/electron.md new file mode 100644 index 0000000000000..c3059c7cb478d --- /dev/null +++ b/src/collections/_documentation/learn/breadcrumbs-example/electron.md @@ -0,0 +1,9 @@ +```javascript +import { addBreadcrumb } from '@sentry/electron'; + +addBreadcrumb({ + category: 'auth', + message: `Authenticated user ${user.email}`, + level: 'info', +}); +``` diff --git a/src/collections/_documentation/learn/breadcrumbs-example/node.md b/src/collections/_documentation/learn/breadcrumbs-example/node.md new file mode 100644 index 0000000000000..9b6e215f79007 --- /dev/null +++ b/src/collections/_documentation/learn/breadcrumbs-example/node.md @@ -0,0 +1,9 @@ +```javascript +const { addBreadcrumb } = require('@sentry/node'); + +addBreadcrumb({ + category: 'auth', + message: `Authenticated user ${user.email}`, + level: 'info', +}); +``` diff --git a/src/collections/_documentation/learn/breadcrumbs-example/python.md b/src/collections/_documentation/learn/breadcrumbs-example/python.md new file mode 100644 index 0000000000000..e23a00ff7ecca --- /dev/null +++ b/src/collections/_documentation/learn/breadcrumbs-example/python.md @@ -0,0 +1,9 @@ +```python +from sentry_sdk import add_breadcrumb + +add_breadcrumb( + category='auth', + message='Authenticated user %s' % user.email, + level='info', +) +``` diff --git a/src/collections/_documentation/learn/breadcrumbs-example/rust.md b/src/collections/_documentation/learn/breadcrumbs-example/rust.md new file mode 100644 index 0000000000000..c3f78d7dd08e7 --- /dev/null +++ b/src/collections/_documentation/learn/breadcrumbs-example/rust.md @@ -0,0 +1,10 @@ +```rust +use sentry::{add_breadcrumb, Breadcrumb, Level}; + +add_breadcrumb(Breadcrumb { + category: Some("auth".into()), + message: Some(format!("Authenticated user {}", user.email)), + level: Level::Info, + ..Default::default() +}); +``` diff --git a/src/collections/_documentation/learn/breadcrumbs.md b/src/collections/_documentation/learn/breadcrumbs.md index 54922d34772f7..1fe00c9fa4cc4 100644 --- a/src/collections/_documentation/learn/breadcrumbs.md +++ b/src/collections/_documentation/learn/breadcrumbs.md @@ -1,47 +1,60 @@ --- title: Breadcrumbs -sidebar_order: 2 +sidebar_order: 3 --- -Sentry supports a concept called Breadcrumbs, which is a trail of events which happened prior to an issue. Often times these events are very similar to traditional logs, but also have the ability to record more rich structured data. +Sentry supports a concept called Breadcrumbs, which is a trail of events which +happened prior to an issue. Often times these events are very similar to +traditional logs, but also have the ability to record more rich structured +data. Each crumb in the trail has the following attributes: Message -: A string describing the event. The most common vector, often used as a drop-in for a traditional log message. +: A string describing the event. The most common vector, often used as a + drop-in for a traditional log message. Data -: A mapping (str => str) of metadata around the event. This is often used instead of message, but may also be used in addition. +: A mapping (str => str) of metadata around the event. This is often used + instead of message, but may also be used in addition. All keys here are + rendered out as table in the breadcrumb on display but some crumb types + might special case some keys. Category -: A category to label the event under. This generally is similar to a logger name, and will let you more easily understand the area an event took place, such as `auth`. +: A category to label the event under. This generally is similar to a logger + name, and will let you more easily understand the area an event took place, + such as `auth`. Level -: The level may be any of `error`, `warning`, `info`, or `debug`. +: The level may be any of `fatal`, `error`, `warning`, `info`, or `debug`. + +Type + +: Additionally a semi internal attribute `type` exists which can control the type + of the breadcrumb. By default all breadcrumbs are recoded as `default` which + makes it appear as a log entry. Other types are available which will + influence how they are rendered. The following types currently exist: + + * `default`: The default breadcrumb rendering. + * `http`: Renders the breadcrumb as HTTP request. + * `error`: Renders the breadcrumb as a hard error. + + Note that the type is not exclusively used to customize the rendering. It's + best not to change the type from the default. ## Recording Crumbs -Each SDK will have an API native to its language, but we’ll use our PHP SDK as an example. - -```php -function loginUser($username, $password) -{ - $sentryClient->breadcrumbs->record(array( - 'message' => 'Authenticating ' . $username, - 'category' => 'auth', - 'level' => 'info', - )); - - // validate login - - $sentryClient->breadcrumbs->record(array( - 'message' => 'Successfully logged in ' . $username, - 'category' => 'auth', - 'level' => 'info', - )); -} -``` +Manual breadcrumb recording is also available and easy to use. This way breadcrumbs +can be added whenever something interesting happens. For instance it might make sense +to record a breadcrumb if the user authenticates or another state change happens. + +{% include components/platform_content.html content_dir='breadcrumbs-example' %} + +## Automatic Breadcrumbs + +SDKs will automatically start recording breadcrumbs by enabling integrations. For instance +the browser JavaScript SDK will automatically record all lcoation changes. diff --git a/src/collections/_documentation/learn/capture-error/browser.md b/src/collections/_documentation/learn/capture-error/browser.md new file mode 100644 index 0000000000000..0859e1a53feac --- /dev/null +++ b/src/collections/_documentation/learn/capture-error/browser.md @@ -0,0 +1,11 @@ +In JavaScript you can pass an error object to `captureException()` to get it captured +as event. Note that it's possible to throw strings as errors in which case no traceback +can be recorded. + +```javascript +try { + aFunctionThatMightFail(); +} catch (err) { + Sentry.captureException(err); +} +``` diff --git a/src/collections/_documentation/learn/capture-error/cordova.md b/src/collections/_documentation/learn/capture-error/cordova.md new file mode 100644 index 0000000000000..5b823bb130142 --- /dev/null +++ b/src/collections/_documentation/learn/capture-error/cordova.md @@ -0,0 +1,13 @@ +In JavaScript you can pass an error object to `captureException()` to get it captured +as event. Note that it's possible to throw strings as errors in which case no traceback +can be recorded. + +```javascript +var Sentry = cordova.require("sentry-cordova.Sentry"); + +try { + aFunctionThatMightFail(); +} catch (err) { + Sentry.captureException(err); +} +``` diff --git a/src/collections/_documentation/learn/capture-error/csharp.md b/src/collections/_documentation/learn/capture-error/csharp.md new file mode 100644 index 0000000000000..5e8fe09d0446a --- /dev/null +++ b/src/collections/_documentation/learn/capture-error/csharp.md @@ -0,0 +1,11 @@ +In .NET you can capture any exception object that you caught: + +```csharp +using Sentry; + +try { + AFunctionThatMightFail(); +} catch (Exception err) { + SentrySdk.CaptureException(err); +} +``` diff --git a/src/collections/_documentation/learn/capture-error/electron.md b/src/collections/_documentation/learn/capture-error/electron.md new file mode 100644 index 0000000000000..8d665264f966e --- /dev/null +++ b/src/collections/_documentation/learn/capture-error/electron.md @@ -0,0 +1,13 @@ +In JavaScript you can pass an error object to `captureException()` to get it captured +as event. Note that it's possible to throw strings as errors in which case no traceback +can be recorded. + +```javascript +import { captureException } from '@sentry/electron'; + +try { + aFunctionThatMightFail(); +} catch (err) { + captureException(err); +} +``` diff --git a/src/collections/_documentation/learn/capture-error/node.md b/src/collections/_documentation/learn/capture-error/node.md new file mode 100644 index 0000000000000..0d5f7c6ff2bc5 --- /dev/null +++ b/src/collections/_documentation/learn/capture-error/node.md @@ -0,0 +1,13 @@ +In JavaScript you can pass an error object to `captureException()` to get it captured +as event. Note that it's possible to throw strings as errors in which case no traceback +can be recorded. + +```javascript +const { captureException } = require('@sentry/node'); + +try { + aFunctionThatMightFail(); +} catch (err) { + captureException(err); +} +``` diff --git a/src/collections/_documentation/learn/capture-error/python.md b/src/collections/_documentation/learn/capture-error/python.md new file mode 100644 index 0000000000000..0c7a17b34c4c8 --- /dev/null +++ b/src/collections/_documentation/learn/capture-error/python.md @@ -0,0 +1,12 @@ +In Python you can either capture a caught exception or the one currently held in +`sys.exc_info()` by not passing an argument: + +```python +from sentry_sdk import capture_exception + +try: + a_potentially_failing_function() +except Exception as e: + # Alternatively the argument can be omitted + capture_exception(e) +``` diff --git a/src/collections/_documentation/learn/capture-error/rust.md b/src/collections/_documentation/learn/capture-error/rust.md new file mode 100644 index 0000000000000..58ddd9c89f318 --- /dev/null +++ b/src/collections/_documentation/learn/capture-error/rust.md @@ -0,0 +1,14 @@ +In Rust you can capture errors that implement the `Fail` trait or that are `failure::Error` +objects: + +```rust +use sentry::integrations::failure::capture_error; + +let result = match function_that_might_fail() { + Ok(result) => result, + Err(err) => { + capture_error(&err); + return Err(err); + } +}; +``` diff --git a/src/collections/_documentation/learn/capture-message/browser.md b/src/collections/_documentation/learn/capture-message/browser.md new file mode 100644 index 0000000000000..edb820b96a915 --- /dev/null +++ b/src/collections/_documentation/learn/capture-message/browser.md @@ -0,0 +1,3 @@ +```javascript +Sentry.captureMessage('Something weng wrong'); +``` diff --git a/src/collections/_documentation/learn/capture-message/cordova.md b/src/collections/_documentation/learn/capture-message/cordova.md new file mode 100644 index 0000000000000..4d2d293fd0095 --- /dev/null +++ b/src/collections/_documentation/learn/capture-message/cordova.md @@ -0,0 +1,5 @@ +```javascript +var Sentry = cordova.require("sentry-cordova.Sentry"); + +Sentry.captureMessage('Something weng wrong'); +``` diff --git a/src/collections/_documentation/learn/capture-message/csharp.md b/src/collections/_documentation/learn/capture-message/csharp.md new file mode 100644 index 0000000000000..03d0d16f19cb0 --- /dev/null +++ b/src/collections/_documentation/learn/capture-message/csharp.md @@ -0,0 +1,5 @@ +```csharp +using Sentry; + +SentrySdk.CaptureMessage("Something went wrong"); +``` diff --git a/src/collections/_documentation/learn/capture-message/electron.md b/src/collections/_documentation/learn/capture-message/electron.md new file mode 100644 index 0000000000000..13910d8acf36f --- /dev/null +++ b/src/collections/_documentation/learn/capture-message/electron.md @@ -0,0 +1,5 @@ +```javascript +import { captureMessage } from '@sentry/electron'; + +captureMessage('Something weng wrong'); +``` diff --git a/src/collections/_documentation/learn/capture-message/node.md b/src/collections/_documentation/learn/capture-message/node.md new file mode 100644 index 0000000000000..599c17136f144 --- /dev/null +++ b/src/collections/_documentation/learn/capture-message/node.md @@ -0,0 +1,5 @@ +```javascript +const { captureMessage } = require('@sentry/node'); + +captureMessage('Something weng wrong'); +``` diff --git a/src/collections/_documentation/learn/capture-message/python.md b/src/collections/_documentation/learn/capture-message/python.md new file mode 100644 index 0000000000000..c2d6f21cd5b0f --- /dev/null +++ b/src/collections/_documentation/learn/capture-message/python.md @@ -0,0 +1,5 @@ +```python +from sentry_sdk import capture_message + +capture_message('Something went wrong') +``` diff --git a/src/collections/_documentation/learn/capture-message/rust.md b/src/collections/_documentation/learn/capture-message/rust.md new file mode 100644 index 0000000000000..2341b2ecef1fe --- /dev/null +++ b/src/collections/_documentation/learn/capture-message/rust.md @@ -0,0 +1,5 @@ +```rust +use sentry::{capture_message, Level}; + +capture_message("Something went wrong", Level::Info); +``` diff --git a/src/collections/_documentation/learn/capturing.md b/src/collections/_documentation/learn/capturing.md new file mode 100644 index 0000000000000..e802d47803798 --- /dev/null +++ b/src/collections/_documentation/learn/capturing.md @@ -0,0 +1,37 @@ +--- +title: Capturing Events +sidebar_order: 3 +--- + +Out of the box SDKs will attempt to hook themselves into your runtime environment +or framework to automatically report fatal errors. However in many situations +it's useful to manually report errors or messages to Sentry. This is called +"capturing". When an event is captured it's sent to Sentry and will create a new +issue group or be added to an already existing once based on Sentry's grouping +algorithm. Separately to capturing you can also record "breadcrumbs" that lead +up to an event. Breadcrumbs are different in that they will not create an event +in Sentry but will be buffered until the next event is sent. For more information +have a look at [the breadcrumbs documentation]({% link _documentation/learn/breadcrumbs.md %}). + +## Capturing Errors / Exceptions + +The most common form of capturing is to capture errors. What can be captured as an +error will depend on the platform. In general if you have something that looks like +an exception it can be captured. For some SDKs you can also omit the argument to +`capture_exception` and it will attempt to capture the current exception. + +{% include components/platform_content.html content_dir='capture-error' %} + +## Capturing Messages + +Another common operation is to capture a bare message. A message is just some textual +information that should be sent to Sentry. Typically messages are not emitted but +there are situations when this is useful. + +{% include components/platform_content.html content_dir='capture-message' %} + +## Capturing Events + +SDKs generally also provide ways to capture entire custom event objects. This is what +integrations internally use to capture bespoke events with a lot of extra data fed +into. For more information about that consult the API documentation of the SDK. diff --git a/src/collections/_documentation/learn/config-intro/browser.md b/src/collections/_documentation/learn/config-intro/browser.md new file mode 100644 index 0000000000000..f2ea797180d83 --- /dev/null +++ b/src/collections/_documentation/learn/config-intro/browser.md @@ -0,0 +1,11 @@ +Options are passed to the `init()` as object: + +```javascript +import * as Sentry from '@sentry/browser'; + +Sentry.init({ + dsn: '___PUBLIC_DSN___', + maxBreadcrumbs: 50, + debug: true, +}) +``` diff --git a/src/collections/_documentation/learn/config-intro/cordova.md b/src/collections/_documentation/learn/config-intro/cordova.md new file mode 100644 index 0000000000000..3e0761c8d76eb --- /dev/null +++ b/src/collections/_documentation/learn/config-intro/cordova.md @@ -0,0 +1,12 @@ +Options are passed to the `init()` as object in the `onDeviceReady` function: + +```javascript +onDeviceReady: function() { + var Sentry = cordova.require("sentry-cordova.Sentry"); + Sentry.init({ + dsn: '___PUBLIC_DSN___', + maxBreadcrumbs: 50, + debug: true, + }); +} +``` diff --git a/src/collections/_documentation/learn/config-intro/csharp.md b/src/collections/_documentation/learn/config-intro/csharp.md new file mode 100644 index 0000000000000..40bd1e120991c --- /dev/null +++ b/src/collections/_documentation/learn/config-intro/csharp.md @@ -0,0 +1,16 @@ +Options can be set by passing a callback to the `Init()` function which will +pass the option object along for modifications: + +```javascript +using Sentry; + +using (SentrySdk.Init(o => +{ + o.Dsn = "___PUBLIC_DSN___"; + o.MaxBreadcrumbs = 50; + o.Debug = true; +}) +{ + // app code here +} +``` diff --git a/src/collections/_documentation/learn/config-intro/electron.md b/src/collections/_documentation/learn/config-intro/electron.md new file mode 100644 index 0000000000000..1f57a8856bee0 --- /dev/null +++ b/src/collections/_documentation/learn/config-intro/electron.md @@ -0,0 +1,11 @@ +Options are passed to the `init()` as object: + +```javascript +import * as sentry from '@sentry/electron'; + +Sentry.init({ + dsn: '___PUBLIC_DSN___', + maxBreadcrumbs: 50, + debug: true, +}) +``` diff --git a/src/collections/_documentation/learn/config-intro/node.md b/src/collections/_documentation/learn/config-intro/node.md new file mode 100644 index 0000000000000..11c2ebe8d3946 --- /dev/null +++ b/src/collections/_documentation/learn/config-intro/node.md @@ -0,0 +1,11 @@ +Options are passed to the `init()` as object: + +```javascript +const Sentry = require('@sentry/node'); + +Sentry.init({ + dsn: '___PUBLIC_DSN___', + maxBreadcrumbs: 50, + debug: true, +}) +``` diff --git a/src/collections/_documentation/learn/config-intro/python.md b/src/collections/_documentation/learn/config-intro/python.md new file mode 100644 index 0000000000000..80de866d72587 --- /dev/null +++ b/src/collections/_documentation/learn/config-intro/python.md @@ -0,0 +1,11 @@ +Options are passed to the `init()` function as optional keyword arguments: + +```python +import sentry_sdk + +sentry_sdk.init( + '___PUBLIC_DSN___', + max_breadcrumbs=50, + debug=True, +) +``` diff --git a/src/collections/_documentation/learn/config-intro/rust.md b/src/collections/_documentation/learn/config-intro/rust.md new file mode 100644 index 0000000000000..e4e5a01cb059b --- /dev/null +++ b/src/collections/_documentation/learn/config-intro/rust.md @@ -0,0 +1,11 @@ +Options are passed to the `init()` as tuple where the first argument is the DSN and the second the options: + +```rust +use sentry; + +sentry::init(("___PUBLIC_DSN___", sentry::ClientOptions { + max_breadcrumbs: 50, + debug: true, + ..Default::default() +})); +``` diff --git a/src/collections/_documentation/learn/config-keys/max_breadcrumbs.md b/src/collections/_documentation/learn/config-keys/max_breadcrumbs.md new file mode 100644 index 0000000000000..7dedf6f29a885 --- /dev/null +++ b/src/collections/_documentation/learn/config-keys/max_breadcrumbs.md @@ -0,0 +1,3 @@ +### {% include components/config_key.html key='max-breadcrumbs' %} + +This variable controls the total amount of keys that should be used. diff --git a/src/collections/_documentation/learn/configuration.md b/src/collections/_documentation/learn/configuration.md new file mode 100644 index 0000000000000..9d7e85c4018c5 --- /dev/null +++ b/src/collections/_documentation/learn/configuration.md @@ -0,0 +1,162 @@ +--- +title: Configuration +sidebar_order: 4 +--- + +SDKs are configurable in many ways. The options are largely standardized between SDKs but there are +some differences to better acomodate platform peculiarities. Options are set when the SDK is first +initialized. + +{% include components/platform_content.html content_dir='config-intro' %} + +## 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. + +{:.config-key} +### debug + +Turns debug mode on or off. If debug is enabled SKD will attempt to print out useful debugging +information if something goes wrong with sending the event. The default is always `false` and +it's generally not recommended to turn it on in production but doing so will not cause any +safety concerns. + +{:.config-key} +### release + +Sets the release. Some SDKs will try to automatically configure a release out of the box but +if you have the chance it's a better idea to manually set it. That way it's guaranteed to be +in sync with your deploy integrations or sourcemap uploads. + +Release names are just strings but some formats are detected by Sentry and might be rendered +differently. For more information have a look at [the releases documentation]({% link _documentation/learn/releases.md %}). + +{:.config-key} +### environment + +Sets the environment. This string is freeform and not set by default. A release can be associated +with more than one environment to separate them im the UI (think `staging` vs `prod` or similar). + +{:.config-key} +### repos + +For repository integration the repository identifiers need to be sent along. For more information +have a look at [the releases documentation]({% link _documentation/learn/releases.md %}). + +{:.config-key} +### sample-rate + +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. + +{:.config-key} +### max-breadcrumbs + +This variable controls the total amount of breadcrumbs that should be captured. This defaults +to `100`. + +{:.config-key} +### http-proxy + +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. Note however that 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. + +{:.config-key} +### https-proxy + +{% unsupported csharp aspnetcore %} +Configures a separate proxy for outgoing HTTPS requests. This value might not be supported by all +SDKs. When not supported the `http-proxy` value is also used for HTTPS requests at all times. +{% endunsupported %} + +{:.config-key} +### attach-stacktrace + +When enabled stacktraces are automatically attached to all messages logged. Note that stacktraces +are always attached to exceptions but when this is set stacktraces are also sent with messages. This +for instance means that stacktraces appear next to all log messages. + +It's important to note that grouping in Sentry is different for events with stacktraces and without. +This means that you will get new groups as you enable or disable this flag for certain events. + +This feature is off by default. + +{:.config-key} +### with-locals + +{% supported python %} +When enabled local variables are sent along with stackframes. This can have a performance +and PII impact. Enabled by default on platforms where this is available. +{% endsupported %} + +{:.config-key} +### send-default-pii + +If this flag is enabled then certain personally identifyable information is added by active +integrations. Without this flag they are never added to the event to begin with. If possible +it's recommended to turn on this feature and use the server side PII stripping to remove the +values instead. + +{:.config-key} +### shutdown-timeout + +{% unsupported browser %} +Controls how many seconds to wait before shutting down. Sentry SDKs send events from a background +queue and this queue is given a certain amount to drain pending events. The default is SDK specific +but typically around 2 seconds. Setting this value too low will most likely cause problems for +sending events from command line applications. Setting it too high will cause the application to +block for long time for users with network connectivity problems. +{% endunsupported %} + +{:.config-key} +### server-name + +{% unsupported browser %} +Can be used to supply a "server name". When provided the name of the server is sent along and +persisted in the event. Note that 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. +{% endunsupported %} + +{:.config-key} +### blacklist-urls + +{% supported browser %} +A pattern for error URLs which should not be sent to Sentry. To whitelist certain errors instead, +use `whitelist-urls`. By default, all errors will be sent. This only applies to events sent +from browsers. +{% endsupported %} + +{:.config-key} +### whitelist-urls + +{% supported browser %} +A pattern for error URLs which should exclusively be sent to Sentry. To +blacklist certain errors instead, use `blacklist-urls`. By default, all errors +will be sent. This only applies to events sent from browsers. +{% endsupported %} + +## Integration Configuration + +For many platform SDKs integrations can be configured alongside it. On some platforms that +happens as part of the `init()` call, in some others different patterns apply. + +{:.config-key} +### integrations + +{% unsupported csharp aspnetcore rust %} +In some SDKs the integrations are configured through this parameter on library initialization. +For more information have a look at the specific integration documentation. +{% endunsupported %} + +{:.config-key} +### default-integrations + +{% supported python %} +This can be used to disable integrations that are added by default. When set to `false` no +default integrations are added. +{% endsupported %} diff --git a/src/collections/_documentation/learn/configure-scope/browser.md b/src/collections/_documentation/learn/configure-scope/browser.md new file mode 100644 index 0000000000000..9c5fd26c6cb27 --- /dev/null +++ b/src/collections/_documentation/learn/configure-scope/browser.md @@ -0,0 +1,9 @@ +```javascript +Sentry.configureScope(function(scope) { + scope.setTag("my-tag", "my value"); + scope.setUser({ + id: 42, + email: "john.doe@example.com" + }); +}); +``` diff --git a/src/collections/_documentation/learn/configure-scope/csharp.md b/src/collections/_documentation/learn/configure-scope/csharp.md new file mode 100644 index 0000000000000..8d889e019ed87 --- /dev/null +++ b/src/collections/_documentation/learn/configure-scope/csharp.md @@ -0,0 +1,11 @@ +```javascript +using Sentry; + +SentrySdk.ConfigureScope(scope => { + scope.SetTag("my-tag", "my value"); + scope.User = new User { + Id = "42", + Email = "john.doe@example.com" + }; +}); +``` diff --git a/src/collections/_documentation/learn/configure-scope/electron.md b/src/collections/_documentation/learn/configure-scope/electron.md new file mode 100644 index 0000000000000..056ae7122d707 --- /dev/null +++ b/src/collections/_documentation/learn/configure-scope/electron.md @@ -0,0 +1,11 @@ +```javascript +import { configureScope } from "@sentry/electron"; + +configureScope((scope) => { + scope.setTag("my-tag", "my value"); + scope.setUser({ + id: 42, + email: "john.doe@example.com" + }); +}); +``` diff --git a/src/collections/_documentation/learn/configure-scope/node.md b/src/collections/_documentation/learn/configure-scope/node.md new file mode 100644 index 0000000000000..043b35b64040f --- /dev/null +++ b/src/collections/_documentation/learn/configure-scope/node.md @@ -0,0 +1,11 @@ +```javascript +const { configureScope } = require("@sentry/node"); + +configureScope((scope) => { + scope.setTag("my-tag", "my value"); + scope.setUser({ + id: 42, + email: "john.doe@example.com" + }); +}); +``` diff --git a/src/collections/_documentation/learn/configure-scope/python.md b/src/collections/_documentation/learn/configure-scope/python.md new file mode 100644 index 0000000000000..c898bd384278b --- /dev/null +++ b/src/collections/_documentation/learn/configure-scope/python.md @@ -0,0 +1,7 @@ +```python +from sentry_sdk import configure_scope + +with configure_scope() as scope: + scope.set_tag("my-tag", "my value") + scope.user = {'id': 42, 'email': 'john.doe@example.com'} +``` diff --git a/src/collections/_documentation/learn/configure-scope/rust.md b/src/collections/_documentation/learn/configure-scope/rust.md new file mode 100644 index 0000000000000..fe0c9d62b37be --- /dev/null +++ b/src/collections/_documentation/learn/configure-scope/rust.md @@ -0,0 +1,12 @@ +```rust +use sentry::{configure_scope, User}; + +configure_scope(|scope| { + scope.set_tag("my-tag", "my value"); + scope.set_user(Some(User { + id: Some(42.to_string()), + email: Some("john.doe@exmaple.com".into()), + ..Default::default() + })); +}); +``` diff --git a/src/collections/_documentation/learn/getting-started-config/aspnetcore.md b/src/collections/_documentation/learn/getting-started-config/aspnetcore.md new file mode 100644 index 0000000000000..95632ed7ffa8d --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-config/aspnetcore.md @@ -0,0 +1,10 @@ +Add Sentry to `Program.cs` through the `WebHostBuilder`: + +```csharp +public static IWebHost BuildWebHost(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup() + // Add this: + .UseSentry("___PUBLIC_DSN___") + .Build(); +``` diff --git a/src/collections/_documentation/learn/getting-started-config/browser.md b/src/collections/_documentation/learn/getting-started-config/browser.md new file mode 100644 index 0000000000000..99a9ae8f3afc8 --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-config/browser.md @@ -0,0 +1 @@ +When using the CDN for browser, no further configuration is required. diff --git a/src/collections/_documentation/learn/getting-started-config/cordova.md b/src/collections/_documentation/learn/getting-started-config/cordova.md new file mode 100644 index 0000000000000..5504e90095a10 --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-config/cordova.md @@ -0,0 +1,9 @@ +You need to inform the sentry electron SDK about your CDN somewhere before +application startup: + +```javascript +onDeviceReady: function() { + var Sentry = cordova.require("sentry-cordova.Sentry"); + Sentry.init({ dsn: '___PUBLIC_DSN___' }); +} +``` diff --git a/src/collections/_documentation/learn/getting-started-config/csharp.md b/src/collections/_documentation/learn/getting-started-config/csharp.md new file mode 100644 index 0000000000000..22f3244d66c5b --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-config/csharp.md @@ -0,0 +1,8 @@ +You should initialize the SDK as early as possible, like in the `Main` method in `Program.cs`: + +```csharp +using (SentrySdk.Init("___PUBLIC_DSN___")) +{ + // App code +} +``` diff --git a/src/collections/_documentation/learn/getting-started-config/electron.md b/src/collections/_documentation/learn/getting-started-config/electron.md new file mode 100644 index 0000000000000..97de4b1c4e61d --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-config/electron.md @@ -0,0 +1,7 @@ +You need to inform the sentry electron SDK about your CDN somewhere before +application startup: + +```javascript +import * as sentry from '@sentry/electron'; +sentry.init({dsn: '___PUBLIC_DSN___'}); +``` diff --git a/src/collections/_documentation/learn/getting-started-config/node.md b/src/collections/_documentation/learn/getting-started-config/node.md new file mode 100644 index 0000000000000..7e6fec356262f --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-config/node.md @@ -0,0 +1,7 @@ +You need to inform the sentry node SDK about your CDN somewhere before +application startup: + +```javascript +const Sentry = require('@sentry/node'); +Sentry.init({dsn: '___PUBLIC_DSN___'}); +``` diff --git a/src/collections/_documentation/learn/getting-started-config/python.md b/src/collections/_documentation/learn/getting-started-config/python.md new file mode 100644 index 0000000000000..d3fa9953b343a --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-config/python.md @@ -0,0 +1,4 @@ +```python +import sentry_sdk +sentry_sdk.init("___PUBLIC_DSN___") +``` diff --git a/src/collections/_documentation/learn/getting-started-config/rust.md b/src/collections/_documentation/learn/getting-started-config/rust.md new file mode 100644 index 0000000000000..5cc70046e42be --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-config/rust.md @@ -0,0 +1,4 @@ +```rust +extern crate sentry; +let _guard = sentry::init("___PUBLIC_DSN___"); +``` diff --git a/src/collections/_documentation/learn/getting-started-install/aspnetcore.md b/src/collections/_documentation/learn/getting-started-install/aspnetcore.md new file mode 100644 index 0000000000000..99a1d8058e9af --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-install/aspnetcore.md @@ -0,0 +1,11 @@ +Install the **NuGet** package: + +Package Manager: +```shell +Install-Package Sentry.AspNetCore +``` + +.NET Core CLI: +```shell +dotnet add package Sentry.AspNetCore +``` diff --git a/src/collections/_documentation/learn/getting-started-install/browser.md b/src/collections/_documentation/learn/getting-started-install/browser.md new file mode 100644 index 0000000000000..1b475d72ccfe5 --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-install/browser.md @@ -0,0 +1,11 @@ +The quickest way to get started is to use the CDN hosted version of the JavaScript browser SDK: + +```html + +``` + +{% include components/alert.html + title="Don't like the CDN?" + content="You can also NPM install our `@sentry/browser` package instead of using the CDN version." + level="info" +%} diff --git a/src/collections/_documentation/learn/getting-started-install/cordova.md b/src/collections/_documentation/learn/getting-started-install/cordova.md new file mode 100644 index 0000000000000..da7493803b8a0 --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-install/cordova.md @@ -0,0 +1,5 @@ +Install our SDK using the cordova command: + +```bash +$ cordova plugin add sentry-cordova +``` diff --git a/src/collections/_documentation/learn/getting-started-install/csharp.md b/src/collections/_documentation/learn/getting-started-install/csharp.md new file mode 100644 index 0000000000000..87b3c534d5ff3 --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-install/csharp.md @@ -0,0 +1,11 @@ +Install the **NuGet** package: + +Package Manager: +```shell +Install-Package Sentry +``` + +.NET Core CLI: +```shell +dotnet add package Sentry +``` diff --git a/src/collections/_documentation/learn/getting-started-install/electron.md b/src/collections/_documentation/learn/getting-started-install/electron.md new file mode 100644 index 0000000000000..b100282341ef0 --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-install/electron.md @@ -0,0 +1,11 @@ +If you are using `yarn` you can add our package as a dependency easily: + +```bash +$ yarn add @sentry/electron +``` + +Or alternatively you can npm install it: + +```bash +$ npm install @sentry/electron +``` diff --git a/src/collections/_documentation/learn/getting-started-install/node.md b/src/collections/_documentation/learn/getting-started-install/node.md new file mode 100644 index 0000000000000..7fc1b22b74ac7 --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-install/node.md @@ -0,0 +1,11 @@ +If you are using `yarn` you can add our package as a dependency easily: + +```bash +$ yarn add @sentry/node +``` + +Or alternatively you can npm install it: + +```bash +$ npm install @sentry/node +``` diff --git a/src/collections/_documentation/learn/getting-started-install/python.md b/src/collections/_documentation/learn/getting-started-install/python.md new file mode 100644 index 0000000000000..f4909a748e648 --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-install/python.md @@ -0,0 +1,5 @@ +Install our Python SDK using [`pip`](https://pip.pypa.io/en/stable/): + +```bash +$ pip install --upgrade sentry-sdk +``` diff --git a/src/collections/_documentation/learn/getting-started-install/rust.md b/src/collections/_documentation/learn/getting-started-install/rust.md new file mode 100644 index 0000000000000..2f0d50c9f8f67 --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-install/rust.md @@ -0,0 +1,6 @@ +To add sentry to your Rust project you just need to add a new dependency to your `Cargo.toml`: + +```toml +[dependencies] +sentry = "0.7.0" +``` diff --git a/src/collections/_documentation/learn/getting-started.md b/src/collections/_documentation/learn/getting-started.md new file mode 100644 index 0000000000000..99993b2b8e0bd --- /dev/null +++ b/src/collections/_documentation/learn/getting-started.md @@ -0,0 +1,36 @@ +--- +title: Getting Started +sidebar_order: 2 +--- + +Sentry is designed to be very simple to get off the ground, yet powerful to +grow into. If you have never used Sentry before, this tutorial will help you +getting started on the platform or your choice. + +## Step 1: Sign up for an account + +To use Sentry you either need to use a self hosted installation or the cloud +hosted version on sentry.io. You can [sign up here](https://sentry.io/signup/) +for free for a sentry.io account. + +Once you have an account you can create a project and retrieve the DSN, which +is something like an API key for submitting sentry events through our SDKs. + +## Step 2: Install your SDK + +Sentry supports many languages and platforms for error reporting. For some +platforms our new unified SDKs are available, for others the SDK usage might +derive slightly from it. Pick your platform to learn more. + +{% include components/platform_content.html content_dir='getting-started-install' %} + +## Step 3: Configure the SDK + +{% include components/platform_content.html content_dir='getting-started-config' %} + +## Relax + +With that you're ready to go. By default the SDKs will automatically capture any +unreported exception as it happens and report it to the project you selected in +Sentry. However with a bit of extra configuration and and instrumentation you can +unlock many more features. diff --git a/src/collections/_documentation/learn/scopes.md b/src/collections/_documentation/learn/scopes.md new file mode 100644 index 0000000000000..a1790f3e9af58 --- /dev/null +++ b/src/collections/_documentation/learn/scopes.md @@ -0,0 +1,65 @@ +--- +title: Scopes and Hubs +sidebar_order: 4 +--- + +When an event is captured and sent to Sentry SDKs will merge that event data with extra +information from the current scope. SDKs will typically automatically mange the scopes +for you in the framework integrations and you don't need to think about them. However +you should know what a scope is and how you can use it for your advantage. + +## What's a Scope, what's a Hub + +You can think of the hub as the central point that our SDKs use to route an +event to Sentry. When you call `init()` a hub is created and a client and a +blank scope are created on it. That hub is then associated with the current +thread and will internally hold a stack of scopes. + +The scope will hold useful information that should be sent along with the +event. For instance [contexts]({% link _documentation/learn/context.md %}) or +[breadcrumbs]({% link _documentation/learn/breadcrumbs.md %}) are stored on +the scope. When a scope is pushed it inherits all data from the parent scope +and when it pops all modifications are reverted. + +The default SDK integrations will push and pop scopes intelligently. For +instance web framework integrations will create and destroy scopes around your +routes or controllers. + +## How do the Scope and Hub Work + +As you start using an SDK a scope and hub are automatically created for you out +of the box. The hub you are unlikely to be interacting with directly unless you +are writing an integration or you want to create or destroy scopes. Scopes on the +other hand are more user facing. You can at any point in time call +`configure_scope` to modify data stored on the scope. This is for instance +used to [modify the context]({% link _documentation/learn/context.md %}). + +{% capture __alert_content -%} +If you are very curious about how this thread locality thing works here are the +nitty gritty details. On platforms such as .NET or on Python 3.7 and later we will +use "ambient data" to have either the hub flow with your code or the hub is already +a singleton that internally manages the scope. + +Effectively this means that when you spawn a task in .NET and the execution flow is +not supressed all the context you have bound to the scope in Sentry will flow along. +If however you surpress the flow you get new scope data. +{% endcapture %} +{%- include components/alert.html + title="Note" + content=__alert_content +%} + +When you call a global function such as `capture_event` internally Sentry +discovers the current hub and asks it to capture an event. Internally the hub will +then merge the event with the topmost scope's data. + +## Configuring the Scope + +The most useful operation when working with scopes is the `configure_scope` function. +It can be used to reconfigure the current scope. This for instance can be used to +add custom tags or to inform sentry about the currently authenticated user. + +{% include components/platform_content.html content_dir='configure-scope' %} + +To learn what useful information can be associated with scopes see +[the context documentation]({% link _documentation/learn/context.md %}). From 56da51fdb39c0f2e9410f5f2d0be6d1cd43076f3 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Mon, 3 Sep 2018 10:53:28 +0200 Subject: [PATCH 002/171] ref: Updated docs for options --- .../_documentation/learn/capturing.md | 2 +- .../_documentation/learn/configuration.md | 114 ++++++++++++------ .../_documentation/learn/getting-started.md | 36 ------ .../_documentation/learn/pricing.md | 2 +- .../_documentation/learn/quickstart.md | 61 ++++------ 5 files changed, 101 insertions(+), 114 deletions(-) delete mode 100644 src/collections/_documentation/learn/getting-started.md diff --git a/src/collections/_documentation/learn/capturing.md b/src/collections/_documentation/learn/capturing.md index e802d47803798..7c45a475ddb39 100644 --- a/src/collections/_documentation/learn/capturing.md +++ b/src/collections/_documentation/learn/capturing.md @@ -1,6 +1,6 @@ --- title: Capturing Events -sidebar_order: 3 +sidebar_order: 2 --- Out of the box SDKs will attempt to hook themselves into your runtime environment diff --git a/src/collections/_documentation/learn/configuration.md b/src/collections/_documentation/learn/configuration.md index 9d7e85c4018c5..95c32d0b3a663 100644 --- a/src/collections/_documentation/learn/configuration.md +++ b/src/collections/_documentation/learn/configuration.md @@ -1,6 +1,6 @@ --- title: Configuration -sidebar_order: 4 +sidebar_order: 1 --- SDKs are configurable in many ways. The options are largely standardized between SDKs but there are @@ -57,22 +57,6 @@ be sent. Events are picked randomly. This variable controls the total amount of breadcrumbs that should be captured. This defaults to `100`. -{:.config-key} -### http-proxy - -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. Note however that 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. - -{:.config-key} -### https-proxy - -{% unsupported csharp aspnetcore %} -Configures a separate proxy for outgoing HTTPS requests. This value might not be supported by all -SDKs. When not supported the `http-proxy` value is also used for HTTPS requests at all times. -{% endunsupported %} - {:.config-key} ### attach-stacktrace @@ -85,14 +69,6 @@ This means that you will get new groups as you enable or disable this flag for c This feature is off by default. -{:.config-key} -### with-locals - -{% supported python %} -When enabled local variables are sent along with stackframes. This can have a performance -and PII impact. Enabled by default on platforms where this is available. -{% endsupported %} - {:.config-key} ### send-default-pii @@ -101,17 +77,6 @@ integrations. Without this flag they are never added to the event to begin with it's recommended to turn on this feature and use the server side PII stripping to remove the values instead. -{:.config-key} -### shutdown-timeout - -{% unsupported browser %} -Controls how many seconds to wait before shutting down. Sentry SDKs send events from a background -queue and this queue is given a certain amount to drain pending events. The default is SDK specific -but typically around 2 seconds. Setting this value too low will most likely cause problems for -sending events from command line applications. Setting it too high will cause the application to -block for long time for users with network connectivity problems. -{% endunsupported %} - {:.config-key} ### server-name @@ -140,6 +105,27 @@ blacklist certain errors instead, use `blacklist-urls`. By default, all errors will be sent. This only applies to events sent from browsers. {% endsupported %} +{:.config-key} +### request-bodies + +{% supported python %} +This parameter controls if integrations should capture HTTP request bodies. It can be set to one +of the following values: + +* `never`: request bodies are never sent. +* `small`: only small request bodies will be captured where the cutoff for small depends on the SDK (typically 4KB) +* `medium`: medium sized requests and small requests will be captured. (typically 10KB) +* `always`: the SDK will always capture the request body for as long as sentry can make sense of it +{% endsupported %} + +{:.config-key} +### with-locals + +{% supported python %} +When enabled local variables are sent along with stackframes. This can have a performance +and PII impact. Enabled by default on platforms where this is available. +{% endsupported %} + ## Integration Configuration For many platform SDKs integrations can be configured alongside it. On some platforms that @@ -160,3 +146,59 @@ For more information have a look at the specific integration documentation. This can be used to disable integrations that are added by default. When set to `false` no default integrations are added. {% endsupported %} + +## Hooks + +These options can be used to hook the SDK in various ways to customize the reporting of events. + +{:.config-key} +### before-send + +This function is called with an SDK specific event object and can return a modified event object or +nothing to skip reporting the event. This can be used for instance for manual PII stripping before +sending. + +{:.config-key} +### before-breadcrumb + +This function is called with an SDK specific breadcrumb object before the breadcrumb is added to the +scope. When nothign is returned from the function the breadcrumb is dropped. + +## Transport Options + +Transports are used to send events to sentry. This can be customized to some degree to better +support highly specific deployments. + +{:.config-key} +### transport + +This switches out the transport that is 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. + +{:.config-key} +### http-proxy + +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. Note however that 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. + +{:.config-key} +### https-proxy + +{% unsupported csharp aspnetcore %} +Configures a separate proxy for outgoing HTTPS requests. This value might not be supported by all +SDKs. When not supported the `http-proxy` value is also used for HTTPS requests at all times. +{% endunsupported %} + +{:.config-key} +### shutdown-timeout + +{% unsupported browser %} +Controls how many seconds to wait before shutting down. Sentry SDKs send events from a background +queue and this queue is given a certain amount to drain pending events. The default is SDK specific +but typically around 2 seconds. Setting this value too low will most likely cause problems for +sending events from command line applications. Setting it too high will cause the application to +block for long time for users with network connectivity problems. +{% endunsupported %} diff --git a/src/collections/_documentation/learn/getting-started.md b/src/collections/_documentation/learn/getting-started.md deleted file mode 100644 index 99993b2b8e0bd..0000000000000 --- a/src/collections/_documentation/learn/getting-started.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Getting Started -sidebar_order: 2 ---- - -Sentry is designed to be very simple to get off the ground, yet powerful to -grow into. If you have never used Sentry before, this tutorial will help you -getting started on the platform or your choice. - -## Step 1: Sign up for an account - -To use Sentry you either need to use a self hosted installation or the cloud -hosted version on sentry.io. You can [sign up here](https://sentry.io/signup/) -for free for a sentry.io account. - -Once you have an account you can create a project and retrieve the DSN, which -is something like an API key for submitting sentry events through our SDKs. - -## Step 2: Install your SDK - -Sentry supports many languages and platforms for error reporting. For some -platforms our new unified SDKs are available, for others the SDK usage might -derive slightly from it. Pick your platform to learn more. - -{% include components/platform_content.html content_dir='getting-started-install' %} - -## Step 3: Configure the SDK - -{% include components/platform_content.html content_dir='getting-started-config' %} - -## Relax - -With that you're ready to go. By default the SDKs will automatically capture any -unreported exception as it happens and report it to the project you selected in -Sentry. However with a bit of extra configuration and and instrumentation you can -unlock many more features. diff --git a/src/collections/_documentation/learn/pricing.md b/src/collections/_documentation/learn/pricing.md index 3bb931998327e..e866e0c54ca9e 100644 --- a/src/collections/_documentation/learn/pricing.md +++ b/src/collections/_documentation/learn/pricing.md @@ -1,6 +1,6 @@ --- title: Pricing -sidebar_order: 1 +sidebar_order: 30 permalink: /pricing/ --- diff --git a/src/collections/_documentation/learn/quickstart.md b/src/collections/_documentation/learn/quickstart.md index b26a19a2512cc..77b31ccfb1c1c 100644 --- a/src/collections/_documentation/learn/quickstart.md +++ b/src/collections/_documentation/learn/quickstart.md @@ -11,73 +11,54 @@ Sentry is designed to be very simple to get off the ground, yet powerful to grow Getting started with Sentry is a three step process: 1. [Sign up for an account](https://sentry.io/signup/) -2. [Configure an SDK](#pick-a-client-integration) -3. [About the DSN](#configure-the-dsn) +2. [Install your SDK](#pick-a-client-integration) +2. [Configure it](#configure-the-sdk) ## Configure an SDK {#pick-a-client-integration} Sentry captures data by using an SDK within your application’s runtime. These are platform specific, and allow Sentry to have a deep understanding of both how your application works. In case your environment is very specific, you can also roll your own SDK using our document [_SDK API_]({%- link _documentation/clientdev/index.md -%}). -Popular integrations are: - -- [_Python_]({%- link _documentation/clients/python/index.md -%}) -- [_JavaScript_]({%- link _documentation/clients/javascript/index.md -%}) -- [_PHP_]({%- link _documentation/clients/php/index.md -%}) -- [_Ruby_]({%- link _documentation/clients/ruby/index.md -%}) -- [_Java_]({%- link _documentation/clients/java/index.md -%}) -- [_Cocoa_]({%- link _documentation/clients/cocoa/index.md -%}) -- [_C#_]({%- link _documentation/clients/csharp/index.md -%}) -- [_Go_]({%- link _documentation/clients/go/index.md -%}) -- [_Elixir_]({%- link _documentation/clients/elixir/index.md -%}) - -For exact configuration for the integration consult the corresponding documentation. For all SDKs however, the basics are the same. - -## About the DSN {#configure-the-dsn} - -After you complete setting up a project in Sentry, you’ll be given a value which we call a _DSN_, or _Data Source Name_. It looks a lot like a standard URL, but it’s actually just a representation of the configuration required by the Sentry SDKs. It consists of a few pieces, including the protocol, public key, the server address, and the project identifier. +{% include components/platform_content.html content_dir='getting-started-install' %} {% capture __alert_content -%} -As of Sentry 9, we removed the need to provide the secret key. Older versions of SDKs may still require you to provide the DSN including the secret which is now called DSN (Legacy). Please check the corresponding docs of the SDK you are using if you still need to provide the secret. +Your platform is not listed? There are more SDKs we support: [list of SDKs]({%- link _documentation/clients/index.md -%}) {%- endcapture -%} {%- include components/alert.html title="Note" content=__alert_content %} -The DSN can be found in Sentry by navigating to [Project Name] -> Project Settings -> Client Keys (DSN). Its template resembles the following: - -``` -'{PROTOCOL}://{PUBLIC_KEY}@{HOST}/{PATH}{PROJECT_ID}' -``` - -If you are using the Hosted Sentry and signed into your account, the documentation will refer to your actual DSNs. You can select the correct one which will adjust the examples for easy copy pasting: +## Configure the SDK {#configure-the-sdk} -``` -'___PUBLIC_DSN___' -``` +After you complete setting up a project in Sentry, you’ll be given a value which we call a _DSN_, or _Data Source Name_. It looks a lot like a standard URL, but it’s actually just a representation of the configuration required by the Sentry SDKs. It consists of a few pieces, including the protocol, public key, the server address, and the project identifier. -It is composed of five important pieces: +{% include components/platform_content.html content_dir='getting-started-config' %} -- The Protocol used. This can be one of the following: http or https. -- The public key to authenticate the SDK. -- The destination Sentry server. -- The project ID which the authenticated user is bound to. +Most SDKs will now automatically collect data if available, some require some extra configuration as automatic error collecting is not +available due to platform limitations. -You’ll have a few options for plugging the DSN into the SDK, depending on what it supports. At the very least, most SDKs will allow you to set it up as the `SENTRY_DSN` environment variable or by passing it into the SDK’s constructor. +{% capture __alert_content -%} +As of Sentry 9, we removed the need to provide the secret key. Older versions of SDKs may still require you to provide the DSN including the secret which is now called DSN (Legacy). Please check the corresponding docs of the SDK you are using if you still need to provide the secret. -For example for the JavaScript SDK it works roughly like this: +The DSN can be found in Sentry by navigating to [Project Name] -> Project Settings -> Client Keys (DSN). Its template resembles the following: -```javascript -import Raven from 'raven-js' -Raven.config('___PUBLIC_DSN___') +``` +'{PROTOCOL}://{PUBLIC_KEY}@{HOST}/{PROJECT_ID}' ``` Note: If you’re using Heroku, and you’ve added Hosted Sentry via the standard addon hooks, most SDKs will automatically pick up the `SENTRY_DSN` environment variable that we’ve already configured for you. +{%- endcapture -%} +{%- include components/alert.html + title="Note" + content=__alert_content +%} ## Next Steps Now that you’ve got basic reporting setup, you’ll want to explore adding additional context to your data. +- [_manual error and event capturing_]({%- link _documentation/learn/capturing.md -%}) +- [_configuration options_]({%- link _documentation/learn/configuration.md -%}) - [_identifying users via context_]({%- link _documentation/learn/context.md -%}) - [_tracing issues with breadcrumbs_]({%- link _documentation/learn/breadcrumbs.md -%}) - [_capturing user feedback on crashes_]({%- link _documentation/learn/user-feedback.md -%}) From 1fbed9ef2c6fe57014f711a4ce21c6dcdef8b9bf Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Mon, 3 Sep 2018 11:04:59 +0200 Subject: [PATCH 003/171] fix: Fix the unsupported hint not showing correctly --- src/_assets/css/_includes/platform-specific-content.scss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/_assets/css/_includes/platform-specific-content.scss b/src/_assets/css/_includes/platform-specific-content.scss index 0d35013a624af..94f917c8bb469 100644 --- a/src/_assets/css/_includes/platform-specific-content.scss +++ b/src/_assets/css/_includes/platform-specific-content.scss @@ -6,10 +6,17 @@ } } +.unsupported { + .unsupported-hint { + display: none; + } +} + .unsupported.is-unsupported { opacity: 0.5; .unsupported-hint { + display: block; font-size: 0.9rem; font-weight: bold; margin-bottom: 0.3rem; From 6ab1a64af248fc41805572a59b1042d2120d3bf3 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Mon, 3 Sep 2018 11:28:05 +0200 Subject: [PATCH 004/171] feat: Updated context docs --- src/_data/platforms.yml | 2 +- .../_documentation/learn/context.md | 71 +++++++------------ .../_documentation/learn/releases.md | 9 +-- .../_documentation/learn/set-extra/python.md | 6 ++ .../learn/set-release/browser.md | 7 ++ .../learn/set-release/cordova.md | 8 +++ .../learn/set-release/electron.md | 7 ++ .../_documentation/learn/set-release/node.md | 7 ++ .../learn/set-release/python.md | 5 ++ .../_documentation/learn/set-release/rust.md | 7 ++ .../_documentation/learn/set-tag/python.md | 6 ++ .../_documentation/learn/set-user/python.md | 6 ++ 12 files changed, 90 insertions(+), 51 deletions(-) create mode 100644 src/collections/_documentation/learn/set-extra/python.md create mode 100644 src/collections/_documentation/learn/set-release/browser.md create mode 100644 src/collections/_documentation/learn/set-release/cordova.md create mode 100644 src/collections/_documentation/learn/set-release/electron.md create mode 100644 src/collections/_documentation/learn/set-release/node.md create mode 100644 src/collections/_documentation/learn/set-release/python.md create mode 100644 src/collections/_documentation/learn/set-release/rust.md create mode 100644 src/collections/_documentation/learn/set-tag/python.md create mode 100644 src/collections/_documentation/learn/set-user/python.md diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index 629b556b26330..1d419ba37707a 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -175,7 +175,7 @@ slug: browser support_level: production type: language - name: Browser + name: Browser JavaScript doc_link: /clients/javascript/ wizard: [] case_style: camelCase diff --git a/src/collections/_documentation/learn/context.md b/src/collections/_documentation/learn/context.md index 96d8fb9ca34b0..68946d3c75282 100644 --- a/src/collections/_documentation/learn/context.md +++ b/src/collections/_documentation/learn/context.md @@ -1,28 +1,42 @@ --- title: Context sidebar_order: 4 +example_tag_name: page_locale +example_tag_value: de-at +example_user_email: 'john.doe@example.com' +example_extra_key: character_name +example_extra_value: 'Mighty Fighter' --- Sentry supports additional context with events. Often this context is shared amongst any issue captured in its lifecycle, and includes the following components: -**Tags** - -: Key/value pairs which generate breakdowns charts and search filters - **User** : Information about the current actor -**Extra** +**Structured Contexts** + +: Specific structured contexts (OS info, runtime information etc.). This is normally set automatically. + +**Tags** + +: Key/value pairs which generate breakdowns charts and search filters -: Arbitrary unstructured data which is stored with an event sample +**Unstructured Extra** -Context is considered to be request state, and thus should be cleared out at the beginning (or end) of each operation. SDKs like the JavaScript SDK usually won’t need to worry about this as they generally are not long lived. +: Arbitrary unstructured data which is stored with an event sample. + +Context is held on the current scope and thus is cleared out at the end of each operation (request etc.). For more information +[have a look at the scopes and hub documentation](({%- link _documentation/learn/scopes.md -%}). ## Tagging Events Sentry implements a system it calls tags. Tags are various key/value pairs that get assigned to an event, and can later be used as a breakdown or quick access to finding related events. +Most SDKs generally support configuring tags by configuring the scope: + +{% include components/platform_content.html content_dir='set-tag' %} + Several common uses for tags include: - The hostname of the server @@ -37,28 +51,14 @@ Once you’ve starting sending tagged data, you’ll see it show up in a few pla We’ll automatically index all tags for an event, as well as the frequency and the last time a value has been seen. Even more so, we keep track of the number of distinct tags, and can assist in you determining hotspots for various issues. -Most SDKs generally support configuring tags at the global SDK level configuration, as well as on a per event basis. - -For example, in the JavaScript SDK: - -```javascript -Raven.captureMessage('hello world!', {tags: { - locale: 'en-us' -}}); -``` - -Or to bind tags to the request context: - -```javascript -Raven.setTagsContext({ - environment: "production" -}); -``` - ## Capturing the User Sending users to Sentry will unlock a number of features, primarily the ability to drill down into the number of users affecting an issue, as well to get a broader sense about the quality of the application. +Capturing the user is fairly straight forward: + +{% include components/platform_content.html content_dir='set-user' %} + Users consist of a few key pieces of information which are used to construct a unique identity in Sentry. Each of these is optional, but one **must** be present in order for the user to be captured: `id` @@ -79,25 +79,8 @@ Users consist of a few key pieces of information which are used to construct a u Additionally you can provide arbitrary key/value pairs beyond the reserved names and those will be stored with the user. -Capturing the user is fairly straight forward. For example, in the JavaScript SDK: - -```javascript -Raven.setUserContext({ - email: 'foo@example.com' -}); -``` - ## Extra Context -In addition to the structured context that Sentry understands, you can send arbitrary key/value pairs of data which will be stored alongside the event. These are not indexed and are simply used to add additional information about what might be happening. - -Extra context can generally be passed in both the event constructor, as well as the global context state: - -For example, in the JavaScript SDK: +In addition to the structured context that Sentry understands, you can send arbitrary key/value pairs of data which will be stored alongside the event. These are not indexed and are simply used to add additional information about what might be happening: -```javascript -Raven.setExtraContext({ - arbitrary: {key: value}, - foo: "bar" -}); -``` +{% include components/platform_content.html content_dir='set-extra' %} diff --git a/src/collections/_documentation/learn/releases.md b/src/collections/_documentation/learn/releases.md index 48ed3dfa2b796..352307e92356b 100644 --- a/src/collections/_documentation/learn/releases.md +++ b/src/collections/_documentation/learn/releases.md @@ -1,6 +1,7 @@ --- title: Releases sidebar_order: 3 +release_identifier: "my-project-name@2.3.12" --- A release is a version of your code that is deployed to an environment. When you give Sentry information about your releases, you unlock a number of new features: @@ -22,13 +23,9 @@ Configuring releases fully is a 3-step process: ### Tag Your Errors {#tag-errors} -Include a release ID (a.k.a version) where you configure your client SDK. This is commonly a git SHA or a custom version number (check language-specific docs for exact syntax): +Include a release ID (a.k.a version) where you configure your client SDK. This is commonly a git SHA or a custom version number. Note that releases are global per organization so make sure to prefix them with something project specific if needed: -```javascript -SentryClient.setRelease({ - release: "6d5a6a446805a06154e25e2fa203d67b9e762f5d" -}); -``` +{% include components/platform_content.html content_dir='set-release' %} How you make the version available to your code is up to you. For example, you could use an environment variable that is set during the build process. diff --git a/src/collections/_documentation/learn/set-extra/python.md b/src/collections/_documentation/learn/set-extra/python.md new file mode 100644 index 0000000000000..c0a5e54708fc9 --- /dev/null +++ b/src/collections/_documentation/learn/set-extra/python.md @@ -0,0 +1,6 @@ +```python +from sentry_sdk import configure_scope + +with configure_scope() as scope: + scope.set_extra({"{{ page.example_extra_key }}": "{{ page.example_extra_value }}") +``` diff --git a/src/collections/_documentation/learn/set-release/browser.md b/src/collections/_documentation/learn/set-release/browser.md new file mode 100644 index 0000000000000..bf2dc7fcf9e66 --- /dev/null +++ b/src/collections/_documentation/learn/set-release/browser.md @@ -0,0 +1,7 @@ +```javascript +import * as Sentry from '@sentry/browser'; + +Sentry.init({ + release: "{{ page.release_identifier }}" +}) +``` diff --git a/src/collections/_documentation/learn/set-release/cordova.md b/src/collections/_documentation/learn/set-release/cordova.md new file mode 100644 index 0000000000000..efd9384d23a81 --- /dev/null +++ b/src/collections/_documentation/learn/set-release/cordova.md @@ -0,0 +1,8 @@ +```javascript +onDeviceReady: function() { + var Sentry = cordova.require("sentry-cordova.Sentry"); + Sentry.init({ + release: "{{ page.release_identifier }}" + }); +} +``` diff --git a/src/collections/_documentation/learn/set-release/electron.md b/src/collections/_documentation/learn/set-release/electron.md new file mode 100644 index 0000000000000..04bca6c162414 --- /dev/null +++ b/src/collections/_documentation/learn/set-release/electron.md @@ -0,0 +1,7 @@ +```javascript +import * as sentry from '@sentry/electron'; + +Sentry.init({ + release: "{{ page.release_identifier }}", +}) +``` diff --git a/src/collections/_documentation/learn/set-release/node.md b/src/collections/_documentation/learn/set-release/node.md new file mode 100644 index 0000000000000..856584e4e3edc --- /dev/null +++ b/src/collections/_documentation/learn/set-release/node.md @@ -0,0 +1,7 @@ +```javascript +const Sentry = require('@sentry/node'); + +Sentry.init({ + release: "{{ page.release_identifier }}" +}) +``` diff --git a/src/collections/_documentation/learn/set-release/python.md b/src/collections/_documentation/learn/set-release/python.md new file mode 100644 index 0000000000000..902836838184f --- /dev/null +++ b/src/collections/_documentation/learn/set-release/python.md @@ -0,0 +1,5 @@ +```python +import sentry_sdk + +sentry_sdk.init(release="{{ page.release_identifier }}") +``` diff --git a/src/collections/_documentation/learn/set-release/rust.md b/src/collections/_documentation/learn/set-release/rust.md new file mode 100644 index 0000000000000..39a303ee24fe4 --- /dev/null +++ b/src/collections/_documentation/learn/set-release/rust.md @@ -0,0 +1,7 @@ +```rust +use sentry; + +sentry::init(sentry::ClientOptions { + release: "{{ page.release_identifier }}" +}); +``` diff --git a/src/collections/_documentation/learn/set-tag/python.md b/src/collections/_documentation/learn/set-tag/python.md new file mode 100644 index 0000000000000..85cbfa833f778 --- /dev/null +++ b/src/collections/_documentation/learn/set-tag/python.md @@ -0,0 +1,6 @@ +```python +from sentry_sdk import configure_scope + +with configure_scope() as scope: + scope.set_tag("{{ page.example_tag_name }}", "{{ page.example_tag_value }}") +``` diff --git a/src/collections/_documentation/learn/set-user/python.md b/src/collections/_documentation/learn/set-user/python.md new file mode 100644 index 0000000000000..503ead5ccf661 --- /dev/null +++ b/src/collections/_documentation/learn/set-user/python.md @@ -0,0 +1,6 @@ +```python +from sentry_sdk import configure_scope + +with configure_scope() as scope: + scope.set_user({"email": "{{ page.example_user_email }}") +``` From 9bca82840d3936ce4e6395c069f6f7ecb0a06109 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Mon, 3 Sep 2018 13:01:10 +0200 Subject: [PATCH 005/171] feat: Initial pass over user feedback --- .../components/platform_content.html | 2 +- .../learn/before-send/python.md | 11 ++++ .../_documentation/learn/environments.md | 10 +--- .../_documentation/learn/rollups.md | 9 +-- .../_documentation/learn/sensitive-data.md | 6 ++ .../learn/set-environment/python.md | 5 ++ .../learn/set-fingerprint/python.md | 6 ++ .../learn/user-feedback-example/django.md | 27 +++++++++ .../_documentation/learn/user-feedback.md | 59 +------------------ 9 files changed, 64 insertions(+), 71 deletions(-) create mode 100644 src/collections/_documentation/learn/before-send/python.md create mode 100644 src/collections/_documentation/learn/set-environment/python.md create mode 100644 src/collections/_documentation/learn/set-fingerprint/python.md create mode 100644 src/collections/_documentation/learn/user-feedback-example/django.md diff --git a/src/_includes/components/platform_content.html b/src/_includes/components/platform_content.html index d7d3dec837324..97f3812a379ad 100644 --- a/src/_includes/components/platform_content.html +++ b/src/_includes/components/platform_content.html @@ -97,7 +97,7 @@ {% include_relative {{ __relative_path }} %} {%- endcapture -%}
- {{ __content | liquify | markdownify }} + {{ __content | markdownify }}
{%- endfor -%} diff --git a/src/collections/_documentation/learn/before-send/python.md b/src/collections/_documentation/learn/before-send/python.md new file mode 100644 index 0000000000000..b1d10c8341489 --- /dev/null +++ b/src/collections/_documentation/learn/before-send/python.md @@ -0,0 +1,11 @@ +```python +import sentry_sdk + +def strip_pii(event): + # modify event here + return event + +sentry_sdk.init( + before_send=strip_pii +) +``` diff --git a/src/collections/_documentation/learn/environments.md b/src/collections/_documentation/learn/environments.md index 87c21360c891b..245cbb56a1ec3 100644 --- a/src/collections/_documentation/learn/environments.md +++ b/src/collections/_documentation/learn/environments.md @@ -1,6 +1,7 @@ --- title: Environments sidebar_order: 5 +example_environment: "staging" --- _Note: The environments feature is only available for early adopters. You can enable early adopter features by navigating to your organization settings._ @@ -35,11 +36,6 @@ If you would like to see Sentry filtered by a certain environment every time you # How to send environment data -Environment data is sent to Sentry by tagging issues via your SDK. You can send environment data to Sentry using the following SDKs: +Environment data is sent to Sentry by tagging issues via your SDK: -- [Javascript]({%- link _documentation/clients/javascript/config.md -%}) -- [Node.js]({%- link _documentation/clients/node/config.md -%}#configuration) -- [Python]({%- link _documentation/clients/python/advanced.md -%}) -- [Ruby]({%- link _documentation/clients/ruby/config.md -%}) -- [php]({%- link _documentation/clients/php/config.md -%}) -- [Java]({%- link _documentation/clients/java/config.md -%}) +{% include components/platform_content.html content_dir='set-environment' %} diff --git a/src/collections/_documentation/learn/rollups.md b/src/collections/_documentation/learn/rollups.md index 53fdac8cccb9a..98ee2ea4a5731 100644 --- a/src/collections/_documentation/learn/rollups.md +++ b/src/collections/_documentation/learn/rollups.md @@ -58,12 +58,9 @@ To work around these the Sentry protocol supports a `fingerprint` attribute. In supported SDKs, this attribute can be passed with the event information, and should be an array of strings: -```javascript -Raven.captureException(ex, {fingerprint: ['my', 'custom', 'fingerprint']}) -``` - -Additionally if you simply wish to append information, thus making the grouping slightly less aggressive, you can do that as well: - ```javascript {% raw %}Raven.captureException(ex, {fingerprint: ['{{ default }}', 'other', 'data']}){% endraw %} ``` +{% include components/platform_content.html content_dir='set-fingerprint' %} + +Additionally if you simply wish to append information, thus making the grouping slightly less aggressive, you can do that as well by adding the special string `{% raw %}{{ default }}{% endraw %}` as one of the items. diff --git a/src/collections/_documentation/learn/sensitive-data.md b/src/collections/_documentation/learn/sensitive-data.md index 50cba21f88f48..aba8b3c73a293 100644 --- a/src/collections/_documentation/learn/sensitive-data.md +++ b/src/collections/_documentation/learn/sensitive-data.md @@ -41,3 +41,9 @@ If you’ve accidentally sent sensitive data to the server it’s likely you’r - If you send it as a tagged value, removing the event is not enough. You can visit Project Settings and under Tags you’ll find a way to permanently remove any related data for a given tag. - If you need to wipe just a single event, you’ll find the ability to bulk delete all sampled events under a rollup by visiting the rollup details page and selecting “Delete”. - If you send sparse events to a project (potentially all of them), your only option is to remove the project and re-create it. Keep in mind this will revoke API credentials, so you likely want to do this in the reverse order. + +## Custom Event Processing + +In the SDKs you can also set a function `before-send` which is invoked before events are sent which can be used to modify the events and remove bad data: + +{% include components/platform_content.html content_dir='before-send' %} diff --git a/src/collections/_documentation/learn/set-environment/python.md b/src/collections/_documentation/learn/set-environment/python.md new file mode 100644 index 0000000000000..605f73aa8cf10 --- /dev/null +++ b/src/collections/_documentation/learn/set-environment/python.md @@ -0,0 +1,5 @@ +```python +import sentry_sdk + +sentry_sdk.init(environment="{{ page.example_environment }}") +``` diff --git a/src/collections/_documentation/learn/set-fingerprint/python.md b/src/collections/_documentation/learn/set-fingerprint/python.md new file mode 100644 index 0000000000000..08bd2541d1faa --- /dev/null +++ b/src/collections/_documentation/learn/set-fingerprint/python.md @@ -0,0 +1,6 @@ +```python +from sentry_sdk import configure_scope + +with configure_scope() as scope: + scope.fingerprint = ['my-view-function'] +``` diff --git a/src/collections/_documentation/learn/user-feedback-example/django.md b/src/collections/_documentation/learn/user-feedback-example/django.md new file mode 100644 index 0000000000000..2b7d269f74f85 --- /dev/null +++ b/src/collections/_documentation/learn/user-feedback-example/django.md @@ -0,0 +1,27 @@ +Custom 500 handler: + +```python +from sentry_sdk import last_event_id +from django.shortcuts import render + +def handler500(request, *args, **argv): + return render(request, "500.html", { + 'sentry_event_id': last_event_id(), + }, status=500) +``` + +And the template that brings up the dialog + +{% raw %} +```html + + +{% if sentry_event_id %} + +{% endif %} +``` +{% endraw %} diff --git a/src/collections/_documentation/learn/user-feedback.md b/src/collections/_documentation/learn/user-feedback.md index 609120221018b..382e1505f69c7 100644 --- a/src/collections/_documentation/learn/user-feedback.md +++ b/src/collections/_documentation/learn/user-feedback.md @@ -15,64 +15,9 @@ When feedback is collected, Sentry will pair it up with the original event givin ## Collecting Feedback -The integration process consists of running our JavaScript SDK (2.1 or newer), authenticating with your public DSN, and passing in the client-side generated Event ID. +The integration process consists of running our JavaScript SDK (2.1 or newer), authenticating with your public DSN, and passing in the client-side generated Event ID: -For example, in Django this looks like the following: - -```html -{% raw %} - - -{% if request.sentry.id %} - -{% endif %}{% endraw %} -``` - -Often this will vary depending on how you handle errors – specifically routing and rendering errors. If you’ve got a more custom setup, you’ll simply need to pull out the event ID and pass it into the widget: - -```python -class IndexController(Controller): - def get(self, request): - try: - 1 / 0 - except Exception: - event_id = Raven.captureException() - return render('500.html', {'sentry_event_id': event_id}) -``` - -Then simply check for the ID in the template, and open the feedback dialog: - -```html -{% raw %} - -{% if sentry_event_id %} - -{% endif %}{% endraw %} -``` - -Some integrations and frameworks will make this even easier: - -- [Browser JavaScript]({%- link _documentation/clients/javascript/usage.md -%}#javascript-user-feedback) -- [Django]({%- link _documentation/clients/python/integrations/django.md -%}#python-django-user-feedback) -- [Flask]({%- link _documentation/clients/python/integrations/flask.md -%}#python-flask-user-feedback) -- [PHP]({%- link _documentation/clients/php/usage.md -%}#php-user-feedback) -- [Cocoa]({%- link _documentation/clients/cocoa/advanced.md -%}#cocoa-user-feedback) - -Take a look at your SDK’s documentation for more information. +{% include components/platform_content.html content_dir='user-feedback-example' %} ## Customizing the Widget From d9b5df348db09e037ae2069ebd70956be9f858a4 Mon Sep 17 00:00:00 2001 From: HazA Date: Tue, 4 Sep 2018 09:14:13 +0200 Subject: [PATCH 006/171] fix: typos and browser platform --- src/_data/platforms.yml | 2 +- .../_documentation/learn/configuration.md | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index 1d419ba37707a..b212fc51be560 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -175,7 +175,7 @@ slug: browser support_level: production type: language - name: Browser JavaScript + name: JavaScript / Browser doc_link: /clients/javascript/ wizard: [] case_style: camelCase diff --git a/src/collections/_documentation/learn/configuration.md b/src/collections/_documentation/learn/configuration.md index 95c32d0b3a663..68a0b863d6c21 100644 --- a/src/collections/_documentation/learn/configuration.md +++ b/src/collections/_documentation/learn/configuration.md @@ -4,7 +4,7 @@ sidebar_order: 1 --- SDKs are configurable in many ways. The options are largely standardized between SDKs but there are -some differences to better acomodate platform peculiarities. Options are set when the SDK is first +some differences to better acommodate platform peculiarities. Options are set when the SDK is first initialized. {% include components/platform_content.html content_dir='config-intro' %} @@ -36,12 +36,12 @@ differently. For more information have a look at [the releases documentation]({ ### environment Sets the environment. This string is freeform and not set by default. A release can be associated -with more than one environment to separate them im the UI (think `staging` vs `prod` or similar). +with more than one environment to separate them in the UI (think `staging` vs `prod` or similar). {:.config-key} ### repos -For repository integration the repository identifiers need to be sent along. For more information +For repository integration, the repository identifiers need to be sent along. For more information have a look at [the releases documentation]({% link _documentation/learn/releases.md %}). {:.config-key} @@ -61,8 +61,7 @@ to `100`. ### attach-stacktrace When enabled stacktraces are automatically attached to all messages logged. Note that stacktraces -are always attached to exceptions but when this is set stacktraces are also sent with messages. This -for instance means that stacktraces appear next to all log messages. +are always attached to exceptions but when this is set stacktraces are also sent with messages. This, for instance, means that stacktraces appear next to all log messages. It's important to note that grouping in Sentry is different for events with stacktraces and without. This means that you will get new groups as you enable or disable this flag for certain events. @@ -72,8 +71,8 @@ This feature is off by default. {:.config-key} ### send-default-pii -If this flag is enabled then certain personally identifyable information is added by active -integrations. Without this flag they are never added to the event to begin with. If possible +If this flag, is enabled then certain personally identifiable information is added by active +integrations. Without this flag they are never added to the event, to begin with. If possible it's recommended to turn on this feature and use the server side PII stripping to remove the values instead. @@ -84,7 +83,7 @@ values instead. Can be used to supply a "server name". When provided the name of the server is sent along and persisted in the event. Note that 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. +will attempt to auto-discover this value. {% endunsupported %} {:.config-key} @@ -114,7 +113,7 @@ of the following values: * `never`: request bodies are never sent. * `small`: only small request bodies will be captured where the cutoff for small depends on the SDK (typically 4KB) -* `medium`: medium sized requests and small requests will be captured. (typically 10KB) +* `medium`: medium-sized requests and small requests will be captured. (typically 10KB) * `always`: the SDK will always capture the request body for as long as sentry can make sense of it {% endsupported %} @@ -162,7 +161,7 @@ sending. ### before-breadcrumb This function is called with an SDK specific breadcrumb object before the breadcrumb is added to the -scope. When nothign is returned from the function the breadcrumb is dropped. +scope. When nothing is returned from the function the breadcrumb is dropped. ## Transport Options From eb9a407d64ba6f60810a4bebfddfe867d590f673 Mon Sep 17 00:00:00 2001 From: HazA Date: Tue, 4 Sep 2018 09:15:53 +0200 Subject: [PATCH 007/171] fix: Add more commas --- src/collections/_documentation/learn/configuration.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/collections/_documentation/learn/configuration.md b/src/collections/_documentation/learn/configuration.md index 68a0b863d6c21..81abd8ac9ec89 100644 --- a/src/collections/_documentation/learn/configuration.md +++ b/src/collections/_documentation/learn/configuration.md @@ -128,7 +128,7 @@ and PII impact. Enabled by default on platforms where this is available. ## Integration Configuration For many platform SDKs integrations can be configured alongside it. On some platforms that -happens as part of the `init()` call, in some others different patterns apply. +happen as part of the `init()` call, in some others, different patterns apply. {:.config-key} ### integrations @@ -172,7 +172,7 @@ support highly specific deployments. ### transport This switches out the transport that is 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 +can, for instance, be used to capture events for unit-testing or to send it through some more complex setup that requires proxy authentication. {:.config-key} @@ -180,8 +180,8 @@ 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. Note however that 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. +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. {:.config-key} ### https-proxy @@ -199,5 +199,5 @@ Controls how many seconds to wait before shutting down. Sentry SDKs send events queue and this queue is given a certain amount to drain pending events. The default is SDK specific but typically around 2 seconds. Setting this value too low will most likely cause problems for sending events from command line applications. Setting it too high will cause the application to -block for long time for users with network connectivity problems. +block for a long time for users with network connectivity problems. {% endunsupported %} From a268deb38dcac7e23ed79fb9dd36ea44a6e2eb3f Mon Sep 17 00:00:00 2001 From: HazA Date: Tue, 4 Sep 2018 14:32:18 +0200 Subject: [PATCH 008/171] fix: Typos and minor stuff --- .../_documentation/learn/config-intro/electron.md | 2 +- .../_documentation/learn/configuration.md | 15 ++++++--------- .../learn/getting-started-config/electron.md | 4 ++-- .../learn/getting-started-install/rust.md | 2 +- .../_documentation/learn/quickstart.md | 6 +++--- .../_documentation/learn/set-release/electron.md | 2 +- 6 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/collections/_documentation/learn/config-intro/electron.md b/src/collections/_documentation/learn/config-intro/electron.md index 1f57a8856bee0..4836c02699521 100644 --- a/src/collections/_documentation/learn/config-intro/electron.md +++ b/src/collections/_documentation/learn/config-intro/electron.md @@ -1,7 +1,7 @@ Options are passed to the `init()` as object: ```javascript -import * as sentry from '@sentry/electron'; +import * as Sentry from '@sentry/electron'; Sentry.init({ dsn: '___PUBLIC_DSN___', diff --git a/src/collections/_documentation/learn/configuration.md b/src/collections/_documentation/learn/configuration.md index 81abd8ac9ec89..f2124288c445c 100644 --- a/src/collections/_documentation/learn/configuration.md +++ b/src/collections/_documentation/learn/configuration.md @@ -66,12 +66,12 @@ are always attached to exceptions but when this is set stacktraces are also sent It's important to note that grouping in Sentry is different for events with stacktraces and without. This means that you will get new groups as you enable or disable this flag for certain events. -This feature is off by default. +This feature is `off` by default. {:.config-key} ### send-default-pii -If this flag, is enabled then certain personally identifiable information is added by active +If this flag is enabled, certain personally identifiable information is added by active integrations. Without this flag they are never added to the event, to begin with. If possible it's recommended to turn on this feature and use the server side PII stripping to remove the values instead. @@ -90,18 +90,15 @@ will attempt to auto-discover this value. ### blacklist-urls {% supported browser %} -A pattern for error URLs which should not be sent to Sentry. To whitelist certain errors instead, -use `whitelist-urls`. By default, all errors will be sent. This only applies to events sent -from browsers. +A pattern for error URLs which should not be sent to Sentry. By default, all errors will be sent. {% endsupported %} {:.config-key} ### whitelist-urls {% supported browser %} -A pattern for error URLs which should exclusively be sent to Sentry. To -blacklist certain errors instead, use `blacklist-urls`. By default, all errors -will be sent. This only applies to events sent from browsers. +A pattern for error URLs which should exclusively be sent to Sentry. By default, all errors +will be sent. {% endsupported %} {:.config-key} @@ -165,7 +162,7 @@ scope. When nothing is returned from the function the breadcrumb is dropped. ## Transport Options -Transports are used to send events to sentry. This can be customized to some degree to better +Transports are used to send events to Sentry. This can be customized to some degree to better support highly specific deployments. {:.config-key} diff --git a/src/collections/_documentation/learn/getting-started-config/electron.md b/src/collections/_documentation/learn/getting-started-config/electron.md index 97de4b1c4e61d..f17dd827e21bf 100644 --- a/src/collections/_documentation/learn/getting-started-config/electron.md +++ b/src/collections/_documentation/learn/getting-started-config/electron.md @@ -2,6 +2,6 @@ You need to inform the sentry electron SDK about your CDN somewhere before application startup: ```javascript -import * as sentry from '@sentry/electron'; -sentry.init({dsn: '___PUBLIC_DSN___'}); +import * as Sentry from '@sentry/electron'; +Sentry.init({dsn: '___PUBLIC_DSN___'}); ``` diff --git a/src/collections/_documentation/learn/getting-started-install/rust.md b/src/collections/_documentation/learn/getting-started-install/rust.md index 2f0d50c9f8f67..885521257f7b1 100644 --- a/src/collections/_documentation/learn/getting-started-install/rust.md +++ b/src/collections/_documentation/learn/getting-started-install/rust.md @@ -1,4 +1,4 @@ -To add sentry to your Rust project you just need to add a new dependency to your `Cargo.toml`: +To add Sentry to your Rust project you just need to add a new dependency to your `Cargo.toml`: ```toml [dependencies] diff --git a/src/collections/_documentation/learn/quickstart.md b/src/collections/_documentation/learn/quickstart.md index 77b31ccfb1c1c..81ea0cc68ea9a 100644 --- a/src/collections/_documentation/learn/quickstart.md +++ b/src/collections/_documentation/learn/quickstart.md @@ -14,9 +14,9 @@ Getting started with Sentry is a three step process: 2. [Install your SDK](#pick-a-client-integration) 2. [Configure it](#configure-the-sdk) -## Configure an SDK {#pick-a-client-integration} +## Install a SDK {#pick-a-client-integration} -Sentry captures data by using an SDK within your application’s runtime. These are platform specific, and allow Sentry to have a deep understanding of both how your application works. In case your environment is very specific, you can also roll your own SDK using our document [_SDK API_]({%- link _documentation/clientdev/index.md -%}). +Sentry captures data by using a SDK within your application’s runtime. These are platform specific and allow Sentry to have a deep understanding of both how your application works. In case your environment is very specific, you can also roll your own SDK using our document [_SDK API_]({%- link _documentation/clientdev/index.md -%}). {% include components/platform_content.html content_dir='getting-started-install' %} @@ -30,7 +30,7 @@ Your platform is not listed? There are more SDKs we support: [list of SDKs]({%- ## Configure the SDK {#configure-the-sdk} -After you complete setting up a project in Sentry, you’ll be given a value which we call a _DSN_, or _Data Source Name_. It looks a lot like a standard URL, but it’s actually just a representation of the configuration required by the Sentry SDKs. It consists of a few pieces, including the protocol, public key, the server address, and the project identifier. +After you completed setting up a project in Sentry, you’ll be given a value which we call a _DSN_, or _Data Source Name_. It looks a lot like a standard URL, but it’s actually just a representation of the configuration required by the Sentry SDKs. It consists of a few pieces, including the protocol, public key, the server address, and the project identifier. {% include components/platform_content.html content_dir='getting-started-config' %} diff --git a/src/collections/_documentation/learn/set-release/electron.md b/src/collections/_documentation/learn/set-release/electron.md index 04bca6c162414..fdb638b53aec2 100644 --- a/src/collections/_documentation/learn/set-release/electron.md +++ b/src/collections/_documentation/learn/set-release/electron.md @@ -1,5 +1,5 @@ ```javascript -import * as sentry from '@sentry/electron'; +import * as Sentry from '@sentry/electron'; Sentry.init({ release: "{{ page.release_identifier }}", From 580539b9eed877996930d005f1dbaf1c647ad921 Mon Sep 17 00:00:00 2001 From: HazA Date: Wed, 5 Sep 2018 13:06:37 +0200 Subject: [PATCH 009/171] feat: Prepre new platform page --- src/_data/documentation_categories.yml | 2 +- src/_data/platform_icons.yml | 3 +++ src/_includes/platform_icon_links.html | 17 +++++++++++++++++ .../_documentation/platforms/browser/index.md | 6 ++++++ .../_documentation/platforms/index.md | 6 ++++++ src/index.md | 4 +++- 6 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 src/_data/platform_icons.yml create mode 100644 src/_includes/platform_icon_links.html create mode 100644 src/collections/_documentation/platforms/browser/index.md create mode 100644 src/collections/_documentation/platforms/index.md diff --git a/src/_data/documentation_categories.yml b/src/_data/documentation_categories.yml index f6b39ff58aaf3..a633916852b1d 100644 --- a/src/_data/documentation_categories.yml +++ b/src/_data/documentation_categories.yml @@ -7,7 +7,7 @@ slug: learn - title: Platforms - slug: clients + slug: platforms - title: Integrations slug: integrations diff --git a/src/_data/platform_icons.yml b/src/_data/platform_icons.yml new file mode 100644 index 0000000000000..57f60173e79ba --- /dev/null +++ b/src/_data/platform_icons.yml @@ -0,0 +1,3 @@ +- name: Browser + link: _documentation/platforms/browser/index.md + platformicon: javascript \ No newline at end of file diff --git a/src/_includes/platform_icon_links.html b/src/_includes/platform_icon_links.html new file mode 100644 index 0000000000000..0dbbeb54e375a --- /dev/null +++ b/src/_includes/platform_icon_links.html @@ -0,0 +1,17 @@ +
+
+ {%- for platform in site.data.platform_icons -%} + {% capture dynamic_link %}{% raw %}{% link {% endraw %}{{ platform.link }}{% raw %} %}{% endraw %}{% endcapture %} + + {%- endfor -%} +
+
diff --git a/src/collections/_documentation/platforms/browser/index.md b/src/collections/_documentation/platforms/browser/index.md new file mode 100644 index 0000000000000..f6aeb1f549078 --- /dev/null +++ b/src/collections/_documentation/platforms/browser/index.md @@ -0,0 +1,6 @@ +--- +title: Browser +sidebar_order: 2 +--- + +Browser \ No newline at end of file diff --git a/src/collections/_documentation/platforms/index.md b/src/collections/_documentation/platforms/index.md new file mode 100644 index 0000000000000..a143508727569 --- /dev/null +++ b/src/collections/_documentation/platforms/index.md @@ -0,0 +1,6 @@ +--- +title: Platforms +sidebar_order: 2 +--- + +Yeah this is the new stuff \ No newline at end of file diff --git a/src/index.md b/src/index.md index 45b40ad2248df..1d1d60828939a 100644 --- a/src/index.md +++ b/src/index.md @@ -15,7 +15,9 @@ To get you started, you might find some of these links relevant: To report to Sentry you’ll need to use a language-specific SDK. The Sentry team builds and maintains these for most popular languages, but there’s also a large ecosystem supported by the community. If your favorite language isn’t listed below, we encourage you to start a discussion about supporting it on our [community forum](https://forum.sentry.io). -{% include LEGACY_platform_icon_links.html %} +# TODO: here should be tabs like in the onboarding wizard + +{% include platform_icon_links.html %} ## Contributing From 672acfc1b4cb26eb7d0a4bc1d8e18f7b17595adc Mon Sep 17 00:00:00 2001 From: HazA Date: Wed, 5 Sep 2018 13:10:07 +0200 Subject: [PATCH 010/171] fix: Move browser to subcategory --- src/_data/platform_icons.yml | 2 +- .../platforms/{ => javascript}/browser/index.md | 0 .../_documentation/platforms/javascript/index.md | 6 ++++++ 3 files changed, 7 insertions(+), 1 deletion(-) rename src/collections/_documentation/platforms/{ => javascript}/browser/index.md (100%) create mode 100644 src/collections/_documentation/platforms/javascript/index.md diff --git a/src/_data/platform_icons.yml b/src/_data/platform_icons.yml index 57f60173e79ba..891c00ba71750 100644 --- a/src/_data/platform_icons.yml +++ b/src/_data/platform_icons.yml @@ -1,3 +1,3 @@ - name: Browser - link: _documentation/platforms/browser/index.md + link: _documentation/platforms/javascript/browser/index.md platformicon: javascript \ No newline at end of file diff --git a/src/collections/_documentation/platforms/browser/index.md b/src/collections/_documentation/platforms/javascript/browser/index.md similarity index 100% rename from src/collections/_documentation/platforms/browser/index.md rename to src/collections/_documentation/platforms/javascript/browser/index.md diff --git a/src/collections/_documentation/platforms/javascript/index.md b/src/collections/_documentation/platforms/javascript/index.md new file mode 100644 index 0000000000000..38d3347aa71be --- /dev/null +++ b/src/collections/_documentation/platforms/javascript/index.md @@ -0,0 +1,6 @@ +--- +title: JavaScript +sidebar_order: 2 +--- + +Browser \ No newline at end of file From 4567109a033c8cb4ff4c09f2cdb803d1ac6a1885 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Wed, 5 Sep 2018 13:53:06 +0200 Subject: [PATCH 011/171] doc: Add basic docs for new py sdk --- src/_data/platform_icons.yml | 14 +++++++- .../platforms/python/celery/index.md | 17 +++++++++ .../platforms/python/django/index.md | 29 +++++++++++++++ .../platforms/python/flask/index.md | 35 +++++++++++++++++++ .../_documentation/platforms/python/index.md | 12 +++++++ .../platforms/python/logging/index.md | 33 +++++++++++++++++ 6 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 src/collections/_documentation/platforms/python/celery/index.md create mode 100644 src/collections/_documentation/platforms/python/django/index.md create mode 100644 src/collections/_documentation/platforms/python/flask/index.md create mode 100644 src/collections/_documentation/platforms/python/index.md create mode 100644 src/collections/_documentation/platforms/python/logging/index.md diff --git a/src/_data/platform_icons.yml b/src/_data/platform_icons.yml index 891c00ba71750..2309bc79ed681 100644 --- a/src/_data/platform_icons.yml +++ b/src/_data/platform_icons.yml @@ -1,3 +1,15 @@ - name: Browser link: _documentation/platforms/javascript/browser/index.md - platformicon: javascript \ No newline at end of file + platformicon: javascript + +- name: Django + link: _documentation/platforms/python/django/index.md + platformicon: django + +- name: Flask + link: _documentation/platforms/python/flask/index.md + platformicon: flask + +- name: Celery + link: _documentation/platforms/python/celery/index.md + platformicon: python diff --git a/src/collections/_documentation/platforms/python/celery/index.md b/src/collections/_documentation/platforms/python/celery/index.md new file mode 100644 index 0000000000000..a615c1e7b2cab --- /dev/null +++ b/src/collections/_documentation/platforms/python/celery/index.md @@ -0,0 +1,17 @@ +--- +title: Celery +sidebar_order: 2 +--- + +Just add ``CeleryIntegration()`` to your ``integrations`` array. For example, in Django: + +```python +import sentry_sdk +from sentry_sdk.integrations.celery import CeleryIntegration +from sentry_sdk.integrations.django import DjangoIntegration + +sentry_sdk.init(dsn="https://foo@sentry.io/123", integrations=[DjangoIntegration(), CeleryIntegration()]) +``` + +With that, the transaction on the event will be set to the task name, and +exceptions will be reported to Sentry. diff --git a/src/collections/_documentation/platforms/python/django/index.md b/src/collections/_documentation/platforms/python/django/index.md new file mode 100644 index 0000000000000..8abe223ae4187 --- /dev/null +++ b/src/collections/_documentation/platforms/python/django/index.md @@ -0,0 +1,29 @@ +--- +title: Django +sidebar_order: 2 +--- + +In your ``settings.py``: + +```python +import sentry_sdk +from sentry_sdk.integrations.django import DjangoIntegration + +sentry_sdk.init(dsn="https://foo@sentry.io/123", integrations=[DjangoIntegration()]) +``` + +* All exceptions are reported. + +* A bit of data is attached to each event: + + * Personally identifiable information (such as user ids, usernames, + cookies, authorization headers, ip addresses) is excluded unless + ``send_default_pii`` is set to ``True``. + + * Request data is attached to all events. + + * If you have ``django.contrib.auth`` installed and configured, user data + (current user id, email address, username) is attached to the event. + +* Logging with any logger will create breadcrumbs. See logging docs for more + information. diff --git a/src/collections/_documentation/platforms/python/flask/index.md b/src/collections/_documentation/platforms/python/flask/index.md new file mode 100644 index 0000000000000..98ba334f04ab9 --- /dev/null +++ b/src/collections/_documentation/platforms/python/flask/index.md @@ -0,0 +1,35 @@ +--- +title: Flask +sidebar_order: 2 +--- + +```python +import sentry_sdk +from sentry_sdk.integrations.flask import FlaskIntegration + +sentry_sdk.init(dsn="https://foo@sentry.io/123", integrations=[FlaskIntegration()]) + +app = Flask(__name__) +``` + +* You can actually run that `init` anywhere. Before or after you define your + routes, before or after you register extensions. + +* The Flask integration will be installed for all of your apps. It hooks into + Flask's signals, not anything on the app object. + +* A bit of data is attached to each event: + + * Personally identifiable information (such as user ids, usernames, + cookies, authorization headers, ip addresses) is excluded unless + ``send_default_pii`` is set to ``true``. + + * Request data is attached to all events. + + * If you have Flask-Login installed and configured, user data is attached to + the event. + +* All exceptions leading to a Internal Server Error are reported. + +* Logging with `app.logger` or really *any* logger will create breadcrumbs. See + logging docs for more information. diff --git a/src/collections/_documentation/platforms/python/index.md b/src/collections/_documentation/platforms/python/index.md new file mode 100644 index 0000000000000..0b5dffae161d0 --- /dev/null +++ b/src/collections/_documentation/platforms/python/index.md @@ -0,0 +1,12 @@ +--- +title: Python +sidebar_order: 3 +--- + +Django + +Celery + +Flask + +Logging diff --git a/src/collections/_documentation/platforms/python/logging/index.md b/src/collections/_documentation/platforms/python/logging/index.md new file mode 100644 index 0000000000000..338a6ccb4903a --- /dev/null +++ b/src/collections/_documentation/platforms/python/logging/index.md @@ -0,0 +1,33 @@ +--- +title: Logging +sidebar_order: 2 +--- + +Calling ``sentry_sdk.init()`` already captures any logging message with a level +higher than or equal to ``INFO``. You can change this behavior by explicitly +passing the logging integration like any other: + +```python +import sentry_sdk +from sentry_sdk.integrations.logging import LoggingIntegration + +sentry_logging = LoggingIntegration( + level=logging.DEBUG, + event_level=logging.ERROR +) +sentry_sdk.init(dsn="https://foo@sentry.io/123", integrations=[sentry_logging]) +``` + +The above configuration captures *all* messages, now including ``DEBUG``, as +breadcrumbs. Messages with level ``ERROR`` and above will show up as their own +events as well. + +## Config + +* ``level`` (default ``INFO``): Log records with a level higher than or equal + to ``level`` will be recorded as breadcrumbs. Any log record with a level + lower than this one is completely ignored. + +* ``event_level`` (default ``None``): Log records with a level higher than or + equal to ``event_level`` will additionally be reported as event. A value of + ``None`` means that no log records will be sent as events. From e14146b2baab3270a8483daf6cde119650df3c0e Mon Sep 17 00:00:00 2001 From: HazA Date: Wed, 5 Sep 2018 14:20:58 +0200 Subject: [PATCH 012/171] feat: Introduce fallback_platform --- src/_data/platforms.yml | 6 ++++- src/_includes/head.html | 2 +- src/_js/lib/PlatformContent.js | 24 ++++++++++++++----- .../learn/breadcrumbs-example/electron.md | 9 ------- .../{browser.md => javascript.md} | 0 .../learn/breadcrumbs-example/node.md | 9 ------- .../learn/capture-error/cordova.md | 13 ---------- .../learn/capture-error/electron.md | 13 ---------- .../{browser.md => javascript.md} | 0 .../learn/capture-error/node.md | 13 ---------- .../learn/capture-message/cordova.md | 5 ---- .../learn/capture-message/electron.md | 5 ---- .../{browser.md => javascript.md} | 0 .../learn/capture-message/node.md | 5 ---- .../learn/configure-scope/electron.md | 11 --------- .../{browser.md => javascript.md} | 2 +- .../learn/configure-scope/node.md | 11 --------- .../_documentation/learn/quickstart.md | 2 +- .../learn/set-extra/javascript.md | 5 ++++ .../learn/set-fingerprint/javascript.md | 5 ++++ .../learn/set-release/browser.md | 7 ------ .../learn/set-release/cordova.md | 8 ------- .../learn/set-release/electron.md | 7 ------ .../set-release/{node.md => javascript.md} | 2 -- .../learn/set-tag/javascript.md | 5 ++++ .../learn/set-user/javascript.md | 5 ++++ .../_documentation/learn/set-user/python.md | 2 +- 27 files changed, 47 insertions(+), 129 deletions(-) delete mode 100644 src/collections/_documentation/learn/breadcrumbs-example/electron.md rename src/collections/_documentation/learn/breadcrumbs-example/{browser.md => javascript.md} (100%) delete mode 100644 src/collections/_documentation/learn/breadcrumbs-example/node.md delete mode 100644 src/collections/_documentation/learn/capture-error/cordova.md delete mode 100644 src/collections/_documentation/learn/capture-error/electron.md rename src/collections/_documentation/learn/capture-error/{browser.md => javascript.md} (100%) delete mode 100644 src/collections/_documentation/learn/capture-error/node.md delete mode 100644 src/collections/_documentation/learn/capture-message/cordova.md delete mode 100644 src/collections/_documentation/learn/capture-message/electron.md rename src/collections/_documentation/learn/capture-message/{browser.md => javascript.md} (100%) delete mode 100644 src/collections/_documentation/learn/capture-message/node.md delete mode 100644 src/collections/_documentation/learn/configure-scope/electron.md rename src/collections/_documentation/learn/configure-scope/{browser.md => javascript.md} (76%) delete mode 100644 src/collections/_documentation/learn/configure-scope/node.md create mode 100644 src/collections/_documentation/learn/set-extra/javascript.md create mode 100644 src/collections/_documentation/learn/set-fingerprint/javascript.md delete mode 100644 src/collections/_documentation/learn/set-release/browser.md delete mode 100644 src/collections/_documentation/learn/set-release/cordova.md delete mode 100644 src/collections/_documentation/learn/set-release/electron.md rename src/collections/_documentation/learn/set-release/{node.md => javascript.md} (65%) create mode 100644 src/collections/_documentation/learn/set-tag/javascript.md create mode 100644 src/collections/_documentation/learn/set-user/javascript.md diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index b212fc51be560..5b3c2358e13c3 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -13,6 +13,7 @@ doc_link: /clients/node/ wizard: ['_documentation/clients/node/index.md#installation', '_documentation/clients/node/index.md#configuring-the-client', '_documentation/clients/node/index.md#reporting-errors'] case_style: camelCase + fallback_platform: javascript - slug: express support_level: production @@ -35,6 +36,7 @@ doc_link: /clients/cordova/ wizard: ['_documentation/clients/cordova/index.md#installation', '_documentation/clients/cordova/index.md#configuration'] case_style: camelCase + fallback_platform: javascript - slug: csharp support_level: production @@ -175,10 +177,11 @@ slug: browser support_level: production type: language - name: JavaScript / Browser + name: Browser / Javascript doc_link: /clients/javascript/ wizard: [] case_style: camelCase + fallback_platform: javascript - slug: javascript support_level: production @@ -251,6 +254,7 @@ doc_link: /clients/electron/ wizard: ['_documentation/clients/electron/index.md#installation', '_documentation/clients/electron/index.md#configuring-the-client'] case_style: camelCase + fallback_platform: javascript - slug: elixir support_level: production diff --git a/src/_includes/head.html b/src/_includes/head.html index 90af8f693cd76..762b12d1005f1 100644 --- a/src/_includes/head.html +++ b/src/_includes/head.html @@ -38,7 +38,7 @@ window.loadIfTrackersOk = []; window.activePlatform = null; window.supportedPlatforms = {{ site.data.platforms | map: "slug" | jsonify }}; - window.platformData = {{ site.data.platforms | map_select: "slug,name,case_style" | make_map_by: "slug" | jsonify }}; + window.platformData = {{ site.data.platforms | map_select: "slug,name,case_style,fallback_platform" | make_map_by: "slug" | jsonify }}; {% asset screen.css %} diff --git a/src/_js/lib/PlatformContent.js b/src/_js/lib/PlatformContent.js index c3e25c4d02ac2..eac37e09e05f6 100644 --- a/src/_js/lib/PlatformContent.js +++ b/src/_js/lib/PlatformContent.js @@ -89,15 +89,27 @@ const showPlatform = function(slug) { if (!verifyPlatformSlug(slug)) return; window.activePlatform = slug; + let platform = window.platformData[window.activePlatform]; $('[data-platform-specific-content]').each((i, el) => { const $block = $(el); - const $dropdownItems = $block.find('[data-toggle="platform"]'); - const $requested = $dropdownItems.filter(`[data-platform="${slug}"]`); - const $preferred = $dropdownItems.filter( - `[data-platform="${localStorage.getItem(KEY)}"]` - ); - let $active = $requested; + let $dropdownItems; + let $requested; + let $preferred; + let $active; + const slugs = [slug, platform.fallback_platform]; + for (const index in slugs) { + $dropdownItems = $block.find('[data-toggle="platform"]'); + $requested = $dropdownItems.filter(`[data-platform="${slugs[index]}"]`); + $preferred = $dropdownItems.filter( + `[data-platform="${localStorage.getItem(KEY)}"]` + ); + $active = $requested; + if ($active.length) { + // We skip and don't use fallback platform + break; + } + } if (!$active.length) { $active = $preferred.length ? $preferred : $dropdownItems.eq(0); } diff --git a/src/collections/_documentation/learn/breadcrumbs-example/electron.md b/src/collections/_documentation/learn/breadcrumbs-example/electron.md deleted file mode 100644 index c3059c7cb478d..0000000000000 --- a/src/collections/_documentation/learn/breadcrumbs-example/electron.md +++ /dev/null @@ -1,9 +0,0 @@ -```javascript -import { addBreadcrumb } from '@sentry/electron'; - -addBreadcrumb({ - category: 'auth', - message: `Authenticated user ${user.email}`, - level: 'info', -}); -``` diff --git a/src/collections/_documentation/learn/breadcrumbs-example/browser.md b/src/collections/_documentation/learn/breadcrumbs-example/javascript.md similarity index 100% rename from src/collections/_documentation/learn/breadcrumbs-example/browser.md rename to src/collections/_documentation/learn/breadcrumbs-example/javascript.md diff --git a/src/collections/_documentation/learn/breadcrumbs-example/node.md b/src/collections/_documentation/learn/breadcrumbs-example/node.md deleted file mode 100644 index 9b6e215f79007..0000000000000 --- a/src/collections/_documentation/learn/breadcrumbs-example/node.md +++ /dev/null @@ -1,9 +0,0 @@ -```javascript -const { addBreadcrumb } = require('@sentry/node'); - -addBreadcrumb({ - category: 'auth', - message: `Authenticated user ${user.email}`, - level: 'info', -}); -``` diff --git a/src/collections/_documentation/learn/capture-error/cordova.md b/src/collections/_documentation/learn/capture-error/cordova.md deleted file mode 100644 index 5b823bb130142..0000000000000 --- a/src/collections/_documentation/learn/capture-error/cordova.md +++ /dev/null @@ -1,13 +0,0 @@ -In JavaScript you can pass an error object to `captureException()` to get it captured -as event. Note that it's possible to throw strings as errors in which case no traceback -can be recorded. - -```javascript -var Sentry = cordova.require("sentry-cordova.Sentry"); - -try { - aFunctionThatMightFail(); -} catch (err) { - Sentry.captureException(err); -} -``` diff --git a/src/collections/_documentation/learn/capture-error/electron.md b/src/collections/_documentation/learn/capture-error/electron.md deleted file mode 100644 index 8d665264f966e..0000000000000 --- a/src/collections/_documentation/learn/capture-error/electron.md +++ /dev/null @@ -1,13 +0,0 @@ -In JavaScript you can pass an error object to `captureException()` to get it captured -as event. Note that it's possible to throw strings as errors in which case no traceback -can be recorded. - -```javascript -import { captureException } from '@sentry/electron'; - -try { - aFunctionThatMightFail(); -} catch (err) { - captureException(err); -} -``` diff --git a/src/collections/_documentation/learn/capture-error/browser.md b/src/collections/_documentation/learn/capture-error/javascript.md similarity index 100% rename from src/collections/_documentation/learn/capture-error/browser.md rename to src/collections/_documentation/learn/capture-error/javascript.md diff --git a/src/collections/_documentation/learn/capture-error/node.md b/src/collections/_documentation/learn/capture-error/node.md deleted file mode 100644 index 0d5f7c6ff2bc5..0000000000000 --- a/src/collections/_documentation/learn/capture-error/node.md +++ /dev/null @@ -1,13 +0,0 @@ -In JavaScript you can pass an error object to `captureException()` to get it captured -as event. Note that it's possible to throw strings as errors in which case no traceback -can be recorded. - -```javascript -const { captureException } = require('@sentry/node'); - -try { - aFunctionThatMightFail(); -} catch (err) { - captureException(err); -} -``` diff --git a/src/collections/_documentation/learn/capture-message/cordova.md b/src/collections/_documentation/learn/capture-message/cordova.md deleted file mode 100644 index 4d2d293fd0095..0000000000000 --- a/src/collections/_documentation/learn/capture-message/cordova.md +++ /dev/null @@ -1,5 +0,0 @@ -```javascript -var Sentry = cordova.require("sentry-cordova.Sentry"); - -Sentry.captureMessage('Something weng wrong'); -``` diff --git a/src/collections/_documentation/learn/capture-message/electron.md b/src/collections/_documentation/learn/capture-message/electron.md deleted file mode 100644 index 13910d8acf36f..0000000000000 --- a/src/collections/_documentation/learn/capture-message/electron.md +++ /dev/null @@ -1,5 +0,0 @@ -```javascript -import { captureMessage } from '@sentry/electron'; - -captureMessage('Something weng wrong'); -``` diff --git a/src/collections/_documentation/learn/capture-message/browser.md b/src/collections/_documentation/learn/capture-message/javascript.md similarity index 100% rename from src/collections/_documentation/learn/capture-message/browser.md rename to src/collections/_documentation/learn/capture-message/javascript.md diff --git a/src/collections/_documentation/learn/capture-message/node.md b/src/collections/_documentation/learn/capture-message/node.md deleted file mode 100644 index 599c17136f144..0000000000000 --- a/src/collections/_documentation/learn/capture-message/node.md +++ /dev/null @@ -1,5 +0,0 @@ -```javascript -const { captureMessage } = require('@sentry/node'); - -captureMessage('Something weng wrong'); -``` diff --git a/src/collections/_documentation/learn/configure-scope/electron.md b/src/collections/_documentation/learn/configure-scope/electron.md deleted file mode 100644 index 056ae7122d707..0000000000000 --- a/src/collections/_documentation/learn/configure-scope/electron.md +++ /dev/null @@ -1,11 +0,0 @@ -```javascript -import { configureScope } from "@sentry/electron"; - -configureScope((scope) => { - scope.setTag("my-tag", "my value"); - scope.setUser({ - id: 42, - email: "john.doe@example.com" - }); -}); -``` diff --git a/src/collections/_documentation/learn/configure-scope/browser.md b/src/collections/_documentation/learn/configure-scope/javascript.md similarity index 76% rename from src/collections/_documentation/learn/configure-scope/browser.md rename to src/collections/_documentation/learn/configure-scope/javascript.md index 9c5fd26c6cb27..f758d7e81ba7e 100644 --- a/src/collections/_documentation/learn/configure-scope/browser.md +++ b/src/collections/_documentation/learn/configure-scope/javascript.md @@ -1,5 +1,5 @@ ```javascript -Sentry.configureScope(function(scope) { +Sentry.configureScope((scope) => { scope.setTag("my-tag", "my value"); scope.setUser({ id: 42, diff --git a/src/collections/_documentation/learn/configure-scope/node.md b/src/collections/_documentation/learn/configure-scope/node.md deleted file mode 100644 index 043b35b64040f..0000000000000 --- a/src/collections/_documentation/learn/configure-scope/node.md +++ /dev/null @@ -1,11 +0,0 @@ -```javascript -const { configureScope } = require("@sentry/node"); - -configureScope((scope) => { - scope.setTag("my-tag", "my value"); - scope.setUser({ - id: 42, - email: "john.doe@example.com" - }); -}); -``` diff --git a/src/collections/_documentation/learn/quickstart.md b/src/collections/_documentation/learn/quickstart.md index 81ea0cc68ea9a..74ecdf877715e 100644 --- a/src/collections/_documentation/learn/quickstart.md +++ b/src/collections/_documentation/learn/quickstart.md @@ -21,7 +21,7 @@ Sentry captures data by using a SDK within your application’s runtime. These a {% include components/platform_content.html content_dir='getting-started-install' %} {% capture __alert_content -%} -Your platform is not listed? There are more SDKs we support: [list of SDKs]({%- link _documentation/clients/index.md -%}) +Your platform is not listed? There are more SDKs we support: [list of SDKs]({%- link _documentation/platforms/index.md -%}) {%- endcapture -%} {%- include components/alert.html title="Note" diff --git a/src/collections/_documentation/learn/set-extra/javascript.md b/src/collections/_documentation/learn/set-extra/javascript.md new file mode 100644 index 0000000000000..52340a4526fc3 --- /dev/null +++ b/src/collections/_documentation/learn/set-extra/javascript.md @@ -0,0 +1,5 @@ +```javascript +Sentry.configureScope((scope) => { + scope.setExtra("{{ page.example_extra_key }}": "{{ page.example_extra_value }}"); +}); +``` diff --git a/src/collections/_documentation/learn/set-fingerprint/javascript.md b/src/collections/_documentation/learn/set-fingerprint/javascript.md new file mode 100644 index 0000000000000..fd538a4cbdded --- /dev/null +++ b/src/collections/_documentation/learn/set-fingerprint/javascript.md @@ -0,0 +1,5 @@ +```javascript +Sentry.configureScope((scope) => { + scope.setFingerprint(['my-view-function']); +}); +``` \ No newline at end of file diff --git a/src/collections/_documentation/learn/set-release/browser.md b/src/collections/_documentation/learn/set-release/browser.md deleted file mode 100644 index bf2dc7fcf9e66..0000000000000 --- a/src/collections/_documentation/learn/set-release/browser.md +++ /dev/null @@ -1,7 +0,0 @@ -```javascript -import * as Sentry from '@sentry/browser'; - -Sentry.init({ - release: "{{ page.release_identifier }}" -}) -``` diff --git a/src/collections/_documentation/learn/set-release/cordova.md b/src/collections/_documentation/learn/set-release/cordova.md deleted file mode 100644 index efd9384d23a81..0000000000000 --- a/src/collections/_documentation/learn/set-release/cordova.md +++ /dev/null @@ -1,8 +0,0 @@ -```javascript -onDeviceReady: function() { - var Sentry = cordova.require("sentry-cordova.Sentry"); - Sentry.init({ - release: "{{ page.release_identifier }}" - }); -} -``` diff --git a/src/collections/_documentation/learn/set-release/electron.md b/src/collections/_documentation/learn/set-release/electron.md deleted file mode 100644 index fdb638b53aec2..0000000000000 --- a/src/collections/_documentation/learn/set-release/electron.md +++ /dev/null @@ -1,7 +0,0 @@ -```javascript -import * as Sentry from '@sentry/electron'; - -Sentry.init({ - release: "{{ page.release_identifier }}", -}) -``` diff --git a/src/collections/_documentation/learn/set-release/node.md b/src/collections/_documentation/learn/set-release/javascript.md similarity index 65% rename from src/collections/_documentation/learn/set-release/node.md rename to src/collections/_documentation/learn/set-release/javascript.md index 856584e4e3edc..d48cec527ff5c 100644 --- a/src/collections/_documentation/learn/set-release/node.md +++ b/src/collections/_documentation/learn/set-release/javascript.md @@ -1,6 +1,4 @@ ```javascript -const Sentry = require('@sentry/node'); - Sentry.init({ release: "{{ page.release_identifier }}" }) diff --git a/src/collections/_documentation/learn/set-tag/javascript.md b/src/collections/_documentation/learn/set-tag/javascript.md new file mode 100644 index 0000000000000..b2f26d82a94e3 --- /dev/null +++ b/src/collections/_documentation/learn/set-tag/javascript.md @@ -0,0 +1,5 @@ +```javascript +Sentry.configureScope((scope) => { + scope.setTag("{{ page.example_tag_name }}", "{{ page.example_tag_value }}"); +}); +``` \ No newline at end of file diff --git a/src/collections/_documentation/learn/set-user/javascript.md b/src/collections/_documentation/learn/set-user/javascript.md new file mode 100644 index 0000000000000..505118b70b00d --- /dev/null +++ b/src/collections/_documentation/learn/set-user/javascript.md @@ -0,0 +1,5 @@ +```javascript +Sentry.configureScope((scope) => { + scope.setUser({"email": "{{ page.example_user_email }}"}); +}); +``` diff --git a/src/collections/_documentation/learn/set-user/python.md b/src/collections/_documentation/learn/set-user/python.md index 503ead5ccf661..99d996f8644fc 100644 --- a/src/collections/_documentation/learn/set-user/python.md +++ b/src/collections/_documentation/learn/set-user/python.md @@ -2,5 +2,5 @@ from sentry_sdk import configure_scope with configure_scope() as scope: - scope.set_user({"email": "{{ page.example_user_email }}") + scope.set_user({"email": "{{ page.example_user_email }}"}) ``` From aa7ad4e8062d79a648477ab0d1061b128aaeee3b Mon Sep 17 00:00:00 2001 From: HazA Date: Thu, 6 Sep 2018 10:39:32 +0200 Subject: [PATCH 013/171] feat: Write loader docs --- .vscode/settings.json | 4 ++ .../learn/getting-started-config/browser.md | 3 +- .../platforms/javascript/browser/index.md | 51 ++++++++++++++++++- .../platforms/javascript/index.md | 3 +- 4 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000000..2fe185fd9c99f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "editor.trimAutoWhitespace": false, + "files.trimTrailingWhitespace": false, +} \ No newline at end of file diff --git a/src/collections/_documentation/learn/getting-started-config/browser.md b/src/collections/_documentation/learn/getting-started-config/browser.md index 99a9ae8f3afc8..59c91cf51ffe4 100644 --- a/src/collections/_documentation/learn/getting-started-config/browser.md +++ b/src/collections/_documentation/learn/getting-started-config/browser.md @@ -1 +1,2 @@ -When using the CDN for browser, no further configuration is required. +When using the CDN for browser, no further configuration is required. +If you want to know more, please visit [What does the CDN version provide?]({% link _documentation/platforms/javascript/browser/index.md %}#what-does-the-cdn-version-provide). diff --git a/src/collections/_documentation/platforms/javascript/browser/index.md b/src/collections/_documentation/platforms/javascript/browser/index.md index f6aeb1f549078..a914d3f0c66cf 100644 --- a/src/collections/_documentation/platforms/javascript/browser/index.md +++ b/src/collections/_documentation/platforms/javascript/browser/index.md @@ -3,4 +3,53 @@ title: Browser sidebar_order: 2 --- -Browser \ No newline at end of file +We recommend using our bundled CDN version for the browser as explained [here]({% link _documentation/learn/quickstart.md %}?platform=browser#pick-a-client-integration). + +### What does the CDN version provide? + +The script you add to your website is a small wrapper around our SDK, we call it _Loader_. +The _Loader_ does a few things: + +- You will always have the newest recommend stable version of our SDK. +- It captures all _global errors_ and _unhandled promise_ rejections. +- It lazy injects our SDK into your website. +- After the SDK is loaded everything will be sent to Sentry. + +By default, the _Loader_ contains all information needed for our SDK to function, like the `DSN`. In case you want to set additional [options]({% link _documentation/learn/configuration.md %}) you have to set them like this: + + +```javascript +Sentry.onLoad(() => { + Sentry.init({ + release: '1.0.0', + environment: 'prod' + }); +}); +``` + +`onLoad` is a function the only the _Loader_ provides, it will be called once the SDK has been injected into the website. With the _Loader_ `init()` works a bit different, instead of just setting the options, we merge the options internally, only for convenience so you don't have to set the `DSN` again since the _Loader_ already contains it. + +As explained before, the _Loader_ lazy loads and injects our SDK into your website but you can also tell the loader to fetch it immediately instead of only fetching it when you need it. Setting `data-lazy` to `no` will tell the _Loader_ to inject the SDK as soon as possible: + +```html + +``` + +The _Loader_ also provides a function called `forceLoad()` which does the same, so you can do the following: + +```html +{% raw %}{% if sentry_event_id %} + +{% endif %}{% endraw %} +``` \ No newline at end of file diff --git a/src/collections/_documentation/platforms/javascript/index.md b/src/collections/_documentation/platforms/javascript/index.md index 38d3347aa71be..69acfaf0ccfba 100644 --- a/src/collections/_documentation/platforms/javascript/index.md +++ b/src/collections/_documentation/platforms/javascript/index.md @@ -3,4 +3,5 @@ title: JavaScript sidebar_order: 2 --- -Browser \ No newline at end of file +All our JavaScript related SDKs provide the same API still there are some differences between them +which this section of the docs explains. From bb1434cbecf5117c9259a9641d76d6d0b90903a7 Mon Sep 17 00:00:00 2001 From: HazA Date: Thu, 6 Sep 2018 14:40:48 +0200 Subject: [PATCH 014/171] feat: Loader and Vue docs --- .../learn/getting-started-config/browser.md | 2 +- .../javascript/{browser/index.md => browser.md} | 0 .../_documentation/platforms/javascript/ember.md | 4 ++++ .../_documentation/platforms/javascript/index.md | 2 +- .../_documentation/platforms/javascript/vue.md | 15 +++++++++++++++ 5 files changed, 21 insertions(+), 2 deletions(-) rename src/collections/_documentation/platforms/javascript/{browser/index.md => browser.md} (100%) create mode 100644 src/collections/_documentation/platforms/javascript/ember.md create mode 100644 src/collections/_documentation/platforms/javascript/vue.md diff --git a/src/collections/_documentation/learn/getting-started-config/browser.md b/src/collections/_documentation/learn/getting-started-config/browser.md index 59c91cf51ffe4..a70e09123c803 100644 --- a/src/collections/_documentation/learn/getting-started-config/browser.md +++ b/src/collections/_documentation/learn/getting-started-config/browser.md @@ -1,2 +1,2 @@ When using the CDN for browser, no further configuration is required. -If you want to know more, please visit [What does the CDN version provide?]({% link _documentation/platforms/javascript/browser/index.md %}#what-does-the-cdn-version-provide). +If you want to know more, please visit [What does the CDN version provide?]({% link _documentation/platforms/javascript/browser.md %}#what-does-the-cdn-version-provide). diff --git a/src/collections/_documentation/platforms/javascript/browser/index.md b/src/collections/_documentation/platforms/javascript/browser.md similarity index 100% rename from src/collections/_documentation/platforms/javascript/browser/index.md rename to src/collections/_documentation/platforms/javascript/browser.md diff --git a/src/collections/_documentation/platforms/javascript/ember.md b/src/collections/_documentation/platforms/javascript/ember.md new file mode 100644 index 0000000000000..2fe37e6e54534 --- /dev/null +++ b/src/collections/_documentation/platforms/javascript/ember.md @@ -0,0 +1,4 @@ +--- +title: Ember +sidebar_order: 40 +--- diff --git a/src/collections/_documentation/platforms/javascript/index.md b/src/collections/_documentation/platforms/javascript/index.md index 69acfaf0ccfba..9ad0503d3e079 100644 --- a/src/collections/_documentation/platforms/javascript/index.md +++ b/src/collections/_documentation/platforms/javascript/index.md @@ -1,6 +1,6 @@ --- title: JavaScript -sidebar_order: 2 +sidebar_order: 20 --- All our JavaScript related SDKs provide the same API still there are some differences between them diff --git a/src/collections/_documentation/platforms/javascript/vue.md b/src/collections/_documentation/platforms/javascript/vue.md new file mode 100644 index 0000000000000..c3a32c0e3def9 --- /dev/null +++ b/src/collections/_documentation/platforms/javascript/vue.md @@ -0,0 +1,15 @@ +--- +title: Vue +sidebar_order: 30 +--- + +```javascript +import * as Sentry from '@sentry/browser' +Sentry.init({ + dsn: '___PUBLIC_DSN___', + integrations: (integrations) => { + integrations.push(new Sentry.Integrations.Vue({ Vue })) + return integrations + } +}) +``` \ No newline at end of file From 02fea65aefe4802e76b4d4517a8866ec7dd42308 Mon Sep 17 00:00:00 2001 From: HazA Date: Thu, 6 Sep 2018 14:51:40 +0200 Subject: [PATCH 015/171] nit: Remove arrow function --- src/collections/_documentation/platforms/javascript/vue.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/collections/_documentation/platforms/javascript/vue.md b/src/collections/_documentation/platforms/javascript/vue.md index c3a32c0e3def9..1064b3a2ddc25 100644 --- a/src/collections/_documentation/platforms/javascript/vue.md +++ b/src/collections/_documentation/platforms/javascript/vue.md @@ -7,7 +7,7 @@ sidebar_order: 30 import * as Sentry from '@sentry/browser' Sentry.init({ dsn: '___PUBLIC_DSN___', - integrations: (integrations) => { + integrations (integrations) { integrations.push(new Sentry.Integrations.Vue({ Vue })) return integrations } From d6dbb0d6a9f18ecd3a15611b98831851262560d7 Mon Sep 17 00:00:00 2001 From: HazA Date: Thu, 6 Sep 2018 15:18:59 +0200 Subject: [PATCH 016/171] fix: Platform icons --- src/_data/platform_icons.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/_data/platform_icons.yml b/src/_data/platform_icons.yml index 2309bc79ed681..caefb39465c41 100644 --- a/src/_data/platform_icons.yml +++ b/src/_data/platform_icons.yml @@ -1,5 +1,9 @@ - name: Browser - link: _documentation/platforms/javascript/browser/index.md + link: _documentation/platforms/javascript/browser.md + platformicon: javascript + +- name: Vue + link: _documentation/platforms/javascript/vue.md platformicon: javascript - name: Django From efd96ba0a76ea92a8a8a2eac48c98443b81faf6c Mon Sep 17 00:00:00 2001 From: HazA Date: Fri, 7 Sep 2018 08:58:26 +0200 Subject: [PATCH 017/171] feat: Add integration docs --- .../platforms/javascript/index.md | 53 +++++++++++++++++++ .../platforms/javascript/vue.md | 1 + 2 files changed, 54 insertions(+) diff --git a/src/collections/_documentation/platforms/javascript/index.md b/src/collections/_documentation/platforms/javascript/index.md index 9ad0503d3e079..835ff8dc45522 100644 --- a/src/collections/_documentation/platforms/javascript/index.md +++ b/src/collections/_documentation/platforms/javascript/index.md @@ -5,3 +5,56 @@ sidebar_order: 20 All our JavaScript related SDKs provide the same API still there are some differences between them which this section of the docs explains. + +## Integrations + +All of our SDKs provide _Integrations_ which can be seen of some kind of plugins. All JavaScript SDKs provide default _Integrations_ please check details of a specific SDK to see which _Integrations_ they provides. + +One thing is the same across all our JavaScript SDKs and that's how you add or remove _Integrations_, e.g.: for `@sentry/browser`. + +### Adding a Integration + +```javascript +import * as Sentry from '@sentry/browser'; + +// All integration that come with an SDK can be found in +// Sentry.Integrations +// Custom integration must conform this interface: +// https://github.com/getsentry/sentry-javascript/blob/1ebeb9edec4b6c7b07a61e0caac426a66eedaf2a/packages/types/src/index.ts#L205 + +Sentry.init({ + dsn: '___PUBLIC_DSN___', + integrations: (integrations) => { + integrations.push(new MyCustomIntegration()) + return integrations + } +}) +``` + +### Removing a default Integration + +In this example we will remove the by default enabled integration for adding breadcrumbs to the event: + +```javascript +import * as Sentry from '@sentry/browser'; + +Sentry.init({ + dsn: '___PUBLIC_DSN___', + integrations: (integrations) => { + return integrations.filter(integration => integration.name !== 'Breadcrumbs'); + } +}) +``` + +### Alternative way of setting an Integration + +You can also set an array of wanted _Integrations_: +```javascript +import * as Sentry from '@sentry/browser'; + +Sentry.init({ + dsn: '___PUBLIC_DSN___', + integrations: [new MyCustomIntegration()], + // integrations: [...Sentry.defaultIntegrations, new MyCustomIntegration()], +}) +``` \ No newline at end of file diff --git a/src/collections/_documentation/platforms/javascript/vue.md b/src/collections/_documentation/platforms/javascript/vue.md index 1064b3a2ddc25..cf8622e2a596f 100644 --- a/src/collections/_documentation/platforms/javascript/vue.md +++ b/src/collections/_documentation/platforms/javascript/vue.md @@ -5,6 +5,7 @@ sidebar_order: 30 ```javascript import * as Sentry from '@sentry/browser' + Sentry.init({ dsn: '___PUBLIC_DSN___', integrations (integrations) { From d09cd43548b9e06829dc49a2088182cee7ceb1bd Mon Sep 17 00:00:00 2001 From: HazA Date: Fri, 7 Sep 2018 09:23:07 +0200 Subject: [PATCH 018/171] feat: Add hint explaination --- .../platforms/javascript/index.md | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/src/collections/_documentation/platforms/javascript/index.md b/src/collections/_documentation/platforms/javascript/index.md index 835ff8dc45522..156d94e5d116b 100644 --- a/src/collections/_documentation/platforms/javascript/index.md +++ b/src/collections/_documentation/platforms/javascript/index.md @@ -12,7 +12,7 @@ All of our SDKs provide _Integrations_ which can be seen of some kind of plugins One thing is the same across all our JavaScript SDKs and that's how you add or remove _Integrations_, e.g.: for `@sentry/browser`. -### Adding a Integration +### Adding an Integration ```javascript import * as Sentry from '@sentry/browser'; @@ -57,4 +57,58 @@ Sentry.init({ integrations: [new MyCustomIntegration()], // integrations: [...Sentry.defaultIntegrations, new MyCustomIntegration()], }) +``` + +### Hints + +Event and Breadcrumb `hints` are objects containing various information used to put together an event or a breadcrumb. For events, those are things like `event_id`, `originalException`, `syntheticException` (used internally to generate cleaner stacktrace), and any other arbitrary `data` that user attaches. For breadcrumbs it's all implementation dependent. For XHR requests, hint contains xhr object itself, for user interactions it contains DOM element and event name etc. + +They are available in two places. `beforeSend`/`beforeBreadcrumb` and `eventProcessors`. Those are two ways we'll allow users to modify what we put together. + +Examples based on your `cause` property (I use `message` for ease of reading, but there's nothing stopping you from modifying event stacktrace frames). + +`beforeSend`/`beforeBreadcrumb`: + +```javascript +import * as Sentry from '@sentry/browser'; + +init({ + dsn: '___PUBLIC_DSN___', + beforeSend(event, hint) { + const processedEvent = { ...event }; + const cause = hint.originalException.cause; + + if (cause) { + processedEvent.message = cause.message; + } + + return processedEvent; + }, + beforeBreadcrumb(breadcrumb, hint) { + if (breadcrumb.category === 'ui.click') { + const target = hint.event.target; + if (target.ariaLabel) breadcrumb.message = target.ariaLabel; + } + return breadcrumb; + }, +}); +``` + +`eventProcessor` (this will be not used that often, but is great for writing custom plugins or share them across multiple projects - in form of an integration, more on this soon): + +```js +import * as Sentry from '@sentry/browser'; + +Sentry.getCurrentHub().configureScope(scope => { + scope.addEventProcessor(async (event, hint) => { + const processedEvent = { ...event }; + const cause = hint.originalException.cause; + + if (cause) { + processedEvent.message = cause.message; + } + + return processedEvent; + }); +}); ``` \ No newline at end of file From f0f46229e465f77f686ecf07041d37c09d3e9e7f Mon Sep 17 00:00:00 2001 From: HazA Date: Fri, 7 Sep 2018 10:00:40 +0200 Subject: [PATCH 019/171] fix: Remove text --- src/collections/_documentation/platforms/javascript/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/collections/_documentation/platforms/javascript/index.md b/src/collections/_documentation/platforms/javascript/index.md index 156d94e5d116b..a0f79a7c1cc95 100644 --- a/src/collections/_documentation/platforms/javascript/index.md +++ b/src/collections/_documentation/platforms/javascript/index.md @@ -94,9 +94,9 @@ init({ }); ``` -`eventProcessor` (this will be not used that often, but is great for writing custom plugins or share them across multiple projects - in form of an integration, more on this soon): +`eventProcessor`: -```js +```javascript import * as Sentry from '@sentry/browser'; Sentry.getCurrentHub().configureScope(scope => { From 756d97942b7203dc39813d9b9a1994b4ed886991 Mon Sep 17 00:00:00 2001 From: HazA Date: Fri, 7 Sep 2018 10:02:38 +0200 Subject: [PATCH 020/171] fix: react-native docs --- .../_documentation/clients/react-native/codepush.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/collections/_documentation/clients/react-native/codepush.md b/src/collections/_documentation/clients/react-native/codepush.md index 7c35980fa4265..6ee9391e2e9f6 100644 --- a/src/collections/_documentation/clients/react-native/codepush.md +++ b/src/collections/_documentation/clients/react-native/codepush.md @@ -19,9 +19,9 @@ Put this somewhere in your code where you already use CodePush. This makes sure After updating your CodePush release you have to upload the new assets to Sentry: ```bash -$ appcenter codepush release-react YourApp ios --outputDir build +$ appcenter codepush release-react YourApp --output-dir ./build $ export SENTRY_PROPERTIES=./ios/sentry.properties -$ sentry-cli react-native codepush YourApp ios ./build +$ sentry-cli react-native appcenter YourApp ios ./build/codePush ``` {% capture __alert_content -%} From 51c85978203bcb23e3402eb74d9c3c56302a8850 Mon Sep 17 00:00:00 2001 From: Bruno Garcia Date: Fri, 7 Sep 2018 16:36:01 +0200 Subject: [PATCH 021/171] feat: csharp 'learn' samples --- .../_documentation/learn/before-send/csharp.md | 15 +++++++++++++++ .../learn/breadcrumbs-example/csharp.md | 8 ++++++++ .../learn/capture-error/csharp.md | 9 ++++++--- .../_documentation/learn/config-intro/csharp.md | 4 ++-- .../learn/configure-scope/csharp.md | 17 ++++++++++++++--- .../learn/set-environment/csharp.md | 5 +++++ .../_documentation/learn/set-extra/csharp.md | 8 ++++++++ .../learn/set-fingerprint/csharp.md | 8 ++++++++ .../_documentation/learn/set-release/csharp.md | 5 +++++ .../_documentation/learn/set-tag/csharp.md | 8 ++++++++ .../_documentation/learn/set-user/csharp.md | 11 +++++++++++ 11 files changed, 90 insertions(+), 8 deletions(-) create mode 100644 src/collections/_documentation/learn/before-send/csharp.md create mode 100644 src/collections/_documentation/learn/breadcrumbs-example/csharp.md create mode 100644 src/collections/_documentation/learn/set-environment/csharp.md create mode 100644 src/collections/_documentation/learn/set-extra/csharp.md create mode 100644 src/collections/_documentation/learn/set-fingerprint/csharp.md create mode 100644 src/collections/_documentation/learn/set-release/csharp.md create mode 100644 src/collections/_documentation/learn/set-tag/csharp.md create mode 100644 src/collections/_documentation/learn/set-user/csharp.md diff --git a/src/collections/_documentation/learn/before-send/csharp.md b/src/collections/_documentation/learn/before-send/csharp.md new file mode 100644 index 0000000000000..235d0a299a9e4 --- /dev/null +++ b/src/collections/_documentation/learn/before-send/csharp.md @@ -0,0 +1,15 @@ +A `Func` can be used to mutate, discard (return null), or return a completely new event. + +```csharp +using Sentry; + +SentrySdk.Init(o => +{ + o.BeforeSend = sentryEvent => + { + // Modify the event here: + sentryEvent.ServerName = null; // Don't send server names. + return sentryEvent; + }; +}); +``` diff --git a/src/collections/_documentation/learn/breadcrumbs-example/csharp.md b/src/collections/_documentation/learn/breadcrumbs-example/csharp.md new file mode 100644 index 0000000000000..ebef6d9a36d63 --- /dev/null +++ b/src/collections/_documentation/learn/breadcrumbs-example/csharp.md @@ -0,0 +1,8 @@ +```csharp +using Sentry; + +SentrySdk.AddBreadcrumb( + message: "Authenticated user " + user.email, + category: "auth", + level: BreadcrumbLevel.Info); +``` diff --git a/src/collections/_documentation/learn/capture-error/csharp.md b/src/collections/_documentation/learn/capture-error/csharp.md index 5e8fe09d0446a..0202efaa572bf 100644 --- a/src/collections/_documentation/learn/capture-error/csharp.md +++ b/src/collections/_documentation/learn/capture-error/csharp.md @@ -1,11 +1,14 @@ -In .NET you can capture any exception object that you caught: +In C# you can capture any exception object that you caught: ```csharp using Sentry; -try { +try +{ AFunctionThatMightFail(); -} catch (Exception err) { +} +catch (Exception err) +{ SentrySdk.CaptureException(err); } ``` diff --git a/src/collections/_documentation/learn/config-intro/csharp.md b/src/collections/_documentation/learn/config-intro/csharp.md index 40bd1e120991c..46b3a6a703e58 100644 --- a/src/collections/_documentation/learn/config-intro/csharp.md +++ b/src/collections/_documentation/learn/config-intro/csharp.md @@ -1,7 +1,7 @@ -Options can be set by passing a callback to the `Init()` function which will +Options can be set by passing a callback to the `Init()` method which will pass the option object along for modifications: -```javascript +```csharp using Sentry; using (SentrySdk.Init(o => diff --git a/src/collections/_documentation/learn/configure-scope/csharp.md b/src/collections/_documentation/learn/configure-scope/csharp.md index 8d889e019ed87..8b534eea79439 100644 --- a/src/collections/_documentation/learn/configure-scope/csharp.md +++ b/src/collections/_documentation/learn/configure-scope/csharp.md @@ -1,11 +1,22 @@ -```javascript +```csharp using Sentry; -SentrySdk.ConfigureScope(scope => { +SentrySdk.ConfigureScope(scope => +{ scope.SetTag("my-tag", "my value"); - scope.User = new User { + scope.User = new User + { Id = "42", Email = "john.doe@example.com" }; }); ``` + +Or when an asynchronous call is required: + +```csharp +await SentrySdk.ConfigureScopeAsync(scope => +{ + scope.User = await _context.Users.FindAsync(id); +}); +``` \ No newline at end of file diff --git a/src/collections/_documentation/learn/set-environment/csharp.md b/src/collections/_documentation/learn/set-environment/csharp.md new file mode 100644 index 0000000000000..ed280f25eb80a --- /dev/null +++ b/src/collections/_documentation/learn/set-environment/csharp.md @@ -0,0 +1,5 @@ +```csharp +using Sentry; + +SentrySdk.Init(o => o.Environment = "{{ page.example_environment }}"); +``` diff --git a/src/collections/_documentation/learn/set-extra/csharp.md b/src/collections/_documentation/learn/set-extra/csharp.md new file mode 100644 index 0000000000000..99b60d0af9a63 --- /dev/null +++ b/src/collections/_documentation/learn/set-extra/csharp.md @@ -0,0 +1,8 @@ +```csharp +using Sentry; + +SentrySdk.ConfigureScope(scope => +{ + scope.SetExtra("{{ page.example_extra_key }}", "{{ page.example_extra_value }}"); +}); +``` diff --git a/src/collections/_documentation/learn/set-fingerprint/csharp.md b/src/collections/_documentation/learn/set-fingerprint/csharp.md new file mode 100644 index 0000000000000..4a238780fd321 --- /dev/null +++ b/src/collections/_documentation/learn/set-fingerprint/csharp.md @@ -0,0 +1,8 @@ +```csharp +using Sentry; + +SentrySdk.ConfigureScope(scope => +{ + scope.SetFingerprint(new[] { "my-view-function" }); +}); +``` diff --git a/src/collections/_documentation/learn/set-release/csharp.md b/src/collections/_documentation/learn/set-release/csharp.md new file mode 100644 index 0000000000000..bf3751d3573f6 --- /dev/null +++ b/src/collections/_documentation/learn/set-release/csharp.md @@ -0,0 +1,5 @@ +```csharp +using Sentry; + +SentrySdk.Init(o => o.Release = "{{ page.release_identifier }}"); +``` diff --git a/src/collections/_documentation/learn/set-tag/csharp.md b/src/collections/_documentation/learn/set-tag/csharp.md new file mode 100644 index 0000000000000..658b3e0baa6e2 --- /dev/null +++ b/src/collections/_documentation/learn/set-tag/csharp.md @@ -0,0 +1,8 @@ +```csharp +using Sentry; + +SentrySdk.ConfigureScope(scope => +{ + scope.SetTag("{{ page.example_tag_name }}", "{{ page.example_tag_value }}"); +}); +``` diff --git a/src/collections/_documentation/learn/set-user/csharp.md b/src/collections/_documentation/learn/set-user/csharp.md new file mode 100644 index 0000000000000..c4ad60bcc4546 --- /dev/null +++ b/src/collections/_documentation/learn/set-user/csharp.md @@ -0,0 +1,11 @@ +```csharp +using Sentry; + +SentrySdk.ConfigureScope(scope => +{ + scope.User = new User + { + Email = "john.doe@example.com" + }; +}); +``` From 229419bcbb7d4c2f8397ecdfc19fb64d6b866d53 Mon Sep 17 00:00:00 2001 From: Bruno Garcia Date: Fri, 7 Sep 2018 16:52:32 +0200 Subject: [PATCH 022/171] fix: typos --- src/collections/_documentation/learn/breadcrumbs.md | 2 +- src/collections/_documentation/learn/scopes.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/collections/_documentation/learn/breadcrumbs.md b/src/collections/_documentation/learn/breadcrumbs.md index 1fe00c9fa4cc4..cf99d6b6b11fb 100644 --- a/src/collections/_documentation/learn/breadcrumbs.md +++ b/src/collections/_documentation/learn/breadcrumbs.md @@ -57,4 +57,4 @@ to record a breadcrumb if the user authenticates or another state change happens ## Automatic Breadcrumbs SDKs will automatically start recording breadcrumbs by enabling integrations. For instance -the browser JavaScript SDK will automatically record all lcoation changes. +the browser JavaScript SDK will automatically record all location changes. diff --git a/src/collections/_documentation/learn/scopes.md b/src/collections/_documentation/learn/scopes.md index a1790f3e9af58..a3807cc448f16 100644 --- a/src/collections/_documentation/learn/scopes.md +++ b/src/collections/_documentation/learn/scopes.md @@ -40,9 +40,9 @@ nitty gritty details. On platforms such as .NET or on Python 3.7 and later we w use "ambient data" to have either the hub flow with your code or the hub is already a singleton that internally manages the scope. -Effectively this means that when you spawn a task in .NET and the execution flow is +Effectively this means that when you spawn a task in .NET and the execution flow is not supressed all the context you have bound to the scope in Sentry will flow along. -If however you surpress the flow you get new scope data. +If however you suppress the flow, you get new scope data. {% endcapture %} {%- include components/alert.html title="Note" From 203a0ecc85e984cba71024455572015dfc61e2f4 Mon Sep 17 00:00:00 2001 From: Bruno Garcia Date: Fri, 7 Sep 2018 18:25:43 +0200 Subject: [PATCH 023/171] doc: doc log4net --- .../_documentation/platforms/dotnet/index.md | 9 +++ .../platforms/dotnet/log4net.md | 56 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 src/collections/_documentation/platforms/dotnet/index.md create mode 100644 src/collections/_documentation/platforms/dotnet/log4net.md diff --git a/src/collections/_documentation/platforms/dotnet/index.md b/src/collections/_documentation/platforms/dotnet/index.md new file mode 100644 index 0000000000000..7f6a72687bf2f --- /dev/null +++ b/src/collections/_documentation/platforms/dotnet/index.md @@ -0,0 +1,9 @@ +--- +title: .NET +sidebar_order: 10 +--- + +ASP.NET Core +Microsoft.Extensions.Logging +log4net +Entity Framework 6 diff --git a/src/collections/_documentation/platforms/dotnet/log4net.md b/src/collections/_documentation/platforms/dotnet/log4net.md new file mode 100644 index 0000000000000..56827929831d8 --- /dev/null +++ b/src/collections/_documentation/platforms/dotnet/log4net.md @@ -0,0 +1,56 @@ +--- +title: log4net +sidebar_order: 10 +--- + +## Installing the integration in your app + +Using package manager: + +```powershell +Install-Package Sentry.Log4Net +``` + +Or using the .NET Core CLI: + +```sh +dotnet add Sentry.Log4Net +``` + +## Configuration + +Once the log4net integration package is installed in your project, you can modify your configuration file to add the appender. +This can be done, for example, via the `app.config` or `web.config` in case of ASP.NET. + +```xml + + + + + + +``` + +For how it's done in this sample, please refer to [sample app.config](https://github.com/getsentry/sentry-dotnet/blob/master/samples/Sentry.Samples.Log4Net/app.config). + +The example above defines the [DSN](https://docs.sentry.io/quickstart/#configure-the-dsn) so that the `SentryAppender` is able to initialize the SDK. + +This is only one of the options. If you wish to configure the SDK manually in the app before creating the logging integration, you could **leave the DSN out** of the log4net configuration file and call: + +```csharp +using Sentry; + +using (SentrySdk.Init("___PUBLIC_KEY___")) +{ + // App code +} +``` + +One of the advantages of this approach is that you can pass multiple configurations via the `Init` method. + +Bottom line is that the SDK needs to be initialized only **once** so you can choose where the initialization will happen. Other integrations (like ASP.NET) is also able to initialize the SDK. +Make sure you pass the DSN to only one of these integrations, or if you are calling `Init` by yourself, there's no need to pass the DSN to the integration. + +Please refer to [the sample](https://github.com/getsentry/sentry-dotnet/tree/master/samples/Sentry.Samples.Log4Net) to see it in action. + +![Sample event in Sentry](https://github.com/getsentry/sentry-dotnet/blob/master/samples/Sentry.Samples.Log4Net/.assets/log4net-sample.gif?raw=true) From 611593a980f925479002a6307acca108483490d7 Mon Sep 17 00:00:00 2001 From: Bruno Garcia Date: Sat, 8 Sep 2018 17:49:53 +0200 Subject: [PATCH 024/171] ref: improved log4net doc --- .../platforms/dotnet/log4net.md | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/collections/_documentation/platforms/dotnet/log4net.md b/src/collections/_documentation/platforms/dotnet/log4net.md index 56827929831d8..275c5d1ce262b 100644 --- a/src/collections/_documentation/platforms/dotnet/log4net.md +++ b/src/collections/_documentation/platforms/dotnet/log4net.md @@ -3,7 +3,13 @@ title: log4net sidebar_order: 10 --- -## Installing the integration in your app +Sentry has an integration with log4net through the `Sentry.Log4Net` NuGet package. + +Without any code change, this package is able to initialize the Sentry SDK and capture events while including additional properties like `Exception` data and more. + +This package extends `Sentry` main SDK. That means besides the log4net `Appender`, through this package you'll also get access to all API and features available in the main `Sentry` SDK. + +## Installation Using package manager: @@ -20,7 +26,7 @@ dotnet add Sentry.Log4Net ## Configuration Once the log4net integration package is installed in your project, you can modify your configuration file to add the appender. -This can be done, for example, via the `app.config` or `web.config` in case of ASP.NET. +This can be done, for example, via the `app.config` for console and desktop apps or `web.config` in case of ASP.NET. ```xml @@ -31,26 +37,20 @@ This can be done, for example, via the `app.config` or `web.config` in case of A ``` -For how it's done in this sample, please refer to [sample app.config](https://github.com/getsentry/sentry-dotnet/blob/master/samples/Sentry.Samples.Log4Net/app.config). +#### SendIdentity -The example above defines the [DSN](https://docs.sentry.io/quickstart/#configure-the-dsn) so that the `SentryAppender` is able to initialize the SDK. +In the example above, the `SendIdentity` flag was switched on. The SDK then will take the log4net `Identity` value and report to Sentry as the user's id. -This is only one of the options. If you wish to configure the SDK manually in the app before creating the logging integration, you could **leave the DSN out** of the log4net configuration file and call: +#### Dsn -```csharp -using Sentry; +Also in the example above, you can find the [DSN](https://docs.sentry.io/quickstart/#configure-the-dsn) being set. That will instruct the `SentryAppender` to initialize the SDK. -using (SentrySdk.Init("___PUBLIC_KEY___")) -{ - // App code -} -``` +> NOTE: +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 of the advantages of this approach is that you can pass multiple configurations via the `Init` method. -Bottom line is that the SDK needs to be initialized only **once** so you can choose where the initialization will happen. Other integrations (like ASP.NET) is also able to initialize the SDK. -Make sure you pass the DSN to only one of these integrations, or if you are calling `Init` by yourself, there's no need to pass the DSN to the integration. +### Sample -Please refer to [the sample](https://github.com/getsentry/sentry-dotnet/tree/master/samples/Sentry.Samples.Log4Net) to see it in action. +For a [sample app.config](https://github.com/getsentry/sentry-dotnet/blob/master/samples/Sentry.Samples.Log4Net/app.config) or a complete working [sample](https://github.com/getsentry/sentry-dotnet/tree/master/samples/Sentry.Samples.Log4Net) to see it in action. ![Sample event in Sentry](https://github.com/getsentry/sentry-dotnet/blob/master/samples/Sentry.Samples.Log4Net/.assets/log4net-sample.gif?raw=true) From 3f6a80fce80baf2c85522a276631e285bc4f8846 Mon Sep 17 00:00:00 2001 From: Bruno Garcia Date: Sat, 8 Sep 2018 18:16:57 +0200 Subject: [PATCH 025/171] feat: integration EntityFramework --- .../platforms/dotnet/entityframework.md | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/collections/_documentation/platforms/dotnet/entityframework.md diff --git a/src/collections/_documentation/platforms/dotnet/entityframework.md b/src/collections/_documentation/platforms/dotnet/entityframework.md new file mode 100644 index 0000000000000..de90fc9f2c7c0 --- /dev/null +++ b/src/collections/_documentation/platforms/dotnet/entityframework.md @@ -0,0 +1,81 @@ +--- +title: EntityFramework +sidebar_order: 8 +--- + +Sentry has an integration with `EntityFramework` through the of the `Sentry.EntityFramework` NuGet package. + +> Looking for `EntityFramework Core`? That integration is achieved through the `Microsoft.Extensions.Logging` package. + +## Features + +* Queries as breadcrumbs +* Validation errors + +All queries executed are added as breadcrumbs and are sent with any event which happens on the same `Scope`. Besides that, validation errors are also included as `Extra`. + +This package extends `Sentry` main SDK. That means that besides the EF features, through this package you'll also get access to all API and features available in the main `Sentry` SDK. + +## Installation + +Using package manager: + +```powershell +Install-Package Sentry.EntityFramework +``` + +Or using the .NET Core CLI: + +```sh +dotnet add Sentry.EntityFramework +``` + +## Configuration + +There are 2 steps to adding Entity Framework 6 support to your project: + +* Call `SentryDatabaseLogging.UseBreadcrumbs()` to either your application's startup method, or into a static constructor inside your Entity Framework object. Make sure you only call this method once! This will add the interceptor to Entity Framework to log database queries. +* When initializing the SDK, call the extension method `AddEntityFramework()` on `SentryOptions`. This will register all error processors to extract extra data, such as validation errors, from the exceptions thrown by Entity Framework. + +### Example configuration + +For example, configuring an ASP.NET app with _global.asax_: + +```csharp +public class MvcApplication : System.Web.HttpApplication +{ + private IDisposable _sentrySdk; + + protected void Application_Start() + { + // We add the query logging here so multiple DbContexts in the same project are supported + SentryDatabaseLogging.UseBreadcrumbs(); + _sentrySdk = SentrySdk.Init(o => + { + // We store the DSN inside Web.config + o.Dsn = new Dsn(ConfigurationManager.AppSettings["SentryDsn"]); + // Add the EntityFramework integration + o.AddEntityFramework(); + }); + } + + // Global error catcher + protected void Application_Error() + { + var exception = Server.GetLastError(); + SentrySdk.CaptureException(exception); + } + + public override void Dispose() + { + _sentrySdk.Dispose(); + base.Dispose(); + } +} +``` + +### Sample + +Check out a complete working [sample](https://github.com/getsentry/sentry-dotnet-ef/tree/master/samples/Sentry.Samples.AspNet.Mvc) to see it in action. + +![Sample breadcrumbs in Sentry](https://github.com/getsentry/sentry-dotnet-ef/blob/master/.assets/ef.PNG?raw=true) From 5a64c58a1880836e8d383e3411d6b3fe10d1b8e4 Mon Sep 17 00:00:00 2001 From: Bruno Garcia Date: Sat, 8 Sep 2018 19:36:01 +0200 Subject: [PATCH 026/171] feat: doc MEL --- .../dotnet/microsoft-extensions-logging.md | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 src/collections/_documentation/platforms/dotnet/microsoft-extensions-logging.md diff --git a/src/collections/_documentation/platforms/dotnet/microsoft-extensions-logging.md b/src/collections/_documentation/platforms/dotnet/microsoft-extensions-logging.md new file mode 100644 index 0000000000000..57abdda727e21 --- /dev/null +++ b/src/collections/_documentation/platforms/dotnet/microsoft-extensions-logging.md @@ -0,0 +1,149 @@ +--- +title: Microsoft.Extensions.Logging +sidebar_order: 12 +--- + +Sentry has an integration with `Microsoft.Extensions.Logging` through the of the `Sentry.Extensions.Logging` NuGet package. + +## Installation + +Using package manager: + +```powershell +Install-Package Sentry.Extensions.Logging +``` + +Or using the .NET Core CLI: + +```sh +dotnet add Sentry.Extensions.Logging +``` + +This package extends `Sentry` main SDK. That means that besides the logging related features, through this package you'll also get access to all API and features available in the main `Sentry` SDK. + +## Features + +* Store log messages as breadcrumbs +* Send events to sentry + +Two separate settings define the minimum log level to keep the log entry as a `Breadcrumb` and to send an `Event` to Sentry. The events include any stored breadcrumb on that `Scope`. + +By default, any message with log level `Information` or higher will be kept as a `Breadcrumb`. + +The default value to report a log entry as an event to Sentry is `Error`. + +This means that out of the box, any `LogError` call will create an `Event` which will include all log messages of level `Information`, `Warning` and also `Error` and `Critical`. + + +## Configuration + +There are two ways to add this integration into your project. In both cases it means calling an extension method. The places where it's available are: + +* `ILoggingBuilder` +* `ILoggerFactory` + +The `ILoggingBuilder` extension is useful when using a `WebHostBuilder` or a `HostBuilder`, also known as _Generic host_. This extension method is used by the ASP.NET Core integration under the hood to automatically. + +The extension to `ILoggerFactory` is a convenient way when only the `LoggerFactory` is being used, without any framework integration. + +In both cases the method call is: + +**AddSentry()** + +### Example configuration + +#### Through `ILoggingBuilder` + +```csharp +public static Task Main() + => new HostBuilder() + .ConfigureHostConfiguration(c => + { + c.SetBasePath(Directory.GetCurrentDirectory()); + c.AddJsonFile("appsettings.json", optional: false); + }) + .ConfigureLogging((c, l) => + { + l.AddConfiguration(c.Configuration); + // Adding Sentry integration to Microsoft.Extensions.Logging + l.AddSentry(); + }) + .Build(); +``` + +In this example, a _generic host_ is being built and the MEL integration with Sentry added through `ConfigureLogging`. The example also demonstrates how to bind the `appsettings.json` configuration to make the values available to the Sentry integration. + +With this approach, options like `Dsn`, `SendDefaultPii`, `MinimumBreadcrumbLevel`, to name a few, can be set in `appsettings.json`. + +Example using `appsettings.json`: + +```json +{ + "Logging": { + "LogLevel": { + "Default": "Debug" + } + }, + "Sentry": { + "Dsn": "___PUBLIC_KEY___", + "MinimumBreadcrumbLevel": "Warning", + "MinimumEventLevel": "Critical", + "MaxBreadcrumbs": 50 + } +} +``` + +Above we set the application wide minimum log level to `Debug`. Sentry specific settings are set under the `Sentry` property. Options are documented below. + +#### Through `ILoggerFactory` + +```csharp +using (var loggerFactory = new LoggerFactory() + .AddConsole(LogLevel.Trace) + .AddSentry(o => o.Dsn = "___PUBLIC_KEY___")) +{ + var logger = loggerFactory.CreateLogger(); +} +``` + +This approach doesn't include any of the framework's configuration system. Since the SDK is being provided via parameter, the SDK will be initialized. +More settings can be passed via the callback configuring the `SentryOptions`. + +## Options and Initialization + +In cases where `AddSentry` is called without arguments, it's worth noting that an overload exists where `SentryOptions` can be configured just like if `SentrySdk.Init` had been called. + +> NOTE: +The SDK only needs to be initialized only once. If the `DSN` is made available to this integration, by default it **will** initialize the SDK. If you do not wish to initialize the SDK via this configuration, set the `InitializeSdk` flag to **false**. Not providing a DSN or leaving it as an _empty string_ will disable the SDK. + +For example: + +```csharp +using (var loggerFactory = new LoggerFactory() + .AddSentry(o => o.InitializeSdk = false)) +{ } +``` + +### Options + +#### MinimumBreadcrumbLevel + +A `LogLevel` which indicates the minimum level a log message has to be to be included as a breadcrumb. By default this value is `Information`. + +#### MinimumEventLevel + +A `LogLevel` which indicates the minimum level a log message has to be to be sent to Sentry as an event. By default this value is `Error`. + +#### InitializeSdk + +Whether or not this integration should initialize the SDK. If you intend to call `SentrySdk.Init` yourself you should set this flag to `true`. + +#### Filters + +A list of filters which are invoked before processing any log message. This allows you to inspect the details of the log entry before they become a `Breadcrumb` or an `Event` with full access to the `Microsoft.Extensions.Logging` data. + + +### Samples + +* A [simple example](https://github.com/getsentry/sentry-dotnet/tree/master/samples/Sentry.Samples.ME.Logging) using simply the `LoggerFactory`. +* An [example](https://github.com/getsentry/sentry-dotnet/tree/master/samples/Sentry.Samples.GenericHost) using the _generic host_. From f0aa3e85481c8dc7bc7739aad8dc711baa4b1ec3 Mon Sep 17 00:00:00 2001 From: Bruno Garcia Date: Sat, 8 Sep 2018 19:36:56 +0200 Subject: [PATCH 027/171] ref: reorder --- .../platforms/dotnet/entityframework.md | 18 ++++++++++-------- .../_documentation/platforms/dotnet/log4net.md | 3 ++- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/collections/_documentation/platforms/dotnet/entityframework.md b/src/collections/_documentation/platforms/dotnet/entityframework.md index de90fc9f2c7c0..c0f4533db9a7e 100644 --- a/src/collections/_documentation/platforms/dotnet/entityframework.md +++ b/src/collections/_documentation/platforms/dotnet/entityframework.md @@ -7,14 +7,6 @@ Sentry has an integration with `EntityFramework` through the of the `Sentry.Enti > Looking for `EntityFramework Core`? That integration is achieved through the `Microsoft.Extensions.Logging` package. -## Features - -* Queries as breadcrumbs -* Validation errors - -All queries executed are added as breadcrumbs and are sent with any event which happens on the same `Scope`. Besides that, validation errors are also included as `Extra`. - -This package extends `Sentry` main SDK. That means that besides the EF features, through this package you'll also get access to all API and features available in the main `Sentry` SDK. ## Installation @@ -30,6 +22,16 @@ Or using the .NET Core CLI: dotnet add Sentry.EntityFramework ``` +This package extends `Sentry` main SDK. That means that besides the EF features, through this package you'll also get access to all API and features available in the main `Sentry` SDK. + +## Features + +* Queries as breadcrumbs +* Validation errors + +All queries executed are added as breadcrumbs and are sent with any event which happens on the same `Scope`. Besides that, validation errors are also included as `Extra`. + + ## Configuration There are 2 steps to adding Entity Framework 6 support to your project: diff --git a/src/collections/_documentation/platforms/dotnet/log4net.md b/src/collections/_documentation/platforms/dotnet/log4net.md index 275c5d1ce262b..1a36b6559f51a 100644 --- a/src/collections/_documentation/platforms/dotnet/log4net.md +++ b/src/collections/_documentation/platforms/dotnet/log4net.md @@ -7,7 +7,6 @@ Sentry has an integration with log4net through the `Sentry.Log4Net` NuGet packa Without any code change, this package is able to initialize the Sentry SDK and capture events while including additional properties like `Exception` data and more. -This package extends `Sentry` main SDK. That means besides the log4net `Appender`, through this package you'll also get access to all API and features available in the main `Sentry` SDK. ## Installation @@ -23,6 +22,8 @@ Or using the .NET Core CLI: dotnet add Sentry.Log4Net ``` +This package extends `Sentry` main SDK. That means besides the log4net `Appender`, through this package you'll also get access to all API and features available in the main `Sentry` SDK. + ## Configuration Once the log4net integration package is installed in your project, you can modify your configuration file to add the appender. From 6df12bd6f7e8892ff3a31100ce049f4b45bc5628 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Mon, 10 Sep 2018 14:23:53 +0200 Subject: [PATCH 028/171] feat: Added basic draining docs --- .../learn/drain-example/javascript.md | 12 ++++++++++++ .../learn/drain-example/python.md | 10 ++++++++++ .../_documentation/learn/drain-example/rust.md | 12 ++++++++++++ .../_documentation/learn/draining.md | 17 +++++++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 src/collections/_documentation/learn/drain-example/javascript.md create mode 100644 src/collections/_documentation/learn/drain-example/python.md create mode 100644 src/collections/_documentation/learn/drain-example/rust.md create mode 100644 src/collections/_documentation/learn/draining.md diff --git a/src/collections/_documentation/learn/drain-example/javascript.md b/src/collections/_documentation/learn/drain-example/javascript.md new file mode 100644 index 0000000000000..c1fba56d3aeb0 --- /dev/null +++ b/src/collections/_documentation/learn/drain-example/javascript.md @@ -0,0 +1,12 @@ +The client provides a close method that optionally takes the time in milliseconds for how long it +waits and will return a promise that resolves when everything was flushed or the timeout kicked +in. + +```javascript +let client = Sentry.getCurrentHub().getClient(); +if (client) { + client.close(2000).then(function() { + process.exit(); + }); +} +``` diff --git a/src/collections/_documentation/learn/drain-example/python.md b/src/collections/_documentation/learn/drain-example/python.md new file mode 100644 index 0000000000000..fd333fca90ec7 --- /dev/null +++ b/src/collections/_documentation/learn/drain-example/python.md @@ -0,0 +1,10 @@ +The Python SDK automatically drains on shutdown unless the `AtExitIntegration` is removed or the `shutdown_timeout` +config key is set to 0. To manually drain the client provides a `close` method: + +```python +from sentry_sdk import Hub + +client = Hub.current.client +if client is not None: + client.close(timeout=2.0) +``` diff --git a/src/collections/_documentation/learn/drain-example/rust.md b/src/collections/_documentation/learn/drain-example/rust.md new file mode 100644 index 0000000000000..ff781cd8824df --- /dev/null +++ b/src/collections/_documentation/learn/drain-example/rust.md @@ -0,0 +1,12 @@ +When the Rust SDK initializes a guard is returned from the `init` function. The destructor +will automatically wait `shutdown_timeout` seconds. This means you just need to hold on to +the guard and make sure it disposes on shutdown. Alternatively the client can be closed: + +```javascript +use std::time::Duration; +use sentry::Hub; + +if let Some(client) = Hub.current().client() { + client.close(Some(Duration::from_secs(2))); +} +``` diff --git a/src/collections/_documentation/learn/draining.md b/src/collections/_documentation/learn/draining.md new file mode 100644 index 0000000000000..0a78db033eb42 --- /dev/null +++ b/src/collections/_documentation/learn/draining.md @@ -0,0 +1,17 @@ +--- +title: 'Shutdown and Draining' +sidebar_order: 16 +--- + +Most SDKs use a background queue to send out events. Because the queue sends asynchronously in the background +it means that some events might be lost if the application shuts down unexpectedly. To prevent this all SDKs +provide mechanisms to cope with this. + +Typically SDKs provide two ways to shut down: a controlled shutdown where the system will wait up to about two +seconds to flush out events (configurable) and an uncontrolled shutdown (also referred to as "killing" the +client). + +{% include components/platform_content.html content_dir='drain-example' %} + +After shutdown the client cannot be used any more so make sure to only do that right before you shut down +the application. From 35566ed228b40a92e77fd147d67433b97dc6ac2b Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Mon, 10 Sep 2018 16:09:07 +0200 Subject: [PATCH 029/171] feat: Added more python docs --- src/_data/platform_icons.yml | 6 +- .../learn/user-feedback-example/flask.md | 26 +++++++ .../python/{celery/index.md => celery.md} | 5 +- .../python/{django/index.md => django.md} | 5 +- .../python/{flask/index.md => flask.md} | 5 +- .../_documentation/platforms/python/index.md | 70 +++++++++++++++++-- .../python/{logging/index.md => logging.md} | 5 +- .../_documentation/platforms/python/system.md | 38 ++++++++++ 8 files changed, 149 insertions(+), 11 deletions(-) create mode 100644 src/collections/_documentation/learn/user-feedback-example/flask.md rename src/collections/_documentation/platforms/python/{celery/index.md => celery.md} (78%) rename src/collections/_documentation/platforms/python/{django/index.md => django.md} (89%) rename src/collections/_documentation/platforms/python/{flask/index.md => flask.md} (92%) rename src/collections/_documentation/platforms/python/{logging/index.md => logging.md} (92%) create mode 100644 src/collections/_documentation/platforms/python/system.md diff --git a/src/_data/platform_icons.yml b/src/_data/platform_icons.yml index caefb39465c41..78b17072a3f9f 100644 --- a/src/_data/platform_icons.yml +++ b/src/_data/platform_icons.yml @@ -7,13 +7,13 @@ platformicon: javascript - name: Django - link: _documentation/platforms/python/django/index.md + link: _documentation/platforms/python/django.md platformicon: django - name: Flask - link: _documentation/platforms/python/flask/index.md + link: _documentation/platforms/python/flask.md platformicon: flask - name: Celery - link: _documentation/platforms/python/celery/index.md + link: _documentation/platforms/python/celery.md platformicon: python diff --git a/src/collections/_documentation/learn/user-feedback-example/flask.md b/src/collections/_documentation/learn/user-feedback-example/flask.md new file mode 100644 index 0000000000000..d83f1a2aaff16 --- /dev/null +++ b/src/collections/_documentation/learn/user-feedback-example/flask.md @@ -0,0 +1,26 @@ +Custom 500 handler: + +```python +from flask import render_template +from sentry_sdk import last_event_id + +@app.errorhandler(500) +def server_error_handler(error): + return render_template("500.html", sentry_event_id=last_event_id()), 500 +``` + +And the template that brings up the dialog: + +{% raw %} +```html + + +{% if sentry_event_id %} + +{% endif %} +``` +{% endraw %} diff --git a/src/collections/_documentation/platforms/python/celery/index.md b/src/collections/_documentation/platforms/python/celery.md similarity index 78% rename from src/collections/_documentation/platforms/python/celery/index.md rename to src/collections/_documentation/platforms/python/celery.md index a615c1e7b2cab..440016d40fdd2 100644 --- a/src/collections/_documentation/platforms/python/celery/index.md +++ b/src/collections/_documentation/platforms/python/celery.md @@ -10,7 +10,10 @@ import sentry_sdk from sentry_sdk.integrations.celery import CeleryIntegration from sentry_sdk.integrations.django import DjangoIntegration -sentry_sdk.init(dsn="https://foo@sentry.io/123", integrations=[DjangoIntegration(), CeleryIntegration()]) +sentry_sdk.init( + dsn="___PUBLIC_DSN___", + integrations=[DjangoIntegration(), CeleryIntegration()] +) ``` With that, the transaction on the event will be set to the task name, and diff --git a/src/collections/_documentation/platforms/python/django/index.md b/src/collections/_documentation/platforms/python/django.md similarity index 89% rename from src/collections/_documentation/platforms/python/django/index.md rename to src/collections/_documentation/platforms/python/django.md index 8abe223ae4187..bf5f1e41e0964 100644 --- a/src/collections/_documentation/platforms/python/django/index.md +++ b/src/collections/_documentation/platforms/python/django.md @@ -9,7 +9,10 @@ In your ``settings.py``: import sentry_sdk from sentry_sdk.integrations.django import DjangoIntegration -sentry_sdk.init(dsn="https://foo@sentry.io/123", integrations=[DjangoIntegration()]) +sentry_sdk.init( + dsn="___PUBLIC_DSN___", + integrations=[DjangoIntegration()] +) ``` * All exceptions are reported. diff --git a/src/collections/_documentation/platforms/python/flask/index.md b/src/collections/_documentation/platforms/python/flask.md similarity index 92% rename from src/collections/_documentation/platforms/python/flask/index.md rename to src/collections/_documentation/platforms/python/flask.md index 98ba334f04ab9..cf43bffdef7e3 100644 --- a/src/collections/_documentation/platforms/python/flask/index.md +++ b/src/collections/_documentation/platforms/python/flask.md @@ -7,7 +7,10 @@ sidebar_order: 2 import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration -sentry_sdk.init(dsn="https://foo@sentry.io/123", integrations=[FlaskIntegration()]) +sentry_sdk.init( + dsn="___PUBLIC_DSN___", + integrations=[FlaskIntegration()] +) app = Flask(__name__) ``` diff --git a/src/collections/_documentation/platforms/python/index.md b/src/collections/_documentation/platforms/python/index.md index 0b5dffae161d0..ba6973c73fb2b 100644 --- a/src/collections/_documentation/platforms/python/index.md +++ b/src/collections/_documentation/platforms/python/index.md @@ -3,10 +3,72 @@ title: Python sidebar_order: 3 --- -Django +The new Python SDK (`sentry-sdk`) follows the new SDK guidelines. To get started +have a look at the [quickstart]({% link _documentation/learn/quickstart.md %}) docs. -Celery +## Integrations -Flask +*Integrations* extend the functionality of the SDK for some common frameworks and +libraries. They can be seen as plugins that extend the functionality of the Sentry +SDK. Integrations are configured by a call to `sentry_sdk.init`. Any default +integration not in the list is automatically added unless `default_integrations` is +set to `False`. -Logging +Example configuration for Django: + +```python +import sentry_sdk +from sentry_sdk.integrations.django import DjangoIntegration + +sentry_sdk.init( + dsn="___PUBLIC_DSN___", + integrations=[DjangoIntegration()] +) +``` + +## Included integrations + +The SDK ships various integrations, some of which are enabled by default but some +need to be opted in manually. + +### Django +Automatically capture exceptions thrown by the Django framework +and extracts useful information from the current request. [More +information]({% link _documentation/platforms/python/django.md %}). + +Class name: `sentry_sdk.integrations.django.DjangoIntegration` + +### Flask +Automatically capture exceptions thrown by Flask apps and extracts useful +information from the current request. [More information]({% link +_documentation/platforms/python/flask.md %}). + +### Celery +Automatically capture errors thrown from Celery tasks and improve the grouping for +failing tasks. [More information]({% link _documentation/platforms/python/celery.md %}). + +### Logging +Automatically capture breadcrumbs from log records and emit Sentry events for +error or fatal log records. This is enabled by default with the default settings +but can be manually configured if wanted. [More +information]({% link _documentation/platforms/python/logging.md %}). + +Import name: `sentry_sdk.integrations.logging.LoggingIntegration` + +### Requests +When this integration is enabled HTTP requests emitted through the `requests` library +will be reported as breadcrumbs. This integration is not enabled by default and +needs to be enabled. + +```python +import sentry_sdk +from sentry_sdk.integrations.requests import RequestsIntegration +sentry_sdk.init(integrations=[RequestsIntegration()]) +``` + +Import name: `sentry_sdk.integrations.requests.RequestsIntegration` + +### System Integrations + +There are some more internal "system" integrations which are enabled by default but can +be disabled if they cause issues. [More information]({% link _documentation/platforms/python/system.md %}). diff --git a/src/collections/_documentation/platforms/python/logging/index.md b/src/collections/_documentation/platforms/python/logging.md similarity index 92% rename from src/collections/_documentation/platforms/python/logging/index.md rename to src/collections/_documentation/platforms/python/logging.md index 338a6ccb4903a..a732e196d0206 100644 --- a/src/collections/_documentation/platforms/python/logging/index.md +++ b/src/collections/_documentation/platforms/python/logging.md @@ -15,7 +15,10 @@ sentry_logging = LoggingIntegration( level=logging.DEBUG, event_level=logging.ERROR ) -sentry_sdk.init(dsn="https://foo@sentry.io/123", integrations=[sentry_logging]) +sentry_sdk.init( + dsn="___PUBLIC_DSN___", + integrations=[sentry_logging] +) ``` The above configuration captures *all* messages, now including ``DEBUG``, as diff --git a/src/collections/_documentation/platforms/python/system.md b/src/collections/_documentation/platforms/python/system.md new file mode 100644 index 0000000000000..4eb95077e9227 --- /dev/null +++ b/src/collections/_documentation/platforms/python/system.md @@ -0,0 +1,38 @@ +--- +title: System +sidebar_order: 4 +--- + +System integrations are integrations enabled by default that integrate into the +standard library or the interpreter itself. They are documented so you can see +what they do and that they can be disabled if they cause issues. To disable +system integrations set `default_integrations=False` when calling `init()`. + +## Atexit +This integrates with the interpreter's `atexit` system to automatically flush +events from the background queue on interpreter shutdown. Typically one does +not need to disable this. Even if the functionality is not wanted it can also +be disabled by setting the `shutdown_timeout` to `0` in the options to +`init()`. + +Import name: `sentry_sdk.integrations.atexit.AtExitIntegration` + +## Excepthook +This integration registers with the interpreter's except hook system. Through this +any exception that is unhandled will be reported to Sentry automatically. Exceptions +raised interactive interpreter sessions will not be reported. + +Import name: `sentry_sdk.integrations.excepthook.ExceptHookIntegration` + +## Deduplication +This integration deduplicates certian events. This is enabled by default and should not +be disabled except in rare circumstances. Disabling this integration for instance will +cause duplicate error logging in the Flask framework. + +Import name: `sentry_sdk.integrations.dedupe.DedupeIntegration` + +## Stdlib +The stdlib integration instruments certain modules in the standard library to emit +breadcrumbs. This is enabled by default and rarely makes sense to disable. + +Import name: `sentry_sdk.integrations.stdlib.StdlibIntegration` From 3c05bea9a2ea8811e58ff1ef7f4db67b49904851 Mon Sep 17 00:00:00 2001 From: Bruno Garcia Date: Mon, 10 Sep 2018 17:38:54 +0200 Subject: [PATCH 030/171] feat: .NET SDK index --- .../_documentation/platforms/dotnet/index.md | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/collections/_documentation/platforms/dotnet/index.md b/src/collections/_documentation/platforms/dotnet/index.md index 7f6a72687bf2f..c0563efe1d801 100644 --- a/src/collections/_documentation/platforms/dotnet/index.md +++ b/src/collections/_documentation/platforms/dotnet/index.md @@ -3,6 +3,47 @@ title: .NET sidebar_order: 10 --- +This section will describe features, configurations and general functionality which are specific to the .NET SDKs. + +### Code + + +#### Automatically discovering release version + +The SDK attempts to locate the release to add that to the events sent to Sentry. + +> [Default values like 1.0 or 1.0.0.0 are ignored](https://github.com/getsentry/sentry-dotnet/blob/dbb5a3af054d0ca6f801de37fb7db3632ca2c65a/src/Sentry/Internal/ApplicationVersionLocator.cs#L14-L21). + +The SDK will firstly look at the [entry assembly's](https://msdn.microsoft.com/en-us/library/system.reflection.assembly.getentryassembly(v=vs.110).aspx) `AssemblyInformationalVersionAttribute`, which accepts a string as +value and is often used to set a GIT commit hash. + +If that returns null, it'll look at the default `AssemblyVersionAttribute` which accepts the numeric version number. When creating a project with Visual Studio, that values is set to *1.0.0.0*. +Since that usually means that the version is either not being set, or is set via a different method. The **automatic version detection will disregard** this value and no *Release* will be reported automatically. + +#### Unit testing + +We often don't want to couple our code with static class like `SentrySdk`. Especially to allow our code to be testable. +If that's your case, you can use 2 abstractions: + +* `ISentryClient` +* `IHub` + +The `ISentryClient` exposes the `CaptureEvent` method and it's implementation `SentryClient` is responsible to queueing the event to be sent to Sentry. It also abstracts away the internal transport. + +The `IHub` on the other hand, holds a client and the current scope. In fact, it extends `ISentryClient` and is able to dispatch calls to the right client depending on the current scope. + +In order to allow different events to hold different contextual data, you need to know in which scope you are in. +That's the job of the [`Hub`](https://github.com/getsentry/sentry-dotnet/blob/master/src/Sentry/Internal/Hub.cs). It holds the scope management as well as a client. + +If all you are doing is sending events, without modification/access to the current scope, then you depend on `ISentryClient`. If on the other hand you would like to have access to the current scope by configuring it or binding a different client to it, you depend on `IHub`. + + +An example using `IHub` for testability is [SentryLogger](https://github.com/getsentry/sentry-dotnet/blob/master/src/Sentry.Extensions.Logging/SentryLogger.cs) and its unit tests [SentryLoggerTests](https://github.com/getsentry/sentry-dotnet/blob/master/test/Sentry.Extensions.Logging.Tests/SentryLoggerTests.cs). +`SentryLogger` depends on `IHub` because it does modify the scope (through `AddBreadcrumb`). In case it only sent events, it should instead depend on `ISentryClient` + + +#### Integrations + ASP.NET Core Microsoft.Extensions.Logging log4net From a2f028528c4e4628a1f9680c30cd7a5b8a597977 Mon Sep 17 00:00:00 2001 From: Bruno Garcia Date: Mon, 10 Sep 2018 17:38:59 +0200 Subject: [PATCH 031/171] fix: SDK -> DSN --- .../platforms/dotnet/microsoft-extensions-logging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/collections/_documentation/platforms/dotnet/microsoft-extensions-logging.md b/src/collections/_documentation/platforms/dotnet/microsoft-extensions-logging.md index 57abdda727e21..fed12792cf9ec 100644 --- a/src/collections/_documentation/platforms/dotnet/microsoft-extensions-logging.md +++ b/src/collections/_documentation/platforms/dotnet/microsoft-extensions-logging.md @@ -106,7 +106,7 @@ using (var loggerFactory = new LoggerFactory() } ``` -This approach doesn't include any of the framework's configuration system. Since the SDK is being provided via parameter, the SDK will be initialized. +This approach doesn't include any of the framework's configuration system. Since the DSN is being provided via parameter, the SDK will be initialized. More settings can be passed via the callback configuring the `SentryOptions`. ## Options and Initialization From cc5519549af6e9d44e130bb124df6b3fb4ce8f18 Mon Sep 17 00:00:00 2001 From: Cameron McEfee Date: Mon, 10 Sep 2018 11:22:33 -0700 Subject: [PATCH 032/171] Add category entry so it shows up in sidebar --- src/_data/documentation_categories.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/_data/documentation_categories.yml b/src/_data/documentation_categories.yml index a633916852b1d..27bc4a2b6b0e9 100644 --- a/src/_data/documentation_categories.yml +++ b/src/_data/documentation_categories.yml @@ -6,6 +6,9 @@ - title: Learn slug: learn +- title: Clients + slug: clients + - title: Platforms slug: platforms From 950888561cc3b14b53fd2d3b9b4efff8b02061bc Mon Sep 17 00:00:00 2001 From: Cameron McEfee Date: Mon, 10 Sep 2018 11:29:56 -0700 Subject: [PATCH 033/171] Put clients after platforms --- _config.yml | 6 +++++- src/_data/documentation_categories.yml | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/_config.yml b/_config.yml index a2bd8d90b5992..0337c06259616 100644 --- a/_config.yml +++ b/_config.yml @@ -56,7 +56,11 @@ defaults: path: collections/_dev_components/markdown-styleguide/* values: layout: doc - + - scope: + path: collections/_dev_components/markdown-styleguide/* + values: + layout: doc + assets: source_maps: false # Prefer webpack sourcemaps plugins: diff --git a/src/_data/documentation_categories.yml b/src/_data/documentation_categories.yml index 27bc4a2b6b0e9..11dcd24898e0f 100644 --- a/src/_data/documentation_categories.yml +++ b/src/_data/documentation_categories.yml @@ -6,12 +6,12 @@ - title: Learn slug: learn -- title: Clients - slug: clients - - title: Platforms slug: platforms +- title: Clients + slug: clients + - title: Integrations slug: integrations From c5e624ee463ffd7ee212b089fd5addcb2d0cf17b Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Mon, 10 Sep 2018 20:55:08 +0200 Subject: [PATCH 034/171] ref: Remove slash from browser javascript --- src/_data/platforms.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index 5b3c2358e13c3..c68756faeff4a 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -177,7 +177,7 @@ slug: browser support_level: production type: language - name: Browser / Javascript + name: Browser Javascript doc_link: /clients/javascript/ wizard: [] case_style: camelCase From d1b07f7c3f96d643f30e31baea0273a7369c7e36 Mon Sep 17 00:00:00 2001 From: Cameron McEfee Date: Mon, 10 Sep 2018 12:29:13 -0700 Subject: [PATCH 035/171] Only generate platform data when a platform has data --- src/_plugins/platform_api.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index 1738a7d12163b..7a132ab6b78ef 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -80,6 +80,8 @@ def generate(site) # Generate each file site.data["platforms"].each do |platform| + return nil if platform["wizard"].nil? + body = "" platform["wizard"].each do |wiz| file, section = wiz.split '#' From 5dbcfe556e7d1406b47f284f3769f5ffec658798 Mon Sep 17 00:00:00 2001 From: Cameron McEfee Date: Mon, 10 Sep 2018 12:47:03 -0700 Subject: [PATCH 036/171] Call them legacy --- src/_data/documentation_categories.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_data/documentation_categories.yml b/src/_data/documentation_categories.yml index 11dcd24898e0f..8be27e2a01b93 100644 --- a/src/_data/documentation_categories.yml +++ b/src/_data/documentation_categories.yml @@ -9,7 +9,7 @@ - title: Platforms slug: platforms -- title: Clients +- title: Legacy Clients slug: clients - title: Integrations From 27d25383c2b0239de57d102feeb94d06d02a8316 Mon Sep 17 00:00:00 2001 From: Cameron McEfee Date: Mon, 10 Sep 2018 14:45:47 -0700 Subject: [PATCH 037/171] refactor --- src/_js/lib/PlatformContent.js | 94 +++++++++++++++------------------- 1 file changed, 41 insertions(+), 53 deletions(-) diff --git a/src/_js/lib/PlatformContent.js b/src/_js/lib/PlatformContent.js index eac37e09e05f6..5b64bce3664ba 100644 --- a/src/_js/lib/PlatformContent.js +++ b/src/_js/lib/PlatformContent.js @@ -1,23 +1,38 @@ import qs from 'query-string'; +const DEFAULT_PLATFORM = 'javascript'; const KEY = 'preferredPlatform'; -// Get the object associated with a given platform slug. +// Platform display priority: // -// slug - slug matching a platform in data/platforms.yml +// - `platform` in url +// - `preferredPlatform` in localStorage +// - default platform // -// Returns an object or null if no platform matches the slug. -const verifyPlatformSlug = function(slug) { - return window.supportedPlatforms.find(x => x === slug); +// `preferredPlatform` will update when: +// +// - `platform` in url is specified +// - A new platform is selected in the UI +// +// platform displayed may be forced by: +// +// - setting the `platform` in the url + +// Get the slug for the platform that should be displayed +// +// Returns a String. +const getPlatformSlug = function() { + return localStorage.getItem(KEY) || DEFAULT_PLATFORM; }; -// Update the url of hte page to reflect a current slug +// Get the object associated with a given platform slug. // // slug - slug matching a platform in data/platforms.yml // -// Returns nothing. -const updateLocationPlatform = function(slug) { - history.replaceState({}, '', updateUrlPlatform(location.href, slug)); +// Returns an object or null if no platform matches the slug. +const verifyPlatformSlug = function(slug) { + if (!slug) return false; + return window.supportedPlatforms.find(x => x === slug); }; // Add or update the platform slug of a url @@ -86,25 +101,21 @@ const syncRelatedElements = function() { // // Returns nothing. const showPlatform = function(slug) { - if (!verifyPlatformSlug(slug)) return; + if (verifyPlatformSlug(slug)) localStorage.setItem(KEY, slug); + slug = getPlatformSlug(); window.activePlatform = slug; let platform = window.platformData[window.activePlatform]; $('[data-platform-specific-content]').each((i, el) => { const $block = $(el); - let $dropdownItems; - let $requested; - let $preferred; + let $dropdownItems = $block.find('[data-toggle="platform"]'); + let $preferred = $dropdownItems.filter(`[data-platform="${slug}"]`); let $active; + const slugs = [slug, platform.fallback_platform]; for (const index in slugs) { - $dropdownItems = $block.find('[data-toggle="platform"]'); - $requested = $dropdownItems.filter(`[data-platform="${slugs[index]}"]`); - $preferred = $dropdownItems.filter( - `[data-platform="${localStorage.getItem(KEY)}"]` - ); - $active = $requested; + $active = $dropdownItems.filter(`[data-platform="${slugs[index]}"]`); if ($active.length) { // We skip and don't use fallback platform break; @@ -114,7 +125,7 @@ const showPlatform = function(slug) { $active = $preferred.length ? $preferred : $dropdownItems.eq(0); } - // Updat the active state of the dropdown items + // Update the active state of the dropdown items $dropdownItems.removeClass('active'); $dropdownItems.attr('aria-selected', false); $active.addClass('active'); @@ -132,25 +143,19 @@ const showPlatform = function(slug) { $block.find('[data-toggle="dropdown"]').text($active.text()); }); + history.replaceState({}, '', updateUrlPlatform(location.href, slug)); syncRelatedElements(); }; -// Add the current platform to all links on the page. -// -// slug - slug matching a platform in data/platforms.yml -// -// Returns nothing. -const addPlatformToLinks = function(slug) { - const validSlug = verifyPlatformSlug(slug); - if (!validSlug) return; - - $('a').each((i, el) => { - const $el = $(el); - const href = $el.attr('href'); - const isDocLink = /(^\/|docs.sentry.io)/.test(href); - if (isDocLink) $el.attr('href', updateUrlPlatform(href, validSlug)); - }); -}; +$(document).on('click', '[data-toggle="platform"]', function(event) { + event.preventDefault(); + showPlatform($(event.target).data('platform')); +}); + +$(document).on('page.didUpdate', function(event) { + // Update the preferredPlatform based on the url. + showPlatform(qs.parse(location.search).platform); +}); // Attach event listeners and set UI state based on the platform supplied via // query param, stored in localStorage as the preferred platform, or the @@ -159,23 +164,6 @@ const addPlatformToLinks = function(slug) { // Returns nothing. const init = function() { initRelatedElements(); - - $(document).on('click', '[data-toggle="platform"]', function(event) { - event.preventDefault(); - const $target = $(event.target); - const slug = $target.data('platform'); - localStorage.setItem(KEY, slug); - showPlatform(slug); - addPlatformToLinks(slug); - updateLocationPlatform(slug); - }); - - $(document).on('page.didUpdate', function(event) { - const queryPlatform = qs.parse(location.search).platform; - const preferredPlatform = localStorage.getItem(KEY); - showPlatform(queryPlatform || preferredPlatform); - addPlatformToLinks(queryPlatform); - }); }; export default { init }; From 640451f3cdd462f0ba96248c22b060d1a7cad8a8 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Tue, 11 Sep 2018 00:09:51 +0200 Subject: [PATCH 038/171] ref: Refactored python docs --- .../_documentation/platforms/python/celery.md | 16 ++--- .../{system.md => default-integrations.md} | 18 ++--- .../_documentation/platforms/python/django.md | 18 ++++- .../_documentation/platforms/python/flask.md | 18 +++-- .../_documentation/platforms/python/index.md | 72 +++++-------------- .../platforms/python/logging.md | 1 + .../platforms/python/requests.md | 17 +++++ 7 files changed, 81 insertions(+), 79 deletions(-) rename src/collections/_documentation/platforms/python/{system.md => default-integrations.md} (81%) create mode 100644 src/collections/_documentation/platforms/python/requests.md diff --git a/src/collections/_documentation/platforms/python/celery.md b/src/collections/_documentation/platforms/python/celery.md index 440016d40fdd2..594b45fec47a5 100644 --- a/src/collections/_documentation/platforms/python/celery.md +++ b/src/collections/_documentation/platforms/python/celery.md @@ -2,19 +2,19 @@ title: Celery sidebar_order: 2 --- +*Import name: `sentry_sdk.integrations.celery.CeleryIntegration`* -Just add ``CeleryIntegration()`` to your ``integrations`` array. For example, in Django: +The celery integration adds support for the [Celery Task Queue System](http://www.celeryproject.org/). + +Just add ``CeleryIntegration()`` to your ``integrations`` list. The integration does not +accept any arguments and will automatically report errors from all celery tasks: ```python import sentry_sdk from sentry_sdk.integrations.celery import CeleryIntegration -from sentry_sdk.integrations.django import DjangoIntegration -sentry_sdk.init( - dsn="___PUBLIC_DSN___", - integrations=[DjangoIntegration(), CeleryIntegration()] -) +sentry_sdk.init(integrations=[CeleryIntegration()]) ``` -With that, the transaction on the event will be set to the task name, and -exceptions will be reported to Sentry. +Additionally the transaction on the event will be set to the task name and +the grouping will be improved for global celery errors such as timeouts. diff --git a/src/collections/_documentation/platforms/python/system.md b/src/collections/_documentation/platforms/python/default-integrations.md similarity index 81% rename from src/collections/_documentation/platforms/python/system.md rename to src/collections/_documentation/platforms/python/default-integrations.md index 4eb95077e9227..073980a822b5b 100644 --- a/src/collections/_documentation/platforms/python/system.md +++ b/src/collections/_documentation/platforms/python/default-integrations.md @@ -1,5 +1,5 @@ --- -title: System +title: Default Integrations sidebar_order: 4 --- @@ -9,30 +9,30 @@ what they do and that they can be disabled if they cause issues. To disable system integrations set `default_integrations=False` when calling `init()`. ## Atexit +*Import name: `sentry_sdk.integrations.atexit.AtExitIntegration`* + This integrates with the interpreter's `atexit` system to automatically flush events from the background queue on interpreter shutdown. Typically one does not need to disable this. Even if the functionality is not wanted it can also be disabled by setting the `shutdown_timeout` to `0` in the options to `init()`. -Import name: `sentry_sdk.integrations.atexit.AtExitIntegration` - ## Excepthook +*Import name: `sentry_sdk.integrations.excepthook.ExceptHookIntegration`* + This integration registers with the interpreter's except hook system. Through this any exception that is unhandled will be reported to Sentry automatically. Exceptions raised interactive interpreter sessions will not be reported. -Import name: `sentry_sdk.integrations.excepthook.ExceptHookIntegration` - ## Deduplication +*Import name: `sentry_sdk.integrations.dedupe.DedupeIntegration`* + This integration deduplicates certian events. This is enabled by default and should not be disabled except in rare circumstances. Disabling this integration for instance will cause duplicate error logging in the Flask framework. -Import name: `sentry_sdk.integrations.dedupe.DedupeIntegration` - ## Stdlib +*Import name: `sentry_sdk.integrations.stdlib.StdlibIntegration`* + The stdlib integration instruments certain modules in the standard library to emit breadcrumbs. This is enabled by default and rarely makes sense to disable. - -Import name: `sentry_sdk.integrations.stdlib.StdlibIntegration` diff --git a/src/collections/_documentation/platforms/python/django.md b/src/collections/_documentation/platforms/python/django.md index bf5f1e41e0964..0f5cbd90fd2ad 100644 --- a/src/collections/_documentation/platforms/python/django.md +++ b/src/collections/_documentation/platforms/python/django.md @@ -2,8 +2,11 @@ title: Django sidebar_order: 2 --- +*Import name: `sentry_sdk.integrations.django.DjangoIntegration`* -In your ``settings.py``: +The Django integration adds support for the [Django Web Framework](https://www.djangoproject.com/) +from Version 1.6 upwards. To configure the SDK initialize it with the Django +integration in your ``settings.py`` file: ```python import sentry_sdk @@ -15,6 +18,10 @@ sentry_sdk.init( ) ``` +## Behavior + +This causes the following this to happen: + * All exceptions are reported. * A bit of data is attached to each event: @@ -28,5 +35,10 @@ sentry_sdk.init( * If you have ``django.contrib.auth`` installed and configured, user data (current user id, email address, username) is attached to the event. -* Logging with any logger will create breadcrumbs. See logging docs for more - information. +* Logging with any logger will create breadcrumbs when the [Logging]({% link _documentation/platforms/python/logging.md %}) + integration is enabled (done by default). + +## User Feedback + +The user feedback feature can be used with this integration. For more information +see [User Feedback]({% link _documentation/learn/user-feedback.md %}?platform=django). diff --git a/src/collections/_documentation/platforms/python/flask.md b/src/collections/_documentation/platforms/python/flask.md index cf43bffdef7e3..8e8140dfdea83 100644 --- a/src/collections/_documentation/platforms/python/flask.md +++ b/src/collections/_documentation/platforms/python/flask.md @@ -2,6 +2,11 @@ title: Flask sidebar_order: 2 --- +*Import name: `sentry_sdk.integrations.flask.FlaskIntegration`* + +The Django integration adds support for the [Flask Web +Framework](http://flask.pocoo.org/). To configure the SDK initialize it with +the integration before or after your app has been initialized: ```python import sentry_sdk @@ -15,8 +20,7 @@ sentry_sdk.init( app = Flask(__name__) ``` -* You can actually run that `init` anywhere. Before or after you define your - routes, before or after you register extensions. +## Behavior * The Flask integration will be installed for all of your apps. It hooks into Flask's signals, not anything on the app object. @@ -34,5 +38,11 @@ app = Flask(__name__) * All exceptions leading to a Internal Server Error are reported. -* Logging with `app.logger` or really *any* logger will create breadcrumbs. See - logging docs for more information. +* Logging with `app.logger` or really *any* logger will create breadcrumbs when + the [Logging]({% link _documentation/platforms/python/logging.md %}) + integration is enabled (done by default). + +## User Feedback + +The user feedback feature can be used with this integration. For more information +see [User Feedback]({% link _documentation/learn/user-feedback.md %}?platform=flask). diff --git a/src/collections/_documentation/platforms/python/index.md b/src/collections/_documentation/platforms/python/index.md index ba6973c73fb2b..ebf4cf89ae244 100644 --- a/src/collections/_documentation/platforms/python/index.md +++ b/src/collections/_documentation/platforms/python/index.md @@ -3,8 +3,12 @@ title: Python sidebar_order: 3 --- -The new Python SDK (`sentry-sdk`) follows the new SDK guidelines. To get started -have a look at the [quickstart]({% link _documentation/learn/quickstart.md %}) docs. +The [Sentry Python SDK](https://pypi.org/project/sentry-sdk) provides Sentry support +for Python 2.7 and 3.5 or later. It follows the new unified SDK architecture. To +get started have a look at the [quickstart]({% link _documentation/learn/quickstart.md %}?platform=python) docs. + +This documentation goes over some Python specific things such as integrations to +frameworks. ## Integrations @@ -14,61 +18,19 @@ SDK. Integrations are configured by a call to `sentry_sdk.init`. Any default integration not in the list is automatically added unless `default_integrations` is set to `False`. -Example configuration for Django: - -```python -import sentry_sdk -from sentry_sdk.integrations.django import DjangoIntegration - -sentry_sdk.init( - dsn="___PUBLIC_DSN___", - integrations=[DjangoIntegration()] -) -``` - -## Included integrations - -The SDK ships various integrations, some of which are enabled by default but some -need to be opted in manually. - -### Django -Automatically capture exceptions thrown by the Django framework -and extracts useful information from the current request. [More -information]({% link _documentation/platforms/python/django.md %}). - -Class name: `sentry_sdk.integrations.django.DjangoIntegration` - -### Flask -Automatically capture exceptions thrown by Flask apps and extracts useful -information from the current request. [More information]({% link -_documentation/platforms/python/flask.md %}). - -### Celery -Automatically capture errors thrown from Celery tasks and improve the grouping for -failing tasks. [More information]({% link _documentation/platforms/python/celery.md %}). - -### Logging -Automatically capture breadcrumbs from log records and emit Sentry events for -error or fatal log records. This is enabled by default with the default settings -but can be manually configured if wanted. [More -information]({% link _documentation/platforms/python/logging.md %}). - -Import name: `sentry_sdk.integrations.logging.LoggingIntegration` +## Framework Integrations -### Requests -When this integration is enabled HTTP requests emitted through the `requests` library -will be reported as breadcrumbs. This integration is not enabled by default and -needs to be enabled. +Framework integrations are opt-in integrations for large frameworks or libraries. Currently +the following are supported: -```python -import sentry_sdk -from sentry_sdk.integrations.requests import RequestsIntegration -sentry_sdk.init(integrations=[RequestsIntegration()]) -``` +* [Celery]({% link _documentation/platforms/python/celery.md %}) +* [Django]({% link _documentation/platforms/python/django.md %}) +* [Flask]({% link _documentation/platforms/python/flask.md %}) +* [Logging]({% link _documentation/platforms/python/logging.md %}) -Import name: `sentry_sdk.integrations.requests.RequestsIntegration` +## Other Integrations -### System Integrations +In addition to framework integrations there are also a few other integrations: -There are some more internal "system" integrations which are enabled by default but can -be disabled if they cause issues. [More information]({% link _documentation/platforms/python/system.md %}). +* [Default integrations]({% link _documentation/platforms/python/default-integrations.md %}) +* [Requests integration]({% link _documentation/platforms/python/requests.md %}) diff --git a/src/collections/_documentation/platforms/python/logging.md b/src/collections/_documentation/platforms/python/logging.md index a732e196d0206..ee4dd7d91e1ee 100644 --- a/src/collections/_documentation/platforms/python/logging.md +++ b/src/collections/_documentation/platforms/python/logging.md @@ -2,6 +2,7 @@ title: Logging sidebar_order: 2 --- +*Import name: `sentry_sdk.integrations.logging.LoggingIntegration`* Calling ``sentry_sdk.init()`` already captures any logging message with a level higher than or equal to ``INFO``. You can change this behavior by explicitly diff --git a/src/collections/_documentation/platforms/python/requests.md b/src/collections/_documentation/platforms/python/requests.md new file mode 100644 index 0000000000000..216f4d682e178 --- /dev/null +++ b/src/collections/_documentation/platforms/python/requests.md @@ -0,0 +1,17 @@ +--- +title: Requests +sidebar_order: 4 +--- + +Import name: `sentry_sdk.integrations.requests.RequestsIntegration` + +When this integration is enabled HTTP requests emitted through the `requests` library +will be reported as breadcrumbs. This integration is not enabled by default and +needs to be enabled. + +```python +import sentry_sdk +from sentry_sdk.integrations.requests import RequestsIntegration + +sentry_sdk.init(integrations=[RequestsIntegration()]) +``` From 447dd006b426455e830a5fd0b244b6d99238f05a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Og=C3=B3rek?= Date: Tue, 11 Sep 2018 10:02:12 +0200 Subject: [PATCH 039/171] feat: beforeSend for javascript --- .../_documentation/learn/before-send/javascript.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/collections/_documentation/learn/before-send/javascript.md diff --git a/src/collections/_documentation/learn/before-send/javascript.md b/src/collections/_documentation/learn/before-send/javascript.md new file mode 100644 index 0000000000000..d523ca1a88cf3 --- /dev/null +++ b/src/collections/_documentation/learn/before-send/javascript.md @@ -0,0 +1,12 @@ +```javascript +Sentry.init({ + beforeSend(event) { + // Modify the event here + if (event.user) { + // Don't send user's email address + delete event.user.email; + } + return event; + } +}); +``` From 2788b69e3c8912c9b3c1b1e7f513a8e9dcc19cb1 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Tue, 11 Sep 2018 10:26:57 +0200 Subject: [PATCH 040/171] feat: Added magic sidebar --- src/_plugins/document_path_tree.rb | 33 ++++++++++++++++--- .../_documentation/clients/cocoa/index.md | 1 + .../_documentation/clients/elixir/index.md | 1 + .../_documentation/clients/go/index.md | 1 + .../_documentation/clients/java/index.md | 1 + .../_documentation/clients/php/index.md | 1 + .../_documentation/clients/ruby/index.md | 1 + .../platforms/python/default-integrations.md | 2 +- 8 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/_plugins/document_path_tree.rb b/src/_plugins/document_path_tree.rb index 700bd2698e4e3..89dcf0de083d6 100644 --- a/src/_plugins/document_path_tree.rb +++ b/src/_plugins/document_path_tree.rb @@ -1,6 +1,7 @@ +require 'pp' Jekyll::Hooks.register :site, :pre_render, priority: :low do |site| - def treeFor(docs, root) + def tree_for(docs, root) tree = [] groups = docs.group_by do |doc| @@ -24,7 +25,7 @@ def treeFor(docs, root) docs_without_index = docs_for_group.reject {|doc| doc.path.include? "#{new_root}index." } - items = new_root.nil? ? nil : treeFor(docs_without_index, new_root) + items = new_root.nil? ? nil : tree_for(docs_without_index, new_root) if !items.nil? items.sort_by! do |i| @@ -49,10 +50,34 @@ def treeFor(docs, root) tree end - mapped = site.collections.map {|c| c[1].docs} documents = mapped.flatten() - tree = treeFor(documents, "") + tree = tree_for(documents, "") + + # relocate some items + def adjacent_move(item, stack) + # TODO: we might have to support direct parent as well + parent = stack[stack.size - 2] + if !parent.nil? && !item["document"].nil? + other_sidebar = item["document"].data["sidebar_relocation"] + if !other_sidebar.nil? && parent["items"] + parent["items"].each do |parent_item| + pp [parent_item["slug"], other_sidebar] + if parent_item["slug"] == other_sidebar + parent_item["items"].push item + return nil + end + end + end + end + + if !item["items"].nil? + item["items"] = item["items"].map { |child| adjacent_move(child, stack + [item]) }.compact + end + item + end + + tree = tree.map { |item| adjacent_move(item, []) } tree.each do |collection| config_slug = "#{collection["name"]}_categories" diff --git a/src/collections/_documentation/clients/cocoa/index.md b/src/collections/_documentation/clients/cocoa/index.md index 29820c98de883..5a5554f0eb796 100644 --- a/src/collections/_documentation/clients/cocoa/index.md +++ b/src/collections/_documentation/clients/cocoa/index.md @@ -1,6 +1,7 @@ --- title: Cocoa sidebar_order: 1 +sidebar_relocation: platforms --- This is the documentation for our official clients for Cocoa (Swift and Objective-C). Starting with version `3.0.0` we’ve switched our interal code from Swift to Objective-C to maximize compatiblity. Also we trimmed the public API of our sdk to a minimum. Some of the lesser used features that where present before are gone now, check out [Migration Guide]({%- link _documentation/clients/cocoa/migration.md -%}#migration) or [Advanced Usage]({%- link _documentation/clients/cocoa/advanced.md -%}#advanced) for details. diff --git a/src/collections/_documentation/clients/elixir/index.md b/src/collections/_documentation/clients/elixir/index.md index 7c7bdb7c75d7c..fa143e61552c2 100644 --- a/src/collections/_documentation/clients/elixir/index.md +++ b/src/collections/_documentation/clients/elixir/index.md @@ -1,6 +1,7 @@ --- title: Elixir sidebar_order: 4 +sidebar_relocation: platforms --- The Elixir SDK for Sentry. diff --git a/src/collections/_documentation/clients/go/index.md b/src/collections/_documentation/clients/go/index.md index c2a06fe1117c5..7397a67e02674 100644 --- a/src/collections/_documentation/clients/go/index.md +++ b/src/collections/_documentation/clients/go/index.md @@ -1,6 +1,7 @@ --- title: Go sidebar_order: 5 +sidebar_relocation: platforms --- {% capture __alert_content -%} diff --git a/src/collections/_documentation/clients/java/index.md b/src/collections/_documentation/clients/java/index.md index 6ac454181cf39..0ddcef596fa08 100644 --- a/src/collections/_documentation/clients/java/index.md +++ b/src/collections/_documentation/clients/java/index.md @@ -1,6 +1,7 @@ --- title: Java sidebar_order: 6 +sidebar_relocation: platforms --- Sentry for Java is the official Java SDK for Sentry. At its core it provides a raw client for sending events to Sentry, but it is highly recommended that you use one of the included library or framework integrations listed below if at all possible. diff --git a/src/collections/_documentation/clients/php/index.md b/src/collections/_documentation/clients/php/index.md index 697524c89cae5..53801a9ebb2df 100644 --- a/src/collections/_documentation/clients/php/index.md +++ b/src/collections/_documentation/clients/php/index.md @@ -1,6 +1,7 @@ --- title: PHP sidebar_order: 11 +sidebar_relocation: platforms --- The PHP SDK for Sentry supports PHP 5.3 and higher. It’s available as a BSD licensed Open Source library. diff --git a/src/collections/_documentation/clients/ruby/index.md b/src/collections/_documentation/clients/ruby/index.md index 7039fd017aa11..8647508e3b00e 100644 --- a/src/collections/_documentation/clients/ruby/index.md +++ b/src/collections/_documentation/clients/ruby/index.md @@ -1,6 +1,7 @@ --- title: Ruby sidebar_order: 14 +sidebar_relocation: platforms --- Raven for Ruby is a client and integration layer for the Sentry error reporting API. It supports Ruby 1.9.3 and 2.x. JRuby support is provided but experimental. diff --git a/src/collections/_documentation/platforms/python/default-integrations.md b/src/collections/_documentation/platforms/python/default-integrations.md index 073980a822b5b..e306e6d8b6368 100644 --- a/src/collections/_documentation/platforms/python/default-integrations.md +++ b/src/collections/_documentation/platforms/python/default-integrations.md @@ -1,6 +1,6 @@ --- title: Default Integrations -sidebar_order: 4 +sidebar_order: 10 --- System integrations are integrations enabled by default that integrate into the From 4a56b51f69fa6d176509a8f4d4c8e5a95e43a3de Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Tue, 11 Sep 2018 10:30:13 +0200 Subject: [PATCH 041/171] fix: Remove a debug print --- src/_plugins/document_path_tree.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/_plugins/document_path_tree.rb b/src/_plugins/document_path_tree.rb index 89dcf0de083d6..f0335494aeb7b 100644 --- a/src/_plugins/document_path_tree.rb +++ b/src/_plugins/document_path_tree.rb @@ -1,5 +1,3 @@ -require 'pp' - Jekyll::Hooks.register :site, :pre_render, priority: :low do |site| def tree_for(docs, root) tree = [] @@ -62,7 +60,6 @@ def adjacent_move(item, stack) other_sidebar = item["document"].data["sidebar_relocation"] if !other_sidebar.nil? && parent["items"] parent["items"].each do |parent_item| - pp [parent_item["slug"], other_sidebar] if parent_item["slug"] == other_sidebar parent_item["items"].push item return nil From 1e73f37bf557ac87e187656f7e0070c1bdb148b1 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Tue, 11 Sep 2018 10:49:38 +0200 Subject: [PATCH 042/171] ref: Moved some legacy stuff around --- src/_data/LEGACY_platform_icons.yml | 29 ------------------- src/_data/documentation_categories.yml | 6 ++-- src/_data/platforms.yml | 4 +-- .../_documentation/clients/index.md | 6 ++-- .../_documentation/clients/minidump/index.md | 1 + .../{clients => platforms}/rust/index.md | 0 6 files changed, 9 insertions(+), 37 deletions(-) rename src/collections/_documentation/{clients => platforms}/rust/index.md (100%) diff --git a/src/_data/LEGACY_platform_icons.yml b/src/_data/LEGACY_platform_icons.yml index 4025c55f8e1c4..eb66ac6ca0884 100644 --- a/src/_data/LEGACY_platform_icons.yml +++ b/src/_data/LEGACY_platform_icons.yml @@ -13,35 +13,6 @@ - name: React Native link: _documentation/clients/react-native/index.md platformicon: react -- name: PHP - link: _documentation/clients/php/index.md - platformicon: php -- name: Ruby - link: _documentation/clients/ruby/index.md - platformicon: ruby -- name: Cocoa - link: _documentation/clients/cocoa/index.md - platformicon: apple -- name: Java - link: _documentation/clients/java/index.md - platformicon: java -- name: 'C#' - link: _documentation/clients/csharp/index.md - platformicon: csharp -- name: Rust - link: _documentation/clients/rust/index.md - platformicon: rust -- name: Go - link: _documentation/clients/go/index.md - platformicon: go -- name: Elixir - link: _documentation/clients/elixir/index.md - platformicon: elixir - name: Perl link: _documentation/clients/perl/index.md platformicon: perl -- name: Cordova - link: _documentation/clients/cordova/index.md - platformicon: cordova -- name: Minidump - link: _documentation/clients/minidump/index.md diff --git a/src/_data/documentation_categories.yml b/src/_data/documentation_categories.yml index 8be27e2a01b93..5be1e90d5fe0d 100644 --- a/src/_data/documentation_categories.yml +++ b/src/_data/documentation_categories.yml @@ -9,12 +9,12 @@ - title: Platforms slug: platforms -- title: Legacy Clients - slug: clients - - title: Integrations slug: integrations +- title: Legacy Clients + slug: clients + - title: On-Premise slug: server diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index c68756faeff4a..e8bc89a121347 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -355,8 +355,8 @@ support_level: production type: language name: Rust - doc_link: /clients/rust/ - wizard: ['_documentation/clients/rust/index.md#installation', '_documentation/clients/rust/index.md#configuring-the-client', '_documentation/clients/rust/index.md#reporting-errors', '_documentation/clients/rust/index.md#catching-panics'] + doc_link: /platforms/rust/ + wizard: ['_documentation/platforms/rust/index.md#installation', '_documentation/platforms/rust/index.md#configuring-the-client', '_documentation/platforms/rust/index.md#reporting-errors', '_documentation/platforms/rust/index.md#catching-panics'] version: 0.6.0 version_key: SENTRY_VERSION case_style: snake_case diff --git a/src/collections/_documentation/clients/index.md b/src/collections/_documentation/clients/index.md index 01f6d5c29ef09..01044cd5f6c03 100644 --- a/src/collections/_documentation/clients/index.md +++ b/src/collections/_documentation/clients/index.md @@ -1,8 +1,8 @@ --- -title: SDKs -sidebar_order: 2 +title: Legacy Clients +sidebar_order: 4 --- -To report to Sentry you’ll need to use a language-specific SDK. The Sentry team builds and maintains these for most popular languages, but there’s also a large ecosystem supported by the community. If your favorite language isn’t listed below, we encourage you to start a discussion about supporting it on our [community forum](https://forum.sentry.io). +Some of the clients that report to Sentry have been replaced by newer SDKs or are no longer maintained. We document them here for users who are still using those clients but they are recommended against for new projects. {% include LEGACY_platform_icon_links.html %} diff --git a/src/collections/_documentation/clients/minidump/index.md b/src/collections/_documentation/clients/minidump/index.md index 46bc30150a159..a980d798ae70b 100644 --- a/src/collections/_documentation/clients/minidump/index.md +++ b/src/collections/_documentation/clients/minidump/index.md @@ -1,6 +1,7 @@ --- title: Minidump sidebar_order: 8 +sidebar_relocation: platforms --- Sentry can process Minidump crash reports, a memory dump used on Windows and by open-source libraries like [_Breakpad_]({%- link _documentation/clients/minidump/breakpad.md -%}) or [_Crashpad_]({%- link _documentation/clients/minidump/crashpad.md -%}). You can either choose to generate and upload minidumps yourself or use a higher-level SDK for platforms with built-in support for native crashes: diff --git a/src/collections/_documentation/clients/rust/index.md b/src/collections/_documentation/platforms/rust/index.md similarity index 100% rename from src/collections/_documentation/clients/rust/index.md rename to src/collections/_documentation/platforms/rust/index.md From 848375c302b23411cde5d81dbc7d474c9429e4cb Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Tue, 11 Sep 2018 11:21:14 +0200 Subject: [PATCH 043/171] ref: Move minidumps to /platforms --- nginx.conf | 8 ++++++++ src/_data/platforms.yml | 4 ++-- .../{clients => platforms}/minidump/breakpad.md | 0 .../{clients => platforms}/minidump/crashpad.md | 0 .../{clients => platforms}/minidump/index.md | 6 +++--- 5 files changed, 13 insertions(+), 5 deletions(-) rename src/collections/_documentation/{clients => platforms}/minidump/breakpad.md (100%) rename src/collections/_documentation/{clients => platforms}/minidump/crashpad.md (100%) rename src/collections/_documentation/{clients => platforms}/minidump/index.md (92%) diff --git a/nginx.conf b/nginx.conf index 6f4f96fca0a2b..df8e42214a523 100644 --- a/nginx.conf +++ b/nginx.conf @@ -15,6 +15,14 @@ server { rewrite ^/(?:hosted|on-premise)/(.*)$ /$1$is_args$args redirect; + location = /clients/rust/ { + return 302 /platforms/rust/$is_args$args; + } + + location = /clients/minidump/ { + return 302 /platforms/minidump/$is_args$args; + } + location = /clients/javascript/integrations/angular2/ { return 302 /clients/javascript/integrations/angular/$is_args$args; } diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index e8bc89a121347..023e9ec36db88 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -365,5 +365,5 @@ support_level: production type: language name: Minidump - doc_link: /clients/minidump/ - wizard: ['_documentation/clients/minidump/index.md#platform-and-language-support', '_documentation/clients/minidump/index.md#creating-and-uploading-minidumps'] + doc_link: /platforms/minidump/ + wizard: ['_documentation/platforms/minidump/index.md#platform-and-language-support', '_documentation/platforms/minidump/index.md#creating-and-uploading-minidumps'] diff --git a/src/collections/_documentation/clients/minidump/breakpad.md b/src/collections/_documentation/platforms/minidump/breakpad.md similarity index 100% rename from src/collections/_documentation/clients/minidump/breakpad.md rename to src/collections/_documentation/platforms/minidump/breakpad.md diff --git a/src/collections/_documentation/clients/minidump/crashpad.md b/src/collections/_documentation/platforms/minidump/crashpad.md similarity index 100% rename from src/collections/_documentation/clients/minidump/crashpad.md rename to src/collections/_documentation/platforms/minidump/crashpad.md diff --git a/src/collections/_documentation/clients/minidump/index.md b/src/collections/_documentation/platforms/minidump/index.md similarity index 92% rename from src/collections/_documentation/clients/minidump/index.md rename to src/collections/_documentation/platforms/minidump/index.md index a980d798ae70b..d93fc9d5c55e9 100644 --- a/src/collections/_documentation/clients/minidump/index.md +++ b/src/collections/_documentation/platforms/minidump/index.md @@ -4,7 +4,7 @@ sidebar_order: 8 sidebar_relocation: platforms --- -Sentry can process Minidump crash reports, a memory dump used on Windows and by open-source libraries like [_Breakpad_]({%- link _documentation/clients/minidump/breakpad.md -%}) or [_Crashpad_]({%- link _documentation/clients/minidump/crashpad.md -%}). You can either choose to generate and upload minidumps yourself or use a higher-level SDK for platforms with built-in support for native crashes: +Sentry can process Minidump crash reports, a memory dump used on Windows and by open-source libraries like [_Breakpad_]({%- link _documentation/platforms/minidump/breakpad.md -%}) or [_Crashpad_]({%- link _documentation/platforms/minidump/crashpad.md -%}). You can either choose to generate and upload minidumps yourself or use a higher-level SDK for platforms with built-in support for native crashes: - [_Cocoa_]({%- link _documentation/clients/cocoa/index.md -%}) - [_Electron_]({%- link _documentation/clients/electron/index.md -%}) @@ -44,8 +44,8 @@ In addition to this information, you can add further meta data specific to Sentr Depending on your operating system and programming language, there are various alternatives to create minidumps and upload them to Sentry. See the following resources for libraries that support generating minidump crash reports: -- [Google Breakpad]({%- link _documentation/clients/minidump/breakpad.md -%}) -- [Google Crashpad]({%- link _documentation/clients/minidump/crashpad.md -%}) +- [Google Breakpad]({%- link _documentation/platforms/minidump/breakpad.md -%}) +- [Google Crashpad]({%- link _documentation/platforms/minidump/crashpad.md -%}) If you have already integrated a library that generates minidumps and would just like to upload them to Sentry, you need to configure the _Minidump Endpoint URL_, which can be found at _Project Settings > Client Keys (DSN)_. This endpoint expects a `POST` request with the minidump in the `upload_file_minidump` field: From 2b1ad1646b39b69c44f2de61c16727feded1e0ac Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Tue, 11 Sep 2018 11:28:41 +0200 Subject: [PATCH 044/171] fix: Fix an endless build loop --- src/collections/_documentation/platforms/minidump/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/collections/_documentation/platforms/minidump/index.md b/src/collections/_documentation/platforms/minidump/index.md index d93fc9d5c55e9..b920fbde66cd2 100644 --- a/src/collections/_documentation/platforms/minidump/index.md +++ b/src/collections/_documentation/platforms/minidump/index.md @@ -1,7 +1,6 @@ --- title: Minidump sidebar_order: 8 -sidebar_relocation: platforms --- Sentry can process Minidump crash reports, a memory dump used on Windows and by open-source libraries like [_Breakpad_]({%- link _documentation/platforms/minidump/breakpad.md -%}) or [_Crashpad_]({%- link _documentation/platforms/minidump/crashpad.md -%}). You can either choose to generate and upload minidumps yourself or use a higher-level SDK for platforms with built-in support for native crashes: From c47b02d8a1155c4acb23e3abc97b3ec5d30ec9ed Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Tue, 11 Sep 2018 13:03:39 +0200 Subject: [PATCH 045/171] feat: Rust integration docs --- .../_documentation/platforms/python/index.md | 11 ++- .../platforms/rust/env_logger.md | 26 +++++ .../platforms/rust/error_chain.md | 24 +++++ .../_documentation/platforms/rust/failure.md | 29 ++++++ .../_documentation/platforms/rust/index.md | 99 ++++--------------- .../_documentation/platforms/rust/log.md | 34 +++++++ .../_documentation/platforms/rust/panic.md | 18 ++++ 7 files changed, 157 insertions(+), 84 deletions(-) create mode 100644 src/collections/_documentation/platforms/rust/env_logger.md create mode 100644 src/collections/_documentation/platforms/rust/error_chain.md create mode 100644 src/collections/_documentation/platforms/rust/failure.md create mode 100644 src/collections/_documentation/platforms/rust/log.md create mode 100644 src/collections/_documentation/platforms/rust/panic.md diff --git a/src/collections/_documentation/platforms/python/index.md b/src/collections/_documentation/platforms/python/index.md index ebf4cf89ae244..57b1ef677bbac 100644 --- a/src/collections/_documentation/platforms/python/index.md +++ b/src/collections/_documentation/platforms/python/index.md @@ -4,8 +4,11 @@ sidebar_order: 3 --- The [Sentry Python SDK](https://pypi.org/project/sentry-sdk) provides Sentry support -for Python 2.7 and 3.5 or later. It follows the new unified SDK architecture. To -get started have a look at the [quickstart]({% link _documentation/learn/quickstart.md %}?platform=python) docs. +for Python 2.7 and 3.5 or later. + +The Python SDK follows the new unified SDK architecture. To get started +have a look at the [quickstart]({% link _documentation/learn/quickstart.md +%}?platform=python) docs. This documentation goes over some Python specific things such as integrations to frameworks. @@ -18,7 +21,7 @@ SDK. Integrations are configured by a call to `sentry_sdk.init`. Any default integration not in the list is automatically added unless `default_integrations` is set to `False`. -## Framework Integrations +### Framework Integrations Framework integrations are opt-in integrations for large frameworks or libraries. Currently the following are supported: @@ -28,7 +31,7 @@ the following are supported: * [Flask]({% link _documentation/platforms/python/flask.md %}) * [Logging]({% link _documentation/platforms/python/logging.md %}) -## Other Integrations +### Other Integrations In addition to framework integrations there are also a few other integrations: diff --git a/src/collections/_documentation/platforms/rust/env_logger.md b/src/collections/_documentation/platforms/rust/env_logger.md new file mode 100644 index 0000000000000..d5a0afd656695 --- /dev/null +++ b/src/collections/_documentation/platforms/rust/env_logger.md @@ -0,0 +1,26 @@ +--- +title: env-logger +sidebar_order: 2 +--- + +*Feature: `with_env_logger` (enabled by default)* + +Adds support for automatic breadcrumb capturing from logs with `env_logger`. + +## Configuration +In the most trivial version you call this crate's init function instead of the +one from `env_logger` and pass `None` as logger: + +```rust +sentry::integrations::env_logger::init(None, Default::default()); +``` + +This parses the default `RUST_LOG` environment variable and configures both +`env_logger` and this crate appropriately. If you want to create your own +logger you can forward it accordingly: + +```rust +let mut log_builder = pretty_env_logger::formatted_builder().unwrap(); +log_builder.parse("info,foo=debug"); +sentry::integrations::env_logger::init(Some(log_builder.build()), Default::default()); +``` diff --git a/src/collections/_documentation/platforms/rust/error_chain.md b/src/collections/_documentation/platforms/rust/error_chain.md new file mode 100644 index 0000000000000..c4a46072be686 --- /dev/null +++ b/src/collections/_documentation/platforms/rust/error_chain.md @@ -0,0 +1,24 @@ +-- +title: error-chain +sidebar_order: 2 +-- + +*Feature: `with_error_chain` (disabled by default)* + +Adds support for the error-chain crate. + +Errors created by the `error-chain` crate can be logged with the +`error_chain` integration. + +## Example + +```rust +use sentry::integrations::error_chain::capture_error_chain; +let result = match function_that_might_fail() { + Ok(result) => result, + Err(err) => { + capture_error_chain(&err); + return Err(err); + } +}; +``` diff --git a/src/collections/_documentation/platforms/rust/failure.md b/src/collections/_documentation/platforms/rust/failure.md new file mode 100644 index 0000000000000..9dbcf7f10fc78 --- /dev/null +++ b/src/collections/_documentation/platforms/rust/failure.md @@ -0,0 +1,29 @@ +--- +title: failure +sidebar_order: 2 +--- + +*Feature: `with_failure` (enabled by default)* + +Adds support for the failure crate. + +Failure errors and `Fail` objects can be logged with the failure integration. +This works really well if you use the `failure::Error` type or if you have +`failure::Fail` objects that use the failure context internally to gain a +backtrace. + +## Example + +```rust +use sentry::integrations::failure::capture_error; + +let result = match function_that_might_fail() { + Ok(result) => result, + Err(err) => { + capture_error(&err); + return Err(err); + } +}; +``` + +To capture fails and not errors use `capture_fail`. diff --git a/src/collections/_documentation/platforms/rust/index.md b/src/collections/_documentation/platforms/rust/index.md index b1081b8e0c456..4ca48549561d0 100644 --- a/src/collections/_documentation/platforms/rust/index.md +++ b/src/collections/_documentation/platforms/rust/index.md @@ -3,100 +3,39 @@ title: Rust sidebar_order: 15 --- -Sentry-Rust is the official Rust SDK for Sentry. It maps the entire Sentry protocol for Rust and provides convenient helpers for sending common types of events to Sentry. +Sentry-Rust is the official Rust SDK for Sentry. It maps the entire Sentry +protocol for Rust and provides convenient helpers for sending common types of +events to Sentry. -## Installation +The Rust SDK follows the new unified SDK architecture. To get started have a +look at the [quickstart]({% link _documentation/learn/quickstart.md +%}?platform=rust) docs. -Sentry-Rust is distributed as a normal crate from crates.io. You can add it to your project as a dependency in your _Cargo.toml_ file: +## Integrations -``` -[dependencies] -sentry = "0.9.0" -``` +*Integrations* extend the functionality of the SDK for some common frameworks +and libraries. -Additionally you can configure a bunch of features to enable or disable functionality in the crate. By default the most common features are compiled into the crate. For a list of features that are available refer to the [API Documentation](https://docs.rs/sentry). +### Error handling integrations -## Configuring the Client +The Rust SDK supports the most commonly used libraries for advanced error management: -The client is configured by calling `sentry::init` with a value that can be converted into a configuration object. These are the most common values: +* [failure]({% link _documentation/platforms/rust/failure.md %}) +* [error-chain]({% link _documentation/platforms/rust/error_chain.md %}) -- _an empty tuple_: in that case the client is configured from the `SENTRY_DSN` environment variably only. -- _a string holding a DSN_: if you pass a string then a DSN is parsed and the client is initialized with that DSN. -- _a tuple in the form (dsn, options)_: This is a form where the client is configured with a DSN plus an options object that allows you to configure additional features. -- _just options_: In that case everything (including the DSN) are configured from the passed options. +Additionally you can catch panics using the panic integration: -This is the most common case for client configuration: +* [panic]({% link _documentation/platforms/rust/panic.md %}) -```rust -extern crate sentry; +### Logging integrations -fn main() { - sentry::init("___PUBLIC_DSN___"); - // code using sentry goes here. -} -``` +Logs can be automatically converted into breadcrumbs. -To configure releases automatically you can use the `sentry_crate_release!` macro in combination with the tuple config syntax: - -```rust -#[macro_use] extern crate sentry; - -fn main() { - sentry::init(("___PUBLIC_DSN___", sentry::ClientOptions { - release: sentry_crate_release!(), - ..Default::default() - })); - // code using sentry goes here. -} -``` - -## Reporting Errors - -Once Sentry is configured errors and other events can be emitted. Since Rust has different mechanisms by which errors can be issued different functionality is provided for them. By default support for the new [failure](https://docs.rs/failure) error system is provided. - -For instance to report a `failure::Error` this code can be used: - -```rust -use sentry::integrations::failure::capture_error; - -let result = match a_function_that_might_fail() { - Ok(val) => val, - Err(err) => { - capture_error(&err); - return Err(err); - } -}; -``` - -## Catching Panics - -To automatically catch panics the panic integration can be used: - -```rust -use sentry::integrations::panic::register_panic_handler; - -fn main() { - sentry::init(...); - register_panic_handler(); -} -``` - -## Flushing Errors on Shutdown - -Since Sentry Rust uses a thread to offload event sending it’s possible that pending events are not sent on shutdown. There are two ways to prevent this from happening. The first one is to retain the guard returned from `sentry::init` which will flush out in the _Drop_ implementation (it will wait up to 2 seconds for this): - -```rust -fn main() { - let _guard = sentry::init(...); -} -``` +* [env_logger]({% link _documentation/platforms/rust/env_logger.md %}) +* [log]({% link _documentation/platforms/rust/log.md %}) ## More Information -For more information (in particular about how to set contextual data) refer to the [full API documentation](https://docs.rs/sentry/) which has all that information and more. - -Resources: - - [API Docs](http://docs.rs/sentry) - [Crates.io page](http://crates.io/crates/sentry) - [Bug Tracker](http://github.com/getsentry/sentry-rust/issues) diff --git a/src/collections/_documentation/platforms/rust/log.md b/src/collections/_documentation/platforms/rust/log.md new file mode 100644 index 0000000000000..816422d179ebb --- /dev/null +++ b/src/collections/_documentation/platforms/rust/log.md @@ -0,0 +1,34 @@ +--- +title: log +sidebar_order: 2 +--- + +*Feature: `with_log` (enabled by default)* + +Adds support for automatic breadcrumb capturing from logs. + +The `log` crate is supported in two ways. First events can be captured as +breadcrumbs for later, secondly error events can be logged as events to Sentry. +By default anything above `Info` is recorded as breadcrumb and anything above +`Error` is captured as error event. + +## Configuration + +However due to how log systems in Rust work this currently requires you to +slightly change your log setup. This is an example with the pretty env logger +crate: + +```rust +let mut log_builder = pretty_env_logger::formatted_builder().unwrap(); +log_builder.parse("info"); // or env::var("RUST_LOG") +let logger = log_builder.build(); +let options = sentry::integrations::log::LoggerOptions { + global_filter: Some(logger.filter()), + ..Default::default() +}; +sentry::integrations::log::init(Some(Box::new(logger)), options); +``` + +For loggers based on `env_logger` (like `pretty_env_logger`) you can also use +the [`env_logger`](../env_logger/index.html) integration which is much easier +to use. diff --git a/src/collections/_documentation/platforms/rust/panic.md b/src/collections/_documentation/platforms/rust/panic.md new file mode 100644 index 0000000000000..5bea9a80a6452 --- /dev/null +++ b/src/collections/_documentation/platforms/rust/panic.md @@ -0,0 +1,18 @@ +--- +title: Handling panics +sidebar_order: 2 +--- + +*Feature: `with_panic` (enabled by default)* + +A panic handler can be installed that will automatically dispatch all errors to +Sentry that are caused by a panic. + +## Configuration + +```rust +use sentry::integrations::panic::register_panic_handler; +register_panic_handler(); +``` + +Additionally panics are forwarded to the previously registered panic hook. From 40d3ef6493e4401d32ae105caf0a9e2fb09e7a26 Mon Sep 17 00:00:00 2001 From: HazA Date: Tue, 11 Sep 2018 13:26:50 +0200 Subject: [PATCH 046/171] fix: reportDialog example --- .../_documentation/learn/user-feedback-example/django.md | 7 +++++-- .../_documentation/learn/user-feedback-example/flask.md | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/collections/_documentation/learn/user-feedback-example/django.md b/src/collections/_documentation/learn/user-feedback-example/django.md index 2b7d269f74f85..1ba5510137029 100644 --- a/src/collections/_documentation/learn/user-feedback-example/django.md +++ b/src/collections/_documentation/learn/user-feedback-example/django.md @@ -18,8 +18,11 @@ And the template that brings up the dialog {% if sentry_event_id %} {% endif %} diff --git a/src/collections/_documentation/learn/user-feedback-example/flask.md b/src/collections/_documentation/learn/user-feedback-example/flask.md index d83f1a2aaff16..0abbcca35f529 100644 --- a/src/collections/_documentation/learn/user-feedback-example/flask.md +++ b/src/collections/_documentation/learn/user-feedback-example/flask.md @@ -17,8 +17,11 @@ And the template that brings up the dialog: {% if sentry_event_id %} {% endif %} From 12eb64df50283659da2856f391959d2859ee8548 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Tue, 11 Sep 2018 13:03:39 +0200 Subject: [PATCH 047/171] feat: Integration docs for actix-web --- .../_documentation/platforms/rust/actix.md | 73 +++++++++++++++++++ .../_documentation/platforms/rust/index.md | 8 +- 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/collections/_documentation/platforms/rust/actix.md diff --git a/src/collections/_documentation/platforms/rust/actix.md b/src/collections/_documentation/platforms/rust/actix.md new file mode 100644 index 0000000000000..b99b2b30dcbfa --- /dev/null +++ b/src/collections/_documentation/platforms/rust/actix.md @@ -0,0 +1,73 @@ +--- +title: Actix-Web +sidebar_order: 2 +--- + +*Crate: `sentry-actix` (has to be installed separately)* + +The `sentry-actix` *crate* adds a middleware for +[`actix-web`](https://actix.rs/) that captures errors and report them to +`Sentry`. + +To use this middleware just configure Sentry and then add it to your actix web +app as a middleware. Because actix is generally working with non sendable +objects and highly concurrent this middleware creates a new hub per request. +As a result many of the sentry integrations such as breadcrumbs do not work +unless you bind the actix hub. + +# Example + +```rust +extern crate actix_web; +extern crate sentry; +extern crate sentry_actix; + +use std::env; +use std::io; + +use actix_web::{server, App, Error, HttpRequest}; +use sentry_actix::SentryMiddleware; + +fn failing(_req: &HttpRequest) -> Result { + Err(io::Error::new(io::ErrorKind::Other, "An error happens here").into()) +} + +fn main() { + let _guard = sentry::init("https://public@sentry.io/1234"); + env::set_var("RUST_BACKTRACE", "1"); + sentry::integrations::panic::register_panic_handler(); + + server::new(|| { + App::new() + .middleware(SentryMiddleware::new()) + .resource("/", |r| r.f(failing)) + }).bind("127.0.0.1:3001") + .unwrap() + .run(); +} +``` + +# Reusing the Hub + +If you use this integration the `Hub::current()` returned hub is typically the wrong one. +To get the request specific one you need to use the `ActixWebHubExt` trait: + +```rust +use sentry::{Hub, Level}; +use sentry_actix::ActixWebHubExt; + +let hub = Hub::from_request(req); +hub.capture_message("Something is not well", Level::Warning); +``` + +The hub can also be made current: + +```rust +use sentry::{Hub, Level}; +use sentry_actix::ActixWebHubExt; + +let hub = Hub::from_request(req); +Hub::run(hub, || { + sentry::capture_message("Something is not well", Level::Warning); +}); +``` diff --git a/src/collections/_documentation/platforms/rust/index.md b/src/collections/_documentation/platforms/rust/index.md index 4ca48549561d0..1156352dd0167 100644 --- a/src/collections/_documentation/platforms/rust/index.md +++ b/src/collections/_documentation/platforms/rust/index.md @@ -16,9 +16,15 @@ look at the [quickstart]({% link _documentation/learn/quickstart.md *Integrations* extend the functionality of the SDK for some common frameworks and libraries. +### Framework integrations + +Sentry-Rust supports the following application frameworks: + +* [actix-web]({% link _documentation/platforms/rust/actix.md %}) + ### Error handling integrations -The Rust SDK supports the most commonly used libraries for advanced error management: +Sentry-Rust supports the most commonly used libraries for advanced error management: * [failure]({% link _documentation/platforms/rust/failure.md %}) * [error-chain]({% link _documentation/platforms/rust/error_chain.md %}) From 6cde21f079d682a54c2ede0b585c267a70fc1b15 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Tue, 11 Sep 2018 14:00:46 +0200 Subject: [PATCH 048/171] feat: Added python and js to legacy platforms --- src/_data/platforms.yml | 25 +++++++++++++++++++++++-- src/_layouts/doc.html | 19 +++++++++++++++++++ src/_plugins/url_starts_with.rb | 11 +++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 src/_plugins/url_starts_with.rb diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index 023e9ec36db88..64682b79eff2f 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -104,9 +104,19 @@ support_level: production type: language name: Python - doc_link: /clients/python/ + doc_link: /platforms/python/ + # this is actually the old wizard wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/usage.md#capture-an-error', '_documentation/clients/python/usage.md#reporting-an-event'] case_style: snake_case +- + slug: python-legacy + support_level: production + type: language + name: Python Legacy + doc_link: /clients/python/ + wizard: [] + case_style: snake_case + superseded_by: python - slug: pyramid support_level: production @@ -187,11 +197,22 @@ support_level: production type: language name: JavaScript - doc_link: /clients/javascript/ + doc_link: /platforms/javascript/ + # this is actually the old wizard wizard: ['_documentation/clients/javascript/index.md#installation', '_documentation/clients/javascript/index.md#configuring-the-client', '_documentation/clients/javascript/index.md#manually-reporting-errors'] + case_style: camelCase + superseded_by: +- + slug: javascript-legacy + support_level: production + type: language + name: JavaScript + doc_link: /clients/javascript/ + wizard: [] version: 3.26.4 version_key: RAVEN_VERSION case_style: camelCase + superseded_by: javascript - slug: vue support_level: production diff --git a/src/_layouts/doc.html b/src/_layouts/doc.html index dbd8502384c48..0dc2dc5f4d21c 100644 --- a/src/_layouts/doc.html +++ b/src/_layouts/doc.html @@ -26,6 +26,25 @@
+ {%- for platform in site.data.platforms -%} + {%- if platform.superseded_by %} + {%- assign __is_active = page.url | url_starts_with: platform.doc_link %} + {%- if __is_active %} + {%- assign __new_platform = site.data.platforms | where: 'slug', platform.superseded_by | first %} + {% capture __alert_content -%} + This SDK has been superseded by a new unified one. The documentation here is + preserved for customers using the old client. For new projects have a look + at the new client documentation: + Unified {{ __new_platform.name }} SDK. + {%- endcapture -%} + {%- include components/alert.html + level="info" + title="Deprecated Client" + content=__alert_content + %} + {%- endif %} + {%- endif %} + {%- endfor %}

{{ page.title }}

diff --git a/src/_plugins/url_starts_with.rb b/src/_plugins/url_starts_with.rb new file mode 100644 index 0000000000000..4848e869dbe4f --- /dev/null +++ b/src/_plugins/url_starts_with.rb @@ -0,0 +1,11 @@ +module Jekyll + module LiquifyFilter + def url_starts_with(input, arg) + arg = arg.chomp('/') + prefix = input[0..arg.length] + prefix == arg || prefix == arg + '/' + end + end +end + +Liquid::Template.register_filter(Jekyll::LiquifyFilter) From 2a8088ea1244f39aca90f959611de8d089ebffd7 Mon Sep 17 00:00:00 2001 From: HazA Date: Tue, 11 Sep 2018 14:01:51 +0200 Subject: [PATCH 049/171] feat: Add more platforms --- src/_data/platform_icons.yml | 36 +++++++++++++++++-- .../platforms/javascript/angularjs.md | 1 + .../platforms/javascript/cordova.md | 1 + .../platforms/javascript/electron.md | 1 + .../platforms/javascript/node.md | 1 + .../platforms/javascript/react.md | 1 + src/index.md | 2 -- 7 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 src/collections/_documentation/platforms/javascript/angularjs.md create mode 100644 src/collections/_documentation/platforms/javascript/cordova.md create mode 100644 src/collections/_documentation/platforms/javascript/electron.md create mode 100644 src/collections/_documentation/platforms/javascript/node.md create mode 100644 src/collections/_documentation/platforms/javascript/react.md diff --git a/src/_data/platform_icons.yml b/src/_data/platform_icons.yml index 78b17072a3f9f..bbc22fe78ef62 100644 --- a/src/_data/platform_icons.yml +++ b/src/_data/platform_icons.yml @@ -1,10 +1,42 @@ -- name: Browser +- name: HTML + link: _documentation/platforms/javascript/browser.md + platformicon: HTML5 + +- name: JavaScript link: _documentation/platforms/javascript/browser.md platformicon: javascript +- name: Node.js + link: _documentation/platforms/javascript/node.md + platformicon: nodejs + - name: Vue link: _documentation/platforms/javascript/vue.md - platformicon: javascript + platformicon: vue + +- name: Angular.js + link: _documentation/platforms/javascript/angularjs.md + platformicon: angularjs + +- name: Ember + link: _documentation/platforms/javascript/ember.md + platformicon: ember + +- name: React + link: _documentation/platforms/javascript/react.md + platformicon: react + +- name: Cordova + link: _documentation/platforms/javascript/cordova.md + platformicon: cordova + +- name: Electron + link: _documentation/platforms/javascript/electron.md + platformicon: electron + +- name: Python + link: _documentation/platforms/python/index.md + platformicon: python - name: Django link: _documentation/platforms/python/django.md diff --git a/src/collections/_documentation/platforms/javascript/angularjs.md b/src/collections/_documentation/platforms/javascript/angularjs.md new file mode 100644 index 0000000000000..30404ce4c5463 --- /dev/null +++ b/src/collections/_documentation/platforms/javascript/angularjs.md @@ -0,0 +1 @@ +TODO \ No newline at end of file diff --git a/src/collections/_documentation/platforms/javascript/cordova.md b/src/collections/_documentation/platforms/javascript/cordova.md new file mode 100644 index 0000000000000..30404ce4c5463 --- /dev/null +++ b/src/collections/_documentation/platforms/javascript/cordova.md @@ -0,0 +1 @@ +TODO \ No newline at end of file diff --git a/src/collections/_documentation/platforms/javascript/electron.md b/src/collections/_documentation/platforms/javascript/electron.md new file mode 100644 index 0000000000000..30404ce4c5463 --- /dev/null +++ b/src/collections/_documentation/platforms/javascript/electron.md @@ -0,0 +1 @@ +TODO \ No newline at end of file diff --git a/src/collections/_documentation/platforms/javascript/node.md b/src/collections/_documentation/platforms/javascript/node.md new file mode 100644 index 0000000000000..30404ce4c5463 --- /dev/null +++ b/src/collections/_documentation/platforms/javascript/node.md @@ -0,0 +1 @@ +TODO \ No newline at end of file diff --git a/src/collections/_documentation/platforms/javascript/react.md b/src/collections/_documentation/platforms/javascript/react.md new file mode 100644 index 0000000000000..30404ce4c5463 --- /dev/null +++ b/src/collections/_documentation/platforms/javascript/react.md @@ -0,0 +1 @@ +TODO \ No newline at end of file diff --git a/src/index.md b/src/index.md index 1d1d60828939a..9ff1580cbd9d5 100644 --- a/src/index.md +++ b/src/index.md @@ -15,8 +15,6 @@ To get you started, you might find some of these links relevant: To report to Sentry you’ll need to use a language-specific SDK. The Sentry team builds and maintains these for most popular languages, but there’s also a large ecosystem supported by the community. If your favorite language isn’t listed below, we encourage you to start a discussion about supporting it on our [community forum](https://forum.sentry.io). -# TODO: here should be tabs like in the onboarding wizard - {% include platform_icon_links.html %} ## Contributing From 77d7bbc4749c657537d89f56662859cb4a7c9f71 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Tue, 11 Sep 2018 14:02:34 +0200 Subject: [PATCH 050/171] ref: Move react-native to the new index for now --- src/collections/_documentation/clients/react-native/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/collections/_documentation/clients/react-native/index.md b/src/collections/_documentation/clients/react-native/index.md index 093d4abe0b5b9..ebcc530834657 100644 --- a/src/collections/_documentation/clients/react-native/index.md +++ b/src/collections/_documentation/clients/react-native/index.md @@ -1,6 +1,7 @@ --- title: 'React Native' sidebar_order: 11 +sidebar_relocation: platforms --- This is the documentation for our React-Native SDK. The React-Native SDK uses a native extension for iOS and Android but will fall back to a pure JavaScript version if necessary. From 0cd525ea257804b54d0476f2b43e028f65b410c1 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Tue, 11 Sep 2018 14:11:03 +0200 Subject: [PATCH 051/171] feat: More legacy platforms --- src/_data/platforms.yml | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index 64682b79eff2f..22b9563e08af7 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -10,15 +10,28 @@ support_level: production type: language name: Node.js + # XXX: does this have a better link? + doc_link: /platforms/javascript/ + # this is actually the old wizard + wizard: ['_documentation/clients/node/index.md#installation', '_documentation/clients/node/index.md#configuring-the-client', '_documentation/clients/node/index.md#reporting-errors'] + case_style: camelCase + fallback_platform: javascript +- + slug: node-legacy + support_level: production + type: language + name: Node.js doc_link: /clients/node/ wizard: ['_documentation/clients/node/index.md#installation', '_documentation/clients/node/index.md#configuring-the-client', '_documentation/clients/node/index.md#reporting-errors'] case_style: camelCase fallback_platform: javascript + superseded_by: node - slug: express support_level: production type: framework name: Express + # XXX: this links to the old ones doc_link: /clients/node/integrations/express/ wizard: ['_documentation/clients/node/index.md#installation', _documentation/clients/node/integrations/express.md] - @@ -26,6 +39,7 @@ support_level: production type: framework name: Connect + # XXX: this links to the old ones doc_link: /clients/node/integrations/connect/ wizard: ['_documentation/clients/node/index.md#installation', _documentation/clients/node/integrations/connect.md] - @@ -301,13 +315,24 @@ version: 4.1.0 version_key: SENTRY_COCOA_TAG - + # XXX: this should probably be dotnet and not csharp slug: csharp + support_level: production + type: language + name: 'C#' + doc_link: /platforms/dotnet/ + # this is actually the old wizard + wizard: ['_documentation/clients/csharp/index.md#installation', '_documentation/clients/csharp/index.md#capturing-exceptions'] + case_style: PascalCase +- + slug: csharp-legacy support_level: community type: language name: 'C#' doc_link: /clients/csharp/ - wizard: ['_documentation/clients/csharp/index.md#installation', '_documentation/clients/csharp/index.md#capturing-exceptions'] + wizard: [] case_style: PascalCase + superseded_by: csharp - slug: go support_level: in-development From 2f32d67feac24afad8e4b6608af68660d4645e1e Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Tue, 11 Sep 2018 14:07:13 +0200 Subject: [PATCH 052/171] fix: Headline level and stray DSN in rust/actix doc --- src/collections/_documentation/platforms/rust/actix.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/collections/_documentation/platforms/rust/actix.md b/src/collections/_documentation/platforms/rust/actix.md index b99b2b30dcbfa..d0206c1697906 100644 --- a/src/collections/_documentation/platforms/rust/actix.md +++ b/src/collections/_documentation/platforms/rust/actix.md @@ -15,7 +15,7 @@ objects and highly concurrent this middleware creates a new hub per request. As a result many of the sentry integrations such as breadcrumbs do not work unless you bind the actix hub. -# Example +## Example ```rust extern crate actix_web; @@ -33,7 +33,7 @@ fn failing(_req: &HttpRequest) -> Result { } fn main() { - let _guard = sentry::init("https://public@sentry.io/1234"); + let _guard = sentry::init("___PUBLIC_DSN___"); env::set_var("RUST_BACKTRACE", "1"); sentry::integrations::panic::register_panic_handler(); @@ -47,7 +47,7 @@ fn main() { } ``` -# Reusing the Hub +## Reusing the Hub If you use this integration the `Hub::current()` returned hub is typically the wrong one. To get the request specific one you need to use the `ActixWebHubExt` trait: From 90a94b9db104f2ec7c1d1520c7965cb9ff869fbd Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Tue, 11 Sep 2018 14:34:18 +0200 Subject: [PATCH 053/171] feat: Added shutdown for .NET and fallback platform for aspnetcore --- src/_data/platforms.yml | 1 + .../_documentation/learn/drain-example/csharp.md | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 src/collections/_documentation/learn/drain-example/csharp.md diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index 22b9563e08af7..0da162c71c9fb 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -64,6 +64,7 @@ type: framework name: ASP.NET Core doc_link: /clients/ + fallback_platform: csharp - slug: java support_level: production diff --git a/src/collections/_documentation/learn/drain-example/csharp.md b/src/collections/_documentation/learn/drain-example/csharp.md new file mode 100644 index 0000000000000..ca80e86b8b054 --- /dev/null +++ b/src/collections/_documentation/learn/drain-example/csharp.md @@ -0,0 +1,9 @@ +The .NET SDK automatically shuts down and waits `ShutdownTimeout` seconds before that happens +when the `Init`'s return value is disposed: + +```csharp +using (SentrySdk.Init(...)) +{ + // App code +} +``` From ecde8877178d3a72b94e669ddf69868b76598a4a Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Tue, 11 Sep 2018 14:29:23 +0200 Subject: [PATCH 054/171] doc: fix supported Python versions of sentry-python --- src/collections/_documentation/platforms/python/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/collections/_documentation/platforms/python/index.md b/src/collections/_documentation/platforms/python/index.md index 57b1ef677bbac..35d64c48ec8c1 100644 --- a/src/collections/_documentation/platforms/python/index.md +++ b/src/collections/_documentation/platforms/python/index.md @@ -3,8 +3,8 @@ title: Python sidebar_order: 3 --- -The [Sentry Python SDK](https://pypi.org/project/sentry-sdk) provides Sentry support -for Python 2.7 and 3.5 or later. +The [Sentry Python SDK](https://pypi.org/project/sentry-sdk) provides Sentry +support for Python 2.7 and 3.4 or later. The Python SDK follows the new unified SDK architecture. To get started have a look at the [quickstart]({% link _documentation/learn/quickstart.md From 9cefae81d5daafe6c45f1a2f87a04c77e96d67f4 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Tue, 11 Sep 2018 14:43:08 +0200 Subject: [PATCH 055/171] feat(python): Remove documentation for requests integration, mention requests in stdlib integration --- .../platforms/python/default-integrations.md | 5 +++++ .../_documentation/platforms/python/index.md | 1 - .../_documentation/platforms/python/requests.md | 17 ----------------- 3 files changed, 5 insertions(+), 18 deletions(-) delete mode 100644 src/collections/_documentation/platforms/python/requests.md diff --git a/src/collections/_documentation/platforms/python/default-integrations.md b/src/collections/_documentation/platforms/python/default-integrations.md index e306e6d8b6368..5392439955b7e 100644 --- a/src/collections/_documentation/platforms/python/default-integrations.md +++ b/src/collections/_documentation/platforms/python/default-integrations.md @@ -36,3 +36,8 @@ cause duplicate error logging in the Flask framework. The stdlib integration instruments certain modules in the standard library to emit breadcrumbs. This is enabled by default and rarely makes sense to disable. + +In detail it provides: + +* Breadcrumbs for HTTP requests done using `httplib`, which also includes + traffic going through `requests`. diff --git a/src/collections/_documentation/platforms/python/index.md b/src/collections/_documentation/platforms/python/index.md index 35d64c48ec8c1..9c5ecd29eb2d7 100644 --- a/src/collections/_documentation/platforms/python/index.md +++ b/src/collections/_documentation/platforms/python/index.md @@ -36,4 +36,3 @@ the following are supported: In addition to framework integrations there are also a few other integrations: * [Default integrations]({% link _documentation/platforms/python/default-integrations.md %}) -* [Requests integration]({% link _documentation/platforms/python/requests.md %}) diff --git a/src/collections/_documentation/platforms/python/requests.md b/src/collections/_documentation/platforms/python/requests.md deleted file mode 100644 index 216f4d682e178..0000000000000 --- a/src/collections/_documentation/platforms/python/requests.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Requests -sidebar_order: 4 ---- - -Import name: `sentry_sdk.integrations.requests.RequestsIntegration` - -When this integration is enabled HTTP requests emitted through the `requests` library -will be reported as breadcrumbs. This integration is not enabled by default and -needs to be enabled. - -```python -import sentry_sdk -from sentry_sdk.integrations.requests import RequestsIntegration - -sentry_sdk.init(integrations=[RequestsIntegration()]) -``` From 99bc8085ded0eb6a1e89d18134c69022f9c5c8a3 Mon Sep 17 00:00:00 2001 From: HazA Date: Tue, 11 Sep 2018 16:04:22 +0200 Subject: [PATCH 056/171] feat: Update showReportDialog --- .../learn/user-feedback-example/flask.md | 11 +++-- .../_documentation/learn/user-feedback.md | 2 + .../platforms/javascript/browser.md | 4 +- .../platforms/javascript/react.md | 44 ++++++++++++++++++- .../platforms/javascript/vue.md | 5 +++ 5 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/collections/_documentation/learn/user-feedback-example/flask.md b/src/collections/_documentation/learn/user-feedback-example/flask.md index 0abbcca35f529..94cd3abc39e07 100644 --- a/src/collections/_documentation/learn/user-feedback-example/flask.md +++ b/src/collections/_documentation/learn/user-feedback-example/flask.md @@ -13,15 +13,14 @@ And the template that brings up the dialog: {% raw %} ```html - + {% if sentry_event_id %} {% endif %} diff --git a/src/collections/_documentation/learn/user-feedback.md b/src/collections/_documentation/learn/user-feedback.md index 382e1505f69c7..cab7d55021108 100644 --- a/src/collections/_documentation/learn/user-feedback.md +++ b/src/collections/_documentation/learn/user-feedback.md @@ -27,6 +27,8 @@ An override for Sentry’s automatic language detection (e.g. `lang=de`) | Param | Default | | --- | --- | +| `eventId` | Manually set the id of the event. | +| `dsn` | Manually set dsn to report to. | | `lang` | _[automatic]_ – **override for Sentry’s language code** | | `title` | It looks like we’re having issues. | | `subtitle` | Our team has been notified. | diff --git a/src/collections/_documentation/platforms/javascript/browser.md b/src/collections/_documentation/platforms/javascript/browser.md index a914d3f0c66cf..74b68768bb273 100644 --- a/src/collections/_documentation/platforms/javascript/browser.md +++ b/src/collections/_documentation/platforms/javascript/browser.md @@ -46,9 +46,7 @@ The _Loader_ also provides a function called `forceLoad()` which does the same, {% endif %}{% endraw %} diff --git a/src/collections/_documentation/platforms/javascript/react.md b/src/collections/_documentation/platforms/javascript/react.md index 30404ce4c5463..36731bc0ac436 100644 --- a/src/collections/_documentation/platforms/javascript/react.md +++ b/src/collections/_documentation/platforms/javascript/react.md @@ -1 +1,43 @@ -TODO \ No newline at end of file +--- +title: React +sidebar_order: 30 +--- + +To use Sentry with your React application, you will need to use `@sentry/browser` (Sentry’s browser JavaScript SDK). +On its own, `@sentry/browser` will report any uncaught exceptions triggered from your application. + +If you’re using React 16 or above, Error Boundaries are an important tool for defining the behavior of your application in the face of errors. Be sure to send errors they catch to Sentry using `Sentry.captureException`, and optionally this is also a great opportunity to surface User Feedback + +```javascript +import * as Sentry from '@sentry/browser'; +// Sentry.init has to be called in the somewhere before + +class ExampleBoundary extends Component { + constructor(props) { + super(props); + this.state = { error: null }; + } + + componentDidCatch(error, errorInfo) { + this.setState({ error }); + Sentry.configureScope(scope => { + Object.keys(errorInfo).forEach(key => { + scope.setExtra(key, errorInfo[key]); + }); + }); + Sentry.captureException(error); + } + + render() { + if (this.state.error) { + //render fallback UI + return ( + Sentry.showReportDialog()}>Report feedback + ); + } else { + //when there's not an error, render children untouched + return this.props.children; + } + } +} +``` \ No newline at end of file diff --git a/src/collections/_documentation/platforms/javascript/vue.md b/src/collections/_documentation/platforms/javascript/vue.md index cf8622e2a596f..3d938a27fa951 100644 --- a/src/collections/_documentation/platforms/javascript/vue.md +++ b/src/collections/_documentation/platforms/javascript/vue.md @@ -3,6 +3,11 @@ title: Vue sidebar_order: 30 --- +To use Sentry with your Vue application, you will need to use `@sentry/browser` (Sentry’s browser JavaScript SDK). +On its own, `@sentry/browser` will report any uncaught exceptions triggered from your application. + +Additionally, the Vue _integration_ will capture the name and props state of the active component where the error was thrown. This is reported via Vue’s `config.errorHandler` hook. + ```javascript import * as Sentry from '@sentry/browser' From bffb70be8d5c2106c6db319c3d0bf1b823fd21c4 Mon Sep 17 00:00:00 2001 From: HazA Date: Tue, 11 Sep 2018 16:27:46 +0200 Subject: [PATCH 057/171] fix: Platform links --- .../learn/getting-started-config/cordova.md | 3 +- .../learn/getting-started-config/electron.md | 5 +- .../platforms/javascript/angularjs.md | 5 +- .../platforms/javascript/browser.md | 2 +- .../platforms/javascript/cordova.md | 90 ++++++++++++++++++- .../platforms/javascript/electron.md | 5 +- .../platforms/javascript/ember.md | 2 +- .../platforms/javascript/index.md | 2 +- .../platforms/javascript/node.md | 5 +- .../platforms/javascript/vue.md | 2 +- 10 files changed, 109 insertions(+), 12 deletions(-) diff --git a/src/collections/_documentation/learn/getting-started-config/cordova.md b/src/collections/_documentation/learn/getting-started-config/cordova.md index 5504e90095a10..38a4a974c593c 100644 --- a/src/collections/_documentation/learn/getting-started-config/cordova.md +++ b/src/collections/_documentation/learn/getting-started-config/cordova.md @@ -1,5 +1,4 @@ -You need to inform the sentry electron SDK about your CDN somewhere before -application startup: +You should `init` the SDK in the `deviceReady` function, to make sure the native integrations runs. For more details about Cordova [click here]({%- link _documentation/platforms/javascript/cordova.md -%}) ```javascript onDeviceReady: function() { diff --git a/src/collections/_documentation/learn/getting-started-config/electron.md b/src/collections/_documentation/learn/getting-started-config/electron.md index f17dd827e21bf..d279435f39590 100644 --- a/src/collections/_documentation/learn/getting-started-config/electron.md +++ b/src/collections/_documentation/learn/getting-started-config/electron.md @@ -1,7 +1,8 @@ -You need to inform the sentry electron SDK about your CDN somewhere before -application startup: +You need to call `init` in your `main` and every `renderer` process you spawn. +For more details about Electron [click here]({%- link _documentation/platforms/javascript/electron.md -%}) ```javascript import * as Sentry from '@sentry/electron'; + Sentry.init({dsn: '___PUBLIC_DSN___'}); ``` diff --git a/src/collections/_documentation/platforms/javascript/angularjs.md b/src/collections/_documentation/platforms/javascript/angularjs.md index 30404ce4c5463..22855082c9b25 100644 --- a/src/collections/_documentation/platforms/javascript/angularjs.md +++ b/src/collections/_documentation/platforms/javascript/angularjs.md @@ -1 +1,4 @@ -TODO \ No newline at end of file +--- +title: Angular +sidebar_order: 35 +--- \ No newline at end of file diff --git a/src/collections/_documentation/platforms/javascript/browser.md b/src/collections/_documentation/platforms/javascript/browser.md index 74b68768bb273..1603cee8ed273 100644 --- a/src/collections/_documentation/platforms/javascript/browser.md +++ b/src/collections/_documentation/platforms/javascript/browser.md @@ -1,6 +1,6 @@ --- title: Browser -sidebar_order: 2 +sidebar_order: 20 --- We recommend using our bundled CDN version for the browser as explained [here]({% link _documentation/learn/quickstart.md %}?platform=browser#pick-a-client-integration). diff --git a/src/collections/_documentation/platforms/javascript/cordova.md b/src/collections/_documentation/platforms/javascript/cordova.md index 30404ce4c5463..b1876cb4a4166 100644 --- a/src/collections/_documentation/platforms/javascript/cordova.md +++ b/src/collections/_documentation/platforms/javascript/cordova.md @@ -1 +1,89 @@ -TODO \ No newline at end of file +--- +title: Cordova +sidebar_order: 200 +--- + +This is the documentation for our Cordova SDK. The SDK uses a native extension for iOS and Android but will fall back to a pure JavaScript version (@sentry/browser) if needed. + +When you [install]({%- link _documentation/learn/quickstart.md -%}?platform=cordova) `sentry-cordova` +[Sentry Wizard](https://github.com/getsentry/sentry-wizard) will help you to configure your project. We also add a build step to your Xcode project to upload debug symbols we need to symbolicate iOS crashes. + +## Configuration + +You have to whitelist `sentry.io` in your `config.xml` like: + +> + +Keep in mind if you use an on-premise installation, adjust this domain accordingly. + +## iOS Specifics + +When you use Xcode you can hook directly into the build process to upload debug symbols. If you however are using bitcode you will need to disable the “Upload Debug Symbols to Sentry” build phase and then separately upload debug symbols from iTunes Connect to Sentry. + +## Run Script Phase + +{% capture __alert_content -%} +If the wizard ran successfully, it should have done setup all the necessary steps for you. You can still check if everything was setup correctly. +{%- endcapture -%} +{%- include components/alert.html + title="Note" + content=__alert_content +%} + +If you want to run the debug symbol upload during building your app. You can add this as a run script phase in Xcode. Also make sure to set the `DEBUG_INFORMATION_FORMAT` in your project settings to `DWARF and dSYM file`. + +> ```bash +> export SENTRY_PROPERTIES=sentry.properties +> function getProperty { +> PROP_KEY=$1 +> PROP_VALUE=`cat $SENTRY_PROPERTIES | grep "$PROP_KEY" | cut -d'=' -f2` +> echo $PROP_VALUE +> } +> if [ ! -f $SENTRY_PROPERTIES ]; then +> echo "warning: SENTRY: sentry.properties file not found! Skipping symbol upload." +> exit 0 +> fi +> echo "# Reading property from $SENTRY_PROPERTIES" +> SENTRY_CLI=$(getProperty "cli.executable") +> SENTRY_COMMAND="../../$SENTRY_CLI upload-dsym" +> $SENTRY_COMMAND +> ``` + +The next script makes sure that all unused architectures are strip from you binary when submitting the build to iTunes Connect. + +If you are getting an error while submitting your build to iTunes Connect, this script is probably missing. Also re-adding the plugin helped some people. +{% raw %} +```bash +# SENTRY_FRAMEWORK_PATCH +APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}" +find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK +do + FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable) + FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME" + echo "Executable is $FRAMEWORK_EXECUTABLE_PATH" + EXTRACTED_ARCHS=() + + for ARCH in $ARCHS + do + echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME" + lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH" + EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH") + done + + echo "Merging extracted architectures: ${ARCHS}" + lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}" + rm "${EXTRACTED_ARCHS[@]}" + echo "Replacing original executable with thinned version" + rm "$FRAMEWORK_EXECUTABLE_PATH" + mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH" +done +``` +{% endraw %} +{%- include components/alert.html + title="Note" + content=__alert_content +%} + +## Deep Dive + +- [Using Sentry with Ionic]({%- link _documentation/clients/cordova/ionic.md -%}) \ No newline at end of file diff --git a/src/collections/_documentation/platforms/javascript/electron.md b/src/collections/_documentation/platforms/javascript/electron.md index 30404ce4c5463..d1ef21756718a 100644 --- a/src/collections/_documentation/platforms/javascript/electron.md +++ b/src/collections/_documentation/platforms/javascript/electron.md @@ -1 +1,4 @@ -TODO \ No newline at end of file +--- +title: Electron +sidebar_order: 100 +--- diff --git a/src/collections/_documentation/platforms/javascript/ember.md b/src/collections/_documentation/platforms/javascript/ember.md index 2fe37e6e54534..fb1073b809c55 100644 --- a/src/collections/_documentation/platforms/javascript/ember.md +++ b/src/collections/_documentation/platforms/javascript/ember.md @@ -1,4 +1,4 @@ --- title: Ember -sidebar_order: 40 +sidebar_order: 50 --- diff --git a/src/collections/_documentation/platforms/javascript/index.md b/src/collections/_documentation/platforms/javascript/index.md index a0f79a7c1cc95..721af2f2de61d 100644 --- a/src/collections/_documentation/platforms/javascript/index.md +++ b/src/collections/_documentation/platforms/javascript/index.md @@ -1,6 +1,6 @@ --- title: JavaScript -sidebar_order: 20 +sidebar_order: 10 --- All our JavaScript related SDKs provide the same API still there are some differences between them diff --git a/src/collections/_documentation/platforms/javascript/node.md b/src/collections/_documentation/platforms/javascript/node.md index 30404ce4c5463..c66512440872c 100644 --- a/src/collections/_documentation/platforms/javascript/node.md +++ b/src/collections/_documentation/platforms/javascript/node.md @@ -1 +1,4 @@ -TODO \ No newline at end of file +--- +title: Node +sidebar_order: 70 +--- diff --git a/src/collections/_documentation/platforms/javascript/vue.md b/src/collections/_documentation/platforms/javascript/vue.md index 3d938a27fa951..946d8e4bce744 100644 --- a/src/collections/_documentation/platforms/javascript/vue.md +++ b/src/collections/_documentation/platforms/javascript/vue.md @@ -1,6 +1,6 @@ --- title: Vue -sidebar_order: 30 +sidebar_order: 40 --- To use Sentry with your Vue application, you will need to use `@sentry/browser` (Sentry’s browser JavaScript SDK). From a8750f7f90ffc598d35883632ece26a04a4ebb15 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Tue, 11 Sep 2018 19:17:09 +0200 Subject: [PATCH 058/171] feat: Add Rust and Actix-Web to platform index --- src/_data/platform_icons.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/_data/platform_icons.yml b/src/_data/platform_icons.yml index bbc22fe78ef62..5efa2c040965c 100644 --- a/src/_data/platform_icons.yml +++ b/src/_data/platform_icons.yml @@ -49,3 +49,11 @@ - name: Celery link: _documentation/platforms/python/celery.md platformicon: python + +- name: Rust + link: _documentation/platforms/rust/index.md + platformicon: rust + +- name: Actix-Web + link: _documentation/platforms/rust/actix.md + platformicon: rust From ef0b4d43ecc4fee2528640f3f2d4466cbf014bdd Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Tue, 11 Sep 2018 19:40:21 +0200 Subject: [PATCH 059/171] feat(rust): Add examples to learn/context --- src/collections/_documentation/learn/set-extra/rust.md | 5 +++++ src/collections/_documentation/learn/set-tag/rust.md | 5 +++++ src/collections/_documentation/learn/set-user/rust.md | 8 ++++++++ 3 files changed, 18 insertions(+) create mode 100644 src/collections/_documentation/learn/set-extra/rust.md create mode 100644 src/collections/_documentation/learn/set-tag/rust.md create mode 100644 src/collections/_documentation/learn/set-user/rust.md diff --git a/src/collections/_documentation/learn/set-extra/rust.md b/src/collections/_documentation/learn/set-extra/rust.md new file mode 100644 index 0000000000000..2c5531e76e9d7 --- /dev/null +++ b/src/collections/_documentation/learn/set-extra/rust.md @@ -0,0 +1,5 @@ +```rust +sentry::configure_scope(|scope| { + scope.set_extra("{{ page.example_extra_key }}", "{{ page.example_extra_value }}".to_owned().into()); +}); +``` diff --git a/src/collections/_documentation/learn/set-tag/rust.md b/src/collections/_documentation/learn/set-tag/rust.md new file mode 100644 index 0000000000000..a082389b62d86 --- /dev/null +++ b/src/collections/_documentation/learn/set-tag/rust.md @@ -0,0 +1,5 @@ +```rust +sentry::configure_scope(|scope| { + scope.set_tag("{{ page.example_tag_name }}", "{{ page.example_tag_value }}"); +}); +``` diff --git a/src/collections/_documentation/learn/set-user/rust.md b/src/collections/_documentation/learn/set-user/rust.md new file mode 100644 index 0000000000000..25aa660163e3c --- /dev/null +++ b/src/collections/_documentation/learn/set-user/rust.md @@ -0,0 +1,8 @@ +```rust +sentry::configure_scope(|scope| { + scope.set_user(Some(sentry::User { + email: "{{ page.example_user_email }}".to_owned() + ..Default::default() + })); +}); +``` From e202d4ad3389ce0f8536a1b049bd10011c0c6213 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Tue, 11 Sep 2018 19:41:07 +0200 Subject: [PATCH 060/171] fix(python): Fix syntax error in example --- src/collections/_documentation/learn/set-extra/python.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/collections/_documentation/learn/set-extra/python.md b/src/collections/_documentation/learn/set-extra/python.md index c0a5e54708fc9..09fd84a10843b 100644 --- a/src/collections/_documentation/learn/set-extra/python.md +++ b/src/collections/_documentation/learn/set-extra/python.md @@ -2,5 +2,5 @@ from sentry_sdk import configure_scope with configure_scope() as scope: - scope.set_extra({"{{ page.example_extra_key }}": "{{ page.example_extra_value }}") + scope.set_extra("{{ page.example_extra_key }}", "{{ page.example_extra_value }}") ``` From 3111467563487ccc4f5b66303025f9833c2dda34 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Tue, 11 Sep 2018 19:47:05 +0200 Subject: [PATCH 061/171] feat(rust): Add example for setting environment --- .../_documentation/learn/set-environment/rust.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/collections/_documentation/learn/set-environment/rust.md diff --git a/src/collections/_documentation/learn/set-environment/rust.md b/src/collections/_documentation/learn/set-environment/rust.md new file mode 100644 index 0000000000000..3aae4f67fd0b3 --- /dev/null +++ b/src/collections/_documentation/learn/set-environment/rust.md @@ -0,0 +1,6 @@ +```rust +sentry::init(sentry::ClientOptions { + environment: Some("{{ page.example_environment }}".into()), + ..Default::default() +}); +``` From b12da825edf455c6fe378618edce3fc4c3dccba1 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Tue, 11 Sep 2018 20:05:05 +0200 Subject: [PATCH 062/171] feat(rust): Add example for setting fingerprint --- src/collections/_documentation/learn/set-fingerprint/rust.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/collections/_documentation/learn/set-fingerprint/rust.md diff --git a/src/collections/_documentation/learn/set-fingerprint/rust.md b/src/collections/_documentation/learn/set-fingerprint/rust.md new file mode 100644 index 0000000000000..0e90846dd82aa --- /dev/null +++ b/src/collections/_documentation/learn/set-fingerprint/rust.md @@ -0,0 +1,5 @@ +```rust +sentry::configure_scope(|scope| { + scope.set_fingerprint(Some(&["my-view-function"])); +}); +``` From 49a6072382b1fcbee55df961691331afa3c8048f Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Tue, 11 Sep 2018 20:23:06 +0200 Subject: [PATCH 063/171] feat(rust): Add example for before_send --- .../_documentation/learn/before-send/rust.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/collections/_documentation/learn/before-send/rust.md diff --git a/src/collections/_documentation/learn/before-send/rust.md b/src/collections/_documentation/learn/before-send/rust.md new file mode 100644 index 0000000000000..4fab9a7fd98a9 --- /dev/null +++ b/src/collections/_documentation/learn/before-send/rust.md @@ -0,0 +1,10 @@ +```rust +sentry::init(sentry::ClientOptions { + before_send: Some(Arc::new(Box::new(|mut event| { + // Modify event here + event.server_name = None; // Don't send server name + Some(event) + }))), + ..Default::default() +}); +``` From 56c1826b1801b6c3ce4342e5add9abe0c8b1cc41 Mon Sep 17 00:00:00 2001 From: Cameron McEfee Date: Tue, 11 Sep 2018 13:19:16 -0700 Subject: [PATCH 064/171] ref: make Platform related content use the event system --- src/_js/lib/PlatformContent.js | 31 ++++++++++--------------------- src/_js/main.js | 3 +-- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/src/_js/lib/PlatformContent.js b/src/_js/lib/PlatformContent.js index 5b64bce3664ba..c74de8ab36030 100644 --- a/src/_js/lib/PlatformContent.js +++ b/src/_js/lib/PlatformContent.js @@ -47,16 +47,6 @@ const updateUrlPlatform = function(url, slug) { return `${origin}?${qs.stringify(query)}`; }; -const initRelatedElements = function() { - $('.config-key').each(function() { - this.setAttribute('data-config-key', $(this).text()); - }); - - $('.unsupported').each(function() { - $('
').prependTo(this); - }); -}; - const syncRelatedElements = function() { let platform = window.platformData[window.activePlatform]; let style = platform && platform.case_style || 'canonical'; @@ -144,6 +134,16 @@ const showPlatform = function(slug) { }); history.replaceState({}, '', updateUrlPlatform(location.href, slug)); + + $('.config-key').each(function() { + this.setAttribute('data-config-key', $(this).text()); + }); + + $('.unsupported-hint').remove(); + $('.unsupported').each(function() { + $('
').prependTo(this); + }); + syncRelatedElements(); }; @@ -156,14 +156,3 @@ $(document).on('page.didUpdate', function(event) { // Update the preferredPlatform based on the url. showPlatform(qs.parse(location.search).platform); }); - -// Attach event listeners and set UI state based on the platform supplied via -// query param, stored in localStorage as the preferred platform, or the -// default platform, in that order. -// -// Returns nothing. -const init = function() { - initRelatedElements(); -}; - -export default { init }; diff --git a/src/_js/main.js b/src/_js/main.js index 07d6a7a640718..1d8d1d835f0a9 100644 --- a/src/_js/main.js +++ b/src/_js/main.js @@ -1,11 +1,11 @@ import Raven from 'raven-js'; import 'bootstrap'; -import PlatformContent from './lib/PlatformContent'; import UserContent from './lib/UserContent'; import Tracking from './lib/Tracking'; import User from './lib/User'; import DynamicLoad from './lib/DynamicLoad'; import Search from './lib/Search'; +import './lib/PlatformContent'; import './lib/HeaderLinker'; import './lib/Feedback'; import './lib/Sidebar'; @@ -24,7 +24,6 @@ $(document).on('page.didUpdate', function(event) { }); $(function() { - PlatformContent.init(); UserContent.init(); Tracking.init(); Search.init(); From f295d26cde3bc144afb392d8d83399a42b8e9feb Mon Sep 17 00:00:00 2001 From: Cameron McEfee Date: Tue, 11 Sep 2018 13:50:42 -0700 Subject: [PATCH 065/171] Remove "new" category template --- src/_includes/sidebar.html | 2 +- src/_includes/sidebar/LEGACY_category.html | 17 ----------------- src/_includes/sidebar/category.html | 10 ++++------ 3 files changed, 5 insertions(+), 24 deletions(-) delete mode 100644 src/_includes/sidebar/LEGACY_category.html diff --git a/src/_includes/sidebar.html b/src/_includes/sidebar.html index 6e55c06d3bd45..a9f7e7ad498d3 100644 --- a/src/_includes/sidebar.html +++ b/src/_includes/sidebar.html @@ -23,7 +23,7 @@ {% include sidebar/tree.html data=__tree - templates="LEGACY_category,default" + templates="category,default" categories=site.data.documentation_categories is_category=true %} diff --git a/src/_includes/sidebar/LEGACY_category.html b/src/_includes/sidebar/LEGACY_category.html deleted file mode 100644 index 236dbcaf99a80..0000000000000 --- a/src/_includes/sidebar/LEGACY_category.html +++ /dev/null @@ -1,17 +0,0 @@ -{%- assign __category = include.categories - | where: 'slug', include.slug - | first --%} -{%- if include.document -%} - -
- {{- __category.title -}} -
-
-{%- else -%} - -{%- endif -%} diff --git a/src/_includes/sidebar/category.html b/src/_includes/sidebar/category.html index ce6c2e42f24c8..236dbcaf99a80 100644 --- a/src/_includes/sidebar/category.html +++ b/src/_includes/sidebar/category.html @@ -3,16 +3,14 @@ | first -%} {%- if include.document -%} - - {% include /svg/{{ __category.icon }}.svg %} -
+ +
{{- __category.title -}}
{%- else -%} - From 7d56237b02843630f495f2209e2cdf53ecb6ab04 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Wed, 12 Sep 2018 10:59:18 +0200 Subject: [PATCH 076/171] feat: honor sidebar relocations in breadcrumbs --- src/_includes/breadcrumbs.html | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/_includes/breadcrumbs.html b/src/_includes/breadcrumbs.html index 5bc081b42a524..f5e7b1544fc09 100644 --- a/src/_includes/breadcrumbs.html +++ b/src/_includes/breadcrumbs.html @@ -14,6 +14,23 @@ | where: "url", __url | first -%} + {%- assign __next_segment = __path[forloop.index] %} + {%- if __next_segment %} + {%- assign __next_url = __url | append: __next_segment | append: '/' %} + {%- assign __next_page = site.pages | concat: site.documentation + | where: "url", __next_url + | first + -%} + {%- else %} + {%- assign __next_page = page %} + {%- endif %} + {%- if __next_page and __next_page.sidebar_relocation %} + {%- assign __relocation_url = __slugs | pop | push: __next_page.sidebar_relocation | join: '/' | append: '/' %} + {%- assign __page = site.pages | concat: site.documentation + | where: "url", __relocation_url + | first + -%} + {%- endif %} {%- if __page -%} {%- else -%} From b69c781123c7cbb28067995c64677c145d59c7b5 Mon Sep 17 00:00:00 2001 From: HazA Date: Wed, 12 Sep 2018 11:48:03 +0200 Subject: [PATCH 077/171] feat: Add ember docs --- nginx.conf | 4 + .../_documentation/clients/cordova/index.md | 140 ------------------ .../platforms/javascript/angularjs.md | 37 ++++- .../platforms/javascript/cordova.md | 4 - .../platforms/javascript/ember.md | 28 ++++ .../cordova => platforms/javascript}/ionic.md | 3 +- .../platforms/javascript/vue.md | 2 + 7 files changed, 72 insertions(+), 146 deletions(-) delete mode 100644 src/collections/_documentation/clients/cordova/index.md rename src/collections/_documentation/{clients/cordova => platforms/javascript}/ionic.md (98%) diff --git a/nginx.conf b/nginx.conf index df8e42214a523..be87687e3d84a 100644 --- a/nginx.conf +++ b/nginx.conf @@ -18,6 +18,10 @@ server { location = /clients/rust/ { return 302 /platforms/rust/$is_args$args; } + + location = /clients/cordova/ { + return 302 /platforms/cordova/$is_args$args; + } location = /clients/minidump/ { return 302 /platforms/minidump/$is_args$args; diff --git a/src/collections/_documentation/clients/cordova/index.md b/src/collections/_documentation/clients/cordova/index.md deleted file mode 100644 index 365a10631081e..0000000000000 --- a/src/collections/_documentation/clients/cordova/index.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: Cordova -sidebar_order: 2 ---- - -This is the documentation for our Cordova SDK. The SDK uses a native extension for iOS and Android but will fall back to a pure JavaScript version (@sentry/browser) if needed. - -## Installation - -Start by adding Sentry and then linking it: - -```bash -$ cordova plugin add sentry-cordova -``` - -[Sentry Wizard](https://github.com/getsentry/sentry-wizard) will help you to configure your project. We also add a build step to your Xcode project to upload debug symbols we need to symbolicate iOS crashes. - -## Configuration - -You have to whitelist `sentry.io` in your `config.xml` like: - -> - -Keep in mind if you use an on-premise installation, adjust this domain accordingly. - -This example shows the bare minimum for a plain Cordova project. Add this to you _index.js_: - -```javascript -onDeviceReady: function() { - ... - var Sentry = cordova.require("sentry-cordova.Sentry"); - Sentry.init({ dsn: '___PUBLIC_DSN___' }); - ... -} -``` - -This will setup the Client for native and JavaScript crashes. If you minify or bundle your code we need your sourcemap files in order to symbolicate JavaScript errors, please see: [JavaScript sourcemaps]({%- link _documentation/clients/javascript/sourcemaps.md -%}) for more details. - -## Usage - -- capturing messages and error: - - ```javascript - Sentry.captureMessage('message'); - try { - myFailingFunction(); - } catch (e) { - Sentry.captureException(e); - } - ``` - -Note that we will track unhandled errors and promises by default. - -- adding breadcrumbs: - - ```javascript - Sentry.addBreadcrumb({ message: 'message' }); - ``` -- context handling: - - ```javascript - Sentry.configureScope(scope => { - scope.setUser({ id: '123', email: 'test@sentry.io', username: 'sentry' }); - scope.setTag('cordova', 'true'); - scope.setExtra('myData', ['1', 2, '3']); - }); - ``` - -## iOS Specifics - -When you use Xcode you can hook directly into the build process to upload debug symbols. If you however are using bitcode you will need to disable the “Upload Debug Symbols to Sentry” build phase and then separately upload debug symbols from iTunes Connect to Sentry. - -## Run Script Phase - -{% capture __alert_content -%} -If the wizard ran successfully, it should have done setup all the necessary steps for you. You can still check if everything was setup correctly. -{%- endcapture -%} -{%- include components/alert.html - title="Note" - content=__alert_content -%} - -If you want to run the debug symbol upload during building your app. You can add this as a run script phase in Xcode. Also make sure to set the `DEBUG_INFORMATION_FORMAT` in your project settings to `DWARF and dSYM file`. - -> ```bash -> export SENTRY_PROPERTIES=sentry.properties -> function getProperty { -> PROP_KEY=$1 -> PROP_VALUE=`cat $SENTRY_PROPERTIES | grep "$PROP_KEY" | cut -d'=' -f2` -> echo $PROP_VALUE -> } -> if [ ! -f $SENTRY_PROPERTIES ]; then -> echo "warning: SENTRY: sentry.properties file not found! Skipping symbol upload." -> exit 0 -> fi -> echo "# Reading property from $SENTRY_PROPERTIES" -> SENTRY_CLI=$(getProperty "cli.executable") -> SENTRY_COMMAND="../../$SENTRY_CLI upload-dsym" -> $SENTRY_COMMAND -> ``` - -The next script makes sure that all unnes architectures are strip from you binary when submitting the build to iTunes Connect. - -{% capture __alert_content -%} -If you are getting an error while submitting your build to iTunes Connect, this script is probably missing. Also readding the plugin helped some people. - -```bash -# SENTRY_FRAMEWORK_PATCH -APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}" -find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK -do - FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable) - FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME" - echo "Executable is $FRAMEWORK_EXECUTABLE_PATH" - EXTRACTED_ARCHS=() - - for ARCH in $ARCHS - do - echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME" - lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH" - EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH") - done - - echo "Merging extracted architectures: ${ARCHS}" - lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}" - rm "${EXTRACTED_ARCHS[@]}" - echo "Replacing original executable with thinned version" - rm "$FRAMEWORK_EXECUTABLE_PATH" - mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH" -done -``` -{%- endcapture -%} -{%- include components/alert.html - title="Note" - content=__alert_content -%} - -## Deep Dive - -- [Using Sentry with Ionic]({%- link _documentation/clients/cordova/ionic.md -%}) diff --git a/src/collections/_documentation/platforms/javascript/angularjs.md b/src/collections/_documentation/platforms/javascript/angularjs.md index 22855082c9b25..642f5d55299e6 100644 --- a/src/collections/_documentation/platforms/javascript/angularjs.md +++ b/src/collections/_documentation/platforms/javascript/angularjs.md @@ -1,4 +1,39 @@ --- title: Angular sidebar_order: 35 ---- \ No newline at end of file +--- + +This document uses Angular to refer to Angular 2+. On its own, `@sentry/browser` will report any uncaught exceptions triggered from your application. + +Additionally, `@sentry/browser` can be configured to catch any Angular-specific (2.x) exceptions reported through the [@angular/core/ErrorHandler](https://angular.io/api/core/ErrorHandler) component. + +```typescript +import { BrowserModule } from "@angular/platform-browser"; +import { NgModule, ErrorHandler, Injectable } from "@angular/core"; + +import { AppComponent } from "./app.component"; + +import * as Sentry from "@sentry/browser"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___" +}); + +@Injectable() +class SentryErrorHandler implements ErrorHandler { + constructor() {} + handleError(error) { + Sentry.captureException(error.originalError || error); + throw error; + } +} + +@NgModule({ + declarations: [AppComponent], + imports: [BrowserModule], + providers: [{ provide: ErrorHandler, useClass: SentryErrorHandler }], + bootstrap: [AppComponent] +}) + +export class AppModule {} +``` \ No newline at end of file diff --git a/src/collections/_documentation/platforms/javascript/cordova.md b/src/collections/_documentation/platforms/javascript/cordova.md index 10e6627c66a93..62639926b62e2 100644 --- a/src/collections/_documentation/platforms/javascript/cordova.md +++ b/src/collections/_documentation/platforms/javascript/cordova.md @@ -86,7 +86,3 @@ done title="Note" content=__alert_content %} - -## Deep Dive - -- [Using Sentry with Ionic]({%- link _documentation/clients/cordova/ionic.md -%}) \ No newline at end of file diff --git a/src/collections/_documentation/platforms/javascript/ember.md b/src/collections/_documentation/platforms/javascript/ember.md index fb1073b809c55..146dae7dc40be 100644 --- a/src/collections/_documentation/platforms/javascript/ember.md +++ b/src/collections/_documentation/platforms/javascript/ember.md @@ -2,3 +2,31 @@ title: Ember sidebar_order: 50 --- + +To use Sentry with your Ember application, you will need to use `@sentry/browser` (Sentry’s browser JavaScript SDK). +On its own, `@sentry/browser` will report any uncaught exceptions triggered from your application. +Also, you need to install `ember-cli-cjs-transform` with `ember install ember-cli-cjs-transform`. + +Add this to your `ember-cli-build.js` file: + +```javascript +app.import('node_modules/@sentry/browser/dist/index.js', { + using: [ + { transformation: 'cjs', as: '@sentry/browser' } + ] +}); +``` + +Then add this to your `app.js`: + +```javascript +import * as Sentry from '@sentry/browser' + +Sentry.init({ + dsn: '___PUBLIC_DSN___', + integrations (integrations) { + integrations.push(new Sentry.Integrations.Ember()) + return integrations + } +}); +``` diff --git a/src/collections/_documentation/clients/cordova/ionic.md b/src/collections/_documentation/platforms/javascript/ionic.md similarity index 98% rename from src/collections/_documentation/clients/cordova/ionic.md rename to src/collections/_documentation/platforms/javascript/ionic.md index e43aa715bbcac..035ff998d0543 100644 --- a/src/collections/_documentation/clients/cordova/ionic.md +++ b/src/collections/_documentation/platforms/javascript/ionic.md @@ -1,5 +1,6 @@ --- -title: 'Using Sentry with Ionic' +title: Ionic +sidebar_order: 201 --- To use Sentry with [Ionic](https://ionicframework.com/) you have to add _sentry-cordova_ as a depenendcy to you package.json. diff --git a/src/collections/_documentation/platforms/javascript/vue.md b/src/collections/_documentation/platforms/javascript/vue.md index 946d8e4bce744..98be81a4199b9 100644 --- a/src/collections/_documentation/platforms/javascript/vue.md +++ b/src/collections/_documentation/platforms/javascript/vue.md @@ -8,6 +8,8 @@ On its own, `@sentry/browser` will report any uncaught exceptions triggered from Additionally, the Vue _integration_ will capture the name and props state of the active component where the error was thrown. This is reported via Vue’s `config.errorHandler` hook. +Passing in `Vue` is optional, if you not pass it `window.Vue` has to be present. + ```javascript import * as Sentry from '@sentry/browser' From ef67fcbd7cfca0235f49311ead4c9c18f7f2e846 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Wed, 12 Sep 2018 12:08:27 +0200 Subject: [PATCH 078/171] ref: Move some product guides into separate section in the docs --- nginx.conf | 4 ++++ src/_data/documentation_categories.yml | 3 +++ src/collections/_documentation/integrations/github.md | 2 +- src/collections/_documentation/integrations/splunk.md | 2 +- src/collections/_documentation/learn/releases.md | 2 +- .../_documentation/{learn => product}/data-forwarding.md | 0 .../_documentation/{learn => product}/issue-owners.md | 0 .../_documentation/{learn => product}/membership.md | 0 .../_documentation/{learn => product}/notifications.md | 0 src/collections/_documentation/{learn => product}/pricing.md | 0 src/collections/_documentation/{learn => product}/sso.md | 0 11 files changed, 10 insertions(+), 3 deletions(-) rename src/collections/_documentation/{learn => product}/data-forwarding.md (100%) rename src/collections/_documentation/{learn => product}/issue-owners.md (100%) rename src/collections/_documentation/{learn => product}/membership.md (100%) rename src/collections/_documentation/{learn => product}/notifications.md (100%) rename src/collections/_documentation/{learn => product}/pricing.md (100%) rename src/collections/_documentation/{learn => product}/sso.md (100%) diff --git a/nginx.conf b/nginx.conf index be87687e3d84a..461f72be8bafb 100644 --- a/nginx.conf +++ b/nginx.conf @@ -27,6 +27,10 @@ server { return 302 /platforms/minidump/$is_args$args; } + location = /learn/(data-forwarding|issue-owners|membership|notifications|pricing|sso)/ { + return 302 /product/$1/$is_args$args; + } + location = /clients/javascript/integrations/angular2/ { return 302 /clients/javascript/integrations/angular/$is_args$args; } diff --git a/src/_data/documentation_categories.yml b/src/_data/documentation_categories.yml index 1efdbff52f345..53bbf1e4f0926 100644 --- a/src/_data/documentation_categories.yml +++ b/src/_data/documentation_categories.yml @@ -6,6 +6,9 @@ - title: Learn slug: learn +- title: Product Guides + slug: product + - title: Platforms slug: platforms diff --git a/src/collections/_documentation/integrations/github.md b/src/collections/_documentation/integrations/github.md index 9ee67979776f1..fbb6c41c0d3d5 100644 --- a/src/collections/_documentation/integrations/github.md +++ b/src/collections/_documentation/integrations/github.md @@ -53,4 +53,4 @@ When Sentry sees this, we’ll automatically annotate the matching issue with a ## GitHub SSO -[Enable Single Sign-on]({%- link _documentation/learn/sso.md -%}) +[Enable Single Sign-on]({%- link _documentation/product/sso.md -%}) diff --git a/src/collections/_documentation/integrations/splunk.md b/src/collections/_documentation/integrations/splunk.md index c9c68a482639e..ee821f430140c 100644 --- a/src/collections/_documentation/integrations/splunk.md +++ b/src/collections/_documentation/integrations/splunk.md @@ -3,7 +3,7 @@ title: Splunk sidebar_order: 8 --- -Connect Splunk to Sentry with the [Data Forwarding]({%- link _documentation/learn/data-forwarding.md -%}) feature. +Connect Splunk to Sentry with the [Data Forwarding]({%- link _documentation/product/data-forwarding.md -%}) feature. {% capture __alert_content -%} See the [Splunk documentation](http://dev.splunk.com/view/event-collector/SP-CAAAE7F) for specific details on your Splunk installation. diff --git a/src/collections/_documentation/learn/releases.md b/src/collections/_documentation/learn/releases.md index 262fb3bc73970..bc699b9dc85cc 100644 --- a/src/collections/_documentation/learn/releases.md +++ b/src/collections/_documentation/learn/releases.md @@ -146,7 +146,7 @@ res = requests.post( For more information, see the [API reference]({%- link _documentation/api/releases/post-organization-releases.md -%}). -After this step, **suspect commits** and **suggested assignees** will start appearing on the issue page. We determine these by tying together the commits in the release, files touched by those commits, files observed in the stack trace, authors of those files, and [ownership rules]({%- link _documentation/learn/issue-owners.md -%}). +After this step, **suspect commits** and **suggested assignees** will start appearing on the issue page. We determine these by tying together the commits in the release, files touched by those commits, files observed in the stack trace, authors of those files, and [ownership rules]({%- link _documentation/product/issue-owners.md -%}). {% asset suspect-commits-highlighted.png %} diff --git a/src/collections/_documentation/learn/data-forwarding.md b/src/collections/_documentation/product/data-forwarding.md similarity index 100% rename from src/collections/_documentation/learn/data-forwarding.md rename to src/collections/_documentation/product/data-forwarding.md diff --git a/src/collections/_documentation/learn/issue-owners.md b/src/collections/_documentation/product/issue-owners.md similarity index 100% rename from src/collections/_documentation/learn/issue-owners.md rename to src/collections/_documentation/product/issue-owners.md diff --git a/src/collections/_documentation/learn/membership.md b/src/collections/_documentation/product/membership.md similarity index 100% rename from src/collections/_documentation/learn/membership.md rename to src/collections/_documentation/product/membership.md diff --git a/src/collections/_documentation/learn/notifications.md b/src/collections/_documentation/product/notifications.md similarity index 100% rename from src/collections/_documentation/learn/notifications.md rename to src/collections/_documentation/product/notifications.md diff --git a/src/collections/_documentation/learn/pricing.md b/src/collections/_documentation/product/pricing.md similarity index 100% rename from src/collections/_documentation/learn/pricing.md rename to src/collections/_documentation/product/pricing.md diff --git a/src/collections/_documentation/learn/sso.md b/src/collections/_documentation/product/sso.md similarity index 100% rename from src/collections/_documentation/learn/sso.md rename to src/collections/_documentation/product/sso.md From 36ef5ebbbb48b2d1d03ce569d419f9dc84c83fa2 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Wed, 12 Sep 2018 12:11:56 +0200 Subject: [PATCH 079/171] feat: Added key dropdowns to csp --- src/_js/lib/User.js | 2 +- .../_documentation/learn/security-policy-reporting.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/_js/lib/User.js b/src/_js/lib/User.js index 9c363ef68e800..6193759508ecd 100644 --- a/src/_js/lib/User.js +++ b/src/_js/lib/User.js @@ -104,7 +104,7 @@ const constructDSNObject = function(project = {}) { id: project.id || -1, group: escape(project.organizationName) || 'Example', PROJECT_NAME: escape(formatProjectLabel(project)) || 'Your Project', - PROJECT_ID: escape(project.projectSlug) || 'your-project', + PROJECT_ID: escape(project.projectSlug) || '', ORG_NAME: escape(project.organizationSlug) || 'your-org', DSN: formatDsn(dsn, { public: false }), PUBLIC_DSN: formatDsn(dsn, { public: true }), diff --git a/src/collections/_documentation/learn/security-policy-reporting.md b/src/collections/_documentation/learn/security-policy-reporting.md index b4b3eb4ae5841..49f8c305f50ac 100644 --- a/src/collections/_documentation/learn/security-policy-reporting.md +++ b/src/collections/_documentation/learn/security-policy-reporting.md @@ -14,13 +14,13 @@ The integration process consists of configuring the the appropriate header with To configure CSP reports in Sentry, you’ll need to send a header from your server describing your policy, as well specifying the authenticated Sentry endpoint: ``` -Content-Security-Policy: ...; report-uri https://sentry.io/api//security/?sentry_key= +Content-Security-Policy: ...; report-uri https://sentry.io/api/___PROJECT_ID___/security/?sentry_key=___PUBLIC_KEY___ ``` Alternatively you can setup CSP reports to simply send reports rather than actually enforcing the policy: ``` -Content-Security-Policy-Report-Only: ...; report-uri https://sentry.io/api//security/?sentry_key= +Content-Security-Policy-Report-Only: ...; report-uri https://sentry.io/api/___PROJECT_ID___/security/?sentry_key=___PUBLIC_KEY___ ``` For more information, see the article on [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy). @@ -32,7 +32,7 @@ For more information, see the article on [MDN](https://developer.mozilla.org/en- To configure reports in Sentry, you’ll need to configure the Expect-CT a header from your server: ``` -Expect-CT: ..., report-uri="https://sentry.io/api//security/?sentry_key=" +Expect-CT: ..., report-uri="https://sentry.io/api/___PROJECT_ID___/security/?sentry_key=___PUBLIC_KEY___" ``` For more information, see the article on [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect-CT). @@ -44,7 +44,7 @@ For more information, see the article on [MDN](https://developer.mozilla.org/en- To configure HPKP reports in Sentry, you’ll need to send a header from your server describing your policy, as well specifying the authenticated Sentry endpoint: ``` -Public-Key-Pins: ...; report-uri="https://sentry.io/api//security/?sentry_key=" +Public-Key-Pins: ...; report-uri="https://sentry.io/api/___PROJECT_ID___/security/?sentry_key=___PUBLIC_KEY___" ``` For more information, see the article on [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Public_Key_Pinning). From fe8aa4dcc48e1338d056776e4dc374758b88134d Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Wed, 12 Sep 2018 12:16:03 +0200 Subject: [PATCH 080/171] ref: Move search page to product --- nginx.conf | 2 +- src/collections/_documentation/{learn => product}/search.md | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/collections/_documentation/{learn => product}/search.md (100%) diff --git a/nginx.conf b/nginx.conf index 461f72be8bafb..447595a7a7eb1 100644 --- a/nginx.conf +++ b/nginx.conf @@ -27,7 +27,7 @@ server { return 302 /platforms/minidump/$is_args$args; } - location = /learn/(data-forwarding|issue-owners|membership|notifications|pricing|sso)/ { + location = /learn/(data-forwarding|issue-owners|membership|notifications|pricing|sso|search)/ { return 302 /product/$1/$is_args$args; } diff --git a/src/collections/_documentation/learn/search.md b/src/collections/_documentation/product/search.md similarity index 100% rename from src/collections/_documentation/learn/search.md rename to src/collections/_documentation/product/search.md From 0d5350ed093d1ad2c1d4018c498b1cbc0314bcea Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Wed, 12 Sep 2018 12:16:53 +0200 Subject: [PATCH 081/171] ref: Move quotas --- nginx.conf | 2 +- src/collections/_documentation/{learn => product}/quotas.md | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/collections/_documentation/{learn => product}/quotas.md (100%) diff --git a/nginx.conf b/nginx.conf index 447595a7a7eb1..a5d0f607fdfc4 100644 --- a/nginx.conf +++ b/nginx.conf @@ -27,7 +27,7 @@ server { return 302 /platforms/minidump/$is_args$args; } - location = /learn/(data-forwarding|issue-owners|membership|notifications|pricing|sso|search)/ { + location = /learn/(data-forwarding|issue-owners|membership|notifications|pricing|sso|search|quotas)/ { return 302 /product/$1/$is_args$args; } diff --git a/src/collections/_documentation/learn/quotas.md b/src/collections/_documentation/product/quotas.md similarity index 100% rename from src/collections/_documentation/learn/quotas.md rename to src/collections/_documentation/product/quotas.md From d177079bb419f5c02b87e94fd9283ab2e9bb5a48 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Wed, 12 Sep 2018 12:18:12 +0200 Subject: [PATCH 082/171] fix: Fixed a bad reference --- src/collections/_documentation/product/pricing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/collections/_documentation/product/pricing.md b/src/collections/_documentation/product/pricing.md index e866e0c54ca9e..3a44134095808 100644 --- a/src/collections/_documentation/product/pricing.md +++ b/src/collections/_documentation/product/pricing.md @@ -57,7 +57,7 @@ Large and Enterprise plans have the option to configure rate limits for each pro If your projects have a high volume of events, you can control how many errors Sentry receives in a few ways: - Within the SDK you can reduce the data volume you’re sending by sampling. -- Turn on [Inbound Filters]({%- link _documentation/learn/quotas.md -%}#inbound-data-filters) for legacy browsers, browser extensions, localhost, and web crawlers. Any filtered events will not count towards your quota. +- Turn on [Inbound Filters]({%- link _documentation/product/quotas.md -%}#inbound-data-filters) for legacy browsers, browser extensions, localhost, and web crawlers. Any filtered events will not count towards your quota. - For JavaScript projects, use _whitelistUrls_ and _ignoreErrors_ - With the Large and Enterprise plans, you’ll be able to set a per-key rate limit for each DSN key in a project at **[Organization] » [Project] » Project Settings » Client Keys (DSN) » Details**. This rate limit is set as number of events to accept during a specific time window (1 minute, 24 hours, etc). From 4d1731c1333f11dec57002f26e6f1bee4148eb69 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Wed, 12 Sep 2018 12:45:55 +0200 Subject: [PATCH 083/171] fix: Fixed the platform selector for config styles --- src/_data/documentation_categories.yml | 6 +++--- src/_js/lib/PlatformContent.js | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/_data/documentation_categories.yml b/src/_data/documentation_categories.yml index 53bbf1e4f0926..4e77c38074c0b 100644 --- a/src/_data/documentation_categories.yml +++ b/src/_data/documentation_categories.yml @@ -6,12 +6,12 @@ - title: Learn slug: learn -- title: Product Guides - slug: product - - title: Platforms slug: platforms +- title: Product Guides + slug: product + - title: Integrations slug: integrations diff --git a/src/_js/lib/PlatformContent.js b/src/_js/lib/PlatformContent.js index c74de8ab36030..9136b13473442 100644 --- a/src/_js/lib/PlatformContent.js +++ b/src/_js/lib/PlatformContent.js @@ -136,7 +136,9 @@ const showPlatform = function(slug) { history.replaceState({}, '', updateUrlPlatform(location.href, slug)); $('.config-key').each(function() { - this.setAttribute('data-config-key', $(this).text()); + if (!this.getAttribute('data-config-key')) { + this.setAttribute('data-config-key', $(this).text().trim()); + } }); $('.unsupported-hint').remove(); From ea77091f3a5573ca054f8fc73b5631a14a231092 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Wed, 12 Sep 2018 10:37:35 +0200 Subject: [PATCH 084/171] fix(clientdev): Adjust order of sidebar entries --- src/collections/_documentation/clientdev/attributes.md | 2 +- src/collections/_documentation/clientdev/context.md | 2 +- src/collections/_documentation/clientdev/data-handling.md | 2 +- src/collections/_documentation/clientdev/features.md | 1 + src/collections/_documentation/clientdev/interfaces/index.md | 2 +- src/collections/_documentation/clientdev/overview.md | 1 + 6 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/collections/_documentation/clientdev/attributes.md b/src/collections/_documentation/clientdev/attributes.md index 783caf41fe9bc..d5b2b18d8f9ad 100644 --- a/src/collections/_documentation/clientdev/attributes.md +++ b/src/collections/_documentation/clientdev/attributes.md @@ -1,6 +1,6 @@ --- title: Attributes -sidebar_order: 1 +sidebar_order: 3 --- Attributes are simple data that Sentry understands to provide the most basic information about events. These are things like the unique ID of an event, the human readable message etc. diff --git a/src/collections/_documentation/clientdev/context.md b/src/collections/_documentation/clientdev/context.md index b43ff224662f5..398698dc810be 100644 --- a/src/collections/_documentation/clientdev/context.md +++ b/src/collections/_documentation/clientdev/context.md @@ -1,6 +1,6 @@ --- title: 'Context Management' -sidebar_order: 2 +sidebar_order: 6 --- All SDKs should have the concept of concurrency safe context storage. What this means depends on the language. The basic idea is that a user of the SDK can call a method to safely provide additional context information from whererever the user has access to the client object. diff --git a/src/collections/_documentation/clientdev/data-handling.md b/src/collections/_documentation/clientdev/data-handling.md index 17be1d2174a15..469a8724c3a06 100644 --- a/src/collections/_documentation/clientdev/data-handling.md +++ b/src/collections/_documentation/clientdev/data-handling.md @@ -1,6 +1,6 @@ --- title: 'Data Handling' -sidebar_order: 3 +sidebar_order: 5 --- ## Sensitive Data diff --git a/src/collections/_documentation/clientdev/features.md b/src/collections/_documentation/clientdev/features.md index 55a23b4e7b532..edc017c81c18e 100644 --- a/src/collections/_documentation/clientdev/features.md +++ b/src/collections/_documentation/clientdev/features.md @@ -1,5 +1,6 @@ --- title: 'Expected Features' +sidebar_order: 2 --- The following is a description of features that are commonly expected in Sentry SDKs. diff --git a/src/collections/_documentation/clientdev/interfaces/index.md b/src/collections/_documentation/clientdev/interfaces/index.md index 0c068c85205bc..5ebb004dd4611 100644 --- a/src/collections/_documentation/clientdev/interfaces/index.md +++ b/src/collections/_documentation/clientdev/interfaces/index.md @@ -1,6 +1,6 @@ --- title: Interfaces -sidebar_order: 1 +sidebar_order: 4 --- Any additional value in the payload of an event which is not an attribute ([_Attributes_]({%- link _documentation/clientdev/attributes.md -%})) is assumed to be a data interface, where the key is the Python path to the interface class name, and the value is the data expected by the interface. Interfaces are used in a variety of ways including storing stacktraces, HTTP request information, and other metadata. diff --git a/src/collections/_documentation/clientdev/overview.md b/src/collections/_documentation/clientdev/overview.md index 61498dd317676..97fbc39cfcf79 100644 --- a/src/collections/_documentation/clientdev/overview.md +++ b/src/collections/_documentation/clientdev/overview.md @@ -1,5 +1,6 @@ --- title: Overview +sidebar_order: 1 --- The following is a guide for implementing a new Sentry SDK. It covers the protocol for event submission as well as guidelines for how clients should typically look and behave. From ad0e53317f3e10fa560ad6f574eb208cfe497f11 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Wed, 12 Sep 2018 13:10:51 +0200 Subject: [PATCH 085/171] feat(clientdev): Add most stuff from internal paper --- .../_documentation/clientdev/context.md | 86 ------------ .../_documentation/clientdev/data-handling.md | 33 +---- .../_documentation/clientdev/features.md | 4 +- .../_documentation/clientdev/index.md | 3 +- .../_documentation/clientdev/overview.md | 122 +++++------------- .../_documentation/clientdev/scopes.md | 105 +++++++++++++++ .../_documentation/clientdev/terminology.md | 32 +++++ 7 files changed, 179 insertions(+), 206 deletions(-) delete mode 100644 src/collections/_documentation/clientdev/context.md create mode 100644 src/collections/_documentation/clientdev/scopes.md create mode 100644 src/collections/_documentation/clientdev/terminology.md diff --git a/src/collections/_documentation/clientdev/context.md b/src/collections/_documentation/clientdev/context.md deleted file mode 100644 index 398698dc810be..0000000000000 --- a/src/collections/_documentation/clientdev/context.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: 'Context Management' -sidebar_order: 6 ---- - -All SDKs should have the concept of concurrency safe context storage. What this means depends on the language. The basic idea is that a user of the SDK can call a method to safely provide additional context information from whererever the user has access to the client object. - -This is implemented as a thread local in most languages, but in some (such as JavaScript) it might be global under the assumption that this is something that makes sense in the environment. - -## User’s Perspective {#user-s-perspective} - -From the user’s perspective of the Sentry SDK there should be two types of APIs: - -`SentryClient.context`: - -: Given a Sentry SDK object it should be possible to get a reference to the underlying context object for manual updating. This might not always be something that makes sense in the context of the language, so it’s sometimes reasonable to hide this. - - If it is possible in the language, then it’s encouraged that this be a thread local accessor so as not to break concurrent environments. For instance the Python SDK has a different context for each thread to support concurrent web frameworks and multithreaded environments. - - If the context is exposed it needs to provide two methods: - - - `merge()`: to merge in a new nested dictionary of data over the existing data. - - `clear()`: to clear the context entirely. This is necessary so that reuse of threads is safe and old data does not leak into the reused context. - -`SentryClient.*_context`: - -: These are methods that update the context according to the name of the method. Which of those methods exist is up to the SDK developer, however as a general rule these should exist: - - - `user_context` - - `tags_context` - - `http_context` - - `extra_context` - -Ideally a user never needs to be concerned with clearing the context. Framework integrations should do this automatically as far as possible. For instance if a SDK integration is configured for a web framework it should automatically hook the framework in a way where it will clear the context at the end of every request and ideally also already invoke things like `http_context` automatically. - -## Context Clearing - -For most SDKs there should be a method to clear the context. This is especially imporant in multithreaded environments where threads might be re-used. It is preferred that the context be cleared automatically if that is something the SDK can provide. As mentioned earlier the framework integrations in the SDKs should do this whenever possible. - -For manual clearing `client.context.clear()` is the preferred method. If the context cannot be directly exposed, `client.clearContext()` or a method with a similar name should exist. - -## Common Context Methods - -It is recommended that the following methods exist: - -`client.user_context(data)`: - -: Updates the user context for future events. - - Equivalent to this: - - ```javascript - client.context.merge({'user': data}) - ``` - -`client.http_context(data)`: - -: Updates the HTTP context for future events. - - Equivalent to this: - - ```javascript - client.context.merge({'request': data}) - ``` - -`client.extra_context(data)`: - -: Update the extra context for future events. - - Equivalent to this: - - ```javascript - client.context.merge({'extra': data}) - ``` - -`client.tags_context(data)`: - -: Update the tags context for future events. - - Equivalent to this: - - ```javascript - client.context.merge({'tags': data}) - ``` - -For some SDKs it also makes sense to provide additional helpers to bind the HTTP context and similar things to common language patterns. For instance if you expect a CGI/WSGI/Rack environment you could provide `client.cgi_context` / `client.wsgi_context` methods. diff --git a/src/collections/_documentation/clientdev/data-handling.md b/src/collections/_documentation/clientdev/data-handling.md index 469a8724c3a06..36fbc7df3a878 100644 --- a/src/collections/_documentation/clientdev/data-handling.md +++ b/src/collections/_documentation/clientdev/data-handling.md @@ -5,38 +5,17 @@ sidebar_order: 5 ## Sensitive Data -SDKs should provide some mechanism for scrubbing data. Ideally through an extensible interface that the user can customize the behavior of. +In older SDKs you might sometimes see elaborate constructs to allow the user to strip away sensitive data. Newer SDKs no longer have this feature as it turned out to be too hard to maintain per-SDK. Instead, only two simple config options are left: -This is generally done as part of the SDK configuration: +- [_send-default-pii_]({%- link _documentation/learn/configuration.md -%}#send-default-pii) is **enabled by default**, meaning that data that is naturally sensitive is stripped entirely. That means, for example: -```php -client = Client(..., { - 'processors': ['processor.className'], -}) -``` + - When attaching HTTP requests to events, "raw" bodies (bodies which cannot be parsed as JSON or formdata) are removed, and known sensitive headers such as `Authentication` or `Cookies` are removed too. -Each processor listed would be some sort of extensible class or a function callback. It would have a single designated method that is passed the data (after it’s been populated), and would then return the data fully intact, or modified with various bits filtered out. + - User-specific information (e.g. the current user ID according to the used webframework) is not sent at all. -For example, if you simply supported callbacks for processors, it might look like this: + - Note that if a user explicitly sets a request on the scope, nothing is stripped from that request. The above rules only apply to integrations that come with the SDK. -```php -function my_processor($data) { - foreach ($data['extra'] as $key => $value) { - if (strpos($value, 'password')) { - $data[$key] = '********'; - } - } -} -``` - -We recommend scrubbing the following values: - -- Values where the keyname matches ‘password’, ‘passwd’, or ‘secret’. -- Values that match the regular expression of `r'^(?:\d[ -]*?){13,16}$'` (credit card-like). -- Session cookies. -- The Authentication header (HTTP). - -Keep in mind that if your SDK is passing extra interface data (e.g. HTTP POST variables) you will also want to scrub those interfaces. Given that, it is a good idea to simply recursively scrub most variables other than predefined things (like HTTP headers). +- [_before-send_]({%- link _documentation/learn/configuration.md -%}#before-send) can be used to register a callback with custom logic to remove sensitive data. ## Variable Size diff --git a/src/collections/_documentation/clientdev/features.md b/src/collections/_documentation/clientdev/features.md index edc017c81c18e..6efc339268bee 100644 --- a/src/collections/_documentation/clientdev/features.md +++ b/src/collections/_documentation/clientdev/features.md @@ -17,9 +17,9 @@ Ability to set attributes on events sent to Sentry. They should be configurable Automatic addition of useful attributes such as `tags` or `extra`. Typically means the SDK hooks into a framework so that it can set attributes that are known to be useful for most users. -## Context system +## Scopes system -A system for storing data that has to do with a given context. What context means depends on the application, for a web framework it is most likely a single request/response cycle. For a mobile application there is often just one single context that represents the single user and their actions. Context can be difficult to implement because it often has to deal with threads or concurrency and can involve deep integration with frameworks. [See the context page]({%- link _documentation/clientdev/context.md -%}#context) for more information. +A system for storing data that has to do with a given scope. What scope means depends on the application, for a web framework it is most likely a single request/response cycle. For a mobile application there is often just one single scope that represents the single user and their actions. Scopin g can be difficult to implement because it often has to deal with threads or concurrency and can involve deep integration with frameworks. [See the scopes page]({%- link _documentation/clientdev/scopes.md -%}#scope) for more information. ## Breadcrumbs diff --git a/src/collections/_documentation/clientdev/index.md b/src/collections/_documentation/clientdev/index.md index 72d52a4c7e1c8..d2fc92562bb44 100644 --- a/src/collections/_documentation/clientdev/index.md +++ b/src/collections/_documentation/clientdev/index.md @@ -10,4 +10,5 @@ The following is a guide for implementing a new Sentry SDK. It covers the protoc - [Attributes]({%- link _documentation/clientdev/attributes.md -%}) - [Interfaces]({%- link _documentation/clientdev/interfaces/index.md -%}) - [Data Handling]({%- link _documentation/clientdev/data-handling.md -%}) -- [Context Management]({%- link _documentation/clientdev/context.md -%}) +- [Scopes]({%- link _documentation/clientdev/scopes.md -%}) +- [Terminology]({%- link _documentation/clientdev/terminology.md -%}) diff --git a/src/collections/_documentation/clientdev/overview.md b/src/collections/_documentation/clientdev/overview.md index 97fbc39cfcf79..087c6920a9bc5 100644 --- a/src/collections/_documentation/clientdev/overview.md +++ b/src/collections/_documentation/clientdev/overview.md @@ -26,7 +26,6 @@ Additionally, the following features are highly encouraged: - Automated error capturing (e.g. uncaught exception handlers) - Logging framework integration - Non-blocking event submission -- Basic data sanitization (e.g. filtering out values that look like passwords) - Context data helpers (e.g. setting the current user, recording breadcrumbs) - Event sampling - Honor Sentry’s HTTP 429 Retry-After header @@ -42,24 +41,38 @@ Generally, using an SDK consists of three steps for the end user, which should l 1. Creation of the SDK (sometimes this is hidden from the user): ```javascript - var myClient = new SentryClient('{DSN}'); + Sentry.init({dsn: '___DSN___'}); ``` + + ```python + sentry_sdk.init('___DSN___') + ``` + 2. Capturing an event: ```javascript - var resultId = myClient.captureException(myException); + var resultId = Sentry.captureException(myException); + ``` + + ```python + result_id = sentry_sdk.capture_exception(my_exception); ``` 3. Using the result of an event capture: + ```javascript + alert(`Your exception was recorded as ${resultId}`); + ``` + ```python - println('Your exception was recorded as %s', resultId); + println('Your exception was recorded as %s', result_id); ``` -The constructor ideally allows several configuration methods. The first argument should always be the DSN value (if possible), followed by an optional secondary argument which is a map of options: +`init` ideally allows several configuration methods. The first argument should always be the DSN value (if possible): ```javascript -client = new SentryClient('{DSN}', { - 'tags': {'foo': 'bar'} +Sentry.init({ + 'dsn': '___DSN___', + 'foo': 'bar' }) ``` @@ -71,51 +84,20 @@ If an empty DSN is passed, you should treat it as valid option which signifies d content=__alert_content %} -Which options you support is up to you, but ideally you would provide defaults for generic values that can be passed to the capture methods. - -Once you accept the options, you should output a logging message describing whether the SDK has been configured actively (as in, it will send to the remote server), or if it has been disabled. This should be done with whatever standard logging module is available for your platform. - -Additionally, you should provide methods (depending on the platform) which allow for capturing of a basic message and an exception-type: - -- `SentryClient.captureMessage(message)` -- `SentryClient.captureException(exception)` +Additionally, you should provide global functions which allow for capturing of +a basic message or exception: -The above methods should also allow optional arguments (or a map of arguments). For example: - -```javascript -client.captureException(myException, { - 'tags': {'foo': 'bar'}, -}) -``` +- `Sentry.captureMessage(message)` +- `Sentry.captureException(exception)` If your platform supports block statements, it is recommended that you provide something like the following: ``` -with client.captureExceptions(tags={'foo': 'bar'}): +with capture_exceptions(): # do something that will cause an error 1 / 0 ``` -{% capture __alert_content -%} -In the above example, we’re passing any options that would normally be passed to the capture methods along with the block wrapper. -{%- endcapture -%} -{%- include components/alert.html - title="Note" - content=__alert_content -%} - -Finally, provide a CLI to test your SDK’s configuration. Python example: - -```bash -raven test {DSN} -``` - -Ruby example: - -```bash -rake raven:test {DSN} -``` - ## Parsing the DSN SDKs are encouraged to allow arbitrary options via the constructor, but must allow the first argument as a DSN string. This string contains the following bits: @@ -133,7 +115,7 @@ The final endpoint you’ll be sending requests to is constructed per the follow For example, given the following constructor: ```javascript -new SentryClient('https://public:secret@sentry.example.com/1') +Sentry.init({dsn: 'https://public:secret@sentry.example.com/1'}) ``` You should parse the following settings: @@ -328,52 +310,12 @@ def should_try(self): return time.time() - self.last_check > interval ``` -## Tags - -Tags are key/value pairs that describe an event. They should be configurable in the following contexts: - -- Environment (SDK-level) -- Thread (block-level) -- Event (as part of capture) - -Each of these should inherit its parent. So for example, if you configure your SDK as so: - -```python -client = Client(..., { - 'tags': {'foo': 'bar'}, -}) -``` - -And then you capture an event: - -```python -client.captureMessage('test', { - 'tags': {'foo': 'baz'}, -}) -``` - -The SDK should send the following upstream for `tags`: - -```python -{ - "tags": [ - ["foo", "bar"], - ["foo", "baz"] - ], -} -``` - -## Contextual Data - -You should also provide relevant contextual interfaces. These should last for the lifecycle of a request, and the general interface is “bind some kind of context”, and then at the end of a request lifecycle, clear any present context. +## Contextual data and concurrency (scopes, contexts, hubs) -This interface consists of _*_context_ methods, access to the _context_ dictionary as well as a _clear_ and _merge_ context method. Method methods exist usually depend on the SDK. The following methods generally make sense: +Most of our SDKs allow the user to: -- `client.user_context` -- `client.tags_context` -- `client.http_context` -- `client.extra_context` -- `client.context.merge` -- `client.context.clear` +* Configure multiple clients (i.e. use multiple DSNs) +* Attach additional data to events -For more information about this (specifically about how to deal with concurrency) please make sure to read [_Context Management_]({%- link _documentation/clientdev/context.md -%}). +Please make sure to read [_Scopes_]({%- link +_documentation/clientdev/scopes.md -%}) to learn how most SDKs implement this. diff --git a/src/collections/_documentation/clientdev/scopes.md b/src/collections/_documentation/clientdev/scopes.md new file mode 100644 index 0000000000000..6cb1aa9cd7164 --- /dev/null +++ b/src/collections/_documentation/clientdev/scopes.md @@ -0,0 +1,105 @@ +--- +title: 'Scopes' +sidebar_order: 6 +--- + +All SDKs should have the concept of concurrency safe context storage. What this means depends on the language. The basic idea is that a user of the SDK can call a method to safely provide additional context information for all events that are about to be recorded. + +This is implemented as a thread local stack in most languages, but in some (such as JavaScript) it might be global under the assumption that this is something that makes sense in the environment. + +From the user's perspective of the Sentry SDK there are two relevant APIs: + +## Scope + +A scope holds data that should implicitly be sent with sentry events. It can hold context data, extra parameters, level overrides, fingerprints etc. + +The user should be able to modify the current scope easily (to set extra, tags, current user), through a global function `configureScope`. `configureScope` takes a callback function to which it passes the current scope. Here's an example from another place in the docs: + +```javascript +Sentry.configureScope((scope) => { + scope.setExtra("character_name": "Mighty Fighter"); +}); +``` + +Why not just have a `getCurrentScope()` function instead of this indirection? If the SDK is disabled (e.g. by not providing a DSN), modifying a scope is pointless because there will never be any events to send. In that situation `configureScope` may choose not to call the callback. + +- `scope.set_user(data)`: Shallow merges user configuration (`email`, `username`, …). Removing user data is SDK-defined, either with a `remove_user` function or by passing nothing as data. + +- `scope.set_extra(key, value)`: Sets the extra key to an arbitrary value, overwriting a potential previous value. Removing a key is SDK-defined, either with a `remove_extra` function or by passing nothing as data. + +- `scope.set_tag(key, value)`: Sets the tag to a string value, overwriting a potential previous value. Removing a key is SDK-defined, either with a `remove_tag` function or by passing nothing as data. + +- `scope.set_context(key, value)`: Sets the context key to a value, overwriting a potential previous value. Removing a key is SDK-defined, either with a `remove_context` function or by passing nothing as data. The types are sdk specified. + +- `scope.set_fingerprint(fingerprint[])`: Sets the fingerprint to group specific events together + +- `scope.clear()`: resets a scope to default values (prevents inheriting) + +- `scope.apply_to_event(event[, max_breadcrumbs])`: Applies the scope data to the given event object. This also applies the event processors stored in the scope internally. Some implementations might want to set a max breadcrumbs count here. + +## Hub + +The hub consists of a client and a stack of scopes. + +The SDK maintains two variables: The *global hub* (a global variable) and the *current hub* (a variable local to the current thread or execution context, also sometimes known as async local or context local) + +The `init()` you saw in the [_Overview_]({%- link _documentation/clientdev/overview.md -%}) typically creates / reinitializes the global hub which is propagated to all new threads/execution contexts, or a hub is created per thread/execution context. + +- `Hub::new(client, scope)`: Creates a new hub with the given client and scope. The client can be reused between hubs. The scope should be owned by the hub (make a clone if necessary) + +- `Hub::new_from_top(hub)` / alternatively native constructor overloads: Creates a new hub by cloning the top stack of another hub. + +- `get_current_hub()` / `Hub::current()` / `Hub::get_current()`: Global function or static function to return the current (threads) hub + +- `get_main_hub()` / `Hub::main()` / `Hub::get_main()`: In languages where the main thread is special this returns the main thread’s hub instead of the current thread’s hub. This might not exist in all languages. + +- `Hub::capture_event` / `Hub::capture_message` / `Hub::capture_exception` Capture message / exception call into capture event. `capture_event` merges the event passed with the scope data and dispatches to the client. + +- `Hub::push_scope()`: Pushes a new scope layer that inherits the previous data. This should return a disposable or stack guard for languages where it makes sense. + +- `Hub::with_scope(func)` (optional): In Python this could be a context manager, in Ruby a block function. Pushes and pops a scope for integration work. + +- `Hub::pop_scope()` (optional): Only exists in languages without better resource management. Better to have this function on a return value of `push_scope` or to use `with_scope`. + +- `Hub::configure_scope(callback)`: Invokes the callback with a mutable reference to the scope for modifiations + +- `Hub::add_breadcrumb(crumb)`: Adds a breadcrumb to the current scope. + + - The argument supported should be: + - function that creates a breadcrumb + - an already created breadcrumb object + - a list of breadcrumbs optionally + - In languages where we do not have a basic form of overloading only a raw breadcrumb object should be accepted. + +- `Hub::client()` / `Hub::get_client()` (optional): Accessor or getter that returns the current client or `None`. + +- `Hub::bind_client(new_client)`: Binds a different client to the hub. If the hub is also the owner of the client that was created by `init` it needs to keep a reference to it still if the hub is the object responsible for disposing it. + +- `Hub::unbind_client()` (optional): Optional way to unbind for languages where `bind_client` does not accept nullables. + +- `Hub::add_event_processor(callback)`: Registers a callback with the hub that returns a callback that processes a specific event. This allows the processor to hold on to closure data until the scope might have to be sent to another thread: + + - `add_event_processor(() => (event) => …))` + + - The initial closure can be persisted until the scope needs to be stored or sent to a thread after which the inner closure is retained. + +- `Hub::run(hub, callback)` `hub.run(callback)`, `run_in_hub(hub, callback)` (optional): Runs a callback with the hub bound as the current hub. + + +## Convenience functions + +The following shortcut functions should be exported in the top-level namespace of your package: + +- `capture_event(event)`: Takes an already assembled event and dispatches it to the client + +- `capture_exception(…)`: Report an error or exception. In Rust this does not exist: There are different kinds of exception types. + +- `capture_message(message, level)`: Reports a message. The level can be optional in language with default parameters. + +- `add_breadcrumb(crumb)`: Adds a new breadcrumb to the scope. If the total number of breadcrumbs exceeds the `maxBreadcrumbs` setting, the oldest breadcrumb should be removed in turn. This works like the Hub api with regards to what `crumb` can be. + +- `configure_scope(callback)`: Calls a callback with a scope object that can be reconfigured. This is used to attach contextual data for future events in the same scope. This is a convenience alias to `Hub::current().configure_scope(…)`. + +- `with_active_hub(callback)` / `Hub::with_active(callback)`: Invokes the callback which is passed the default hub if a client is bound or does nothing if the client is not bound. + + This one is intended for integrations and in some systems that might not be necessary to add. The advantage of having it means that a user cannot accidentally create a sentry structure in a disabled environment. Alternatively a user would need to check upfront if the client is active. diff --git a/src/collections/_documentation/clientdev/terminology.md b/src/collections/_documentation/clientdev/terminology.md new file mode 100644 index 0000000000000..5f08342f75c75 --- /dev/null +++ b/src/collections/_documentation/clientdev/terminology.md @@ -0,0 +1,32 @@ +--- +title: 'Terminology' +sidebar_order: 7 +--- + +This page lists a few words that you may encounter when reading the sourcecode of one of our SDKs. + +- **minimal**: a minimal layer that provides a way to configure data and emit breadcrumbs and events to a configured sentry client. These layers are typically distributed separately or a library can be reconfigured to remove all actual reporting. Names might be minimal, abstraction or interface. + +- **hub**: an object that manages the state. An implied global thread local or similar hub exists that can be used by default. Hubs can be created manually. + +- **context**: contexts give extra data to sentry. There are the special contexts (user and similar) and the generic ones (runtime, os, device) etc. Check out https://docs.sentry.io/clientdev/interfaces/contexts/ for valid keys. *Note: In older SDKs you might encounter an unrelated concept of + context, which is now deprecated by scopes* + +- **tags**: tags can be arbitrary string→string pairs by which events can be searched. Contexts are converted into tags. + +- **extra**: truly arbitrary data attached by client users + +- **scope**: a scope holds data that should implicitly be sent with sentry events. It can hold context data, extra parameters, level overrides, fingerprints etc. + +- **client**: a client is an object that is configured once and can be bound to the + hub. The user can then auto discover the client and dispatch calls to it. + Users typically do not need to work with the client directly. They either do + it via the hub or static convenience functions. + +- **client options**: are parameters that are language and runtime specific and + used to configure the client. This can be release and environment but also + things like which integrations to configure, how in-app works etc. + +- **transport**: The transport is an internal construct of the client that abstracts away the event sending. Typically the transport runs in a separate thread and gets events to send via a queue. The transport is responsible for sending, retrying and handling rate limits. The transport might also persist unsent events across restarts if needed. + +- **integration**: code that provides middlewares, bindings or hooks into certain frameworks or environments, along with code that inserts those bindings and activates them. Usage for integrations does not follow a common interface. From 5079203c496070973918eb0c7f3ecdc0a5da9ae1 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Wed, 12 Sep 2018 13:24:57 +0200 Subject: [PATCH 086/171] fix: Fix link in clientdev/terminology and reformat --- .../_documentation/clientdev/terminology.md | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/collections/_documentation/clientdev/terminology.md b/src/collections/_documentation/clientdev/terminology.md index 5f08342f75c75..6a36ed636f3e1 100644 --- a/src/collections/_documentation/clientdev/terminology.md +++ b/src/collections/_documentation/clientdev/terminology.md @@ -5,28 +5,24 @@ sidebar_order: 7 This page lists a few words that you may encounter when reading the sourcecode of one of our SDKs. -- **minimal**: a minimal layer that provides a way to configure data and emit breadcrumbs and events to a configured sentry client. These layers are typically distributed separately or a library can be reconfigured to remove all actual reporting. Names might be minimal, abstraction or interface. +- **minimal**: A separate "facade" package that re-exports a subset of the SDK's functionality through interfaces or proxies. That package does not directly depend on the SDK, instead it should make every operation a noop if the SDK is not installed. -- **hub**: an object that manages the state. An implied global thread local or similar hub exists that can be used by default. Hubs can be created manually. + The purpose of such a package is to allow random libraries to record breadcrumbs and set context data while not having a hard dependency on the SDK. -- **context**: contexts give extra data to sentry. There are the special contexts (user and similar) and the generic ones (runtime, os, device) etc. Check out https://docs.sentry.io/clientdev/interfaces/contexts/ for valid keys. *Note: In older SDKs you might encounter an unrelated concept of - context, which is now deprecated by scopes* +- **hub**: An object that manages the state. An implied global thread local or similar hub exists that can be used by default. Hubs can be created manually. -- **tags**: tags can be arbitrary string→string pairs by which events can be searched. Contexts are converted into tags. +- **context**: Contexts give extra data to sentry. There are the special contexts (user and similar) and the generic ones (runtime, os, device) etc. Check out [_Contexts_]({%- link _documentation/clientdev/interfaces/contexts.md -%}) for valid keys. *Note: In older SDKs you might encounter an unrelated concept of context, which is now deprecated by scopes* -- **extra**: truly arbitrary data attached by client users +- **tags**: Tags can be arbitrary string→string pairs by which events can be searched. Contexts are converted into tags. -- **scope**: a scope holds data that should implicitly be sent with sentry events. It can hold context data, extra parameters, level overrides, fingerprints etc. +- **extra**: Truly arbitrary data attached by client users. -- **client**: a client is an object that is configured once and can be bound to the - hub. The user can then auto discover the client and dispatch calls to it. - Users typically do not need to work with the client directly. They either do - it via the hub or static convenience functions. +- **scope**: A scope holds data that should implicitly be sent with sentry events. It can hold context data, extra parameters, level overrides, fingerprints etc. -- **client options**: are parameters that are language and runtime specific and - used to configure the client. This can be release and environment but also - things like which integrations to configure, how in-app works etc. +- **client**: A client is an object that is configured once and can be bound to the hub. The user can then auto discover the client and dispatch calls to it. Users typically do not need to work with the client directly. They either do it via the hub or static convenience functions. + +- **client options**: Are parameters that are language and runtime specific and used to configure the client. This can be release and environment but also things like which integrations to configure, how in-app works etc. - **transport**: The transport is an internal construct of the client that abstracts away the event sending. Typically the transport runs in a separate thread and gets events to send via a queue. The transport is responsible for sending, retrying and handling rate limits. The transport might also persist unsent events across restarts if needed. -- **integration**: code that provides middlewares, bindings or hooks into certain frameworks or environments, along with code that inserts those bindings and activates them. Usage for integrations does not follow a common interface. +- **integration**: Code that provides middlewares, bindings or hooks into certain frameworks or environments, along with code that inserts those bindings and activates them. Usage for integrations does not follow a common interface. From 64f50180dcfee3f2decf18ab815823c2b9fcedcf Mon Sep 17 00:00:00 2001 From: HazA Date: Wed, 12 Sep 2018 13:30:09 +0200 Subject: [PATCH 087/171] feat: Add express docs --- .../platforms/javascript/node.md | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/collections/_documentation/platforms/javascript/node.md b/src/collections/_documentation/platforms/javascript/node.md index c66512440872c..324eb9d560498 100644 --- a/src/collections/_documentation/platforms/javascript/node.md +++ b/src/collections/_documentation/platforms/javascript/node.md @@ -1,4 +1,36 @@ --- title: Node -sidebar_order: 70 +sidebar_order: 1000 --- + + + +# Express + +```javascript +const express = require('express'); +const app = express(); +const Sentry = require('@sentry/node') ; + +Sentry.init({ dsn:'___PUBLIC_DSN___' }); + +// The request handler must be the first middleware on the app +app.use(Sentry.Handlers.requestHandler()); + +app.get('/', function mainHandler(req, res) { + throw new Error('Broke!'); +}); + +// The error handler must be before any other error middleware +app.use(Sentry.Handlers.errorHandler()); + +// Optional fallthrough error handler +app.use(function onError(err, req, res, next) { + // The error id is attached to `res.sentry` to be returned + // and optionally displayed to the user for support. + res.statusCode = 500; + res.end(res.sentry + '\n'); +}); + +app.listen(3000); +``` \ No newline at end of file From 8a288f92b971841b7e2141f98add601e338716d0 Mon Sep 17 00:00:00 2001 From: HazA Date: Wed, 12 Sep 2018 15:23:53 +0200 Subject: [PATCH 088/171] feat: Write docs for cordova and electron Also migrate source maps docs --- nginx.conf | 6 +- src/_data/LEGACY_platform_icons.yml | 3 - src/_data/platform_icons.yml | 2 +- .../_documentation/clients/electron/config.md | 229 ------------ .../clients/electron/javascript.md | 175 --------- .../clients/electron/sourcemaps.md | 141 -------- .../learn/getting-started-config/electron.md | 2 +- .../platforms/javascript/electron.md | 4 - .../javascript}/electron/index.md | 98 +++-- .../javascript}/electron/native.md | 1 - .../javascript/electron/sourcemaps.md | 12 + .../platforms/javascript/sourcemaps.md | 338 ++++++++++++++++++ .../platforms/minidump/index.md | 2 +- 13 files changed, 417 insertions(+), 596 deletions(-) delete mode 100644 src/collections/_documentation/clients/electron/config.md delete mode 100644 src/collections/_documentation/clients/electron/javascript.md delete mode 100644 src/collections/_documentation/clients/electron/sourcemaps.md delete mode 100644 src/collections/_documentation/platforms/javascript/electron.md rename src/collections/_documentation/{clients => platforms/javascript}/electron/index.md (53%) rename src/collections/_documentation/{clients => platforms/javascript}/electron/native.md (99%) create mode 100644 src/collections/_documentation/platforms/javascript/electron/sourcemaps.md create mode 100644 src/collections/_documentation/platforms/javascript/sourcemaps.md diff --git a/nginx.conf b/nginx.conf index a5d0f607fdfc4..ceb0a0b651eb9 100644 --- a/nginx.conf +++ b/nginx.conf @@ -15,12 +15,16 @@ server { rewrite ^/(?:hosted|on-premise)/(.*)$ /$1$is_args$args redirect; + location = /clients/electron/ { + return 302 /platforms/javascript/electron/$is_args$args; + } + location = /clients/rust/ { return 302 /platforms/rust/$is_args$args; } location = /clients/cordova/ { - return 302 /platforms/cordova/$is_args$args; + return 302 /platforms/javascript/cordova/$is_args$args; } location = /clients/minidump/ { diff --git a/src/_data/LEGACY_platform_icons.yml b/src/_data/LEGACY_platform_icons.yml index 25db24863c63e..185114a16f134 100644 --- a/src/_data/LEGACY_platform_icons.yml +++ b/src/_data/LEGACY_platform_icons.yml @@ -7,9 +7,6 @@ - name: Node.js link: _documentation/clients/node/index.md platformicon: nodejs -- name: Electron - link: _documentation/clients/electron/index.md - platformicon: electron - name: Perl link: _documentation/clients/perl/index.md platformicon: perl diff --git a/src/_data/platform_icons.yml b/src/_data/platform_icons.yml index 8728e0e9260b0..f3fa803be20c7 100644 --- a/src/_data/platform_icons.yml +++ b/src/_data/platform_icons.yml @@ -51,7 +51,7 @@ platformicon: cordova - name: Electron - link: _documentation/platforms/javascript/electron.md + link: _documentation/platforms/javascript/electron/index.md platformicon: electron - name: Python diff --git a/src/collections/_documentation/clients/electron/config.md b/src/collections/_documentation/clients/electron/config.md deleted file mode 100644 index 2f70456818e88..0000000000000 --- a/src/collections/_documentation/clients/electron/config.md +++ /dev/null @@ -1,229 +0,0 @@ ---- -title: Configuration ---- - -To get started, you need to initialize the Electron SDK and declare your Sentry DSN: - -```javascript -const { init } = require('@sentry/electron'); -init({ dsn: '___PUBLIC_DSN___' }); -``` - -This code snippet has to be executed in every process you start in Electron. Besides the main process, this includes renderers and other sub processes. Be sure to initilalize the SDK as early as possible, so it can also catch errors that happen during startup. - -We recommend to put the initialization in a separate JavaScript module, to keep configuration options consistent. This also allows to use it as preload script when creating new `BrowserWindow` instances: - -```javascript -mainWindow = new BrowserWindow({ - width: 800, - height: 600, - webPreferences: { - preload: path.join(__dirname, 'sentry.js') - } -}); -``` - -After this, the SDK is ready to capture any uncaught exception and native crashes that occur in those processes. - -## Node Integration - -The SDK requires some NodeJS APIs to operate properly. When creating windows without Node integration, the SDK must be loaded in a preload script, as described above. Doing so also ensures that the SDK is loaded as early as possible. - -```javascript -mainWindow = new BrowserWindow({ - width: 800, - height: 600, - webPreferences: { - nodeIntegration: false, - preload: path.join(__dirname, 'sentry.js') - } -}); -``` - -## Sandbox Mode - -[Sandbox mode](https://electronjs.org/docs/api/sandbox-option) fully isolates the renderer processes from the operating system using OS-specific methods. Since most node APIs require system access, they are not available in sandbox mode, most notably `require()`. See the linked documentation for a detailed description of sandbox restrictions. - -The Electron SDK can still be used from within a preload script. However, it needs to be bundled into a single file using bundlers like Webpack or Rollup due to the missing `require()` function. Please refer to the respective documentation your chosen tool for all possible configuration options. - -The SDK is written in a way that prevents bundlers from processing any code that is only meant to be executed in the main process. The only remaining external dependency is `electron`, which must be explicitly excluded from inlining. For Webpack, this would be: - -```javascript -module.exports = { - externals: { - electron: 'commonjs electron', - }, - // ... -}; -``` - -Or for Rollup: - -```javascript -export default { - external: ['electron'], - plugins: [commonjs()], - // ... -}; -``` - -## Options - -To customize SDK behavior, simply pass additional options to the `init()` call. All available options are documented below: - -`enableJavaScript` - -: Enables JavaScript error reporting. Default: `true` - - Based on the process type, this configures our JavaScript SDKs with sane defaults. In the main process (`process.type: 'browser'`), it uses the Node SDK. In renderer processes (`process.type: 'renderer'`), it uses the JavaScript SDK. - - If you need to use a specific configuration option of one of these SDKs, you can include it in the options object directly, as it will be passed down by `init`. - - ```javascript - { - enableJavaScript: true - } - ``` - -`enableNative` - -: Enables reporting of native crashes. Default: `true` - - This enables and configures the [Electron CrashReporter](https://electronjs.org/docs/api/crash-reporter) to generate memory dumps when the app or a renderer crashes. Those dumps will be uploaded to Sentry for processing once the app restarts. Metadata, such as context information or breadcrumbs are automatically included. - - For more information on native crashes, see [_Native Usage_]({%- link _documentation/clients/electron/native.md -%}). - - ```javascript - { - enableNative: true - } - ``` - -`release` - -: Explicitly set the version of your application to track it in Sentry. - - Note that the release ID must be unique within your organization. This is required to enable proper source map support. For more information, see [_Source Maps_]({%- link _documentation/clients/electron/sourcemaps.md -%}). - - ```javascript - { - release: '721e41770371db95eee98ca2707686226b993eda' - } - ``` - -`environment` - -: Track the application environment in Sentry. - - This can be useful to distinguish prereleases and special builds from production apps. This works similar to tags. - - ```javascript - { - environment: 'production' - } - ``` - -`maxBreadcrumbs` - -: Set the maximum number of breadcrumbs captured by default. You can increase this to be as high as `100`. Defaults to `30` - - Note that breadcrumbs are kept in memory and periodically flushed in a cache file. This way, breadcrumbs can even be included when the entire application crashes. However, in very high-concurrency situations there is potential for significant memory and disk usage. If you find your application to generate large breadcrumbs, consider reducing `maxBreadcrumbs` the option. - - ```javascript - { - maxBreadcrumbs: 20 - } - ``` - -`shouldSend` - -: A callback invoked during event submission, allowing to cancel it. If unspecified, all events will be sent to Sentry. - - This function is called for both captured errors and messages before all other callbacks. Note that the SDK might perform other actions after calling this function. Use `beforeSend` for notifications on events instead. - - ```javascript - { - shouldSend: function (data) { - return Math.random() > 0.5; - } - } - ``` - -`beforeSend` - -: A callback function that allows mutation of the event payload right before being sent to Sentry. - - This function is called after `shouldSend` and immediately precedes the actual event submission. You must return valid event payload from this callback. If you wish to cancel event submission instead, use `shouldSend`. - - ```javascript - { - beforeSend: function (data) { - // add a user context - data.user = { - id: 1337, - name: 'janedoe', - email: 'janedoe@example.com' - }; - return data; - } - } - ``` - -`afterSend` - -: A callback invoked after the event has been submitted. The second parameter contains a status that indicates whether submission was successful. - - ```javascript - { - afterSend: function (data, status) { - // status can be one of: - // - "unknown": The status could not be determined - // - "skipped": The event was skipped due to configuration or callbacks - // - "success": The event was sent to Sentry successfully - // - "rate_limit": The client is currently rate limited and will try again later - // - "invalid": The event could not be processed - // - "failed": A server-side error ocurred during submission - } - } - ``` - -`shouldAddBreadcrumb` - -: A callback allowing to skip breadcrumbs. - - This function is called for both manual and automatic breadcrumbs before all other callbacks. Note that the SDK might perform other actions after calling this function. Use `beforeBreadcrumb` for notifications on breadcrumbs instead. - - ```javascript - { - shouldAddBreadcrumb: function (data) { - return Math.random() > 0.5; - } - } - ``` - -`beforeBreadcrumb` - -: A callback function that allows mutation of the breadcrumb before adding it. - - This function is called after `shouldAddBreadcrumb`. You must return valid breadcrumb from this callback. If you wish to omit this breadcrumb instead, use `shouldAddBreadcrumb`. - - ```javascript - { - beforeBreadcrumb: function (data) { - data.level = "fatal"; - return data; - } - } - ``` - -`afterBreadcrumb` - -: A callback invoked after a breadcrumb has been added. - - ```javascript - { - afterBreadcrumb: function (data) { - // ... - } - } - ``` diff --git a/src/collections/_documentation/clients/electron/javascript.md b/src/collections/_documentation/clients/electron/javascript.md deleted file mode 100644 index c4f39045a08bf..0000000000000 --- a/src/collections/_documentation/clients/electron/javascript.md +++ /dev/null @@ -1,175 +0,0 @@ ---- -title: 'JavaScript Usage' -sidebar_order: 1 ---- - -Using Sentry from JavaScript code works exactly the same as in any other JavaScript environment. However, the Electron SDK conveniently configures the right SDK when you initialize it: - -- In the main process, it uses the _Node SDK_. -- In renderers, it uses the _Browser SDK_. - -{% capture __alert_content -%} -There is no need to include `@sentry/node` or `@sentry/browser` in addition to the Electron SDK. It includes all their features and even configures them with sane defaults. If you prefer to override some of their settings, you can specify them in addition to the options listed in [_Configuration_]({%- link _documentation/clients/electron/config.md -%}) when calling `init()`. -{%- endcapture -%} -{%- include components/alert.html - title="Tip" - content=__alert_content -%} - -In this document, we assume that the entire SDK is imported into a `Sentry` variable and in scope. Depending on your language level, you might need different syntax for this: - -```javascript -// Node -const Sentry = require('@sentry/electron'); - -// ES2015+ -import * as Sentry from '@sentry/electron'; - -// TypeScript -import * as Sentry from '@sentry/electron'; -``` - -## Reporting Correctly - -By default, the Electron SDK tries to capture meaningful stack traces, but the concurrent Electron’s processes make this difficult. The easiest solution is to prevent errors from bubbling all the way up the stack. - -Depending on the circumstances, there are different methods to report errors: - -### try … catch - -The simplest way, is to try and explicitly capture and report potentially problematic code with a `try...catch` block and `captureException`. - -```javascript -try { - doSomething(a[0]); -} catch(e) { - captureException(e); -} -``` - -{% capture __alert_content -%} -Always throw an actual `Error` object. It’s impossible to retrieve a stack trace from a string. If this happens, the SDK transmits the error as a plain message. For example: - -```javascript -throw new Error('broken'); // good -throw 'broken'; // bad -``` -{%- endcapture -%} -{%- include components/alert.html - title="Do not throw strings!" - content=__alert_content -%} - -### Custom Messages - -If you wish to send a non-error event instead, use `captureMessage`. This will show up with a different level in Sentry: - -```javascript -Sentry.captureMessage('My custom event'); -``` - -## Tracking Users - -While a user is logged in, you can tell Sentry to associate errors with user data: - -```javascript -Sentry.configureScope(scope => { - scope.setUser({ - id: '42', - email: 'user@example.org' - }); -}); -``` - -This data is generally submitted with each error or message and allows you to figure out which users are affected by problems. If at any point the user becomes unauthenticated, call `scope.setUser({})` with an empty object to remove their data. - -## Tagging Events - -Sentry allows to filter and search for issues by tags. You can set global tags to be merged in with future exceptions or messages via `scope.setTag`: - -```javascript -Sentry.configureScope(scope => { - scope.setTag('key', 'value'); -}); -``` - -Tags given in `scope.setTag` are merged with existing tags. If you need to remove a tag, then set it explicitly to `null` or `undefined`. - -## Passing Additional Data - -In addition to user context and tags, you can pass arbitrary to associate with future events. Note that the objects you pass in must be JSON-serializable: - -```javascript -Sentry.configureScope(scope => { - scope.setExtra('my', {data: 2}); -}); -``` - -Data given in `scope.setExtra` is shallow-merged with existing extras. To remove a top-level key from extras, explicitly set it to `null` or `undefined`. - -## Recording Breadcrumbs - -Breadcrumbs are browser and application lifecycle events that are helpful in understanding the state of the application leading up to a crash. - -In renderers, the SDK instruments browser built-ins and DOM events to automatically collect a few useful breadcrumbs for you: - -- fetch and XMLHttpRequests -- URL / address bar changes -- UI clicks and keypress DOM events -- console log statements -- previous errors - -In the main process, the SDK also automatically captures breadcrumbs for: - -- HTTP/HTTPS requests -- console log statements - -You can also record your own breadcrumbs: - -```javascript -Sentry.addBreadcrumb({ - message: 'Item added to shopping cart', - category: 'action', - data: { - isbn: '978-1617290541', - cartSize: '3' - } -}); -``` - -For more on configuring breadcrumbs, see [_Configuration_]({%- link _documentation/clients/electron/config.md -%}). To learn more about what types of data can be collected via breadcrumbs, see the [breadcrumbs client API specification]({%- link _documentation/learn/breadcrumbs.md -%}). - -## Receiving Source Context - -The Electron SDK supports [Source Maps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/). If you upload source maps in addition to your minified files that data becomes available in Sentry. This applies to the main process as well as renderer processes. For more information see [_Source Maps_]({%- link _documentation/clients/electron/sourcemaps.md -%}). - -{% capture __alert_content -%} -Without uploading sourcemaps or source code to Sentry, you might not see source context in issues at all. In the main process, the SDK will try to read source files from the app, but this process will not work in renderers necessarily. -{%- endcapture -%} -{%- include components/alert.html - title="Note" - content=__alert_content -%} - -## Uncaught Exceptions - -The default behavior for dealing with globally unhandled exceptions and Promise rejections differs by process. - -In the main process, such unhandled errors Sentry will capture before showing the default dialog electron always shows. To override this behavior, declare a custom `onFatalError` callback when configuring the SDK, for example if you want your app to exit do: - -```javascript -Sentry.init({ - dsn: '___PUBLIC_DSN___', - onFatalError: function (err) { - if (!sendErr) { - console.log('Successfully sent fatal error to Sentry:'); - console.error(err.stack); - } - - console.log('This is thy sheath; there rust, and let me die.'); - process.exit(1); - } -}); -``` - -Renderer processes do not crash on unhandled errors and there is no `onFatalError` configuration option. Instead, the SDK automatically captures them and sends them to Sentry. This also applies to Promises and polyfills that report a global `unhandledrejection` DOM event. diff --git a/src/collections/_documentation/clients/electron/sourcemaps.md b/src/collections/_documentation/clients/electron/sourcemaps.md deleted file mode 100644 index f6062fbef2a5c..0000000000000 --- a/src/collections/_documentation/clients/electron/sourcemaps.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -title: 'Source Maps' -sidebar_order: 3 ---- - -Sentry supports un-minifying JavaScript via Source Maps. This lets you view source code context obtained from stack traces in their original form, which is particularly useful for debugging minified code (e.g. UglifyJS), or transpiled code from a higher-level language (e.g. TypeScript). - -Even when using plain JavaScript, you must upload your source files to allow Sentry to display source context for stack traces from renderer processes. This is caused by restrictions of [sandboxing](https://electronjs.org/docs/api/sandbox-option) or disabling Node integration. - -## Specifying the Release - -To upload source map artifacts to Sentry, you have to specify the `release` in the SDK configuration and during the upload. Releases are global within your organization and might incorporate multiple of your projects. To isolate it, prefix the release version with an App id. Sentry will use this release name to associate digested event data with the files you’ve uploaded. - -```javascript -Sentry.init({ - dsn: '___PUBLIC_DSN___', - release: 'myapp-1.2.3' -}); -``` - -## Generating Source Maps - -Most modern JavaScript transpilers support source maps. Below are instructions for common tools. - -To allow Sentry to match source code references to uploaded source maps or source files, make sure your tool outputs files relative to your project root folder and prefixes them either with `/` or with `~/`. Some tools do this automatically (e.g. Webpack), or have a configuration option (e.g. TypeScript). For others, please see the section on rewriting source maps before uploading. - -The SDK will rewrite stack traces before sending them to Sentry. If your application generates manual stack traces for some reason, make sure stack frames always contain relative paths from the project root starting with `~/` or `app:///`. - -### UglifyJS - -UglifyJS is a popular tool for minifying your source code for production. It can dramatically reduce the size of your files by eliminating whitespace, rewriting variable names, removing dead code branches, and more. - -If you are using UglifyJS to minify your source code, the following command will additionally generate a source map that maps the minified code back to the original source: - -```sh -$ uglifyjs app.js \ - -o app.min.js.map \ - --source-map url=app.min.js.map,includeSources -``` - -### Webpack - -Webpack is a powerful build tool that resolves and bundles your JavaScript modules into files fit for running in the browser. It also supports various _loaders_ to transpile higher-level languages, reference stylesheets, or include static assets. - -We have created a convenient [webpack plugin](https://github.com/getsentry/sentry-webpack-plugin) that configures source maps and uploads them to Sentry during the build. This is the recommended way for uploading sources to Sentry. First, install the plugin via: - -```sh -$ npm install --save-dev @sentry/webpack-plugin -$ yarn add --dev @sentry/webpack-plugin -``` - -To allow the plugin to upload source maps automatically, create a `.sentryclirc` or configure environment variables as described in the [CLI configuration docs]({%- link _documentation/learn/cli/configuration.md -%}). Then, add the plugin to your `webpack.config.js`: - -```javascript -const SentryWebpackPlugin = require('@sentry/webpack-plugin'); - -module.exports = { - // other configuration - plugins: [ - new SentryWebpackPlugin({ - include: '.', - ignoreFile: '.sentrycliignore', - ignore: ['node_modules', 'webpack.config.js'], - configFile: 'sentry.properties' - }) - ] -}; -``` - -Alternatively, if you prefer to upload source maps manually, Webpack just needs to be configured to output source maps: - -```javascript -module.exports = { - output: { - path: path.join(__dirname, 'dist'), - filename: "[name].js", - sourceMapFilename: "[name].js.map" - } - // other configuration -}; -``` - -{% capture __alert_content -%} -In case you use [SourceMapDevToolPlugin](https://webpack.js.org/plugins/source-map-dev-tool-plugin) for more fine grained control of source map generation, leave `noSources` turned off, so Sentry can display proper source code context in event stack traces. -{%- endcapture -%} -{%- include components/alert.html - title="Note" - content=__alert_content -%} - -### TypeScript - -The TypeScript compiler can output source maps. Configure the `sourceRoot` property to `/` to strip the build path prefix from generated source code references. This allows Sentry to match source files relative to your source root folder: - -```json -{ - "compilerOptions": { - "sourceMap": true, - "inlineSources": true, - "sourceRoot": "/" - } -} -``` - -## Uploading Source Maps to Sentry - -Except for webpack, the recommended way to upload source maps is using [Sentry CLI]({%- link _documentation/learn/cli/index.md -%}). If you have used _Sentry Wizard_ to set up your project, it has already created all necessary configuration to upload source maps. Otherwise, follow the [CLI configuration docs]({%- link _documentation/learn/cli/configuration.md -%}) to set up your project. - -Sentry uses **Releases** to match the correct source maps to your events. To create a new release, run the following command (e.g. during publishing): - -```sh -$ sentry-cli releases new -``` - -Note the release name must be **unique within your organization** and match the `release` option in your SDK initialization code. Then, use the `upload-sourcemaps` command to scan a folder for source maps, process them and upload them to Sentry: - -```sh -$ sentry-cli releases files upload-sourcemaps /path/to/files -``` - -This command will upload all files ending in _.js_ and _.map_ to the specified release. If you wish to change these extensions – e.g. to upload typescript sources – use the `--ext` option: - -```sh -$ sentry-cli releases files upload-sourcemaps --ext ts,map /path/to/files -``` - -{% capture __alert_content -%} -Unfortunately, it can be quite challenging to ensure that source maps are actually valid and uploaded correctly. To ensure that everything is working as intended, you can add the `--validate` flag when uploading source maps. It attempts to parse the source maps and verify source references locally. Note that this flag might produce false positives if you have references to external source maps. -{%- endcapture -%} -{%- include components/alert.html - title="Validating Sourcemaps with Sentry CLI" - content=__alert_content -%} - -Until now, the release is in a draft state (“_unreleased_”). Once all source maps have been uploaded and your app has been published successfully, finalize the release with the following command: - -```sh -$ sentry-cli releases finalize -``` - -For convenience, you can alternatively pass the `--finalize` flag to the `new` command which will immediately finalize the release. diff --git a/src/collections/_documentation/learn/getting-started-config/electron.md b/src/collections/_documentation/learn/getting-started-config/electron.md index d279435f39590..0e10d755d39b3 100644 --- a/src/collections/_documentation/learn/getting-started-config/electron.md +++ b/src/collections/_documentation/learn/getting-started-config/electron.md @@ -1,5 +1,5 @@ You need to call `init` in your `main` and every `renderer` process you spawn. -For more details about Electron [click here]({%- link _documentation/platforms/javascript/electron.md -%}) +For more details about Electron [click here]({%- link _documentation/platforms/javascript/electron/index.md -%}) ```javascript import * as Sentry from '@sentry/electron'; diff --git a/src/collections/_documentation/platforms/javascript/electron.md b/src/collections/_documentation/platforms/javascript/electron.md deleted file mode 100644 index d1ef21756718a..0000000000000 --- a/src/collections/_documentation/platforms/javascript/electron.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Electron -sidebar_order: 100 ---- diff --git a/src/collections/_documentation/clients/electron/index.md b/src/collections/_documentation/platforms/javascript/electron/index.md similarity index 53% rename from src/collections/_documentation/clients/electron/index.md rename to src/collections/_documentation/platforms/javascript/electron/index.md index e3d290cb7bf30..e43aa0e312352 100644 --- a/src/collections/_documentation/clients/electron/index.md +++ b/src/collections/_documentation/platforms/javascript/electron/index.md @@ -1,6 +1,6 @@ --- title: Electron -sidebar_order: 3 +sidebar_order: 2000 --- `@sentry/electron` is the official Sentry SDK for Electron applications. It can capture JavaScript exceptions in the main process and renderers, as well as collect native crash reports (Minidumps). @@ -15,30 +15,24 @@ This SDK is still in beta and undergoing active development. It is part of an ea %}{% capture __alert_content -%} Support for Electron is currently limited to [sentry.io](https://sentry.io). The latest on-premise version of Sentry (_8.22.0_) does not provide server-side support for native crashes and their debug information files. Full support for Electron will made available to all on-premise customers with the next release. -To use the Electron SDK for reporting JavaScript errors at your own discretion, disable native crash handling and use the private DSN: +To use the Electron SDK for reporting JavaScript errors at your own discretion, disable native crash handling and use the DSN: -```javascript -const { init } = require('@sentry/electron'); -init({ - dsn: '___DSN___', - enableNative: false, -}); -``` {%- endcapture -%} {%- include components/alert.html title="Sentry On-Premise" content=__alert_content %} -## Installation - -The Electron SDK is distributed via _npm_: - -```sh -$ npm install --save @sentry/electron -$ yarn add @sentry/electron +```javascript +const { init } = require('@sentry/electron'); +init({ + dsn: '___PUBLIC_DSN___', + enableNative: false, +}); ``` +## Wizard + Our Sentry Wizard can help with the setup process. Make sure you have installed the `@sentry/wizard` npm package globally, then run: ```sh @@ -50,36 +44,65 @@ This will guide you through the installation and configuration process and sugge ## Configuring the Client -Initialize the client and configure it to use your [Sentry DSN]({%- link _documentation/learn/quickstart.md -%}#configure-the-dsn): +After [configuring the SDK]({%- link _documentation/learn/quickstart.md -%}?platform=electron#configure-the-sdk) the [Electron CrashReporter](https://electronjs.org/docs/api/crash-reporter) for native app crashes and captures any uncaught JavaScript exceptions using the JavaScript SDKs under the hood. Be sure to call this function as early as possible in the main process and all renderer processes to also catch errors during startup. + +## Browser integration + +We recommend to put the initialization in a separate JavaScript module, to keep configuration options consistent. This also allows to use it as preload script when creating new `BrowserWindow` instances: ```javascript -const { init } = require('@sentry/electron'); -init({ - dsn: '___PUBLIC_DSN___', - // more options... +mainWindow = new BrowserWindow({ + width: 800, + height: 600, + webPreferences: { + preload: path.join(__dirname, 'sentry.js') + } }); ``` -This configures the [Electron CrashReporter](https://electronjs.org/docs/api/crash-reporter) for native app crashes and captures any uncaught JavaScript exceptions using the JavaScript SDKs under the hood. Be sure to call this function as early as possible in the main process and all renderer processes to also catch errors during startup. +After this, the SDK is ready to capture any uncaught exception and native crashes that occur in those processes. + +## Node Integration + +The SDK requires some NodeJS APIs to operate properly. When creating windows without Node integration, the SDK must be loaded in a preload script, as described above. Doing so also ensures that the SDK is loaded as early as possible. -For more information on all configuration options, as well as the correct setup in [Sandbox mode](https://electronjs.org/docs/api/sandbox-option) or with disabled Node integration, see [_Configuration_]({%- link _documentation/clients/electron/config.md -%}). +```javascript +mainWindow = new BrowserWindow({ + width: 800, + height: 600, + webPreferences: { + nodeIntegration: false, + preload: path.join(__dirname, 'sentry.js') + } +}); +``` + +## Sandbox Mode -## Manually Reporting Errors +[Sandbox mode](https://electronjs.org/docs/api/sandbox-option) fully isolates the renderer processes from the operating system using OS-specific methods. Since most node APIs require system access, they are not available in sandbox mode, most notably `require()`. See the linked documentation for a detailed description of sandbox restrictions. -By default, the Electron SDK makes a best effort to capture any uncaught exception and send crash reports from the Electron processes to Sentry. +The Electron SDK can still be used from within a preload script. However, it needs to be bundled into a single file using bundlers like Webpack or Rollup due to the missing `require()` function. Please refer to the respective documentation your chosen tool for all possible configuration options. -To report errors manually, wrap potentially problematic code with a `try...catch` block and call _captureException_: +The SDK is written in a way that prevents bundlers from processing any code that is only meant to be executed in the main process. The only remaining external dependency is `electron`, which must be explicitly excluded from inlining. For Webpack, this would be: ```javascript -const { captureException } = require('@sentry/electron'); -try { - myEvilOperation(); -} catch (e) { - captureException(e); -} +module.exports = { + externals: { + electron: 'commonjs electron', + }, + // ... +}; ``` -The SDK will automatically add useful information, such as the app name and version or collect breadcrumbs for certain events. But there are more ways to report errors and add custom metadata. For a complete guide on this see [_JavaScript Usage_]({%- link _documentation/clients/electron/javascript.md -%}). +Or for Rollup: + +```javascript +export default { + external: ['electron'], + plugins: [commonjs()], + // ... +}; +``` ## Uploading Debug Information @@ -89,7 +112,7 @@ To get symbolicated stack traces for native crashes, you have to upload debug sy $ node sentry-symbols.js ``` -If your app uses a custom Electron fork, contains modules with native extensions or spawns subprocesses, you have to upload those symbols manually using Sentry CLI. For more information, see [_Native Usage_]({%- link _documentation/clients/electron/native.md -%}). +If your app uses a custom Electron fork, contains modules with native extensions or spawns subprocesses, you have to upload those symbols manually using Sentry CLI. For more information, see [_Native Usage_]({%- link _documentation/platforms/javascript/electron/native.md -%}). {% capture __alert_content -%} It is currently not possible to send events from native code (such as a C++ extension). However, crashes will still be reported to Sentry if they happen in a process where the SDK has been configured. Also, crash reports from sub processes will not be reported automatically on all platforms. This feature will be added in a future SDK update. @@ -101,13 +124,10 @@ It is currently not possible to send events from native code (such as a C++ exte ## Dealing with Minified Source Code -The Electron SDK supports [Source Maps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/). If you upload source maps in addition to your minified files that data becomes available in Sentry. For more information see [_Source Maps_]({%- link _documentation/clients/electron/sourcemaps.md -%}). +The Electron SDK supports [Source Maps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/). If you upload source maps in addition to your minified files that data becomes available in Sentry. For more information see [_Source Maps_]({%- link _documentation/platforms/javascript/electron/sourcemaps.md -%}). ## Deep Dive For more detailed information about how to get most out of the Electron SDK, there is additional documentation available that covers all the rest: -- [Configuration]({%- link _documentation/clients/electron/config.md -%}) -- [JavaScript Usage]({%- link _documentation/clients/electron/javascript.md -%}) -- [Native Usage]({%- link _documentation/clients/electron/native.md -%}) -- [Source Maps]({%- link _documentation/clients/electron/sourcemaps.md -%}) +- [Native Usage]({%- link _documentation/platforms/javascript/electron/native.md -%}) diff --git a/src/collections/_documentation/clients/electron/native.md b/src/collections/_documentation/platforms/javascript/electron/native.md similarity index 99% rename from src/collections/_documentation/clients/electron/native.md rename to src/collections/_documentation/platforms/javascript/electron/native.md index 7ccf952a58d85..e38c03de9c30f 100644 --- a/src/collections/_documentation/clients/electron/native.md +++ b/src/collections/_documentation/platforms/javascript/electron/native.md @@ -1,6 +1,5 @@ --- title: 'Native Usage' -sidebar_order: 2 --- Sentry can process Minidumps created when the Electron process or one of its renderers crashes. To do so, the SDK needs to upload those files once the application restarts (or immediately for renderer crashes). All event meta data including user information and breadcrumbs are included in these uploads. diff --git a/src/collections/_documentation/platforms/javascript/electron/sourcemaps.md b/src/collections/_documentation/platforms/javascript/electron/sourcemaps.md new file mode 100644 index 0000000000000..56c26c17ecf77 --- /dev/null +++ b/src/collections/_documentation/platforms/javascript/electron/sourcemaps.md @@ -0,0 +1,12 @@ +--- +title: 'Source Maps' +sidebar_order: 3 +--- + +To find out why Sentry needs your source maps and how to provide them visit: [Source Maps]({%- link _documentation/platforms/javascript/sourcemaps.md -%}) + +## Native Application + +To allow Sentry to match source code references to uploaded source maps or source files, make sure your tool outputs files relative to your project root folder and prefixes them either with `/` or with `~/`. Some tools do this automatically (e.g. Webpack), or have a configuration option (e.g. TypeScript). For others, please see the section on rewriting source maps before uploading. + +The SDK will rewrite stack traces before sending them to Sentry. If your application generates manual stack traces for some reason, make sure stack frames always contain relative paths from the project root starting with `~/` or `app:///`. diff --git a/src/collections/_documentation/platforms/javascript/sourcemaps.md b/src/collections/_documentation/platforms/javascript/sourcemaps.md new file mode 100644 index 0000000000000..6b2f4a86ce6f2 --- /dev/null +++ b/src/collections/_documentation/platforms/javascript/sourcemaps.md @@ -0,0 +1,338 @@ +--- +title: 'Source Maps' +sidebar_order: 5 +--- + +Sentry supports un-minifying JavaScript via [Source Maps](http://blog.sentry.io/2015/10/29/debuggable-javascript-with-source-maps.html). This lets you view source code context obtained from stack traces in their original untransformed form, which is particularly useful for debugging minified code (e.g. UglifyJS), or transpiled code from a higher-level language (e.g. TypeScript, ES6). + +## Specify the release + +If you are uploading sourcemap artifacts yourself, you must specify the release in your SDK see: [Releases]({%- link _documentation/learn/releases.md -%}). Sentry will use the release name to associate digested event data with the files you’ve uploaded via the [releases API]({%- link _documentation/api/releases/index.md -%}), [sentry-cli]({%- link _documentation/learn/cli/index.md -%}) or [sentry-webpack-plugin](https://github.com/getsentry/sentry-webpack-plugin). This step is optional if you are hosting sourcemaps on the remote server. + +## Generating a Source Map + +Most modern JavaScript transpilers support source maps. Below are instructions for some common tools. + +### UglifyJS + +UglifyJS is a popular tool for minifying your source code for production. It can dramatically reduce the size of your files by eliminating whitespace, rewriting variable names, removing dead code branches, and more. + +If you are using UglifyJS to minify your source code, the following command will additionally generate a source map that maps the minified code back to the original source: + +```bash +uglifyjs app.js \ + -o app.min.js.map \ + --source-map url=app.min.js.map,includeSources +``` + +### Webpack + +Webpack is a powerful build tool that resolves and bundles your JavaScript modules into files fit for running in the browser. It also supports various _loaders_ to transpile higher-level languages, reference stylesheets, or include static assets. + +We have created a convenient [webpack plugin](https://github.com/getsentry/sentry-webpack-plugin) that configures source maps and uploads them to Sentry during the build. This is the recommended way for uploading sources to Sentry. First, install the plugin via: + +```sh +$ npm install --save-dev @sentry/webpack-plugin +$ yarn add --dev @sentry/webpack-plugin +``` + +To allow the plugin to upload source maps automatically, create a `.sentryclirc` or configure environment variables as described in the [CLI configuration docs]({%- link _documentation/learn/cli/configuration.md -%}). Then, add the plugin to your `webpack.config.js`: + +```javascript +const SentryWebpackPlugin = require('@sentry/webpack-plugin'); + +module.exports = { + // other configuration + plugins: [ + new SentryWebpackPlugin({ + include: '.', + ignoreFile: '.sentrycliignore', + ignore: ['node_modules', 'webpack.config.js'], + configFile: 'sentry.properties' + }) + ] +}; +``` + +Alternatively, if you prefer to upload source maps manually, Webpack just needs to be configured to output source maps: + +```javascript +module.exports = { + output: { + path: path.join(__dirname, 'dist'), + filename: "[name].js", + sourceMapFilename: "[name].js.map" + } + // other configuration +}; +``` + +{% capture __alert_content -%} +In case you use [SourceMapDevToolPlugin](https://webpack.js.org/plugins/source-map-dev-tool-plugin) for more fine grained control of source map generation, leave `noSources` turned off, so Sentry can display proper source code context in event stack traces. +{%- endcapture -%} +{%- include components/alert.html + title="Note" + content=__alert_content +%} + +### SystemJS + +SystemJS is the default module loader for Angular 2 projects. The [SystemJS build tool](https://github.com/systemjs/builder) can be used to bundle, transpile, and minify source code for use in production environments, and can be configured to output source maps. + +```javascript +builder.bundle('src/app.js', 'dist/app.min.js', { + minify: true, + sourceMaps: true, + sourceMapContents: true +}); +``` + +{% capture __alert_content -%} +All of the example configurations above inline your original, un-transformed source files into the generated source map file. Sentry requires both source map(s) **and** your original source files in order to perform reverse transformations. If you choose NOT to inline your source files, you must make those source files available to Sentry in _addition_ to your source maps (see below). +{%- endcapture -%} +{%- include components/alert.html + title="Inline Sources" + content=__alert_content +%} + +### TypeScript + +The TypeScript compiler can output source maps. Configure the `sourceRoot` property to `/` to strip the build path prefix from generated source code references. This allows Sentry to match source files relative to your source root folder: + +```json +{ + "compilerOptions": { + "sourceMap": true, + "inlineSources": true, + "sourceRoot": "/" + } +} +``` + +## Making Source Maps Available to Sentry + +Source maps can be either: + +1. Served publicly over HTTP alongside your source files. +2. Uploaded directly to Sentry (**recommended**). + +### Hosting Source Map Files + +By default, Sentry will look for source map directives in your compiled JavaScript files, which are located on the last line and have the following format: + +```javascript +//# sourceMappingURL= +``` + +When Sentry encounters such a directive, it will resolve the source map URL relative the source file in which it is found, and attempt an HTTP request to fetch it. + +So for example if you have a minified JavaScript file located at `http://example.org/js/app.min.js`. And in that file, on the last line, the following directive is found: + +```javascript +//# sourceMappingURL=app.js.map +``` + +Sentry will attempt to fetch `app.js.map` from [http://example.org/js/app.js.map](http://example.org/js/app.js.map). + +Alternatively, during source map generation you can specify a fully qualified URL where your source maps are located: + +```javascript +//# sourceMappingURL=http://example.org/js/app.js.map +``` + +While making source maps available to Sentry from your servers is the easiest integration, it is not always advisable: + +- Sentry may not always be able to reach your servers. +- If you do not specify versions in your asset URLs, there may be a version mismatch +- The additional latency may mean that source mappings are not available for all errors. + +For these reasons, it is recommended to upload source maps to Sentry beforehand (see below). + +{% capture __alert_content -%} +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, [IP Ranges]({%- link ip-ranges.md -%}#ip-ranges). +{%- endcapture -%} +{%- include components/alert.html + title="Working Behind a Firewall" + content=__alert_content +%}{% capture __alert_content -%} +If you want to keep your source maps secret and choose not to upload your source maps directly to Sentry, you can enable the “Security Token” option in your project settings. This will cause outbound requests from Sentry’s servers to URLs originating from your “Allowed Domains” to have the HTTP header “X-Sentry-Token: {token}” appended, where {token} is a secure value you define. You can then configure your web server to allow access to your source maps when this header/token pair is present. You can alternatively override the default header name (X-Sentry-Token) and use HTTP Basic Authentication, e.g. by passing “Authorization: Basic {encoded_password}”. +{%- endcapture -%} +{%- include components/alert.html + title="Secure Access to Source Maps" + content=__alert_content +%} + +### Uploading Source Maps to Sentry + +Except for webpack, the recommended way to upload source maps is using [Sentry CLI]({%- link _documentation/learn/cli/index.md -%}). If you have used _Sentry Wizard_ to set up your project, it has already created all necessary configuration to upload source maps. Otherwise, follow the [CLI configuration docs]({%- link _documentation/learn/cli/configuration.md -%}) to set up your project. + +Sentry uses **Releases** to match the correct source maps to your events. To create a new release, run the following command (e.g. during publishing): + +```sh +$ sentry-cli releases new +``` + +Note the release name must be **unique within your organization** and match the `release` option in your SDK initialization code. Then, use the `upload-sourcemaps` command to scan a folder for source maps, process them and upload them to Sentry: + +```sh +$ sentry-cli releases files upload-sourcemaps /path/to/files +``` + +This command will upload all files ending in _.js_ and _.map_ to the specified release. If you wish to change these extensions – e.g. to upload typescript sources – use the `--ext` option: + +```sh +$ sentry-cli releases files upload-sourcemaps --ext ts,map /path/to/files +``` + +{% capture __alert_content -%} +Unfortunately, it can be quite challenging to ensure that source maps are actually valid and uploaded correctly. To ensure that everything is working as intended, you can add the `--validate` flag when uploading source maps. It attempts to parse the source maps and verify source references locally. Note that this flag might produce false positives if you have references to external source maps. +{%- endcapture -%} +{%- include components/alert.html + title="Validating Sourcemaps with Sentry CLI" + content=__alert_content +%} + +Until now, the release is in a draft state (“_unreleased_”). Once all source maps have been uploaded and your app has been published successfully, finalize the release with the following command: + +```sh +$ sentry-cli releases finalize +``` + +For convenience, you can alternatively pass the `--finalize` flag to the `new` command which will immediately finalize the release. + +Note: You dont _have_ to upload the source files (ref’d by sourcemaps), but without them the grouping algorithm will not be as strong, and the UI will not show any contextual source. + +Additional information can be found in the [Releases API documentation]({%- link _documentation/api/releases/index.md -%}). + +{% capture __alert_content -%} +It’s not uncommon for a web application to be accessible at multiple origins. For example: + +- Website is operable over both `https` and `http` +- Geolocated web addresses: e.g. `https://us.example.com`, `https://eu.example.com` +- Multiple static CDNs: e.g. `https://static1.example.com`, `https://static2.example.com` +- Customer-specific domains/subdomains + +In this situation, **identical** JavaScript and source map files may be located at two or more distinct origins. If you are dealing with such a deployment, you have two choices for naming your uploaded artifacts: + +1. Upload the same artifact multiple times with each possible URL where it appears, for example: + + > - [https://static1.example.com/js/app.js](https://static1.example.com/js/app.js) + > - [https://static2.example.com/js/app.js](https://static2.example.com/js/app.js) +2. Alternatively, you can omit the protocol + host and use a special tilde (~) prefixed path like so: + + > ~/js/app.js + +The ~ prefix tells Sentry that for a given URL, **any** combination of protocol and hostname whose path is `/js/app.js` should use this artifact. **ONLY** use this method if your source/sourcemap files are identical at all possible protocol/hostname combinations. Note that Sentry will prioritize full URLs over tilde prefixed paths if found. +{%- endcapture -%} +{%- include components/alert.html + title="Assets Accessible at Multiple Origins" + content=__alert_content +%} + +{% capture __alert_content -%} +Unfortunately it can be quite challenging to ensure that sourcemaps are actually valid themselves and uploaded correctly. To ensure that everything is working as intended you can use the _–validate_ flag when uploading sourcemaps which will attempt to locally parse the sourcemap 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 sourcemaps then the validation tool will indicate a failure). + +Here are some things you can check in addition to the validation step: + +- Make sure that the URL prefix is correct for your files. This is easy to get wrong. +- Make sure you upload the matching sourcemaps for your minimized files. +- Make sure that your minified files you have on your servers actually have references to your files. +{%- endcapture -%} +{%- include components/alert.html + title="Validating Sourcemaps with Sentry CLI" + content=__alert_content +%} + +## Troubleshooting + +Source maps can sometimes be tricky to get going. If you’re having trouble, try the following tips. + +### Verify your source maps are built correctly + +We maintain an online validation tool that can be used to test your source (and sourcemaps) against: [sourcemaps.io](http://sourcemaps.io). + +Alternatively, if you are using Sentry CLI to upload source maps to Sentry, you can use the _–validate_ command line option to verify your source maps are correct. + +### Verify sourceMappingURL is present + +Some CDNs automatically strip comments from static files, including JavaScript files. This can have the effect of stripping your JavaScript file of its `sourceMappingURL` directive, because it is considered a comment. For example, CloudFlare has a feature called [Auto-Minify](https://blog.cloudflare.com/an-all-new-and-improved-autominify/) which will strip `sourceMappingURL` if it is enabled. + +Double-check that your deployed, final JavaScript files have `sourceMappingURL` present. + +### Verify artifact names match sourceMappingURL + +When [uploading source maps to Sentry](#uploading-source-maps-to-sentry), you must name your source map files with the same name found in `sourceMappingURL`. + +For example, if you have the following in a minified application file, `app.min.js`: + +```javascript +//-- end app.min.js +//# sourceMappingURL=https://example.com/dist/js/app.min.js.map +``` + +Sentry will look for a matching artifact named exactly `https://example.com/dist/js/app.min.js.map`. + +Note also that Sentry will resolve relative paths. For example, if you have the following: + +```JavaScript +// -- end app.min.js (located at https://example.com/dist/js/app.min.js) +//# sourceMappingURL=app.min.js.map +``` + +Sentry will resolve `sourceMappingURL` relative to `https://example.com/dist/js/` (the root path from which `app.min.js` was served). You will again need to name your source map with the full URL: `https://example.com/dist/js/app.min.js.map`. + +If you serve the same assets from multiple origins, you can also alternatively use our tilde (~) path prefix to ignore matching against protocol + hostname. In which case, `~/dist/js/app.min.js.map`, will also work. See: [Assets Accessible at Multiple Origins](#assets-multiple-origins). + +### Verify artifacts are uploaded before errors occur + +Sentry expects that source code and source maps in a given release are uploaded to Sentry **before** errors occur in that release. + +If you upload artifacts **after** an error is captured by Sentry, Sentry will not go back and retroactively apply any source annotations to those errors. Only new errors triggered after the artifact was uploaded will be affected. + +### Verify your source maps work locally + +If you find that Sentry is not mapping filename, line, or column mappings correctly, you should verify that your source maps are functioning locally. To do so, you can use Node.js coupled with Mozilla’s [source-map library](https://github.com/mozilla/source-map). + +First, install `source-map` globally as an npm module: + +```bash +npm install -g source-map +``` + +Then, write a script that reads your source map file and tests a mapping. Here’s an example: + +```JavaScript +var fs = require('fs'), + path = require('path'), + sourceMap = require('source-map'); + +// file output by Webpack, Uglify, etc. +var GENERATED_FILE = path.join('.', 'app.min.js.map'); + +// line and column located in your generated file (e.g. source of your error +// from your minified file) +var GENERATED_LINE_AND_COLUMN = {line: 1, column: 1000}; + +var rawSourceMap = fs.readFileSync(GENERATED_FILE).toString(); +var smc = new sourceMap.SourceMapConsumer(rawSourceMap); + +var pos = smc.originalPositionFor(GENERATED_LINE_AND_COLUMN); + +// should see something like: +// { source: 'original.js', line: 57, column: 9, name: 'myfunc' } +console.log(pos); +``` + +If you have the same (incorrect) results locally as you do via Sentry, double-check your source map generation configuration. + +### Verify your source files are not too large + +For an individual artifact, Sentry accepts a max filesize of **40 MB**. + +Often users hit this limit because they are transmitting source files at an interim build stage. For example, after Webpack/Browserify has combined all your source files, but before minification has taken place. If possible, send the original source files. + +### Verify artifacts are not gzipped + +The Sentry API currently only works with source maps and source files that are uploaded as plain text (UTF-8 encoded). If the files are uploaded in a compressed format (e.g. gzip), they will be not be interpreted correctly. + +This sometimes occurs with build scripts and plugins that produce pre-compressed minified files. For example, Webpack’s [compression plugin](https://github.com/webpack/compression-webpack-plugin). You’ll need to disable such plugins and perform the compression _after_ the generated source maps / source files have been uploaded to Sentry. diff --git a/src/collections/_documentation/platforms/minidump/index.md b/src/collections/_documentation/platforms/minidump/index.md index b920fbde66cd2..81dcdc64ac53a 100644 --- a/src/collections/_documentation/platforms/minidump/index.md +++ b/src/collections/_documentation/platforms/minidump/index.md @@ -6,7 +6,7 @@ sidebar_order: 8 Sentry can process Minidump crash reports, a memory dump used on Windows and by open-source libraries like [_Breakpad_]({%- link _documentation/platforms/minidump/breakpad.md -%}) or [_Crashpad_]({%- link _documentation/platforms/minidump/crashpad.md -%}). You can either choose to generate and upload minidumps yourself or use a higher-level SDK for platforms with built-in support for native crashes: - [_Cocoa_]({%- link _documentation/clients/cocoa/index.md -%}) -- [_Electron_]({%- link _documentation/clients/electron/index.md -%}) +- [_Electron_]({%- link _documentation/platforms/javascript/electron/index.md -%}) In order to receive symbolicated stack traces, you have to upload debug information to Sentry. For more information, see [Uploading Debug Information](#minidump-dif). From e5a47806b0fd1bd9c8cbe6ee44a1e864925c5162 Mon Sep 17 00:00:00 2001 From: HazA Date: Wed, 12 Sep 2018 15:49:44 +0200 Subject: [PATCH 089/171] feat: Move source maps lower --- .../_documentation/platforms/javascript/sourcemaps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/collections/_documentation/platforms/javascript/sourcemaps.md b/src/collections/_documentation/platforms/javascript/sourcemaps.md index 6b2f4a86ce6f2..cb2b7c649e8e5 100644 --- a/src/collections/_documentation/platforms/javascript/sourcemaps.md +++ b/src/collections/_documentation/platforms/javascript/sourcemaps.md @@ -1,6 +1,6 @@ --- title: 'Source Maps' -sidebar_order: 5 +sidebar_order: 60 --- Sentry supports un-minifying JavaScript via [Source Maps](http://blog.sentry.io/2015/10/29/debuggable-javascript-with-source-maps.html). This lets you view source code context obtained from stack traces in their original untransformed form, which is particularly useful for debugging minified code (e.g. UglifyJS), or transpiled code from a higher-level language (e.g. TypeScript, ES6). From ac17e12a7ab3fc8af6cc26bf7c45a56515722d0c Mon Sep 17 00:00:00 2001 From: Bruno Garcia Date: Wed, 12 Sep 2018 16:39:56 +0200 Subject: [PATCH 090/171] feat: user feedback ASP.NET Core --- .../learn/user-feedback-example/aspnetcore.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/collections/_documentation/learn/user-feedback-example/aspnetcore.md diff --git a/src/collections/_documentation/learn/user-feedback-example/aspnetcore.md b/src/collections/_documentation/learn/user-feedback-example/aspnetcore.md new file mode 100644 index 0000000000000..1f2dde5cc2d0e --- /dev/null +++ b/src/collections/_documentation/learn/user-feedback-example/aspnetcore.md @@ -0,0 +1,18 @@ +With ASP.NET Core MVC, the `Error.cshtml` razor page: + +{% raw %} +```html +@using Sentry + + + +@if (SentrySdk.LastEventId != Guid.Empty) +{ + +} +``` +{% endraw %} From c28fef0b82d36b894798cd378814995fc8f616ca Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Wed, 12 Sep 2018 16:45:39 +0200 Subject: [PATCH 091/171] feat: Show sdk versions in getting-started-install --- _config.yml | 1 + src/_plugins/release_registry.rb | 60 +++++++++++++++++++ .../getting-started-install/aspnetcore.md | 4 +- .../learn/getting-started-install/cordova.md | 2 +- .../learn/getting-started-install/csharp.md | 4 +- .../learn/getting-started-install/electron.md | 4 +- .../learn/getting-started-install/node.md | 4 +- .../learn/getting-started-install/python.md | 2 +- .../learn/getting-started-install/rust.md | 2 +- 9 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 src/_plugins/release_registry.rb diff --git a/_config.yml b/_config.yml index 0337c06259616..6eb41092653ed 100644 --- a/_config.yml +++ b/_config.yml @@ -7,6 +7,7 @@ baseurl: '' url: 'https://docs.sentry.io' twitter_username: getsentry home_url: https://sentry.io +release_service: https://release-registry.services.sentry.io # Build settings port: 9000 diff --git a/src/_plugins/release_registry.rb b/src/_plugins/release_registry.rb new file mode 100644 index 0000000000000..52e8eb8f2c8cf --- /dev/null +++ b/src/_plugins/release_registry.rb @@ -0,0 +1,60 @@ +require 'net/http' + +module Jekyll + class ReleaseRegistryTag < Liquid::Tag + CACHE = {} + + def initialize(tag_name, text, tokens) + super + @params = text.split(/\s+/) + end + + def render(context) + get_info["version"] + end + + def entity + raise NotImplementedError.new + end + + private + + def name + @params[0] + end + + def version + @params[1] || "latest" + end + + def get_info + self.class::CACHE[[entity, name, version]] ||= + begin + uri = URI("#{server}/#{entity}/#{name}/#{version}") + JSON.parse(Net::HTTP.get(uri)) + rescue Exception => e + raise RuntimeError.new("WARN: Failed to fetch version '#{version}' for '#{name}': #{e}") + end + end + + def server + # XXX: This prints out the configuration path every time it's accessed. + @server ||= Jekyll.configuration({})['release_service'] + end + end + + class PackageVersionTag < ReleaseRegistryTag + def entity + "packages" + end + end + + class SdkVersionTag < ReleaseRegistryTag + def entity + "sdks" + end + end +end + +Liquid::Template.register_tag('package_version', Jekyll::PackageVersionTag) +Liquid::Template.register_tag('sdk_version', Jekyll::SdkVersionTag) diff --git a/src/collections/_documentation/learn/getting-started-install/aspnetcore.md b/src/collections/_documentation/learn/getting-started-install/aspnetcore.md index 99a1d8058e9af..d42db22bed273 100644 --- a/src/collections/_documentation/learn/getting-started-install/aspnetcore.md +++ b/src/collections/_documentation/learn/getting-started-install/aspnetcore.md @@ -2,10 +2,10 @@ Install the **NuGet** package: Package Manager: ```shell -Install-Package Sentry.AspNetCore +Install-Package Sentry.AspNetCore -Version {% sdk_version sentry.dotnet.aspnetcore %} ``` .NET Core CLI: ```shell -dotnet add package Sentry.AspNetCore +dotnet add package Sentry.AspNetCore -v {% sdk_version sentry.dotnet.aspnetcore %} ``` diff --git a/src/collections/_documentation/learn/getting-started-install/cordova.md b/src/collections/_documentation/learn/getting-started-install/cordova.md index da7493803b8a0..b7e2b58bbc231 100644 --- a/src/collections/_documentation/learn/getting-started-install/cordova.md +++ b/src/collections/_documentation/learn/getting-started-install/cordova.md @@ -1,5 +1,5 @@ Install our SDK using the cordova command: ```bash -$ cordova plugin add sentry-cordova +$ cordova plugin add sentry-cordova@{% sdk_version sentry.javascript.cordova %} ``` diff --git a/src/collections/_documentation/learn/getting-started-install/csharp.md b/src/collections/_documentation/learn/getting-started-install/csharp.md index 87b3c534d5ff3..613a630a78ff9 100644 --- a/src/collections/_documentation/learn/getting-started-install/csharp.md +++ b/src/collections/_documentation/learn/getting-started-install/csharp.md @@ -2,10 +2,10 @@ Install the **NuGet** package: Package Manager: ```shell -Install-Package Sentry +Install-Package Sentry -Version {% sdk_version sentry.dotnet %} ``` .NET Core CLI: ```shell -dotnet add package Sentry +dotnet add package Sentry -v {% sdk_version sentry.dotnet %} ``` diff --git a/src/collections/_documentation/learn/getting-started-install/electron.md b/src/collections/_documentation/learn/getting-started-install/electron.md index b100282341ef0..d60d2b75857e2 100644 --- a/src/collections/_documentation/learn/getting-started-install/electron.md +++ b/src/collections/_documentation/learn/getting-started-install/electron.md @@ -1,11 +1,11 @@ If you are using `yarn` you can add our package as a dependency easily: ```bash -$ yarn add @sentry/electron +$ yarn add @sentry/electron@{% sdk_version sentry.javascript.electron %} ``` Or alternatively you can npm install it: ```bash -$ npm install @sentry/electron +$ npm install @sentry/electron@{% sdk_version sentry.javascript.electron %} ``` diff --git a/src/collections/_documentation/learn/getting-started-install/node.md b/src/collections/_documentation/learn/getting-started-install/node.md index 7fc1b22b74ac7..9cdf057f86b40 100644 --- a/src/collections/_documentation/learn/getting-started-install/node.md +++ b/src/collections/_documentation/learn/getting-started-install/node.md @@ -1,11 +1,11 @@ If you are using `yarn` you can add our package as a dependency easily: ```bash -$ yarn add @sentry/node +$ yarn add @sentry/node@{% sdk_version sentry.javascript.node %} ``` Or alternatively you can npm install it: ```bash -$ npm install @sentry/node +$ npm install @sentry/node@{% sdk_version sentry.javascript.node %} ``` diff --git a/src/collections/_documentation/learn/getting-started-install/python.md b/src/collections/_documentation/learn/getting-started-install/python.md index f4909a748e648..4ab922bee185a 100644 --- a/src/collections/_documentation/learn/getting-started-install/python.md +++ b/src/collections/_documentation/learn/getting-started-install/python.md @@ -1,5 +1,5 @@ Install our Python SDK using [`pip`](https://pip.pypa.io/en/stable/): ```bash -$ pip install --upgrade sentry-sdk +$ pip install --upgrade sentry-sdk=={% sdk_version sentry.python %} ``` diff --git a/src/collections/_documentation/learn/getting-started-install/rust.md b/src/collections/_documentation/learn/getting-started-install/rust.md index 885521257f7b1..11afe36d36738 100644 --- a/src/collections/_documentation/learn/getting-started-install/rust.md +++ b/src/collections/_documentation/learn/getting-started-install/rust.md @@ -2,5 +2,5 @@ To add Sentry to your Rust project you just need to add a new dependency to your ```toml [dependencies] -sentry = "0.7.0" +sentry = "{% sdk_version sentry.rust %}" ``` From c9de0dbe4eab26e3e771f6a2c93e862d966c8a1f Mon Sep 17 00:00:00 2001 From: Bruno Garcia Date: Wed, 12 Sep 2018 18:35:59 +0200 Subject: [PATCH 092/171] feat: doc aspnetcore --- .../platforms/dotnet/aspnetcore.md | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 src/collections/_documentation/platforms/dotnet/aspnetcore.md diff --git a/src/collections/_documentation/platforms/dotnet/aspnetcore.md b/src/collections/_documentation/platforms/dotnet/aspnetcore.md new file mode 100644 index 0000000000000..d4d02c784d89f --- /dev/null +++ b/src/collections/_documentation/platforms/dotnet/aspnetcore.md @@ -0,0 +1,190 @@ +--- +title: Sentry.AspNetCore +sidebar_order: 2 +--- + +Sentry has an integration with _ASP.NET Core_ through the `Sentry.AspNetCore` NuGet package. + +## Installation + +Using package manager: + +```powershell +Install-Package Sentry.AspNetCore +``` + +Or using the .NET Core CLI: + +```sh +dotnet add Sentry.AspNetCore +``` + +This package extends [Sentry.Extensions.Logging]({%- link _documentation/platforms/dotnet/microsoft-extensions-logging.md -%}). This means that besides the ASP.NET Core related features, through this package you'll also get access to all the framework's logging integration and also the features available in the main [Sentry]({%- link _documentation/platforms/dotnet/index.md -%}) SDK. + +## Overview of the features + +* Easy ASP.NET Core integration, single line: `UseSentry` +* Captures unhandled exceptions in the middleware pipeline +* Captures exceptions handled by the framework `UseExceptionHandler` and Error page display +* Captures process-wide unhandled exceptions (AppDomain) +* Captures `LogError` or `LogCritical` +* Any event sent will include relevant application log messages +* RequestId as tag +* URL as tag +* Environment is automatically set (IHostingEnvironment) +* Release automatically set (`AssemblyInformationalVersionAttribute`, `AssemblyVersion` or environment variable) +* Request payload can be captured if opt-in +* Support for EventProcessors registered with DI +* Support for ExceptionProcessors registered with DI +* Supports configuration system (bind to `SentryAspNetCoreOptions`) +* Server OS info sent +* Server Runtime info sent +* Request headers sent +* HTTP Proxy configuration +* Request body compressed +* Event flooding protection (429 retry-after and internal bound queue) +* Assembly Strong named +* Tested on Windows, Linux and macOS +* Tested on .NET Core, .NET Framework and Mono + +### Configuration + +The simplest way to configure the `Sentry.AspNetCore` package is not by calling `SentrySdk.Init` directly but rather using the extension method `UseSentry` to the `WebHostBuilder` in combination with the framework's configuration system. +The configuration values bind to `SentryAspNetCoreOptions` which extends `SentryLoggingOptions` from the `Sentry.Extensions.Logging` and further extends `SentryOptions` from the `Sentry` package. + +This means all options for the inner packages are available to be configured through the configuration system. + +When using `WebHost.CreateDefaultBuilder`, the framework automatically loads `appsettings.json` and environment variables, binding to `SentryAspNetCoreOptions`. + +For example: + +```json + "Sentry": { + "Dsn": "___PUBLIC_DSN___", + "IncludeRequestPayload": true, + "SendDefaultPii": true, + "MinimumBreadcrumbLevel": "Debug", + "MinimumEventLevel": "Warning", + "AttachStackTrace": true, + "Debug": true, + "DiagnosticsLevel": "Error" + }, +``` + +> An example of some of the options that can be configured via `appsettings.json`. + +It's also possible to bind properties to the SDK via environment variables, like: + +Windows +```sh +set Sentry__Debug=true +``` + +Linux or macOS +```sh +export Sentry__Debug=true +``` + +ASP.NET Core will automatically read this environment variable and bind it to the SDK configuration object. + +When configuring the SDK via the frameworks configuration system, it's possible to add the SDK by simply calling `UseSentry` without providing any further information: + +```csharp +public static IWebHost BuildWebHost(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup() + // Add this: + .UseSentry() + .Build(); +``` + +Some of the settings require actual code. For those, like the `BeforeSend` callback you can simply: + +```csharp +public static IWebHost BuildWebHost(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup() + .UseSentry(options => + { + options.BeforeSend = @event => + { + // Never report server names + @event.ServerName = null; + return @event; + }; + }) + .Build(); +``` + +> Example modifying all events before they are sent to avoid server names being reported. + +## Dependency Injection + +Much of the behavior of the ASP.NET Core integration with Sentry can be customized by using the frameworks dependency injection system. That is done by registering your own implementation of some of the exposed abstraction. + +### Lifetimes + +The lifetime used will be respected by the SDK. For example, when registering a `Transient` dependency, a new instance of the processor is created for each event sent out to Sentry. This allows the use of non thread-safe event processors. + +### Capturing the affected user + +When opting-in to [SendDefaultPii](#senddefaultpii), the SDK will automatically read the user from the request by inspecting `HttpContext.User`. Default claim values like `NameIdentifier` for the _Id_ will be used. + +If you wish to change the behavior of how to read the user from the request, you can register a new `IUserFactory` into the container: + +```csharp +public void ConfigureServices(IServiceCollection services) +{ + services.AddSingleton(); +} +``` + +### Adding event and exception processors + +Event processors and exception processors can be added via DI: + +```csharp +public void ConfigureServices(IServiceCollection services) +{ + services.AddTransient(); + services.AddScoped(); +} +``` + +## Options and Initialization + +As previously mentioned, this package is a wrapper around [Sentry.Extensions.Logging]({%- link _documentation/platforms/dotnet/microsoft-extensions-logging.md -%}) and [Sentry]({%- link _documentation/platforms/dotnet/index.md -%}). Please refer to the documentation of these packages to get the options that are defined at those levels. + +Below, the options that are specific to `Sentry.AspNetCore` will be described. + +### SendDefaultPii + +Although this setting is part of the [Sentry]({%- link _documentation/platforms/dotnet/index.md -%}) package, in the context of ASP.NET Core, it means reporting the user by reading the frameworks `HttpContext.User`. The strategy to create the `SentryUser` can be customized. Please read [retrieving user info](#capturing-the-affected-user) for more. + +### Environment + +The environment name is automatically populated by reading the frameworks `IHostingEnvironment` value. + +> Note: This option is part of the [Sentry]({%- link _documentation/platforms/dotnet/index.md -%}) package. The value of `IHostingEnvironment` will only be used if **no other method was used**. + +Methods that take precedence over `IHostingEnvironment` are: + +* Programatically: `options.Environment` +* Environment variable _SENTRY_ENVIRONMENT_ +* Configuration system like `appsettings.json` + + + +### IncludeRequestPayload + +Opt-in to send the request body to Sentry. By enabling this flag, all requests will have the `EnableRewind` method invoked. This is done so that the request data can be read at a later point in case an error happens while processing the request. + +### IncludeActivityData + +Opt-in to capture values from [System.Diagnostic.Activity](https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/ActivityUserGuide.md) if one exists. + +### Samples + +* A [simple example](https://github.com/getsentry/sentry-dotnet/tree/master/samples/Sentry.Samples.AspNetCore.Basic) without MVC. +* An [example](https://github.com/getsentry/sentry-dotnet/tree/master/samples/Sentry.Samples.AspNetCore.Mvc) using MVC and most of the SDK features. +* For [more samples](https://github.com/getsentry/sentry-dotnet-samples) of the .NET SDKs \ No newline at end of file From ae717de17662702798acdcbc7dbb8d0d8c620c08 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Wed, 12 Sep 2018 12:08:59 -0700 Subject: [PATCH 093/171] ref: simplify sidebar logic to fix bugs --- src/_js/lib/Sidebar.js | 56 +++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/src/_js/lib/Sidebar.js b/src/_js/lib/Sidebar.js index af8659007fae9..25e5e32b15079 100644 --- a/src/_js/lib/Sidebar.js +++ b/src/_js/lib/Sidebar.js @@ -1,46 +1,40 @@ -const filterDepth = depth => { - return (i, el) => { - const $parents = $(el).parentsUntil( - '[data-sidebar-root]', - '[data-sidebar-branch]' - ); - return $parents.length === depth; - }; -}; - $(document).on('page.didUpdate', function(event) { const $links = $('[data-sidebar-link]'); + const $sections = $('[data-sidebar-root] > [data-sidebar-tree]').find( + '> [data-sidebar-branch]' + ); + let $active = $links.filter(`[href="${location.pathname}"]`).last(); - const $categoryTree = $('[data-sidebar-tree]').filter(filterDepth(1)); - $active = !!$active.length - ? $active - : $categoryTree.first().siblings('[data-sidebar-link]'); + + if (!$active.length) { + $active = $sections + .first() + .find('> [data-sidebar-tree]') + .find('> [data-sidebar-branch]') + .first() + .find('> [data-sidebar-link]'); + } + $links.each((i, el) => { const $el = $(el); $el.toggleClass('active', $el.is($active)); }); - const $sectionTree = $('[data-sidebar-branch]').filter(filterDepth(0)); - const $activeBranch = $active.closest('[data-sidebar-branch]'); + $('[data-sidebar-branch]').each((i, el) => { const $branch = $(el); - const $link = $branch.find('> [data-sidebar-link]'); - const $tree = $branch.find('> [data-sidebar-tree]'); + const $parentBranch = $branch + .parent() + .closest('[data-sidebar-branch],[data-sidebar-root]'); const hideWhenNoActiveChild = $branch.data('hide-when-inactive') !== undefined; - const containsActive = !!$tree.has($active).length; - const isActive = $branch.is($activeBranch); - const isSiblingOfActive = !!$branch.siblings().is($activeBranch); - const isChildOfActive = $branch - .parent() - .closest('[data-sidebar-branch]') - .is($activeBranch); - const isSection = $sectionTree.is($branch); + const parentTreeContainsActive = $parentBranch + .find('[data-sidebar-link]') + .is($active); + + const containsActive = $branch.find('[data-sidebar-link]').is($active); + const leaveVisble = - (isSection && !hideWhenNoActiveChild) || - isActive || - isSiblingOfActive || - isChildOfActive || - containsActive; + containsActive || (parentTreeContainsActive && !hideWhenNoActiveChild); $branch.toggleClass('collapse', !leaveVisble); }); }); From 3b8aa8115024a1cbe9b600d0e9e3f536fa7c0098 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Wed, 12 Sep 2018 13:03:19 -0700 Subject: [PATCH 094/171] wizard -> legacy_wizard --- src/_data/platforms.yml | 110 +++++++++++++++++------------------ src/_plugins/platform_api.rb | 7 ++- 2 files changed, 59 insertions(+), 58 deletions(-) diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index 0da162c71c9fb..5a85e7e8ebdcd 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -4,7 +4,7 @@ type: framework name: Koa doc_link: /clients/node/integrations/koa/ - wizard: ['_documentation/clients/node/index.md#installation', _documentation/clients/node/integrations/koa.md] + legacy_wizard:: ['_documentation/clients/node/index.md#installation', _documentation/clients/node/integrations/koa.md] - slug: node support_level: production @@ -12,8 +12,8 @@ name: Node.js # XXX: does this have a better link? doc_link: /platforms/javascript/ - # this is actually the old wizard - wizard: ['_documentation/clients/node/index.md#installation', '_documentation/clients/node/index.md#configuring-the-client', '_documentation/clients/node/index.md#reporting-errors'] + # this is actually the old legacy_wizard: + legacy_wizard:: ['_documentation/clients/node/index.md#installation', '_documentation/clients/node/index.md#configuring-the-client', '_documentation/clients/node/index.md#reporting-errors'] case_style: camelCase fallback_platform: javascript - @@ -22,7 +22,7 @@ type: language name: Node.js doc_link: /clients/node/ - wizard: ['_documentation/clients/node/index.md#installation', '_documentation/clients/node/index.md#configuring-the-client', '_documentation/clients/node/index.md#reporting-errors'] + legacy_wizard:: ['_documentation/clients/node/index.md#installation', '_documentation/clients/node/index.md#configuring-the-client', '_documentation/clients/node/index.md#reporting-errors'] case_style: camelCase fallback_platform: javascript superseded_by: node @@ -33,7 +33,7 @@ name: Express # XXX: this links to the old ones doc_link: /clients/node/integrations/express/ - wizard: ['_documentation/clients/node/index.md#installation', _documentation/clients/node/integrations/express.md] + legacy_wizard:: ['_documentation/clients/node/index.md#installation', _documentation/clients/node/integrations/express.md] - slug: connect support_level: production @@ -41,14 +41,14 @@ name: Connect # XXX: this links to the old ones doc_link: /clients/node/integrations/connect/ - wizard: ['_documentation/clients/node/index.md#installation', _documentation/clients/node/integrations/connect.md] + legacy_wizard:: ['_documentation/clients/node/index.md#installation', _documentation/clients/node/integrations/connect.md] - slug: cordova support_level: production type: language name: Cordova doc_link: /clients/cordova/ - wizard: ['_documentation/clients/cordova/index.md#installation', '_documentation/clients/cordova/index.md#configuration'] + legacy_wizard:: ['_documentation/clients/cordova/index.md#installation', '_documentation/clients/cordova/index.md#configuration'] case_style: camelCase fallback_platform: javascript - @@ -71,57 +71,57 @@ type: language name: Java doc_link: /clients/java/ - wizard: ['_documentation/clients/java/usage.md#installation', '_documentation/clients/java/usage.md#capture-an-error'] + legacy_wizard:: ['_documentation/clients/java/usage.md#installation', '_documentation/clients/java/usage.md#capture-an-error'] - slug: logging support_level: production type: framework name: java.util.logging doc_link: /clients/java/modules/jul/ - wizard: ['_documentation/clients/java/modules/jul.md#installation', '_documentation/clients/java/modules/jul.md#usage'] + legacy_wizard:: ['_documentation/clients/java/modules/jul.md#installation', '_documentation/clients/java/modules/jul.md#usage'] - slug: logback support_level: production type: framework name: Logback doc_link: /clients/java/modules/logback/ - wizard: ['_documentation/clients/java/modules/logback.md#installation', '_documentation/clients/java/modules/logback.md#usage'] + legacy_wizard:: ['_documentation/clients/java/modules/logback.md#installation', '_documentation/clients/java/modules/logback.md#usage'] - slug: android support_level: production type: framework name: Android doc_link: /clients/java/modules/android/ - wizard: ['_documentation/clients/java/modules/android.md#installation', '_documentation/clients/java/modules/android.md#usage'] + legacy_wizard:: ['_documentation/clients/java/modules/android.md#installation', '_documentation/clients/java/modules/android.md#usage'] - slug: log4j2 support_level: production type: framework name: 'Log4j 2.x' doc_link: /clients/java/modules/log4j2/ - wizard: ['_documentation/clients/java/modules/log4j2.md#installation', '_documentation/clients/java/modules/log4j2.md#usage'] + legacy_wizard:: ['_documentation/clients/java/modules/log4j2.md#installation', '_documentation/clients/java/modules/log4j2.md#usage'] - slug: log4j support_level: production type: framework name: 'Log4j 1.x' doc_link: /clients/java/modules/log4j/ - wizard: ['_documentation/clients/java/modules/log4j.md#installation', '_documentation/clients/java/modules/log4j.md#usage'] + legacy_wizard:: ['_documentation/clients/java/modules/log4j.md#installation', '_documentation/clients/java/modules/log4j.md#usage'] - slug: appengine support_level: production type: framework name: 'Google App Engine' doc_link: /clients/java/modules/appengine/ - wizard: ['_documentation/clients/java/modules/appengine.md#installation', '_documentation/clients/java/modules/appengine.md#usage'] + legacy_wizard:: ['_documentation/clients/java/modules/appengine.md#installation', '_documentation/clients/java/modules/appengine.md#usage'] - slug: python support_level: production type: language name: Python doc_link: /platforms/python/ - # this is actually the old wizard - wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/usage.md#capture-an-error', '_documentation/clients/python/usage.md#reporting-an-event'] + # this is actually the old legacy_wizard: + legacy_wizard:: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/usage.md#capture-an-error', '_documentation/clients/python/usage.md#reporting-an-event'] case_style: snake_case - slug: python-legacy @@ -129,7 +129,7 @@ type: language name: Python Legacy doc_link: /clients/python/ - wizard: [] + legacy_wizard:: [] case_style: snake_case superseded_by: python - @@ -138,7 +138,7 @@ type: framework name: Pyramid doc_link: /clients/python/integrations/pyramid/ - wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/pyramid.md#pastedeploy-filter', '_documentation/clients/python/integrations/pyramid.md#logger-setup'] + legacy_wizard:: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/pyramid.md#pastedeploy-filter', '_documentation/clients/python/integrations/pyramid.md#logger-setup'] case_style: camelCase - slug: rq @@ -146,56 +146,56 @@ type: framework name: RQ doc_link: /clients/python/integrations/rq/ - wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/rq.md#usage', '_documentation/clients/python/integrations/rq.md#extended-setup'] + legacy_wizard:: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/rq.md#usage', '_documentation/clients/python/integrations/rq.md#extended-setup'] - slug: flask support_level: production type: framework name: Flask doc_link: /clients/python/integrations/flask/ - wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/flask.md#installation', '_documentation/clients/python/integrations/flask.md#setup'] + legacy_wizard:: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/flask.md#installation', '_documentation/clients/python/integrations/flask.md#setup'] - slug: django support_level: production type: framework name: Django doc_link: /clients/python/integrations/django/ - wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/django.md#setup'] + legacy_wizard:: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/django.md#setup'] - slug: celery support_level: production type: library name: Celery doc_link: /clients/python/integrations/celery/ - wizard: ['_documentation/clients/python/index.md#installation', _documentation/clients/python/integrations/celery.md] + legacy_wizard:: ['_documentation/clients/python/index.md#installation', _documentation/clients/python/integrations/celery.md] - slug: tornado support_level: production type: framework name: Tornado doc_link: /clients/python/integrations/tornado/ - wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/tornado.md#setup', '_documentation/clients/python/integrations/tornado.md#usage'] + legacy_wizard:: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/tornado.md#setup', '_documentation/clients/python/integrations/tornado.md#usage'] - slug: bottle support_level: production type: framework name: Bottle doc_link: /clients/python/integrations/bottle/ - wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/bottle.md#setup', '_documentation/clients/python/integrations/bottle.md#usage'] + legacy_wizard:: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/bottle.md#setup', '_documentation/clients/python/integrations/bottle.md#usage'] - slug: pylons support_level: production type: framework name: Pylons doc_link: /clients/python/integrations/pylons/ - wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/pylons.md#wsgi-middleware', '_documentation/clients/python/integrations/pylons.md#logger-setup'] + legacy_wizard:: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/pylons.md#wsgi-middleware', '_documentation/clients/python/integrations/pylons.md#logger-setup'] - slug: swift support_level: production type: language name: Swift doc_link: /clients/cocoa/ - wizard: ['_documentation/clients/cocoa/index.md#installation', '_documentation/clients/cocoa/index.md#configuration', '_documentation/clients/cocoa/index.md#debug-symbols', '_documentation/clients/cocoa/dsym.md#upload-symbols-with-sentry-cli'] + legacy_wizard:: ['_documentation/clients/cocoa/index.md#installation', '_documentation/clients/cocoa/index.md#configuration', '_documentation/clients/cocoa/index.md#debug-symbols', '_documentation/clients/cocoa/dsym.md#upload-symbols-with-sentry-cli'] version: 4.1.0 version_key: SENTRY_COCOA_TAG - @@ -204,7 +204,7 @@ type: language name: Browser Javascript doc_link: /clients/javascript/ - wizard: [] + legacy_wizard:: [] case_style: camelCase fallback_platform: javascript - @@ -213,17 +213,17 @@ type: language name: JavaScript doc_link: /platforms/javascript/ - # this is actually the old wizard - wizard: ['_documentation/clients/javascript/index.md#installation', '_documentation/clients/javascript/index.md#configuring-the-client', '_documentation/clients/javascript/index.md#manually-reporting-errors'] + # this is actually the old legacy_wizard: + legacy_wizard:: ['_documentation/clients/javascript/index.md#installation', '_documentation/clients/javascript/index.md#configuring-the-client', '_documentation/clients/javascript/index.md#manually-reporting-errors'] case_style: camelCase - superseded_by: + superseded_by: - slug: javascript-legacy support_level: production type: language name: JavaScript doc_link: /clients/javascript/ - wizard: [] + legacy_wizard:: [] version: 3.26.4 version_key: RAVEN_VERSION case_style: camelCase @@ -234,7 +234,7 @@ type: framework name: Vue doc_link: /clients/javascript/integrations/vue/ - wizard: ['_documentation/clients/javascript/integrations/vue.md#installation'] + legacy_wizard:: ['_documentation/clients/javascript/integrations/vue.md#installation'] version: 3.26.4 version_key: RAVEN_VERSION - @@ -243,7 +243,7 @@ type: framework name: Backbone doc_link: /clients/javascript/integrations/backbone/ - wizard: ['_documentation/clients/javascript/integrations/backbone.md#installation', '_documentation/clients/javascript/integrations/backbone.md#configuring-the-client'] + legacy_wizard:: ['_documentation/clients/javascript/integrations/backbone.md#installation', '_documentation/clients/javascript/integrations/backbone.md#configuring-the-client'] version: 3.26.4 version_key: RAVEN_VERSION - @@ -252,7 +252,7 @@ type: framework name: Ember doc_link: /clients/javascript/integrations/ember/ - wizard: ['_documentation/clients/javascript/integrations/ember.md#installation'] + legacy_wizard:: ['_documentation/clients/javascript/integrations/ember.md#installation'] version: 3.26.4 version_key: RAVEN_VERSION - @@ -261,7 +261,7 @@ type: framework name: React doc_link: /clients/javascript/integrations/react/ - wizard: ['_documentation/clients/javascript/integrations/react.md#installation', '_documentation/clients/javascript/integrations/react.md#configuring-the-client'] + legacy_wizard:: ['_documentation/clients/javascript/integrations/react.md#installation', '_documentation/clients/javascript/integrations/react.md#configuring-the-client'] version: 3.26.4 version_key: RAVEN_VERSION - @@ -270,7 +270,7 @@ type: framework name: AngularJS doc_link: /clients/javascript/integrations/angularjs/ - wizard: ['_documentation/clients/javascript/integrations/angularjs.md#installation', '_documentation/clients/javascript/integrations/angularjs.md#angularjs-configuration'] + legacy_wizard:: ['_documentation/clients/javascript/integrations/angularjs.md#installation', '_documentation/clients/javascript/integrations/angularjs.md#angularjs-configuration'] version: 3.26.4 version_key: RAVEN_VERSION - @@ -279,7 +279,7 @@ type: framework name: Angular doc_link: /clients/javascript/integrations/angular/ - wizard: ['_documentation/clients/javascript/integrations/angular.md#installation', '_documentation/clients/javascript/integrations/angular.md#configuration'] + legacy_wizard:: ['_documentation/clients/javascript/integrations/angular.md#installation', '_documentation/clients/javascript/integrations/angular.md#configuration'] version: 3.26.4 version_key: RAVEN_VERSION - @@ -288,7 +288,7 @@ type: language name: Electron doc_link: /clients/electron/ - wizard: ['_documentation/clients/electron/index.md#installation', '_documentation/clients/electron/index.md#configuring-the-client'] + legacy_wizard:: ['_documentation/clients/electron/index.md#installation', '_documentation/clients/electron/index.md#configuring-the-client'] case_style: camelCase fallback_platform: javascript - @@ -297,7 +297,7 @@ type: language name: Elixir doc_link: /clients/elixir/ - wizard: ['_documentation/clients/elixir/index.md#installation', '_documentation/clients/elixir/index.md#configuration', '_documentation/clients/elixir/usage.md#capturing-errors'] + legacy_wizard:: ['_documentation/clients/elixir/index.md#installation', '_documentation/clients/elixir/index.md#configuration', '_documentation/clients/elixir/usage.md#capturing-errors'] case_style: PascalCase - slug: cocoa @@ -305,14 +305,14 @@ type: language name: React-Native doc_link: /clients/react-native/ - wizard: ['_documentation/clients/react-native/index.md#installation', '_documentation/clients/react-native/index.md#client-configuration'] + legacy_wizard:: ['_documentation/clients/react-native/index.md#installation', '_documentation/clients/react-native/index.md#client-configuration'] - slug: objc support_level: production type: language name: Objective-C doc_link: /clients/cocoa/ - wizard: ['_documentation/clients/cocoa/index.md#installation', '_documentation/clients/cocoa/index.md#configuration', '_documentation/clients/cocoa/index.md#debug-symbols', '_documentation/clients/cocoa/dsym.md#upload-symbols-with-sentry-cli'] + legacy_wizard:: ['_documentation/clients/cocoa/index.md#installation', '_documentation/clients/cocoa/index.md#configuration', '_documentation/clients/cocoa/index.md#debug-symbols', '_documentation/clients/cocoa/dsym.md#upload-symbols-with-sentry-cli'] version: 4.1.0 version_key: SENTRY_COCOA_TAG - @@ -322,8 +322,8 @@ type: language name: 'C#' doc_link: /platforms/dotnet/ - # this is actually the old wizard - wizard: ['_documentation/clients/csharp/index.md#installation', '_documentation/clients/csharp/index.md#capturing-exceptions'] + # this is actually the old legacy_wizard: + legacy_wizard:: ['_documentation/clients/csharp/index.md#installation', '_documentation/clients/csharp/index.md#capturing-exceptions'] case_style: PascalCase - slug: csharp-legacy @@ -331,7 +331,7 @@ type: language name: 'C#' doc_link: /clients/csharp/ - wizard: [] + legacy_wizard:: [] case_style: PascalCase superseded_by: csharp - @@ -340,70 +340,70 @@ type: language name: Go doc_link: /clients/go/ - wizard: ['_documentation/clients/go/index.md#installation', '_documentation/clients/go/index.md#configuring-the-client', '_documentation/clients/go/index.md#reporting-errors', '_documentation/clients/go/index.md#reporting-panics'] + legacy_wizard:: ['_documentation/clients/go/index.md#installation', '_documentation/clients/go/index.md#configuring-the-client', '_documentation/clients/go/index.md#reporting-errors', '_documentation/clients/go/index.md#reporting-panics'] - slug: http support_level: in-development type: framework name: net/http doc_link: /clients/go/integrations/http/ - wizard: ['_documentation/clients/go/integrations/http.md#installation', '_documentation/clients/go/integrations/http.md#setup'] + legacy_wizard:: ['_documentation/clients/go/integrations/http.md#installation', '_documentation/clients/go/integrations/http.md#setup'] - slug: laravel support_level: production type: framework name: Laravel doc_link: /clients/php/integrations/laravel/ - wizard: ['_documentation/clients/php/integrations/laravel.md#laravel-5-x', '_documentation/clients/php/integrations/laravel.md#laravel-4-x', '_documentation/clients/php/integrations/laravel.md#lumen-5-x'] + legacy_wizard:: ['_documentation/clients/php/integrations/laravel.md#laravel-5-x', '_documentation/clients/php/integrations/laravel.md#laravel-4-x', '_documentation/clients/php/integrations/laravel.md#lumen-5-x'] - slug: php support_level: production type: language name: PHP doc_link: /clients/php/ - wizard: ['_documentation/clients/php/index.md#installation', '_documentation/clients/php/index.md#configuration', '_documentation/clients/php/usage.md#capturing-errors'] + legacy_wizard:: ['_documentation/clients/php/index.md#installation', '_documentation/clients/php/index.md#configuration', '_documentation/clients/php/usage.md#capturing-errors'] - slug: monolog support_level: production type: framework name: Monolog doc_link: /clients/php/integrations/monolog/ - wizard: ['_documentation/clients/php/index.md#installation', _documentation/clients/php/integrations/monolog.md] + legacy_wizard:: ['_documentation/clients/php/index.md#installation', _documentation/clients/php/integrations/monolog.md] - slug: symfony2 support_level: production type: framework name: Symfony2 doc_link: /clients/php/integrations/symfony2/ - wizard: ['_documentation/clients/php/integrations/symfony2.md#symfony-2'] + legacy_wizard:: ['_documentation/clients/php/integrations/symfony2.md#symfony-2'] - slug: ruby support_level: production type: language name: Ruby doc_link: /clients/ruby/ - wizard: ['_documentation/clients/ruby/index.md#installation', '_documentation/clients/ruby/index.md#configuration', '_documentation/clients/ruby/index.md#reporting-failures'] + legacy_wizard:: ['_documentation/clients/ruby/index.md#installation', '_documentation/clients/ruby/index.md#configuration', '_documentation/clients/ruby/index.md#reporting-failures'] - slug: rack support_level: production type: framework name: Rack doc_link: /clients/ruby/integrations/rack/ - wizard: [_documentation/clients/ruby/integrations/rack.md] + legacy_wizard:: [_documentation/clients/ruby/integrations/rack.md] - slug: rails support_level: production type: framework name: Rails doc_link: /clients/ruby/integrations/rails/ - wizard: [_documentation/clients/ruby/integrations/rails.md] + legacy_wizard:: [_documentation/clients/ruby/integrations/rails.md] - slug: rust support_level: production type: language name: Rust doc_link: /platforms/rust/ - wizard: ['_documentation/platforms/rust/index.md#installation', '_documentation/platforms/rust/index.md#configuring-the-client', '_documentation/platforms/rust/index.md#reporting-errors', '_documentation/platforms/rust/index.md#catching-panics'] + legacy_wizard:: ['_documentation/platforms/rust/index.md#installation', '_documentation/platforms/rust/index.md#configuring-the-client', '_documentation/platforms/rust/index.md#reporting-errors', '_documentation/platforms/rust/index.md#catching-panics'] version: 0.6.0 version_key: SENTRY_VERSION case_style: snake_case @@ -413,4 +413,4 @@ type: language name: Minidump doc_link: /platforms/minidump/ - wizard: ['_documentation/platforms/minidump/index.md#platform-and-language-support', '_documentation/platforms/minidump/index.md#creating-and-uploading-minidumps'] + legacy_wizard:: ['_documentation/platforms/minidump/index.md#platform-and-language-support', '_documentation/platforms/minidump/index.md#creating-and-uploading-minidumps'] diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index 7a132ab6b78ef..8f4286fd88ab6 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -80,11 +80,12 @@ def generate(site) # Generate each file site.data["platforms"].each do |platform| - return nil if platform["wizard"].nil? - + return nil if platform["legacy_wizard"].nil? + body = "" - platform["wizard"].each do |wiz| + platform["legacy_wizard"].each do |wiz| file, section = wiz.split '#' + p docs[file], file section ||= :document if docs[file][section].nil? raise "Cannot find section '#{section}' in #{file}" From 89b717d40e79dad257c3b1f78ee4aaa05b76b312 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Wed, 12 Sep 2018 13:16:31 -0700 Subject: [PATCH 095/171] mark cordova for new wizard --- src/_data/platforms.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index 5a85e7e8ebdcd..bffc2fa2bce41 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -48,7 +48,7 @@ type: language name: Cordova doc_link: /clients/cordova/ - legacy_wizard:: ['_documentation/clients/cordova/index.md#installation', '_documentation/clients/cordova/index.md#configuration'] + wizard: true case_style: camelCase fallback_platform: javascript - From 33a5e8ddd641a39a09dbd1afa09a096960e447d0 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Wed, 12 Sep 2018 13:22:42 -0700 Subject: [PATCH 096/171] fix :: --- src/_data/platforms.yml | 98 ++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index bffc2fa2bce41..7da8a88022537 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -4,7 +4,7 @@ type: framework name: Koa doc_link: /clients/node/integrations/koa/ - legacy_wizard:: ['_documentation/clients/node/index.md#installation', _documentation/clients/node/integrations/koa.md] + legacy_wizard: ['_documentation/clients/node/index.md#installation', _documentation/clients/node/integrations/koa.md] - slug: node support_level: production @@ -13,7 +13,7 @@ # XXX: does this have a better link? doc_link: /platforms/javascript/ # this is actually the old legacy_wizard: - legacy_wizard:: ['_documentation/clients/node/index.md#installation', '_documentation/clients/node/index.md#configuring-the-client', '_documentation/clients/node/index.md#reporting-errors'] + legacy_wizard: ['_documentation/clients/node/index.md#installation', '_documentation/clients/node/index.md#configuring-the-client', '_documentation/clients/node/index.md#reporting-errors'] case_style: camelCase fallback_platform: javascript - @@ -22,7 +22,7 @@ type: language name: Node.js doc_link: /clients/node/ - legacy_wizard:: ['_documentation/clients/node/index.md#installation', '_documentation/clients/node/index.md#configuring-the-client', '_documentation/clients/node/index.md#reporting-errors'] + legacy_wizard: ['_documentation/clients/node/index.md#installation', '_documentation/clients/node/index.md#configuring-the-client', '_documentation/clients/node/index.md#reporting-errors'] case_style: camelCase fallback_platform: javascript superseded_by: node @@ -33,7 +33,7 @@ name: Express # XXX: this links to the old ones doc_link: /clients/node/integrations/express/ - legacy_wizard:: ['_documentation/clients/node/index.md#installation', _documentation/clients/node/integrations/express.md] + legacy_wizard: ['_documentation/clients/node/index.md#installation', _documentation/clients/node/integrations/express.md] - slug: connect support_level: production @@ -41,7 +41,7 @@ name: Connect # XXX: this links to the old ones doc_link: /clients/node/integrations/connect/ - legacy_wizard:: ['_documentation/clients/node/index.md#installation', _documentation/clients/node/integrations/connect.md] + legacy_wizard: ['_documentation/clients/node/index.md#installation', _documentation/clients/node/integrations/connect.md] - slug: cordova support_level: production @@ -71,49 +71,49 @@ type: language name: Java doc_link: /clients/java/ - legacy_wizard:: ['_documentation/clients/java/usage.md#installation', '_documentation/clients/java/usage.md#capture-an-error'] + legacy_wizard: ['_documentation/clients/java/usage.md#installation', '_documentation/clients/java/usage.md#capture-an-error'] - slug: logging support_level: production type: framework name: java.util.logging doc_link: /clients/java/modules/jul/ - legacy_wizard:: ['_documentation/clients/java/modules/jul.md#installation', '_documentation/clients/java/modules/jul.md#usage'] + legacy_wizard: ['_documentation/clients/java/modules/jul.md#installation', '_documentation/clients/java/modules/jul.md#usage'] - slug: logback support_level: production type: framework name: Logback doc_link: /clients/java/modules/logback/ - legacy_wizard:: ['_documentation/clients/java/modules/logback.md#installation', '_documentation/clients/java/modules/logback.md#usage'] + legacy_wizard: ['_documentation/clients/java/modules/logback.md#installation', '_documentation/clients/java/modules/logback.md#usage'] - slug: android support_level: production type: framework name: Android doc_link: /clients/java/modules/android/ - legacy_wizard:: ['_documentation/clients/java/modules/android.md#installation', '_documentation/clients/java/modules/android.md#usage'] + legacy_wizard: ['_documentation/clients/java/modules/android.md#installation', '_documentation/clients/java/modules/android.md#usage'] - slug: log4j2 support_level: production type: framework name: 'Log4j 2.x' doc_link: /clients/java/modules/log4j2/ - legacy_wizard:: ['_documentation/clients/java/modules/log4j2.md#installation', '_documentation/clients/java/modules/log4j2.md#usage'] + legacy_wizard: ['_documentation/clients/java/modules/log4j2.md#installation', '_documentation/clients/java/modules/log4j2.md#usage'] - slug: log4j support_level: production type: framework name: 'Log4j 1.x' doc_link: /clients/java/modules/log4j/ - legacy_wizard:: ['_documentation/clients/java/modules/log4j.md#installation', '_documentation/clients/java/modules/log4j.md#usage'] + legacy_wizard: ['_documentation/clients/java/modules/log4j.md#installation', '_documentation/clients/java/modules/log4j.md#usage'] - slug: appengine support_level: production type: framework name: 'Google App Engine' doc_link: /clients/java/modules/appengine/ - legacy_wizard:: ['_documentation/clients/java/modules/appengine.md#installation', '_documentation/clients/java/modules/appengine.md#usage'] + legacy_wizard: ['_documentation/clients/java/modules/appengine.md#installation', '_documentation/clients/java/modules/appengine.md#usage'] - slug: python support_level: production @@ -121,7 +121,7 @@ name: Python doc_link: /platforms/python/ # this is actually the old legacy_wizard: - legacy_wizard:: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/usage.md#capture-an-error', '_documentation/clients/python/usage.md#reporting-an-event'] + legacy_wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/usage.md#capture-an-error', '_documentation/clients/python/usage.md#reporting-an-event'] case_style: snake_case - slug: python-legacy @@ -129,7 +129,7 @@ type: language name: Python Legacy doc_link: /clients/python/ - legacy_wizard:: [] + legacy_wizard: [] case_style: snake_case superseded_by: python - @@ -138,7 +138,7 @@ type: framework name: Pyramid doc_link: /clients/python/integrations/pyramid/ - legacy_wizard:: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/pyramid.md#pastedeploy-filter', '_documentation/clients/python/integrations/pyramid.md#logger-setup'] + legacy_wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/pyramid.md#pastedeploy-filter', '_documentation/clients/python/integrations/pyramid.md#logger-setup'] case_style: camelCase - slug: rq @@ -146,56 +146,56 @@ type: framework name: RQ doc_link: /clients/python/integrations/rq/ - legacy_wizard:: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/rq.md#usage', '_documentation/clients/python/integrations/rq.md#extended-setup'] + legacy_wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/rq.md#usage', '_documentation/clients/python/integrations/rq.md#extended-setup'] - slug: flask support_level: production type: framework name: Flask doc_link: /clients/python/integrations/flask/ - legacy_wizard:: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/flask.md#installation', '_documentation/clients/python/integrations/flask.md#setup'] + legacy_wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/flask.md#installation', '_documentation/clients/python/integrations/flask.md#setup'] - slug: django support_level: production type: framework name: Django doc_link: /clients/python/integrations/django/ - legacy_wizard:: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/django.md#setup'] + legacy_wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/django.md#setup'] - slug: celery support_level: production type: library name: Celery doc_link: /clients/python/integrations/celery/ - legacy_wizard:: ['_documentation/clients/python/index.md#installation', _documentation/clients/python/integrations/celery.md] + legacy_wizard: ['_documentation/clients/python/index.md#installation', _documentation/clients/python/integrations/celery.md] - slug: tornado support_level: production type: framework name: Tornado doc_link: /clients/python/integrations/tornado/ - legacy_wizard:: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/tornado.md#setup', '_documentation/clients/python/integrations/tornado.md#usage'] + legacy_wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/tornado.md#setup', '_documentation/clients/python/integrations/tornado.md#usage'] - slug: bottle support_level: production type: framework name: Bottle doc_link: /clients/python/integrations/bottle/ - legacy_wizard:: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/bottle.md#setup', '_documentation/clients/python/integrations/bottle.md#usage'] + legacy_wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/bottle.md#setup', '_documentation/clients/python/integrations/bottle.md#usage'] - slug: pylons support_level: production type: framework name: Pylons doc_link: /clients/python/integrations/pylons/ - legacy_wizard:: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/pylons.md#wsgi-middleware', '_documentation/clients/python/integrations/pylons.md#logger-setup'] + legacy_wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/pylons.md#wsgi-middleware', '_documentation/clients/python/integrations/pylons.md#logger-setup'] - slug: swift support_level: production type: language name: Swift doc_link: /clients/cocoa/ - legacy_wizard:: ['_documentation/clients/cocoa/index.md#installation', '_documentation/clients/cocoa/index.md#configuration', '_documentation/clients/cocoa/index.md#debug-symbols', '_documentation/clients/cocoa/dsym.md#upload-symbols-with-sentry-cli'] + legacy_wizard: ['_documentation/clients/cocoa/index.md#installation', '_documentation/clients/cocoa/index.md#configuration', '_documentation/clients/cocoa/index.md#debug-symbols', '_documentation/clients/cocoa/dsym.md#upload-symbols-with-sentry-cli'] version: 4.1.0 version_key: SENTRY_COCOA_TAG - @@ -204,7 +204,7 @@ type: language name: Browser Javascript doc_link: /clients/javascript/ - legacy_wizard:: [] + legacy_wizard: [] case_style: camelCase fallback_platform: javascript - @@ -214,7 +214,7 @@ name: JavaScript doc_link: /platforms/javascript/ # this is actually the old legacy_wizard: - legacy_wizard:: ['_documentation/clients/javascript/index.md#installation', '_documentation/clients/javascript/index.md#configuring-the-client', '_documentation/clients/javascript/index.md#manually-reporting-errors'] + legacy_wizard: ['_documentation/clients/javascript/index.md#installation', '_documentation/clients/javascript/index.md#configuring-the-client', '_documentation/clients/javascript/index.md#manually-reporting-errors'] case_style: camelCase superseded_by: - @@ -223,7 +223,7 @@ type: language name: JavaScript doc_link: /clients/javascript/ - legacy_wizard:: [] + legacy_wizard: [] version: 3.26.4 version_key: RAVEN_VERSION case_style: camelCase @@ -234,7 +234,7 @@ type: framework name: Vue doc_link: /clients/javascript/integrations/vue/ - legacy_wizard:: ['_documentation/clients/javascript/integrations/vue.md#installation'] + legacy_wizard: ['_documentation/clients/javascript/integrations/vue.md#installation'] version: 3.26.4 version_key: RAVEN_VERSION - @@ -243,7 +243,7 @@ type: framework name: Backbone doc_link: /clients/javascript/integrations/backbone/ - legacy_wizard:: ['_documentation/clients/javascript/integrations/backbone.md#installation', '_documentation/clients/javascript/integrations/backbone.md#configuring-the-client'] + legacy_wizard: ['_documentation/clients/javascript/integrations/backbone.md#installation', '_documentation/clients/javascript/integrations/backbone.md#configuring-the-client'] version: 3.26.4 version_key: RAVEN_VERSION - @@ -252,7 +252,7 @@ type: framework name: Ember doc_link: /clients/javascript/integrations/ember/ - legacy_wizard:: ['_documentation/clients/javascript/integrations/ember.md#installation'] + legacy_wizard: ['_documentation/clients/javascript/integrations/ember.md#installation'] version: 3.26.4 version_key: RAVEN_VERSION - @@ -261,7 +261,7 @@ type: framework name: React doc_link: /clients/javascript/integrations/react/ - legacy_wizard:: ['_documentation/clients/javascript/integrations/react.md#installation', '_documentation/clients/javascript/integrations/react.md#configuring-the-client'] + legacy_wizard: ['_documentation/clients/javascript/integrations/react.md#installation', '_documentation/clients/javascript/integrations/react.md#configuring-the-client'] version: 3.26.4 version_key: RAVEN_VERSION - @@ -270,7 +270,7 @@ type: framework name: AngularJS doc_link: /clients/javascript/integrations/angularjs/ - legacy_wizard:: ['_documentation/clients/javascript/integrations/angularjs.md#installation', '_documentation/clients/javascript/integrations/angularjs.md#angularjs-configuration'] + legacy_wizard: ['_documentation/clients/javascript/integrations/angularjs.md#installation', '_documentation/clients/javascript/integrations/angularjs.md#angularjs-configuration'] version: 3.26.4 version_key: RAVEN_VERSION - @@ -279,7 +279,7 @@ type: framework name: Angular doc_link: /clients/javascript/integrations/angular/ - legacy_wizard:: ['_documentation/clients/javascript/integrations/angular.md#installation', '_documentation/clients/javascript/integrations/angular.md#configuration'] + legacy_wizard: ['_documentation/clients/javascript/integrations/angular.md#installation', '_documentation/clients/javascript/integrations/angular.md#configuration'] version: 3.26.4 version_key: RAVEN_VERSION - @@ -288,7 +288,7 @@ type: language name: Electron doc_link: /clients/electron/ - legacy_wizard:: ['_documentation/clients/electron/index.md#installation', '_documentation/clients/electron/index.md#configuring-the-client'] + legacy_wizard: ['_documentation/clients/electron/index.md#installation', '_documentation/clients/electron/index.md#configuring-the-client'] case_style: camelCase fallback_platform: javascript - @@ -297,7 +297,7 @@ type: language name: Elixir doc_link: /clients/elixir/ - legacy_wizard:: ['_documentation/clients/elixir/index.md#installation', '_documentation/clients/elixir/index.md#configuration', '_documentation/clients/elixir/usage.md#capturing-errors'] + legacy_wizard: ['_documentation/clients/elixir/index.md#installation', '_documentation/clients/elixir/index.md#configuration', '_documentation/clients/elixir/usage.md#capturing-errors'] case_style: PascalCase - slug: cocoa @@ -305,14 +305,14 @@ type: language name: React-Native doc_link: /clients/react-native/ - legacy_wizard:: ['_documentation/clients/react-native/index.md#installation', '_documentation/clients/react-native/index.md#client-configuration'] + legacy_wizard: ['_documentation/clients/react-native/index.md#installation', '_documentation/clients/react-native/index.md#client-configuration'] - slug: objc support_level: production type: language name: Objective-C doc_link: /clients/cocoa/ - legacy_wizard:: ['_documentation/clients/cocoa/index.md#installation', '_documentation/clients/cocoa/index.md#configuration', '_documentation/clients/cocoa/index.md#debug-symbols', '_documentation/clients/cocoa/dsym.md#upload-symbols-with-sentry-cli'] + legacy_wizard: ['_documentation/clients/cocoa/index.md#installation', '_documentation/clients/cocoa/index.md#configuration', '_documentation/clients/cocoa/index.md#debug-symbols', '_documentation/clients/cocoa/dsym.md#upload-symbols-with-sentry-cli'] version: 4.1.0 version_key: SENTRY_COCOA_TAG - @@ -323,7 +323,7 @@ name: 'C#' doc_link: /platforms/dotnet/ # this is actually the old legacy_wizard: - legacy_wizard:: ['_documentation/clients/csharp/index.md#installation', '_documentation/clients/csharp/index.md#capturing-exceptions'] + legacy_wizard: ['_documentation/clients/csharp/index.md#installation', '_documentation/clients/csharp/index.md#capturing-exceptions'] case_style: PascalCase - slug: csharp-legacy @@ -331,7 +331,7 @@ type: language name: 'C#' doc_link: /clients/csharp/ - legacy_wizard:: [] + legacy_wizard: [] case_style: PascalCase superseded_by: csharp - @@ -340,70 +340,70 @@ type: language name: Go doc_link: /clients/go/ - legacy_wizard:: ['_documentation/clients/go/index.md#installation', '_documentation/clients/go/index.md#configuring-the-client', '_documentation/clients/go/index.md#reporting-errors', '_documentation/clients/go/index.md#reporting-panics'] + legacy_wizard: ['_documentation/clients/go/index.md#installation', '_documentation/clients/go/index.md#configuring-the-client', '_documentation/clients/go/index.md#reporting-errors', '_documentation/clients/go/index.md#reporting-panics'] - slug: http support_level: in-development type: framework name: net/http doc_link: /clients/go/integrations/http/ - legacy_wizard:: ['_documentation/clients/go/integrations/http.md#installation', '_documentation/clients/go/integrations/http.md#setup'] + legacy_wizard: ['_documentation/clients/go/integrations/http.md#installation', '_documentation/clients/go/integrations/http.md#setup'] - slug: laravel support_level: production type: framework name: Laravel doc_link: /clients/php/integrations/laravel/ - legacy_wizard:: ['_documentation/clients/php/integrations/laravel.md#laravel-5-x', '_documentation/clients/php/integrations/laravel.md#laravel-4-x', '_documentation/clients/php/integrations/laravel.md#lumen-5-x'] + legacy_wizard: ['_documentation/clients/php/integrations/laravel.md#laravel-5-x', '_documentation/clients/php/integrations/laravel.md#laravel-4-x', '_documentation/clients/php/integrations/laravel.md#lumen-5-x'] - slug: php support_level: production type: language name: PHP doc_link: /clients/php/ - legacy_wizard:: ['_documentation/clients/php/index.md#installation', '_documentation/clients/php/index.md#configuration', '_documentation/clients/php/usage.md#capturing-errors'] + legacy_wizard: ['_documentation/clients/php/index.md#installation', '_documentation/clients/php/index.md#configuration', '_documentation/clients/php/usage.md#capturing-errors'] - slug: monolog support_level: production type: framework name: Monolog doc_link: /clients/php/integrations/monolog/ - legacy_wizard:: ['_documentation/clients/php/index.md#installation', _documentation/clients/php/integrations/monolog.md] + legacy_wizard: ['_documentation/clients/php/index.md#installation', _documentation/clients/php/integrations/monolog.md] - slug: symfony2 support_level: production type: framework name: Symfony2 doc_link: /clients/php/integrations/symfony2/ - legacy_wizard:: ['_documentation/clients/php/integrations/symfony2.md#symfony-2'] + legacy_wizard: ['_documentation/clients/php/integrations/symfony2.md#symfony-2'] - slug: ruby support_level: production type: language name: Ruby doc_link: /clients/ruby/ - legacy_wizard:: ['_documentation/clients/ruby/index.md#installation', '_documentation/clients/ruby/index.md#configuration', '_documentation/clients/ruby/index.md#reporting-failures'] + legacy_wizard: ['_documentation/clients/ruby/index.md#installation', '_documentation/clients/ruby/index.md#configuration', '_documentation/clients/ruby/index.md#reporting-failures'] - slug: rack support_level: production type: framework name: Rack doc_link: /clients/ruby/integrations/rack/ - legacy_wizard:: [_documentation/clients/ruby/integrations/rack.md] + legacy_wizard: [_documentation/clients/ruby/integrations/rack.md] - slug: rails support_level: production type: framework name: Rails doc_link: /clients/ruby/integrations/rails/ - legacy_wizard:: [_documentation/clients/ruby/integrations/rails.md] + legacy_wizard: [_documentation/clients/ruby/integrations/rails.md] - slug: rust support_level: production type: language name: Rust doc_link: /platforms/rust/ - legacy_wizard:: ['_documentation/platforms/rust/index.md#installation', '_documentation/platforms/rust/index.md#configuring-the-client', '_documentation/platforms/rust/index.md#reporting-errors', '_documentation/platforms/rust/index.md#catching-panics'] + legacy_wizard: ['_documentation/platforms/rust/index.md#installation', '_documentation/platforms/rust/index.md#configuring-the-client', '_documentation/platforms/rust/index.md#reporting-errors', '_documentation/platforms/rust/index.md#catching-panics'] version: 0.6.0 version_key: SENTRY_VERSION case_style: snake_case @@ -413,4 +413,4 @@ type: language name: Minidump doc_link: /platforms/minidump/ - legacy_wizard:: ['_documentation/platforms/minidump/index.md#platform-and-language-support', '_documentation/platforms/minidump/index.md#creating-and-uploading-minidumps'] + legacy_wizard: ['_documentation/platforms/minidump/index.md#platform-and-language-support', '_documentation/platforms/minidump/index.md#creating-and-uploading-minidumps'] From 73074d50bba499f09da1d7b0e64c6bc2c26b26f8 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Thu, 13 Sep 2018 01:04:48 +0200 Subject: [PATCH 097/171] feat: Updated client dev docs to realities --- .../_documentation/clientdev/attributes.md | 12 +- .../_documentation/clientdev/data-handling.md | 4 +- .../_documentation/clientdev/features.md | 60 +++---- .../_documentation/clientdev/index.md | 8 +- .../clientdev/interfaces/index.md | 2 +- .../_documentation/clientdev/overview.md | 94 +++++----- .../_documentation/clientdev/scopes.md | 2 +- .../_documentation/clientdev/terminology.md | 28 --- .../_documentation/clientdev/unified-api.md | 168 ++++++++++++++++++ .../_documentation/learn/configuration.md | 4 +- 10 files changed, 261 insertions(+), 121 deletions(-) delete mode 100644 src/collections/_documentation/clientdev/terminology.md create mode 100644 src/collections/_documentation/clientdev/unified-api.md diff --git a/src/collections/_documentation/clientdev/attributes.md b/src/collections/_documentation/clientdev/attributes.md index d5b2b18d8f9ad..d93109b37a2b7 100644 --- a/src/collections/_documentation/clientdev/attributes.md +++ b/src/collections/_documentation/clientdev/attributes.md @@ -1,6 +1,6 @@ --- title: Attributes -sidebar_order: 3 +sidebar_order: 10 --- Attributes are simple data that Sentry understands to provide the most basic information about events. These are things like the unique ID of an event, the human readable message etc. @@ -117,18 +117,22 @@ Additionally, there are several optional values which Sentry recognizes and are - `info` - `debug` -`culprit` +`transaction` -: The name of the transaction (or culprit) which caused this exception. +: The name of the transaction which caused this exception For example, in a web app, this might be the route name: `/welcome/` ```json { - "culprit": "my.module.function_name" + "transaction": "/users//" } ``` +`culprit` + +: The name of the culprit which caused this exception. This attribute is deprecated. + `server_name` : Identifies the host SDK from which the event was recorded. diff --git a/src/collections/_documentation/clientdev/data-handling.md b/src/collections/_documentation/clientdev/data-handling.md index 36fbc7df3a878..55c19bd9791db 100644 --- a/src/collections/_documentation/clientdev/data-handling.md +++ b/src/collections/_documentation/clientdev/data-handling.md @@ -1,8 +1,10 @@ --- title: 'Data Handling' -sidebar_order: 5 +sidebar_order: 30 --- +Data handling is the standardized context in how we want SDKs help users filter data. + ## Sensitive Data In older SDKs you might sometimes see elaborate constructs to allow the user to strip away sensitive data. Newer SDKs no longer have this feature as it turned out to be too hard to maintain per-SDK. Instead, only two simple config options are left: diff --git a/src/collections/_documentation/clientdev/features.md b/src/collections/_documentation/clientdev/features.md index 6efc339268bee..47203b7b39ab6 100644 --- a/src/collections/_documentation/clientdev/features.md +++ b/src/collections/_documentation/clientdev/features.md @@ -1,25 +1,33 @@ --- title: 'Expected Features' -sidebar_order: 2 +sidebar_order: 4 --- -The following is a description of features that are commonly expected in Sentry SDKs. +The following is a description of features that are commonly expected in Sentry SDKs. Make sure to also +have consulated the [unified API design]({% link _documentation/clientdev/unified-api.md %}) documentation +which explains the common API design. -## Uncaught exception handler +## Background Sending -Ability for the SDK to be set as a hook to record any uncaught exceptions. At the language level this is typically a global hook provided by the language itself. For framework intergations this is typically part of middleware or some other system. +Events should be transmitted in the background thread or similar system. This queue must be flushed when the +application shuts down with a specific timeout. This feature is typically user facing and explained +as part of [shutdown and draining]({% link _documentation/learn/draining.md %}). -## Setting Attributes +## Uncaught Exception Handler -Ability to set attributes on events sent to Sentry. They should be configurable “globally” on the client itself (so that they are sent with all future events) and also per event. Important examples are being able to set the `release`, `environment`, `tags` and `extra`. [See the attributes page]({%- link _documentation/clientdev/attributes.md -%}#attributes) for more information and examples. +Ability for the SDK to be set as a hook to record any uncaught exceptions. At the language level this is typically a global hook provided by the language itself. For framework intergations this might be part of middleware or some other system. -## Automatic Attributes +This behavior is typically provided by a default integration that can be disabled. -Automatic addition of useful attributes such as `tags` or `extra`. Typically means the SDK hooks into a framework so that it can set attributes that are known to be useful for most users. +## Scopes -## Scopes system +Scopes should be provided by SDKs to set common attributes and context data on events sent to Sentry emitted from the current scope. They should be inherited to lower scopes so that they can be set "globally" on startup. Note that some attributes can only be set in the client options (`release`, `environment`) and not on scopes. -A system for storing data that has to do with a given scope. What scope means depends on the application, for a web framework it is most likely a single request/response cycle. For a mobile application there is often just one single scope that represents the single user and their actions. Scopin g can be difficult to implement because it often has to deal with threads or concurrency and can involve deep integration with frameworks. [See the scopes page]({%- link _documentation/clientdev/scopes.md -%}#scope) for more information. +What scope means depends on the application, for a web framework it is most likely a single request/response cycle. For a mobile application there is often just one single scope that represents the single user and their actions. Scoping can be difficult to implement because it often has to deal with threads or concurrency and can involve deep integration with frameworks. [See the scopes page]({%- link _documentation/clientdev/scopes.md -%}#scope) for more information. + +## Automatic Context Data + +Automatic addition of useful attributes such as `tags` or `extra` or specific `contexts`. Typically means the SDK hooks into a framework so that it can set attributes that are known to be useful for most users. ## Breadcrumbs @@ -36,26 +44,22 @@ sample_rate = options.get('sample_rate', 1.0) # assuming random() returns a value between 0.0 (inclusive) and 1.0 (exclusive) if random() < sample_rate: - client.send(data) + transport.capture_event(event) ``` ## HTTP 429 Retry-After backoff Respect Sentry’s HTTP 429 Retry-After header when the user goes over their limits. Events should be dropped during backoff. -## Ignore patterns - -The user should be able to define exceptions that are ignored/dropped based on the error message or type. - ## In-App frames Stack parsing can tell which frames should be identified as part of the user’s application (as opposed to part of the language, a library, or a framework), either automatically or by user configuration at startup, often declared as a package/module prefix. -## Surrounding source in stacktrace +## Surrounding Source in Stacktrace Lines of source code to provide context in stacktraces. This is easier in interpreted languages, may be hard or impossible in compiled ones. -## Variable values +## Local Variables Local variable names and values for each stack frame, where possible. Restrictions apply on some platforms, for example it’s may only be possible to collect the values of parameters passed into each function, or it may be completely impossible to collect this information at all. @@ -63,33 +67,29 @@ Local variable names and values for each stack frame, where possible. Restrictio Turn compiled or obfuscated code/method names in stacktraces back into the original. Desymbolication always requires Sentry backend support. Not necessary for many languages. -## Configuration via the runtime environment - -Whether static client configuration can set/overridden by the runtime environment _without changing code_. For example, a _SENTRY_RELEASE=1.3_ environment variable that configures the client. Important so that users can package/compile their applications once and adjust Sentry config without rebuilding (very common now for all languages because of the popularity of containers). Not available or doesn’t make sense on some runtimes (browsers, mobile). - -## Retrieve last event ID +## Retrieve Last Event ID Ability to get the ID of the last event sent. Event IDs are useful for correlation, logging, customers rolling their own feedback forms, etc. -## User feedback +## User Feedback On user-facing platforms such as mobile or the browser this means first class support for requesting user feedback when an error occurs. On backend platforms, SDKs should document how to use the last event ID to prompt the user for feedback themselves. -## Pre-send hook +## Before-Send Hook -Hook called with the event **and** thrown exception (where applicable) that allow the user to decide whether an event should be sent or not. +Hook called with the event (and on some platforms the hint) that allow the user to decide whether an event should be sent or not. This can also be used to further modify the event. -## Post-send hook +## Before-Breadcrumb Hook -Hook called on success **or** error, and passed the event and exception so that users can peform actions based on events actually being sent. +Hook called with the breadcrumb (and on some platforms the hint) that allow the user to decide whether and how an breadcrumb should be sent. -## List loaded libraries +## List Loaded Libraries Include a list of loaded libraries (and versions) when sending an event. -## Buffer to disk +## Buffer to Disk Write events to disk before attempting to send, so that they can be retried in the event of a temporary network failure. Needs to implement a cap on the number of stored events. @@ -97,4 +97,4 @@ This is mostly useful on mobile clients where connectivity is often not availabl ## HTTP Proxy -Ability to use an HTTP proxy. Often easy to implement using the existing HTTP client. +Ability to use an HTTP proxy. Often easy to implement using the existing HTTP client. This should be picked up from the system config if possible or exlicit config in the client options. diff --git a/src/collections/_documentation/clientdev/index.md b/src/collections/_documentation/clientdev/index.md index d2fc92562bb44..03587190a7b57 100644 --- a/src/collections/_documentation/clientdev/index.md +++ b/src/collections/_documentation/clientdev/index.md @@ -3,12 +3,14 @@ title: 'SDK Reference' sidebar_order: 7 --- -The following is a guide for implementing a new Sentry SDK. It covers the protocol for event submission as well as guidelines for how clients should typically look and behave. +The following is a guide for implementing a new Sentry SDK based on the new +[Unified API]({% link _documentation/clientdev/unified-api.md %}). It covers +the protocol for event submission as well as guidelines for how clients should +typically look and behave. - [Overview]({%- link _documentation/clientdev/overview.md -%}) +- [Unified API]({%- link _documentation/clientdev/unified-api.md -%}) - [Expected Features]({%- link _documentation/clientdev/features.md -%}) - [Attributes]({%- link _documentation/clientdev/attributes.md -%}) - [Interfaces]({%- link _documentation/clientdev/interfaces/index.md -%}) - [Data Handling]({%- link _documentation/clientdev/data-handling.md -%}) -- [Scopes]({%- link _documentation/clientdev/scopes.md -%}) -- [Terminology]({%- link _documentation/clientdev/terminology.md -%}) diff --git a/src/collections/_documentation/clientdev/interfaces/index.md b/src/collections/_documentation/clientdev/interfaces/index.md index 5ebb004dd4611..e55025f7704df 100644 --- a/src/collections/_documentation/clientdev/interfaces/index.md +++ b/src/collections/_documentation/clientdev/interfaces/index.md @@ -1,6 +1,6 @@ --- title: Interfaces -sidebar_order: 4 +sidebar_order: 20 --- Any additional value in the payload of an event which is not an attribute ([_Attributes_]({%- link _documentation/clientdev/attributes.md -%})) is assumed to be a data interface, where the key is the Python path to the interface class name, and the value is the data expected by the interface. Interfaces are used in a variety of ways including storing stacktraces, HTTP request information, and other metadata. diff --git a/src/collections/_documentation/clientdev/overview.md b/src/collections/_documentation/clientdev/overview.md index 087c6920a9bc5..9c01383c6b12c 100644 --- a/src/collections/_documentation/clientdev/overview.md +++ b/src/collections/_documentation/clientdev/overview.md @@ -90,26 +90,18 @@ a basic message or exception: - `Sentry.captureMessage(message)` - `Sentry.captureException(exception)` -If your platform supports block statements, it is recommended that you provide something like the following: - -``` -with capture_exceptions(): - # do something that will cause an error - 1 / 0 -``` - ## Parsing the DSN SDKs are encouraged to allow arbitrary options via the constructor, but must allow the first argument as a DSN string. This string contains the following bits: ``` -'{PROTOCOL}://{PUBLIC_KEY}:{SECRET_KEY}@{HOST}/{PATH}{PROJECT_ID}' +'{PROTOCOL}://{PUBLIC_KEY}:{SECRET_KEY}@{HOST}/{PROJECT_ID}' ``` The final endpoint you’ll be sending requests to is constructed per the following: ``` -'{URI}/api/{PROJECT ID}/store/' +'{URI}/api/{PROJECT_ID}/store/' ``` For example, given the following constructor: @@ -132,7 +124,9 @@ The resulting POST request would then transmit to: ``` {% capture __alert_content -%} -If any of configuration values are not present, the SDK should notify the user immediately that they’ve misconfigured the SDK. +Note that the secret part of the DSN is optional and effectively deprecated at this point. While clients are +still supposed to honor it if supplied future versions of Sentry will entirely ignore it. The DSN parsing +code must not require the secret key to be set. {%- endcapture -%} {%- include components/alert.html title="Note" @@ -146,22 +140,27 @@ The body of the post is a string representation of a JSON object. For example, w ```json { "event_id": "fc6d8c0c43fc4630ad850ee518f1b9d0", - "culprit": "my.module.function_name", + "transaction": "my.module.function_name", "timestamp": "2011-05-02T17:41:36", "tags": { "ios_version": "4.0" }, - "exception": [{ + "exception": {"values":[{ "type": "SyntaxError", "value": "Wattttt!", "module": "__builtins__" - }] + }]} } ``` -The body of the event can carry attributes or interface values. The difference between them is that attributes are very barebones key/value pairs (for the most part) and interfaces are rich styled interface elements. Examples of attribute are `event_id` or `tags` whereas the `exception` key is an interface. +The body of the event can carry attributes or interface values. The difference +between them is that attributes are very barebones key/value pairs (for the +most part) and interfaces are rich styled interface elements. Examples of +attribute are `event_id` or `tags` whereas the `exception` key is an interface. -For a list of all supported attributes see [_Attributes_]({%- link _documentation/clientdev/attributes.md -%}). For a list of built-in interfaces see [_Interfaces_]({%- link _documentation/clientdev/interfaces/index.md -%}). +For a list of all supported attributes see [_Attributes_]({%- link +_documentation/clientdev/attributes.md -%}). For a list of built-in interfaces +see [_Interfaces_]({%- link _documentation/clientdev/interfaces/index.md -%}). ## Authentication @@ -175,6 +174,9 @@ X-Sentry-Auth: Sentry sentry_version=5, sentry_secret= ``` +The `secret_secret` must only be included if a secret key portion was contained in the DSN. Future versions +of the protocol will fully deprecate the secret key. + {% capture __alert_content -%} You should include the SDK version string in the User-Agent portion of the header, and it will be used if `sentry_client` is not sent in the auth header. {%- endcapture -%} @@ -213,13 +215,9 @@ In situations where it’s not possible to send the custom `X-Sentry-Auth` heade : The secret key which should be provided as part of the SDK configuration. - {% capture __alert_content -%} - You should only pass the secret key if you’re communicating via secure communication to the server. Client-side behavior (such as JavaScript) should use CORS, and only pass the public key. - {%- endcapture -%} - {%- include components/alert.html - title="Note" - content=__alert_content - %} + This key is effectively deprecated but for the time being should still be + emitted by SDKs as some older Sentry versions required it in most situations. + The secret key will be phased out entirely in future versions of Sentry. ## A Working Example @@ -246,11 +244,15 @@ X-Sentry-Auth: Sentry sentry_version=7, "culprit": "my.module.function_name", "timestamp": "2011-05-02T17:41:36", "message": "SyntaxError: Wattttt!", - "exception": [{ - "type": "SyntaxError", - "value": "Wattttt!", - "module": "__builtins__" - }] + "exception": { + "values": [ + { + "type": "SyntaxError", + "value": "Wattttt!", + "module": "__builtins__" + } + ] + } } ``` @@ -283,9 +285,7 @@ Client request error: Missing client version identifier ``` {% capture __alert_content -%} -The X-Sentry-Error header will always be present with the precise error message and it is the preferred way to identify the root cause. - -If it’s not available, it’s likely the request was not handled by the API server, or a critical system failure has occurred. +The X-Sentry-Error header will not always be present but it can be used to debug clients. When it can be emitted it will contain the precise error message. This header is a good way to identify the root cause. {%- endcapture -%} {%- include components/alert.html title="Note" @@ -294,28 +294,18 @@ If it’s not available, it’s likely the request was not handled by the API se ## Handling Failures -It is **highly encouraged** that your SDK handles failures from the Sentry server gracefully. This means taking care of several key things: - -- Soft failures when the Sentry server fails to respond in a reasonable amount of time (e.g. 3s) -- Exponential backoff when Sentry fails (don’t continue trying if the server is offline) -- Failover to a standard logging module on errors. - -For example, the Python SDK will log any failed requests to the Sentry server to a named logger, `sentry.errors`. It will also only retry every few seconds, based on how many consecutive failures its seen. The code for this is simple: - -```python -def should_try(self): - if self.status == self.ONLINE: - return True - interval = min(self.retry_number, 6) ** 2 - return time.time() - self.last_check > interval -``` +It is **highly encouraged** that your SDK handles failures from the Sentry server gracefully. SDKs are expected to honor the 429 status code and to not try sending until the retry-after kicks in. It's acceptable for SDKs to drop events if Sentry is unavailable instead of retrying. -## Contextual data and concurrency (scopes, contexts, hubs) +## Concurrency (Scope and Hubs) -Most of our SDKs allow the user to: +SDKs are supposed to provide standardized concurrency handling through the +concept of hubs and scopes. This is explained in more details in the +[_Concurrency_]({%- link _documentation/clientdev/unified-api.md -%}#concurrency) chapter of the unified API docs. -* Configure multiple clients (i.e. use multiple DSNs) -* Attach additional data to events +## Layer of Integratiom -Please make sure to read [_Scopes_]({%- link -_documentation/clientdev/scopes.md -%}) to learn how most SDKs implement this. +SDKs when possible are supposed to integrate on a low level which will capture as much of the runtime +as possible. This means that if an SDK can hook the runtime or a framework directly this is preferred +over requiring users to subclass specific base classes (or mix in helpers). For instance the Python +SDK will monkey patch core functionality in frameworks to automatically pick up on errors and to integrate +scope handling. diff --git a/src/collections/_documentation/clientdev/scopes.md b/src/collections/_documentation/clientdev/scopes.md index 6cb1aa9cd7164..82292fbeebe96 100644 --- a/src/collections/_documentation/clientdev/scopes.md +++ b/src/collections/_documentation/clientdev/scopes.md @@ -1,6 +1,6 @@ --- title: 'Scopes' -sidebar_order: 6 +sidebar_order: 3 --- All SDKs should have the concept of concurrency safe context storage. What this means depends on the language. The basic idea is that a user of the SDK can call a method to safely provide additional context information for all events that are about to be recorded. diff --git a/src/collections/_documentation/clientdev/terminology.md b/src/collections/_documentation/clientdev/terminology.md deleted file mode 100644 index 6a36ed636f3e1..0000000000000 --- a/src/collections/_documentation/clientdev/terminology.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: 'Terminology' -sidebar_order: 7 ---- - -This page lists a few words that you may encounter when reading the sourcecode of one of our SDKs. - -- **minimal**: A separate "facade" package that re-exports a subset of the SDK's functionality through interfaces or proxies. That package does not directly depend on the SDK, instead it should make every operation a noop if the SDK is not installed. - - The purpose of such a package is to allow random libraries to record breadcrumbs and set context data while not having a hard dependency on the SDK. - -- **hub**: An object that manages the state. An implied global thread local or similar hub exists that can be used by default. Hubs can be created manually. - -- **context**: Contexts give extra data to sentry. There are the special contexts (user and similar) and the generic ones (runtime, os, device) etc. Check out [_Contexts_]({%- link _documentation/clientdev/interfaces/contexts.md -%}) for valid keys. *Note: In older SDKs you might encounter an unrelated concept of context, which is now deprecated by scopes* - -- **tags**: Tags can be arbitrary string→string pairs by which events can be searched. Contexts are converted into tags. - -- **extra**: Truly arbitrary data attached by client users. - -- **scope**: A scope holds data that should implicitly be sent with sentry events. It can hold context data, extra parameters, level overrides, fingerprints etc. - -- **client**: A client is an object that is configured once and can be bound to the hub. The user can then auto discover the client and dispatch calls to it. Users typically do not need to work with the client directly. They either do it via the hub or static convenience functions. - -- **client options**: Are parameters that are language and runtime specific and used to configure the client. This can be release and environment but also things like which integrations to configure, how in-app works etc. - -- **transport**: The transport is an internal construct of the client that abstracts away the event sending. Typically the transport runs in a separate thread and gets events to send via a queue. The transport is responsible for sending, retrying and handling rate limits. The transport might also persist unsent events across restarts if needed. - -- **integration**: Code that provides middlewares, bindings or hooks into certain frameworks or environments, along with code that inserts those bindings and activates them. Usage for integrations does not follow a common interface. diff --git a/src/collections/_documentation/clientdev/unified-api.md b/src/collections/_documentation/clientdev/unified-api.md new file mode 100644 index 0000000000000..486a1d7c4b181 --- /dev/null +++ b/src/collections/_documentation/clientdev/unified-api.md @@ -0,0 +1,168 @@ +--- +title: 'Unified API' +sidebar_order: 2 +--- + +New Sentry SDKs should follow the unified API, use consistent terms to refer to concepts. This +documentation explains what the unified API is and why it exits. + +## Motivation + +Sentry has a wide range of SDKs that have been developed over the years by different developers +and based on different ideas. This has lead to the situation that the feature sets across the +SDKs are different, use different concepts and terms which has lead to the situation that it's +often not clear how to achive the same thing on different platforms. + +Additionally those SDKs were purely centered around error reporting through explicit clients which +meant that certain integrations (such as breadcrumbs) were often not possible. + +## Terminology + +- **minimal**: A separate "facade" package that re-exports a subset of the SDK's functionality through interfaces or proxies. That package does not directly depend on the SDK, instead it should make every operation a noop if the SDK is not installed. + + The purpose of such a package is to allow random libraries to record breadcrumbs and set context data while not having a hard dependency on the SDK. + +- **hub**: An object that manages the state. An implied global thread local or similar hub exists that can be used by default. Hubs can be created manually. + +- **scope**: A scope holds data that should implicitly be sent with sentry events. It can hold context data, extra parameters, level overrides, fingerprints etc. + +- **client**: A client is an object that is configured once and can be bound to the hub. The user can then auto discover the client and dispatch calls to it. Users typically do not need to work with the client directly. They either do it via the hub or static convenience functions. + +- **client options**: Are parameters that are language and runtime specific and used to configure the client. This can be release and environment but also things like which integrations to configure, how in-app works etc. + +- **context**: Contexts give extra data to sentry. There are the special contexts (user and similar) and the generic ones (runtime, os, device) etc. Check out [_Contexts_]({%- link _documentation/clientdev/interfaces/contexts.md -%}) for valid keys. *Note: In older SDKs you might encounter an unrelated concept of context, which is now deprecated by scopes* + +- **tags**: Tags can be arbitrary string→string pairs by which events can be searched. Contexts are converted into tags. + +- **extra**: Truly arbitrary data attached by client users. + +- **transport**: The transport is an internal construct of the client that abstracts away the event sending. Typically the transport runs in a separate thread and gets events to send via a queue. The transport is responsible for sending, retrying and handling rate limits. The transport might also persist unsent events across restarts if needed. + +- **integration**: Code that provides middlewares, bindings or hooks into certain frameworks or environments, along with code that inserts those bindings and activates them. Usage for integrations does not follow a common interface. + +## "Static API" + +The static API functions is the most common user facing API. A user just imports these functions and can start +emitting events to sentry or configuring scopes. These shortcut functions should be exported in the top-level +namespace of your package. Behind the scenes they use scopes use hubs and scopes (see [Concurrency](#concurrency) for more information) if available on that platform: + +- `capture_event(event, hint)`: Takes an already assembled event and dispatches it to the currently active hub. The event object can be a plain dictionary or a typed object whatever makes more sense in the SDK. It should follow the native protocol as close as possible ignoring platform specific renames (case styles etc.). + + For the hint parameter see [hints](#hints). + +- `capture_exception(error)`: Report an error or exception object. Depending on the platform different parameters are possible. The most obvious version accepts just an error object but also variations are possible where no error is passed and the current exception is used. + +- `capture_message(message, level)`: Reports a message. The level can be optional in language with default parameters in which case it should default to `info`. + +- `add_breadcrumb(crumb, hint)`: Adds a new breadcrumb to the scope. If the total number of breadcrumbs exceeds the `max_breadcrumbs` setting, the oldest breadcrumb should be removed in turn. This works like the Hub api with regards to what `crumb` can be. + + For the hint parameter see [hints](#hints). + +- `configure_scope(callback)`: Calls a callback with a scope object that can be reconfigured. This is used to attach contextual data for future events in the same scope. + +- `last_event_id()`: Should return the last event ID emitted by the current scope. This is for instance used to implement user feedback dialogs. + +## Concurrency + +All SDKs should have the concept of concurrency safe context storage. What this means depends on the language. The basic idea is that a user of the SDK can call a method to safely provide additional context information for all events that are about to be recorded. + +This is implemented as a thread local stack in most languages, but in some (such as JavaScript) it might be global under the assumption that this is something that makes sense in the environment. + +Here are some common concurrench patterns: + +* **Thread bound hub**: in that pattern each thread gets its own "hub" which internally manages a stack of scopes. If that pattern is followed one thread (the one that calls `init()`) becomes the "main" hub which is used as the based for newly spawned threads which will get a hub that is based on the main hub (but otherwise independent). + +* **Internally scoped hub**: On some platforms such as .NET ambient data is available in which case the Hub can internally manage the scopes. + +* **Dummy hub**: On some platforms concurrency just doesn't inherently exists. In that case the hub might be entirely absent or just be a singleton without concurrenty management. + +## Hub + +Under normal circumstances the hub consists of a client and a stack of scopes. + +The SDK maintains two variables: The *main hub* (a global variable) and the *current hub* (a variable local to the current thread or execution context, also sometimes known as async local or context local) + +The `init()` you saw in the [_Overview_]({%- link _documentation/clientdev/overview.md -%}) typically creates / reinitializes the global hub which is propagated to all new threads/execution contexts, or a hub is created per thread/execution context. + +- `Hub::new(client, scope)`: Creates a new hub with the given client and scope. The client can be reused between hubs. The scope should be owned by the hub (make a clone if necessary) + +- `Hub::new_from_top(hub)` / alternatively native constructor overloads: Creates a new hub by cloning the top stack of another hub. + +- `get_current_hub()` / `Hub::current()` / `Hub::get_current()`: Global function or static function to return the current (threads) hub + +- `get_main_hub()` / `Hub::main()` / `Hub::get_main()`: In languages where the main thread is special ("Thread bound hub" model) this returns the main thread’s hub instead of the current thread’s hub. This might not exist in all languages. + +- `Hub::capture_event` / `Hub::capture_message` / `Hub::capture_exception` Capture message / exception call into capture event. `capture_event` merges the event passed with the scope data and dispatches to the client. + +- `Hub::push_scope()`: Pushes a new scope layer that inherits the previous data. This should return a disposable or stack guard for languages where it makes sense. When the "internally scoped hub" concurrency model is used calls to this are often necessary as otherwise a scope might be accidentally incorrectly shared. + +- `Hub::with_scope(func)` (optional): In Python this could be a context manager, in Ruby a block function. Pushes and pops a scope for integration work. + +- `Hub::pop_scope()` (optional): Only exists in languages without better resource management. Better to have this function on a return value of `push_scope` or to use `with_scope`. This is also sometimes called `pop_scope_unsafe` to indicate that this method should not be used directly. + +- `Hub::configure_scope(callback)`: Invokes the callback with a mutable reference to the scope for modifiations This can also be a `with` statement in languages that have it (Python). + +- `Hub::add_breadcrumb(crumb, hint)`: Adds a breadcrumb to the current scope. + + - The argument supported should be: + - function that creates a breadcrumb + - an already created breadcrumb object + - a list of breadcrumbs optionally + - In languages where we do not have a basic form of overloading only a raw breadcrumb object should be accepted. + + For the hint parameter see [hints](#hints). + +- `Hub::client()` / `Hub::get_client()` (optional): Accessor or getter that returns the current client or `None`. + +- `Hub::bind_client(new_client)`: Binds a different client to the hub. If the hub is also the owner of the client that was created by `init` it needs to keep a reference to it still if the hub is the object responsible for disposing it. + +- `Hub::unbind_client()` (optional): Optional way to unbind for languages where `bind_client` does not accept nullables. + +- `Hub::last_event_id()`: Should return the last event ID emitted by the current scope. This is for instance used to implement user feedback dialogs. + +- `Hub::run(hub, callback)` `hub.run(callback)`, `run_in_hub(hub, callback)` (optional): Runs a callback with the hub bound as the current hub. + +### Scope + +A scope holds data that should implicitly be sent with sentry events. It can hold context data, extra parameters, level overrides, fingerprints etc. + +The user should be able to modify the current scope easily (to set extra, tags, current user), through a global function `configureScope`. `configure_scope` takes a callback function to which it passes the current scope. Here's an example from another place in the docs: + +```javascript +Sentry.configure_scope((scope) => { + scope.setExtra("character_name": "Mighty Fighter"); +}); +``` + +Why not just have a `get_current_scope()` function instead of this indirection? If the SDK is disabled (e.g. by not providing a DSN), modifying a scope is pointless because there will never be any events to send. In that situation `configure_scope` may choose not to call the callback. This is also used to more efficiently flush out scope changes in some languages. When a `with` statement is used that always executes the scope needs to be a dummy scope object. + +- `scope.set_user(data)`: Shallow merges user configuration (`email`, `username`, …). Removing user data is SDK-defined, either with a `remove_user` function or by passing nothing as data. + +- `scope.set_extra(key, value)`: Sets the extra key to an arbitrary value, overwriting a potential previous value. Removing a key is SDK-defined, either with a `remove_extra` function or by passing nothing as data. + +- `scope.set_tag(key, value)`: Sets the tag to a string value, overwriting a potential previous value. Removing a key is SDK-defined, either with a `remove_tag` function or by passing nothing as data. + +- `scope.set_context(key, value)`: Sets the context key to a value, overwriting a potential previous value. Removing a key is SDK-defined, either with a `remove_context` function or by passing nothing as data. The types are sdk specified. + +- `scope.set_fingerprint(fingerprint[])`: Sets the fingerprint to group specific events together + +- `scope.add_event_processor(processor)`: Registers an event processor function. It takes an event and returns a new event or `None` to drop it. This is the basis of many integrations. + +- `scope.add_error_processor(processor)`: Registers an error processor function. It takes an event and exception object and returns a new event or `None` to drop it. This can be used to extract additional information out of an exception object that the SDK cannot extract itself. + +- `scope.clear()`: resets a scope to default values (prevents inheriting). This never clears registered event processors. + +- `scope.apply_to_event(event[, max_breadcrumbs])`: Applies the scope data to the given event object. This also applies the event processors stored in the scope internally. Some implementations might want to set a max breadcrumbs count here. + +## Hints + +Optionally a second parameter is supported to event capturing and breadcrumb adding: a hint. + +A hint is SDK specific but provides high level information about the origin of +the event. For instance if an exception was captured the hint might carry the +original exception object. Not all SDKs are required to provide this. The +parameter however is reserved for this purpose. + +## Options + +Many options are standardized across SDKs. For a list of these refer to [the main options documentation]({% link _documentation/learn/configuration.md %}). diff --git a/src/collections/_documentation/learn/configuration.md b/src/collections/_documentation/learn/configuration.md index f2124288c445c..fc3b253e82e6c 100644 --- a/src/collections/_documentation/learn/configuration.md +++ b/src/collections/_documentation/learn/configuration.md @@ -158,7 +158,9 @@ sending. ### before-breadcrumb This function is called with an SDK specific breadcrumb object before the breadcrumb is added to the -scope. When nothing is returned from the function the breadcrumb is dropped. +scope. When nothing is returned from the function the breadcrumb is dropped. The callback typically +gets a second argument (called a "hint") which contains the original object that the breadcrumb was +created from to further customize what the breadcrumb should look like. ## Transport Options From 0f880b765b5af1cf7b9a336221d0a9fe3e25c133 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Thu, 13 Sep 2018 01:12:34 +0200 Subject: [PATCH 098/171] ref: kill scopes.md --- .../_documentation/clientdev/scopes.md | 105 ------------------ 1 file changed, 105 deletions(-) delete mode 100644 src/collections/_documentation/clientdev/scopes.md diff --git a/src/collections/_documentation/clientdev/scopes.md b/src/collections/_documentation/clientdev/scopes.md deleted file mode 100644 index 82292fbeebe96..0000000000000 --- a/src/collections/_documentation/clientdev/scopes.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: 'Scopes' -sidebar_order: 3 ---- - -All SDKs should have the concept of concurrency safe context storage. What this means depends on the language. The basic idea is that a user of the SDK can call a method to safely provide additional context information for all events that are about to be recorded. - -This is implemented as a thread local stack in most languages, but in some (such as JavaScript) it might be global under the assumption that this is something that makes sense in the environment. - -From the user's perspective of the Sentry SDK there are two relevant APIs: - -## Scope - -A scope holds data that should implicitly be sent with sentry events. It can hold context data, extra parameters, level overrides, fingerprints etc. - -The user should be able to modify the current scope easily (to set extra, tags, current user), through a global function `configureScope`. `configureScope` takes a callback function to which it passes the current scope. Here's an example from another place in the docs: - -```javascript -Sentry.configureScope((scope) => { - scope.setExtra("character_name": "Mighty Fighter"); -}); -``` - -Why not just have a `getCurrentScope()` function instead of this indirection? If the SDK is disabled (e.g. by not providing a DSN), modifying a scope is pointless because there will never be any events to send. In that situation `configureScope` may choose not to call the callback. - -- `scope.set_user(data)`: Shallow merges user configuration (`email`, `username`, …). Removing user data is SDK-defined, either with a `remove_user` function or by passing nothing as data. - -- `scope.set_extra(key, value)`: Sets the extra key to an arbitrary value, overwriting a potential previous value. Removing a key is SDK-defined, either with a `remove_extra` function or by passing nothing as data. - -- `scope.set_tag(key, value)`: Sets the tag to a string value, overwriting a potential previous value. Removing a key is SDK-defined, either with a `remove_tag` function or by passing nothing as data. - -- `scope.set_context(key, value)`: Sets the context key to a value, overwriting a potential previous value. Removing a key is SDK-defined, either with a `remove_context` function or by passing nothing as data. The types are sdk specified. - -- `scope.set_fingerprint(fingerprint[])`: Sets the fingerprint to group specific events together - -- `scope.clear()`: resets a scope to default values (prevents inheriting) - -- `scope.apply_to_event(event[, max_breadcrumbs])`: Applies the scope data to the given event object. This also applies the event processors stored in the scope internally. Some implementations might want to set a max breadcrumbs count here. - -## Hub - -The hub consists of a client and a stack of scopes. - -The SDK maintains two variables: The *global hub* (a global variable) and the *current hub* (a variable local to the current thread or execution context, also sometimes known as async local or context local) - -The `init()` you saw in the [_Overview_]({%- link _documentation/clientdev/overview.md -%}) typically creates / reinitializes the global hub which is propagated to all new threads/execution contexts, or a hub is created per thread/execution context. - -- `Hub::new(client, scope)`: Creates a new hub with the given client and scope. The client can be reused between hubs. The scope should be owned by the hub (make a clone if necessary) - -- `Hub::new_from_top(hub)` / alternatively native constructor overloads: Creates a new hub by cloning the top stack of another hub. - -- `get_current_hub()` / `Hub::current()` / `Hub::get_current()`: Global function or static function to return the current (threads) hub - -- `get_main_hub()` / `Hub::main()` / `Hub::get_main()`: In languages where the main thread is special this returns the main thread’s hub instead of the current thread’s hub. This might not exist in all languages. - -- `Hub::capture_event` / `Hub::capture_message` / `Hub::capture_exception` Capture message / exception call into capture event. `capture_event` merges the event passed with the scope data and dispatches to the client. - -- `Hub::push_scope()`: Pushes a new scope layer that inherits the previous data. This should return a disposable or stack guard for languages where it makes sense. - -- `Hub::with_scope(func)` (optional): In Python this could be a context manager, in Ruby a block function. Pushes and pops a scope for integration work. - -- `Hub::pop_scope()` (optional): Only exists in languages without better resource management. Better to have this function on a return value of `push_scope` or to use `with_scope`. - -- `Hub::configure_scope(callback)`: Invokes the callback with a mutable reference to the scope for modifiations - -- `Hub::add_breadcrumb(crumb)`: Adds a breadcrumb to the current scope. - - - The argument supported should be: - - function that creates a breadcrumb - - an already created breadcrumb object - - a list of breadcrumbs optionally - - In languages where we do not have a basic form of overloading only a raw breadcrumb object should be accepted. - -- `Hub::client()` / `Hub::get_client()` (optional): Accessor or getter that returns the current client or `None`. - -- `Hub::bind_client(new_client)`: Binds a different client to the hub. If the hub is also the owner of the client that was created by `init` it needs to keep a reference to it still if the hub is the object responsible for disposing it. - -- `Hub::unbind_client()` (optional): Optional way to unbind for languages where `bind_client` does not accept nullables. - -- `Hub::add_event_processor(callback)`: Registers a callback with the hub that returns a callback that processes a specific event. This allows the processor to hold on to closure data until the scope might have to be sent to another thread: - - - `add_event_processor(() => (event) => …))` - - - The initial closure can be persisted until the scope needs to be stored or sent to a thread after which the inner closure is retained. - -- `Hub::run(hub, callback)` `hub.run(callback)`, `run_in_hub(hub, callback)` (optional): Runs a callback with the hub bound as the current hub. - - -## Convenience functions - -The following shortcut functions should be exported in the top-level namespace of your package: - -- `capture_event(event)`: Takes an already assembled event and dispatches it to the client - -- `capture_exception(…)`: Report an error or exception. In Rust this does not exist: There are different kinds of exception types. - -- `capture_message(message, level)`: Reports a message. The level can be optional in language with default parameters. - -- `add_breadcrumb(crumb)`: Adds a new breadcrumb to the scope. If the total number of breadcrumbs exceeds the `maxBreadcrumbs` setting, the oldest breadcrumb should be removed in turn. This works like the Hub api with regards to what `crumb` can be. - -- `configure_scope(callback)`: Calls a callback with a scope object that can be reconfigured. This is used to attach contextual data for future events in the same scope. This is a convenience alias to `Hub::current().configure_scope(…)`. - -- `with_active_hub(callback)` / `Hub::with_active(callback)`: Invokes the callback which is passed the default hub if a client is bound or does nothing if the client is not bound. - - This one is intended for integrations and in some systems that might not be necessary to add. The advantage of having it means that a user cannot accidentally create a sentry structure in a disabled environment. Alternatively a user would need to check upfront if the client is active. From 74e2c43c7366abc6ba71472cf7c9b57874fbb10e Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Thu, 13 Sep 2018 01:13:14 +0200 Subject: [PATCH 099/171] fix: Fixed a broken link --- src/collections/_documentation/clientdev/features.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/collections/_documentation/clientdev/features.md b/src/collections/_documentation/clientdev/features.md index 47203b7b39ab6..a6894b0568f08 100644 --- a/src/collections/_documentation/clientdev/features.md +++ b/src/collections/_documentation/clientdev/features.md @@ -23,7 +23,7 @@ This behavior is typically provided by a default integration that can be disable Scopes should be provided by SDKs to set common attributes and context data on events sent to Sentry emitted from the current scope. They should be inherited to lower scopes so that they can be set "globally" on startup. Note that some attributes can only be set in the client options (`release`, `environment`) and not on scopes. -What scope means depends on the application, for a web framework it is most likely a single request/response cycle. For a mobile application there is often just one single scope that represents the single user and their actions. Scoping can be difficult to implement because it often has to deal with threads or concurrency and can involve deep integration with frameworks. [See the scopes page]({%- link _documentation/clientdev/scopes.md -%}#scope) for more information. +What scope means depends on the application, for a web framework it is most likely a single request/response cycle. For a mobile application there is often just one single scope that represents the single user and their actions. Scoping can be difficult to implement because it often has to deal with threads or concurrency and can involve deep integration with frameworks. [See the scopes page]({%- link _documentation/clientdev/unified-api.md -%}#scope) for more information. ## Automatic Context Data From 05e1b6ce3e91f2b77c218280fd9758ff9c3f594a Mon Sep 17 00:00:00 2001 From: HazA Date: Thu, 13 Sep 2018 12:38:27 +0200 Subject: [PATCH 100/171] feat: Update js integration docs --- src/collections/_documentation/platforms/javascript/ember.md | 5 +---- src/collections/_documentation/platforms/javascript/index.md | 1 + src/collections/_documentation/platforms/javascript/vue.md | 5 +---- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/collections/_documentation/platforms/javascript/ember.md b/src/collections/_documentation/platforms/javascript/ember.md index 146dae7dc40be..2af0f5f526da2 100644 --- a/src/collections/_documentation/platforms/javascript/ember.md +++ b/src/collections/_documentation/platforms/javascript/ember.md @@ -24,9 +24,6 @@ import * as Sentry from '@sentry/browser' Sentry.init({ dsn: '___PUBLIC_DSN___', - integrations (integrations) { - integrations.push(new Sentry.Integrations.Ember()) - return integrations - } + integrations: [new Sentry.Integrations.Ember()] }); ``` diff --git a/src/collections/_documentation/platforms/javascript/index.md b/src/collections/_documentation/platforms/javascript/index.md index 721af2f2de61d..cb1e5eca10d20 100644 --- a/src/collections/_documentation/platforms/javascript/index.md +++ b/src/collections/_documentation/platforms/javascript/index.md @@ -28,6 +28,7 @@ Sentry.init({ integrations.push(new MyCustomIntegration()) return integrations } + // integrations: [new MyCustomIntegration()] }) ``` diff --git a/src/collections/_documentation/platforms/javascript/vue.md b/src/collections/_documentation/platforms/javascript/vue.md index 98be81a4199b9..ec207db26da6b 100644 --- a/src/collections/_documentation/platforms/javascript/vue.md +++ b/src/collections/_documentation/platforms/javascript/vue.md @@ -15,9 +15,6 @@ import * as Sentry from '@sentry/browser' Sentry.init({ dsn: '___PUBLIC_DSN___', - integrations (integrations) { - integrations.push(new Sentry.Integrations.Vue({ Vue })) - return integrations - } + integrations: [new Sentry.Integrations.Vue({ Vue })] }) ``` \ No newline at end of file From 08939cc66d392f1ef6e0e1089469267dce918d0a Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Thu, 13 Sep 2018 13:29:40 +0200 Subject: [PATCH 101/171] feat(javascript): Add examples for setting environment --- .../_documentation/learn/set-environment/browser.md | 9 +++++++++ .../_documentation/learn/set-environment/cordova.md | 8 ++++++++ .../_documentation/learn/set-environment/electron.md | 7 +++++++ .../_documentation/learn/set-environment/node.md | 7 +++++++ 4 files changed, 31 insertions(+) create mode 100644 src/collections/_documentation/learn/set-environment/browser.md create mode 100644 src/collections/_documentation/learn/set-environment/cordova.md create mode 100644 src/collections/_documentation/learn/set-environment/electron.md create mode 100644 src/collections/_documentation/learn/set-environment/node.md diff --git a/src/collections/_documentation/learn/set-environment/browser.md b/src/collections/_documentation/learn/set-environment/browser.md new file mode 100644 index 0000000000000..5716d172d8324 --- /dev/null +++ b/src/collections/_documentation/learn/set-environment/browser.md @@ -0,0 +1,9 @@ +Options are passed to the `init()` as object: + +```javascript +import * as Sentry from '@sentry/browser'; + +Sentry.init({ + environment: '{{ page.example_environment }}', +}) +``` diff --git a/src/collections/_documentation/learn/set-environment/cordova.md b/src/collections/_documentation/learn/set-environment/cordova.md new file mode 100644 index 0000000000000..d01c94807fdba --- /dev/null +++ b/src/collections/_documentation/learn/set-environment/cordova.md @@ -0,0 +1,8 @@ +```javascript +onDeviceReady: function() { + var Sentry = cordova.require("sentry-cordova.Sentry"); + Sentry.init({ + environment: '{{ page.example_environment }}', + }); +} +``` diff --git a/src/collections/_documentation/learn/set-environment/electron.md b/src/collections/_documentation/learn/set-environment/electron.md new file mode 100644 index 0000000000000..36e798899cd70 --- /dev/null +++ b/src/collections/_documentation/learn/set-environment/electron.md @@ -0,0 +1,7 @@ +```javascript +import * as Sentry from '@sentry/electron'; + +Sentry.init({ + environment: '{{ page.example_environment }}', +}) +``` diff --git a/src/collections/_documentation/learn/set-environment/node.md b/src/collections/_documentation/learn/set-environment/node.md new file mode 100644 index 0000000000000..a22d40e799a76 --- /dev/null +++ b/src/collections/_documentation/learn/set-environment/node.md @@ -0,0 +1,7 @@ +```javascript +const Sentry = require('@sentry/node'); + +Sentry.init({ + environment: '{{ page.example_environment }}', +}) +``` From ca50c7bbb94c219c1f604f73bdb1ff177f1d9727 Mon Sep 17 00:00:00 2001 From: HazA Date: Thu, 13 Sep 2018 14:55:36 +0200 Subject: [PATCH 102/171] feat: Add browser report dialog --- .../learn/user-feedback-example/browser.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/collections/_documentation/learn/user-feedback-example/browser.md diff --git a/src/collections/_documentation/learn/user-feedback-example/browser.md b/src/collections/_documentation/learn/user-feedback-example/browser.md new file mode 100644 index 0000000000000..734cd2a8cf744 --- /dev/null +++ b/src/collections/_documentation/learn/user-feedback-example/browser.md @@ -0,0 +1,12 @@ +```html + + + +``` \ No newline at end of file From 9ff94dbaf21f8dd316bd052ea7e30ed7f80079b0 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Thu, 13 Sep 2018 14:58:03 +0200 Subject: [PATCH 103/171] feat: Added initial work on hints --- .../learn/before-breadcrumb/python.md | 12 ++++++++++++ .../learn/breadcrumbs-example/rust.md | 8 ++++---- src/collections/_documentation/learn/breadcrumbs.md | 10 ++++++++++ src/collections/_documentation/learn/hints.md | 6 ++++++ .../_documentation/platforms/python/index.md | 13 +++++++++++++ 5 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 src/collections/_documentation/learn/before-breadcrumb/python.md create mode 100644 src/collections/_documentation/learn/hints.md diff --git a/src/collections/_documentation/learn/before-breadcrumb/python.md b/src/collections/_documentation/learn/before-breadcrumb/python.md new file mode 100644 index 0000000000000..0dfd6a2c5acf9 --- /dev/null +++ b/src/collections/_documentation/learn/before-breadcrumb/python.md @@ -0,0 +1,12 @@ +```python +import sentry_sdk + +def before_breadcrumb(crumb, hint): + if 'log_record' in hint: + crumb['data']['filename'] = hint['log_record'].filename + return crumb + +sentry_sdk.init(before_breadcrumb=before_breadcrumb) +``` + +For information about which hints are available see [hints in python]({% link _documentation/platforms/python/index.md %}#hints). diff --git a/src/collections/_documentation/learn/breadcrumbs-example/rust.md b/src/collections/_documentation/learn/breadcrumbs-example/rust.md index c3f78d7dd08e7..8e530626e83c5 100644 --- a/src/collections/_documentation/learn/breadcrumbs-example/rust.md +++ b/src/collections/_documentation/learn/breadcrumbs-example/rust.md @@ -2,9 +2,9 @@ use sentry::{add_breadcrumb, Breadcrumb, Level}; add_breadcrumb(Breadcrumb { - category: Some("auth".into()), - message: Some(format!("Authenticated user {}", user.email)), - level: Level::Info, - ..Default::default() + category: Some("auth".into()), + message: Some(format!("Authenticated user {}", user.email)), + level: Level::Info, + ..Default::default() }); ``` diff --git a/src/collections/_documentation/learn/breadcrumbs.md b/src/collections/_documentation/learn/breadcrumbs.md index cf99d6b6b11fb..a16b33ee930c3 100644 --- a/src/collections/_documentation/learn/breadcrumbs.md +++ b/src/collections/_documentation/learn/breadcrumbs.md @@ -58,3 +58,13 @@ to record a breadcrumb if the user authenticates or another state change happens SDKs will automatically start recording breadcrumbs by enabling integrations. For instance the browser JavaScript SDK will automatically record all location changes. + +## Breadcrumb Customization + +SDKs following the unified API support customizing breadcrumbs through the `before_breadcrumb` +hook. This hook is passed an already assembled breadcrumb and in some SDKs an optional +hint. The hint object is platform specific and typically carries a reference to the source +of the breadcrumb. The `before_breadcrumb` function can then modify the breadcrumb or +discard it. + +{% include components/platform_content.html content_dir='before-breadcrumb' %} diff --git a/src/collections/_documentation/learn/hints.md b/src/collections/_documentation/learn/hints.md new file mode 100644 index 0000000000000..d9ea12bc93746 --- /dev/null +++ b/src/collections/_documentation/learn/hints.md @@ -0,0 +1,6 @@ +--- +title: Hints +sidebar_order: 3 +--- + +XXX: document hints diff --git a/src/collections/_documentation/platforms/python/index.md b/src/collections/_documentation/platforms/python/index.md index 9c5ecd29eb2d7..c03634782c146 100644 --- a/src/collections/_documentation/platforms/python/index.md +++ b/src/collections/_documentation/platforms/python/index.md @@ -36,3 +36,16 @@ the following are supported: In addition to framework integrations there are also a few other integrations: * [Default integrations]({% link _documentation/platforms/python/default-integrations.md %}) + +## Hints + +The Python SDK provides some common [hints]({% link _documentation/learn/hints.md %}) for breadcrumbs +and events. These hints are passed as the `hint` parameter to `before_send` and `before_breadcrumb` +(as well as event processors) as a dictionary. More than one hint can be supplied but this is rare. + +* `exc_info`: If this hint is set then it's an exc info tuple in the form `(exc_type, exc_value, tb)`. This + can be used to extract additional information from the original error object. +* `log_record`: This hint is passed to breadcrumbs and contains the log record that crated it. It can be used + to extract additional information from the original `logging` log record that is not extracted by default. + Likewise it can be useful to discard uninteresting breadcrumbs. +* `httplib_request`: An `httplib` request object for breadcrumbs created from HTTP requests. From d690ebb6b56e4e74a62a65bb2c6fb9a126b34a56 Mon Sep 17 00:00:00 2001 From: HazA Date: Thu, 13 Sep 2018 15:32:07 +0200 Subject: [PATCH 104/171] fix: Keep selected platform --- src/_js/lib/PlatformContent.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/_js/lib/PlatformContent.js b/src/_js/lib/PlatformContent.js index 9136b13473442..41ca018734b26 100644 --- a/src/_js/lib/PlatformContent.js +++ b/src/_js/lib/PlatformContent.js @@ -104,9 +104,13 @@ const showPlatform = function(slug) { let $active; const slugs = [slug, platform.fallback_platform]; + for (const index in slugs) { $active = $dropdownItems.filter(`[data-platform="${slugs[index]}"]`); if ($active.length) { + if (index > 0) { // means we are in fallback platform + $active.data('platform', platform.slug); // But if we click on it we want to keep our inital platform + } // We skip and don't use fallback platform break; } From 02c103ea8e8c25895ef75f393199441a39deb866 Mon Sep 17 00:00:00 2001 From: Bruno Garcia Date: Thu, 13 Sep 2018 15:53:03 +0200 Subject: [PATCH 105/171] feat: link to nuget, versions --- .../platforms/dotnet/aspnetcore.md | 6 ++-- .../platforms/dotnet/entityframework.md | 8 ++--- .../_documentation/platforms/dotnet/index.md | 36 ++++++++++++------- .../platforms/dotnet/log4net.md | 6 ++-- .../dotnet/microsoft-extensions-logging.md | 8 +++-- 5 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/collections/_documentation/platforms/dotnet/aspnetcore.md b/src/collections/_documentation/platforms/dotnet/aspnetcore.md index d4d02c784d89f..c9da1af37a99a 100644 --- a/src/collections/_documentation/platforms/dotnet/aspnetcore.md +++ b/src/collections/_documentation/platforms/dotnet/aspnetcore.md @@ -3,20 +3,20 @@ title: Sentry.AspNetCore sidebar_order: 2 --- -Sentry has an integration with _ASP.NET Core_ through the `Sentry.AspNetCore` NuGet package. +Sentry has an integration with _ASP.NET Core_ through the [Sentry.AspNetCore NuGet package](https://www.nuget.org/packages/Sentry.AspNetCore). ## Installation Using package manager: ```powershell -Install-Package Sentry.AspNetCore +Install-Package Sentry.AspNetCore -Version {% sdk_version sentry.dotnet.aspnetcore %} ``` Or using the .NET Core CLI: ```sh -dotnet add Sentry.AspNetCore +dotnet add Sentry.AspNetCore -v {% sdk_version sentry.dotnet.aspnetcore %} ``` This package extends [Sentry.Extensions.Logging]({%- link _documentation/platforms/dotnet/microsoft-extensions-logging.md -%}). This means that besides the ASP.NET Core related features, through this package you'll also get access to all the framework's logging integration and also the features available in the main [Sentry]({%- link _documentation/platforms/dotnet/index.md -%}) SDK. diff --git a/src/collections/_documentation/platforms/dotnet/entityframework.md b/src/collections/_documentation/platforms/dotnet/entityframework.md index c0f4533db9a7e..3989c67534581 100644 --- a/src/collections/_documentation/platforms/dotnet/entityframework.md +++ b/src/collections/_documentation/platforms/dotnet/entityframework.md @@ -3,9 +3,9 @@ title: EntityFramework sidebar_order: 8 --- -Sentry has an integration with `EntityFramework` through the of the `Sentry.EntityFramework` NuGet package. +Sentry has an integration with `EntityFramework` through the of the [Sentry.EntityFramework NuGet package](https://www.nuget.org/packages/Sentry.EntityFramework). -> Looking for `EntityFramework Core`? That integration is achieved through the `Microsoft.Extensions.Logging` package. +> Looking for `EntityFramework Core`? That integration is achieved through the [Sentry.Extensions.Logging]({%- link _documentation/platforms/dotnet/microsoft-extensions-logging.md -%}) package. ## Installation @@ -13,13 +13,13 @@ Sentry has an integration with `EntityFramework` through the of the `Sentry.Enti Using package manager: ```powershell -Install-Package Sentry.EntityFramework +Install-Package Sentry.EntityFramework -Version {% sdk_version sentry.dotnet.ef %} ``` Or using the .NET Core CLI: ```sh -dotnet add Sentry.EntityFramework +dotnet add Sentry.EntityFramework -v {% sdk_version sentry.dotnet.ef %} ``` This package extends `Sentry` main SDK. That means that besides the EF features, through this package you'll also get access to all API and features available in the main `Sentry` SDK. diff --git a/src/collections/_documentation/platforms/dotnet/index.md b/src/collections/_documentation/platforms/dotnet/index.md index c0563efe1d801..e61c9057f5125 100644 --- a/src/collections/_documentation/platforms/dotnet/index.md +++ b/src/collections/_documentation/platforms/dotnet/index.md @@ -3,12 +3,31 @@ title: .NET sidebar_order: 10 --- -This section will describe features, configurations and general functionality which are specific to the .NET SDKs. +This section will describe features, configurations and general functionality which are specific to the .NET SDK. -### Code +> New to Sentry and the SDKs in general? Check out our [getting started]({%- link _documentation/learn/quickstart.md -%}) section and learn about our unified SDK API. +If you already have the main concepts covered, continue reading for a deep dive into specifics of the .NET SDK. +# Compatibility -#### Automatically discovering release version +The main [Sentry NuGet package](https://www.nuget.org/packages/Sentry) targets .NET Standard 2.0. That means, according to the [compatibility table](https://docs.microsoft.com/en-us/dotnet/standard/net-standard), it is compatible with the following versions or newer: + +* .NET Framework 4.6.1 (4.7.2 advised) +* .NET Core 2.0 +* Mono 5.4 +* Xamarin.Android 8.0 +* Xamarin.Mac 3.8 +* Xamarin.iOS 10.14 +* Universal Windows Platform 10.0.16299 + +Of those, we run our unit/integration tests against: + +* .NET Framework 4.7.2 on Windows +* Mono 5.12 macOS and Linux +* .NET Core 2.0 Windows, macOS and Linux +* .NET Core 2.1 Windows, macOS and Linux + +## Automatically discovering release version The SDK attempts to locate the release to add that to the events sent to Sentry. @@ -20,7 +39,7 @@ value and is often used to set a GIT commit hash. If that returns null, it'll look at the default `AssemblyVersionAttribute` which accepts the numeric version number. When creating a project with Visual Studio, that values is set to *1.0.0.0*. Since that usually means that the version is either not being set, or is set via a different method. The **automatic version detection will disregard** this value and no *Release* will be reported automatically. -#### Unit testing +## Unit testing We often don't want to couple our code with static class like `SentrySdk`. Especially to allow our code to be testable. If that's your case, you can use 2 abstractions: @@ -37,14 +56,5 @@ That's the job of the [`Hub`](https://github.com/getsentry/sentry-dotnet/blob/ma If all you are doing is sending events, without modification/access to the current scope, then you depend on `ISentryClient`. If on the other hand you would like to have access to the current scope by configuring it or binding a different client to it, you depend on `IHub`. - An example using `IHub` for testability is [SentryLogger](https://github.com/getsentry/sentry-dotnet/blob/master/src/Sentry.Extensions.Logging/SentryLogger.cs) and its unit tests [SentryLoggerTests](https://github.com/getsentry/sentry-dotnet/blob/master/test/Sentry.Extensions.Logging.Tests/SentryLoggerTests.cs). `SentryLogger` depends on `IHub` because it does modify the scope (through `AddBreadcrumb`). In case it only sent events, it should instead depend on `ISentryClient` - - -#### Integrations - -ASP.NET Core -Microsoft.Extensions.Logging -log4net -Entity Framework 6 diff --git a/src/collections/_documentation/platforms/dotnet/log4net.md b/src/collections/_documentation/platforms/dotnet/log4net.md index 1a36b6559f51a..a4204ef518d07 100644 --- a/src/collections/_documentation/platforms/dotnet/log4net.md +++ b/src/collections/_documentation/platforms/dotnet/log4net.md @@ -3,7 +3,7 @@ title: log4net sidebar_order: 10 --- -Sentry has an integration with log4net through the `Sentry.Log4Net` NuGet package. +Sentry has an integration with log4net through the [Sentry.Log4Net NuGet package](https://www.nuget.org/packages/Sentry.Log4Net). Without any code change, this package is able to initialize the Sentry SDK and capture events while including additional properties like `Exception` data and more. @@ -13,13 +13,13 @@ Without any code change, this package is able to initialize the Sentry SDK and c Using package manager: ```powershell -Install-Package Sentry.Log4Net +Install-Package Sentry.Log4Net -Version {% sdk_version sentry.dotnet.log4net %} ``` Or using the .NET Core CLI: ```sh -dotnet add Sentry.Log4Net +dotnet add Sentry.Log4Net -v {% sdk_version sentry.dotnet.log4net %} ``` This package extends `Sentry` main SDK. That means besides the log4net `Appender`, through this package you'll also get access to all API and features available in the main `Sentry` SDK. diff --git a/src/collections/_documentation/platforms/dotnet/microsoft-extensions-logging.md b/src/collections/_documentation/platforms/dotnet/microsoft-extensions-logging.md index fed12792cf9ec..798f54c20fd41 100644 --- a/src/collections/_documentation/platforms/dotnet/microsoft-extensions-logging.md +++ b/src/collections/_documentation/platforms/dotnet/microsoft-extensions-logging.md @@ -3,24 +3,26 @@ title: Microsoft.Extensions.Logging sidebar_order: 12 --- -Sentry has an integration with `Microsoft.Extensions.Logging` through the of the `Sentry.Extensions.Logging` NuGet package. +Sentry has an integration with `Microsoft.Extensions.Logging` through the [Sentry.Extensions.Logging NuGet package](https://www.nuget.org/packages/Sentry.Extensions.Logging). ## Installation Using package manager: ```powershell -Install-Package Sentry.Extensions.Logging +Install-Package Sentry.Extensions.Logging -Version {% sdk_version sentry.dotnet.extensions.logging %} ``` Or using the .NET Core CLI: ```sh -dotnet add Sentry.Extensions.Logging +dotnet add Sentry.Extensions.Logging -v {% sdk_version sentry.dotnet.extensions.logging %} ``` This package extends `Sentry` main SDK. That means that besides the logging related features, through this package you'll also get access to all API and features available in the main `Sentry` SDK. +> NOTE: Messages logged from assemblies with the name starting with `Sentry` will not generate events. + ## Features * Store log messages as breadcrumbs From 4fcad352ba922c05374000db332724c99903e099 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Thu, 13 Sep 2018 14:44:21 +0200 Subject: [PATCH 106/171] feat: Add more code samples to rust platforms --- .../_documentation/clientdev/data-handling.md | 2 +- src/collections/_documentation/platforms/rust/actix.md | 10 ++++++++++ .../_documentation/platforms/rust/env_logger.md | 1 + .../_documentation/platforms/rust/error_chain.md | 9 +++++++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/collections/_documentation/clientdev/data-handling.md b/src/collections/_documentation/clientdev/data-handling.md index 55c19bd9791db..cc7a534709d78 100644 --- a/src/collections/_documentation/clientdev/data-handling.md +++ b/src/collections/_documentation/clientdev/data-handling.md @@ -9,7 +9,7 @@ Data handling is the standardized context in how we want SDKs help users filter In older SDKs you might sometimes see elaborate constructs to allow the user to strip away sensitive data. Newer SDKs no longer have this feature as it turned out to be too hard to maintain per-SDK. Instead, only two simple config options are left: -- [_send-default-pii_]({%- link _documentation/learn/configuration.md -%}#send-default-pii) is **enabled by default**, meaning that data that is naturally sensitive is stripped entirely. That means, for example: +- [_send-default-pii_]({%- link _documentation/learn/configuration.md -%}#send-default-pii) is **disabled by default**, meaning that data that is naturally sensitive is not sent by default. That means, for example: - When attaching HTTP requests to events, "raw" bodies (bodies which cannot be parsed as JSON or formdata) are removed, and known sensitive headers such as `Authentication` or `Cookies` are removed too. diff --git a/src/collections/_documentation/platforms/rust/actix.md b/src/collections/_documentation/platforms/rust/actix.md index b244a2e99b052..8e4afbb9089d4 100644 --- a/src/collections/_documentation/platforms/rust/actix.md +++ b/src/collections/_documentation/platforms/rust/actix.md @@ -17,6 +17,16 @@ unless you bind the actix hub. ## Example +In your `Cargo.toml`: + +```toml +[dependencies] +sentry = "{% sdk_version sentry.rust %}" +sentry-actix = "{% package_version cargo:sentry-actix %}" +``` + +And your Rust code: + ```rust extern crate actix_web; extern crate sentry; diff --git a/src/collections/_documentation/platforms/rust/env_logger.md b/src/collections/_documentation/platforms/rust/env_logger.md index d5a0afd656695..03007e17a3e04 100644 --- a/src/collections/_documentation/platforms/rust/env_logger.md +++ b/src/collections/_documentation/platforms/rust/env_logger.md @@ -8,6 +8,7 @@ sidebar_order: 2 Adds support for automatic breadcrumb capturing from logs with `env_logger`. ## Configuration + In the most trivial version you call this crate's init function instead of the one from `env_logger` and pass `None` as logger: diff --git a/src/collections/_documentation/platforms/rust/error_chain.md b/src/collections/_documentation/platforms/rust/error_chain.md index c4a46072be686..de995df635fe5 100644 --- a/src/collections/_documentation/platforms/rust/error_chain.md +++ b/src/collections/_documentation/platforms/rust/error_chain.md @@ -12,6 +12,15 @@ Errors created by the `error-chain` crate can be logged with the ## Example +In your `Cargo.toml`: + +``` +[dependencies] +sentry = { version = "{% sdk_version sentry.rust %}", features = ["with_error_chain"] } +``` + +And your Rust code: + ```rust use sentry::integrations::error_chain::capture_error_chain; let result = match function_that_might_fail() { From 41f4e0e1183e97689b71d23a0de10a45f8266cfe Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Thu, 13 Sep 2018 17:03:22 +0200 Subject: [PATCH 107/171] feat: Tag to return github repo link for SDK {% sdk_repo_url "sentry.dotnet" %} cc @bruno-garcia --- src/_plugins/release_registry.rb | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/_plugins/release_registry.rb b/src/_plugins/release_registry.rb index 52e8eb8f2c8cf..0be404f8ce435 100644 --- a/src/_plugins/release_registry.rb +++ b/src/_plugins/release_registry.rb @@ -9,10 +9,6 @@ def initialize(tag_name, text, tokens) @params = text.split(/\s+/) end - def render(context) - get_info["version"] - end - def entity raise NotImplementedError.new end @@ -47,14 +43,33 @@ class PackageVersionTag < ReleaseRegistryTag def entity "packages" end + + def render(context) + get_info["version"] + end end class SdkVersionTag < ReleaseRegistryTag def entity "sdks" end + + def render(context) + get_info["version"] + end + end + + class SdkRepoUrlTag < ReleaseRegistryTag + def entity + "sdks" + end + + def render(context) + get_info["repo_url"] + end end end Liquid::Template.register_tag('package_version', Jekyll::PackageVersionTag) Liquid::Template.register_tag('sdk_version', Jekyll::SdkVersionTag) +Liquid::Template.register_tag('sdk_repo_url', Jekyll::SdkRepoUrlTag) From 2f9d7ad1927bcc6289ccf65c39651c24f17f44f8 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Thu, 13 Sep 2018 10:45:53 -0700 Subject: [PATCH 108/171] mark more platforms --- src/_data/platforms.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index 7da8a88022537..4240abcb87894 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -288,7 +288,7 @@ type: language name: Electron doc_link: /clients/electron/ - legacy_wizard: ['_documentation/clients/electron/index.md#installation', '_documentation/clients/electron/index.md#configuring-the-client'] + wizard: true case_style: camelCase fallback_platform: javascript - @@ -403,7 +403,7 @@ type: language name: Rust doc_link: /platforms/rust/ - legacy_wizard: ['_documentation/platforms/rust/index.md#installation', '_documentation/platforms/rust/index.md#configuring-the-client', '_documentation/platforms/rust/index.md#reporting-errors', '_documentation/platforms/rust/index.md#catching-panics'] + wizard: true version: 0.6.0 version_key: SENTRY_VERSION case_style: snake_case From afd5342df74fe0d3493d6e1e3155c3a1a1d8f65c Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Thu, 13 Sep 2018 11:51:23 -0700 Subject: [PATCH 109/171] Refactor to support flagging wizard content inline --- src/_plugins/platform_api.rb | 76 ++++++++++++------- .../_documentation/learn/quickstart.md | 2 + 2 files changed, 50 insertions(+), 28 deletions(-) diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index 8f4286fd88ab6..d85f474d82c5e 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -56,46 +56,66 @@ def generate(site) docs = {} site.collections["documentation"].docs.each do |doc| content = doc.to_s - sections = { - :document => content - } - headings = get_headings(content) - headings.each do |heading| - startLine = heading[:line] - close = headings.find {|h| h[:line] > startLine && heading[:level] >= h[:level]} - if !close.nil? - endLine = close[:line] - sections[heading[:slug]] = content.lines[startLine, endLine - startLine].join - else - sections[heading[:slug]] = content.lines[startLine..-1].join + + if content =~ // + rendered = Jekyll::Renderer.new(site, doc, site.site_payload).run + wizard = /([\s\S]+?)/.match(rendered).captures + docs[doc.relative_path] = { :content => wizard.first } + else + sections = { + :document => content + } + headings = get_headings(content) + headings.each do |heading| + startLine = heading[:line] + close = headings.find {|h| h[:line] > startLine && heading[:level] >= h[:level]} + if !close.nil? + endLine = close[:line] + sections[heading[:slug]] = content.lines[startLine, endLine - startLine].join + else + sections[heading[:slug]] = content.lines[startLine..-1].join + end end - end - docs[doc.relative_path] = sections + docs[doc.relative_path] = { :sections => sections } + + end end indexPayload = { :platforms => {} } + + # Generate each file site.data["platforms"].each do |platform| - return nil if platform["legacy_wizard"].nil? - - body = "" - platform["legacy_wizard"].each do |wiz| - file, section = wiz.split '#' - p docs[file], file - section ||= :document - if docs[file][section].nil? - raise "Cannot find section '#{section}' in #{file}" + next if platform["legacy_wizard"].nil? && platform["wizard"].nil? + + if platform["legacy_wizard"] + body = "" + platform["legacy_wizard"].each do |wiz| + file, section = wiz.split '#' + section ||= :document + doc = docs[file] + if doc[:sections] + section_content = doc[:sections][section] + if section_content.nil? + raise "Cannot find section '#{section}' in #{file}" + end + body += section_content + else + body = doc[:content] + end + end - body += docs[file][section] - end - platform["body"] = site.find_converter_instance( - Jekyll::Converters::Markdown - ).convert(body) + platform["body"] = site.find_converter_instance( + Jekyll::Converters::Markdown + ).convert(body) + else + platform["body"] = docs['_documentation/learn/quickstart.md'][:content] + end pathData = Pathname(platform["doc_link"]).each_filename.to_a diff --git a/src/collections/_documentation/learn/quickstart.md b/src/collections/_documentation/learn/quickstart.md index 74ecdf877715e..647e3f11ad5ed 100644 --- a/src/collections/_documentation/learn/quickstart.md +++ b/src/collections/_documentation/learn/quickstart.md @@ -18,6 +18,7 @@ Getting started with Sentry is a three step process: Sentry captures data by using a SDK within your application’s runtime. These are platform specific and allow Sentry to have a deep understanding of both how your application works. In case your environment is very specific, you can also roll your own SDK using our document [_SDK API_]({%- link _documentation/clientdev/index.md -%}). + {% include components/platform_content.html content_dir='getting-started-install' %} {% capture __alert_content -%} @@ -36,6 +37,7 @@ After you completed setting up a project in Sentry, you’ll be given a value wh Most SDKs will now automatically collect data if available, some require some extra configuration as automatic error collecting is not available due to platform limitations. + {% capture __alert_content -%} As of Sentry 9, we removed the need to provide the secret key. Older versions of SDKs may still require you to provide the DSN including the secret which is now called DSN (Legacy). Please check the corresponding docs of the SDK you are using if you still need to provide the secret. From 9a38d96557b639bd8f628c13ccb97ed1531fec3c Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Thu, 13 Sep 2018 16:05:10 -0700 Subject: [PATCH 110/171] mark all docs for the wizard --- src/_data/platforms.yml | 148 ++++++++++++------ .../_documentation/clients/cocoa/dsym.md | 2 + .../_documentation/clients/cocoa/index.md | 3 +- .../_documentation/clients/csharp/index.md | 2 + .../_documentation/clients/elixir/index.md | 2 + .../_documentation/clients/elixir/usage.md | 2 + .../_documentation/clients/go/index.md | 2 + .../clients/go/integrations/http.md | 2 + .../clients/java/modules/android.md | 4 + .../clients/java/modules/appengine.md | 2 + .../clients/java/modules/jul.md | 2 + .../clients/java/modules/log4j.md | 2 + .../clients/java/modules/log4j2.md | 2 + .../clients/java/modules/logback.md | 2 + .../_documentation/clients/java/usage.md | 4 + .../clients/javascript/index.md | 2 + .../javascript/integrations/angular.md | 2 + .../javascript/integrations/angularjs.md | 2 + .../javascript/integrations/backbone.md | 2 + .../clients/javascript/integrations/ember.md | 2 + .../clients/javascript/integrations/react.md | 3 +- .../clients/javascript/integrations/vue.md | 3 + .../_documentation/clients/node/index.md | 6 + .../clients/node/integrations/connect.md | 2 + .../clients/node/integrations/express.md | 2 + .../clients/node/integrations/koa.md | 2 + .../_documentation/clients/php/index.md | 4 + .../clients/php/integrations/laravel.md | 3 +- .../clients/php/integrations/monolog.md | 2 + .../clients/php/integrations/symfony2.md | 2 + .../_documentation/clients/php/usage.md | 2 + .../_documentation/clients/python/index.md | 2 + .../clients/python/integrations/bottle.md | 2 + .../clients/python/integrations/celery.md | 2 + .../clients/python/integrations/django.md | 2 + .../clients/python/integrations/flask.md | 2 + .../clients/python/integrations/pylons.md | 2 + .../clients/python/integrations/pyramid.md | 2 + .../clients/python/integrations/rq.md | 2 + .../clients/python/integrations/tornado.md | 3 +- .../_documentation/clients/python/usage.md | 2 + .../clients/react-native/index.md | 4 + .../_documentation/clients/ruby/index.md | 2 + .../clients/ruby/integrations/rack.md | 2 + .../clients/ruby/integrations/rails.md | 2 + .../platforms/minidump/index.md | 4 + 46 files changed, 206 insertions(+), 51 deletions(-) diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index 4240abcb87894..c7347ad56a82c 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -4,7 +4,9 @@ type: framework name: Koa doc_link: /clients/node/integrations/koa/ - legacy_wizard: ['_documentation/clients/node/index.md#installation', _documentation/clients/node/integrations/koa.md] + legacy_wizard: + - _documentation/clients/node/index.md#installation + - _documentation/clients/node/integrations/koa.md - slug: node support_level: production @@ -13,7 +15,8 @@ # XXX: does this have a better link? doc_link: /platforms/javascript/ # this is actually the old legacy_wizard: - legacy_wizard: ['_documentation/clients/node/index.md#installation', '_documentation/clients/node/index.md#configuring-the-client', '_documentation/clients/node/index.md#reporting-errors'] + legacy_wizard: + - _documentation/clients/node/index.md case_style: camelCase fallback_platform: javascript - @@ -22,7 +25,6 @@ type: language name: Node.js doc_link: /clients/node/ - legacy_wizard: ['_documentation/clients/node/index.md#installation', '_documentation/clients/node/index.md#configuring-the-client', '_documentation/clients/node/index.md#reporting-errors'] case_style: camelCase fallback_platform: javascript superseded_by: node @@ -33,7 +35,9 @@ name: Express # XXX: this links to the old ones doc_link: /clients/node/integrations/express/ - legacy_wizard: ['_documentation/clients/node/index.md#installation', _documentation/clients/node/integrations/express.md] + legacy_wizard: + - _documentation/clients/node/index.md#installation + - _documentation/clients/node/integrations/express.md - slug: connect support_level: production @@ -41,7 +45,9 @@ name: Connect # XXX: this links to the old ones doc_link: /clients/node/integrations/connect/ - legacy_wizard: ['_documentation/clients/node/index.md#installation', _documentation/clients/node/integrations/connect.md] + legacy_wizard: + - _documentation/clients/node/index.md#installation + - _documentation/clients/node/integrations/connect.md - slug: cordova support_level: production @@ -71,49 +77,56 @@ type: language name: Java doc_link: /clients/java/ - legacy_wizard: ['_documentation/clients/java/usage.md#installation', '_documentation/clients/java/usage.md#capture-an-error'] + legacy_wizard: + - _documentation/clients/java/usage.md - slug: logging support_level: production type: framework name: java.util.logging doc_link: /clients/java/modules/jul/ - legacy_wizard: ['_documentation/clients/java/modules/jul.md#installation', '_documentation/clients/java/modules/jul.md#usage'] + legacy_wizard: + - _documentation/clients/java/modules/jul.md - slug: logback support_level: production type: framework name: Logback doc_link: /clients/java/modules/logback/ - legacy_wizard: ['_documentation/clients/java/modules/logback.md#installation', '_documentation/clients/java/modules/logback.md#usage'] + legacy_wizard: + - _documentation/clients/java/modules/logback.md - slug: android support_level: production type: framework name: Android doc_link: /clients/java/modules/android/ - legacy_wizard: ['_documentation/clients/java/modules/android.md#installation', '_documentation/clients/java/modules/android.md#usage'] + legacy_wizard: + - _documentation/clients/java/modules/android.md - slug: log4j2 support_level: production type: framework name: 'Log4j 2.x' doc_link: /clients/java/modules/log4j2/ - legacy_wizard: ['_documentation/clients/java/modules/log4j2.md#installation', '_documentation/clients/java/modules/log4j2.md#usage'] + legacy_wizard: + - _documentation/clients/java/modules/log4j2.md - slug: log4j support_level: production type: framework name: 'Log4j 1.x' doc_link: /clients/java/modules/log4j/ - legacy_wizard: ['_documentation/clients/java/modules/log4j.md#installation', '_documentation/clients/java/modules/log4j.md#usage'] + legacy_wizard: + - _documentation/clients/java/modules/log4j.md - slug: appengine support_level: production type: framework name: 'Google App Engine' doc_link: /clients/java/modules/appengine/ - legacy_wizard: ['_documentation/clients/java/modules/appengine.md#installation', '_documentation/clients/java/modules/appengine.md#usage'] + legacy_wizard: + - _documentation/clients/java/modules/appengine.md - slug: python support_level: production @@ -121,7 +134,9 @@ name: Python doc_link: /platforms/python/ # this is actually the old legacy_wizard: - legacy_wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/usage.md#capture-an-error', '_documentation/clients/python/usage.md#reporting-an-event'] + legacy_wizard: + - _documentation/clients/python/index.md + - _documentation/clients/python/usage.md case_style: snake_case - slug: python-legacy @@ -129,7 +144,6 @@ type: language name: Python Legacy doc_link: /clients/python/ - legacy_wizard: [] case_style: snake_case superseded_by: python - @@ -138,7 +152,9 @@ type: framework name: Pyramid doc_link: /clients/python/integrations/pyramid/ - legacy_wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/pyramid.md#pastedeploy-filter', '_documentation/clients/python/integrations/pyramid.md#logger-setup'] + legacy_wizard: + - _documentation/clients/python/index.md + - _documentation/clients/python/integrations/pyramid.md case_style: camelCase - slug: rq @@ -146,56 +162,72 @@ type: framework name: RQ doc_link: /clients/python/integrations/rq/ - legacy_wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/rq.md#usage', '_documentation/clients/python/integrations/rq.md#extended-setup'] + legacy_wizard: + _documentation/clients/python/index.md + _documentation/clients/python/integrations/rq.md - slug: flask support_level: production type: framework name: Flask doc_link: /clients/python/integrations/flask/ - legacy_wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/flask.md#installation', '_documentation/clients/python/integrations/flask.md#setup'] + legacy_wizard: + - _documentation/clients/python/index.md + - _documentation/clients/python/integrations/flask.md - slug: django support_level: production type: framework name: Django doc_link: /clients/python/integrations/django/ - legacy_wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/django.md#setup'] + legacy_wizard: + - _documentation/clients/python/index.md + - _documentation/clients/python/integrations/django.md - slug: celery support_level: production type: library name: Celery doc_link: /clients/python/integrations/celery/ - legacy_wizard: ['_documentation/clients/python/index.md#installation', _documentation/clients/python/integrations/celery.md] + legacy_wizard: + - _documentation/clients/python/index.md + - _documentation/clients/python/integrations/celery.md - slug: tornado support_level: production type: framework name: Tornado doc_link: /clients/python/integrations/tornado/ - legacy_wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/tornado.md#setup', '_documentation/clients/python/integrations/tornado.md#usage'] + legacy_wizard: + - _documentation/clients/python/index.md + - _documentation/clients/python/integrations/tornado.md - slug: bottle support_level: production type: framework name: Bottle doc_link: /clients/python/integrations/bottle/ - legacy_wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/bottle.md#setup', '_documentation/clients/python/integrations/bottle.md#usage'] + legacy_wizard: + - _documentation/clients/python/index.md + - _documentation/clients/python/integrations/bottle.md - slug: pylons support_level: production type: framework name: Pylons doc_link: /clients/python/integrations/pylons/ - legacy_wizard: ['_documentation/clients/python/index.md#installation', '_documentation/clients/python/integrations/pylons.md#wsgi-middleware', '_documentation/clients/python/integrations/pylons.md#logger-setup'] + legacy_wizard: + - _documentation/clients/python/index.md + - _documentation/clients/python/integrations/pylons.md - slug: swift support_level: production type: language name: Swift doc_link: /clients/cocoa/ - legacy_wizard: ['_documentation/clients/cocoa/index.md#installation', '_documentation/clients/cocoa/index.md#configuration', '_documentation/clients/cocoa/index.md#debug-symbols', '_documentation/clients/cocoa/dsym.md#upload-symbols-with-sentry-cli'] + legacy_wizard: + - _documentation/clients/cocoa/index.md + - _documentation/clients/cocoa/dsym.md#upload-symbols-with-sentry-cli version: 4.1.0 version_key: SENTRY_COCOA_TAG - @@ -204,7 +236,6 @@ type: language name: Browser Javascript doc_link: /clients/javascript/ - legacy_wizard: [] case_style: camelCase fallback_platform: javascript - @@ -214,7 +245,8 @@ name: JavaScript doc_link: /platforms/javascript/ # this is actually the old legacy_wizard: - legacy_wizard: ['_documentation/clients/javascript/index.md#installation', '_documentation/clients/javascript/index.md#configuring-the-client', '_documentation/clients/javascript/index.md#manually-reporting-errors'] + legacy_wizard: + - _documentation/clients/javascript/index.md case_style: camelCase superseded_by: - @@ -223,7 +255,6 @@ type: language name: JavaScript doc_link: /clients/javascript/ - legacy_wizard: [] version: 3.26.4 version_key: RAVEN_VERSION case_style: camelCase @@ -234,7 +265,8 @@ type: framework name: Vue doc_link: /clients/javascript/integrations/vue/ - legacy_wizard: ['_documentation/clients/javascript/integrations/vue.md#installation'] + legacy_wizard: + - _documentation/clients/javascript/integrations/vue.md version: 3.26.4 version_key: RAVEN_VERSION - @@ -243,7 +275,8 @@ type: framework name: Backbone doc_link: /clients/javascript/integrations/backbone/ - legacy_wizard: ['_documentation/clients/javascript/integrations/backbone.md#installation', '_documentation/clients/javascript/integrations/backbone.md#configuring-the-client'] + legacy_wizard: + - _documentation/clients/javascript/integrations/backbone.md version: 3.26.4 version_key: RAVEN_VERSION - @@ -252,7 +285,8 @@ type: framework name: Ember doc_link: /clients/javascript/integrations/ember/ - legacy_wizard: ['_documentation/clients/javascript/integrations/ember.md#installation'] + legacy_wizard: + - _documentation/clients/javascript/integrations/ember.md version: 3.26.4 version_key: RAVEN_VERSION - @@ -261,7 +295,8 @@ type: framework name: React doc_link: /clients/javascript/integrations/react/ - legacy_wizard: ['_documentation/clients/javascript/integrations/react.md#installation', '_documentation/clients/javascript/integrations/react.md#configuring-the-client'] + legacy_wizard: + - _documentation/clients/javascript/integrations/react.md version: 3.26.4 version_key: RAVEN_VERSION - @@ -270,7 +305,8 @@ type: framework name: AngularJS doc_link: /clients/javascript/integrations/angularjs/ - legacy_wizard: ['_documentation/clients/javascript/integrations/angularjs.md#installation', '_documentation/clients/javascript/integrations/angularjs.md#angularjs-configuration'] + legacy_wizard: + - _documentation/clients/javascript/integrations/angularjs.md version: 3.26.4 version_key: RAVEN_VERSION - @@ -279,7 +315,8 @@ type: framework name: Angular doc_link: /clients/javascript/integrations/angular/ - legacy_wizard: ['_documentation/clients/javascript/integrations/angular.md#installation', '_documentation/clients/javascript/integrations/angular.md#configuration'] + legacy_wizard: + - _documentation/clients/javascript/integrations/angular.md version: 3.26.4 version_key: RAVEN_VERSION - @@ -297,7 +334,9 @@ type: language name: Elixir doc_link: /clients/elixir/ - legacy_wizard: ['_documentation/clients/elixir/index.md#installation', '_documentation/clients/elixir/index.md#configuration', '_documentation/clients/elixir/usage.md#capturing-errors'] + legacy_wizard: + - _documentation/clients/elixir/index.md + - _documentation/clients/elixir/usage.md case_style: PascalCase - slug: cocoa @@ -305,14 +344,17 @@ type: language name: React-Native doc_link: /clients/react-native/ - legacy_wizard: ['_documentation/clients/react-native/index.md#installation', '_documentation/clients/react-native/index.md#client-configuration'] + legacy_wizard: + - _documentation/clients/react-native/index.md - slug: objc support_level: production type: language name: Objective-C doc_link: /clients/cocoa/ - legacy_wizard: ['_documentation/clients/cocoa/index.md#installation', '_documentation/clients/cocoa/index.md#configuration', '_documentation/clients/cocoa/index.md#debug-symbols', '_documentation/clients/cocoa/dsym.md#upload-symbols-with-sentry-cli'] + legacy_wizard: + - _documentation/clients/cocoa/index.md + - _documentation/clients/cocoa/dsym.md version: 4.1.0 version_key: SENTRY_COCOA_TAG - @@ -323,7 +365,8 @@ name: 'C#' doc_link: /platforms/dotnet/ # this is actually the old legacy_wizard: - legacy_wizard: ['_documentation/clients/csharp/index.md#installation', '_documentation/clients/csharp/index.md#capturing-exceptions'] + legacy_wizard: + - _documentation/clients/csharp/index.md case_style: PascalCase - slug: csharp-legacy @@ -331,7 +374,6 @@ type: language name: 'C#' doc_link: /clients/csharp/ - legacy_wizard: [] case_style: PascalCase superseded_by: csharp - @@ -340,63 +382,74 @@ type: language name: Go doc_link: /clients/go/ - legacy_wizard: ['_documentation/clients/go/index.md#installation', '_documentation/clients/go/index.md#configuring-the-client', '_documentation/clients/go/index.md#reporting-errors', '_documentation/clients/go/index.md#reporting-panics'] + legacy_wizard: + - _documentation/clients/go/index.md - slug: http support_level: in-development type: framework name: net/http doc_link: /clients/go/integrations/http/ - legacy_wizard: ['_documentation/clients/go/integrations/http.md#installation', '_documentation/clients/go/integrations/http.md#setup'] + legacy_wizard: + - _documentation/clients/go/integrations/http.md - slug: laravel support_level: production type: framework name: Laravel doc_link: /clients/php/integrations/laravel/ - legacy_wizard: ['_documentation/clients/php/integrations/laravel.md#laravel-5-x', '_documentation/clients/php/integrations/laravel.md#laravel-4-x', '_documentation/clients/php/integrations/laravel.md#lumen-5-x'] + legacy_wizard: + - _documentation/clients/php/integrations/laravel.md - slug: php support_level: production type: language name: PHP doc_link: /clients/php/ - legacy_wizard: ['_documentation/clients/php/index.md#installation', '_documentation/clients/php/index.md#configuration', '_documentation/clients/php/usage.md#capturing-errors'] + legacy_wizard: + - _documentation/clients/php/index.md + - _documentation/clients/php/usage.md - slug: monolog support_level: production type: framework name: Monolog doc_link: /clients/php/integrations/monolog/ - legacy_wizard: ['_documentation/clients/php/index.md#installation', _documentation/clients/php/integrations/monolog.md] + legacy_wizard: + - _documentation/clients/php/index.md#installation + - _documentation/clients/php/integrations/monolog.md - slug: symfony2 support_level: production type: framework name: Symfony2 doc_link: /clients/php/integrations/symfony2/ - legacy_wizard: ['_documentation/clients/php/integrations/symfony2.md#symfony-2'] + legacy_wizard: + - _documentation/clients/php/integrations/symfony2.md#symfony-2 - slug: ruby support_level: production type: language name: Ruby doc_link: /clients/ruby/ - legacy_wizard: ['_documentation/clients/ruby/index.md#installation', '_documentation/clients/ruby/index.md#configuration', '_documentation/clients/ruby/index.md#reporting-failures'] + legacy_wizard: + - _documentation/clients/ruby/index.md - slug: rack support_level: production type: framework name: Rack doc_link: /clients/ruby/integrations/rack/ - legacy_wizard: [_documentation/clients/ruby/integrations/rack.md] + legacy_wizard: + - _documentation/clients/ruby/integrations/rack.md - slug: rails support_level: production type: framework name: Rails doc_link: /clients/ruby/integrations/rails/ - legacy_wizard: [_documentation/clients/ruby/integrations/rails.md] + legacy_wizard: + - _documentation/clients/ruby/integrations/rails.md - slug: rust support_level: production @@ -413,4 +466,5 @@ type: language name: Minidump doc_link: /platforms/minidump/ - legacy_wizard: ['_documentation/platforms/minidump/index.md#platform-and-language-support', '_documentation/platforms/minidump/index.md#creating-and-uploading-minidumps'] + legacy_wizard: + - _documentation/platforms/minidump/index.md diff --git a/src/collections/_documentation/clients/cocoa/dsym.md b/src/collections/_documentation/clients/cocoa/dsym.md index 88b30ac37942c..ca9061790b4f8 100644 --- a/src/collections/_documentation/clients/cocoa/dsym.md +++ b/src/collections/_documentation/clients/cocoa/dsym.md @@ -95,6 +95,7 @@ api_host: 'https://mysentry.invalid/' content=__alert_content %} + ### Upload Symbols with _sentry-cli_ Your project’s dSYM can be upload during the build phase as a “Run Script”. For this you need to st the _DEBUG_INFORMATION_FORMAT_ to be _DWARF with dSYM File_. By default, an Xcode project will only have _DEBUG_INFORMATION_FORMAT_ set to _DWARF with dSYM File_ in _Release_ so make sure everything is set in your build settings properly. @@ -133,6 +134,7 @@ export SENTRY_URL=https://mysentry.invalid/ title="On Prem" content=__alert_content %} + ### Manually with _sentry-cli_ diff --git a/src/collections/_documentation/clients/cocoa/index.md b/src/collections/_documentation/clients/cocoa/index.md index 5a5554f0eb796..93df0998cf048 100644 --- a/src/collections/_documentation/clients/cocoa/index.md +++ b/src/collections/_documentation/clients/cocoa/index.md @@ -6,6 +6,7 @@ sidebar_relocation: platforms This is the documentation for our official clients for Cocoa (Swift and Objective-C). Starting with version `3.0.0` we’ve switched our interal code from Swift to Objective-C to maximize compatiblity. Also we trimmed the public API of our sdk to a minimum. Some of the lesser used features that where present before are gone now, check out [Migration Guide]({%- link _documentation/clients/cocoa/migration.md -%}#migration) or [Advanced Usage]({%- link _documentation/clients/cocoa/advanced.md -%}#advanced) for details. + ## Installation The SDK can be installed using [CocoaPods](http://cocoapods.org) or [Carthage](https://github.com/Carthage/Carthage). This is the recommended client for both Swift and Objective-C. @@ -85,7 +86,7 @@ Before you can start capturing crashes you will need to tell Sentry about the de - [With Bitcode]({%- link _documentation/clients/cocoa/dsym.md -%}#dsym-with-bitcode) - [Without Bitcode]({%- link _documentation/clients/cocoa/dsym.md -%}#dsym-without-bitcode) - + ## Testing a Crash If you would like to test the crash reporting you will need to cause a crash. While, the seemingly obvious method would be make it crash on launch, this will not give the Sentry client a chance to actually submit the crash report. Instead, we recommend triggering a crash from a button tap. diff --git a/src/collections/_documentation/clients/csharp/index.md b/src/collections/_documentation/clients/csharp/index.md index c8c40d2052433..f01d5d7ac6ae1 100644 --- a/src/collections/_documentation/clients/csharp/index.md +++ b/src/collections/_documentation/clients/csharp/index.md @@ -4,6 +4,7 @@ title: 'C#' Raven is the C# client for Sentry. Raven relies on the most popular logging libraries to capture and convert logs before sending details to a Sentry instance. + ## Installation A [NuGet Package](https://www.nuget.org/packages/SharpRaven) is available for SharpRaven if you don’t want to compile it yourself. @@ -29,6 +30,7 @@ catch (Exception exception) ravenClient.Capture(new SentryEvent(exception)); } ``` + ## Logging Non-Exceptions diff --git a/src/collections/_documentation/clients/elixir/index.md b/src/collections/_documentation/clients/elixir/index.md index fa143e61552c2..fe2350298302f 100644 --- a/src/collections/_documentation/clients/elixir/index.md +++ b/src/collections/_documentation/clients/elixir/index.md @@ -6,6 +6,7 @@ sidebar_relocation: platforms The Elixir SDK for Sentry. + ## Installation Edit your mix.exs file to add it as a dependency and add the `:sentry` package to your applications: @@ -64,6 +65,7 @@ If using an environment with Plug or Phoenix add the following to your router: use Plug.ErrorHandler use Sentry.Plug ``` + ## Filtering Events diff --git a/src/collections/_documentation/clients/elixir/usage.md b/src/collections/_documentation/clients/elixir/usage.md index 8edbd929863b6..691d5c02abf6b 100644 --- a/src/collections/_documentation/clients/elixir/usage.md +++ b/src/collections/_documentation/clients/elixir/usage.md @@ -3,6 +3,7 @@ title: Usage sidebar_order: 1 --- + ## Capturing Errors If you use the error logger and setup Plug/Phoenix then you are already done, all errors will bubble up to sentry. @@ -17,6 +18,7 @@ rescue Sentry.capture_exception(my_exception, [stacktrace: System.stacktrace(), extra: %{extra: information}]) end ``` + ## Optional Attributes diff --git a/src/collections/_documentation/clients/go/index.md b/src/collections/_documentation/clients/go/index.md index 7397a67e02674..03bcf7e580fc0 100644 --- a/src/collections/_documentation/clients/go/index.md +++ b/src/collections/_documentation/clients/go/index.md @@ -15,6 +15,7 @@ The Go SDK is maintained and supported by Sentry but currently under development Raven-Go provides a Sentry client implementation for the Go programming language. + ## Installation Raven-Go can be installed like any other Go library through `go get`: @@ -60,6 +61,7 @@ raven.CapturePanic(func() { // do all of the scary things here }, nil) ``` + ## Additional Context diff --git a/src/collections/_documentation/clients/go/integrations/http.md b/src/collections/_documentation/clients/go/integrations/http.md index e81e184a992dc..ae3d821cf3f93 100644 --- a/src/collections/_documentation/clients/go/integrations/http.md +++ b/src/collections/_documentation/clients/go/integrations/http.md @@ -4,6 +4,7 @@ title: net/http Raven Go provides middleware that can be used with the stdlib `net/http` library to automatically handle panics that occur during an http request. + ## Installation Simply install `raven-go` through `go get`: @@ -36,3 +37,4 @@ func root(w http.ResponseWriter, r *http.Request) { } http.HandleFunc("/", raven.RecoveryHandler(root)) ``` + diff --git a/src/collections/_documentation/clients/java/modules/android.md b/src/collections/_documentation/clients/java/modules/android.md index 734e8d8f71770..475ca1b43fe9c 100644 --- a/src/collections/_documentation/clients/java/modules/android.md +++ b/src/collections/_documentation/clients/java/modules/android.md @@ -13,6 +13,7 @@ An `UncaughtExceptionHandler` is configured so that crash events will be stored The `AndroidEventBuilderHelper` is enabled by default, which will automatically enrich events with data about the current state of the device, such as memory usage, storage usage, display resolution, connectivity, battery level, model, Android version, whether the device is rooted or not, etc. + ## Installation Using Gradle (Android Studio) in your `app/build.gradle` add: @@ -22,6 +23,7 @@ compile 'io.sentry:sentry-android:1.7.5' ``` For other dependency managers see the [central Maven repository](https://search.maven.org/#artifactdetails%7Cio.sentry%7Csentry-android%7C1.7.5%7Cjar). + ## Initialization @@ -58,6 +60,7 @@ public class MainActivity extends Activity { You can optionally configure other values such as `environment` and `release`. [See the configuration page]({%- link _documentation/clients/java/config.md -%}#configuration) for ways you can do this. + ## Usage Now you can use `Sentry` to capture events anywhere in your application: @@ -109,6 +112,7 @@ public class MyClass { } } ``` + ## ProGuard diff --git a/src/collections/_documentation/clients/java/modules/appengine.md b/src/collections/_documentation/clients/java/modules/appengine.md index 6c1f9eee954a9..7535b530e8c89 100644 --- a/src/collections/_documentation/clients/java/modules/appengine.md +++ b/src/collections/_documentation/clients/java/modules/appengine.md @@ -7,6 +7,7 @@ The `sentry-appengine` library provides [Google App Engine](https://cloud.google The source can be found [on Github](https://github.com/getsentry/sentry-java/tree/master/sentry-appengine). + ## Installation Using Maven: @@ -38,6 +39,7 @@ For other dependency managers see the [central Maven repository](https://search. This module provides a new `SentryClientFactory` implementation which replaces the default async system with a Google App Engine compatible one. You’ll need to configure Sentry to use the `io.sentry.appengine.AppEngineSentryClientFactory` as its factory. The queue size and thread options will not be used as they are specific to the default Java threading system. + ## Queue Name diff --git a/src/collections/_documentation/clients/java/modules/jul.md b/src/collections/_documentation/clients/java/modules/jul.md index 26fc5d6349dfc..e91adbb7abba6 100644 --- a/src/collections/_documentation/clients/java/modules/jul.md +++ b/src/collections/_documentation/clients/java/modules/jul.md @@ -9,6 +9,7 @@ The source for `sentry` can be found [on Github](https://github.com/getsentry/se **Note:** The old `raven` library is no longer maintained. It is highly recommended that you [migrate]({%- link _documentation/clients/java/migration.md -%}) to `sentry` (which this documentation covers). [Check out the migration guide]({%- link _documentation/clients/java/migration.md -%}) for more information. If you are still using `raven` you can [find the old documentation here](https://github.com/getsentry/sentry-java/blob/raven-java-8.x/docs/modules/raven.rst). + ## Installation Using Maven: @@ -59,6 +60,7 @@ $ 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]({%- link _documentation/clients/java/config.md -%}#configuration) for ways you can do this. + ## In Practice diff --git a/src/collections/_documentation/clients/java/modules/log4j.md b/src/collections/_documentation/clients/java/modules/log4j.md index 96a46f6305659..94e9441f124d6 100644 --- a/src/collections/_documentation/clients/java/modules/log4j.md +++ b/src/collections/_documentation/clients/java/modules/log4j.md @@ -9,6 +9,7 @@ The source can be found [on Github](https://github.com/getsentry/sentry-java/tre **Note:** The old `raven-log4j` library is no longer maintained. It is highly recommended that you [migrate]({%- link _documentation/clients/java/migration.md -%}) to `sentry-log4j` (which this documentation covers). [Check out the migration guide]({%- link _documentation/clients/java/migration.md -%}) for more information. If you are still using `raven-log4j` you can [find the old documentation here](https://github.com/getsentry/sentry-java/blob/raven-java-8.x/docs/modules/log4j.rst). + ## Installation Using Maven: @@ -89,6 +90,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]({%- link _documentation/clients/java/config.md -%}#configuration) for ways you can do this. + ## Additional Data diff --git a/src/collections/_documentation/clients/java/modules/log4j2.md b/src/collections/_documentation/clients/java/modules/log4j2.md index 4e4c09e2fcaab..d3685d7b093d9 100644 --- a/src/collections/_documentation/clients/java/modules/log4j2.md +++ b/src/collections/_documentation/clients/java/modules/log4j2.md @@ -9,6 +9,7 @@ The source can be found [on Github](https://github.com/getsentry/sentry-java/tre **Note:** The old `raven-log4j2` library is no longer maintained. It is highly recommended that you [migrate]({%- link _documentation/clients/java/migration.md -%}) to `sentry-log4j2` (which this documentation covers). [Check out the migration guide]({%- link _documentation/clients/java/migration.md -%}) for more information. If you are still using `raven-log4j2` you can [find the old documentation here](https://github.com/getsentry/sentry-java/blob/raven-java-8.x/docs/modules/log4j2.rst). + ## Installation Using Maven: @@ -63,6 +64,7 @@ Example configuration using the `log4j2.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]({%- link _documentation/clients/java/config.md -%}#configuration) for ways you can do this. + ## Additional Data diff --git a/src/collections/_documentation/clients/java/modules/logback.md b/src/collections/_documentation/clients/java/modules/logback.md index 186c2eb290ac4..a76c972e369a9 100644 --- a/src/collections/_documentation/clients/java/modules/logback.md +++ b/src/collections/_documentation/clients/java/modules/logback.md @@ -9,6 +9,7 @@ The source can be found [on Github](https://github.com/getsentry/sentry-java/tre **Note:** The old `raven-logback` library is no longer maintained. It is highly recommended that you [migrate]({%- link _documentation/clients/java/migration.md -%}) to `sentry-logback` (which this documentation covers). [Check out the migration guide]({%- link _documentation/clients/java/migration.md -%}) for more information. If you are still using `raven-logback` you can [find the old documentation here](https://github.com/getsentry/sentry-java/blob/raven-java-8.x/docs/modules/logback.rst). + ## Installation Using Maven: @@ -67,6 +68,7 @@ Example configuration using the `logback.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]({%- link _documentation/clients/java/config.md -%}#setting-the-dsn) for ways you can do this. + ## Additional Data diff --git a/src/collections/_documentation/clients/java/usage.md b/src/collections/_documentation/clients/java/usage.md index d6363a4d1bbf4..1543de6f3ffdc 100644 --- a/src/collections/_documentation/clients/java/usage.md +++ b/src/collections/_documentation/clients/java/usage.md @@ -5,6 +5,7 @@ sidebar_order: 2 **Note:** The following page provides examples on how to configure and use Sentry directly. It is **highly recommended** that you use one of the [provided integrations]({%- link _documentation/clients/java/modules/index.md -%}#integrations) if possible. Once the integration is configured you can _also_ use Sentry’s static API, as shown below, in order to do things like record breadcrumbs, set the current user, or manually send events. + ## Installation Using Maven: @@ -30,7 +31,9 @@ libraryDependencies += "io.sentry" % "sentry" % "1.7.5" ``` For other dependency managers see the [central Maven repository](https://search.maven.org/#artifactdetails%7Cio.sentry%7Csentry%7C1.7.5%7Cjar). + + ## 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: @@ -140,6 +143,7 @@ public class MyClass { } } ``` + ### Building More Complex Events diff --git a/src/collections/_documentation/clients/javascript/index.md b/src/collections/_documentation/clients/javascript/index.md index 2798b1659e264..b6df36e5d5418 100644 --- a/src/collections/_documentation/clients/javascript/index.md +++ b/src/collections/_documentation/clients/javascript/index.md @@ -7,6 +7,7 @@ Raven.js is the official browser JavaScript client for Sentry. It automatically **Note**: If you’re using Node.js on the server, you’ll need [raven-node]({%- link _documentation/clients/node/index.md -%}). + ## Installation The easiest way to load Raven.js is to load it directly from our CDN. This script tag should be included after other libraries are loaded, but before your main application code (e.g. app.js): @@ -52,6 +53,7 @@ try { ``` There are more ways to report errors. For a complete guide on this see [Reporting Errors Correctly]({%- link _documentation/clients/javascript/usage.md -%}#raven-js-reporting-errors). + ## Adding Context diff --git a/src/collections/_documentation/clients/javascript/integrations/angular.md b/src/collections/_documentation/clients/javascript/integrations/angular.md index 1c9ea27d50120..213eb00fbc916 100644 --- a/src/collections/_documentation/clients/javascript/integrations/angular.md +++ b/src/collections/_documentation/clients/javascript/integrations/angular.md @@ -11,6 +11,7 @@ Additionally, Raven.js can be configured to catch any Angular-specific (2.x) exc Raven.js ships with a [TypeScript declaration file](https://github.com/getsentry/raven-js/blob/master/packages/raven-js/typescript/raven.d.ts), which helps static checking correctness of Raven.js API calls, and facilitates auto-complete in TypeScript-aware IDEs like Visual Studio Code. + ## Installation Raven.js should be installed via npm. @@ -107,3 +108,4 @@ export class AppModule { } ``` Once you’ve completed that step, you are done. + diff --git a/src/collections/_documentation/clients/javascript/integrations/angularjs.md b/src/collections/_documentation/clients/javascript/integrations/angularjs.md index 7c8c72ef9105e..d43044ff01489 100644 --- a/src/collections/_documentation/clients/javascript/integrations/angularjs.md +++ b/src/collections/_documentation/clients/javascript/integrations/angularjs.md @@ -11,6 +11,7 @@ Additionally, the Raven.js AngularJS plugin will catch any AngularJS-specific ex **Note**: This documentation is for Angular 1.x. See also: [_Angular 2.x_]({%- link _documentation/clients/javascript/integrations/angular.md -%}) + ## Installation Raven.js and the Raven.js Angular plugin are distributed using a few different methods. @@ -126,3 +127,4 @@ angular.module(moduleName, [ module.exports = moduleName; ``` + diff --git a/src/collections/_documentation/clients/javascript/integrations/backbone.md b/src/collections/_documentation/clients/javascript/integrations/backbone.md index c69dd8c4e8d80..95df48e03bbb8 100644 --- a/src/collections/_documentation/clients/javascript/integrations/backbone.md +++ b/src/collections/_documentation/clients/javascript/integrations/backbone.md @@ -3,6 +3,7 @@ title: Backbone sidebar_order: 8 --- + ## Installation Start by adding the `raven.js` script tag to your page. It should be loaded as early as possible. @@ -21,3 +22,4 @@ Raven.config('___PUBLIC_DSN___').install() ``` At this point, Raven is ready to capture any uncaught exception. + diff --git a/src/collections/_documentation/clients/javascript/integrations/ember.md b/src/collections/_documentation/clients/javascript/integrations/ember.md index 9efa52ae4f4eb..0750e9b0e1e0d 100644 --- a/src/collections/_documentation/clients/javascript/integrations/ember.md +++ b/src/collections/_documentation/clients/javascript/integrations/ember.md @@ -9,6 +9,7 @@ On its own, Raven.js will report any uncaught exceptions triggered from your app Additionally, the Raven.js Ember plugin will catch any Ember-specific exceptions reported through Ember’s [onerror](https://guides.emberjs.com/v3.0.2/configuring-ember/debugging/#toc_implement-an-ember-onerror-hook-to-log-all-errors-in-production). hook and any [RSVP promises](https://guides.emberjs.com/v3.2.0/configuring-ember/debugging/#toc_errors-within-an-code-rsvp-promise-code) that would otherwise be swallowed. + ## Installation Raven.js and the Raven.js Ember plugin are distributed using a few different methods. @@ -80,3 +81,4 @@ These examples assume that Ember is exported globally as `window.Ember`. You can ```javascript Raven.addPlugin(Raven.Plugins.Ember, Ember); ``` + diff --git a/src/collections/_documentation/clients/javascript/integrations/react.md b/src/collections/_documentation/clients/javascript/integrations/react.md index fb317a6494e67..8acbdbc204c9f 100644 --- a/src/collections/_documentation/clients/javascript/integrations/react.md +++ b/src/collections/_documentation/clients/javascript/integrations/react.md @@ -3,6 +3,7 @@ title: React sidebar_order: 10 --- + ## Installation Start by adding the `raven.js` script tag to your page. It should be loaded as early as possible, before your main javascript bundle. @@ -21,7 +22,7 @@ Raven.config('___PUBLIC_DSN___').install() ``` At this point, Raven is ready to capture any uncaught exception. - + ## Expanded Usage If you’re using React 16 or above, [Error Boundaries](https://reactjs.org/blog/2017/07/26/error-handling-in-react-16.html) are an important tool for defining the behavior of your application in the face of errors. Be sure to send errors they catch to Sentry using `Raven.captureException`, and optionally this is also a great opportunity to surface [User Feedback]({%- link _documentation/learn/user-feedback.md -%}) diff --git a/src/collections/_documentation/clients/javascript/integrations/vue.md b/src/collections/_documentation/clients/javascript/integrations/vue.md index 20301cc8c823a..e8dab6b672294 100644 --- a/src/collections/_documentation/clients/javascript/integrations/vue.md +++ b/src/collections/_documentation/clients/javascript/integrations/vue.md @@ -18,6 +18,7 @@ On its own, Raven.js will report any uncaught exceptions triggered from your app Additionally, the Raven.js Vue plugin will capture the name and props state of the active component where the error was thrown. This is reported via Vue’s _config.errorHandler_ hook. + ## Installation Raven.js and the Raven.js Vue plugin are distributed using a few different methods. @@ -96,3 +97,5 @@ Raven .addPlugin(RavenVue, Vue) .install(); ``` + + diff --git a/src/collections/_documentation/clients/node/index.md b/src/collections/_documentation/clients/node/index.md index 98363ca10d182..2b3a04cad573f 100644 --- a/src/collections/_documentation/clients/node/index.md +++ b/src/collections/_documentation/clients/node/index.md @@ -7,6 +7,7 @@ raven-node is the official Node.js client for Sentry. **Note**: If you’re using JavaScript in the browser, you’ll need [raven-js](https://docs.sentry.io/clients/javascript). + ## Installation Raven is distributed via `npm`: @@ -14,7 +15,9 @@ Raven is distributed via `npm`: ```bash $ npm install raven --save ``` + + ## Configuring the Client Next you need to initialize the Raven client and configure it to use your [Sentry DSN]({%- link _documentation/learn/quickstart.md -%}#configure-the-dsn): @@ -27,7 +30,9 @@ Raven.config('___PUBLIC_DSN___').install(); At this point, Raven is set up to capture and report any uncaught exceptions. You can optionally pass an object of configuration options as the 2nd argument to _Raven.config_. For more information, see [_Configuration_]({%- link _documentation/clients/node/config.md -%}). + + ## Reporting Errors Raven’s `install` method sets up a global handler to automatically capture any uncaught exceptions. You can also report errors manually with `try...catch` and a call to `captureException`: @@ -39,6 +44,7 @@ try { Raven.captureException(e); } ``` + You can also use `wrap` and `context` to have Raven wrap a function and automatically capture any exceptions it throws: diff --git a/src/collections/_documentation/clients/node/integrations/connect.md b/src/collections/_documentation/clients/node/integrations/connect.md index bd697e35f537a..4a95149d91f66 100644 --- a/src/collections/_documentation/clients/node/integrations/connect.md +++ b/src/collections/_documentation/clients/node/integrations/connect.md @@ -3,6 +3,7 @@ title: Connect sidebar_order: 6 --- + ```javascript var connect = require('connect'); var Raven = require('raven'); @@ -36,3 +37,4 @@ connect( onError, ).listen(3000); ``` + diff --git a/src/collections/_documentation/clients/node/integrations/express.md b/src/collections/_documentation/clients/node/integrations/express.md index 998f5d0b0f757..5ec71b023b582 100644 --- a/src/collections/_documentation/clients/node/integrations/express.md +++ b/src/collections/_documentation/clients/node/integrations/express.md @@ -3,6 +3,7 @@ title: Express sidebar_order: 7 --- + ```javascript var app = require('express')(); var Raven = require('raven'); @@ -30,3 +31,4 @@ app.use(function onError(err, req, res, next) { app.listen(3000); ``` + diff --git a/src/collections/_documentation/clients/node/integrations/koa.md b/src/collections/_documentation/clients/node/integrations/koa.md index ae9d73d7b4754..58ef948a74e8b 100644 --- a/src/collections/_documentation/clients/node/integrations/koa.md +++ b/src/collections/_documentation/clients/node/integrations/koa.md @@ -3,6 +3,7 @@ title: Koa sidebar_order: 8 --- + ```javascript var koa = require('koa'); var Raven = require('raven'); @@ -18,3 +19,4 @@ app.on('error', function (err) { app.listen(3000); ``` + diff --git a/src/collections/_documentation/clients/php/index.md b/src/collections/_documentation/clients/php/index.md index 53801a9ebb2df..84aa5017454b5 100644 --- a/src/collections/_documentation/clients/php/index.md +++ b/src/collections/_documentation/clients/php/index.md @@ -6,6 +6,7 @@ sidebar_relocation: platforms The PHP SDK for Sentry supports PHP 5.3 and higher. It’s available as a BSD licensed Open Source library. + ## Installation There are various ways to install the PHP integration for Sentry. The recommended way is to use [Composer](http://getcomposer.org/): @@ -23,7 +24,9 @@ Alternatively you can manually install it: require_once '/path/to/Raven/library/Raven/Autoloader.php'; Raven_Autoloader::register(); ``` + + ## Configuration The most important part is the creation of the raven client. Create it once and reference it from anywhere you want to interface with Sentry: @@ -40,6 +43,7 @@ $error_handler->registerExceptionHandler(); $error_handler->registerErrorHandler(); $error_handler->registerShutdownFunction(); ``` + ## Adding Context diff --git a/src/collections/_documentation/clients/php/integrations/laravel.md b/src/collections/_documentation/clients/php/integrations/laravel.md index 84835aa873414..b2d65083569c0 100644 --- a/src/collections/_documentation/clients/php/integrations/laravel.md +++ b/src/collections/_documentation/clients/php/integrations/laravel.md @@ -5,6 +5,7 @@ sidebar_order: 3 Laravel is supported via a native package, [sentry-laravel](https://github.com/getsentry/sentry-laravel). + ## Laravel 5.x {#laravel-5-x} Install the `sentry/sentry-laravel` package: @@ -205,7 +206,7 @@ return array( // 'release' => trim(exec('git log --pretty="%h" -n1 HEAD')), ); ``` - + ## Testing with Artisan You can test your configuration using the provided `artisan` command: diff --git a/src/collections/_documentation/clients/php/integrations/monolog.md b/src/collections/_documentation/clients/php/integrations/monolog.md index 1e9ba2de42832..38e7fa5475fca 100644 --- a/src/collections/_documentation/clients/php/integrations/monolog.md +++ b/src/collections/_documentation/clients/php/integrations/monolog.md @@ -3,6 +3,7 @@ title: Monolog sidebar_order: 4 --- + ## Capturing Errors Monolog supports Sentry out of the box, so you’ll just need to configure a handler: @@ -50,3 +51,4 @@ $client = new Raven_Client('___PUBLIC_DSN___'); $handler = new \Raven_Breadcrumbs_MonologHandler($client); $monolog->pushHandler($handler); ``` + diff --git a/src/collections/_documentation/clients/php/integrations/symfony2.md b/src/collections/_documentation/clients/php/integrations/symfony2.md index 7a244a611b85a..277d67bd6b5b8 100644 --- a/src/collections/_documentation/clients/php/integrations/symfony2.md +++ b/src/collections/_documentation/clients/php/integrations/symfony2.md @@ -5,6 +5,7 @@ sidebar_order: 5 Symfony is supported via the [sentry-symfony](https://github.com/getsentry/sentry-symfony) package as a native bundle. + ## Symfony 2+ Install the `sentry/sentry-symfony` package: @@ -40,3 +41,4 @@ Add your DSN to `app/config/config.yml`: sentry: dsn: "___PUBLIC_DSN___" ``` + diff --git a/src/collections/_documentation/clients/php/usage.md b/src/collections/_documentation/clients/php/usage.md index c421b06e3da43..95fcfca7f8b15 100644 --- a/src/collections/_documentation/clients/php/usage.md +++ b/src/collections/_documentation/clients/php/usage.md @@ -13,6 +13,7 @@ The most important part is the creation of the raven client. Create it once and $sentryClient = new Raven_Client('___PUBLIC_DSN___'); ``` + ## Capturing Errors Sentry includes basic functionality for reporting any uncaught exceptions or PHP errors. This is done via the error handler, and appropriate hooks for each of PHP’s built-in reporting: @@ -31,6 +32,7 @@ Calling `install()` on a Raven_Client instance will automatically register these title="Note" content=__alert_content %} + ## Reporting Exceptions diff --git a/src/collections/_documentation/clients/python/index.md b/src/collections/_documentation/clients/python/index.md index 6b3a8d2c65447..a39f9ae64058a 100644 --- a/src/collections/_documentation/clients/python/index.md +++ b/src/collections/_documentation/clients/python/index.md @@ -5,6 +5,7 @@ sidebar_order: 12 For pairing Sentry up with Python you can use the Raven for Python (raven-python) library. It is the official standalone Python client for Sentry. It can be used with any modern Python interpreter be it CPython 2.x or 3.x, PyPy or Jython. It’s an Open Source project and available under a very liberal BSD license. + ## Installation If you haven’t already, start by downloading Raven. The easiest way is with _pip_: @@ -12,6 +13,7 @@ If you haven’t already, start by downloading Raven. The easiest way is with _p ```bash pip install raven --upgrade ``` + ## Configuring the Client diff --git a/src/collections/_documentation/clients/python/integrations/bottle.md b/src/collections/_documentation/clients/python/integrations/bottle.md index 84df049824811..daacc47e743a2 100644 --- a/src/collections/_documentation/clients/python/integrations/bottle.md +++ b/src/collections/_documentation/clients/python/integrations/bottle.md @@ -13,6 +13,7 @@ If you haven’t already, start by downloading Raven. The easiest way is with _p pip install raven --upgrade ``` + ## Setup The first thing you’ll need to do is to disable catchall in your Bottle app: @@ -65,3 +66,4 @@ Log a generic message with `captureMessage`: ```python request.app.sentry.captureMessage('Hello, world!') ``` + diff --git a/src/collections/_documentation/clients/python/integrations/celery.md b/src/collections/_documentation/clients/python/integrations/celery.md index dd62e7092e01f..12508be004830 100644 --- a/src/collections/_documentation/clients/python/integrations/celery.md +++ b/src/collections/_documentation/clients/python/integrations/celery.md @@ -13,6 +13,7 @@ If you haven’t already, start by downloading Raven. The easiest way is with _p pip install raven --upgrade ``` + ## Setup To capture errors, you need to register a couple of signals to hijack Celery error handling: @@ -61,3 +62,4 @@ class Celery(celery.Celery): app = Celery(__name__) app.config_from_object('django.conf:settings') ``` + diff --git a/src/collections/_documentation/clients/python/integrations/django.md b/src/collections/_documentation/clients/python/integrations/django.md index e2c14d828c3bb..a89548b129b8a 100644 --- a/src/collections/_documentation/clients/python/integrations/django.md +++ b/src/collections/_documentation/clients/python/integrations/django.md @@ -13,6 +13,7 @@ If you haven’t already, start by downloading Raven. The easiest way is with _p pip install raven --upgrade ``` + ## Setup Using the Django integration is as simple as adding `raven.contrib.django.raven_compat` to your installed apps: @@ -58,6 +59,7 @@ from raven.contrib.django.raven_compat.models import client client.captureException() ``` + ## Using with Raven.js {#using-with-raven-js} diff --git a/src/collections/_documentation/clients/python/integrations/flask.md b/src/collections/_documentation/clients/python/integrations/flask.md index 48f1fff60112f..88cc4cfe5ed95 100644 --- a/src/collections/_documentation/clients/python/integrations/flask.md +++ b/src/collections/_documentation/clients/python/integrations/flask.md @@ -3,6 +3,7 @@ title: Flask sidebar_order: 7 --- + ## Installation If you haven’t already, install raven with its explicit Flask dependencies: @@ -21,6 +22,7 @@ sentry = Sentry(app, dsn='___DSN___') ``` If you don’t specify the `dsn` value, we will attempt to read it from your environment under the `SENTRY_DSN` key. + ## Extended Setup diff --git a/src/collections/_documentation/clients/python/integrations/pylons.md b/src/collections/_documentation/clients/python/integrations/pylons.md index 4085c626545cb..1809c321a5745 100644 --- a/src/collections/_documentation/clients/python/integrations/pylons.md +++ b/src/collections/_documentation/clients/python/integrations/pylons.md @@ -13,6 +13,7 @@ If you haven’t already, start by downloading Raven. The easiest way is with _p pip install raven --upgrade ``` + ## WSGI Middleware A Pylons-specific middleware exists to enable easy configuration from settings: @@ -80,3 +81,4 @@ You may want to setup other loggers as well. title="Note" content=__alert_content %} + diff --git a/src/collections/_documentation/clients/python/integrations/pyramid.md b/src/collections/_documentation/clients/python/integrations/pyramid.md index 83f181ba0ec3b..48798f5f032b5 100644 --- a/src/collections/_documentation/clients/python/integrations/pyramid.md +++ b/src/collections/_documentation/clients/python/integrations/pyramid.md @@ -11,6 +11,7 @@ If you haven’t already, start by downloading Raven. The easiest way is with _p pip install raven --upgrade ``` + ## PasteDeploy Filter A filter factory for [PasteDeploy](https://pastedeploy.readthedocs.io/en/latest/) exists to allow easily inserting Raven into a WSGI pipeline: @@ -83,3 +84,4 @@ You may want to setup other loggers as well. See the [Pyramid Logging Documentat %} Instead of defining the DSN in the _.ini_ file you can also use the environment variable `SENTRY_DSN` which overwrites the setting in this file. Because of a syntax check you cannot remove the `args` setting completely, as workaround you can define an empty list of arguments `args = ()`. + diff --git a/src/collections/_documentation/clients/python/integrations/rq.md b/src/collections/_documentation/clients/python/integrations/rq.md index 6599b63e7f21f..cf1588cc6b16c 100644 --- a/src/collections/_documentation/clients/python/integrations/rq.md +++ b/src/collections/_documentation/clients/python/integrations/rq.md @@ -5,6 +5,7 @@ sidebar_order: 12 Starting with RQ version 0.3.1, support for Sentry has been built in. + ## Usage RQ natively supports binding with Sentry by passing your `SENTRY_DSN` through `rqworker`: @@ -27,3 +28,4 @@ register_sentry(client, worker) ``` Please see `rq`‘s documentation for more information: [http://python-rq.org/patterns/sentry/](http://python-rq.org/patterns/sentry/) + diff --git a/src/collections/_documentation/clients/python/integrations/tornado.md b/src/collections/_documentation/clients/python/integrations/tornado.md index 5e0cabf5673db..fc19e1d6136cf 100644 --- a/src/collections/_documentation/clients/python/integrations/tornado.md +++ b/src/collections/_documentation/clients/python/integrations/tornado.md @@ -12,7 +12,7 @@ If you haven’t already, start by downloading Raven. The easiest way is with _p ```bash pip install raven --upgrade ``` - + ## Setup The first thing you’ll need to do is to initialize sentry client under your application @@ -48,6 +48,7 @@ class UncaughtExceptionExampleHandler( ``` You can also send events manually using the shortcuts defined in _SentryMixin_. The shortcuts can be used for both asynchronous and synchronous usage. + ### Asynchronous diff --git a/src/collections/_documentation/clients/python/usage.md b/src/collections/_documentation/clients/python/usage.md index 167e87a4a61ff..285f6baa594c4 100644 --- a/src/collections/_documentation/clients/python/usage.md +++ b/src/collections/_documentation/clients/python/usage.md @@ -4,6 +4,7 @@ title: 'Basic Usage' This gives a basic overview of how to use the raven client with Python directly. + ## Capture an Error The most basic use for raven is to record one specific error that occurs: @@ -26,6 +27,7 @@ To report an arbitrary event you can use the [`capture()`]({%- link _documentati ```python client.captureMessage('Something went fundamentally wrong') ``` + ## Adding Context diff --git a/src/collections/_documentation/clients/react-native/index.md b/src/collections/_documentation/clients/react-native/index.md index ebcc530834657..a22f9d2b19fc1 100644 --- a/src/collections/_documentation/clients/react-native/index.md +++ b/src/collections/_documentation/clients/react-native/index.md @@ -6,6 +6,7 @@ sidebar_relocation: platforms This is the documentation for our React-Native SDK. The React-Native SDK uses a native extension for iOS and Android but will fall back to a pure JavaScript version if necessary. + ## Installation Start by adding Sentry and then linking it: @@ -36,6 +37,7 @@ Upon linking the following changes will be performed: To see what is happening during linking you can refer to [_Manual Setup_]({%- link _documentation/clients/react-native/manual-setup.md -%}) which will give you all the details. Note that we only support `react-native >= 0.38` at the moment. + ## Upgrading @@ -54,6 +56,7 @@ When you use Xcode you can hook directly into the build process to upload debug For Android we hook into gradle for the sourcemap build process. When you run `react-native link` the gradle files are automatically updated. When you run `./gradlew assembleRelease` sourcemaps are automatically built and uploaded to Sentry. + ## Client Configuration Note: When you run `react-native link` we will automatically update your _index.ios.js_ / _index.android.js_ with the following changes: @@ -64,6 +67,7 @@ Sentry.config('___PUBLIC_DSN___').install(); ``` You can pass additional configuration options to the _config()_ method if you want to do so. + ## Mixed Stacktraces diff --git a/src/collections/_documentation/clients/ruby/index.md b/src/collections/_documentation/clients/ruby/index.md index 8647508e3b00e..837b91f9fd666 100644 --- a/src/collections/_documentation/clients/ruby/index.md +++ b/src/collections/_documentation/clients/ruby/index.md @@ -6,6 +6,7 @@ sidebar_relocation: platforms Raven for Ruby is a client and integration layer for the Sentry error reporting API. It supports Ruby 1.9.3 and 2.x. JRuby support is provided but experimental. + ## Installation Raven Ruby comes as a gem and is straightforward to install. If you are using Bundler just add this to your `Gemfile`: @@ -46,6 +47,7 @@ rescue ZeroDivisionError => exception Raven.capture_exception(exception) end ``` + ## Additional Context diff --git a/src/collections/_documentation/clients/ruby/integrations/rack.md b/src/collections/_documentation/clients/ruby/integrations/rack.md index 00e4da86d3f48..fc40d690e4e90 100644 --- a/src/collections/_documentation/clients/ruby/integrations/rack.md +++ b/src/collections/_documentation/clients/ruby/integrations/rack.md @@ -3,6 +3,7 @@ title: 'Rack (Sinatra etc.)' sidebar_order: 8 --- + ## Installation Install the SDK via Rubygems by adding it to your `Gemfile`: @@ -24,3 +25,4 @@ end use Raven::Rack ``` + diff --git a/src/collections/_documentation/clients/ruby/integrations/rails.md b/src/collections/_documentation/clients/ruby/integrations/rails.md index 6ca8553b7ebad..8ffa1528dafcc 100644 --- a/src/collections/_documentation/clients/ruby/integrations/rails.md +++ b/src/collections/_documentation/clients/ruby/integrations/rails.md @@ -3,6 +3,7 @@ title: 'Ruby on Rails' sidebar_order: 7 --- + In Rails, all uncaught exceptions will be automatically reported. We support Rails 4 and newer. @@ -55,3 +56,4 @@ end ## Caveats Currently, custom exception applications (_config.exceptions_app_) are not supported. If you are using a custom exception app, you must manually integrate Raven yourself. + diff --git a/src/collections/_documentation/platforms/minidump/index.md b/src/collections/_documentation/platforms/minidump/index.md index 81dcdc64ac53a..1a0ecd6b17a35 100644 --- a/src/collections/_documentation/platforms/minidump/index.md +++ b/src/collections/_documentation/platforms/minidump/index.md @@ -10,6 +10,7 @@ Sentry can process Minidump crash reports, a memory dump used on Windows and by In order to receive symbolicated stack traces, you have to upload debug information to Sentry. For more information, see [Uploading Debug Information](#minidump-dif). + ## Platform and Language Support Minidumps are currently supported for **Windows, macOS and Linux**. There is no limitation as to which programming language can be used. Sentry can also demangle symbols from the following languages; other languages will show the mangled name instead: @@ -18,6 +19,7 @@ Minidumps are currently supported for **Windows, macOS and Linux**. There is no - ObjectiveC and ObjectiveC++ - Swift - Rust + ## What is a Minidump? {#what-is-a-minidump} @@ -39,6 +41,7 @@ Minidumps are memory dumps of the process at the moment it crashes. As such, the In addition to this information, you can add further meta data specific to Sentry, which can help in organizing and analyzing issues. For more information, see [Passing Additional Data](#minidump-additional). + ## Creating and Uploading Minidumps {#minidump-integration} Depending on your operating system and programming language, there are various alternatives to create minidumps and upload them to Sentry. See the following resources for libraries that support generating minidump crash reports: @@ -55,6 +58,7 @@ $ curl -X POST \ ``` To send additional information, simply add more form fields to this request. For a full description of fields accepted by Sentry, see [Passing Additional Data](#minidump-additional). + ## Passing Additional Data {#minidump-additional} From 462950897189e9636c5ab30ac93d771f6584d13d Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Thu, 13 Sep 2018 16:07:41 -0700 Subject: [PATCH 111/171] everything is wizard --- src/_data/platforms.yml | 84 ++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index c7347ad56a82c..1511b9735c6b5 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -4,7 +4,7 @@ type: framework name: Koa doc_link: /clients/node/integrations/koa/ - legacy_wizard: + wizard: - _documentation/clients/node/index.md#installation - _documentation/clients/node/integrations/koa.md - @@ -15,7 +15,7 @@ # XXX: does this have a better link? doc_link: /platforms/javascript/ # this is actually the old legacy_wizard: - legacy_wizard: + wizard: - _documentation/clients/node/index.md case_style: camelCase fallback_platform: javascript @@ -35,7 +35,7 @@ name: Express # XXX: this links to the old ones doc_link: /clients/node/integrations/express/ - legacy_wizard: + wizard: - _documentation/clients/node/index.md#installation - _documentation/clients/node/integrations/express.md - @@ -45,7 +45,7 @@ name: Connect # XXX: this links to the old ones doc_link: /clients/node/integrations/connect/ - legacy_wizard: + wizard: - _documentation/clients/node/index.md#installation - _documentation/clients/node/integrations/connect.md - @@ -77,7 +77,7 @@ type: language name: Java doc_link: /clients/java/ - legacy_wizard: + wizard: - _documentation/clients/java/usage.md - slug: logging @@ -85,7 +85,7 @@ type: framework name: java.util.logging doc_link: /clients/java/modules/jul/ - legacy_wizard: + wizard: - _documentation/clients/java/modules/jul.md - slug: logback @@ -93,7 +93,7 @@ type: framework name: Logback doc_link: /clients/java/modules/logback/ - legacy_wizard: + wizard: - _documentation/clients/java/modules/logback.md - slug: android @@ -101,7 +101,7 @@ type: framework name: Android doc_link: /clients/java/modules/android/ - legacy_wizard: + wizard: - _documentation/clients/java/modules/android.md - slug: log4j2 @@ -109,7 +109,7 @@ type: framework name: 'Log4j 2.x' doc_link: /clients/java/modules/log4j2/ - legacy_wizard: + wizard: - _documentation/clients/java/modules/log4j2.md - slug: log4j @@ -117,7 +117,7 @@ type: framework name: 'Log4j 1.x' doc_link: /clients/java/modules/log4j/ - legacy_wizard: + wizard: - _documentation/clients/java/modules/log4j.md - slug: appengine @@ -125,7 +125,7 @@ type: framework name: 'Google App Engine' doc_link: /clients/java/modules/appengine/ - legacy_wizard: + wizard: - _documentation/clients/java/modules/appengine.md - slug: python @@ -134,7 +134,7 @@ name: Python doc_link: /platforms/python/ # this is actually the old legacy_wizard: - legacy_wizard: + wizard: - _documentation/clients/python/index.md - _documentation/clients/python/usage.md case_style: snake_case @@ -152,7 +152,7 @@ type: framework name: Pyramid doc_link: /clients/python/integrations/pyramid/ - legacy_wizard: + wizard: - _documentation/clients/python/index.md - _documentation/clients/python/integrations/pyramid.md case_style: camelCase @@ -162,7 +162,7 @@ type: framework name: RQ doc_link: /clients/python/integrations/rq/ - legacy_wizard: + wizard: _documentation/clients/python/index.md _documentation/clients/python/integrations/rq.md - @@ -171,7 +171,7 @@ type: framework name: Flask doc_link: /clients/python/integrations/flask/ - legacy_wizard: + wizard: - _documentation/clients/python/index.md - _documentation/clients/python/integrations/flask.md - @@ -180,7 +180,7 @@ type: framework name: Django doc_link: /clients/python/integrations/django/ - legacy_wizard: + wizard: - _documentation/clients/python/index.md - _documentation/clients/python/integrations/django.md - @@ -189,7 +189,7 @@ type: library name: Celery doc_link: /clients/python/integrations/celery/ - legacy_wizard: + wizard: - _documentation/clients/python/index.md - _documentation/clients/python/integrations/celery.md - @@ -198,7 +198,7 @@ type: framework name: Tornado doc_link: /clients/python/integrations/tornado/ - legacy_wizard: + wizard: - _documentation/clients/python/index.md - _documentation/clients/python/integrations/tornado.md - @@ -207,7 +207,7 @@ type: framework name: Bottle doc_link: /clients/python/integrations/bottle/ - legacy_wizard: + wizard: - _documentation/clients/python/index.md - _documentation/clients/python/integrations/bottle.md - @@ -216,7 +216,7 @@ type: framework name: Pylons doc_link: /clients/python/integrations/pylons/ - legacy_wizard: + wizard: - _documentation/clients/python/index.md - _documentation/clients/python/integrations/pylons.md - @@ -225,7 +225,7 @@ type: language name: Swift doc_link: /clients/cocoa/ - legacy_wizard: + wizard: - _documentation/clients/cocoa/index.md - _documentation/clients/cocoa/dsym.md#upload-symbols-with-sentry-cli version: 4.1.0 @@ -245,7 +245,7 @@ name: JavaScript doc_link: /platforms/javascript/ # this is actually the old legacy_wizard: - legacy_wizard: + wizard: - _documentation/clients/javascript/index.md case_style: camelCase superseded_by: @@ -265,7 +265,7 @@ type: framework name: Vue doc_link: /clients/javascript/integrations/vue/ - legacy_wizard: + wizard: - _documentation/clients/javascript/integrations/vue.md version: 3.26.4 version_key: RAVEN_VERSION @@ -275,7 +275,7 @@ type: framework name: Backbone doc_link: /clients/javascript/integrations/backbone/ - legacy_wizard: + wizard: - _documentation/clients/javascript/integrations/backbone.md version: 3.26.4 version_key: RAVEN_VERSION @@ -285,7 +285,7 @@ type: framework name: Ember doc_link: /clients/javascript/integrations/ember/ - legacy_wizard: + wizard: - _documentation/clients/javascript/integrations/ember.md version: 3.26.4 version_key: RAVEN_VERSION @@ -295,7 +295,7 @@ type: framework name: React doc_link: /clients/javascript/integrations/react/ - legacy_wizard: + wizard: - _documentation/clients/javascript/integrations/react.md version: 3.26.4 version_key: RAVEN_VERSION @@ -305,7 +305,7 @@ type: framework name: AngularJS doc_link: /clients/javascript/integrations/angularjs/ - legacy_wizard: + wizard: - _documentation/clients/javascript/integrations/angularjs.md version: 3.26.4 version_key: RAVEN_VERSION @@ -315,7 +315,7 @@ type: framework name: Angular doc_link: /clients/javascript/integrations/angular/ - legacy_wizard: + wizard: - _documentation/clients/javascript/integrations/angular.md version: 3.26.4 version_key: RAVEN_VERSION @@ -334,7 +334,7 @@ type: language name: Elixir doc_link: /clients/elixir/ - legacy_wizard: + wizard: - _documentation/clients/elixir/index.md - _documentation/clients/elixir/usage.md case_style: PascalCase @@ -344,7 +344,7 @@ type: language name: React-Native doc_link: /clients/react-native/ - legacy_wizard: + wizard: - _documentation/clients/react-native/index.md - slug: objc @@ -352,7 +352,7 @@ type: language name: Objective-C doc_link: /clients/cocoa/ - legacy_wizard: + wizard: - _documentation/clients/cocoa/index.md - _documentation/clients/cocoa/dsym.md version: 4.1.0 @@ -365,7 +365,7 @@ name: 'C#' doc_link: /platforms/dotnet/ # this is actually the old legacy_wizard: - legacy_wizard: + wizard: - _documentation/clients/csharp/index.md case_style: PascalCase - @@ -382,7 +382,7 @@ type: language name: Go doc_link: /clients/go/ - legacy_wizard: + wizard: - _documentation/clients/go/index.md - slug: http @@ -390,7 +390,7 @@ type: framework name: net/http doc_link: /clients/go/integrations/http/ - legacy_wizard: + wizard: - _documentation/clients/go/integrations/http.md - slug: laravel @@ -398,7 +398,7 @@ type: framework name: Laravel doc_link: /clients/php/integrations/laravel/ - legacy_wizard: + wizard: - _documentation/clients/php/integrations/laravel.md - slug: php @@ -406,7 +406,7 @@ type: language name: PHP doc_link: /clients/php/ - legacy_wizard: + wizard: - _documentation/clients/php/index.md - _documentation/clients/php/usage.md - @@ -415,7 +415,7 @@ type: framework name: Monolog doc_link: /clients/php/integrations/monolog/ - legacy_wizard: + wizard: - _documentation/clients/php/index.md#installation - _documentation/clients/php/integrations/monolog.md - @@ -424,7 +424,7 @@ type: framework name: Symfony2 doc_link: /clients/php/integrations/symfony2/ - legacy_wizard: + wizard: - _documentation/clients/php/integrations/symfony2.md#symfony-2 - slug: ruby @@ -432,7 +432,7 @@ type: language name: Ruby doc_link: /clients/ruby/ - legacy_wizard: + wizard: - _documentation/clients/ruby/index.md - slug: rack @@ -440,7 +440,7 @@ type: framework name: Rack doc_link: /clients/ruby/integrations/rack/ - legacy_wizard: + wizard: - _documentation/clients/ruby/integrations/rack.md - slug: rails @@ -448,7 +448,7 @@ type: framework name: Rails doc_link: /clients/ruby/integrations/rails/ - legacy_wizard: + wizard: - _documentation/clients/ruby/integrations/rails.md - slug: rust @@ -466,5 +466,5 @@ type: language name: Minidump doc_link: /platforms/minidump/ - legacy_wizard: + wizard: - _documentation/platforms/minidump/index.md From 275c043b14f8d68259ef98541eab2732faf283ba Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Thu, 13 Sep 2018 16:15:05 -0700 Subject: [PATCH 112/171] Include slugs in the picker --- src/_includes/components/platform_content.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_includes/components/platform_content.html b/src/_includes/components/platform_content.html index 76c70a0d7312e..b87f0ca470bc3 100644 --- a/src/_includes/components/platform_content.html +++ b/src/_includes/components/platform_content.html @@ -97,7 +97,7 @@ {%- capture __content -%} {% include_relative {{ __relative_path }} %} {%- endcapture -%} -
+
{{ __content | markdownify }}
{%- endfor -%} From 77f8dab2fdb2fe76d1f409e0135fffffc685ea00 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Thu, 13 Sep 2018 16:15:14 -0700 Subject: [PATCH 113/171] Document --- src/_plugins/platform_api.rb | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index d85f474d82c5e..6bda70b3933bf 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -1,5 +1,27 @@ require 'json' +# The platform api is generated based on the `wizard` key in platforms.yml. This +# key can either be an array of documents with optional section slugs, or `true` +# which sets the value to `_documentation/quickstart.md` and renders only +# the content for that platform. +# +# In the targeted files, the wizard section is indicated by a comment, like so: +# +# +# +# Slugs are optional and are only useful for documents where only one of many +# sections must be referenced, or when sections must be reordered. +# +# When a file is specified without a section, all wizard blocks will be +# concatinated. If a section is specified, only the matching block will be used. +# +# Example: +# +# wizard: true +# wizard: +# - _documentation/path/to/doc.md +# - _documentation/path/to/doc-with-section.md#section-name + module Jekyll class CategoryPage < Page From 5d9ae7c8157ed04aac4d91d8f109f6fb7189e782 Mon Sep 17 00:00:00 2001 From: HazA Date: Fri, 14 Sep 2018 09:36:33 +0200 Subject: [PATCH 114/171] feat: Add learn box for overview pages in platforms --- src/_data/platform_icons.yml | 8 ++++---- src/_includes/learn-sdk.md | 8 ++++++++ src/collections/_documentation/platforms/dotnet/index.md | 2 ++ .../_documentation/platforms/javascript/index.md | 2 ++ .../_documentation/platforms/javascript/react.md | 2 +- src/collections/_documentation/platforms/python/index.md | 2 ++ src/collections/_documentation/platforms/rust/index.md | 2 ++ 7 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 src/_includes/learn-sdk.md diff --git a/src/_data/platform_icons.yml b/src/_data/platform_icons.yml index f3fa803be20c7..26187eeb94c74 100644 --- a/src/_data/platform_icons.yml +++ b/src/_data/platform_icons.yml @@ -1,8 +1,8 @@ -- name: HTML - link: _documentation/platforms/javascript/browser.md - platformicon: HTML5 - - name: JavaScript + link: _documentation/platforms/javascript/index.md + platformicon: javascript + +- name: Browser link: _documentation/platforms/javascript/browser.md platformicon: javascript diff --git a/src/_includes/learn-sdk.md b/src/_includes/learn-sdk.md new file mode 100644 index 0000000000000..057ef5bc7b124 --- /dev/null +++ b/src/_includes/learn-sdk.md @@ -0,0 +1,8 @@ +{% capture __alert_content -%} +This page will provide you with details that are very specific to the platform, to learn how to use our +SDKs in general, please visit the [Learn section]({%- link _documentation/learn/quickstart.md -%}?platform={{ include.platform }}) +{%- endcapture -%} +{%- include components/alert.html + title="Learn about SDK usage" + content=__alert_content +%} \ No newline at end of file diff --git a/src/collections/_documentation/platforms/dotnet/index.md b/src/collections/_documentation/platforms/dotnet/index.md index e61c9057f5125..62ca5b5a582fc 100644 --- a/src/collections/_documentation/platforms/dotnet/index.md +++ b/src/collections/_documentation/platforms/dotnet/index.md @@ -3,6 +3,8 @@ title: .NET sidebar_order: 10 --- +{% include learn-sdk.md platform="csharp" %} + This section will describe features, configurations and general functionality which are specific to the .NET SDK. > New to Sentry and the SDKs in general? Check out our [getting started]({%- link _documentation/learn/quickstart.md -%}) section and learn about our unified SDK API. diff --git a/src/collections/_documentation/platforms/javascript/index.md b/src/collections/_documentation/platforms/javascript/index.md index cb1e5eca10d20..e083d3b330543 100644 --- a/src/collections/_documentation/platforms/javascript/index.md +++ b/src/collections/_documentation/platforms/javascript/index.md @@ -3,6 +3,8 @@ title: JavaScript sidebar_order: 10 --- +{% include learn-sdk.md platform="javascript" %} + All our JavaScript related SDKs provide the same API still there are some differences between them which this section of the docs explains. diff --git a/src/collections/_documentation/platforms/javascript/react.md b/src/collections/_documentation/platforms/javascript/react.md index 36731bc0ac436..3dbddf30b908f 100644 --- a/src/collections/_documentation/platforms/javascript/react.md +++ b/src/collections/_documentation/platforms/javascript/react.md @@ -8,7 +8,7 @@ On its own, `@sentry/browser` will report any uncaught exceptions triggered from If you’re using React 16 or above, Error Boundaries are an important tool for defining the behavior of your application in the face of errors. Be sure to send errors they catch to Sentry using `Sentry.captureException`, and optionally this is also a great opportunity to surface User Feedback -```javascript +```jsx import * as Sentry from '@sentry/browser'; // Sentry.init has to be called in the somewhere before diff --git a/src/collections/_documentation/platforms/python/index.md b/src/collections/_documentation/platforms/python/index.md index c03634782c146..efd1c2c131b92 100644 --- a/src/collections/_documentation/platforms/python/index.md +++ b/src/collections/_documentation/platforms/python/index.md @@ -3,6 +3,8 @@ title: Python sidebar_order: 3 --- +{% include learn-sdk.md platform="python" %} + The [Sentry Python SDK](https://pypi.org/project/sentry-sdk) provides Sentry support for Python 2.7 and 3.4 or later. diff --git a/src/collections/_documentation/platforms/rust/index.md b/src/collections/_documentation/platforms/rust/index.md index 1156352dd0167..57b2af926d9fe 100644 --- a/src/collections/_documentation/platforms/rust/index.md +++ b/src/collections/_documentation/platforms/rust/index.md @@ -3,6 +3,8 @@ title: Rust sidebar_order: 15 --- +{% include learn-sdk.md platform="rust" %} + Sentry-Rust is the official Rust SDK for Sentry. It maps the entire Sentry protocol for Rust and provides convenient helpers for sending common types of events to Sentry. From 32acdbb1af99bfad1db3ec023b66e91ad536c6d5 Mon Sep 17 00:00:00 2001 From: HazA Date: Fri, 14 Sep 2018 10:13:02 +0200 Subject: [PATCH 115/171] feat: Improve JS docs --- src/_includes/learn-sdk.md | 2 +- .../learn/before-breadcrumb/javascript.md | 17 ++++++++++ .../_documentation/platforms/dotnet/index.md | 3 -- .../platforms/javascript/index.md | 32 +++++++++++-------- .../_documentation/platforms/python/index.md | 4 --- 5 files changed, 37 insertions(+), 21 deletions(-) create mode 100644 src/collections/_documentation/learn/before-breadcrumb/javascript.md diff --git a/src/_includes/learn-sdk.md b/src/_includes/learn-sdk.md index 057ef5bc7b124..48d5164db3343 100644 --- a/src/_includes/learn-sdk.md +++ b/src/_includes/learn-sdk.md @@ -1,5 +1,5 @@ {% capture __alert_content -%} -This page will provide you with details that are very specific to the platform, to learn how to use our +This page will provide you with details that are very specific to the platform, to learn how to use our unified SDKs in general, please visit the [Learn section]({%- link _documentation/learn/quickstart.md -%}?platform={{ include.platform }}) {%- endcapture -%} {%- include components/alert.html diff --git a/src/collections/_documentation/learn/before-breadcrumb/javascript.md b/src/collections/_documentation/learn/before-breadcrumb/javascript.md new file mode 100644 index 0000000000000..abf9d34e2dc70 --- /dev/null +++ b/src/collections/_documentation/learn/before-breadcrumb/javascript.md @@ -0,0 +1,17 @@ + +```javascript +import * as Sentry from '@sentry/browser'; + +init({ + dsn: 'https://@sentry.io/', + beforeBreadcrumb(breadcrumb, hint) { + if (breadcrumb.category === 'ui.click') { + const target = hint.event.target; + if (target.ariaLabel) breadcrumb.message = target.ariaLabel; + } + return breadcrumb; + }, +}); +``` + +For information about which hints are available see [hints in javascript]({% link _documentation/platforms/javascript/index.md %}#hints). diff --git a/src/collections/_documentation/platforms/dotnet/index.md b/src/collections/_documentation/platforms/dotnet/index.md index 62ca5b5a582fc..757597f7bcf25 100644 --- a/src/collections/_documentation/platforms/dotnet/index.md +++ b/src/collections/_documentation/platforms/dotnet/index.md @@ -7,9 +7,6 @@ sidebar_order: 10 This section will describe features, configurations and general functionality which are specific to the .NET SDK. -> New to Sentry and the SDKs in general? Check out our [getting started]({%- link _documentation/learn/quickstart.md -%}) section and learn about our unified SDK API. -If you already have the main concepts covered, continue reading for a deep dive into specifics of the .NET SDK. - # Compatibility The main [Sentry NuGet package](https://www.nuget.org/packages/Sentry) targets .NET Standard 2.0. That means, according to the [compatibility table](https://docs.microsoft.com/en-us/dotnet/standard/net-standard), it is compatible with the following versions or newer: diff --git a/src/collections/_documentation/platforms/javascript/index.md b/src/collections/_documentation/platforms/javascript/index.md index e083d3b330543..85fec13c8ef64 100644 --- a/src/collections/_documentation/platforms/javascript/index.md +++ b/src/collections/_documentation/platforms/javascript/index.md @@ -26,15 +26,11 @@ import * as Sentry from '@sentry/browser'; Sentry.init({ dsn: '___PUBLIC_DSN___', - integrations: (integrations) => { - integrations.push(new MyCustomIntegration()) - return integrations - } - // integrations: [new MyCustomIntegration()] + integrations: [new MyAwesomeIntegration()], }) ``` -### Removing a default Integration +### Removing an Integration In this example we will remove the by default enabled integration for adding breadcrumbs to the event: @@ -51,14 +47,20 @@ Sentry.init({ ### Alternative way of setting an Integration -You can also set an array of wanted _Integrations_: ```javascript import * as Sentry from '@sentry/browser'; +// All integration that come with an SDK can be found in +// Sentry.Integrations +// Custom integration must conform this interface: +// https://github.com/getsentry/sentry-javascript/blob/1ebeb9edec4b6c7b07a61e0caac426a66eedaf2a/packages/types/src/index.ts#L205 + Sentry.init({ dsn: '___PUBLIC_DSN___', - integrations: [new MyCustomIntegration()], - // integrations: [...Sentry.defaultIntegrations, new MyCustomIntegration()], + integrations: (integrations) => { + integrations.push(new MyCustomIntegration()) + return integrations + } }) ``` @@ -68,7 +70,7 @@ Event and Breadcrumb `hints` are objects containing various information used to They are available in two places. `beforeSend`/`beforeBreadcrumb` and `eventProcessors`. Those are two ways we'll allow users to modify what we put together. -Examples based on your `cause` property (I use `message` for ease of reading, but there's nothing stopping you from modifying event stacktrace frames). +Examples based on your `cause` property. `beforeSend`/`beforeBreadcrumb`: @@ -82,7 +84,7 @@ init({ const cause = hint.originalException.cause; if (cause) { - processedEvent.message = cause.message; + processedEvent.extra.cause = cause.message; } return processedEvent; @@ -97,7 +99,11 @@ init({ }); ``` -`eventProcessor`: +### EventProcessors + +With `eventProcessors` you are able to hook into the process of enriching the event with additional data. +You can add you own `eventProcessor` on the current scope. The difference to `beforeSend` is that +`eventProcessors` run on the scope level where `beforeSend` runs globally not matter in which scope you are. ```javascript import * as Sentry from '@sentry/browser'; @@ -108,7 +114,7 @@ Sentry.getCurrentHub().configureScope(scope => { const cause = hint.originalException.cause; if (cause) { - processedEvent.message = cause.message; + processedEvent.extra.cause = cause.message; } return processedEvent; diff --git a/src/collections/_documentation/platforms/python/index.md b/src/collections/_documentation/platforms/python/index.md index efd1c2c131b92..e830c98a493a8 100644 --- a/src/collections/_documentation/platforms/python/index.md +++ b/src/collections/_documentation/platforms/python/index.md @@ -8,10 +8,6 @@ sidebar_order: 3 The [Sentry Python SDK](https://pypi.org/project/sentry-sdk) provides Sentry support for Python 2.7 and 3.4 or later. -The Python SDK follows the new unified SDK architecture. To get started -have a look at the [quickstart]({% link _documentation/learn/quickstart.md -%}?platform=python) docs. - This documentation goes over some Python specific things such as integrations to frameworks. From 9382bfba27d2ba22816f10c032e2c60851855b1a Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Fri, 14 Sep 2018 10:25:47 +0200 Subject: [PATCH 116/171] ref: Moved some hint stuff around --- .../learn/before-breadcrumb-hint/python.md | 12 +++++++++++ .../learn/before-breadcrumb/python.md | 6 ++---- .../_documentation/learn/breadcrumbs.md | 6 +++--- src/collections/_documentation/learn/hints.md | 21 +++++++++++++++++-- 4 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 src/collections/_documentation/learn/before-breadcrumb-hint/python.md diff --git a/src/collections/_documentation/learn/before-breadcrumb-hint/python.md b/src/collections/_documentation/learn/before-breadcrumb-hint/python.md new file mode 100644 index 0000000000000..e96e41486f07b --- /dev/null +++ b/src/collections/_documentation/learn/before-breadcrumb-hint/python.md @@ -0,0 +1,12 @@ +```python +import sentry_sdk + +def before_breadcrumb(crumb, hint): + if 'log_record' in hint: + crumb['data']['thread'] = hint['log_record'].threadName + return crumb + +sentry_sdk.init(before_breadcrumb=before_breadcrumb) +``` + +For information about which hints are available see [hints in python]({% link _documentation/platforms/python/index.md %}#hints). diff --git a/src/collections/_documentation/learn/before-breadcrumb/python.md b/src/collections/_documentation/learn/before-breadcrumb/python.md index 0dfd6a2c5acf9..6f78145b8dd85 100644 --- a/src/collections/_documentation/learn/before-breadcrumb/python.md +++ b/src/collections/_documentation/learn/before-breadcrumb/python.md @@ -2,11 +2,9 @@ import sentry_sdk def before_breadcrumb(crumb, hint): - if 'log_record' in hint: - crumb['data']['filename'] = hint['log_record'].filename + if crumb['category'] == 'a.spammy.Logger': + return None return crumb sentry_sdk.init(before_breadcrumb=before_breadcrumb) ``` - -For information about which hints are available see [hints in python]({% link _documentation/platforms/python/index.md %}#hints). diff --git a/src/collections/_documentation/learn/breadcrumbs.md b/src/collections/_documentation/learn/breadcrumbs.md index a16b33ee930c3..dd769a6681ed2 100644 --- a/src/collections/_documentation/learn/breadcrumbs.md +++ b/src/collections/_documentation/learn/breadcrumbs.md @@ -63,8 +63,8 @@ the browser JavaScript SDK will automatically record all location changes. SDKs following the unified API support customizing breadcrumbs through the `before_breadcrumb` hook. This hook is passed an already assembled breadcrumb and in some SDKs an optional -hint. The hint object is platform specific and typically carries a reference to the source -of the breadcrumb. The `before_breadcrumb` function can then modify the breadcrumb or -discard it. +hint. The function can modify the breadcrumb or decide to discard it entirely: {% include components/platform_content.html content_dir='before-breadcrumb' %} + +For information about what can be done with the hint see [hints]({% link _documentation/learn/hints.md %}). diff --git a/src/collections/_documentation/learn/hints.md b/src/collections/_documentation/learn/hints.md index d9ea12bc93746..2c85c0a3e6cec 100644 --- a/src/collections/_documentation/learn/hints.md +++ b/src/collections/_documentation/learn/hints.md @@ -1,6 +1,23 @@ --- -title: Hints +title: Hints-based Customization sidebar_order: 3 --- -XXX: document hints +When an SDK creates an event or breadcrumb for transmission that 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 SDKs). + +# Before Send + +The `before-send` callback is passed the event and a second argument `hint` which holds one or more +hints. Typically this hint holds the original exception so that additional data can be extracted. + +# Before Breadcrumb + +Similar to `before-breadcrumb` hints are also supported here. This is particularly useful when +breadcrumbs should be augmented or changed with some extra data from log records or events. The +following example shows a typical situation where you might want to extract extra information and +how to do it: + +{% include components/platform_content.html content_dir='before-breadcrumb-hint' %} From 0a9c601c05ac2880d1b3fdbeaf537f52cab34992 Mon Sep 17 00:00:00 2001 From: HazA Date: Fri, 14 Sep 2018 10:44:02 +0200 Subject: [PATCH 117/171] feat: Add browser npm platform --- src/_data/platform_icons.yml | 2 +- src/_data/platforms.yml | 10 ++++++++++ .../_documentation/learn/config-intro/browser.md | 3 --- .../_documentation/learn/config-intro/cordova.md | 12 ------------ .../_documentation/learn/config-intro/electron.md | 11 ----------- .../learn/config-intro/{node.md => javascript.md} | 2 -- .../_documentation/learn/configuration.md | 4 ++-- .../learn/getting-started-config/browsernpm.md | 7 +++++++ .../learn/getting-started-config/node.md | 4 ++-- .../learn/getting-started-install/browsernpm.md | 11 +++++++++++ .../_documentation/platforms/javascript/index.md | 4 ++-- 11 files changed, 35 insertions(+), 35 deletions(-) delete mode 100644 src/collections/_documentation/learn/config-intro/cordova.md delete mode 100644 src/collections/_documentation/learn/config-intro/electron.md rename src/collections/_documentation/learn/config-intro/{node.md => javascript.md} (78%) create mode 100644 src/collections/_documentation/learn/getting-started-config/browsernpm.md create mode 100644 src/collections/_documentation/learn/getting-started-install/browsernpm.md diff --git a/src/_data/platform_icons.yml b/src/_data/platform_icons.yml index 26187eeb94c74..e7b3432f43bfa 100644 --- a/src/_data/platform_icons.yml +++ b/src/_data/platform_icons.yml @@ -2,7 +2,7 @@ link: _documentation/platforms/javascript/index.md platformicon: javascript -- name: Browser +- name: Browser JavaScript CDN link: _documentation/platforms/javascript/browser.md platformicon: javascript diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index 0da162c71c9fb..e92e65d3acd48 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -207,6 +207,16 @@ wizard: [] case_style: camelCase fallback_platform: javascript + +- + slug: browsernpm + support_level: production + type: language + name: Browser Javascript NPM + doc_link: /clients/javascript/ + wizard: [] + case_style: camelCase + fallback_platform: javascript - slug: javascript support_level: production diff --git a/src/collections/_documentation/learn/config-intro/browser.md b/src/collections/_documentation/learn/config-intro/browser.md index f2ea797180d83..c67b359f6be46 100644 --- a/src/collections/_documentation/learn/config-intro/browser.md +++ b/src/collections/_documentation/learn/config-intro/browser.md @@ -1,10 +1,7 @@ Options are passed to the `init()` as object: ```javascript -import * as Sentry from '@sentry/browser'; - Sentry.init({ - dsn: '___PUBLIC_DSN___', maxBreadcrumbs: 50, debug: true, }) diff --git a/src/collections/_documentation/learn/config-intro/cordova.md b/src/collections/_documentation/learn/config-intro/cordova.md deleted file mode 100644 index 3e0761c8d76eb..0000000000000 --- a/src/collections/_documentation/learn/config-intro/cordova.md +++ /dev/null @@ -1,12 +0,0 @@ -Options are passed to the `init()` as object in the `onDeviceReady` function: - -```javascript -onDeviceReady: function() { - var Sentry = cordova.require("sentry-cordova.Sentry"); - Sentry.init({ - dsn: '___PUBLIC_DSN___', - maxBreadcrumbs: 50, - debug: true, - }); -} -``` diff --git a/src/collections/_documentation/learn/config-intro/electron.md b/src/collections/_documentation/learn/config-intro/electron.md deleted file mode 100644 index 4836c02699521..0000000000000 --- a/src/collections/_documentation/learn/config-intro/electron.md +++ /dev/null @@ -1,11 +0,0 @@ -Options are passed to the `init()` as object: - -```javascript -import * as Sentry from '@sentry/electron'; - -Sentry.init({ - dsn: '___PUBLIC_DSN___', - maxBreadcrumbs: 50, - debug: true, -}) -``` diff --git a/src/collections/_documentation/learn/config-intro/node.md b/src/collections/_documentation/learn/config-intro/javascript.md similarity index 78% rename from src/collections/_documentation/learn/config-intro/node.md rename to src/collections/_documentation/learn/config-intro/javascript.md index 11c2ebe8d3946..637e144caac52 100644 --- a/src/collections/_documentation/learn/config-intro/node.md +++ b/src/collections/_documentation/learn/config-intro/javascript.md @@ -1,8 +1,6 @@ Options are passed to the `init()` as object: ```javascript -const Sentry = require('@sentry/node'); - Sentry.init({ dsn: '___PUBLIC_DSN___', maxBreadcrumbs: 50, diff --git a/src/collections/_documentation/learn/configuration.md b/src/collections/_documentation/learn/configuration.md index fc3b253e82e6c..e7855e3d659af 100644 --- a/src/collections/_documentation/learn/configuration.md +++ b/src/collections/_documentation/learn/configuration.md @@ -138,10 +138,10 @@ For more information have a look at the specific integration documentation. {:.config-key} ### default-integrations -{% supported python %} +{% unsupported csharp aspnetcore rust %} This can be used to disable integrations that are added by default. When set to `false` no default integrations are added. -{% endsupported %} +{% endunsupported %} ## Hooks diff --git a/src/collections/_documentation/learn/getting-started-config/browsernpm.md b/src/collections/_documentation/learn/getting-started-config/browsernpm.md new file mode 100644 index 0000000000000..768e67e773529 --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-config/browsernpm.md @@ -0,0 +1,7 @@ +You should `init` the Sentry browser SDK as soon as possible during your application load up: + +```javascript +import * as Sentry from '@sentry/browser'; + +Sentry.init({ dsn: '___PUBLIC_DSN___' }); +``` diff --git a/src/collections/_documentation/learn/getting-started-config/node.md b/src/collections/_documentation/learn/getting-started-config/node.md index 7e6fec356262f..c82706566011f 100644 --- a/src/collections/_documentation/learn/getting-started-config/node.md +++ b/src/collections/_documentation/learn/getting-started-config/node.md @@ -1,7 +1,7 @@ -You need to inform the sentry node SDK about your CDN somewhere before +You need to inform the sentry node SDK about your DSN somewhere before application startup: ```javascript const Sentry = require('@sentry/node'); -Sentry.init({dsn: '___PUBLIC_DSN___'}); +Sentry.init({ dsn: '___PUBLIC_DSN___' }); ``` diff --git a/src/collections/_documentation/learn/getting-started-install/browsernpm.md b/src/collections/_documentation/learn/getting-started-install/browsernpm.md new file mode 100644 index 0000000000000..50f85dac924be --- /dev/null +++ b/src/collections/_documentation/learn/getting-started-install/browsernpm.md @@ -0,0 +1,11 @@ +If you are using `yarn` you can add our package as a dependency easily: + +```bash +$ yarn add @sentry/browser@{% sdk_version sentry.javascript.browser %} +``` + +Or alternatively you can npm install it: + +```bash +$ npm install @sentry/browser@{% sdk_version sentry.javascript.browser %} +``` diff --git a/src/collections/_documentation/platforms/javascript/index.md b/src/collections/_documentation/platforms/javascript/index.md index 85fec13c8ef64..1917ad1a6d955 100644 --- a/src/collections/_documentation/platforms/javascript/index.md +++ b/src/collections/_documentation/platforms/javascript/index.md @@ -39,7 +39,7 @@ import * as Sentry from '@sentry/browser'; Sentry.init({ dsn: '___PUBLIC_DSN___', - integrations: (integrations) => { + integrations: (integrations) => { // integrations will be all default integrations return integrations.filter(integration => integration.name !== 'Breadcrumbs'); } }) @@ -57,7 +57,7 @@ import * as Sentry from '@sentry/browser'; Sentry.init({ dsn: '___PUBLIC_DSN___', - integrations: (integrations) => { + integrations: (integrations) => { // integrations will be all default integrations integrations.push(new MyCustomIntegration()) return integrations } From 6513a01605ec57a8c8f23a61e6c67cc757e6565d Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Fri, 14 Sep 2018 10:56:47 +0200 Subject: [PATCH 118/171] feat: Added before send hint docs --- .../learn/before-send-hint/python.md | 14 ++++++++++++++ src/collections/_documentation/learn/hints.md | 10 ++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 src/collections/_documentation/learn/before-send-hint/python.md diff --git a/src/collections/_documentation/learn/before-send-hint/python.md b/src/collections/_documentation/learn/before-send-hint/python.md new file mode 100644 index 0000000000000..5d69cb9b0d5ba --- /dev/null +++ b/src/collections/_documentation/learn/before-send-hint/python.md @@ -0,0 +1,14 @@ +```python +import sentry_sdk + +def before_send(event, hint): + if 'exc_info' in hint: + exc_type, exc_value, tb = hint['exc_info'] + if isinstance(exc_value, DatabaseUnavailable): + event['fingerprint'] = ['database-unavailable'] + return event + +sentry_sdk.init(before_send=before_send) +``` + +For information about which hints are available see [hints in python]({% link _documentation/platforms/python/index.md %}#hints). diff --git a/src/collections/_documentation/learn/hints.md b/src/collections/_documentation/learn/hints.md index 2c85c0a3e6cec..ab2cf490dbe02 100644 --- a/src/collections/_documentation/learn/hints.md +++ b/src/collections/_documentation/learn/hints.md @@ -1,5 +1,5 @@ --- -title: Hints-based Customization +title: Hint-based Customization sidebar_order: 3 --- @@ -11,7 +11,13 @@ instance. For better customization SDKs send these objects to certain callbacks # Before Send The `before-send` callback is passed the event and a second argument `hint` which holds one or more -hints. Typically this hint holds the original exception so that additional data can be extracted. +hints. Typically this hint holds the original exception so that additional data can be extracted +or grouping be affected. + +In this example the fingerprint is forced to a common value if an exception of a certain type has +been caught: + +{% include components/platform_content.html content_dir='before-send-hint' %} # Before Breadcrumb From e26c9c4bc01177a1b44415aa39d92dee350178c6 Mon Sep 17 00:00:00 2001 From: HazA Date: Fri, 14 Sep 2018 11:02:42 +0200 Subject: [PATCH 119/171] feat: Removed index platform overview --- .../_documentation/learn/config-intro/browser.md | 2 +- src/collections/_documentation/learn/configuration.md | 8 +++++++- src/index.md | 6 ------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/collections/_documentation/learn/config-intro/browser.md b/src/collections/_documentation/learn/config-intro/browser.md index c67b359f6be46..b5f44914ef224 100644 --- a/src/collections/_documentation/learn/config-intro/browser.md +++ b/src/collections/_documentation/learn/config-intro/browser.md @@ -4,5 +4,5 @@ Options are passed to the `init()` as object: Sentry.init({ maxBreadcrumbs: 50, debug: true, -}) +}); ``` diff --git a/src/collections/_documentation/learn/configuration.md b/src/collections/_documentation/learn/configuration.md index e7855e3d659af..66be641b4770e 100644 --- a/src/collections/_documentation/learn/configuration.md +++ b/src/collections/_documentation/learn/configuration.md @@ -14,10 +14,16 @@ initialized. 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. +{:.config-key} +### dsn + +The _DSN_ tells the SDK where to send the events to. This option is always required and different SDKs might pick this up from an environment +variable (`SENTRY_DSN`) or in the case if you are using the CDN version or the Browser SDK, it's already configured for you. + {:.config-key} ### debug -Turns debug mode on or off. If debug is enabled SKD will attempt to print out useful debugging +Turns debug mode on or off. If debug is enabled SDK will attempt to print out useful debugging information if something goes wrong with sending the event. The default is always `false` and it's generally not recommended to turn it on in production but doing so will not cause any safety concerns. diff --git a/src/index.md b/src/index.md index 6da637ec3af1f..984dc9a18c675 100644 --- a/src/index.md +++ b/src/index.md @@ -13,12 +13,6 @@ To get you started, you might find some of these links relevant: - Stuck? Feel free to contact [_Support_]({%- link support.md -%}). - Installing the Sentry server yourself? See [_Installation_]({%- link _documentation/server/installation/index.md -%}) -## Platforms - -To report to Sentry you’ll need to use a language-specific SDK. The Sentry team builds and maintains these for most popular languages, but there’s also a large ecosystem supported by the community. If your favorite language isn’t listed below, we encourage you to start a discussion about supporting it on our [community forum](https://forum.sentry.io). - -{% include platform_icon_links.html %} - ## Contributing Looking to get started contributing to Sentry? Our [_internal documentation_]({%- link _documentation/internal/index.md -%}) has you covered. From 44fb141844b1cd5c4a91545b75794062185d6006 Mon Sep 17 00:00:00 2001 From: HazA Date: Fri, 14 Sep 2018 11:50:15 +0200 Subject: [PATCH 120/171] fix: Update source maps --- .../platforms/javascript/sourcemaps.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/collections/_documentation/platforms/javascript/sourcemaps.md b/src/collections/_documentation/platforms/javascript/sourcemaps.md index cb2b7c649e8e5..1bf10ad80e0e6 100644 --- a/src/collections/_documentation/platforms/javascript/sourcemaps.md +++ b/src/collections/_documentation/platforms/javascript/sourcemaps.md @@ -7,7 +7,7 @@ Sentry supports un-minifying JavaScript via [Source Maps](http://blog.sentry.io/ ## Specify the release -If you are uploading sourcemap artifacts yourself, you must specify the release in your SDK see: [Releases]({%- link _documentation/learn/releases.md -%}). Sentry will use the release name to associate digested event data with the files you’ve uploaded via the [releases API]({%- link _documentation/api/releases/index.md -%}), [sentry-cli]({%- link _documentation/learn/cli/index.md -%}) or [sentry-webpack-plugin](https://github.com/getsentry/sentry-webpack-plugin). This step is optional if you are hosting sourcemaps on the remote server. +If you are uploading source map artifacts yourself, you must specify the release in your SDK see: [Releases]({%- link _documentation/learn/releases.md -%}). Sentry will use the release name to associate digested event data with the files you’ve uploaded via the [releases API]({%- link _documentation/api/releases/index.md -%}), [sentry-cli]({%- link _documentation/learn/cli/index.md -%}) or [sentry-webpack-plugin](https://github.com/getsentry/sentry-webpack-plugin). This step is optional if you are hosting source maps on the remote server. ## Generating a Source Map @@ -188,7 +188,7 @@ $ sentry-cli releases files upload-sourcemaps --ext ts,map /path/ Unfortunately, it can be quite challenging to ensure that source maps are actually valid and uploaded correctly. To ensure that everything is working as intended, you can add the `--validate` flag when uploading source maps. It attempts to parse the source maps and verify source references locally. Note that this flag might produce false positives if you have references to external source maps. {%- endcapture -%} {%- include components/alert.html - title="Validating Sourcemaps with Sentry CLI" + title="Validating source maps with Sentry CLI" content=__alert_content %} @@ -200,7 +200,7 @@ $ sentry-cli releases finalize For convenience, you can alternatively pass the `--finalize` flag to the `new` command which will immediately finalize the release. -Note: You dont _have_ to upload the source files (ref’d by sourcemaps), but without them the grouping algorithm will not be as strong, and the UI will not show any contextual source. +Note: You dont _have_ to upload the source files (ref’d by source maps), but without them the grouping algorithm will not be as strong, and the UI will not show any contextual source. Additional information can be found in the [Releases API documentation]({%- link _documentation/api/releases/index.md -%}). @@ -222,7 +222,7 @@ In this situation, **identical** JavaScript and source map files may be located > ~/js/app.js -The ~ prefix tells Sentry that for a given URL, **any** combination of protocol and hostname whose path is `/js/app.js` should use this artifact. **ONLY** use this method if your source/sourcemap files are identical at all possible protocol/hostname combinations. Note that Sentry will prioritize full URLs over tilde prefixed paths if found. +The ~ prefix tells Sentry that for a given URL, **any** combination of protocol and hostname whose path is `/js/app.js` should use this artifact. **ONLY** use this method if your source/source map files are identical at all possible protocol/hostname combinations. Note that Sentry will prioritize full URLs over tilde prefixed paths if found. {%- endcapture -%} {%- include components/alert.html title="Assets Accessible at Multiple Origins" @@ -230,16 +230,16 @@ The ~ prefix tells Sentry that for a given URL, **any** combination of protocol %} {% capture __alert_content -%} -Unfortunately it can be quite challenging to ensure that sourcemaps are actually valid themselves and uploaded correctly. To ensure that everything is working as intended you can use the _–validate_ flag when uploading sourcemaps which will attempt to locally parse the sourcemap 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 sourcemaps then the validation tool will indicate a failure). +Unfortunately it can be quite challenging to ensure that source maps are actually valid themselves and uploaded correctly. To ensure that everything is working as intended you can use the _–validate_ flag when uploading source maps 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). Here are some things you can check in addition to the validation step: - Make sure that the URL prefix is correct for your files. This is easy to get wrong. -- Make sure you upload the matching sourcemaps for your minimized files. +- Make sure you upload the matching source maps for your minimized files. - Make sure that your minified files you have on your servers actually have references to your files. {%- endcapture -%} {%- include components/alert.html - title="Validating Sourcemaps with Sentry CLI" + title="Validating source maps with Sentry CLI" content=__alert_content %} @@ -249,7 +249,7 @@ Source maps can sometimes be tricky to get going. If you’re having trouble, tr ### Verify your source maps are built correctly -We maintain an online validation tool that can be used to test your source (and sourcemaps) against: [sourcemaps.io](http://sourcemaps.io). +We maintain an online validation tool that can be used to test your source (and source maps) against: [sourcemaps.io](http://sourcemaps.io). Alternatively, if you are using Sentry CLI to upload source maps to Sentry, you can use the _–validate_ command line option to verify your source maps are correct. From 02e4ff713ca7b379645d4cfd63ba017b82ad501c Mon Sep 17 00:00:00 2001 From: Jan Michael Auer Date: Fri, 14 Sep 2018 13:48:44 +0200 Subject: [PATCH 121/171] feat: Add missing SDK interface attributes --- .../clientdev/interfaces/sdk.md | 40 ++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/src/collections/_documentation/clientdev/interfaces/sdk.md b/src/collections/_documentation/clientdev/interfaces/sdk.md index c92de4926a387..e4b29189d28bf 100644 --- a/src/collections/_documentation/clientdev/interfaces/sdk.md +++ b/src/collections/_documentation/clientdev/interfaces/sdk.md @@ -3,19 +3,49 @@ title: 'SDK Interface' sidebar_order: 13 --- -An interface which describes the SDK used to capture and transmit the event. +An interface which describes the SDK and its configuration used to capture and +transmit the event. `name` -: The name of the SDK. +: **Required**. The name of the SDK. Its format is `sentry.ecosystem[.flavor]` +where the _flavor_ is optional and should only be set if it has its own SDK. `version` -: The version of the SDK. +: **Required**. The semantic version of the SDK. The version should always be +sent without a `v` prefix. + +`integrations` + +: _Optional_. A list of integrations with the platform or a framework that were +explicitly actived by the user. This does not include default integrations. + +`packages` + +: _Optional_. A list of packages that were installed as part of this SDK or the +activated integrations. Each package consists of a `name` in the format +`source:identifier` and a semver `version`. If the source is a git repository, +a checkout link and git reference (branch, tag or sha) should be used. + +## Example ```json "sdk": { - "name": "sentry-php", - "version": "1.0.0" + "name": "sentry.javscript.react-native", + "version": "1.0.0", + "integrations": [ + "redux" + ], + "packages": [ + { + "name": "npm:@sentry/react-native", + "version": "0.39.0" + }, + { + "name": "git:https://github.com/getsentry/sentry-cocoa.git", + "version": "4.1.0" + } + ] } ``` From 442523f43d552fd931cfa70345b68fad362d6555 Mon Sep 17 00:00:00 2001 From: Jan Michael Auer Date: Fri, 14 Sep 2018 13:57:21 +0200 Subject: [PATCH 122/171] fix: Remove invalid info from the interfaces index --- .../clientdev/interfaces/index.md | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/collections/_documentation/clientdev/interfaces/index.md b/src/collections/_documentation/clientdev/interfaces/index.md index e55025f7704df..e5e9032b2c6d9 100644 --- a/src/collections/_documentation/clientdev/interfaces/index.md +++ b/src/collections/_documentation/clientdev/interfaces/index.md @@ -3,30 +3,35 @@ title: Interfaces sidebar_order: 20 --- -Any additional value in the payload of an event which is not an attribute ([_Attributes_]({%- link _documentation/clientdev/attributes.md -%})) is assumed to be a data interface, where the key is the Python path to the interface class name, and the value is the data expected by the interface. Interfaces are used in a variety of ways including storing stacktraces, HTTP request information, and other metadata. +Any additional value in the payload of an event which is not an attribute (see +[_Attributes_]({%- link _documentation/clientdev/attributes.md -%})) is assumed +to be a data interface, where the key is the canonical interface short name, and +the value is the data expected by the interface (usually a dictionary). +Interfaces are used in a variety of ways including storing stacktraces, HTTP +request information, and other metadata. -For the most part interfaces are an evolving part of Sentry. Like with attributes, SDKs are expected to assume more can appear at any point in the future. More than that however, for on-premise installations of Sentry the interfaces can be customized so SDK libraries should ideally be written in a way that custom interfaces can be emitted. - -Interfaces are typically identified by their full canonical path as it exists in Sentry. For built-in interfaces we also provide aliases which should be used instead. For instance the full canonical path for the stacktrace interface is `sentry.interfaces.Stacktrace` which is also available under the alias `stacktrace`. +For the most part, interfaces are an evolving part of Sentry. Like with +attributes, SDKs are expected to assume that more interfaces will be added at +any point in the future. ## Core Data -- [Exception Interface]({%- link _documentation/clientdev/interfaces/exception.md -%}) -- [Message Interface]({%- link _documentation/clientdev/interfaces/message.md -%}) -- [Stacktrace Interface]({%- link _documentation/clientdev/interfaces/stacktrace.md -%}) -- [Template Interface]({%- link _documentation/clientdev/interfaces/template.md -%}) +- [Exception Interface]({%- link _documentation/clientdev/interfaces/exception.md -%}) +- [Log Entry Interface]({%- link _documentation/clientdev/interfaces/message.md -%}) +- [Stacktrace Interface]({%- link _documentation/clientdev/interfaces/stacktrace.md -%}) +- [Template Interface]({%- link _documentation/clientdev/interfaces/template.md -%}) -## Context +## Scope -- [Breadcrumbs Interface]({%- link _documentation/clientdev/interfaces/breadcrumbs.md -%}) -- [Contexts Interface]({%- link _documentation/clientdev/interfaces/contexts.md -%}) -- [HTTP Interface]({%- link _documentation/clientdev/interfaces/http.md -%}) -- [Threads Interface]({%- link _documentation/clientdev/interfaces/threads.md -%}) -- [User Interface]({%- link _documentation/clientdev/interfaces/user.md -%}) +- [Breadcrumbs Interface]({%- link _documentation/clientdev/interfaces/breadcrumbs.md -%}) +- [Contexts Interface]({%- link _documentation/clientdev/interfaces/contexts.md -%}) +- [HTTP Interface]({%- link _documentation/clientdev/interfaces/http.md -%}) +- [Threads Interface]({%- link _documentation/clientdev/interfaces/threads.md -%}) +- [User Interface]({%- link _documentation/clientdev/interfaces/user.md -%}) ## Misc -- [Debug Interface]({%- link _documentation/clientdev/interfaces/debug.md -%}) -- [Exception Mechanism Interface]({%- link _documentation/clientdev/interfaces/mechanism.md -%}) -- [Repos Interface]({%- link _documentation/clientdev/interfaces/repos.md -%}) -- [SDK Interface]({%- link _documentation/clientdev/interfaces/sdk.md -%}) +- [Debug Interface]({%- link _documentation/clientdev/interfaces/debug.md -%}) +- [Exception Mechanism Interface]({%- link _documentation/clientdev/interfaces/mechanism.md -%}) +- [Repos Interface]({%- link _documentation/clientdev/interfaces/repos.md -%}) +- [SDK Interface]({%- link _documentation/clientdev/interfaces/sdk.md -%}) From 7f5c41a0d7e3e1819b9417119b3e108a0cdbe421 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Fri, 14 Sep 2018 14:02:11 +0200 Subject: [PATCH 123/171] feat: Add docs for Python modules integration --- .../_documentation/platforms/python/default-integrations.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/collections/_documentation/platforms/python/default-integrations.md b/src/collections/_documentation/platforms/python/default-integrations.md index 5392439955b7e..a9313e93f1cc2 100644 --- a/src/collections/_documentation/platforms/python/default-integrations.md +++ b/src/collections/_documentation/platforms/python/default-integrations.md @@ -41,3 +41,8 @@ In detail it provides: * Breadcrumbs for HTTP requests done using `httplib`, which also includes traffic going through `requests`. + +## Modules +*Import name: `sentry_sdk.integrations.modules.ModulesIntegration`* + +Send a list of installed Python packages along with each event. From dd266138a58bb7a3993a912839be7eb4dcfd7965 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Fri, 14 Sep 2018 14:16:15 +0200 Subject: [PATCH 124/171] fix: Show nicer error message --- src/_plugins/platform_api.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index 7a132ab6b78ef..20d9dfc328d14 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -86,7 +86,7 @@ def generate(site) platform["wizard"].each do |wiz| file, section = wiz.split '#' section ||= :document - if docs[file][section].nil? + if docs[file].nil? || docs[file][section].nil? raise "Cannot find section '#{section}' in #{file}" end body += docs[file][section] From 59085da4387d00412166e14e92058682c99a2512 Mon Sep 17 00:00:00 2001 From: Jan Michael Auer Date: Fri, 14 Sep 2018 14:15:30 +0200 Subject: [PATCH 125/171] feat: Describe the breadcrumbs interface --- .../clientdev/interfaces/breadcrumbs.md | 113 +++++++++++------- 1 file changed, 72 insertions(+), 41 deletions(-) diff --git a/src/collections/_documentation/clientdev/interfaces/breadcrumbs.md b/src/collections/_documentation/clientdev/interfaces/breadcrumbs.md index ca13703842c64..4f274fa2e2362 100644 --- a/src/collections/_documentation/clientdev/interfaces/breadcrumbs.md +++ b/src/collections/_documentation/clientdev/interfaces/breadcrumbs.md @@ -3,64 +3,92 @@ title: 'Breadcrumbs Interface' sidebar_order: 5 --- -The breadcrumbs interface specifies a series of application events, or “breadcrumbs”, that occurred before the main event. +The breadcrumbs interface specifies a series of application events, or +“breadcrumbs”, that occurred before the main event. Its canonical name is +`"breadcrumbs"`. -The value of the interface is an array of breadcrumb objects. Breadcrumb entries are ordered from oldest to newest. The last breadcrumb in the array should be the last entry before the main event fired. +This interface is an object with a sole `values` key containing an ordered list +of breadcrumb objects. The entries are ordered from oldest to newest. +Consequently, the last entry in the array should be the last entry before the +event occurred. -Each breadcrumb has a few properties of which at least `timestamp` and `category` must be provided. The rest is optional and depending on what is provided the rendering might be different. +Each breadcrumb has a few properties of which at least `timestamp` and +`category` must be provided. The rest is optional and depending on what is +provided the rendering might be different: `timestamp` -: A timestamp representing when the breadcrumb occurred. This can be either an ISO datetime string, or a Unix timestamp. +: **Required**. A timestamp representing when the breadcrumb occurred. This can +be either an ISO datetime string, or a Unix timestamp. `type` -: The type of breadcrumb. The default type is `default` which indicates no specific handling. Other types are currently `http` for HTTP requests and `navigation` for navigation events. More about types later. +: _Optional_. The type of breadcrumb. The default type is `default` which +indicates no specific handling. Other types are currently `http` for HTTP +requests and `navigation` for navigation events. More about types later. -`message` +`category` -: If a message is provided it’s rendered as text and the whitespace is preserved. Very long text might be abbreviated in the UI. +: _Optional_. A dotted string indicating what the crumb is or where it comes +from. Typically it is a module name or a descriptive string. For instance, +_ui.click_ could be used to indicate that a click happend in the UI or _flask_ +could be used to indicate that the event originated in the Flask framework. -`data` +`message` -: Data associated with this breadcrumb. Contains a sub-object whose contents depend on the breadcrumb `type`. See descriptions of breadcrumb types below. Additional parameters that are unsupported by the type are rendered as a key/value table. +: _Optional_. If a message is provided it is rendered as text with all +whitespace preserved. Very long text might be truncated in the UI. -`category` +`data` -: Categories are dotted strings that indicate what the crumb is or where it comes from. Typically it’s a module name or a descriptive string. For instance _ui.click_ could be used to indicate that a click happend in the UI or _flask_ could be used to indicate that the event originated in the Flask framework. +: _Optional_. Arbitrary data associated with this breadcrumb. Contains a +dictionary whose contents depend on the breadcrumb `type`. See descriptions of +breadcrumb types below. Additional parameters that are unsupported by the type +are rendered as a key/value table. `level` -: This defines the level of the event. If not provided it defaults to `info` which is the middle level. In the order of priority from highest to lowest the levels are `critical`, `error`, `warning`, `info` and `debug`. Levels are used in the UI to emphasize and deemphasize the crumb. +: _Optional_. This defines the severity level of the breadcrumb. Allowed values +are, from highest to lowest: `critical`, `error`, `warning`, `info` and `debug`. +Levels are used in the UI to emphasize and deemphasize the crumb. Defaults to +`info`. + +## Examples ```json -"breadcrumbs": [ - { - "timestamp": 1461185753845, - "message": "Something happened", - "category": "log", - "data": { - "foo": "bar", - "blub": "blah" +"breadcrumbs": { + "values": [ + { + "timestamp": 1461185753845, + "message": "Something happened", + "category": "log", + "data": { + "foo": "bar", + "blub": "blah" + } + }, + { + "timestamp": "2016-04-20T20:55:53.847Z", + "type": "navigation", + "data": { + "from": "/login", + "to": "/dashboard" + } } - }, { - "timestamp": 1461185753847, - "type": "navigation", - "data": { - "from": "/login", - "to": "/dashboard" - } - } + ] ] ``` ## Breadcrumb Types -Below are descriptions of individual breadcrumb types, and what their `data` properties look like. +Below are descriptions of individual breadcrumb types, and what their `data` +properties look like. -`default` +### `default` -Describes an unspecified breadcrumb. This is typically a generic log message or something similar. The `data` part is entirely undefined and as such completely rendered as a key/value table. +Describes an generic breadcrumb. This is typically a log message or user +generated breadcrumb. The `data` part is entirely undefined and as such +completely rendered as a key/value table. ```json { @@ -73,19 +101,20 @@ Describes an unspecified breadcrumb. This is typically a generic log message or } ``` -`navigation` +### `navigation` -Describes a navigation breadcrumb. A navigation event can be a URL change in a web application, or a UI transition in a mobile or desktop application, etc. +Describes a navigation breadcrumb. A navigation event can be a URL change in a +web application, or a UI transition in a mobile or desktop application, etc. Its `data` property has the following sub-properties: `from` -: A string representing the original application state / location. +: **Required**. A string representing the original application state / location. `to` -: A string representing the new application state / location. +: **Required**. A string representing the new application state / location. ```json { @@ -98,27 +127,29 @@ Its `data` property has the following sub-properties: } ``` -`http` +### `http` -Describes an HTTP request breadcrumb. This represents an HTTP request transmitted from your application. This could be an AJAX request from a web application, or a server-to-server HTTP request to an API service provider, etc. +Describes an HTTP request breadcrumb. This represents an HTTP request +transmitted from your application. This could be an AJAX request from a web +application, or a server-to-server HTTP request to an API service provider, etc. Its `data` property has the following sub-properties: `url` -: The request URL. +: _Optional_. The request URL. `method` -: The HTTP request method. +: _Optional_. The HTTP request method. `status_code` -: The HTTP status code of the response. +: _Optional_. The HTTP status code of the response. `reason` -: A text that describes the status code. +: _Optional_. A text that describes the status code. ```json { From b8bb281b0ad3cb38a7fc79bfb7d58a8598027cb6 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Fri, 14 Sep 2018 14:18:22 +0200 Subject: [PATCH 126/171] feat: Added burning man --- src/_assets/css/_includes/index.scss | 11 +++++++++++ src/_assets/css/screen.scss | 1 + src/_assets/img/on-fire.png | Bin 0 -> 74429 bytes .../_documentation/internal/index.md | 5 +++++ src/index.md | 9 +++++++-- 5 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 src/_assets/css/_includes/index.scss create mode 100644 src/_assets/img/on-fire.png diff --git a/src/_assets/css/_includes/index.scss b/src/_assets/css/_includes/index.scss new file mode 100644 index 0000000000000..996988b4da7a9 --- /dev/null +++ b/src/_assets/css/_includes/index.scss @@ -0,0 +1,11 @@ +.index-illustration { + float: right; + margin: 0 0 30px 30px; + width: 260px; + + img { + border: none; + box-shadow: none; + border-radius: 0; + } +} diff --git a/src/_assets/css/screen.scss b/src/_assets/css/screen.scss index d38606ec988fb..19d3e30fe19ce 100644 --- a/src/_assets/css/screen.scss +++ b/src/_assets/css/screen.scss @@ -21,3 +21,4 @@ @import '_includes/tracking-widget'; @import '_includes/loader'; @import '_includes/platform-link'; +@import '_includes/index'; diff --git a/src/_assets/img/on-fire.png b/src/_assets/img/on-fire.png new file mode 100644 index 0000000000000000000000000000000000000000..48976a1c89397d9283605416aa6301acc41bdd12 GIT binary patch literal 74429 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

Z)kPQJQSG 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 Wmu$t + {% asset on-fire.png %} +

+ +Welcome to the Sentry documentation. Sentry is an Open-source error tracking that helps you monitor and fix crashes in real time. Here we cover everything about the product and the platform integrations and our on-prem offering. ## Getting Started @@ -15,4 +19,5 @@ To get you started, you might find some of these links relevant: ## Contributing -Looking to get started contributing to Sentry? Our [_internal documentation_]({%- link _documentation/internal/index.md -%}) has you covered. +Looking to get started contributing to Sentry? Our [_internal documentation_]({%- link _documentation/internal/index.md -%}) has you covered. Also +have a look at our [_Forums_](https://forums.sentry.io/) and our [_Github org_](https://github.com/getsentry). From 1d3faeb246f2f255b275e91237dcb0a842cdbe2c Mon Sep 17 00:00:00 2001 From: Jan Michael Auer Date: Fri, 14 Sep 2018 14:29:42 +0200 Subject: [PATCH 127/171] fix: Remove deprecated tags format --- .../_documentation/clientdev/attributes.md | 70 ++++++++++--------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/src/collections/_documentation/clientdev/attributes.md b/src/collections/_documentation/clientdev/attributes.md index d93109b37a2b7..47cdde90e388e 100644 --- a/src/collections/_documentation/clientdev/attributes.md +++ b/src/collections/_documentation/clientdev/attributes.md @@ -3,9 +3,13 @@ title: Attributes sidebar_order: 10 --- -Attributes are simple data that Sentry understands to provide the most basic information about events. These are things like the unique ID of an event, the human readable message etc. +Attributes are simple data that Sentry understands to provide the most basic +information about events. These are things like the unique ID of an event, the +human readable message etc. -Attributes are separate from [_Interfaces_]({%- link _documentation/clientdev/interfaces/index.md -%}) which provide very specific and tailored data such as exception data, stacktraces, etc. +Attributes are separate from [_Interfaces_]({%- link +_documentation/clientdev/interfaces/index.md -%}) which provide very specific +and tailored data such as exception data, stacktraces, etc. ## Required Attributes @@ -13,9 +17,8 @@ The following attributes are required for all events: `event_id` -: Hexadecimal string representing a uuid4 value. - - The length is exactly 32 characters (no dashes!) +: Hexadecimal string representing a uuid4 value. The length is exactly 32 + characters. Dashes are not allowed. ```json { @@ -25,11 +28,9 @@ The following attributes are required for all events: `timestamp` -: Indicates when the logging record was created (in the Sentry SDK). - - The Sentry server assumes the time is in UTC. - - The timestamp should be in ISO 8601 format, without a timezone. +: Indicates when the logging record was created (in the Sentry SDK). The Sentry + server assumes the time is in UTC. The timestamp should be in ISO 8601 format, + without a timezone. ```json { @@ -49,7 +50,8 @@ The following attributes are required for all events: `platform` -: A string representing the platform the SDK is submitting from. This will be used by the Sentry interface to customize various components in the interface. +: A string representing the platform the SDK is submitting from. This will be + used by the Sentry interface to customize various components in the interface. ```json { @@ -77,7 +79,9 @@ The following attributes are required for all events: `sdk` -: Information about the SDK sending the event. Note that the `integrations` key is optional and used to list any of the SDK and language specific integrations that the user is actively using. +: Information about the SDK sending the event. Note that the `integrations` key + is optional and used to list any of the SDK and language specific integrations + that the user is actively using. ```json { @@ -93,7 +97,8 @@ The following attributes are required for all events: ## Optional Attributes -Additionally, there are several optional values which Sentry recognizes and are highly encouraged: +Additionally, there are several optional values which Sentry recognizes and are +highly encouraged: `level` @@ -131,7 +136,8 @@ Additionally, there are several optional values which Sentry recognizes and are `culprit` -: The name of the culprit which caused this exception. This attribute is deprecated. +: The name of the culprit which caused this exception. This attribute is + deprecated. `server_name` @@ -147,7 +153,8 @@ Additionally, there are several optional values which Sentry recognizes and are : The release version of the application. - This value will generally be something along the lines of the git SHA for the given project. + This value will generally be something along the lines of the git SHA for the + given project. ```json { @@ -168,18 +175,9 @@ Additionally, there are several optional values which Sentry recognizes and are } ``` - ```json - { - "tags": [ - ["ios_version", "4.0"], - ["context", "production"] - ] - } - ``` - `environment` -: The environment name, such as ‘production’ or ‘staging’. +: The environment name, such as `production` or `staging`. ```json { @@ -216,22 +214,30 @@ Additionally, there are several optional values which Sentry recognizes and are `fingerprint` -: An array of strings used to dictate the deduplication of this event. - - A value of `{% raw %}{{ default }}{% endraw %}` will be replaced with the built-in behavior, thus allowing you to extend it, or completely replace it. +: A list of strings used to dictate the deduplication of this event. A value + of `{% raw %}{{ default }}{% endraw %}` will be replaced with the built-in + behavior, thus allowing you to extend it, or completely replace it. ```json { - "fingerprint": ["myrpc", "POST", "/foo.bar"] + "fingerprint": [ + "myrpc", + "POST", + "/foo.bar" + ] } ``` ```json {% raw %}{ - "fingerprint": ["{{ default }}", "http://example.com/my.url"] + "fingerprint": [ + "{{ default }}", + "http://example.com/my.url" + ] }{% endraw %} ``` - {% version_added Protocol: version ‘7’ %} + {% version_added Protocol: 7 %} -For information about overriding grouping see [Customize Grouping with Fingerprints]({%- link _documentation/learn/rollups.md -%}#custom-grouping). +For information about overriding grouping see [Customize Grouping with +Fingerprints]({%- link _documentation/learn/rollups.md -%}#custom-grouping). From fafef4bbe791a4419ca0bbe5e177bd46663f5835 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Fri, 14 Sep 2018 15:15:29 +0200 Subject: [PATCH 128/171] feat: link between cdn/non cdn version in quickstart --- src/_js/lib/PlatformContent.js | 9 +++++++++ .../learn/getting-started-install/browser.md | 2 +- .../learn/getting-started-install/browsernpm.md | 6 ++++++ .../_documentation/platforms/python/index.md | 14 +++++++++++--- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/_js/lib/PlatformContent.js b/src/_js/lib/PlatformContent.js index 41ca018734b26..0782ddf2bed37 100644 --- a/src/_js/lib/PlatformContent.js +++ b/src/_js/lib/PlatformContent.js @@ -153,12 +153,21 @@ const showPlatform = function(slug) { syncRelatedElements(); }; +$(document).on('click', 'a[href^="?platform="]', function(event) { + event.preventDefault(); + const { query } = qs.parseUrl(this.href); + showPlatform(query.platform); +}); + $(document).on('click', '[data-toggle="platform"]', function(event) { event.preventDefault(); showPlatform($(event.target).data('platform')); }); $(document).on('page.didUpdate', function(event) { + // cameron help me. why do i need to do this -- mitsuhiko + $('a[href^="?platform"]').attr('data-not-dynamic', '1'); + // Update the preferredPlatform based on the url. showPlatform(qs.parse(location.search).platform); }); diff --git a/src/collections/_documentation/learn/getting-started-install/browser.md b/src/collections/_documentation/learn/getting-started-install/browser.md index 1b475d72ccfe5..5d0d554d24b8d 100644 --- a/src/collections/_documentation/learn/getting-started-install/browser.md +++ b/src/collections/_documentation/learn/getting-started-install/browser.md @@ -6,6 +6,6 @@ The quickest way to get started is to use the CDN hosted version of the JavaScri {% include components/alert.html title="Don't like the CDN?" - content="You can also NPM install our `@sentry/browser` package instead of using the CDN version." + content="You can also [NPM install our browser library](?platform=browsernpm)" level="info" %} diff --git a/src/collections/_documentation/learn/getting-started-install/browsernpm.md b/src/collections/_documentation/learn/getting-started-install/browsernpm.md index 50f85dac924be..dfca924d24f90 100644 --- a/src/collections/_documentation/learn/getting-started-install/browsernpm.md +++ b/src/collections/_documentation/learn/getting-started-install/browsernpm.md @@ -9,3 +9,9 @@ Or alternatively you can npm install it: ```bash $ npm install @sentry/browser@{% sdk_version sentry.javascript.browser %} ``` + +{% include components/alert.html + title="Want a CDN?" + content="You can also [use our more comfortable CDN version](?platform=browser)" + level="info" +%} diff --git a/src/collections/_documentation/platforms/python/index.md b/src/collections/_documentation/platforms/python/index.md index e830c98a493a8..9f5f62923c150 100644 --- a/src/collections/_documentation/platforms/python/index.md +++ b/src/collections/_documentation/platforms/python/index.md @@ -41,9 +41,17 @@ The Python SDK provides some common [hints]({% link _documentation/learn/hints.m and events. These hints are passed as the `hint` parameter to `before_send` and `before_breadcrumb` (as well as event processors) as a dictionary. More than one hint can be supplied but this is rare. -* `exc_info`: If this hint is set then it's an exc info tuple in the form `(exc_type, exc_value, tb)`. This +`exc_info` + +: If this hint is set then it's an exc info tuple in the form `(exc_type, exc_value, tb)`. This can be used to extract additional information from the original error object. -* `log_record`: This hint is passed to breadcrumbs and contains the log record that crated it. It can be used + +`log_record` + +: This hint is passed to breadcrumbs and contains the log record that crated it. It can be used to extract additional information from the original `logging` log record that is not extracted by default. Likewise it can be useful to discard uninteresting breadcrumbs. -* `httplib_request`: An `httplib` request object for breadcrumbs created from HTTP requests. + +`httplib_request` + +: An `httplib` request object for breadcrumbs created from HTTP requests. From 42ec12520c9614e65591c440b64c710873eda2dd Mon Sep 17 00:00:00 2001 From: Jan Michael Auer Date: Fri, 14 Sep 2018 15:19:52 +0200 Subject: [PATCH 129/171] feat: Add missing context interface attributes --- .../clientdev/interfaces/contexts.md | 129 +++++++++++------- 1 file changed, 83 insertions(+), 46 deletions(-) diff --git a/src/collections/_documentation/clientdev/interfaces/contexts.md b/src/collections/_documentation/clientdev/interfaces/contexts.md index 8a469ab004a6c..d118ce340b781 100644 --- a/src/collections/_documentation/clientdev/interfaces/contexts.md +++ b/src/collections/_documentation/clientdev/interfaces/contexts.md @@ -3,22 +3,26 @@ title: 'Contexts Interface' sidebar_order: 6 --- -The context interfaces provide additional context data. Typically this is data related to the current user, the current HTTP request. +The context interfaces provide additional context data. Typically this is data +related to the current user, the current HTTP request. Its canonical name is `"contexts"`. -The `contexts` type can be used to defined almost arbitrary contextual data on the event. It accepts an object of key, value pairs. The key is the “alias” of the context and can be freely chosen. However as per policy it should match the type of the context unless there are two values for a type. +The `contexts` type can be used to defined almost arbitrary contextual data on +the event. It accepts an object of key, value pairs. The key is the “alias” of +the context and can be freely chosen. However as per policy it should match the +type of the context unless there are two values for a type. Example: -```php +```json "contexts": { - "os": { - "type": "os", - "name": "Windows" - } + "os": { + "type": "os", + "name": "Windows" + } } ``` -If `type` is omitted it uses the alias as type. +If `type` is omitted it uses the key name as type. Unknown data for the contexts is rendered as a key/value list. @@ -28,162 +32,195 @@ The following types are known: `device` -: This describes the device that caused the event. This is most appropriate for mobile applications. +: This describes the device that caused the event. This is most appropriate for + mobile applications. Attributes: `name`: - : The name of the device. This is typically a hostname. + : _Optional_. The name of the device. This is typically a hostname. `family`: - : The family of the device. This is normally the common part of model names across generations. For instance `iPhone` would be a reasonable family, so would be `Samsung Galaxy`. + : _Optional_. The family of the device. This is normally the common part of + model names across generations. For instance `iPhone` would be a reasonable + family, so would be `Samsung Galaxy`. `model`: - : The model name. This for instance can be `Samsung Galaxy S3`. + : _Optional_. The model name. This for instance can be `Samsung Galaxy S3`. `model_id`: - : An internal hardware revision to identify the device exactly. + : _Optional_. An internal hardware revision to identify the device exactly. `arch`: - : The CPU architecture. + : _Optional_. The CPU architecture. `battery_level`: - : If the device has a battery this can be an floating point value defining the battery level (in the range 0-100). + : _Optional_. If the device has a battery, this can be an floating point value + defining the battery level (in the range 0-100). `orientation`: - : This can be a string `portrait` or `landscape` to define the orientation of a device. + : _Optional_. This can be a string `portrait` or `landscape` to define the + orientation of a device. `simulator`: - : A boolean defining whether this device is a simulator or an actual device. + : _Optional_. A flag indicating whether this device is a simulator or an + actual device. `memory_size`: - : Total system memory available in bytes. + : _Optional_. Total system memory available in bytes. `free_memory`: - : Free system memory in bytes. + : _Optional_. Free system memory in bytes. `usable_memory`: - : Memory usable for the app in bytes. + : _Optional_. Memory usable for the app in bytes. `storage_size`: - : Total device storage in bytes. + : _Optional_. Total device storage in bytes. `free_storage`: - : Free device storage in bytes. + : _Optional_. Free device storage in bytes. `external_storage_size`: - : Total size of an attached external storage in bytes (e.g.: android SDK card). + : _Optional_. Total size of an attached external storage in bytes (e.g.: + android SDK card). `external_free_storage`: - : Free size of an attached external storage in bytes (e.g.: android SDK card). + : _Optional_. Free size of an attached external storage in bytes (e.g.: + android SDK card). `boot_time`: - : A formatted UTC timestamp when the system was booted, e.g.: `"2018-02-08T12:52:12Z"`. + : _Optional_. A formatted UTC timestamp when the system was booted, e.g.: + `"2018-02-08T12:52:12Z"`. `timezone`: - : The timezone of the device, e.g.: `Europe/Vienna`. + : _Optional_. The timezone of the device, e.g.: `Europe/Vienna`. `os` -: Describes the operating system on which the event was created. In web contexts, this is the operating system of the browser (normally pulled from the User-Agent string). +: Describes the operating system on which the event was created. In web + contexts, this is the operating system of the browser (normally pulled from + the User-Agent string). Attributes: `name`: - : The name of the operating system. + : _Optional_. The name of the operating system. `version`: - : The version of the operating system. + : _Optional_. The version of the operating system. `build`: - : The internal build revision of the operating system. + : _Optional_. The internal build revision of the operating system. `kernel_version`: - : If known, this can be an independent kernel version string. Typically this is something like the entire output of the `uname` tool. + : _Optional_. An independent kernel version string. This is typically the + entire output of the `uname` syscall. `rooted`: - : An optional boolean that defines if the OS has been jailbroken or rooted. + : _Optional_. A flag indicating whether the OS has been jailbroken or rooted. + + `raw_description`: + + : _Optional_. An unprocessed description string obtained by the operating + system. For some well-known runtimes, Sentry will attempt to parse `name` + and `version` from this string, if they are not explicitly given. + `runtime` -: Describes a runtime in more detail. Typically this context is used multiple times if multiple runtimes are involved (for instance if you have a JavaScript application running on top of JVM) +: Describes a runtime in more detail. Typically this context is used multiple + times if multiple runtimes are involved (for instance if you have a JavaScript + application running on top of JVM) Attributes: `name`: - : The name of the runtime. + : _Optional_. The name of the runtime. `version`: - : The version identifier of the runtime. + : _Optional_. The version identifier of the runtime. + + `raw_description`: + + : _Optional_. An unprocessed description string obtained by the runtime. For + some well-known runtimes, Sentry will attempt to parse `name` and `version` + from this string, if they are not explicitly given. `app` -: Describes the application. As opposed to the runtime, this is the actual application that was running and carries meta data about the current session. +: Describes the application. As opposed to the runtime, this is the actual + application that was running and carries meta data about the current session. Attributes: `app_start_time`: - : Formatted UTC timestamp when the application was started by the user. + : _Optional_. Formatted UTC timestamp when the application was started by the + user. `device_app_hash`: - : Application specific device identifier. + : _Optional_. Application specific device identifier. `build_type`: - : String identifying the kind of build, e.g. `testflight`. + : _Optional_. String identifying the kind of build, e.g. `testflight`. `app_identifier`: - : Version-independent application identifier, often a dotted bundle ID. + : _Optional_. Version-independent application identifier, often a dotted + bundle ID. `app_name`: - : Human readable application name, as it appears on the platform. + : _Optional_. Human readable application name, as it appears on the platform. `app_version`: - : Human readable application version, as it appears on the platform. + : _Optional_. Human readable application version, as it appears on the + platform. `app_build`: - : Internal build identifier, as it appears on the platform. + : _Optional_. Internal build identifier, as it appears on the platform. `browser` -: Carries information about the browser or user agent for web-related errors. This can either be the browser this event ocurred in, or the user agent of a web request that triggered the event. +: Carries information about the browser or user agent for web-related errors. + This can either be the browser this event ocurred in, or the user agent of a + web request that triggered the event. Attributes: `name`: - : Display name of the browser application. + : _Optional_. Display name of the browser application. `version`: - : Version string of the browser. + : _Optional_. Version string of the browser. From f5f5b872608d298c5f5e20615db9f51f29ced9cc Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Fri, 14 Sep 2018 22:13:04 +0200 Subject: [PATCH 130/171] ref: Moved some hint docs around --- .../learn/before-breadcrumb-hint/javascript.md | 16 ++++++++++++++++ .../learn/before-breadcrumb/javascript.md | 10 ++-------- 2 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 src/collections/_documentation/learn/before-breadcrumb-hint/javascript.md diff --git a/src/collections/_documentation/learn/before-breadcrumb-hint/javascript.md b/src/collections/_documentation/learn/before-breadcrumb-hint/javascript.md new file mode 100644 index 0000000000000..e866dbdf6ef8e --- /dev/null +++ b/src/collections/_documentation/learn/before-breadcrumb-hint/javascript.md @@ -0,0 +1,16 @@ +```javascript +import * as Sentry from '@sentry/browser'; + +Sentry.init({ + dsn: 'https://@sentry.io/', + beforeBreadcrumb(breadcrumb, hint) { + if (breadcrumb.category === 'ui.click') { + const target = hint.event.target; + if (target.ariaLabel) breadcrumb.message = target.ariaLabel; + } + return breadcrumb; + }, +}); +``` + +For information about which hints are available see [hints in javascript]({% link _documentation/platforms/javascript/index.md %}#hints). diff --git a/src/collections/_documentation/learn/before-breadcrumb/javascript.md b/src/collections/_documentation/learn/before-breadcrumb/javascript.md index abf9d34e2dc70..d52f65fc4e474 100644 --- a/src/collections/_documentation/learn/before-breadcrumb/javascript.md +++ b/src/collections/_documentation/learn/before-breadcrumb/javascript.md @@ -2,16 +2,10 @@ ```javascript import * as Sentry from '@sentry/browser'; -init({ +Sentry.init({ dsn: 'https://@sentry.io/', beforeBreadcrumb(breadcrumb, hint) { - if (breadcrumb.category === 'ui.click') { - const target = hint.event.target; - if (target.ariaLabel) breadcrumb.message = target.ariaLabel; - } - return breadcrumb; + return breadcrumb.category === 'ui.click' ? null : breadcrumb; }, }); ``` - -For information about which hints are available see [hints in javascript]({% link _documentation/platforms/javascript/index.md %}#hints). From 209a072cbe68fbff740f3cff45563c7dc99acb59 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Fri, 14 Sep 2018 22:36:54 +0200 Subject: [PATCH 131/171] ref: unified hint examples --- .../before-breadcrumb-hint/javascript.md | 6 +- .../learn/before-send-hint/javascript.md | 15 ++++ .../platforms/javascript/index.md | 87 ++++++++----------- 3 files changed, 56 insertions(+), 52 deletions(-) create mode 100644 src/collections/_documentation/learn/before-send-hint/javascript.md diff --git a/src/collections/_documentation/learn/before-breadcrumb-hint/javascript.md b/src/collections/_documentation/learn/before-breadcrumb-hint/javascript.md index e866dbdf6ef8e..b2a7672b8119f 100644 --- a/src/collections/_documentation/learn/before-breadcrumb-hint/javascript.md +++ b/src/collections/_documentation/learn/before-breadcrumb-hint/javascript.md @@ -5,8 +5,10 @@ Sentry.init({ dsn: 'https://@sentry.io/', beforeBreadcrumb(breadcrumb, hint) { if (breadcrumb.category === 'ui.click') { - const target = hint.event.target; - if (target.ariaLabel) breadcrumb.message = target.ariaLabel; + const { target } = hint.event; + if (target.ariaLabel) { + breadcrumb.message = target.ariaLabel; + } } return breadcrumb; }, diff --git a/src/collections/_documentation/learn/before-send-hint/javascript.md b/src/collections/_documentation/learn/before-send-hint/javascript.md new file mode 100644 index 0000000000000..a8b087fc781c3 --- /dev/null +++ b/src/collections/_documentation/learn/before-send-hint/javascript.md @@ -0,0 +1,15 @@ +```javascript +import * as Sentry from '@sentry/browser'; + +init({ + beforeSend(event, hint) { + const { message } = hint.originalException; + if (message && message.match(/database unavailable/i)) { + event.fingerprint = ['database-unavailable']; + } + return event; + } +}); +``` + +For information about which hints are available see [hints in JavaScript]({% link _documentation/platforms/javascript/index.md %}#hints). diff --git a/src/collections/_documentation/platforms/javascript/index.md b/src/collections/_documentation/platforms/javascript/index.md index 1917ad1a6d955..58b6fcef81216 100644 --- a/src/collections/_documentation/platforms/javascript/index.md +++ b/src/collections/_documentation/platforms/javascript/index.md @@ -21,8 +21,7 @@ import * as Sentry from '@sentry/browser'; // All integration that come with an SDK can be found in // Sentry.Integrations -// Custom integration must conform this interface: -// https://github.com/getsentry/sentry-javascript/blob/1ebeb9edec4b6c7b07a61e0caac426a66eedaf2a/packages/types/src/index.ts#L205 +// Custom integration must conform this interface: https://bit.ly/2xdcbAR Sentry.init({ dsn: '___PUBLIC_DSN___', @@ -50,11 +49,6 @@ Sentry.init({ ```javascript import * as Sentry from '@sentry/browser'; -// All integration that come with an SDK can be found in -// Sentry.Integrations -// Custom integration must conform this interface: -// https://github.com/getsentry/sentry-javascript/blob/1ebeb9edec4b6c7b07a61e0caac426a66eedaf2a/packages/types/src/index.ts#L205 - Sentry.init({ dsn: '___PUBLIC_DSN___', integrations: (integrations) => { // integrations will be all default integrations @@ -64,60 +58,53 @@ Sentry.init({ }) ``` -### Hints +## Hints Event and Breadcrumb `hints` are objects containing various information used to put together an event or a breadcrumb. For events, those are things like `event_id`, `originalException`, `syntheticException` (used internally to generate cleaner stacktrace), and any other arbitrary `data` that user attaches. For breadcrumbs it's all implementation dependent. For XHR requests, hint contains xhr object itself, for user interactions it contains DOM element and event name etc. They are available in two places. `beforeSend`/`beforeBreadcrumb` and `eventProcessors`. Those are two ways we'll allow users to modify what we put together. -Examples based on your `cause` property. +These common hints currently exist for events: -`beforeSend`/`beforeBreadcrumb`: +`originalException` -```javascript -import * as Sentry from '@sentry/browser'; +: The original exception that caused the event to be created. This is useful for changing how events + are grouped or to extract additional information. -init({ - dsn: '___PUBLIC_DSN___', - beforeSend(event, hint) { - const processedEvent = { ...event }; - const cause = hint.originalException.cause; - - if (cause) { - processedEvent.extra.cause = cause.message; - } - - return processedEvent; - }, - beforeBreadcrumb(breadcrumb, hint) { - if (breadcrumb.category === 'ui.click') { - const target = hint.event.target; - if (target.ariaLabel) breadcrumb.message = target.ariaLabel; - } - return breadcrumb; - }, -}); -``` +`syntheticException` -### EventProcessors +: When a string or a non error object is raised, Sentry creates a synthetic exception so you can get a + basic stacktrace. This exception is stored here for further data extraction. -With `eventProcessors` you are able to hook into the process of enriching the event with additional data. -You can add you own `eventProcessor` on the current scope. The difference to `beforeSend` is that -`eventProcessors` run on the scope level where `beforeSend` runs globally not matter in which scope you are. +And these exist for breadcrumbs: -```javascript -import * as Sentry from '@sentry/browser'; +`event` -Sentry.getCurrentHub().configureScope(scope => { - scope.addEventProcessor(async (event, hint) => { - const processedEvent = { ...event }; - const cause = hint.originalException.cause; +: For breadcrumbs created from browser events the event is often supplied to the breadcrumb as hint. This + for instance can be used to extract data from the target DOM element into a breadcrumb. - if (cause) { - processedEvent.extra.cause = cause.message; - } +`level` / `input` - return processedEvent; - }); -}); -``` \ No newline at end of file +: For breadcrumbs created from console log interceptions this holds the original console log level and the + original input data to the log function. + +`response` / `input` + +: For breadcrumbs created from HTTP requests this holds the response object + (from the fetch api) and the input parameters to the fetch function. + +`request` / `response` / `event` + +: For breadcrumbs created from HTTP requests this holds the request and response object + (from the node HTTP API) as well as the node event (`response` or `error`). + +`xhr` + +: For breadcrumnbs created from HTTP requests done via the legacy `XMLHttpRequest` API this holds + the original xhr object. + +## EventProcessors + +With `eventProcessors` you are able to hook into the process of enriching the event with additional data. +You can add you own `eventProcessor` on the current scope. The difference to `beforeSend` is that +`eventProcessors` run on the scope level where `beforeSend` runs globally not matter in which scope you are. From a93fac7363bf6b5c30b7a07e58526433422c1c14 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Fri, 14 Sep 2018 16:24:17 -0700 Subject: [PATCH 132/171] refactor the platform api to support the new wizard format --- src/_data/platforms.yml | 52 ++++++++- src/_layouts/json.json | 1 - src/_plugins/platform_api.rb | 198 +++++++++++++---------------------- 3 files changed, 121 insertions(+), 130 deletions(-) delete mode 100644 src/_layouts/json.json diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index 1511b9735c6b5..e1313087a2a00 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -4,6 +4,7 @@ type: framework name: Koa doc_link: /clients/node/integrations/koa/ + wizard_parent: node wizard: - _documentation/clients/node/index.md#installation - _documentation/clients/node/integrations/koa.md @@ -15,6 +16,7 @@ # XXX: does this have a better link? doc_link: /platforms/javascript/ # this is actually the old legacy_wizard: + wizard_parent: node wizard: - _documentation/clients/node/index.md case_style: camelCase @@ -35,6 +37,7 @@ name: Express # XXX: this links to the old ones doc_link: /clients/node/integrations/express/ + wizard_parent: node wizard: - _documentation/clients/node/index.md#installation - _documentation/clients/node/integrations/express.md @@ -45,6 +48,7 @@ name: Connect # XXX: this links to the old ones doc_link: /clients/node/integrations/connect/ + wizard_parent: node wizard: - _documentation/clients/node/index.md#installation - _documentation/clients/node/integrations/connect.md @@ -54,6 +58,7 @@ type: language name: Cordova doc_link: /clients/cordova/ + wizard_parent: cordova wizard: true case_style: camelCase fallback_platform: javascript @@ -77,6 +82,7 @@ type: language name: Java doc_link: /clients/java/ + wizard_parent: java wizard: - _documentation/clients/java/usage.md - @@ -85,6 +91,7 @@ type: framework name: java.util.logging doc_link: /clients/java/modules/jul/ + wizard_parent: java wizard: - _documentation/clients/java/modules/jul.md - @@ -93,6 +100,7 @@ type: framework name: Logback doc_link: /clients/java/modules/logback/ + wizard_parent: java wizard: - _documentation/clients/java/modules/logback.md - @@ -109,6 +117,7 @@ type: framework name: 'Log4j 2.x' doc_link: /clients/java/modules/log4j2/ + wizard_parent: java wizard: - _documentation/clients/java/modules/log4j2.md - @@ -117,6 +126,7 @@ type: framework name: 'Log4j 1.x' doc_link: /clients/java/modules/log4j/ + wizard_parent: java wizard: - _documentation/clients/java/modules/log4j.md - @@ -125,6 +135,7 @@ type: framework name: 'Google App Engine' doc_link: /clients/java/modules/appengine/ + wizard_parent: java wizard: - _documentation/clients/java/modules/appengine.md - @@ -134,6 +145,7 @@ name: Python doc_link: /platforms/python/ # this is actually the old legacy_wizard: + wizard_parent: python wizard: - _documentation/clients/python/index.md - _documentation/clients/python/usage.md @@ -152,6 +164,7 @@ type: framework name: Pyramid doc_link: /clients/python/integrations/pyramid/ + wizard_parent: python wizard: - _documentation/clients/python/index.md - _documentation/clients/python/integrations/pyramid.md @@ -162,15 +175,17 @@ type: framework name: RQ doc_link: /clients/python/integrations/rq/ + wizard_parent: python wizard: - _documentation/clients/python/index.md - _documentation/clients/python/integrations/rq.md + - _documentation/clients/python/index.md + - _documentation/clients/python/integrations/rq.md - slug: flask support_level: production type: framework name: Flask doc_link: /clients/python/integrations/flask/ + wizard_parent: python wizard: - _documentation/clients/python/index.md - _documentation/clients/python/integrations/flask.md @@ -180,6 +195,7 @@ type: framework name: Django doc_link: /clients/python/integrations/django/ + wizard_parent: python wizard: - _documentation/clients/python/index.md - _documentation/clients/python/integrations/django.md @@ -189,6 +205,7 @@ type: library name: Celery doc_link: /clients/python/integrations/celery/ + wizard_parent: python wizard: - _documentation/clients/python/index.md - _documentation/clients/python/integrations/celery.md @@ -198,6 +215,7 @@ type: framework name: Tornado doc_link: /clients/python/integrations/tornado/ + wizard_parent: python wizard: - _documentation/clients/python/index.md - _documentation/clients/python/integrations/tornado.md @@ -207,6 +225,7 @@ type: framework name: Bottle doc_link: /clients/python/integrations/bottle/ + wizard_parent: python wizard: - _documentation/clients/python/index.md - _documentation/clients/python/integrations/bottle.md @@ -216,6 +235,7 @@ type: framework name: Pylons doc_link: /clients/python/integrations/pylons/ + wizard_parent: python wizard: - _documentation/clients/python/index.md - _documentation/clients/python/integrations/pylons.md @@ -225,9 +245,10 @@ type: language name: Swift doc_link: /clients/cocoa/ + wizard_parent: cocoa wizard: - _documentation/clients/cocoa/index.md - - _documentation/clients/cocoa/dsym.md#upload-symbols-with-sentry-cli + - _documentation/clients/cocoa/dsym.md version: 4.1.0 version_key: SENTRY_COCOA_TAG - @@ -245,6 +266,7 @@ name: JavaScript doc_link: /platforms/javascript/ # this is actually the old legacy_wizard: + wizard_parent: javascript wizard: - _documentation/clients/javascript/index.md case_style: camelCase @@ -265,6 +287,7 @@ type: framework name: Vue doc_link: /clients/javascript/integrations/vue/ + wizard_parent: javascript wizard: - _documentation/clients/javascript/integrations/vue.md version: 3.26.4 @@ -275,6 +298,7 @@ type: framework name: Backbone doc_link: /clients/javascript/integrations/backbone/ + wizard_parent: javascript wizard: - _documentation/clients/javascript/integrations/backbone.md version: 3.26.4 @@ -285,6 +309,7 @@ type: framework name: Ember doc_link: /clients/javascript/integrations/ember/ + wizard_parent: javascript wizard: - _documentation/clients/javascript/integrations/ember.md version: 3.26.4 @@ -295,6 +320,7 @@ type: framework name: React doc_link: /clients/javascript/integrations/react/ + wizard_parent: javascript wizard: - _documentation/clients/javascript/integrations/react.md version: 3.26.4 @@ -305,6 +331,7 @@ type: framework name: AngularJS doc_link: /clients/javascript/integrations/angularjs/ + wizard_parent: javascript wizard: - _documentation/clients/javascript/integrations/angularjs.md version: 3.26.4 @@ -315,6 +342,7 @@ type: framework name: Angular doc_link: /clients/javascript/integrations/angular/ + wizard_parent: javascript wizard: - _documentation/clients/javascript/integrations/angular.md version: 3.26.4 @@ -325,6 +353,7 @@ type: language name: Electron doc_link: /clients/electron/ + wizard_parent: electron wizard: true case_style: camelCase fallback_platform: javascript @@ -334,6 +363,7 @@ type: language name: Elixir doc_link: /clients/elixir/ + wizard_parent: elixir wizard: - _documentation/clients/elixir/index.md - _documentation/clients/elixir/usage.md @@ -344,6 +374,7 @@ type: language name: React-Native doc_link: /clients/react-native/ + wizard_parent: react-native wizard: - _documentation/clients/react-native/index.md - @@ -352,6 +383,7 @@ type: language name: Objective-C doc_link: /clients/cocoa/ + wizard_parent: cocoa wizard: - _documentation/clients/cocoa/index.md - _documentation/clients/cocoa/dsym.md @@ -365,6 +397,7 @@ name: 'C#' doc_link: /platforms/dotnet/ # this is actually the old legacy_wizard: + wizard_parent: csharp wizard: - _documentation/clients/csharp/index.md case_style: PascalCase @@ -382,6 +415,7 @@ type: language name: Go doc_link: /clients/go/ + wizard_parent: go wizard: - _documentation/clients/go/index.md - @@ -390,6 +424,7 @@ type: framework name: net/http doc_link: /clients/go/integrations/http/ + wizard_parent: go wizard: - _documentation/clients/go/integrations/http.md - @@ -398,6 +433,7 @@ type: framework name: Laravel doc_link: /clients/php/integrations/laravel/ + wizard_parent: php wizard: - _documentation/clients/php/integrations/laravel.md - @@ -406,6 +442,7 @@ type: language name: PHP doc_link: /clients/php/ + wizard_parent: php wizard: - _documentation/clients/php/index.md - _documentation/clients/php/usage.md @@ -415,6 +452,7 @@ type: framework name: Monolog doc_link: /clients/php/integrations/monolog/ + wizard_parent: php wizard: - _documentation/clients/php/index.md#installation - _documentation/clients/php/integrations/monolog.md @@ -424,14 +462,16 @@ type: framework name: Symfony2 doc_link: /clients/php/integrations/symfony2/ + wizard_parent: php wizard: - - _documentation/clients/php/integrations/symfony2.md#symfony-2 + - _documentation/clients/php/integrations/symfony2.md - slug: ruby support_level: production type: language name: Ruby doc_link: /clients/ruby/ + wizard_parent: ruby wizard: - _documentation/clients/ruby/index.md - @@ -440,6 +480,7 @@ type: framework name: Rack doc_link: /clients/ruby/integrations/rack/ + wizard_parent: ruby wizard: - _documentation/clients/ruby/integrations/rack.md - @@ -448,6 +489,7 @@ type: framework name: Rails doc_link: /clients/ruby/integrations/rails/ + wizard_parent: ruby wizard: - _documentation/clients/ruby/integrations/rails.md - @@ -456,6 +498,7 @@ type: language name: Rust doc_link: /platforms/rust/ + wizard_parent: rust wizard: true version: 0.6.0 version_key: SENTRY_VERSION @@ -466,5 +509,6 @@ type: language name: Minidump doc_link: /platforms/minidump/ + wizard_parent: minidump wizard: - _documentation/platforms/minidump/index.md diff --git a/src/_layouts/json.json b/src/_layouts/json.json deleted file mode 100644 index 342ae716a7ed6..0000000000000 --- a/src/_layouts/json.json +++ /dev/null @@ -1 +0,0 @@ -{{ page.json | jsonify }} diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index 6bda70b3933bf..96d2bfab9823a 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -1,4 +1,5 @@ -require 'json' +require "Nokogiri" +require "json" # The platform api is generated based on the `wizard` key in platforms.yml. This # key can either be an array of documents with optional section slugs, or `true` @@ -22,151 +23,98 @@ # - _documentation/path/to/doc.md # - _documentation/path/to/doc-with-section.md#section-name -module Jekyll +Jekyll::Hooks.register :site, :post_render, priority: :high do |site| - class CategoryPage < Page - def initialize(site, base, dir, platform) + class PlatformAPIError < StandardError + end + + class CategoryPage < Jekyll::Page + def initialize(site, base, dir, platform, name) @site = site @base = base @dir = dir - @name = "#{platform["slug"]}.json" + @name = name self.process(@name) - self.read_yaml(File.join(base, '_layouts'), 'json.json') keys = ["support_level","type","name","doc_link","body"] - self.data['json'] = platform.select {|key,_| keys.include? key} - self.data['json']['doc_link'] = "#{site.config["url"]}#{self.data['json']['doc_link']}" + payload = platform.select {|key,_| keys.include? key} + payload["doc_link"] = "#{site.config["url"]}#{payload['doc_link']}" + self.output = payload.to_json end end - class IndexPage < Page - def initialize(site, base, dir, payload) + class IndexPage < Jekyll::Page + def initialize(site, base, dir, payload, name) @site = site @base = base @dir = dir - @name = "_index.json" + @name = name self.process(@name) - self.read_yaml(File.join(base, '_layouts'), 'json.json') - self.data['json'] = payload + self.output = payload.to_json end end - class CategoryPageGenerator < Generator - safe true - - def get_headings(md) - headings = [] - enabled = true - # Make an index of all headings and their line numbers in the file - md.each_line.with_index do |line, i| - enabled = !enabled if line =~ /^```/ - if enabled && line =~ /^(#+)/ - headings << { - line: i, - level: $1.size, - # Remove initial hash or trailing attribute list - slug: Utils.slugify(line.gsub(/(^#+ |\s?\{.*\}$)/,'')) - } - end - end - headings + index_payload = { + :platforms => {} + } + + site.data["platforms"].each do |platform| + next if platform["wizard"].nil? || platform["wizard_parent"].nil? + + # Create entry for _platforms/_index.json + file_name = "#{platform["slug"]}.json" + group_slug = platform["wizard_parent"] + is_self = group_slug === platform["slug"] + platform_slug = is_self ? "_self" : platform["slug"] + index_payload[:platforms][group_slug] ||= {} + index_payload[:platforms][group_slug][platform_slug] = { + :type => platform["type"], + :details => group_slug === platform_slug ? platform_slug : "#{group_slug}/#{file_name}", + :doc_link => "#{site.config["url"]}#{platform["doc_link"]}", + :name => platform["name"] + } + + documentation = site.collections["documentation"].docs + + directives = case platform["wizard"] + when TrueClass + ["_documentation/learn/quickstart.md"] + when Array + platform["wizard"] + when NilClass + else + raise PlatformAPIError, "Unsupported value for `wizard` in #{platform["slug"]}: Must be `true` or an array of file paths." end - def generate(site) - return if ENV["JEKYLL_DISABLE_PLATFORM_API"] == "true" - - # Create an index of all the sections in every document - docs = {} - site.collections["documentation"].docs.each do |doc| - content = doc.to_s - - if content =~ // - rendered = Jekyll::Renderer.new(site, doc, site.site_payload).run - wizard = /([\s\S]+?)/.match(rendered).captures - docs[doc.relative_path] = { :content => wizard.first } - else - sections = { - :document => content - } - headings = get_headings(content) - headings.each do |heading| - startLine = heading[:line] - close = headings.find {|h| h[:line] > startLine && heading[:level] >= h[:level]} - if !close.nil? - endLine = close[:line] - sections[heading[:slug]] = content.lines[startLine, endLine - startLine].join - else - sections[heading[:slug]] = content.lines[startLine..-1].join - end - end - - docs[doc.relative_path] = { :sections => sections } - - end + # Create entry for _platforms/.json or _platforms//.json + wizard_snippets = directives.map do |directive| + file_path, section_id = directive.split "#" + document = documentation.find { |d| d.relative_path === file_path } + blocks = document.content.scan(/([\s\S]+?)/) + + body = if section_id.nil? + blocks.map { |b| b[1] }.join + else + match = blocks.find { |b| b[0] === section_id } + raise PlatformAPIError, "Could not find wizard section '#{section_id}' in #{file_path}" if match.nil? + match[1] end - indexPayload = { - :platforms => {} - } - - - - # Generate each file - site.data["platforms"].each do |platform| - next if platform["legacy_wizard"].nil? && platform["wizard"].nil? - - if platform["legacy_wizard"] - body = "" - platform["legacy_wizard"].each do |wiz| - file, section = wiz.split '#' - section ||= :document - doc = docs[file] - if doc[:sections] - section_content = doc[:sections][section] - if section_content.nil? - raise "Cannot find section '#{section}' in #{file}" - end - body += section_content - else - body = doc[:content] - end - - end - - platform["body"] = site.find_converter_instance( - Jekyll::Converters::Markdown - ).convert(body) - else - platform["body"] = docs['_documentation/learn/quickstart.md'][:content] - end - - pathData = Pathname(platform["doc_link"]).each_filename.to_a - - if pathData.size > 2 - dir = "_platforms/#{pathData[1]}" - indexKey = platform["slug"] - else - dir = "_platforms" - indexKey = "_self" - end - - platformKey = pathData[1] - - detailName = "#{platform["slug"]}.json" - - # In which the javascript guy pretends to ruby - indexPayload[:platforms][platformKey] ||= {} - indexPayload[:platforms][platformKey][indexKey] ||= {} - indexPayload[:platforms][platformKey][indexKey] = { - :type => platform["type"], - :details => pathData.size > 2 ? File.join(pathData[1], detailName) : detailName, - :doc_link => "#{site.config["url"]}#{platform["doc_link"]}", - :name => platform["name"] - } - - site.pages << CategoryPage.new(site, site.source, dir, platform) + # Strip out platform content that doesn't relate to the current platform + noko_doc = Nokogiri::HTML(body) + noko_doc.css(".platform-specific-content").each do |node| + platform_content = node.css("[data-slug='#{platform["slug"]}']").children + raise PlatformAPIError, "Could not find platform content for '#{platform["slug"]}' in #{file_path}" if platform_content.empty? + node.replace platform_content end - - site.pages << IndexPage.new(site, site.source, "_platforms", indexPayload) + noko_doc.css("body").children.to_s end + + platform["body"] = wizard_snippets.join.strip + + dir = is_self ? "_platforms" : "_platforms/#{group_slug}" + + site.pages << CategoryPage.new(site, site.source, dir, platform, file_name) end + + site.pages << IndexPage.new(site, site.source, "_platforms", index_payload, "_index.json") end From 5ed093785663fb092bc904d231ff00d328bc6388 Mon Sep 17 00:00:00 2001 From: HazA Date: Mon, 17 Sep 2018 14:10:58 +0200 Subject: [PATCH 133/171] feat: Add local scopes --- .../_documentation/learn/scopes.md | 20 ++++++++++++++++++- .../learn/with-scope/javascript.md | 7 +++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/collections/_documentation/learn/with-scope/javascript.md diff --git a/src/collections/_documentation/learn/scopes.md b/src/collections/_documentation/learn/scopes.md index a3807cc448f16..976663e92c1f1 100644 --- a/src/collections/_documentation/learn/scopes.md +++ b/src/collections/_documentation/learn/scopes.md @@ -3,7 +3,7 @@ title: Scopes and Hubs sidebar_order: 4 --- -When an event is captured and sent to Sentry SDKs will merge that event data with extra +When an event is captured and sent to Sentry, SDKs will merge that event data with extra information from the current scope. SDKs will typically automatically mange the scopes for you in the framework integrations and you don't need to think about them. However you should know what a scope is and how you can use it for your advantage. @@ -63,3 +63,21 @@ add custom tags or to inform sentry about the currently authenticated user. To learn what useful information can be associated with scopes see [the context documentation]({% link _documentation/learn/context.md %}). + +## Local Scope + +We also have a function called `with_scope` which is also very helpful +if you only want to send data with one specific event. +In the following example we are using `with_scope` to attach a `level` and a `tag` to only +one specific `captureException`: + +{% include components/platform_content.html content_dir='with-scope' %} + +While this example looks similar to `configure_scope` it very different, in the sense that +`configure_scope` actually changes the current active scope, all successive calls to `configure_scope` +will keep the changes. +While on the other hand using `with_scope` creates a clone of the current scope +and will stay isolated until the function call is completed. +So you can either set context information in there that you don't want to be somewhere +else or create do not attach any context information at all +by calling `clear` on the scope, while the "global" scope remains unchanged. \ No newline at end of file diff --git a/src/collections/_documentation/learn/with-scope/javascript.md b/src/collections/_documentation/learn/with-scope/javascript.md new file mode 100644 index 0000000000000..7cb66d835ec15 --- /dev/null +++ b/src/collections/_documentation/learn/with-scope/javascript.md @@ -0,0 +1,7 @@ +```javascript +Sentry.withScope(scope => { + scope.setTag("my-tag", "my value"); + scope.setLevel('warning'); + Sentry.captureException(new Error('my error')); +}); +``` From 77881dbf572aea15fb63c8a115ccf66ccd1eb432 Mon Sep 17 00:00:00 2001 From: HazA Date: Mon, 17 Sep 2018 14:14:55 +0200 Subject: [PATCH 134/171] fix: an SDK --- src/collections/_documentation/learn/quickstart.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/collections/_documentation/learn/quickstart.md b/src/collections/_documentation/learn/quickstart.md index 74ecdf877715e..4b0fe85e26882 100644 --- a/src/collections/_documentation/learn/quickstart.md +++ b/src/collections/_documentation/learn/quickstart.md @@ -14,9 +14,9 @@ Getting started with Sentry is a three step process: 2. [Install your SDK](#pick-a-client-integration) 2. [Configure it](#configure-the-sdk) -## Install a SDK {#pick-a-client-integration} +## Install an SDK {#pick-a-client-integration} -Sentry captures data by using a SDK within your application’s runtime. These are platform specific and allow Sentry to have a deep understanding of both how your application works. In case your environment is very specific, you can also roll your own SDK using our document [_SDK API_]({%- link _documentation/clientdev/index.md -%}). +Sentry captures data by using an SDK within your application’s runtime. These are platform specific and allow Sentry to have a deep understanding of both how your application works. In case your environment is very specific, you can also roll your own SDK using our document [_SDK API_]({%- link _documentation/clientdev/index.md -%}). {% include components/platform_content.html content_dir='getting-started-install' %} From 09fbf6fa06807455192823b0938618ef5212a30b Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Mon, 17 Sep 2018 15:35:52 +0200 Subject: [PATCH 135/171] feat: Basic relay docs --- src/_data/documentation_categories.yml | 3 + src/_js/lib/User.js | 2 +- src/collections/_documentation/relay/index.md | 134 ++++++++++++++++++ 3 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 src/collections/_documentation/relay/index.md diff --git a/src/_data/documentation_categories.yml b/src/_data/documentation_categories.yml index 4e77c38074c0b..0fc2e867ddf16 100644 --- a/src/_data/documentation_categories.yml +++ b/src/_data/documentation_categories.yml @@ -22,6 +22,9 @@ - title: On-Premise slug: server +- title: Relay + slug: relay + - title: 'API Reference' slug: api diff --git a/src/_js/lib/User.js b/src/_js/lib/User.js index 6193759508ecd..1d357b308cc1e 100644 --- a/src/_js/lib/User.js +++ b/src/_js/lib/User.js @@ -104,7 +104,7 @@ const constructDSNObject = function(project = {}) { id: project.id || -1, group: escape(project.organizationName) || 'Example', PROJECT_NAME: escape(formatProjectLabel(project)) || 'Your Project', - PROJECT_ID: escape(project.projectSlug) || '', + PROJECT_ID: escape(project.projectSlug) || '<project-id>', ORG_NAME: escape(project.organizationSlug) || 'your-org', DSN: formatDsn(dsn, { public: false }), PUBLIC_DSN: formatDsn(dsn, { public: true }), diff --git a/src/collections/_documentation/relay/index.md b/src/collections/_documentation/relay/index.md new file mode 100644 index 0000000000000..317a849903ab4 --- /dev/null +++ b/src/collections/_documentation/relay/index.md @@ -0,0 +1,134 @@ +--- +title: 'Relay' +sidebar_order: 6 +--- + +Relay is a proxy application you can set up on-premise in front of Sentry that +allows you to modify or drop events, rate-limit clients or queue events in case +of a downtime. It is supposed to combine some of the benefits of on-premise +hosting (control over data) with the benefits of SaaS (less administrational +effort). + +## Installation + +The codename of Relay is `semaphore`. Download one of the binaries at +[GitHub](https://github.com/getsentry/semaphore/releases), and store the +downloaded binary somewhere in your `$PATH`. After that, you can use the config +wizard: + + $ semaphore config init + Initializing relay in /Users/untitaker/projects/semaphore/.semaphore + There is no relay config yet. Do you want to create one? + > yes, create default config + yes, create custom config + no, abort + Do you want to enable the internal crash reporting? + > yes, share relay internal crash reports with sentry.io + no, do not share crash reports + There are currently no credentials set up. Do you want to create some? + > no, just use relay without setting up credentials (simple proxy mode, recommended) + yes, set up relay with credentials (currently requires own Sentry installation) + All done! + +{% capture __alert_content -%} +If you're using on-prem, you need to create a custom config for your relay. Answer accordingly to the first question of the wizard. +{%- endcapture -%} +{%- include components/alert.html + title="Note" + content=__alert_content +%} + +You now have a folder named `.semaphore` in your current working directory. To +launch the server, run: + + semaphore run + +If you moved your config folder somewhere else, you can use the `-c` option: + + semaphore run -c ./my/custom/semaphore_folder/ + +## Setting up a project + +Right now Relay is only really usable in "simple proxy mode" (without +credentials), and as such calls the same exact endpoints on Sentry that an SDK +would. That unfortunately also means you have to configure each project +individually in Relay for now. + +Create a new file named: + +``` +.semaphore/project/___PROJECT_ID___.json +``` + +With the following content: + +```json +{ + "allowedDomains": ["*"], + "trustedRelays": [], + "publicKeys": ["___PUBLIC_KEY___"], + "config": { + "piiConfig": {} + } +} +``` + +The relay has to know all public keys (i.e. the secret part of the DSN) that +will send events to it. DSNs unknown for this project will be rejected. + +## Sending a test event + +Launch the server with `semaphore run`, and set up any SDK with the following DSN: + +``` +http://___PUBLIC_KEY___@127.0.0.1:3000/___PROJECT_ID___ +``` + +As you can see we only changed the host and port of the DSN to point to your +Relay setup. You should be able to use the SDK normally at this point. Events +arrive at the Sentry instance that Relay is configured to use in +`.semaphore/config.yml`. + +## PII stripping + +Now let's get to the entire point of this proxy setup: Stripping sensitive +data. + +The easiest way to go about this is if you already have a raw JSON payload from some SDK. Go to our PII config editor [PIInGUIn](https://getsentry.github.io/piinguin/), and: + +1. Paste in a raw event +2. Click on data you want eliminated +3. Paste in other payloads and see if they look fine, go to step **2** if necessary. + +After iterating on the config, paste it back into the project config you created earlier: + +``` +.semaphore/project/___PROJECT_ID___.json +``` + + +For example: + +```json +{ + "allowedDomains": ["*"], + "trustedRelays": [], + "publicKeys": ["___PUBLIC_KEY___"], + "config": { + "piiConfig": { + "rules": { + "device_id": { + "type": "pattern", + "pattern": "d/[a-f0-9]{12}", + "redaction": { + "method": "hash" + } + }, + "applications": { + "freeform": ["device_id"] + } + } + } + } +} +``` From e62920f0178a83f41fc3e909e87f916829b2f6de Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Mon, 17 Sep 2018 15:49:26 +0200 Subject: [PATCH 136/171] feat: Refer to relay from sensitive data docs --- src/collections/_documentation/learn/sensitive-data.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/collections/_documentation/learn/sensitive-data.md b/src/collections/_documentation/learn/sensitive-data.md index aba8b3c73a293..01e9118f0cb07 100644 --- a/src/collections/_documentation/learn/sensitive-data.md +++ b/src/collections/_documentation/learn/sensitive-data.md @@ -42,8 +42,12 @@ If you’ve accidentally sent sensitive data to the server it’s likely you’r - If you need to wipe just a single event, you’ll find the ability to bulk delete all sampled events under a rollup by visiting the rollup details page and selecting “Delete”. - If you send sparse events to a project (potentially all of them), your only option is to remove the project and re-create it. Keep in mind this will revoke API credentials, so you likely want to do this in the reverse order. -## Custom Event Processing +## Custom Event Processing in the SDK In the SDKs you can also set a function `before-send` which is invoked before events are sent which can be used to modify the events and remove bad data: {% include components/platform_content.html content_dir='before-send' %} + +## Custom Event Processing using Relay + +In addition you have the option to put a proxy between your applications and Sentry that can strip sensitive data from your events. Head over to [_Relay_]({%- link _documentation/relay/index.md -%}). From a8bc60541a07f09cb3860da6c928bf5e83a87fce Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Mon, 17 Sep 2018 16:47:37 +0200 Subject: [PATCH 137/171] feat: Document all relay options --- src/collections/_documentation/relay/index.md | 125 +-------- .../_documentation/relay/options.md | 237 ++++++++++++++++++ .../_documentation/relay/quickstart.md | 127 ++++++++++ 3 files changed, 366 insertions(+), 123 deletions(-) create mode 100644 src/collections/_documentation/relay/options.md create mode 100644 src/collections/_documentation/relay/quickstart.md diff --git a/src/collections/_documentation/relay/index.md b/src/collections/_documentation/relay/index.md index 317a849903ab4..d7a89bc3fce25 100644 --- a/src/collections/_documentation/relay/index.md +++ b/src/collections/_documentation/relay/index.md @@ -9,126 +9,5 @@ of a downtime. It is supposed to combine some of the benefits of on-premise hosting (control over data) with the benefits of SaaS (less administrational effort). -## Installation - -The codename of Relay is `semaphore`. Download one of the binaries at -[GitHub](https://github.com/getsentry/semaphore/releases), and store the -downloaded binary somewhere in your `$PATH`. After that, you can use the config -wizard: - - $ semaphore config init - Initializing relay in /Users/untitaker/projects/semaphore/.semaphore - There is no relay config yet. Do you want to create one? - > yes, create default config - yes, create custom config - no, abort - Do you want to enable the internal crash reporting? - > yes, share relay internal crash reports with sentry.io - no, do not share crash reports - There are currently no credentials set up. Do you want to create some? - > no, just use relay without setting up credentials (simple proxy mode, recommended) - yes, set up relay with credentials (currently requires own Sentry installation) - All done! - -{% capture __alert_content -%} -If you're using on-prem, you need to create a custom config for your relay. Answer accordingly to the first question of the wizard. -{%- endcapture -%} -{%- include components/alert.html - title="Note" - content=__alert_content -%} - -You now have a folder named `.semaphore` in your current working directory. To -launch the server, run: - - semaphore run - -If you moved your config folder somewhere else, you can use the `-c` option: - - semaphore run -c ./my/custom/semaphore_folder/ - -## Setting up a project - -Right now Relay is only really usable in "simple proxy mode" (without -credentials), and as such calls the same exact endpoints on Sentry that an SDK -would. That unfortunately also means you have to configure each project -individually in Relay for now. - -Create a new file named: - -``` -.semaphore/project/___PROJECT_ID___.json -``` - -With the following content: - -```json -{ - "allowedDomains": ["*"], - "trustedRelays": [], - "publicKeys": ["___PUBLIC_KEY___"], - "config": { - "piiConfig": {} - } -} -``` - -The relay has to know all public keys (i.e. the secret part of the DSN) that -will send events to it. DSNs unknown for this project will be rejected. - -## Sending a test event - -Launch the server with `semaphore run`, and set up any SDK with the following DSN: - -``` -http://___PUBLIC_KEY___@127.0.0.1:3000/___PROJECT_ID___ -``` - -As you can see we only changed the host and port of the DSN to point to your -Relay setup. You should be able to use the SDK normally at this point. Events -arrive at the Sentry instance that Relay is configured to use in -`.semaphore/config.yml`. - -## PII stripping - -Now let's get to the entire point of this proxy setup: Stripping sensitive -data. - -The easiest way to go about this is if you already have a raw JSON payload from some SDK. Go to our PII config editor [PIInGUIn](https://getsentry.github.io/piinguin/), and: - -1. Paste in a raw event -2. Click on data you want eliminated -3. Paste in other payloads and see if they look fine, go to step **2** if necessary. - -After iterating on the config, paste it back into the project config you created earlier: - -``` -.semaphore/project/___PROJECT_ID___.json -``` - - -For example: - -```json -{ - "allowedDomains": ["*"], - "trustedRelays": [], - "publicKeys": ["___PUBLIC_KEY___"], - "config": { - "piiConfig": { - "rules": { - "device_id": { - "type": "pattern", - "pattern": "d/[a-f0-9]{12}", - "redaction": { - "method": "hash" - } - }, - "applications": { - "freeform": ["device_id"] - } - } - } - } -} -``` +- [Getting started]({%- link _documentation/relay/quickstart.md -%}) +- [Configuration options]({%- link _documentation/relay/options.md -%}) diff --git a/src/collections/_documentation/relay/options.md b/src/collections/_documentation/relay/options.md new file mode 100644 index 0000000000000..abdea97bd03d5 --- /dev/null +++ b/src/collections/_documentation/relay/options.md @@ -0,0 +1,237 @@ +--- +title: 'Configuration Options' +sidebar_order: 2 +--- + +## Relay + +{:.config-key} +### relay.upstream + +*string, default: `https://ingest.sentry.io`* + +The upstream relay or sentry instance. + +It is not a good idea to set this to a value that will make the relay send errors to itself. + +{:.config-key} +### relay.host + +*string, default: `127.0.0.1`* + +The host the relay should bind to (network interface). Example: `0.0.0.0` + +{:.config-key} +### relay.port + +*integer, default: `3000`* + +The port to bind for the unencrypted relay HTTP server. Example: `3000` + +{:.config-key} +### relay.tls_port + +*integer, optional* + +Optional port to bind for the encrypted relay HTTPS server. Example: `3001` + +This is in addition to the `port` option: If you set up a HTTPS server at +`tls_port`, the HTTP server at `port` still exists. + +{:.config-key} +### relay.tls_identity_path + +*string, optional* + +The filesystem path to the identity (DER-encoded PKCS12) to use for the HTTPS +server. Example: `relay_dev.pfx` + +{:.config-key} +### relay.tls_identity_password + +*string, optional* + +Password for the PKCS12 archive in `tls_identity_path`. + +## HTTP + +Set various network-related settings. + +{:.config-key} +### http.timeout + +*integer, default: `5`* + +Timeout for upstream requests in seconds. + +{:.config-key} +### http.max_retry_interval + +*integer, default: `60`* + +Maximum interval between failed request retries in seconds. + +## Caching + +Fine-tune caching of project state. + +{:.config-key} +### cache.project_expiry + +*integer, default: `300` (5 minutes)* + +The cache timeout for project configurations in seconds. Irrelevant if you use +the "simple proxy mode", where your project config is stored in a local file. + +{:.config-key} +### cache.relay_expiry + +*integer, default: `3600` (1 hour)* + +The cache timeout for downstream relay info (public keys) in seconds. + +{:.config-key} +### cache.event_expiry + +*integer, default: `600` (10 minutes)* + +The cache timeout for events (store) before dropping them. + +{:.config-key} +### cache.miss_expiry + +*integer, default: `60` (1 minute)* + +The cache timeout for non-existing entries. + +{:.config-key} +### cache.batch_interval + +*integer, default: `100` (100 milliseconds)* + +The buffer timeout for batched queries before sending them upstream **in milliseconds**. + +{:.config-key} +### cache.file_interval + +*integer, default: `10` (10 seconds)* + +Interval for watching local cache override files in seconds. + +## Size Limits + +Controls various HTTP-related limits. All values are human-readable strings of a number and a human-readable unit, such as: + +- `1KiB` +- `1MB` +- `1MiB` +- `1MiB` +- `1025B` + +{:.config-key} +### limits.max_event_payload_size + +*string, default: `256KB`* + +The maximum payload size for events. + +{:.config-key} +### limits.max_api_payload_size + +*string, default: `20MB`* + +The maximum payload size for general API requests. + +{:.config-key} +### limits.max_api_file_upload_size + +*string, default: `40MB`* + +The maximum payload size for file uploads and chunks. + +{:.config-key} +### limits.max_api_chunk_upload_size + +*string, default: `100MB`* + +The maximum payload size for chunks + +{:.config-key} +## Logging + +{:.config-key} +### logging.level + +*string, default: `info`* + +The log level for the relay. One of: + +- `off` +- `error` +- `warn` +- `info` +- `debug` +- `trace` + +{:.config-key} +### logging.log_failed_payloads + +*boolean, default: `false`* + +If set to true this emits log messages for failed event payloads. + +{:.config-key} +### logging.format + +*string, default: `auto`* + +Controls the log format. One of: + +- `auto`: Auto detect (pretty for tty, simplified for other) +- `pretty`: With colors +- `simplified`: Simplified log output +- `json`: Dump out JSON lines + +{:.config-key} +### logging.enable_backtraces + +*boolean, default: `true`* + +When set to true, backtraces are forced on. + +{:.config-key} +## Statsd Metrics + +{:.config-key} +### metrics.statsd + +*string, optional* + +If set to a host/port string then metrics will be reported to this statsd +instance. + +{:.config-key} +### metrics.prefix + +*string, default: `sentry.relay`* + +The prefix that should be added to all metrics. + +{:.config-key} +## Internal Error Reporting + +{:.config-key} +### sentry.enabled + +*boolean, default: `false`* + +Whether to report internal errors to a separate DSN. `false` means no internal errors are sent (just logged). + +{:.config-key} +### sentry.dsn + +*string, optional* + +DSN to report internal relay failures to. + +It is not a good idea to set this to a value that will make the relay send errors to itself. Ideally this should just send errors to Sentry directly, not another relay. diff --git a/src/collections/_documentation/relay/quickstart.md b/src/collections/_documentation/relay/quickstart.md new file mode 100644 index 0000000000000..33165d93be517 --- /dev/null +++ b/src/collections/_documentation/relay/quickstart.md @@ -0,0 +1,127 @@ +--- +title: 'Getting started' +sidebar_order: 1 +--- + +Download one of the binaries at +[GitHub](https://github.com/getsentry/semaphore/releases), and store the +downloaded binary somewhere in your `$PATH`. After that, you can use the config +wizard: + + # The codename of Relay is semaphore + $ semaphore config init + Initializing relay in /Users/untitaker/projects/semaphore/.semaphore + There is no relay config yet. Do you want to create one? + > yes, create default config + yes, create custom config + no, abort + Do you want to enable the internal crash reporting? + > yes, share relay internal crash reports with sentry.io + no, do not share crash reports + There are currently no credentials set up. Do you want to create some? + > no, just use relay without setting up credentials (simple proxy mode, recommended) + yes, set up relay with credentials (currently requires own Sentry installation) + All done! + +{% capture __alert_content -%} +If you're using on-prem, you need to create a custom config for your relay. Answer accordingly to the first question of the wizard. +{%- endcapture -%} +{%- include components/alert.html + title="Note" + content=__alert_content +%} + +You now have a folder named `.semaphore` in your current working directory. To +launch the server, run: + + semaphore run + +If you moved your config folder somewhere else, you can use the `-c` option: + + semaphore run -c ./my/custom/semaphore_folder/ + +## Setting up a project + +Right now Relay is only really usable in "simple proxy mode" (without +credentials), and as such calls the same exact endpoints on Sentry that an SDK +would. That unfortunately also means you have to configure each project +individually in Relay for now. + +Create a new file named: + +``` +.semaphore/project/___PROJECT_ID___.json +``` + +With the following content: + +```json +{ + "allowedDomains": ["*"], + "trustedRelays": [], + "publicKeys": ["___PUBLIC_KEY___"], + "config": { + "piiConfig": {} + } +} +``` + +The relay has to know all public keys (i.e. the secret part of the DSN) that +will send events to it. DSNs unknown for this project will be rejected. + +## Sending a test event + +Launch the server with `semaphore run`, and set up any SDK with the following DSN: + +``` +http://___PUBLIC_KEY___@127.0.0.1:3000/___PROJECT_ID___ +``` + +As you can see we only changed the host and port of the DSN to point to your +Relay setup. You should be able to use the SDK normally at this point. Events +arrive at the Sentry instance that Relay is configured to use in +`.semaphore/config.yml`. + +## PII stripping + +Now let's get to the entire point of this proxy setup: Stripping sensitive +data. + +The easiest way to go about this is if you already have a raw JSON payload from some SDK. Go to our PII config editor [PIInGUIn](https://getsentry.github.io/piinguin/), and: + +1. Paste in a raw event +2. Click on data you want eliminated +3. Paste in other payloads and see if they look fine, go to step **2** if necessary. + +After iterating on the config, paste it back into the project config you created earlier: + +``` +.semaphore/project/___PROJECT_ID___.json +``` + + +For example: + +```json +{ + "allowedDomains": ["*"], + "trustedRelays": [], + "publicKeys": ["___PUBLIC_KEY___"], + "config": { + "piiConfig": { + "rules": { + "device_id": { + "type": "pattern", + "pattern": "d/[a-f0-9]{12}", + "redaction": { + "method": "hash" + } + }, + "applications": { + "freeform": ["device_id"] + } + } + } + } +} +``` From a039396c8d6c60d32f45f6a5c55f4eaf409d8afc Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Mon, 17 Sep 2018 09:05:33 -0700 Subject: [PATCH 138/171] emulate jekyll style I'm not familiar enough with ruby to tell you the difference but I assume it's some sort of scoping thing --- src/_plugins/platform_api.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index 96d2bfab9823a..ccd05e0de7889 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -25,10 +25,10 @@ Jekyll::Hooks.register :site, :post_render, priority: :high do |site| - class PlatformAPIError < StandardError + PlatformAPIError = Class.new(StandardError) do end - class CategoryPage < Jekyll::Page + CategoryPage = Class.new(Jekyll::Page) do def initialize(site, base, dir, platform, name) @site = site @base = base @@ -42,7 +42,7 @@ def initialize(site, base, dir, platform, name) end end - class IndexPage < Jekyll::Page + IndexPage = Class.new(Jekyll::Page) do def initialize(site, base, dir, payload, name) @site = site @base = base From f8a84a17b8c9958b6d5da807051890983a08fdc7 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Mon, 17 Sep 2018 10:53:01 -0700 Subject: [PATCH 139/171] Add missing data for android --- src/_data/platforms.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index e1313087a2a00..09a9052e84c88 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -109,6 +109,7 @@ type: framework name: Android doc_link: /clients/java/modules/android/ + wizard_parent: java wizard: - _documentation/clients/java/modules/android.md - From 23af9fa174adca5f3d63cb28461394ff341370e5 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Mon, 17 Sep 2018 10:53:13 -0700 Subject: [PATCH 140/171] Files need data in serve mode --- src/_plugins/platform_api.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index ccd05e0de7889..b4a19c55d71a3 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -34,6 +34,7 @@ def initialize(site, base, dir, platform, name) @base = base @dir = dir @name = name + @data ||= {} self.process(@name) keys = ["support_level","type","name","doc_link","body"] payload = platform.select {|key,_| keys.include? key} @@ -48,6 +49,7 @@ def initialize(site, base, dir, payload, name) @base = base @dir = dir @name = name + @data ||= {} self.process(@name) self.output = payload.to_json end From e2fa1bb4e52415523c6a2fdc0efbbaf4c575cfdd Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Mon, 17 Sep 2018 21:26:24 +0200 Subject: [PATCH 141/171] feat: Add documentation for PII config --- src/collections/_documentation/relay/index.md | 6 +- .../_documentation/relay/options.md | 2 + .../_documentation/relay/pii-config.md | 59 +++++ .../_documentation/relay/pii-rule-methods.md | 97 ++++++++ .../_documentation/relay/pii-rule-types.md | 224 ++++++++++++++++++ .../_documentation/relay/project-config.md | 46 ++++ 6 files changed, 432 insertions(+), 2 deletions(-) create mode 100644 src/collections/_documentation/relay/pii-config.md create mode 100644 src/collections/_documentation/relay/pii-rule-methods.md create mode 100644 src/collections/_documentation/relay/pii-rule-types.md create mode 100644 src/collections/_documentation/relay/project-config.md diff --git a/src/collections/_documentation/relay/index.md b/src/collections/_documentation/relay/index.md index d7a89bc3fce25..5870962d0e689 100644 --- a/src/collections/_documentation/relay/index.md +++ b/src/collections/_documentation/relay/index.md @@ -9,5 +9,7 @@ of a downtime. It is supposed to combine some of the benefits of on-premise hosting (control over data) with the benefits of SaaS (less administrational effort). -- [Getting started]({%- link _documentation/relay/quickstart.md -%}) -- [Configuration options]({%- link _documentation/relay/options.md -%}) +- [Getting Started]({%- link _documentation/relay/quickstart.md -%}) +- [Configuration]({%- link _documentation/relay/options.md -%}) +- [Project Configuration]({%- link _documentation/relay/project-config.md -%}) +- [PII Configuration]({%- link _documentation/relay/pii-config.md -%}) diff --git a/src/collections/_documentation/relay/options.md b/src/collections/_documentation/relay/options.md index abdea97bd03d5..196ea1bb7b592 100644 --- a/src/collections/_documentation/relay/options.md +++ b/src/collections/_documentation/relay/options.md @@ -3,6 +3,8 @@ title: 'Configuration Options' sidebar_order: 2 --- +The base configuration for Relay lives in the file `.semaphore/config.yml`. All keys are `snake_case`. + ## Relay {:.config-key} diff --git a/src/collections/_documentation/relay/pii-config.md b/src/collections/_documentation/relay/pii-config.md new file mode 100644 index 0000000000000..f4cfe1c3c147d --- /dev/null +++ b/src/collections/_documentation/relay/pii-config.md @@ -0,0 +1,59 @@ +--- +title: 'PII Configuration' +sidebar_order: 4 +--- + +The following document explores the syntax and semantics of PII configs for Relay. To get started with PII configs, it's recommended to use [_Piinguin_](https://getsentry.github.io/piinguin) and refer back to this document when needed. + +## A basic example + +Say you have an exception message which, unfortunately, contains IP addresses which are not supposed to be there. You'd write: + +```json +{ + "applications": { + "freeform": ["@ip:replace"] + } +} +``` + +It reads as "apply rule `@ip:replace` to all fields of kind `freeform`". + +## PII kinds + +Almost every field in an event has an assigned *PII kind*. The following PII kinds exist: + +- `freeform`: Arbitrary text. That might for example be the `message` field of a log entry, or an exception value/message. +- `ip`: Fields containing IP addresses. +- `id`: A user ID, device ID, device ID or similar. +- `username`: A username. +- `hostname`: A hostname. +- `sensitive`: Passwords, secret tokens. +- `email`: An email address. +- `databag`: Local variables in stacktraces, custom data in `extra`. + +Note that PII kinds always match on _location_, not on _content_. For example, +the `email` PII kind really only matches on JSON keys where emails are +suspected to be. + +## Rules + +PII kinds don't employ any kind of pattern matching. That's where PII _rules_ +come in. The following rules exist by default: + +- `@ip:replace` and `@ip:hash` for pattern-matching IP addresses +- `@imei:replace` and `@imei:hash` for pattern-matching IMEIs +- `@mac:replace`, `@mac:mask` and `@mac:hash` for pattern-matching MAC addresses +- `@email:mask`, `@email:replace` and `@email:hash` for pattern-matching email addresses +- `@creditcard:mask`, `@creditcard:replace` and `@creditcard:hash` for pattern-matching creditcard numbers +- `@userpath:replace` and `@userpath:hash` for pattern-matching local paths (e.g. `C:/Users/foo/`) +- `@password:remove` for pattern matching passwords. In this case we're pattern matching against the field's key, whether it contains `password`, `credentials` or similar strings. + +### Writing your own rules + +Rules generally consist of two parts: + +- *Rule types* describe what to match. See [_PII Rule Types_]({%- link _documentation/relay/pii-rule-types.md -%}) for an exhaustive list. +- *Rule redaction methods* describe what to do with the match. See [_PII Rule Redaction Methods_]({%- link _documentation/relay/pii-rule-methods.md -%}) for a list. + +Each page comes with examples. Try those examples out by pasting them into the "PII config" column of [_Piinguin_](https://getsentry.github.io/piinguin) and clicking on fields to get suggestions. diff --git a/src/collections/_documentation/relay/pii-rule-methods.md b/src/collections/_documentation/relay/pii-rule-methods.md new file mode 100644 index 0000000000000..70d1fd7db77c8 --- /dev/null +++ b/src/collections/_documentation/relay/pii-rule-methods.md @@ -0,0 +1,97 @@ +--- +title: 'PII Rule Redaction Methods' +sidebar_order: 6 +--- + +{:.config-key} +#### remove + +Remove the entire field. Relay may choose to either set it to `null` or to remove it entirely. + +```json +{ + "rules": { + "remove_ip": { + "type": "ip", + "redaction": { + "method": "remove" + } + } + }, + "applications": { + "freeform": ["remove_ip"] + } +} +``` + +{:.config-key} +#### replace + +Replace the key with a static string. + +```json +{ + "rules": { + "replace_ip": { + "type": "ip", + "redaction": { + "method": "replace", + "text": "[censored]" + } + } + }, + "applications": { + "freeform": ["replace_ip"] + } +} +``` + +{:.config-key} +#### mask + +Replace every character of the matched string with a "masking" char. Compared to `replace` this preserves the length of the original string. + +```javascript +{ + "rules": { + "mask_ip": { + "type": "ip", + "redaction": { + "method": "mask", + "mask_char": "0", // The character used for masking. Optional, default "*" + "chars_to_ignore": ".", // Which characters to ignore. Optional, default empty + "range": [0, -1] // Which range of the string to replace. Optional, defaults to full range. Negative indices count from the matches' end. + } + } + }, + "applications": { + "freeform": ["mask_ip"] + } +} +``` + +{:.config-key} +#### hash + +Replace the string with a hashed version of itself. Equal strings will produce the same hash, so if you, for example, decide to hash the user ID instead of replacing or removing it, you will still have an accurate count of users affected. + +```javascript +{ + "rules": { + "hash_ip": { + "type": "ip", + "redaction": { + "method": "hash", + "algorithm": "HMAC-SHA1", // One of "HMAC-SHA1", "HMAC-SHA256", "HMAC-SHA512" + "key": "myOverriddenKey" // A key to salt the hash with. Defaults to the default key set in "vars" + } + } + }, + "vars": { + "hashKey": "myDefaultKey" // The default key to use + } + "applications": { + "freeform": ["mask_ip"] + } +} +``` diff --git a/src/collections/_documentation/relay/pii-rule-types.md b/src/collections/_documentation/relay/pii-rule-types.md new file mode 100644 index 0000000000000..d1bcf6bdeb432 --- /dev/null +++ b/src/collections/_documentation/relay/pii-rule-types.md @@ -0,0 +1,224 @@ +--- +title: 'PII Rule Types' +sidebar_order: 5 +--- + +{:.config-key} +#### pattern + +Custom Perl-style regex (PCRE). + +```json +{ + "rules": { + "hash_device_id": { + "type": "pattern", + "pattern": "d/[a-f0-9]{12}", + "redaction": { + "method": "hash" + } + } + }, + "applications": { + "freeform": ["hash_device_id"] + } +} +``` + +{:.config-key} +#### imei + +Matches an IMEI or IMEISV. + +```json +{ + "rules": { + "hash_imei": { + "type": "imei", + "redaction": { + "method": "hash" + } + } + }, + "applications": { + "freeform": ["hash_imei"] + } +} +``` + +{:.config-key} +#### mac + +Matches a MAC address. + +```json +{ + "rules": { + "hash_mac": { + "type": "mac", + "redaction": { + "method": "hash" + } + } + }, + "applications": { + "freeform": ["hash_mac"] + } +} +``` + +{:.config-key} +#### ip + +Matches any IP address. + +```json +{ + "rules": { + "hash_ip": { + "type": "ip", + "redaction": { + "method": "hash" + } + } + }, + "applications": { + "freeform": ["hash_ip"] + } +} +``` + +{:.config-key} +#### creditcard + +Matches a creditcard number. + +```json +{ + "rules": { + "hash_cc": { + "type": "creditcard", + "redaction": { + "method": "hash" + } + } + }, + "applications": { + "freeform": ["hash_cc"] + } +} +``` + +{:.config-key} +#### userpath + +Matches a local path (e.g. `C:/Users/foo/`). + +```json +{ + "rules": { + "hash_userpath": { + "type": "userpath", + "redaction": { + "method": "hash" + } + } + }, + "applications": { + "freeform": ["hash_userpath"] + } +} +``` + +{:.config-key} +#### remove + +Matches anything. This is basically equivalent to a wildcard regex. + +For example, to remove all data with the PII kind `freeform`: + +```json +{ + "rules": { + "remove_everything": { + "type": "remove", + "redaction": { + "method": "remove" + } + } + }, + "applications": { + "freeform": ["remove_everything"] + } +} +``` + +{:.config-key} +#### multiple + +Combine multiple rules into one. This is a disjunction (OR): The field in question has to match only one of the rules to match the combined rule, not all of them. + +```javascript +{ + "rules": { + "remove_ips_and_macs": { + "type": "multiple", + "rules": [ + "@ip", + "@mac" + ], + "hide_rule": false, // Hide the inner rules when showing which rules have been applied. Defaults to false. + "redaction": { + "method": "remove" + } + } + }, + "applications": { + "freeform": ["remove_ips_and_macs"] + } +} +``` + +{:.config-key} +#### alias + +Alias one rule to the other. This is the same as `multiple` except that you can only wrap one rule. + +```javascript +{ + "rules": { + "remove_ips": { + "type": "multiple", + "rule": "@ip", + "hide_rule": false, // Hide the inner rule when showing which rules have been applied. Defaults to false. + "redaction": { + "method": "remove" + } + } + }, + "applications": { + "freeform": ["remove_ips"] + } +} +``` + +{:.config-key} +#### redactPair + +Apply a regex to the key name. The value matches if the key matches the given regex. This is useful for removing tokens and keys, since those are usually completely random. + +```json +{ + "applications": { + "freeform": [ + "remove_all_passwords" + ] + }, + "rules": { + "remove_all_passwords": { + "keyPattern": "(password|token|credentials)", + "type": "redactPair" + } + } +} +``` diff --git a/src/collections/_documentation/relay/project-config.md b/src/collections/_documentation/relay/project-config.md new file mode 100644 index 0000000000000..97b9b9a9931bb --- /dev/null +++ b/src/collections/_documentation/relay/project-config.md @@ -0,0 +1,46 @@ +--- +title: 'Project Configuration' +sidebar_order: 3 +--- + +A Relay will generally not accept or forward events where it doesn't know the project. See [_Getting Started_]({%- link _documentation/relay/quickstart.md -%}) for a short introduction to project configs. This page enumerates all possible options. + +The configuration for a project with the ID `123` lives in the file `.semaphore/projects/123.json`. You can get the project ID from the path section of a DSN. + +All config keys in a project config are `camelCase`. + +{:.config-key} +## disabled + +*boolean, default: `false`* + +Whether the project is disabled. If set to `true`, the Relay will drop all events sent to this project. + +{:.config-key} +## publicKeys + +*map from string to boolean, default: `{}`* + +A map enumerating known public keys (the public key in a DSN) and whether events using that key should be accepted. Example: + +```json +{ + "publicKeys": { + "___PUBLIC_KEY___": true + } +} +``` + +{:.config-key} +## config.allowedDomains + +*array of origins (strings), default: `[]`* + +Configure origin URLs which Sentry should accept events from. + +This is basically the same as the "Allowed Domains" setting in the Sentry UI. + +{:.config-key} +## config.piiConfig + +See [_PII Configuration_]({%- link _documentation/relay/pii-config.md -%}). From b8da04de00d2d694409cbdc38d546664aa28f17d Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Mon, 17 Sep 2018 21:31:39 +0200 Subject: [PATCH 142/171] feat: Fix casing of piinguin --- src/collections/_documentation/relay/quickstart.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/collections/_documentation/relay/quickstart.md b/src/collections/_documentation/relay/quickstart.md index 33165d93be517..4f8ab5f298f2d 100644 --- a/src/collections/_documentation/relay/quickstart.md +++ b/src/collections/_documentation/relay/quickstart.md @@ -87,7 +87,7 @@ arrive at the Sentry instance that Relay is configured to use in Now let's get to the entire point of this proxy setup: Stripping sensitive data. -The easiest way to go about this is if you already have a raw JSON payload from some SDK. Go to our PII config editor [PIInGUIn](https://getsentry.github.io/piinguin/), and: +The easiest way to go about this is if you already have a raw JSON payload from some SDK. Go to our PII config editor [Piinguin](https://getsentry.github.io/piinguin/), and: 1. Paste in a raw event 2. Click on data you want eliminated From fa3cc5c2716453d0e63260c69ab970bb375ba7ca Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Mon, 17 Sep 2018 13:13:17 -0700 Subject: [PATCH 143/171] Add legacy doc support --- src/_plugins/platform_api.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index b4a19c55d71a3..31c4d0dcb3e78 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -116,6 +116,13 @@ def initialize(site, base, dir, payload, name) dir = is_self ? "_platforms" : "_platforms/#{group_slug}" site.pages << CategoryPage.new(site, site.source, dir, platform, file_name) + + # Special cases for legacy docs + case platform['slug'] + when "objc", "cocoa", "swift" + site.pages << CategoryPage.new(site, site.source, "_platforms", platform, file_name) + site.pages << CategoryPage.new(site, site.source, "_platforms", platform, file_name) + end end site.pages << IndexPage.new(site, site.source, "_platforms", index_payload, "_index.json") From 1ea84d372ce460d69b01bad6bd1db4e097bb0969 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Mon, 17 Sep 2018 13:49:55 -0700 Subject: [PATCH 144/171] Set doc_link for new docs to quickstart --- src/_data/platforms.yml | 3 --- src/_plugins/platform_api.rb | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index 09a9052e84c88..f77e61e34c730 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -57,7 +57,6 @@ support_level: production type: language name: Cordova - doc_link: /clients/cordova/ wizard_parent: cordova wizard: true case_style: camelCase @@ -353,7 +352,6 @@ support_level: production type: language name: Electron - doc_link: /clients/electron/ wizard_parent: electron wizard: true case_style: camelCase @@ -498,7 +496,6 @@ support_level: production type: language name: Rust - doc_link: /platforms/rust/ wizard_parent: rust wizard: true version: 0.6.0 diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index 31c4d0dcb3e78..977ca9f66f05b 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -38,7 +38,6 @@ def initialize(site, base, dir, platform, name) self.process(@name) keys = ["support_level","type","name","doc_link","body"] payload = platform.select {|key,_| keys.include? key} - payload["doc_link"] = "#{site.config["url"]}#{payload['doc_link']}" self.output = payload.to_json end end @@ -67,11 +66,12 @@ def initialize(site, base, dir, payload, name) group_slug = platform["wizard_parent"] is_self = group_slug === platform["slug"] platform_slug = is_self ? "_self" : platform["slug"] + doc_link = platform["wizard"] === true ? "/quickstart/" : platform["doc_link"] index_payload[:platforms][group_slug] ||= {} index_payload[:platforms][group_slug][platform_slug] = { :type => platform["type"], - :details => group_slug === platform_slug ? platform_slug : "#{group_slug}/#{file_name}", - :doc_link => "#{site.config["url"]}#{platform["doc_link"]}", + :details => group_slug === platform["slug"] ? file_name : "#{group_slug}/#{file_name}", + :doc_link => "#{site.config["url"]}#{doc_link}", :name => platform["name"] } From 6454e763f0488e73a50d5765f9a1219eb803e5d8 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Mon, 17 Sep 2018 13:50:05 -0700 Subject: [PATCH 145/171] Add nokogiri to gemfile --- Gemfile | 1 + Gemfile.lock | 1 + 2 files changed, 2 insertions(+) diff --git a/Gemfile b/Gemfile index 89499d9585965..d053c06a1b51d 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,7 @@ source "https://rubygems.org" gem "jekyll", "3.8.2" +gem "nokogiri", "1.8.3" # If you have any plugins, put them here! group :jekyll_plugins do diff --git a/Gemfile.lock b/Gemfile.lock index 6271a6ec22ffd..7e6c46854df52 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -108,6 +108,7 @@ DEPENDENCIES jekyll-assets (= 3.0.11) jekyll-extlinks liquid-md5 + nokogiri (= 1.8.3) sprockets (~> 4.0.beta) terminal-notifier tzinfo-data From 00e9983aefcd9b442adc954d0615bbba379b8320 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Mon, 17 Sep 2018 13:58:01 -0700 Subject: [PATCH 146/171] Update nokogiri --- Gemfile | 2 +- Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index d053c06a1b51d..e935bb3c9312c 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source "https://rubygems.org" gem "jekyll", "3.8.2" -gem "nokogiri", "1.8.3" +gem "nokogiri", '~> 1.6', '>= 1.6.7.2' # If you have any plugins, put them here! group :jekyll_plugins do diff --git a/Gemfile.lock b/Gemfile.lock index 7e6c46854df52..43b23c771f419 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -108,7 +108,7 @@ DEPENDENCIES jekyll-assets (= 3.0.11) jekyll-extlinks liquid-md5 - nokogiri (= 1.8.3) + nokogiri (~> 1.6, >= 1.6.7.2) sprockets (~> 4.0.beta) terminal-notifier tzinfo-data From cebce9811c5597468ffcdfdc437fbb2a3ccf4bb9 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Mon, 17 Sep 2018 14:05:22 -0700 Subject: [PATCH 147/171] go back --- Gemfile | 2 +- Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index e935bb3c9312c..d053c06a1b51d 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source "https://rubygems.org" gem "jekyll", "3.8.2" -gem "nokogiri", '~> 1.6', '>= 1.6.7.2' +gem "nokogiri", "1.8.3" # If you have any plugins, put them here! group :jekyll_plugins do diff --git a/Gemfile.lock b/Gemfile.lock index 43b23c771f419..7e6c46854df52 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -108,7 +108,7 @@ DEPENDENCIES jekyll-assets (= 3.0.11) jekyll-extlinks liquid-md5 - nokogiri (~> 1.6, >= 1.6.7.2) + nokogiri (= 1.8.3) sprockets (~> 4.0.beta) terminal-notifier tzinfo-data From fbad840a157908090b19c5faf31188ac8eeb0554 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Mon, 17 Sep 2018 14:08:02 -0700 Subject: [PATCH 148/171] require ruby 2.5.1 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index abd644651041c..50da0b99c4bad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ sudo: false language: ruby rvm: - - 2.3.6 + - 2.5.1 node_js: - "node" cache: From 0e9af3f1cd360efa9cfbd248cc0056826e84af76 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Mon, 17 Sep 2018 14:12:21 -0700 Subject: [PATCH 149/171] unix be damned --- src/_plugins/platform_api.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index 977ca9f66f05b..5f26c0ce2e80d 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -1,4 +1,4 @@ -require "Nokogiri" +require "nokogiri" require "json" # The platform api is generated based on the `wizard` key in platforms.yml. This From f0b1d991e77a4376f5754a9c5b7feb744516eaa5 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Mon, 17 Sep 2018 14:17:13 -0700 Subject: [PATCH 150/171] remove empty wizard --- src/_data/platforms.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/_data/platforms.yml b/src/_data/platforms.yml index 10725ea966b02..70daadbe5c3e8 100644 --- a/src/_data/platforms.yml +++ b/src/_data/platforms.yml @@ -259,14 +259,13 @@ doc_link: /clients/javascript/ case_style: camelCase fallback_platform: javascript - + - slug: browsernpm support_level: production type: language name: Browser Javascript NPM doc_link: /clients/javascript/ - wizard: [] case_style: camelCase fallback_platform: javascript - From 662a5b3e00f749503727d5aec4db07bcef100b44 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Mon, 17 Sep 2018 14:19:14 -0700 Subject: [PATCH 151/171] remove duplicated page --- src/_plugins/platform_api.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index 5f26c0ce2e80d..ecdd5452a0648 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -121,7 +121,6 @@ def initialize(site, base, dir, payload, name) case platform['slug'] when "objc", "cocoa", "swift" site.pages << CategoryPage.new(site, site.source, "_platforms", platform, file_name) - site.pages << CategoryPage.new(site, site.source, "_platforms", platform, file_name) end end From c6d415f527afdce7118d42540fa2ff04e4deb664 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Mon, 17 Sep 2018 14:51:51 -0700 Subject: [PATCH 152/171] tweak legacy cases --- src/_plugins/platform_api.rb | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index ecdd5452a0648..1f4dc6f2a64b4 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -55,7 +55,25 @@ def initialize(site, base, dir, payload, name) end index_payload = { - :platforms => {} + :platforms => { + # These are legacy cases + "cocoa": { + "_self": { + :type => "language", + :details => "objc.json", + :doc_link => "https://docs.sentry.io/clients/cocoa/", + :name => "Objective-C" + } + }, + "react-native": { + "_self": { + :type => "language", + :details => "cocoa.json", + :doc_link => "https://docs.sentry.io/clients/react-native/", + :name => "React-Native" + } + }, + } } site.data["platforms"].each do |platform| @@ -117,9 +135,9 @@ def initialize(site, base, dir, payload, name) site.pages << CategoryPage.new(site, site.source, dir, platform, file_name) - # Special cases for legacy docs + # Generate legacy docs case platform['slug'] - when "objc", "cocoa", "swift" + when "objc", "cocoa" site.pages << CategoryPage.new(site, site.source, "_platforms", platform, file_name) end end From 002ca57a4f173bdf7d3688fd18b3ce9cd4f987af Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Tue, 18 Sep 2018 00:08:29 +0200 Subject: [PATCH 153/171] feat: Added python and rust to with-scope --- .../_documentation/learn/scopes.md | 25 ++++++++++--------- .../_documentation/learn/with-scope/python.md | 8 ++++++ .../_documentation/learn/with-scope/rust.md | 15 +++++++++++ 3 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 src/collections/_documentation/learn/with-scope/python.md create mode 100644 src/collections/_documentation/learn/with-scope/rust.md diff --git a/src/collections/_documentation/learn/scopes.md b/src/collections/_documentation/learn/scopes.md index 976663e92c1f1..9af11d7af89a7 100644 --- a/src/collections/_documentation/learn/scopes.md +++ b/src/collections/_documentation/learn/scopes.md @@ -31,7 +31,7 @@ As you start using an SDK a scope and hub are automatically created for you out of the box. The hub you are unlikely to be interacting with directly unless you are writing an integration or you want to create or destroy scopes. Scopes on the other hand are more user facing. You can at any point in time call -`configure_scope` to modify data stored on the scope. This is for instance +`configure-scope` to modify data stored on the scope. This is for instance used to [modify the context]({% link _documentation/learn/context.md %}). {% capture __alert_content -%} @@ -55,7 +55,7 @@ then merge the event with the topmost scope's data. ## Configuring the Scope -The most useful operation when working with scopes is the `configure_scope` function. +The most useful operation when working with scopes is the `configure-scope` function. It can be used to reconfigure the current scope. This for instance can be used to add custom tags or to inform sentry about the currently authenticated user. @@ -64,20 +64,21 @@ add custom tags or to inform sentry about the currently authenticated user. To learn what useful information can be associated with scopes see [the context documentation]({% link _documentation/learn/context.md %}). -## Local Scope +## Local Scopes -We also have a function called `with_scope` which is also very helpful -if you only want to send data with one specific event. -In the following example we are using `with_scope` to attach a `level` and a `tag` to only -one specific `captureException`: +We also have support for pushing and configuring a scope in one go. This is +typically called `with-scope` or `push-scope` which is also very helpful +if you only want to send data with one specific event. In the following example we are using +that function to attach a `level` and a `tag` to only one specific error: {% include components/platform_content.html content_dir='with-scope' %} -While this example looks similar to `configure_scope` it very different, in the sense that -`configure_scope` actually changes the current active scope, all successive calls to `configure_scope` -will keep the changes. -While on the other hand using `with_scope` creates a clone of the current scope +While this example looks similar to `configure-scope` it very different, in the sense that +`configure-scope` actually changes the current active scope, all successive calls to `configure-scope` +will keep the changes. + +While on the other hand using `with-scope` creates a clone of the current scope and will stay isolated until the function call is completed. So you can either set context information in there that you don't want to be somewhere else or create do not attach any context information at all -by calling `clear` on the scope, while the "global" scope remains unchanged. \ No newline at end of file +by calling `clear` on the scope, while the "global" scope remains unchanged. diff --git a/src/collections/_documentation/learn/with-scope/python.md b/src/collections/_documentation/learn/with-scope/python.md new file mode 100644 index 0000000000000..dd11f21c814e4 --- /dev/null +++ b/src/collections/_documentation/learn/with-scope/python.md @@ -0,0 +1,8 @@ +```python +from sentry_sdk import push_scope, capture_exception + +with push_scope() as scope: + scope.set_tag("my-tag", "my value") + scope.level = 'warning' + capture_exception(Exception("my error")) +``` diff --git a/src/collections/_documentation/learn/with-scope/rust.md b/src/collections/_documentation/learn/with-scope/rust.md new file mode 100644 index 0000000000000..89d395cde9e6d --- /dev/null +++ b/src/collections/_documentation/learn/with-scope/rust.md @@ -0,0 +1,15 @@ +```rust +use sentry::{Level, with_scope}; +use sentry::integrations::failure::capture_error; +use failure::err_msg; + +with_scope(|scope| { + scope.set_tag("my-tag", "my value"); + scope.set_level(Some(Level::Warning)); +}, || { + capture_error(err_msg("my error")) +}); +``` + +*Note that in Rust two callbacks are invoked. One for configuring the scope, and a second +which is executed in the context of the scope.* From 3c589da253d8a212408b695bcc1270d731e8f9f3 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Mon, 17 Sep 2018 15:42:46 -0700 Subject: [PATCH 154/171] Ok, let's do it this way --- src/_plugins/platform_api.rb | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index 1f4dc6f2a64b4..a74e30729ed08 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -55,25 +55,7 @@ def initialize(site, base, dir, payload, name) end index_payload = { - :platforms => { - # These are legacy cases - "cocoa": { - "_self": { - :type => "language", - :details => "objc.json", - :doc_link => "https://docs.sentry.io/clients/cocoa/", - :name => "Objective-C" - } - }, - "react-native": { - "_self": { - :type => "language", - :details => "cocoa.json", - :doc_link => "https://docs.sentry.io/clients/react-native/", - :name => "React-Native" - } - }, - } + :platforms => {} } site.data["platforms"].each do |platform| @@ -85,6 +67,7 @@ def initialize(site, base, dir, payload, name) is_self = group_slug === platform["slug"] platform_slug = is_self ? "_self" : platform["slug"] doc_link = platform["wizard"] === true ? "/quickstart/" : platform["doc_link"] + index_payload[:platforms][group_slug] ||= {} index_payload[:platforms][group_slug][platform_slug] = { :type => platform["type"], @@ -138,6 +121,13 @@ def initialize(site, base, dir, payload, name) # Generate legacy docs case platform['slug'] when "objc", "cocoa" + index_payload[:platforms][platform['slug']] ||= {} + index_payload[:platforms][platform['slug']]["_self"] = { + :type => platform["type"], + :details => file_name, + :doc_link => "#{site.config["url"]}#{doc_link}", + :name => platform["name"] + } site.pages << CategoryPage.new(site, site.source, "_platforms", platform, file_name) end end From aff3f3da949765a20f0cbb5b63680b83ec4177fb Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Tue, 18 Sep 2018 00:54:54 +0200 Subject: [PATCH 155/171] ref: moved some relay stuff around --- src/_layouts/doc.html | 13 +++++ src/collections/_documentation/relay/index.md | 4 +- .../_documentation/relay/options.md | 14 +++-- .../{pii-config.md => pii-config/index.md} | 4 +- .../methods.md} | 0 .../types.md} | 0 .../_documentation/relay/project-config.md | 2 +- .../_documentation/relay/quickstart.md | 56 ++++++++----------- 8 files changed, 50 insertions(+), 43 deletions(-) rename src/collections/_documentation/relay/{pii-config.md => pii-config/index.md} (95%) rename src/collections/_documentation/relay/{pii-rule-methods.md => pii-config/methods.md} (100%) rename src/collections/_documentation/relay/{pii-rule-types.md => pii-config/types.md} (100%) diff --git a/src/_layouts/doc.html b/src/_layouts/doc.html index b057c568bac49..8c608a1355099 100644 --- a/src/_layouts/doc.html +++ b/src/_layouts/doc.html @@ -26,6 +26,19 @@
+ {%- assign __is_active = page.url | url_starts_with: "/relay" %} + {%- if __is_active %} + {% capture __alert_content -%} + Relay is currently in alpha. Not all functionality is currently available and + the user experience did not receive the necessary polishing yet. + {%- endcapture -%} + {%- include components/alert.html + level="warning" + title="Alpha Functionality" + content=__alert_content + %} + {%- endif %} + {%- for platform in site.data.platforms -%} {%- if platform.superseded_by %} {%- assign __is_active = page.url | url_starts_with: platform.doc_link %} diff --git a/src/collections/_documentation/relay/index.md b/src/collections/_documentation/relay/index.md index 5870962d0e689..130705b134af2 100644 --- a/src/collections/_documentation/relay/index.md +++ b/src/collections/_documentation/relay/index.md @@ -5,11 +5,11 @@ sidebar_order: 6 Relay is a proxy application you can set up on-premise in front of Sentry that allows you to modify or drop events, rate-limit clients or queue events in case -of a downtime. It is supposed to combine some of the benefits of on-premise +of network failures. It is supposed to combine some of the benefits of on-premise hosting (control over data) with the benefits of SaaS (less administrational effort). - [Getting Started]({%- link _documentation/relay/quickstart.md -%}) - [Configuration]({%- link _documentation/relay/options.md -%}) - [Project Configuration]({%- link _documentation/relay/project-config.md -%}) -- [PII Configuration]({%- link _documentation/relay/pii-config.md -%}) +- [PII Configuration]({%- link _documentation/relay/pii-config/index.md -%}) diff --git a/src/collections/_documentation/relay/options.md b/src/collections/_documentation/relay/options.md index 196ea1bb7b592..18a3ae22c579f 100644 --- a/src/collections/_documentation/relay/options.md +++ b/src/collections/_documentation/relay/options.md @@ -3,10 +3,12 @@ title: 'Configuration Options' sidebar_order: 2 --- -The base configuration for Relay lives in the file `.semaphore/config.yml`. All keys are `snake_case`. +The base configuration for Relay lives in the file `.semaphore/config.yml`. All keys are `snake_case`. ## Relay +General relay settings. + {:.config-key} ### relay.upstream @@ -21,14 +23,14 @@ It is not a good idea to set this to a value that will make the relay send error *string, default: `127.0.0.1`* -The host the relay should bind to (network interface). Example: `0.0.0.0` +The host the relay should bind to (network interface). Example: `0.0.0.0` {:.config-key} ### relay.port *integer, default: `3000`* -The port to bind for the unencrypted relay HTTP server. Example: `3000` +The port to bind for the unencrypted relay HTTP server. Example: `3000` {:.config-key} ### relay.tls_port @@ -46,7 +48,7 @@ This is in addition to the `port` option: If you set up a HTTPS server at *string, optional* The filesystem path to the identity (DER-encoded PKCS12) to use for the HTTPS -server. Example: `relay_dev.pfx` +server. Example: `relay_dev.pfx` {:.config-key} ### relay.tls_identity_password @@ -82,7 +84,7 @@ Fine-tune caching of project state. *integer, default: `300` (5 minutes)* -The cache timeout for project configurations in seconds. Irrelevant if you use +The cache timeout for project configurations in seconds. Irrelevant if you use the "simple proxy mode", where your project config is stored in a local file. {:.config-key} @@ -122,7 +124,7 @@ Interval for watching local cache override files in seconds. ## Size Limits -Controls various HTTP-related limits. All values are human-readable strings of a number and a human-readable unit, such as: +Controls various HTTP-related limits. All values are human-readable strings of a number and a human-readable unit, such as: - `1KiB` - `1MB` diff --git a/src/collections/_documentation/relay/pii-config.md b/src/collections/_documentation/relay/pii-config/index.md similarity index 95% rename from src/collections/_documentation/relay/pii-config.md rename to src/collections/_documentation/relay/pii-config/index.md index f4cfe1c3c147d..49bb50cdbed04 100644 --- a/src/collections/_documentation/relay/pii-config.md +++ b/src/collections/_documentation/relay/pii-config/index.md @@ -53,7 +53,7 @@ come in. The following rules exist by default: Rules generally consist of two parts: -- *Rule types* describe what to match. See [_PII Rule Types_]({%- link _documentation/relay/pii-rule-types.md -%}) for an exhaustive list. -- *Rule redaction methods* describe what to do with the match. See [_PII Rule Redaction Methods_]({%- link _documentation/relay/pii-rule-methods.md -%}) for a list. +- *Rule types* describe what to match. See [_PII Rule Types_]({%- link _documentation/relay/pii-config/types.md -%}) for an exhaustive list. +- *Rule redaction methods* describe what to do with the match. See [_PII Rule Redaction Methods_]({%- link _documentation/relay/pii-config/methods.md -%}) for a list. Each page comes with examples. Try those examples out by pasting them into the "PII config" column of [_Piinguin_](https://getsentry.github.io/piinguin) and clicking on fields to get suggestions. diff --git a/src/collections/_documentation/relay/pii-rule-methods.md b/src/collections/_documentation/relay/pii-config/methods.md similarity index 100% rename from src/collections/_documentation/relay/pii-rule-methods.md rename to src/collections/_documentation/relay/pii-config/methods.md diff --git a/src/collections/_documentation/relay/pii-rule-types.md b/src/collections/_documentation/relay/pii-config/types.md similarity index 100% rename from src/collections/_documentation/relay/pii-rule-types.md rename to src/collections/_documentation/relay/pii-config/types.md diff --git a/src/collections/_documentation/relay/project-config.md b/src/collections/_documentation/relay/project-config.md index 97b9b9a9931bb..cded3477a703b 100644 --- a/src/collections/_documentation/relay/project-config.md +++ b/src/collections/_documentation/relay/project-config.md @@ -43,4 +43,4 @@ This is basically the same as the "Allowed Domains" setting in the Sentry UI. {:.config-key} ## config.piiConfig -See [_PII Configuration_]({%- link _documentation/relay/pii-config.md -%}). +See [_PII Configuration_]({%- link _documentation/relay/pii-config/index.md -%}). diff --git a/src/collections/_documentation/relay/quickstart.md b/src/collections/_documentation/relay/quickstart.md index 4f8ab5f298f2d..eadf7593e3c39 100644 --- a/src/collections/_documentation/relay/quickstart.md +++ b/src/collections/_documentation/relay/quickstart.md @@ -3,33 +3,25 @@ title: 'Getting started' sidebar_order: 1 --- -Download one of the binaries at -[GitHub](https://github.com/getsentry/semaphore/releases), and store the -downloaded binary somewhere in your `$PATH`. After that, you can use the config -wizard: +The relay server is called "semaphore". Binaries can be downloaded from the +[GitHub releases page](https://github.com/getsentry/semaphore/releases). After +downloading place the binary somewhere on your `PATH` and make it executable. + +The `config init` command is provided to initialize the initial config. The +config will be created the folder it's run from in a hidden `.semaphore` +subdirectory: - # The codename of Relay is semaphore $ semaphore config init - Initializing relay in /Users/untitaker/projects/semaphore/.semaphore - There is no relay config yet. Do you want to create one? - > yes, create default config - yes, create custom config - no, abort - Do you want to enable the internal crash reporting? - > yes, share relay internal crash reports with sentry.io - no, do not share crash reports - There are currently no credentials set up. Do you want to create some? - > no, just use relay without setting up credentials (simple proxy mode, recommended) - yes, set up relay with credentials (currently requires own Sentry installation) - All done! - -{% capture __alert_content -%} -If you're using on-prem, you need to create a custom config for your relay. Answer accordingly to the first question of the wizard. -{%- endcapture -%} -{%- include components/alert.html - title="Note" - content=__alert_content -%} + +The wizard will ask a few questions: + +1. default vs custom config. In the default config the relay will connect to + sentry.io for sending and will generally use the defaults. In the custom + config a different upstream can be configured. +2. Relay internal crash reporting can be enabled or disabled. When enabled the + relay will report its own internal errors to sentry.io to help us debug it. +3. Lastly the relay will ask it should run authenticated with credentials or + not. Currently we do not yet support authenticated mode against sentry.io. You now have a folder named `.semaphore` in your current working directory. To launch the server, run: @@ -40,14 +32,14 @@ If you moved your config folder somewhere else, you can use the `-c` option: semaphore run -c ./my/custom/semaphore_folder/ -## Setting up a project +## Setting up a Project Right now Relay is only really usable in "simple proxy mode" (without credentials), and as such calls the same exact endpoints on Sentry that an SDK -would. That unfortunately also means you have to configure each project -individually in Relay for now. +would. That also means you have to configure each project individually in +Relay. -Create a new file named: +Create a new file in the form `project_id.json`: ``` .semaphore/project/___PROJECT_ID___.json @@ -67,9 +59,9 @@ With the following content: ``` The relay has to know all public keys (i.e. the secret part of the DSN) that -will send events to it. DSNs unknown for this project will be rejected. +will send events to it. DSNs unknown for this project will be rejected. -## Sending a test event +## Sending a Test Event Launch the server with `semaphore run`, and set up any SDK with the following DSN: @@ -82,7 +74,7 @@ Relay setup. You should be able to use the SDK normally at this point. Events arrive at the Sentry instance that Relay is configured to use in `.semaphore/config.yml`. -## PII stripping +## PII Stripping Now let's get to the entire point of this proxy setup: Stripping sensitive data. From 2b4174f11e9ddf14fe869015dcd03b9d4ab14495 Mon Sep 17 00:00:00 2001 From: cameronmcefee Date: Mon, 17 Sep 2018 16:08:59 -0700 Subject: [PATCH 156/171] more tweaks to get the right output --- src/_plugins/platform_api.rb | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index a74e30729ed08..e6ef965cf9574 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -116,19 +116,30 @@ def initialize(site, base, dir, payload, name) dir = is_self ? "_platforms" : "_platforms/#{group_slug}" - site.pages << CategoryPage.new(site, site.source, dir, platform, file_name) - - # Generate legacy docs + # The first two cases are legacy structure for docs case platform['slug'] - when "objc", "cocoa" - index_payload[:platforms][platform['slug']] ||= {} - index_payload[:platforms][platform['slug']]["_self"] = { + when "cocoa" + index_payload[:platforms]["react-native"] ||= {} + index_payload[:platforms]["react-native"]["_self"] = { + :type => platform["type"], + :details => file_name, + :doc_link => "#{site.config["url"]}#{doc_link}", + :name => platform["name"] + } + site.pages << CategoryPage.new(site, site.source, "_platforms", platform, file_name) + index_payload[:platforms]["react-native"].delete "cocoa" + when "objc" + index_payload[:platforms]["cocoa"] ||= {} + index_payload[:platforms]["cocoa"]["_self"] = { :type => platform["type"], :details => file_name, :doc_link => "#{site.config["url"]}#{doc_link}", :name => platform["name"] } site.pages << CategoryPage.new(site, site.source, "_platforms", platform, file_name) + site.pages << CategoryPage.new(site, site.source, dir, platform, file_name) + else + site.pages << CategoryPage.new(site, site.source, dir, platform, file_name) end end From 17a848f9ed9029b8c837dd0568eea9684e9a7428 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Tue, 18 Sep 2018 13:29:06 +0200 Subject: [PATCH 157/171] fix: relay config --- src/collections/_documentation/relay/quickstart.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/collections/_documentation/relay/quickstart.md b/src/collections/_documentation/relay/quickstart.md index eadf7593e3c39..ef2f4c47b168a 100644 --- a/src/collections/_documentation/relay/quickstart.md +++ b/src/collections/_documentation/relay/quickstart.md @@ -96,10 +96,10 @@ For example: ```json { - "allowedDomains": ["*"], - "trustedRelays": [], "publicKeys": ["___PUBLIC_KEY___"], "config": { + "allowedDomains": ["*"], + "trustedRelays": [], "piiConfig": { "rules": { "device_id": { @@ -108,10 +108,10 @@ For example: "redaction": { "method": "hash" } - }, - "applications": { - "freeform": ["device_id"] } + }, + "applications": { + "freeform": ["device_id"] } } } From 48fc05f338e29607b5a9fe542998b99eb5884fa3 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Tue, 18 Sep 2018 13:31:09 +0200 Subject: [PATCH 158/171] fix: More fixes --- src/collections/_documentation/relay/quickstart.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/collections/_documentation/relay/quickstart.md b/src/collections/_documentation/relay/quickstart.md index ef2f4c47b168a..bbff9715d09f5 100644 --- a/src/collections/_documentation/relay/quickstart.md +++ b/src/collections/_documentation/relay/quickstart.md @@ -96,7 +96,9 @@ For example: ```json { - "publicKeys": ["___PUBLIC_KEY___"], + "publicKeys": { + "___PUBLIC_KEY___": true + }, "config": { "allowedDomains": ["*"], "trustedRelays": [], From b55e7d2f928781729107c062fd75287084aa49d4 Mon Sep 17 00:00:00 2001 From: HazA Date: Tue, 18 Sep 2018 15:05:58 +0200 Subject: [PATCH 159/171] fix: Move alert out of wizard --- src/collections/_documentation/learn/quickstart.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/collections/_documentation/learn/quickstart.md b/src/collections/_documentation/learn/quickstart.md index 42d37fef76ad9..693da01472233 100644 --- a/src/collections/_documentation/learn/quickstart.md +++ b/src/collections/_documentation/learn/quickstart.md @@ -18,9 +18,6 @@ Getting started with Sentry is a three step process: Sentry captures data by using an SDK within your application’s runtime. These are platform specific and allow Sentry to have a deep understanding of both how your application works. In case your environment is very specific, you can also roll your own SDK using our document [_SDK API_]({%- link _documentation/clientdev/index.md -%}). - -{% include components/platform_content.html content_dir='getting-started-install' %} - {% capture __alert_content -%} Your platform is not listed? There are more SDKs we support: [list of SDKs]({%- link _documentation/platforms/index.md -%}) {%- endcapture -%} @@ -29,6 +26,9 @@ Your platform is not listed? There are more SDKs we support: [list of SDKs]({%- content=__alert_content %} + +{% include components/platform_content.html content_dir='getting-started-install' %} + ## Configure the SDK {#configure-the-sdk} After you completed setting up a project in Sentry, you’ll be given a value which we call a _DSN_, or _Data Source Name_. It looks a lot like a standard URL, but it’s actually just a representation of the configuration required by the Sentry SDKs. It consists of a few pieces, including the protocol, public key, the server address, and the project identifier. From 56a4f3c628cb03a62dd204ba7d1c47e6155ab39d Mon Sep 17 00:00:00 2001 From: Cameron McEfee Date: Tue, 18 Sep 2018 08:42:39 -0700 Subject: [PATCH 160/171] add platform slug to doc_link --- src/_plugins/platform_api.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index e6ef965cf9574..f19a7e75d5309 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -66,7 +66,7 @@ def initialize(site, base, dir, payload, name) group_slug = platform["wizard_parent"] is_self = group_slug === platform["slug"] platform_slug = is_self ? "_self" : platform["slug"] - doc_link = platform["wizard"] === true ? "/quickstart/" : platform["doc_link"] + doc_link = platform["wizard"] === true ? "/quickstart?platform=#{platform["slug"]}" : platform["doc_link"] index_payload[:platforms][group_slug] ||= {} index_payload[:platforms][group_slug][platform_slug] = { From 10ca3abbee16ff665dd8d79175b2d44656884891 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Tue, 18 Sep 2018 17:51:56 +0200 Subject: [PATCH 161/171] feat: Rename remove PII type --- src/collections/_documentation/relay/pii-config/types.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/collections/_documentation/relay/pii-config/types.md b/src/collections/_documentation/relay/pii-config/types.md index d1bcf6bdeb432..9821951af4e36 100644 --- a/src/collections/_documentation/relay/pii-config/types.md +++ b/src/collections/_documentation/relay/pii-config/types.md @@ -131,9 +131,9 @@ Matches a local path (e.g. `C:/Users/foo/`). ``` {:.config-key} -#### remove +#### anything -Matches anything. This is basically equivalent to a wildcard regex. +Matches any value. This is basically equivalent to a wildcard regex. For example, to remove all data with the PII kind `freeform`: @@ -141,7 +141,7 @@ For example, to remove all data with the PII kind `freeform`: { "rules": { "remove_everything": { - "type": "remove", + "type": "anything", "redaction": { "method": "remove" } From 5501b804cb7d365671e4df0b6e042d8f6a029c0d Mon Sep 17 00:00:00 2001 From: Cameron McEfee Date: Tue, 18 Sep 2018 10:18:20 -0700 Subject: [PATCH 162/171] update doc_link universally --- src/_plugins/platform_api.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index f19a7e75d5309..ea17e96a56a2c 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -66,13 +66,13 @@ def initialize(site, base, dir, payload, name) group_slug = platform["wizard_parent"] is_self = group_slug === platform["slug"] platform_slug = is_self ? "_self" : platform["slug"] - doc_link = platform["wizard"] === true ? "/quickstart?platform=#{platform["slug"]}" : platform["doc_link"] + platform["doc_link"] = platform["wizard"] === true ? "/quickstart?platform=#{platform["slug"]}" : platform["doc_link"] index_payload[:platforms][group_slug] ||= {} index_payload[:platforms][group_slug][platform_slug] = { :type => platform["type"], :details => group_slug === platform["slug"] ? file_name : "#{group_slug}/#{file_name}", - :doc_link => "#{site.config["url"]}#{doc_link}", + :doc_link => "#{site.config["url"]}#{platform["doc_link"]}", :name => platform["name"] } @@ -123,7 +123,7 @@ def initialize(site, base, dir, payload, name) index_payload[:platforms]["react-native"]["_self"] = { :type => platform["type"], :details => file_name, - :doc_link => "#{site.config["url"]}#{doc_link}", + :doc_link => "#{site.config["url"]}#{platform["doc_link"]}", :name => platform["name"] } site.pages << CategoryPage.new(site, site.source, "_platforms", platform, file_name) @@ -133,7 +133,7 @@ def initialize(site, base, dir, payload, name) index_payload[:platforms]["cocoa"]["_self"] = { :type => platform["type"], :details => file_name, - :doc_link => "#{site.config["url"]}#{doc_link}", + :doc_link => "#{site.config["url"]}#{platform["doc_link"]}", :name => platform["name"] } site.pages << CategoryPage.new(site, site.source, "_platforms", platform, file_name) From 7fd297d35f1c94051a7c01b1897a875a6790b160 Mon Sep 17 00:00:00 2001 From: Cameron McEfee Date: Tue, 18 Sep 2018 10:57:13 -0700 Subject: [PATCH 163/171] always prepend doclink --- src/_plugins/platform_api.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index ea17e96a56a2c..31b08eb2b67f5 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -66,13 +66,13 @@ def initialize(site, base, dir, payload, name) group_slug = platform["wizard_parent"] is_self = group_slug === platform["slug"] platform_slug = is_self ? "_self" : platform["slug"] - platform["doc_link"] = platform["wizard"] === true ? "/quickstart?platform=#{platform["slug"]}" : platform["doc_link"] + platform["doc_link"] = "#{site.config["url"]}#{ platform["wizard"] === true ? "/quickstart?platform=#{platform["slug"]}" : platform["doc_link"] }" index_payload[:platforms][group_slug] ||= {} index_payload[:platforms][group_slug][platform_slug] = { :type => platform["type"], :details => group_slug === platform["slug"] ? file_name : "#{group_slug}/#{file_name}", - :doc_link => "#{site.config["url"]}#{platform["doc_link"]}", + :doc_link => platform["doc_link"], :name => platform["name"] } @@ -123,7 +123,7 @@ def initialize(site, base, dir, payload, name) index_payload[:platforms]["react-native"]["_self"] = { :type => platform["type"], :details => file_name, - :doc_link => "#{site.config["url"]}#{platform["doc_link"]}", + :doc_link => platform["doc_link"], :name => platform["name"] } site.pages << CategoryPage.new(site, site.source, "_platforms", platform, file_name) @@ -133,7 +133,7 @@ def initialize(site, base, dir, payload, name) index_payload[:platforms]["cocoa"]["_self"] = { :type => platform["type"], :details => file_name, - :doc_link => "#{site.config["url"]}#{platform["doc_link"]}", + :doc_link => platform["doc_link"], :name => platform["name"] } site.pages << CategoryPage.new(site, site.source, "_platforms", platform, file_name) From 7aeb96c6a17dc3d097c02ae80bb24c6389bd6656 Mon Sep 17 00:00:00 2001 From: Cameron McEfee Date: Tue, 18 Sep 2018 11:06:30 -0700 Subject: [PATCH 164/171] break up doc_link asignment to be a little clearer --- src/_plugins/platform_api.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/_plugins/platform_api.rb b/src/_plugins/platform_api.rb index 31b08eb2b67f5..aefdad9fd04dd 100644 --- a/src/_plugins/platform_api.rb +++ b/src/_plugins/platform_api.rb @@ -66,7 +66,8 @@ def initialize(site, base, dir, payload, name) group_slug = platform["wizard_parent"] is_self = group_slug === platform["slug"] platform_slug = is_self ? "_self" : platform["slug"] - platform["doc_link"] = "#{site.config["url"]}#{ platform["wizard"] === true ? "/quickstart?platform=#{platform["slug"]}" : platform["doc_link"] }" + doc_link = platform["wizard"] === true ? "/quickstart?platform=#{platform["slug"]}" : platform["doc_link"] + platform["doc_link"] = "#{site.config["url"]}#{ doc_link }" index_payload[:platforms][group_slug] ||= {} index_payload[:platforms][group_slug][platform_slug] = { From 996c674b5fa98d9a763a9810be4c8d8400404086 Mon Sep 17 00:00:00 2001 From: Cameron McEfee Date: Tue, 18 Sep 2018 12:30:04 -0700 Subject: [PATCH 165/171] fix: more specific target for updating the platform switcher text --- src/_includes/components/platform_content.html | 2 +- src/_js/lib/PlatformContent.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/_includes/components/platform_content.html b/src/_includes/components/platform_content.html index b87f0ca470bc3..c80edcf092d83 100644 --- a/src/_includes/components/platform_content.html +++ b/src/_includes/components/platform_content.html @@ -58,7 +58,7 @@