Skip to content

feat(profiling): add serverless scheduler and conditionally use it #3870

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 39 commits into from
Aug 8, 2022

Conversation

astuyve
Copy link
Contributor

@astuyve astuyve commented Jun 27, 2022

  • feat: WIP profiling support for Python
  • wip: function name as tag
  • feat: custom serverless scheduler to wake up every second and check if we've acquired 60s of data before flushing
  • feat: Conditionally use serverless scheduler. Refactor to inherit from base scheduler and override periodic method
  • fix: use 60s, not 61s
  • feat: test. Back to 60s
  • feat: Fix double flushing issue by comparing last export time as well as counting number of profiled seconds
  • feat: riot formatter
  • fix: _interval should be int, not float
  • feat: remove unneeded .encode()
  • feat: revert setup
  • feat: Move encode to after nil check
  • feat: Guard against unset _last_export. Add tests for overriden periodic function.
  • feat: formatting

Description

Based on Julien's feedback in our RFC, I've added a small scheduler which flushes after the periodic function is called 60 times. This ensures that profiles are sampled over the course of 60s of runtime instead of wallclock time.

Checklist

Motivation

Design

Testing strategy

Relevant issue(s)

Testing strategy

Reviewer Checklist

  • Title is accurate.
  • Description motivates each change.
  • No unnecessary changes were introduced in this PR.
  • PR cannot be broken up into smaller PRs.
  • Avoid breaking API changes unless absolutely necessary.
  • Tests provided or description of manual testing performed is included in the code or PR.
  • Release note has been added for fixes and features, or else changelog/no-changelog label added.
  • All relevant GitHub issues are correctly linked.
  • Backports are identified and tagged with Mergifyio.
  • Add to milestone.

@astuyve astuyve requested a review from a team as a code owner June 27, 2022 19:09
@astuyve astuyve changed the title feat(profiling): Add serverless scheduler and conditionally use it. feat(profiling): add serverless scheduler and conditionally use it Jun 27, 2022
@astuyve astuyve requested a review from jd June 27, 2022 19:18
@codecov-commenter
Copy link

codecov-commenter commented Jul 1, 2022

Codecov Report

Merging #3870 (fc2c22b) into 1.x (e618c0f) will decrease coverage by 0.79%.
The diff coverage is 43.82%.

@@            Coverage Diff             @@
##              1.x    #3870      +/-   ##
==========================================
- Coverage   79.86%   79.06%   -0.80%     
==========================================
  Files         717      719       +2     
  Lines       56347    56898     +551     
==========================================
- Hits        45004    44989      -15     
- Misses      11343    11909     +566     
Impacted Files Coverage Δ
ddtrace/contrib/flask/patch.py 0.00% <0.00%> (ø)
ddtrace/profiling/profiler.py 0.00% <0.00%> (ø)
ddtrace/profiling/scheduler.py 0.00% <0.00%> (ø)
tests/contrib/django/django_app/settings.py 100.00% <ø> (ø)
tests/contrib/django/test_django.py 100.00% <ø> (ø)
tests/contrib/flask/test_flask_appsec.py 0.00% <0.00%> (ø)
tests/contrib/flask/test_flask_snapshot.py 0.00% <0.00%> (ø)
tests/contrib/flask/test_hooks.py 0.00% <0.00%> (ø)
tests/contrib/flask/test_request.py 0.00% <0.00%> (ø)
tests/contrib/flask/test_static.py 0.00% <0.00%> (ø)
... and 38 more

📣 Codecov can now indicate which changes are the most critical in Pull Requests. Learn more

@astuyve astuyve requested a review from jd July 18, 2022 15:46
Copy link
Contributor

@jd jd left a comment

Choose a reason for hiding this comment

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

I'm a bit confused on how this solves the problem. You write:

Based on Julien's feedback in our RFC, I've added a small scheduler which flushes after the periodic function is called 60 times. This ensures that profiles are sampled over the course of 60s of runtime instead of wallclock time.

You're still doing 60 × 1s which is 60s of runtime. It's just that this now sleeps 60 times 1 second, rather than 1 time 60 seconds.

How is that going to solve the "serverless" problem? (if that solves it we should write it in the commit/ PR body)

Copy link
Contributor

@jd jd left a comment

Choose a reason for hiding this comment

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

a few changes but LGTM otherwise

Comment on lines 136 to 139
_scheduler = attr.ib(
init=False, default=None, type=Union[scheduler.Scheduler, serverless_scheduler.ServerlessScheduler]
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
_scheduler = attr.ib(
init=False, default=None, type=Union[scheduler.Scheduler, serverless_scheduler.ServerlessScheduler]
)
_scheduler = attr.ib(
init=False, default=None, type=scheduler.Scheduler,
)

The serverless scheduler is a subclass so that's ok

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've tried this, when combined with the comment to remove the Union at line 225, mypy still fails:

ddtrace/profiling/profiler.py:222: error: Incompatible types in assignment (expression has type "Type[Scheduler]", variable has type "Type[ServerlessScheduler]")  [assignment]
Found 1 error in 1 file (checked 404 source files)
Test failed with exit code 1

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you show line 225 when you have this error?
It seems that you are assigning a class rather than instance on L225.

if self._lambda_function_name:
scheduler_class = (
serverless_scheduler.ServerlessScheduler
) # type: Union[type[scheduler.Scheduler], type[serverless_scheduler.ServerlessScheduler]]
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think you need type then here
otherwise typing.Type[serverless_scheduler.ServerlessScheduler] or typing.Type[sscheduler.Scheduler] should be what you want I guess.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See above comment, this fails mypy

@jd jd force-pushed the aj/serverless-profiling branch from 7611d12 to e2205ab Compare August 5, 2022 12:55
@jd jd force-pushed the aj/serverless-profiling branch from e2205ab to e600cbe Compare August 5, 2022 12:55
@jd jd force-pushed the aj/serverless-profiling branch from d6c96f1 to 528e325 Compare August 5, 2022 13:52
jd
jd previously approved these changes Aug 5, 2022
mabdinur
mabdinur previously approved these changes Aug 5, 2022
Copy link
Member

@Kyle-Verhoog Kyle-Verhoog left a comment

Choose a reason for hiding this comment

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

just a few nits

@astuyve astuyve dismissed stale reviews from mabdinur and jd via fc2c22b August 8, 2022 10:56
@astuyve astuyve requested review from mabdinur, jd and Kyle-Verhoog August 8, 2022 10:56
@Kyle-Verhoog Kyle-Verhoog added this to the v1.4.0 milestone Aug 8, 2022
@Kyle-Verhoog
Copy link
Member

@Mergifyio backport 1.4

@mergify
Copy link
Contributor

mergify bot commented Aug 8, 2022

backport 1.4

✅ Backports have been created

@Kyle-Verhoog Kyle-Verhoog merged commit 83ce6ce into 1.x Aug 8, 2022
@Kyle-Verhoog Kyle-Verhoog deleted the aj/serverless-profiling branch August 8, 2022 15:57
mergify bot pushed a commit that referenced this pull request Aug 8, 2022
…3870)

Based on Julien's feedback in our RFC, I've added a small scheduler which flushes after the periodic function is called 60 times. This ensures that profiles are sampled over the course of 60s of runtime instead of wallclock time.

(cherry picked from commit 83ce6ce)
@github-actions github-actions bot modified the milestones: v1.4.0, v1.5.0 Aug 8, 2022
mergify bot added a commit that referenced this pull request Aug 8, 2022
…3870) (#4058)

Based on Julien's feedback in our RFC, I've added a small scheduler which flushes after the periodic function is called 60 times. This ensures that profiles are sampled over the course of 60s of runtime instead of wallclock time.

(cherry picked from commit 83ce6ce)

Co-authored-by: AJ Stuyvenberg <[email protected]>
Sign up for free to 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.

5 participants