This is an overview of the tools I used for debugging or analysis, not necessarily complete and comprehensive, if you know better tools, please mark in the comments.
Log
Yes, indeed, it is important to stress that enough logging is essential to the application. You should keep track of important things, and if your records are good enough, you can save a lot of time by identifying problems from the logs.
If you have ever used the print statement to debug your code now stop, replace it with Logging.debug, start slowly and disable it completely later ...
Tracking
Sometimes it can be helpful to see how a program is executed. You can use the IDE's debugging conjugate NGN to run the program step-by-step, but you need to know what you're looking for, otherwise it's going to be a long process.
There is a trace module in the standard library that can print all the content (like the production coverage report) during execution.
Python-mtrace--trace script.py
This produces a lot of output (each row is printed out, so you'd better go through the pipe and use grep to see only the parts of your interest), such as:
Python-mtrace--trace script.py | Egrep ' ^ (mod1.py|mod2.py) '
-
If you like new features, you can try Smiley-it can show variable content changes, and you can use it to remotely track programs.
Pdb
Import PDB
pdb.set_trace () # opens up PDB prompt
Or:
Try:
code
that
fails
except:
import pdb
pdb.pm () # or Pdb.post_mortem ()
or (press the keyboard C key to start the script):
Like in the REPL:
- C or Continue
- Q or quit
- L or list, display source in current interface
- W or where, showing backtracking
- D or down, showing the next interface of backtracking
- U or up, showing the previous interface of backtracking
- <enter> repeat the last command.
- Anything else, in the current interface to evaluate the source code (t there are some other commands)
- Corcontinue
- Qorquit
- Lorlist, showing the source of the current frame
- Worwhere, showing backtracking
- Dordown, downhill 1 frame backtracking
- Uorup, up 1 frame backtracking
- Return, repeat Last command
Almost anything, to evaluate the current frame of the Python code (and several other commands)
You can override the PDB:
- IPDB (Easy_install ipdb)-like Ipython (automatically padded, color, etc.)
- Pudb (Easy_install pudb)-Based on curses (class GUI), browsing the source code has a very good performance.
Remote PDB
sudo apt-get install winpdb
Alternative Pdb.set_trace ():
Import rpdb2
Rpdb2.start_embedded_debugger ("Secretpassword")
Now run winpdb and enter the password to File > Attach.
Don't like winpdb? Just run the PDB over TCP
Use the following code:
Import loggging class Rdb (PDB. PDB): "" This would run PDB as a ephemeral Telnet service. Once you connect no one else can connect.
On construction This object would block execution till a client has connected.
Based on https://github.com/tamentis/rpdb I ... To use this:: Rdb (4444). Set_trace () Then run:telnet 127.0.0.1 4444 "" Def __init__ (Self, port=0): Self . old_stdout = Sys.stdout Self.old_stdin = Sys.stdin Self.listen_socket = socket.socket (socket.af_inet, socket. Sock_stream) Self.listen_socket.bind ((' 0.0.0.0 ', port) if not port:logging.critical ("PDB Remote session OP En on:%s ", Self.listen_socket.getsockname ()" Print >> sys.__stderr__, "PDB Remote sessions Open on:", Self.lis Ten_socket.getsockname () Sys.stderr.flush () Self.listen_socket.listen (1) self.connected_socket, address = SE Lf.listen_socket.accept () Self.handle = Self.connected_socket.makefile (' rw ') pdb.pdb.__init__ (self, Completekey= ' tab ', Stdin=self.handle, stdout=self.handle) sys.stdout = Sys.stdin = Self.handle def do_continue (self, a RG): Sys.stdout = self.old_stdout Sys.stdin = Self.old_stdin self.handle.close () Self.connected_socket.clo SE () self.listen_socket.close () self.set_continue () return 1 Do_c = Do_cont = Do_continue def set_trace (
): "" "opens a remote PDB on the available port.
"" "RDB = Rdb () rdb.set_trace ()
Want to REPL? What about IPython?
If you don't need a whole debugger, just start Ipython with the following code:
Import IPython
ipython.embed ()
Standard Linux Tools
I was amazed that they had not been fully exploited. With these toolset you can figure out many of these problems: from performance issues (too many system calls, memory allocations, etc.) to deadlocks, networks, and disks.
sudo apt-get install htop
sudo htop
The most useful is to drop the right to run Strace, simply run the Quick-frozen strace-p 12345 or strace-f command parameters (-F to represent the strace branching process). There is usually a lot of output, and you'd better have the output redirected to a file (add &> filename after the command) for more in-depth analysis.
Then there is the Ltrace, which is similar to the Strace only through library calls, and the parameters are basically the same.
Lsof can provide the processing number you have seen ltrace/strace, so use: Lsof-p 12345
let the trace get deeper.
It is easy to use and can do a lot of things, provided that everyone has installed the htop!
Now, to find the process you want, just press:
- s display system call tracking (Strace)
- L Display library call tracking (LTRACE)
- L Show Lsof
Monitoring
There is no better alternative, the server continues to monitor, have you ever found yourself using weird tracking methods to find out why it is slow and how resources are consumed, so don't be bothered by Iotop, Iftop, Htop, Iostat, Vmstat, etc. Quickly use the Dstat bar, it can do most of the mentioned tools can do, and can do better!
It will be in compact, stylish code coloring (PRO, unlike Iostat, Vmstat yo) to continuously display your data, and you can always see the previous data (and Iftop, iotop, Htop different yo).
Just run this:
Dstat--cpu--io--mem--net--load--fs--vm--disk-util--disk-tps--freespace--swap--top-io--top-bio-adv
There is also a simpler way to write yo, like shell history (shell history) or rename command (aliases)
Gdb
This is a fairly complex and powerful tool, but I only relate to the basics (settings and basic commands).
sudo apt-get install gdb python-dbg
zcat/usr/share/doc/python2.7/gdbinit.gz > ~/.gdbinit
run App with python2.7-dbg
sudo gdb-p 12345
Now please use:
bt-stack Trajectory (C-level)
Pystack-python stack trajectory If you need to own ~/.gdbinit and use python-dbg
C (continued)
Is there any segfaults? Faulthandler!
Other than Python 3.3, this terrible error comes back to Python 2.x
Just follow the instructions below and you will find at least one cause of the error.
>>> import Faulthandler
>>> faulthandler.enable ()
Memory leaks
OK, there are a lot of tools, some of which are specifically for WSGI applications, like Dozer, but my favorite is definitely objgraph. It is so amazingly convenient and easy to use. It does not inherit with Wsgi or anything else, so you need to find your own way to run the following code:
>>> import objgraph
>>> objs = Objgraph.by_type ("Request") [:]
>>> objgraph.show _backrefs (Objs, max_depth=20, Highlight=lambda v:v in Objs, filename= "/tmp/graph.png")
graph written to/tmp/ Objgraph-zbdm4z.dot (nodes)
Image generated as/tmp/graph.png
You'll get a chart like this (warning: This chart is very large). You will also get dot output.
Memory Utilization
Sometimes you want to use less memory. Allocating less memory usually makes the program run faster and better, and users like to keep improving:
There are a lot of tools to use [1], but it seems to me that the best is pytracemalloc--compared to other tools, its overhead is very small (no need to rely on weakening the speed of the Sys.settrace) and its output is very detailed. What's troubling is its configuration because it requires you to recompile python, but SPT makes it easy to do.
Just run the following command, and then you can go shopping for lunch or something else:
Apt-get source python2.7 cd python2.7-*
wget https://github.com/wyplay/pytracemalloc/raw/master/python2.7_track _free_list.patch
Patch-p1 < python2.7_track_free_list.patch
debuild-us-uc CD.
sudo dpkg-i python2.7-minimal_2.7*.deb python2.7-dev_*.deb
Then install Pytracemalloc (Note: If you're doing this in a virtual environment, then after the python reinstall you'll need to rebuild it-run virtualenv myenv only):
Pip Install Pytracemalloc
Now you can encapsulate your application with the following code:
Import Tracemalloc, Time
tracemalloc.enable () Top
= Tracemalloc. Displaytop (
5000, # Log the top 5000 locations
file=open ('/tmp/memory-profile-%s '% time.time (), "W")
) C15/>top.show_lineno = True
try:
# code that needs to is traced
finally:
Top.display ()
Will get output like the following:
2013-05-31 18:05:07:top 5000 allocations per file and line #1: .../site-packages/billiard/_conne ction.py:198:size=1288 KiB, count=70 (+0), average=18 KiB #2: .../site-packages/billiard/_connection.py:199:size=1288
KiB, Count=70 (+0), average=18 KiB #3: .../python2.7/importlib/__init__.py:37:size=459 KiB, count=5958 (+0), average=78 B #4:/site-packages/amqp/transport.py:232:size=217 KiB, count=6960 (+0), average=32 B #5: .../site-packages/amqp/ transport.py:231:size=206 KiB, count=8798 (+0), average=24 B #6: .../site-packages/amqp/serialization.py:210:size=199 KiB, count=822 (+0), average=248 b #7: .../lib/python2.7/socket.py:224:size=179 KiB, count=5947 (+0), average=30 b #8:. ./celery/utils/term.py:89:size=172 KiB, count=1953 (+0), average=90 B #9: .../site-packages/kombu/connection.py:281: size=153 KiB, count=2400 (+0), average=65 B #10: .../site-packages/amqp/serialization.py:462:size=147 KiB, count=4704 (+ 0), average=32 B ...