feat(cloudflare): instrument scheduled handler - #13114

Merged
AbhiPrasad merged 3 commits into
developfrom
abhi-scheduled-handler
Aug 2, 2024
Merged

feat(cloudflare): instrument scheduled handler#13114
AbhiPrasad merged 3 commits into
developfrom
abhi-scheduled-handler

Conversation

@AbhiPrasad

Copy link
Copy Markdown
Contributor

resolves#13112

This PR adds instrumentation for the scheduled handler in cloudflare workers. This is used for cron triggers.

I elected to not do automatic cron instrumentation for now, this is tracked by #13113. Instead I added manual instrumentation docs to the README, this will get copied to the sentry docs eventually.

ref #12620

@AbhiPrasad
AbhiPrasad requested a review from a teamJuly 30, 2024 15:06
@AbhiPrasadAbhiPrasad self-assigned this Jul 30, 2024
@AbhiPrasad
AbhiPrasad requested review from mydea and nicohrubec and removed request for a teamJuly 30, 2024 15:06
@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch from 20adfb9 to 1482a37CompareJuly 30, 2024 15:52
@AbhiPrasad
AbhiPrasad marked this pull request as draft July 30, 2024 21:14
@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

Drafting this PR for the time being because #13123 refactors a lot of this code, so this PR needs to be updated.

Hence let's wait for that to get merged in first, and then look at this one in more detail.

@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch 3 times, most recently from 16ddfe8 to 6aa304fCompareJuly 31, 2024 15:56
@AbhiPrasad
AbhiPrasad marked this pull request as ready for review July 31, 2024 15:57
@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

This is now ready to review - I refactored this PR to pull in the refactors from #13123

attributes: {
'faas.cron': event.cron,
'faas.time': new Date(event.scheduledTime).toISOString(),
'faas.trigger': 'timer',

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.


addCloudResourceContext(isolationScope);

return startSpan(

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.

This duplication with the request handler is not ideal, but I'd rather refactor this later once I'm more confident in the API design of the withIsolationScope callback.

@nicohrubecnicohrubec left a comment

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.

looks good from my pov

handler.scheduled = new Proxy(handler.scheduled, {
apply(target, thisArg, args: Parameters<ExportedHandlerScheduledHandler<ExtractEnv<E>>>) {
const [event, env, context] = args;
return withIsolationScope(isolationScope => {

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.

just for my understanding, what do we need this isolation scope for here?

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.

To make sure scope bleed doesn't happen. If you define both a scheduled handler and a fetch handler, there's a chance that both happen at the same time, so we need to isolate accordingly.

captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });
throw e;
} finally {
context.waitUntil(flush(2000));

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.

why do we need to wait here?

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.

waitUntil will execute keep the serverless function alive until we flush out all sentry requests, but it will ensure that this happens after a response is sent. Therefore flushing to sentry does not block sending a response back to whatever sent the request to the cloudflare worker.

@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch from a0a3666 to 459be04CompareAugust 2, 2024 14:25
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.

Instrument Scheduled Handler

2 participants

@AbhiPrasad@nicohrubec
, '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(cloudflare): instrument scheduled handler - #13114

Merged
AbhiPrasad merged 3 commits into
developfrom
abhi-scheduled-handler
Aug 2, 2024
Merged

feat(cloudflare): instrument scheduled handler#13114
AbhiPrasad merged 3 commits into
developfrom
abhi-scheduled-handler

Conversation

@AbhiPrasad

Copy link
Copy Markdown
Contributor

resolves#13112

This PR adds instrumentation for the scheduled handler in cloudflare workers. This is used for cron triggers.

I elected to not do automatic cron instrumentation for now, this is tracked by #13113. Instead I added manual instrumentation docs to the README, this will get copied to the sentry docs eventually.

ref #12620

@AbhiPrasad
AbhiPrasad requested a review from a teamJuly 30, 2024 15:06
@AbhiPrasadAbhiPrasad self-assigned this Jul 30, 2024
@AbhiPrasad
AbhiPrasad requested review from mydea and nicohrubec and removed request for a teamJuly 30, 2024 15:06
@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch from 20adfb9 to 1482a37CompareJuly 30, 2024 15:52
@AbhiPrasad
AbhiPrasad marked this pull request as draft July 30, 2024 21:14
@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

Drafting this PR for the time being because #13123 refactors a lot of this code, so this PR needs to be updated.

Hence let's wait for that to get merged in first, and then look at this one in more detail.

@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch 3 times, most recently from 16ddfe8 to 6aa304fCompareJuly 31, 2024 15:56
@AbhiPrasad
AbhiPrasad marked this pull request as ready for review July 31, 2024 15:57
@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

This is now ready to review - I refactored this PR to pull in the refactors from #13123

attributes: {
'faas.cron': event.cron,
'faas.time': new Date(event.scheduledTime).toISOString(),
'faas.trigger': 'timer',

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.


addCloudResourceContext(isolationScope);

return startSpan(

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.

This duplication with the request handler is not ideal, but I'd rather refactor this later once I'm more confident in the API design of the withIsolationScope callback.

@nicohrubecnicohrubec left a comment

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.

looks good from my pov

handler.scheduled = new Proxy(handler.scheduled, {
apply(target, thisArg, args: Parameters<ExportedHandlerScheduledHandler<ExtractEnv<E>>>) {
const [event, env, context] = args;
return withIsolationScope(isolationScope => {

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.

just for my understanding, what do we need this isolation scope for here?

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.

To make sure scope bleed doesn't happen. If you define both a scheduled handler and a fetch handler, there's a chance that both happen at the same time, so we need to isolate accordingly.

captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });
throw e;
} finally {
context.waitUntil(flush(2000));

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.

why do we need to wait here?

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.

waitUntil will execute keep the serverless function alive until we flush out all sentry requests, but it will ensure that this happens after a response is sent. Therefore flushing to sentry does not block sending a response back to whatever sent the request to the cloudflare worker.

@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch from a0a3666 to 459be04CompareAugust 2, 2024 14:25
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.

Instrument Scheduled Handler

2 participants

@AbhiPrasad@nicohrubec
, '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(cloudflare): instrument scheduled handler - #13114

Merged
AbhiPrasad merged 3 commits into
developfrom
abhi-scheduled-handler
Aug 2, 2024
Merged

feat(cloudflare): instrument scheduled handler#13114
AbhiPrasad merged 3 commits into
developfrom
abhi-scheduled-handler

Conversation

@AbhiPrasad

Copy link
Copy Markdown
Contributor

resolves#13112

This PR adds instrumentation for the scheduled handler in cloudflare workers. This is used for cron triggers.

I elected to not do automatic cron instrumentation for now, this is tracked by #13113. Instead I added manual instrumentation docs to the README, this will get copied to the sentry docs eventually.

ref #12620

@AbhiPrasad
AbhiPrasad requested a review from a teamJuly 30, 2024 15:06
@AbhiPrasadAbhiPrasad self-assigned this Jul 30, 2024
@AbhiPrasad
AbhiPrasad requested review from mydea and nicohrubec and removed request for a teamJuly 30, 2024 15:06
@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch from 20adfb9 to 1482a37CompareJuly 30, 2024 15:52
@AbhiPrasad
AbhiPrasad marked this pull request as draft July 30, 2024 21:14
@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

Drafting this PR for the time being because #13123 refactors a lot of this code, so this PR needs to be updated.

Hence let's wait for that to get merged in first, and then look at this one in more detail.

@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch 3 times, most recently from 16ddfe8 to 6aa304fCompareJuly 31, 2024 15:56
@AbhiPrasad
AbhiPrasad marked this pull request as ready for review July 31, 2024 15:57
@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

This is now ready to review - I refactored this PR to pull in the refactors from #13123

attributes: {
'faas.cron': event.cron,
'faas.time': new Date(event.scheduledTime).toISOString(),
'faas.trigger': 'timer',

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.


addCloudResourceContext(isolationScope);

return startSpan(

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.

This duplication with the request handler is not ideal, but I'd rather refactor this later once I'm more confident in the API design of the withIsolationScope callback.

@nicohrubecnicohrubec left a comment

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.

looks good from my pov

handler.scheduled = new Proxy(handler.scheduled, {
apply(target, thisArg, args: Parameters<ExportedHandlerScheduledHandler<ExtractEnv<E>>>) {
const [event, env, context] = args;
return withIsolationScope(isolationScope => {

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.

just for my understanding, what do we need this isolation scope for here?

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.

To make sure scope bleed doesn't happen. If you define both a scheduled handler and a fetch handler, there's a chance that both happen at the same time, so we need to isolate accordingly.

captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });
throw e;
} finally {
context.waitUntil(flush(2000));

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.

why do we need to wait here?

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.

waitUntil will execute keep the serverless function alive until we flush out all sentry requests, but it will ensure that this happens after a response is sent. Therefore flushing to sentry does not block sending a response back to whatever sent the request to the cloudflare worker.

@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch from a0a3666 to 459be04CompareAugust 2, 2024 14:25
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.

Instrument Scheduled Handler

2 participants

@AbhiPrasad@nicohrubec
, '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(cloudflare): instrument scheduled handler - #13114

Merged
AbhiPrasad merged 3 commits into
developfrom
abhi-scheduled-handler
Aug 2, 2024
Merged

feat(cloudflare): instrument scheduled handler#13114
AbhiPrasad merged 3 commits into
developfrom
abhi-scheduled-handler

Conversation

@AbhiPrasad

Copy link
Copy Markdown
Contributor

resolves#13112

This PR adds instrumentation for the scheduled handler in cloudflare workers. This is used for cron triggers.

I elected to not do automatic cron instrumentation for now, this is tracked by #13113. Instead I added manual instrumentation docs to the README, this will get copied to the sentry docs eventually.

ref #12620

@AbhiPrasad
AbhiPrasad requested a review from a teamJuly 30, 2024 15:06
@AbhiPrasadAbhiPrasad self-assigned this Jul 30, 2024
@AbhiPrasad
AbhiPrasad requested review from mydea and nicohrubec and removed request for a teamJuly 30, 2024 15:06
@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch from 20adfb9 to 1482a37CompareJuly 30, 2024 15:52
@AbhiPrasad
AbhiPrasad marked this pull request as draft July 30, 2024 21:14
@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

Drafting this PR for the time being because #13123 refactors a lot of this code, so this PR needs to be updated.

Hence let's wait for that to get merged in first, and then look at this one in more detail.

@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch 3 times, most recently from 16ddfe8 to 6aa304fCompareJuly 31, 2024 15:56
@AbhiPrasad
AbhiPrasad marked this pull request as ready for review July 31, 2024 15:57
@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

This is now ready to review - I refactored this PR to pull in the refactors from #13123

attributes: {
'faas.cron': event.cron,
'faas.time': new Date(event.scheduledTime).toISOString(),
'faas.trigger': 'timer',

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.


addCloudResourceContext(isolationScope);

return startSpan(

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.

This duplication with the request handler is not ideal, but I'd rather refactor this later once I'm more confident in the API design of the withIsolationScope callback.

@nicohrubecnicohrubec left a comment

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.

looks good from my pov

handler.scheduled = new Proxy(handler.scheduled, {
apply(target, thisArg, args: Parameters<ExportedHandlerScheduledHandler<ExtractEnv<E>>>) {
const [event, env, context] = args;
return withIsolationScope(isolationScope => {

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.

just for my understanding, what do we need this isolation scope for here?

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.

To make sure scope bleed doesn't happen. If you define both a scheduled handler and a fetch handler, there's a chance that both happen at the same time, so we need to isolate accordingly.

captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });
throw e;
} finally {
context.waitUntil(flush(2000));

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.

why do we need to wait here?

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.

waitUntil will execute keep the serverless function alive until we flush out all sentry requests, but it will ensure that this happens after a response is sent. Therefore flushing to sentry does not block sending a response back to whatever sent the request to the cloudflare worker.

@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch from a0a3666 to 459be04CompareAugust 2, 2024 14:25
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.

Instrument Scheduled Handler

2 participants

@AbhiPrasad@nicohrubec
, '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(cloudflare): instrument scheduled handler - #13114

Merged
AbhiPrasad merged 3 commits into
developfrom
abhi-scheduled-handler
Aug 2, 2024
Merged

feat(cloudflare): instrument scheduled handler#13114
AbhiPrasad merged 3 commits into
developfrom
abhi-scheduled-handler

Conversation

@AbhiPrasad

Copy link
Copy Markdown
Contributor

resolves#13112

This PR adds instrumentation for the scheduled handler in cloudflare workers. This is used for cron triggers.

I elected to not do automatic cron instrumentation for now, this is tracked by #13113. Instead I added manual instrumentation docs to the README, this will get copied to the sentry docs eventually.

ref #12620

@AbhiPrasad
AbhiPrasad requested a review from a teamJuly 30, 2024 15:06
@AbhiPrasadAbhiPrasad self-assigned this Jul 30, 2024
@AbhiPrasad
AbhiPrasad requested review from mydea and nicohrubec and removed request for a teamJuly 30, 2024 15:06
@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch from 20adfb9 to 1482a37CompareJuly 30, 2024 15:52
@AbhiPrasad
AbhiPrasad marked this pull request as draft July 30, 2024 21:14
@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

Drafting this PR for the time being because #13123 refactors a lot of this code, so this PR needs to be updated.

Hence let's wait for that to get merged in first, and then look at this one in more detail.

@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch 3 times, most recently from 16ddfe8 to 6aa304fCompareJuly 31, 2024 15:56
@AbhiPrasad
AbhiPrasad marked this pull request as ready for review July 31, 2024 15:57
@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

This is now ready to review - I refactored this PR to pull in the refactors from #13123

attributes: {
'faas.cron': event.cron,
'faas.time': new Date(event.scheduledTime).toISOString(),
'faas.trigger': 'timer',

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.


addCloudResourceContext(isolationScope);

return startSpan(

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.

This duplication with the request handler is not ideal, but I'd rather refactor this later once I'm more confident in the API design of the withIsolationScope callback.

@nicohrubecnicohrubec left a comment

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.

looks good from my pov

handler.scheduled = new Proxy(handler.scheduled, {
apply(target, thisArg, args: Parameters<ExportedHandlerScheduledHandler<ExtractEnv<E>>>) {
const [event, env, context] = args;
return withIsolationScope(isolationScope => {

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.

just for my understanding, what do we need this isolation scope for here?

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.

To make sure scope bleed doesn't happen. If you define both a scheduled handler and a fetch handler, there's a chance that both happen at the same time, so we need to isolate accordingly.

captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });
throw e;
} finally {
context.waitUntil(flush(2000));

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.

why do we need to wait here?

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.

waitUntil will execute keep the serverless function alive until we flush out all sentry requests, but it will ensure that this happens after a response is sent. Therefore flushing to sentry does not block sending a response back to whatever sent the request to the cloudflare worker.

@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch from a0a3666 to 459be04CompareAugust 2, 2024 14:25
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.

Instrument Scheduled Handler

2 participants

@AbhiPrasad@nicohrubec
, '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(cloudflare): instrument scheduled handler - #13114

Merged
AbhiPrasad merged 3 commits into
developfrom
abhi-scheduled-handler
Aug 2, 2024
Merged

feat(cloudflare): instrument scheduled handler#13114
AbhiPrasad merged 3 commits into
developfrom
abhi-scheduled-handler

Conversation

@AbhiPrasad

Copy link
Copy Markdown
Contributor

resolves#13112

This PR adds instrumentation for the scheduled handler in cloudflare workers. This is used for cron triggers.

I elected to not do automatic cron instrumentation for now, this is tracked by #13113. Instead I added manual instrumentation docs to the README, this will get copied to the sentry docs eventually.

ref #12620

@AbhiPrasad
AbhiPrasad requested a review from a teamJuly 30, 2024 15:06
@AbhiPrasadAbhiPrasad self-assigned this Jul 30, 2024
@AbhiPrasad
AbhiPrasad requested review from mydea and nicohrubec and removed request for a teamJuly 30, 2024 15:06
@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch from 20adfb9 to 1482a37CompareJuly 30, 2024 15:52
@AbhiPrasad
AbhiPrasad marked this pull request as draft July 30, 2024 21:14
@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

Drafting this PR for the time being because #13123 refactors a lot of this code, so this PR needs to be updated.

Hence let's wait for that to get merged in first, and then look at this one in more detail.

@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch 3 times, most recently from 16ddfe8 to 6aa304fCompareJuly 31, 2024 15:56
@AbhiPrasad
AbhiPrasad marked this pull request as ready for review July 31, 2024 15:57
@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

This is now ready to review - I refactored this PR to pull in the refactors from #13123

attributes: {
'faas.cron': event.cron,
'faas.time': new Date(event.scheduledTime).toISOString(),
'faas.trigger': 'timer',

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.


addCloudResourceContext(isolationScope);

return startSpan(

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.

This duplication with the request handler is not ideal, but I'd rather refactor this later once I'm more confident in the API design of the withIsolationScope callback.

@nicohrubecnicohrubec left a comment

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.

looks good from my pov

handler.scheduled = new Proxy(handler.scheduled, {
apply(target, thisArg, args: Parameters<ExportedHandlerScheduledHandler<ExtractEnv<E>>>) {
const [event, env, context] = args;
return withIsolationScope(isolationScope => {

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.

just for my understanding, what do we need this isolation scope for here?

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.

To make sure scope bleed doesn't happen. If you define both a scheduled handler and a fetch handler, there's a chance that both happen at the same time, so we need to isolate accordingly.

captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });
throw e;
} finally {
context.waitUntil(flush(2000));

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.

why do we need to wait here?

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.

waitUntil will execute keep the serverless function alive until we flush out all sentry requests, but it will ensure that this happens after a response is sent. Therefore flushing to sentry does not block sending a response back to whatever sent the request to the cloudflare worker.

@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch from a0a3666 to 459be04CompareAugust 2, 2024 14:25
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.

Instrument Scheduled Handler

2 participants

@AbhiPrasad@nicohrubec
, '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(cloudflare): instrument scheduled handler - #13114

Merged
AbhiPrasad merged 3 commits into
developfrom
abhi-scheduled-handler
Aug 2, 2024
Merged

feat(cloudflare): instrument scheduled handler#13114
AbhiPrasad merged 3 commits into
developfrom
abhi-scheduled-handler

Conversation

@AbhiPrasad

Copy link
Copy Markdown
Contributor

resolves#13112

This PR adds instrumentation for the scheduled handler in cloudflare workers. This is used for cron triggers.

I elected to not do automatic cron instrumentation for now, this is tracked by #13113. Instead I added manual instrumentation docs to the README, this will get copied to the sentry docs eventually.

ref #12620

@AbhiPrasad
AbhiPrasad requested a review from a teamJuly 30, 2024 15:06
@AbhiPrasadAbhiPrasad self-assigned this Jul 30, 2024
@AbhiPrasad
AbhiPrasad requested review from mydea and nicohrubec and removed request for a teamJuly 30, 2024 15:06
@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch from 20adfb9 to 1482a37CompareJuly 30, 2024 15:52
@AbhiPrasad
AbhiPrasad marked this pull request as draft July 30, 2024 21:14
@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

Drafting this PR for the time being because #13123 refactors a lot of this code, so this PR needs to be updated.

Hence let's wait for that to get merged in first, and then look at this one in more detail.

@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch 3 times, most recently from 16ddfe8 to 6aa304fCompareJuly 31, 2024 15:56
@AbhiPrasad
AbhiPrasad marked this pull request as ready for review July 31, 2024 15:57
@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

This is now ready to review - I refactored this PR to pull in the refactors from #13123

attributes: {
'faas.cron': event.cron,
'faas.time': new Date(event.scheduledTime).toISOString(),
'faas.trigger': 'timer',

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.


addCloudResourceContext(isolationScope);

return startSpan(

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.

This duplication with the request handler is not ideal, but I'd rather refactor this later once I'm more confident in the API design of the withIsolationScope callback.

@nicohrubecnicohrubec left a comment

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.

looks good from my pov

handler.scheduled = new Proxy(handler.scheduled, {
apply(target, thisArg, args: Parameters<ExportedHandlerScheduledHandler<ExtractEnv<E>>>) {
const [event, env, context] = args;
return withIsolationScope(isolationScope => {

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.

just for my understanding, what do we need this isolation scope for here?

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.

To make sure scope bleed doesn't happen. If you define both a scheduled handler and a fetch handler, there's a chance that both happen at the same time, so we need to isolate accordingly.

captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });
throw e;
} finally {
context.waitUntil(flush(2000));

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.

why do we need to wait here?

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.

waitUntil will execute keep the serverless function alive until we flush out all sentry requests, but it will ensure that this happens after a response is sent. Therefore flushing to sentry does not block sending a response back to whatever sent the request to the cloudflare worker.

@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch from a0a3666 to 459be04CompareAugust 2, 2024 14:25
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.

Instrument Scheduled Handler

2 participants

@AbhiPrasad@nicohrubec
, '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(cloudflare): instrument scheduled handler - #13114

Merged
AbhiPrasad merged 3 commits into
developfrom
abhi-scheduled-handler
Aug 2, 2024
Merged

feat(cloudflare): instrument scheduled handler#13114
AbhiPrasad merged 3 commits into
developfrom
abhi-scheduled-handler

Conversation

@AbhiPrasad

Copy link
Copy Markdown
Contributor

resolves#13112

This PR adds instrumentation for the scheduled handler in cloudflare workers. This is used for cron triggers.

I elected to not do automatic cron instrumentation for now, this is tracked by #13113. Instead I added manual instrumentation docs to the README, this will get copied to the sentry docs eventually.

ref #12620

@AbhiPrasad
AbhiPrasad requested a review from a teamJuly 30, 2024 15:06
@AbhiPrasadAbhiPrasad self-assigned this Jul 30, 2024
@AbhiPrasad
AbhiPrasad requested review from mydea and nicohrubec and removed request for a teamJuly 30, 2024 15:06
@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch from 20adfb9 to 1482a37CompareJuly 30, 2024 15:52
@AbhiPrasad
AbhiPrasad marked this pull request as draft July 30, 2024 21:14
@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

Drafting this PR for the time being because #13123 refactors a lot of this code, so this PR needs to be updated.

Hence let's wait for that to get merged in first, and then look at this one in more detail.

@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch 3 times, most recently from 16ddfe8 to 6aa304fCompareJuly 31, 2024 15:56
@AbhiPrasad
AbhiPrasad marked this pull request as ready for review July 31, 2024 15:57
@AbhiPrasad

Copy link
Copy Markdown
ContributorAuthor

This is now ready to review - I refactored this PR to pull in the refactors from #13123

attributes: {
'faas.cron': event.cron,
'faas.time': new Date(event.scheduledTime).toISOString(),
'faas.trigger': 'timer',

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.


addCloudResourceContext(isolationScope);

return startSpan(

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.

This duplication with the request handler is not ideal, but I'd rather refactor this later once I'm more confident in the API design of the withIsolationScope callback.

@nicohrubecnicohrubec left a comment

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.

looks good from my pov

handler.scheduled = new Proxy(handler.scheduled, {
apply(target, thisArg, args: Parameters<ExportedHandlerScheduledHandler<ExtractEnv<E>>>) {
const [event, env, context] = args;
return withIsolationScope(isolationScope => {

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.

just for my understanding, what do we need this isolation scope for here?

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.

To make sure scope bleed doesn't happen. If you define both a scheduled handler and a fetch handler, there's a chance that both happen at the same time, so we need to isolate accordingly.

captureException(e, { mechanism: { handled: false, type: 'cloudflare' } });
throw e;
} finally {
context.waitUntil(flush(2000));

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.

why do we need to wait here?

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.

waitUntil will execute keep the serverless function alive until we flush out all sentry requests, but it will ensure that this happens after a response is sent. Therefore flushing to sentry does not block sending a response back to whatever sent the request to the cloudflare worker.

@AbhiPrasad
AbhiPrasadforce-pushed the abhi-scheduled-handler branch from a0a3666 to 459be04CompareAugust 2, 2024 14:25
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.

Instrument Scheduled Handler

2 participants

@AbhiPrasad@nicohrubec