Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Load Testing

Server Side

Legacy Tests - https://github.com/edx/load-tests (internal-only repo)

...

Framework - https://github.com/locustio/locust(used currently in edx-load-tests. We also have a fork, and some legacy JMeter scripts)

How to Run Load Tests

Client Side (Browser)

Framework - http://www.sitespeed.io/ (Install via npm)

...

Network throttling tools: Network Link Conditioner, tc (ubuntu native), wondersharper (which does not work on virtual machines), etc

...

Monitoring in Environments

New Relic

...

Profiling

PyInstrument

PyInstrument can be helpful because of the way it writes output data as a call tree. More info here:

https://github.com/joerick/pyinstrument

Example of a profile using pyinstrument, writing output to a file:


Code Block
python
python
from pyinstrument import Profiler
profiler = Profiler(use_signal=False)
profiler.start()
# Do stuff here
profiler.stop()
 
# write profile data to file
with open('my.log', 'w') as f:
  f.write(profiler.output_text())


SnakeViz

Here are the steps to profile your python code with cProfile and then view the results using SnakeViz.

    1. export VAGRANT_X11=1
    2. vagrant ssh
    3. First time only: Install SnakeViz.  Please update this document with the steps you used if you do it.
    4. sudo su edxapp
    5. Add the following to the code that you want to profile


      Code Block
      @contextmanager
      def collect_profile(file_prefix):
          """
          Context manager to collect profile information.
          """
          import cProfile
          import uuid
          profiler = cProfile.Profile()
          profiler.enable()
          try:
              yield
          finally:
              profiler.disable()
              profiler.dump_stats("{0}_{1}.profile".format(file_prefix, uuid.uuid4()))
      
      with collect_profile:
          <python_code_to_profile>

      OR, if you want to profile an entire function, you can use this decorator:

      Code Block
      def collect_profile_func(file_prefix, enabled=False):
          """
          Method decorator for collecting profile.
          """
          import functools
      
          def _outer(func):
              """
              Outer function decorator.
              """
              @functools.wraps(func)
              def _inner(self, *args, **kwargs):
                  """
                  Inner wrapper function.
                  """
                  if enabled:
                      with collect_profile(file_prefix):
                          return func(self, *args, **kwargs)
                  else:
                      return func(self, *args, **kwargs)
              return _inner
          return _outer
      
      
      @contextmanager
      def collect_profile(file_prefix):
          """
          Context manager to collect profile information.
          """
          import cProfile
          import uuid
          profiler = cProfile.Profile()
          profiler.enable()
          try:
              yield
          finally:
              profiler.disable()
              profiler.dump_stats("{0}_{1}.profile".format(file_prefix, uuid.uuid4()))


    6. Then use SnakeViz by issuing:

      1. snakeviz DIRECTORY/FILE_NAME.profile

Tips

When profiling locally, disable features that would affect performance numbers.  For instance, the following can be set in the a local [lms/cms]/envs/private.py file:

...