Skip to content
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

Add profiling functionality to jobs. #3484

Merged
merged 11 commits into from
Apr 17, 2023

Conversation

Kircheneer
Copy link
Contributor

@Kircheneer Kircheneer commented Mar 24, 2023

Closes: #DNE - discussed verbally

What's Changed

Add cProfile profiling flag to jobs when DEBUG is set in the config. Example output:

# nautobot-server runjob plugins/example_plugin.jobs/ExampleLoggingJob --data '{"interval": 2}' --profile --local
[15:57:31] Running plugins/example_plugin.jobs/ExampleLoggingJob...
15:57:31.012 INFO    nautobot.jobs.ExampleLoggingJob jobs.py                                run_job() :
  Running job (commit=False)
15:57:31.019 INFO    nautobot.jobs.ExampleLoggingJob jobs.py                                    log() :
  Running for 2 seconds.
15:57:32.021 INFO    nautobot.jobs.ExampleLoggingJob jobs.py                                    log() :
  Step 1
15:57:33.039 INFO    nautobot.jobs.ExampleLoggingJob jobs.py                                    log() :
  Step 2
15:57:33.049 INFO    nautobot.jobs.ExampleLoggingJob jobs.py                                    log() :
  None
15:57:33.059 INFO    nautobot.jobs.ExampleLoggingJob jobs.py                                    log() :
  Wrote profiling information to /tmp/5c4bc8c1-5fe8-4a67-9116-70d4d943e944.pstats.
15:57:33.059 INFO    nautobot.jobs.ExampleLoggingJob jobs.py                               _run_job() :
  job completed successfully
15:57:33.061 INFO    nautobot.jobs.ExampleLoggingJob jobs.py                                    log() :
  Database changes have been reverted automatically.
15:57:33.065 INFO    nautobot.jobs.ExampleLoggingJob jobs.py                               _run_job() :
  Job completed in 0 minutes, 2.06 seconds
        run: 1 success, 4 info, 0 warning, 0 failure
                default: Running for 2 seconds.
                info: Step 1
                info: Step 2
                success: None
                info: Wrote profiling information to /tmp/5c4bc8c1-5fe8-4a67-9116-70d4d943e944.pstats.
                info: Database changes have been reverted automatically.

Ran for 2 seconds
[15:57:33] plugins/example_plugin.jobs/ExampleLoggingJob: SUCCESS
[15:57:33] plugins/example_plugin.jobs/ExampleLoggingJob: Duration 0 minutes, 2.06 seconds
[15:57:33] Finished
# python
>>> import pstats
>>> stats = pstats.Stats("/tmp/5c4bc8c1-5fe8-4a67-9116-70d4d943e944.pstats")
>>> stats.sort_stats(pstats.SortKey.CUMULATIVE).print_stats(10)
Fri Mar 24 15:57:33 2023    /tmp/5c4bc8c1-5fe8-4a67-9116-70d4d943e944.pstats

         5860 function calls (5718 primitive calls) in 2.036 seconds

   Ordered by: cumulative time
   List reduced from 438 to 10 due to restriction <10>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    2.036    2.036 /source/examples/example_plugin/example_plugin/jobs.py:46(run)
        2    2.006    1.003    2.006    1.003 {built-in method time.sleep}
        4    0.000    0.000    0.029    0.007 /source/nautobot/extras/jobs.py:531(_log)
        4    0.000    0.000    0.029    0.007 /source/nautobot/extras/models/jobs.py:769(log)
        4    0.000    0.000    0.026    0.006 /usr/local/lib/python3.7/site-packages/django/db/models/base.py:685(save)
        4    0.000    0.000    0.025    0.006 /usr/local/lib/python3.7/site-packages/django/db/models/base.py:743(save_base)
        4    0.000    0.000    0.024    0.006 /usr/local/lib/python3.7/site-packages/django/db/models/base.py:822(_save_table)
        4    0.000    0.000    0.024    0.006 /usr/local/lib/python3.7/site-packages/django/db/models/base.py:914(_do_insert)
        4    0.000    0.000    0.024    0.006 /usr/local/lib/python3.7/site-packages/django/db/models/manager.py:84(manager_method)
        4    0.000    0.000    0.024    0.006 /usr/local/lib/python3.7/site-packages/django/db/models/query.py:1260(_insert)


<pstats.Stats object at 0xffffbb207e90>
>>> 

Open questions

  • Should I make this available via
    • the API endpoint for running jobs?
    • the management command for running jobs?
    • the running of scheduled jobs?
  • Is the way I'm outputting this to disk okay? Should it be configurable as to what the path is? I wanted to keep it as simple as possible.

TODO

  • Explanation of Change(s)
  • Added change log fragment(s) (for more information see the documentation)
  • Attached Screenshots, Payload Example
  • Unit, Integration Tests
  • Documentation Updates (when adding/changing features)
  • Outline Remaining Work, Constraints from Design

@glennmatthews
Copy link
Contributor

Looks very cool!

Should I make this available via
the API endpoint for running jobs?
the management command for running jobs?
the running of scheduled jobs?

I think exposing it to the run_job management command would make the most sense. Since it's a debug-only feature I don't think there's any great need to add it to the API or to scheduled jobs.

Is the way I'm outputting this to disk okay? Should it be configurable as to what the path is? I wanted to keep it as simple as possible.

Seems fine as a local-development feature.

@Kircheneer Kircheneer force-pushed the lk-cprofile branch 4 times, most recently from 9c95470 to 89f06c1 Compare March 24, 2023 16:11
Copy link
Contributor

@glennmatthews glennmatthews left a comment

Choose a reason for hiding this comment

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

Nits only. Nice feature!

nautobot/docs/additional-features/jobs.md Outdated Show resolved Hide resolved
nautobot/docs/additional-features/jobs.md Outdated Show resolved Hide resolved
nautobot/docs/additional-features/jobs.md Outdated Show resolved Hide resolved
nautobot/extras/forms/forms.py Outdated Show resolved Hide resolved
nautobot/extras/jobs.py Outdated Show resolved Hide resolved
nautobot/docs/additional-features/jobs.md Show resolved Hide resolved
nautobot/extras/management/commands/runjob.py Outdated Show resolved Hide resolved
Kircheneer and others added 6 commits April 3, 2023 08:31
Co-authored-by: Glenn Matthews <glenn.matthews@networktocode.com>
Co-authored-by: Glenn Matthews <glenn.matthews@networktocode.com>
Co-authored-by: Glenn Matthews <glenn.matthews@networktocode.com>
Co-authored-by: Glenn Matthews <glenn.matthews@networktocode.com>
Co-authored-by: Glenn Matthews <glenn.matthews@networktocode.com>
Co-authored-by: Glenn Matthews <glenn.matthews@networktocode.com>
@Kircheneer Kircheneer force-pushed the lk-cprofile branch 5 times, most recently from 7a5f2b9 to 32469d0 Compare April 3, 2023 08:29
@Kircheneer
Copy link
Contributor Author

How should we handle job hook receivers? The CI is failing because (I believe) the way the forms are set up the _profile field is passed into job hook receivers as well. I guess people may want to profile job hook receivers as well, so should we support it? (CI Link: https://github.com/nautobot/nautobot/actions/runs/4594538893/jobs/8113771851?pr=3484#step:7:159)

@Kircheneer
Copy link
Contributor Author

Decided not to handle that case for now and just fixed the unit test.

@Kircheneer Kircheneer force-pushed the lk-cprofile branch 2 times, most recently from bac5b72 to 63c4cec Compare April 5, 2023 10:28
@bryanculver
Copy link
Member

@jathanism @gsnider2195 Can you do a quick look of this to figure out how this will impact the code written for #765

Copy link
Member

@bryanculver bryanculver 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 comments @Kircheneer reviewed with fresh eyes.

I'd still like this to be on @gsnider2195's radar with the recent work in 2.0 for Jobs overhaul how this will need to be merged up.


# TODO: This should probably be available as a file download rather than dumped to the hard drive.
# Pending this: https://github.com/nautobot/nautobot/issues/3352
profiling_path = f"/tmp/nautobot-jobresult-{job_result_pk}.pstats"
Copy link
Member

Choose a reason for hiding this comment

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

Sorry for the late review @Kircheneer but I'm curious if we can assume /tmp is writable.

nautobot/docs/additional-features/jobs.md Outdated Show resolved Hide resolved
nautobot/docs/additional-features/jobs.md Outdated Show resolved Hide resolved
Co-authored-by: Bryan Culver <31187+bryanculver@users.noreply.github.com>
Copy link
Contributor

@gsnider2195 gsnider2195 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 bit of feedback around testing but otherwise looks good and shouldn't cause any problems with 2.0

Copy link
Contributor

@gsnider2195 gsnider2195 left a comment

Choose a reason for hiding this comment

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

Nice!

@bryanculver bryanculver merged commit 2b78b59 into nautobot:develop Apr 17, 2023
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.

None yet

5 participants