feat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relay - #2091

Merged
iambriccardo merged 16 commits into
masterfrom
riccardo/feat/add-sampling-to-relay-server
May 8, 2023
Merged

feat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relay#2091
iambriccardo merged 16 commits into
masterfrom
riccardo/feat/add-sampling-to-relay-server

Conversation

@iambriccardo

@iambriccardoiambriccardo commented May 3, 2023

Copy link
Copy Markdown
Contributor

This PR adds a new function to sentry-relay called run_dynamic_sampling which will run dynamic sampling on a two SamplingConfigs.

@iambriccardoiambriccardo changed the title feat(dynamic-sampling): Add possibility to run dynamic sampling fromfeat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relayMay 3, 2023
@iambriccardo
iambriccardo requested a review from jjbayerMay 4, 2023 06:14
@iambriccardo
iambriccardo marked this pull request as ready for review May 4, 2023 06:14
@iambriccardo
iambriccardo requested a review from a teamMay 4, 2023 06:14
Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +361 to +363
let sampling_config = serde_json::from_str::<SamplingConfig>((*sampling_config).as_str())?;
let root_sampling_config =
serde_json::from_str::<SamplingConfig>((*root_sampling_config).as_str())?;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to use the ? operator for curiosity and I don't understand why the compiler allows me to return a Result when the type is RelayStr.

Comment threadCHANGELOG.md Outdated
- Scrub sensitive keys (`passwd`, `token`, ...) in Replay recording data. ([#2034](https://github.com/getsentry/relay/pull/2034))
- Add document_uri to csp filter. ([#2059](https://github.com/getsentry/relay/pull/2059))
- Store `geo.subdivision` of the end user location. ([#2058](https://github.com/getsentry/relay/pull/2058))
- Add new FFI function for running dynamic sampling. ([#2091](https://github.com/getsentry/relay/pull/2091))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this to py/CHANGELOG.md

raise ValueError(error)


def run_dynamic_sampling(sampling_config, root_sampling_config, dsc, event):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we take an entire envelope as interface, instead? In Relay's pipeline, DS also reads information from other envelope headers.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to keep it stupid simple for now, in case we want, we can extend it to have an envelope as well.

Comment threadpy/sentry_relay/processing.py Outdated
Comment on lines +277 to +287
return json.loads(
decode_str(
rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
)
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add free=True to decode_str, since the owned string returned by FFI needs to be released. You can make this more readable like so:

Suggested change
returnjson.loads(
decode_str(
rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
)
)
result_json=rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
returnjson.loads(decode_str(result_json, free=True))

assert str(e.value) == 'json atom at path ".foobar" is missing from rhs'


def test_run_dynamic_sampling_with_valid_params_and_match():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are quite elaborate and will have to change every time we change something about sampling internals, particularly because they check the contents of the returned rules. Should we instead make more general checks, such as assert "merged_sampling_configs" in result and leave the rest to the DS unit tests in Rust?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a very good idea yes!

Comment threadrelay-cabi/src/processing.rs Outdated
use std::os::raw::c_char;
use std::slice;

use crate::core::{RelayBuf, RelayStr};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please order imports according to the style guide. This concerns the chrono and crate imports.

Comment threadrelay-cabi/src/processing.rs Outdated
serde_json::from_str::<SamplingConfig>((*root_sampling_config).as_str())?;
// We can optionally accept a dsc and event.
let dsc = serde_json::from_str::<DynamicSamplingContext>((*dsc).as_str());
let event = serde_json::from_str::<EphemeralEvent>((*event).as_str());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of parsing some synthetic EphemeralEvent, you should just load an actual Annotated<Event> directly:

Suggested change
let event = serde_json::from_str::<EphemeralEvent>((*event).as_str());
let event = Annotated::<Event>::from_json((*event).as_str())?;
let event = event.value().ok_or(<some error>)?;

Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +356 to +359
sampling_config: *const RelayStr,
root_sampling_config: *const RelayStr,
dsc: *const RelayStr,
event: *const RelayStr,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can pass all of these as references and then don't have to worry about dereferencing the pointer below. This is something we've not done consistently in the codebase, but we should move towards:

Suggested change
sampling_config:*constRelayStr,
root_sampling_config:*constRelayStr,
dsc:*constRelayStr,
event:*constRelayStr,
sampling_config:&RelayStr,
root_sampling_config:&RelayStr,
dsc:&RelayStr,
event:&RelayStr,

@iambriccardo
iambriccardo requested a review from jan-auerMay 5, 2023 08:31
Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +6 to +7
use anyhow::Context;
use chrono::Utc;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move these two imports to the next import group (above once_cell).

@iambriccardo
iambriccardo merged commit 6e5bab1 into masterMay 8, 2023
@iambriccardo
iambriccardo deleted the riccardo/feat/add-sampling-to-relay-server branch May 8, 2023 08:42
jan-auer added a commit that referenced this pull request May 9, 2023
* master: (178 commits)
ref(crons): Allow `_` in monitor slugs (#2100)
fix(span-metrics): Scrub subdomains in metric tags (#2103)
feat(normalization): Scrub span description URLs (#2095)
feat(dynamic-sampling): Add possibility to run dynamic sampling from `sentry-relay` (#2091)
ref(dynamic-config): Remove transaction metrics allowlist from Sentry (#2092)
feat(protocol): Support old effective-directory format (#2048)
ref(spans): Add more tags to span metrics (#2090)
fix(server): Support HTTP half-close connections (#2089)
ref(spans): Use transactions namespace with `span` prefix (#2087)
ref(spans): Update span metrics feature flag name (#2086)
feat(metrics): Extract more metrics from spans (#2080)
build: Bump tempfile to remove flagged dependency (#2085)
feat(filter): Add document_uri csp filter (#2059)
build: Use jemalloc on Linux (#2084)
ci(gha): add debugging for "Couldn'\''t write tracker file" issue (#2081)
feat(crons): Pass-through minimal `sdk` field (#2073)
fix(quota): Parse large limits (#2079)
instr(server): More details on unexpected envelope drop (#2077)
fix(ci): Skip flaky integration test (#2076)
feat(dynamic-sampling): Add support for `trace.replay_id` in matching rules (#2070)
...
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@iambriccardo@jan-auer
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relay - #2091

Merged
iambriccardo merged 16 commits into
masterfrom
riccardo/feat/add-sampling-to-relay-server
May 8, 2023
Merged

feat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relay#2091
iambriccardo merged 16 commits into
masterfrom
riccardo/feat/add-sampling-to-relay-server

Conversation

@iambriccardo

@iambriccardoiambriccardo commented May 3, 2023

Copy link
Copy Markdown
Contributor

This PR adds a new function to sentry-relay called run_dynamic_sampling which will run dynamic sampling on a two SamplingConfigs.

@iambriccardoiambriccardo changed the title feat(dynamic-sampling): Add possibility to run dynamic sampling fromfeat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relayMay 3, 2023
@iambriccardo
iambriccardo requested a review from jjbayerMay 4, 2023 06:14
@iambriccardo
iambriccardo marked this pull request as ready for review May 4, 2023 06:14
@iambriccardo
iambriccardo requested a review from a teamMay 4, 2023 06:14
Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +361 to +363
let sampling_config = serde_json::from_str::<SamplingConfig>((*sampling_config).as_str())?;
let root_sampling_config =
serde_json::from_str::<SamplingConfig>((*root_sampling_config).as_str())?;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to use the ? operator for curiosity and I don't understand why the compiler allows me to return a Result when the type is RelayStr.

Comment threadCHANGELOG.md Outdated
- Scrub sensitive keys (`passwd`, `token`, ...) in Replay recording data. ([#2034](https://github.com/getsentry/relay/pull/2034))
- Add document_uri to csp filter. ([#2059](https://github.com/getsentry/relay/pull/2059))
- Store `geo.subdivision` of the end user location. ([#2058](https://github.com/getsentry/relay/pull/2058))
- Add new FFI function for running dynamic sampling. ([#2091](https://github.com/getsentry/relay/pull/2091))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this to py/CHANGELOG.md

raise ValueError(error)


def run_dynamic_sampling(sampling_config, root_sampling_config, dsc, event):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we take an entire envelope as interface, instead? In Relay's pipeline, DS also reads information from other envelope headers.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to keep it stupid simple for now, in case we want, we can extend it to have an envelope as well.

Comment threadpy/sentry_relay/processing.py Outdated
Comment on lines +277 to +287
return json.loads(
decode_str(
rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
)
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add free=True to decode_str, since the owned string returned by FFI needs to be released. You can make this more readable like so:

Suggested change
returnjson.loads(
decode_str(
rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
)
)
result_json=rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
returnjson.loads(decode_str(result_json, free=True))

assert str(e.value) == 'json atom at path ".foobar" is missing from rhs'


def test_run_dynamic_sampling_with_valid_params_and_match():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are quite elaborate and will have to change every time we change something about sampling internals, particularly because they check the contents of the returned rules. Should we instead make more general checks, such as assert "merged_sampling_configs" in result and leave the rest to the DS unit tests in Rust?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a very good idea yes!

Comment threadrelay-cabi/src/processing.rs Outdated
use std::os::raw::c_char;
use std::slice;

use crate::core::{RelayBuf, RelayStr};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please order imports according to the style guide. This concerns the chrono and crate imports.

Comment threadrelay-cabi/src/processing.rs Outdated
serde_json::from_str::<SamplingConfig>((*root_sampling_config).as_str())?;
// We can optionally accept a dsc and event.
let dsc = serde_json::from_str::<DynamicSamplingContext>((*dsc).as_str());
let event = serde_json::from_str::<EphemeralEvent>((*event).as_str());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of parsing some synthetic EphemeralEvent, you should just load an actual Annotated<Event> directly:

Suggested change
let event = serde_json::from_str::<EphemeralEvent>((*event).as_str());
let event = Annotated::<Event>::from_json((*event).as_str())?;
let event = event.value().ok_or(<some error>)?;

Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +356 to +359
sampling_config: *const RelayStr,
root_sampling_config: *const RelayStr,
dsc: *const RelayStr,
event: *const RelayStr,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can pass all of these as references and then don't have to worry about dereferencing the pointer below. This is something we've not done consistently in the codebase, but we should move towards:

Suggested change
sampling_config:*constRelayStr,
root_sampling_config:*constRelayStr,
dsc:*constRelayStr,
event:*constRelayStr,
sampling_config:&RelayStr,
root_sampling_config:&RelayStr,
dsc:&RelayStr,
event:&RelayStr,

@iambriccardo
iambriccardo requested a review from jan-auerMay 5, 2023 08:31
Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +6 to +7
use anyhow::Context;
use chrono::Utc;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move these two imports to the next import group (above once_cell).

@iambriccardo
iambriccardo merged commit 6e5bab1 into masterMay 8, 2023
@iambriccardo
iambriccardo deleted the riccardo/feat/add-sampling-to-relay-server branch May 8, 2023 08:42
jan-auer added a commit that referenced this pull request May 9, 2023
* master: (178 commits)
ref(crons): Allow `_` in monitor slugs (#2100)
fix(span-metrics): Scrub subdomains in metric tags (#2103)
feat(normalization): Scrub span description URLs (#2095)
feat(dynamic-sampling): Add possibility to run dynamic sampling from `sentry-relay` (#2091)
ref(dynamic-config): Remove transaction metrics allowlist from Sentry (#2092)
feat(protocol): Support old effective-directory format (#2048)
ref(spans): Add more tags to span metrics (#2090)
fix(server): Support HTTP half-close connections (#2089)
ref(spans): Use transactions namespace with `span` prefix (#2087)
ref(spans): Update span metrics feature flag name (#2086)
feat(metrics): Extract more metrics from spans (#2080)
build: Bump tempfile to remove flagged dependency (#2085)
feat(filter): Add document_uri csp filter (#2059)
build: Use jemalloc on Linux (#2084)
ci(gha): add debugging for "Couldn'\''t write tracker file" issue (#2081)
feat(crons): Pass-through minimal `sdk` field (#2073)
fix(quota): Parse large limits (#2079)
instr(server): More details on unexpected envelope drop (#2077)
fix(ci): Skip flaky integration test (#2076)
feat(dynamic-sampling): Add support for `trace.replay_id` in matching rules (#2070)
...
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@iambriccardo@jan-auer
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relay - #2091

Merged
iambriccardo merged 16 commits into
masterfrom
riccardo/feat/add-sampling-to-relay-server
May 8, 2023
Merged

feat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relay#2091
iambriccardo merged 16 commits into
masterfrom
riccardo/feat/add-sampling-to-relay-server

Conversation

@iambriccardo

@iambriccardoiambriccardo commented May 3, 2023

Copy link
Copy Markdown
Contributor

This PR adds a new function to sentry-relay called run_dynamic_sampling which will run dynamic sampling on a two SamplingConfigs.

@iambriccardoiambriccardo changed the title feat(dynamic-sampling): Add possibility to run dynamic sampling fromfeat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relayMay 3, 2023
@iambriccardo
iambriccardo requested a review from jjbayerMay 4, 2023 06:14
@iambriccardo
iambriccardo marked this pull request as ready for review May 4, 2023 06:14
@iambriccardo
iambriccardo requested a review from a teamMay 4, 2023 06:14
Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +361 to +363
let sampling_config = serde_json::from_str::<SamplingConfig>((*sampling_config).as_str())?;
let root_sampling_config =
serde_json::from_str::<SamplingConfig>((*root_sampling_config).as_str())?;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to use the ? operator for curiosity and I don't understand why the compiler allows me to return a Result when the type is RelayStr.

Comment threadCHANGELOG.md Outdated
- Scrub sensitive keys (`passwd`, `token`, ...) in Replay recording data. ([#2034](https://github.com/getsentry/relay/pull/2034))
- Add document_uri to csp filter. ([#2059](https://github.com/getsentry/relay/pull/2059))
- Store `geo.subdivision` of the end user location. ([#2058](https://github.com/getsentry/relay/pull/2058))
- Add new FFI function for running dynamic sampling. ([#2091](https://github.com/getsentry/relay/pull/2091))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this to py/CHANGELOG.md

raise ValueError(error)


def run_dynamic_sampling(sampling_config, root_sampling_config, dsc, event):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we take an entire envelope as interface, instead? In Relay's pipeline, DS also reads information from other envelope headers.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to keep it stupid simple for now, in case we want, we can extend it to have an envelope as well.

Comment threadpy/sentry_relay/processing.py Outdated
Comment on lines +277 to +287
return json.loads(
decode_str(
rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
)
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add free=True to decode_str, since the owned string returned by FFI needs to be released. You can make this more readable like so:

Suggested change
returnjson.loads(
decode_str(
rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
)
)
result_json=rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
returnjson.loads(decode_str(result_json, free=True))

assert str(e.value) == 'json atom at path ".foobar" is missing from rhs'


def test_run_dynamic_sampling_with_valid_params_and_match():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are quite elaborate and will have to change every time we change something about sampling internals, particularly because they check the contents of the returned rules. Should we instead make more general checks, such as assert "merged_sampling_configs" in result and leave the rest to the DS unit tests in Rust?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a very good idea yes!

Comment threadrelay-cabi/src/processing.rs Outdated
use std::os::raw::c_char;
use std::slice;

use crate::core::{RelayBuf, RelayStr};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please order imports according to the style guide. This concerns the chrono and crate imports.

Comment threadrelay-cabi/src/processing.rs Outdated
serde_json::from_str::<SamplingConfig>((*root_sampling_config).as_str())?;
// We can optionally accept a dsc and event.
let dsc = serde_json::from_str::<DynamicSamplingContext>((*dsc).as_str());
let event = serde_json::from_str::<EphemeralEvent>((*event).as_str());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of parsing some synthetic EphemeralEvent, you should just load an actual Annotated<Event> directly:

Suggested change
let event = serde_json::from_str::<EphemeralEvent>((*event).as_str());
let event = Annotated::<Event>::from_json((*event).as_str())?;
let event = event.value().ok_or(<some error>)?;

Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +356 to +359
sampling_config: *const RelayStr,
root_sampling_config: *const RelayStr,
dsc: *const RelayStr,
event: *const RelayStr,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can pass all of these as references and then don't have to worry about dereferencing the pointer below. This is something we've not done consistently in the codebase, but we should move towards:

Suggested change
sampling_config:*constRelayStr,
root_sampling_config:*constRelayStr,
dsc:*constRelayStr,
event:*constRelayStr,
sampling_config:&RelayStr,
root_sampling_config:&RelayStr,
dsc:&RelayStr,
event:&RelayStr,

@iambriccardo
iambriccardo requested a review from jan-auerMay 5, 2023 08:31
Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +6 to +7
use anyhow::Context;
use chrono::Utc;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move these two imports to the next import group (above once_cell).

@iambriccardo
iambriccardo merged commit 6e5bab1 into masterMay 8, 2023
@iambriccardo
iambriccardo deleted the riccardo/feat/add-sampling-to-relay-server branch May 8, 2023 08:42
jan-auer added a commit that referenced this pull request May 9, 2023
* master: (178 commits)
ref(crons): Allow `_` in monitor slugs (#2100)
fix(span-metrics): Scrub subdomains in metric tags (#2103)
feat(normalization): Scrub span description URLs (#2095)
feat(dynamic-sampling): Add possibility to run dynamic sampling from `sentry-relay` (#2091)
ref(dynamic-config): Remove transaction metrics allowlist from Sentry (#2092)
feat(protocol): Support old effective-directory format (#2048)
ref(spans): Add more tags to span metrics (#2090)
fix(server): Support HTTP half-close connections (#2089)
ref(spans): Use transactions namespace with `span` prefix (#2087)
ref(spans): Update span metrics feature flag name (#2086)
feat(metrics): Extract more metrics from spans (#2080)
build: Bump tempfile to remove flagged dependency (#2085)
feat(filter): Add document_uri csp filter (#2059)
build: Use jemalloc on Linux (#2084)
ci(gha): add debugging for "Couldn'\''t write tracker file" issue (#2081)
feat(crons): Pass-through minimal `sdk` field (#2073)
fix(quota): Parse large limits (#2079)
instr(server): More details on unexpected envelope drop (#2077)
fix(ci): Skip flaky integration test (#2076)
feat(dynamic-sampling): Add support for `trace.replay_id` in matching rules (#2070)
...
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@iambriccardo@jan-auer
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relay - #2091

Merged
iambriccardo merged 16 commits into
masterfrom
riccardo/feat/add-sampling-to-relay-server
May 8, 2023
Merged

feat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relay#2091
iambriccardo merged 16 commits into
masterfrom
riccardo/feat/add-sampling-to-relay-server

Conversation

@iambriccardo

@iambriccardoiambriccardo commented May 3, 2023

Copy link
Copy Markdown
Contributor

This PR adds a new function to sentry-relay called run_dynamic_sampling which will run dynamic sampling on a two SamplingConfigs.

@iambriccardoiambriccardo changed the title feat(dynamic-sampling): Add possibility to run dynamic sampling fromfeat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relayMay 3, 2023
@iambriccardo
iambriccardo requested a review from jjbayerMay 4, 2023 06:14
@iambriccardo
iambriccardo marked this pull request as ready for review May 4, 2023 06:14
@iambriccardo
iambriccardo requested a review from a teamMay 4, 2023 06:14
Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +361 to +363
let sampling_config = serde_json::from_str::<SamplingConfig>((*sampling_config).as_str())?;
let root_sampling_config =
serde_json::from_str::<SamplingConfig>((*root_sampling_config).as_str())?;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to use the ? operator for curiosity and I don't understand why the compiler allows me to return a Result when the type is RelayStr.

Comment threadCHANGELOG.md Outdated
- Scrub sensitive keys (`passwd`, `token`, ...) in Replay recording data. ([#2034](https://github.com/getsentry/relay/pull/2034))
- Add document_uri to csp filter. ([#2059](https://github.com/getsentry/relay/pull/2059))
- Store `geo.subdivision` of the end user location. ([#2058](https://github.com/getsentry/relay/pull/2058))
- Add new FFI function for running dynamic sampling. ([#2091](https://github.com/getsentry/relay/pull/2091))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this to py/CHANGELOG.md

raise ValueError(error)


def run_dynamic_sampling(sampling_config, root_sampling_config, dsc, event):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we take an entire envelope as interface, instead? In Relay's pipeline, DS also reads information from other envelope headers.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to keep it stupid simple for now, in case we want, we can extend it to have an envelope as well.

Comment threadpy/sentry_relay/processing.py Outdated
Comment on lines +277 to +287
return json.loads(
decode_str(
rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
)
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add free=True to decode_str, since the owned string returned by FFI needs to be released. You can make this more readable like so:

Suggested change
returnjson.loads(
decode_str(
rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
)
)
result_json=rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
returnjson.loads(decode_str(result_json, free=True))

assert str(e.value) == 'json atom at path ".foobar" is missing from rhs'


def test_run_dynamic_sampling_with_valid_params_and_match():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are quite elaborate and will have to change every time we change something about sampling internals, particularly because they check the contents of the returned rules. Should we instead make more general checks, such as assert "merged_sampling_configs" in result and leave the rest to the DS unit tests in Rust?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a very good idea yes!

Comment threadrelay-cabi/src/processing.rs Outdated
use std::os::raw::c_char;
use std::slice;

use crate::core::{RelayBuf, RelayStr};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please order imports according to the style guide. This concerns the chrono and crate imports.

Comment threadrelay-cabi/src/processing.rs Outdated
serde_json::from_str::<SamplingConfig>((*root_sampling_config).as_str())?;
// We can optionally accept a dsc and event.
let dsc = serde_json::from_str::<DynamicSamplingContext>((*dsc).as_str());
let event = serde_json::from_str::<EphemeralEvent>((*event).as_str());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of parsing some synthetic EphemeralEvent, you should just load an actual Annotated<Event> directly:

Suggested change
let event = serde_json::from_str::<EphemeralEvent>((*event).as_str());
let event = Annotated::<Event>::from_json((*event).as_str())?;
let event = event.value().ok_or(<some error>)?;

Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +356 to +359
sampling_config: *const RelayStr,
root_sampling_config: *const RelayStr,
dsc: *const RelayStr,
event: *const RelayStr,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can pass all of these as references and then don't have to worry about dereferencing the pointer below. This is something we've not done consistently in the codebase, but we should move towards:

Suggested change
sampling_config:*constRelayStr,
root_sampling_config:*constRelayStr,
dsc:*constRelayStr,
event:*constRelayStr,
sampling_config:&RelayStr,
root_sampling_config:&RelayStr,
dsc:&RelayStr,
event:&RelayStr,

@iambriccardo
iambriccardo requested a review from jan-auerMay 5, 2023 08:31
Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +6 to +7
use anyhow::Context;
use chrono::Utc;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move these two imports to the next import group (above once_cell).

@iambriccardo
iambriccardo merged commit 6e5bab1 into masterMay 8, 2023
@iambriccardo
iambriccardo deleted the riccardo/feat/add-sampling-to-relay-server branch May 8, 2023 08:42
jan-auer added a commit that referenced this pull request May 9, 2023
* master: (178 commits)
ref(crons): Allow `_` in monitor slugs (#2100)
fix(span-metrics): Scrub subdomains in metric tags (#2103)
feat(normalization): Scrub span description URLs (#2095)
feat(dynamic-sampling): Add possibility to run dynamic sampling from `sentry-relay` (#2091)
ref(dynamic-config): Remove transaction metrics allowlist from Sentry (#2092)
feat(protocol): Support old effective-directory format (#2048)
ref(spans): Add more tags to span metrics (#2090)
fix(server): Support HTTP half-close connections (#2089)
ref(spans): Use transactions namespace with `span` prefix (#2087)
ref(spans): Update span metrics feature flag name (#2086)
feat(metrics): Extract more metrics from spans (#2080)
build: Bump tempfile to remove flagged dependency (#2085)
feat(filter): Add document_uri csp filter (#2059)
build: Use jemalloc on Linux (#2084)
ci(gha): add debugging for "Couldn'\''t write tracker file" issue (#2081)
feat(crons): Pass-through minimal `sdk` field (#2073)
fix(quota): Parse large limits (#2079)
instr(server): More details on unexpected envelope drop (#2077)
fix(ci): Skip flaky integration test (#2076)
feat(dynamic-sampling): Add support for `trace.replay_id` in matching rules (#2070)
...
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@iambriccardo@jan-auer
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relay - #2091

Merged
iambriccardo merged 16 commits into
masterfrom
riccardo/feat/add-sampling-to-relay-server
May 8, 2023
Merged

feat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relay#2091
iambriccardo merged 16 commits into
masterfrom
riccardo/feat/add-sampling-to-relay-server

Conversation

@iambriccardo

@iambriccardoiambriccardo commented May 3, 2023

Copy link
Copy Markdown
Contributor

This PR adds a new function to sentry-relay called run_dynamic_sampling which will run dynamic sampling on a two SamplingConfigs.

@iambriccardoiambriccardo changed the title feat(dynamic-sampling): Add possibility to run dynamic sampling fromfeat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relayMay 3, 2023
@iambriccardo
iambriccardo requested a review from jjbayerMay 4, 2023 06:14
@iambriccardo
iambriccardo marked this pull request as ready for review May 4, 2023 06:14
@iambriccardo
iambriccardo requested a review from a teamMay 4, 2023 06:14
Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +361 to +363
let sampling_config = serde_json::from_str::<SamplingConfig>((*sampling_config).as_str())?;
let root_sampling_config =
serde_json::from_str::<SamplingConfig>((*root_sampling_config).as_str())?;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to use the ? operator for curiosity and I don't understand why the compiler allows me to return a Result when the type is RelayStr.

Comment threadCHANGELOG.md Outdated
- Scrub sensitive keys (`passwd`, `token`, ...) in Replay recording data. ([#2034](https://github.com/getsentry/relay/pull/2034))
- Add document_uri to csp filter. ([#2059](https://github.com/getsentry/relay/pull/2059))
- Store `geo.subdivision` of the end user location. ([#2058](https://github.com/getsentry/relay/pull/2058))
- Add new FFI function for running dynamic sampling. ([#2091](https://github.com/getsentry/relay/pull/2091))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this to py/CHANGELOG.md

raise ValueError(error)


def run_dynamic_sampling(sampling_config, root_sampling_config, dsc, event):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we take an entire envelope as interface, instead? In Relay's pipeline, DS also reads information from other envelope headers.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to keep it stupid simple for now, in case we want, we can extend it to have an envelope as well.

Comment threadpy/sentry_relay/processing.py Outdated
Comment on lines +277 to +287
return json.loads(
decode_str(
rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
)
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add free=True to decode_str, since the owned string returned by FFI needs to be released. You can make this more readable like so:

Suggested change
returnjson.loads(
decode_str(
rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
)
)
result_json=rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
returnjson.loads(decode_str(result_json, free=True))

assert str(e.value) == 'json atom at path ".foobar" is missing from rhs'


def test_run_dynamic_sampling_with_valid_params_and_match():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are quite elaborate and will have to change every time we change something about sampling internals, particularly because they check the contents of the returned rules. Should we instead make more general checks, such as assert "merged_sampling_configs" in result and leave the rest to the DS unit tests in Rust?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a very good idea yes!

Comment threadrelay-cabi/src/processing.rs Outdated
use std::os::raw::c_char;
use std::slice;

use crate::core::{RelayBuf, RelayStr};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please order imports according to the style guide. This concerns the chrono and crate imports.

Comment threadrelay-cabi/src/processing.rs Outdated
serde_json::from_str::<SamplingConfig>((*root_sampling_config).as_str())?;
// We can optionally accept a dsc and event.
let dsc = serde_json::from_str::<DynamicSamplingContext>((*dsc).as_str());
let event = serde_json::from_str::<EphemeralEvent>((*event).as_str());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of parsing some synthetic EphemeralEvent, you should just load an actual Annotated<Event> directly:

Suggested change
let event = serde_json::from_str::<EphemeralEvent>((*event).as_str());
let event = Annotated::<Event>::from_json((*event).as_str())?;
let event = event.value().ok_or(<some error>)?;

Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +356 to +359
sampling_config: *const RelayStr,
root_sampling_config: *const RelayStr,
dsc: *const RelayStr,
event: *const RelayStr,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can pass all of these as references and then don't have to worry about dereferencing the pointer below. This is something we've not done consistently in the codebase, but we should move towards:

Suggested change
sampling_config:*constRelayStr,
root_sampling_config:*constRelayStr,
dsc:*constRelayStr,
event:*constRelayStr,
sampling_config:&RelayStr,
root_sampling_config:&RelayStr,
dsc:&RelayStr,
event:&RelayStr,

@iambriccardo
iambriccardo requested a review from jan-auerMay 5, 2023 08:31
Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +6 to +7
use anyhow::Context;
use chrono::Utc;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move these two imports to the next import group (above once_cell).

@iambriccardo
iambriccardo merged commit 6e5bab1 into masterMay 8, 2023
@iambriccardo
iambriccardo deleted the riccardo/feat/add-sampling-to-relay-server branch May 8, 2023 08:42
jan-auer added a commit that referenced this pull request May 9, 2023
* master: (178 commits)
ref(crons): Allow `_` in monitor slugs (#2100)
fix(span-metrics): Scrub subdomains in metric tags (#2103)
feat(normalization): Scrub span description URLs (#2095)
feat(dynamic-sampling): Add possibility to run dynamic sampling from `sentry-relay` (#2091)
ref(dynamic-config): Remove transaction metrics allowlist from Sentry (#2092)
feat(protocol): Support old effective-directory format (#2048)
ref(spans): Add more tags to span metrics (#2090)
fix(server): Support HTTP half-close connections (#2089)
ref(spans): Use transactions namespace with `span` prefix (#2087)
ref(spans): Update span metrics feature flag name (#2086)
feat(metrics): Extract more metrics from spans (#2080)
build: Bump tempfile to remove flagged dependency (#2085)
feat(filter): Add document_uri csp filter (#2059)
build: Use jemalloc on Linux (#2084)
ci(gha): add debugging for "Couldn'\''t write tracker file" issue (#2081)
feat(crons): Pass-through minimal `sdk` field (#2073)
fix(quota): Parse large limits (#2079)
instr(server): More details on unexpected envelope drop (#2077)
fix(ci): Skip flaky integration test (#2076)
feat(dynamic-sampling): Add support for `trace.replay_id` in matching rules (#2070)
...
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@iambriccardo@jan-auer
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relay - #2091

Merged
iambriccardo merged 16 commits into
masterfrom
riccardo/feat/add-sampling-to-relay-server
May 8, 2023
Merged

feat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relay#2091
iambriccardo merged 16 commits into
masterfrom
riccardo/feat/add-sampling-to-relay-server

Conversation

@iambriccardo

@iambriccardoiambriccardo commented May 3, 2023

Copy link
Copy Markdown
Contributor

This PR adds a new function to sentry-relay called run_dynamic_sampling which will run dynamic sampling on a two SamplingConfigs.

@iambriccardoiambriccardo changed the title feat(dynamic-sampling): Add possibility to run dynamic sampling fromfeat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relayMay 3, 2023
@iambriccardo
iambriccardo requested a review from jjbayerMay 4, 2023 06:14
@iambriccardo
iambriccardo marked this pull request as ready for review May 4, 2023 06:14
@iambriccardo
iambriccardo requested a review from a teamMay 4, 2023 06:14
Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +361 to +363
let sampling_config = serde_json::from_str::<SamplingConfig>((*sampling_config).as_str())?;
let root_sampling_config =
serde_json::from_str::<SamplingConfig>((*root_sampling_config).as_str())?;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to use the ? operator for curiosity and I don't understand why the compiler allows me to return a Result when the type is RelayStr.

Comment threadCHANGELOG.md Outdated
- Scrub sensitive keys (`passwd`, `token`, ...) in Replay recording data. ([#2034](https://github.com/getsentry/relay/pull/2034))
- Add document_uri to csp filter. ([#2059](https://github.com/getsentry/relay/pull/2059))
- Store `geo.subdivision` of the end user location. ([#2058](https://github.com/getsentry/relay/pull/2058))
- Add new FFI function for running dynamic sampling. ([#2091](https://github.com/getsentry/relay/pull/2091))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this to py/CHANGELOG.md

raise ValueError(error)


def run_dynamic_sampling(sampling_config, root_sampling_config, dsc, event):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we take an entire envelope as interface, instead? In Relay's pipeline, DS also reads information from other envelope headers.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to keep it stupid simple for now, in case we want, we can extend it to have an envelope as well.

Comment threadpy/sentry_relay/processing.py Outdated
Comment on lines +277 to +287
return json.loads(
decode_str(
rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
)
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add free=True to decode_str, since the owned string returned by FFI needs to be released. You can make this more readable like so:

Suggested change
returnjson.loads(
decode_str(
rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
)
)
result_json=rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
returnjson.loads(decode_str(result_json, free=True))

assert str(e.value) == 'json atom at path ".foobar" is missing from rhs'


def test_run_dynamic_sampling_with_valid_params_and_match():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are quite elaborate and will have to change every time we change something about sampling internals, particularly because they check the contents of the returned rules. Should we instead make more general checks, such as assert "merged_sampling_configs" in result and leave the rest to the DS unit tests in Rust?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a very good idea yes!

Comment threadrelay-cabi/src/processing.rs Outdated
use std::os::raw::c_char;
use std::slice;

use crate::core::{RelayBuf, RelayStr};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please order imports according to the style guide. This concerns the chrono and crate imports.

Comment threadrelay-cabi/src/processing.rs Outdated
serde_json::from_str::<SamplingConfig>((*root_sampling_config).as_str())?;
// We can optionally accept a dsc and event.
let dsc = serde_json::from_str::<DynamicSamplingContext>((*dsc).as_str());
let event = serde_json::from_str::<EphemeralEvent>((*event).as_str());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of parsing some synthetic EphemeralEvent, you should just load an actual Annotated<Event> directly:

Suggested change
let event = serde_json::from_str::<EphemeralEvent>((*event).as_str());
let event = Annotated::<Event>::from_json((*event).as_str())?;
let event = event.value().ok_or(<some error>)?;

Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +356 to +359
sampling_config: *const RelayStr,
root_sampling_config: *const RelayStr,
dsc: *const RelayStr,
event: *const RelayStr,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can pass all of these as references and then don't have to worry about dereferencing the pointer below. This is something we've not done consistently in the codebase, but we should move towards:

Suggested change
sampling_config:*constRelayStr,
root_sampling_config:*constRelayStr,
dsc:*constRelayStr,
event:*constRelayStr,
sampling_config:&RelayStr,
root_sampling_config:&RelayStr,
dsc:&RelayStr,
event:&RelayStr,

@iambriccardo
iambriccardo requested a review from jan-auerMay 5, 2023 08:31
Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +6 to +7
use anyhow::Context;
use chrono::Utc;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move these two imports to the next import group (above once_cell).

@iambriccardo
iambriccardo merged commit 6e5bab1 into masterMay 8, 2023
@iambriccardo
iambriccardo deleted the riccardo/feat/add-sampling-to-relay-server branch May 8, 2023 08:42
jan-auer added a commit that referenced this pull request May 9, 2023
* master: (178 commits)
ref(crons): Allow `_` in monitor slugs (#2100)
fix(span-metrics): Scrub subdomains in metric tags (#2103)
feat(normalization): Scrub span description URLs (#2095)
feat(dynamic-sampling): Add possibility to run dynamic sampling from `sentry-relay` (#2091)
ref(dynamic-config): Remove transaction metrics allowlist from Sentry (#2092)
feat(protocol): Support old effective-directory format (#2048)
ref(spans): Add more tags to span metrics (#2090)
fix(server): Support HTTP half-close connections (#2089)
ref(spans): Use transactions namespace with `span` prefix (#2087)
ref(spans): Update span metrics feature flag name (#2086)
feat(metrics): Extract more metrics from spans (#2080)
build: Bump tempfile to remove flagged dependency (#2085)
feat(filter): Add document_uri csp filter (#2059)
build: Use jemalloc on Linux (#2084)
ci(gha): add debugging for "Couldn'\''t write tracker file" issue (#2081)
feat(crons): Pass-through minimal `sdk` field (#2073)
fix(quota): Parse large limits (#2079)
instr(server): More details on unexpected envelope drop (#2077)
fix(ci): Skip flaky integration test (#2076)
feat(dynamic-sampling): Add support for `trace.replay_id` in matching rules (#2070)
...
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@iambriccardo@jan-auer
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relay - #2091

Merged
iambriccardo merged 16 commits into
masterfrom
riccardo/feat/add-sampling-to-relay-server
May 8, 2023
Merged

feat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relay#2091
iambriccardo merged 16 commits into
masterfrom
riccardo/feat/add-sampling-to-relay-server

Conversation

@iambriccardo

@iambriccardoiambriccardo commented May 3, 2023

Copy link
Copy Markdown
Contributor

This PR adds a new function to sentry-relay called run_dynamic_sampling which will run dynamic sampling on a two SamplingConfigs.

@iambriccardoiambriccardo changed the title feat(dynamic-sampling): Add possibility to run dynamic sampling fromfeat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relayMay 3, 2023
@iambriccardo
iambriccardo requested a review from jjbayerMay 4, 2023 06:14
@iambriccardo
iambriccardo marked this pull request as ready for review May 4, 2023 06:14
@iambriccardo
iambriccardo requested a review from a teamMay 4, 2023 06:14
Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +361 to +363
let sampling_config = serde_json::from_str::<SamplingConfig>((*sampling_config).as_str())?;
let root_sampling_config =
serde_json::from_str::<SamplingConfig>((*root_sampling_config).as_str())?;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to use the ? operator for curiosity and I don't understand why the compiler allows me to return a Result when the type is RelayStr.

Comment threadCHANGELOG.md Outdated
- Scrub sensitive keys (`passwd`, `token`, ...) in Replay recording data. ([#2034](https://github.com/getsentry/relay/pull/2034))
- Add document_uri to csp filter. ([#2059](https://github.com/getsentry/relay/pull/2059))
- Store `geo.subdivision` of the end user location. ([#2058](https://github.com/getsentry/relay/pull/2058))
- Add new FFI function for running dynamic sampling. ([#2091](https://github.com/getsentry/relay/pull/2091))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this to py/CHANGELOG.md

raise ValueError(error)


def run_dynamic_sampling(sampling_config, root_sampling_config, dsc, event):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we take an entire envelope as interface, instead? In Relay's pipeline, DS also reads information from other envelope headers.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to keep it stupid simple for now, in case we want, we can extend it to have an envelope as well.

Comment threadpy/sentry_relay/processing.py Outdated
Comment on lines +277 to +287
return json.loads(
decode_str(
rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
)
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add free=True to decode_str, since the owned string returned by FFI needs to be released. You can make this more readable like so:

Suggested change
returnjson.loads(
decode_str(
rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
)
)
result_json=rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
returnjson.loads(decode_str(result_json, free=True))

assert str(e.value) == 'json atom at path ".foobar" is missing from rhs'


def test_run_dynamic_sampling_with_valid_params_and_match():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are quite elaborate and will have to change every time we change something about sampling internals, particularly because they check the contents of the returned rules. Should we instead make more general checks, such as assert "merged_sampling_configs" in result and leave the rest to the DS unit tests in Rust?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a very good idea yes!

Comment threadrelay-cabi/src/processing.rs Outdated
use std::os::raw::c_char;
use std::slice;

use crate::core::{RelayBuf, RelayStr};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please order imports according to the style guide. This concerns the chrono and crate imports.

Comment threadrelay-cabi/src/processing.rs Outdated
serde_json::from_str::<SamplingConfig>((*root_sampling_config).as_str())?;
// We can optionally accept a dsc and event.
let dsc = serde_json::from_str::<DynamicSamplingContext>((*dsc).as_str());
let event = serde_json::from_str::<EphemeralEvent>((*event).as_str());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of parsing some synthetic EphemeralEvent, you should just load an actual Annotated<Event> directly:

Suggested change
let event = serde_json::from_str::<EphemeralEvent>((*event).as_str());
let event = Annotated::<Event>::from_json((*event).as_str())?;
let event = event.value().ok_or(<some error>)?;

Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +356 to +359
sampling_config: *const RelayStr,
root_sampling_config: *const RelayStr,
dsc: *const RelayStr,
event: *const RelayStr,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can pass all of these as references and then don't have to worry about dereferencing the pointer below. This is something we've not done consistently in the codebase, but we should move towards:

Suggested change
sampling_config:*constRelayStr,
root_sampling_config:*constRelayStr,
dsc:*constRelayStr,
event:*constRelayStr,
sampling_config:&RelayStr,
root_sampling_config:&RelayStr,
dsc:&RelayStr,
event:&RelayStr,

@iambriccardo
iambriccardo requested a review from jan-auerMay 5, 2023 08:31
Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +6 to +7
use anyhow::Context;
use chrono::Utc;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move these two imports to the next import group (above once_cell).

@iambriccardo
iambriccardo merged commit 6e5bab1 into masterMay 8, 2023
@iambriccardo
iambriccardo deleted the riccardo/feat/add-sampling-to-relay-server branch May 8, 2023 08:42
jan-auer added a commit that referenced this pull request May 9, 2023
* master: (178 commits)
ref(crons): Allow `_` in monitor slugs (#2100)
fix(span-metrics): Scrub subdomains in metric tags (#2103)
feat(normalization): Scrub span description URLs (#2095)
feat(dynamic-sampling): Add possibility to run dynamic sampling from `sentry-relay` (#2091)
ref(dynamic-config): Remove transaction metrics allowlist from Sentry (#2092)
feat(protocol): Support old effective-directory format (#2048)
ref(spans): Add more tags to span metrics (#2090)
fix(server): Support HTTP half-close connections (#2089)
ref(spans): Use transactions namespace with `span` prefix (#2087)
ref(spans): Update span metrics feature flag name (#2086)
feat(metrics): Extract more metrics from spans (#2080)
build: Bump tempfile to remove flagged dependency (#2085)
feat(filter): Add document_uri csp filter (#2059)
build: Use jemalloc on Linux (#2084)
ci(gha): add debugging for "Couldn'\''t write tracker file" issue (#2081)
feat(crons): Pass-through minimal `sdk` field (#2073)
fix(quota): Parse large limits (#2079)
instr(server): More details on unexpected envelope drop (#2077)
fix(ci): Skip flaky integration test (#2076)
feat(dynamic-sampling): Add support for `trace.replay_id` in matching rules (#2070)
...
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@iambriccardo@jan-auer
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relay - #2091

Merged
iambriccardo merged 16 commits into
masterfrom
riccardo/feat/add-sampling-to-relay-server
May 8, 2023
Merged

feat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relay#2091
iambriccardo merged 16 commits into
masterfrom
riccardo/feat/add-sampling-to-relay-server

Conversation

@iambriccardo

@iambriccardoiambriccardo commented May 3, 2023

Copy link
Copy Markdown
Contributor

This PR adds a new function to sentry-relay called run_dynamic_sampling which will run dynamic sampling on a two SamplingConfigs.

@iambriccardoiambriccardo changed the title feat(dynamic-sampling): Add possibility to run dynamic sampling fromfeat(dynamic-sampling): Add possibility to run dynamic sampling from sentry-relayMay 3, 2023
@iambriccardo
iambriccardo requested a review from jjbayerMay 4, 2023 06:14
@iambriccardo
iambriccardo marked this pull request as ready for review May 4, 2023 06:14
@iambriccardo
iambriccardo requested a review from a teamMay 4, 2023 06:14
Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +361 to +363
let sampling_config = serde_json::from_str::<SamplingConfig>((*sampling_config).as_str())?;
let root_sampling_config =
serde_json::from_str::<SamplingConfig>((*root_sampling_config).as_str())?;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to use the ? operator for curiosity and I don't understand why the compiler allows me to return a Result when the type is RelayStr.

Comment threadCHANGELOG.md Outdated
- Scrub sensitive keys (`passwd`, `token`, ...) in Replay recording data. ([#2034](https://github.com/getsentry/relay/pull/2034))
- Add document_uri to csp filter. ([#2059](https://github.com/getsentry/relay/pull/2059))
- Store `geo.subdivision` of the end user location. ([#2058](https://github.com/getsentry/relay/pull/2058))
- Add new FFI function for running dynamic sampling. ([#2091](https://github.com/getsentry/relay/pull/2091))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this to py/CHANGELOG.md

raise ValueError(error)


def run_dynamic_sampling(sampling_config, root_sampling_config, dsc, event):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we take an entire envelope as interface, instead? In Relay's pipeline, DS also reads information from other envelope headers.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to keep it stupid simple for now, in case we want, we can extend it to have an envelope as well.

Comment threadpy/sentry_relay/processing.py Outdated
Comment on lines +277 to +287
return json.loads(
decode_str(
rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
)
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add free=True to decode_str, since the owned string returned by FFI needs to be released. You can make this more readable like so:

Suggested change
returnjson.loads(
decode_str(
rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
)
)
result_json=rustcall(
lib.run_dynamic_sampling,
encode_str(sampling_config),
encode_str(root_sampling_config),
encode_str(dsc),
encode_str(event),
)
returnjson.loads(decode_str(result_json, free=True))

assert str(e.value) == 'json atom at path ".foobar" is missing from rhs'


def test_run_dynamic_sampling_with_valid_params_and_match():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are quite elaborate and will have to change every time we change something about sampling internals, particularly because they check the contents of the returned rules. Should we instead make more general checks, such as assert "merged_sampling_configs" in result and leave the rest to the DS unit tests in Rust?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a very good idea yes!

Comment threadrelay-cabi/src/processing.rs Outdated
use std::os::raw::c_char;
use std::slice;

use crate::core::{RelayBuf, RelayStr};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please order imports according to the style guide. This concerns the chrono and crate imports.

Comment threadrelay-cabi/src/processing.rs Outdated
serde_json::from_str::<SamplingConfig>((*root_sampling_config).as_str())?;
// We can optionally accept a dsc and event.
let dsc = serde_json::from_str::<DynamicSamplingContext>((*dsc).as_str());
let event = serde_json::from_str::<EphemeralEvent>((*event).as_str());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of parsing some synthetic EphemeralEvent, you should just load an actual Annotated<Event> directly:

Suggested change
let event = serde_json::from_str::<EphemeralEvent>((*event).as_str());
let event = Annotated::<Event>::from_json((*event).as_str())?;
let event = event.value().ok_or(<some error>)?;

Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +356 to +359
sampling_config: *const RelayStr,
root_sampling_config: *const RelayStr,
dsc: *const RelayStr,
event: *const RelayStr,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can pass all of these as references and then don't have to worry about dereferencing the pointer below. This is something we've not done consistently in the codebase, but we should move towards:

Suggested change
sampling_config:*constRelayStr,
root_sampling_config:*constRelayStr,
dsc:*constRelayStr,
event:*constRelayStr,
sampling_config:&RelayStr,
root_sampling_config:&RelayStr,
dsc:&RelayStr,
event:&RelayStr,

@iambriccardo
iambriccardo requested a review from jan-auerMay 5, 2023 08:31
Comment threadrelay-cabi/src/processing.rs Outdated
Comment on lines +6 to +7
use anyhow::Context;
use chrono::Utc;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move these two imports to the next import group (above once_cell).

@iambriccardo
iambriccardo merged commit 6e5bab1 into masterMay 8, 2023
@iambriccardo
iambriccardo deleted the riccardo/feat/add-sampling-to-relay-server branch May 8, 2023 08:42
jan-auer added a commit that referenced this pull request May 9, 2023
* master: (178 commits)
ref(crons): Allow `_` in monitor slugs (#2100)
fix(span-metrics): Scrub subdomains in metric tags (#2103)
feat(normalization): Scrub span description URLs (#2095)
feat(dynamic-sampling): Add possibility to run dynamic sampling from `sentry-relay` (#2091)
ref(dynamic-config): Remove transaction metrics allowlist from Sentry (#2092)
feat(protocol): Support old effective-directory format (#2048)
ref(spans): Add more tags to span metrics (#2090)
fix(server): Support HTTP half-close connections (#2089)
ref(spans): Use transactions namespace with `span` prefix (#2087)
ref(spans): Update span metrics feature flag name (#2086)
feat(metrics): Extract more metrics from spans (#2080)
build: Bump tempfile to remove flagged dependency (#2085)
feat(filter): Add document_uri csp filter (#2059)
build: Use jemalloc on Linux (#2084)
ci(gha): add debugging for "Couldn'\''t write tracker file" issue (#2081)
feat(crons): Pass-through minimal `sdk` field (#2073)
fix(quota): Parse large limits (#2079)
instr(server): More details on unexpected envelope drop (#2077)
fix(ci): Skip flaky integration test (#2076)
feat(dynamic-sampling): Add support for `trace.replay_id` in matching rules (#2070)
...
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@iambriccardo@jan-auer