~ubuntu-branches/ubuntu/saucy/keystone/saucy-proposed

« back to all changes in this revision

Viewing changes to tools/tracer.py

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2011-08-23 10:18:22 UTC
  • Revision ID: james.westby@ubuntu.com-20110823101822-enve6zceb3lqhuvj
Tags: upstream-1.0~d4~20110823.1078
ImportĀ upstreamĀ versionĀ 1.0~d4~20110823.1078

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
3
 
 
4
# Copyright 2010 United States Government as represented by the
 
5
# Administrator of the National Aeronautics and Space Administration.
 
6
# Copyright 2011 OpenStack LLC.
 
7
# All Rights Reserved.
 
8
#
 
9
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 
10
#    not use this file except in compliance with the License. You may obtain
 
11
#    a copy of the License at
 
12
#
 
13
#         http://www.apache.org/licenses/LICENSE-2.0
 
14
#
 
15
#    Unless required by applicable law or agreed to in writing, software
 
16
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
17
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
18
#    License for the specific language governing permissions and limitations
 
19
#    under the License.
 
20
#
 
21
# Author: Ziad Sawalha (http://launchpad.net/~ziad-sawalha)
 
22
# Original maintained at: https://github.com/ziadsawalha/Python-tracer
 
23
#
 
24
 
 
25
"""
 
26
OpenStack Call Tracing Tool
 
27
 
 
28
To use this:
 
29
1. include the tools dirextory in your project (__init__.py and tracer.py)
 
30
2. import tools.tracer as early as possible into your module
 
31
3. add --trace-calls to any argument parsers you use so the argument doesn't
 
32
get flagged as invalid.
 
33
 
 
34
Usage:
 
35
# Add this as early as possible in the first module called in your service
 
36
import tools.tracer   #load this first
 
37
 
 
38
If a '--trace-calls' parameter is found, it will trace calls to the console and
 
39
space them to show the call graph.
 
40
 
 
41
"""
 
42
 
 
43
import os
 
44
import sys
 
45
 
 
46
 
 
47
if '--trace-calls' in sys.argv:
 
48
    stack_depth = 0
 
49
 
 
50
    def localtrace(frame, event, arg):
 
51
        global stack_depth
 
52
        if event == "return":
 
53
            stack_depth = stack_depth - 1
 
54
        elif event == "exception":
 
55
            co = frame.f_code
 
56
            func_name = co.co_name
 
57
            line_no = frame.f_lineno
 
58
            filename = co.co_filename
 
59
            exc_type, exc_value, exc_traceback = arg
 
60
            print '\033[91m%sERROR: %s %s on line %s of %s\033[0m' % \
 
61
                ('  ' * stack_depth, exc_type.__name__, exc_value, line_no,
 
62
                 func_name)
 
63
        return None
 
64
 
 
65
    def selectivetrace(frame, event, arg):
 
66
        global stack_depth
 
67
        if event == "exception":
 
68
            co = frame.f_code
 
69
            func_name = co.co_name
 
70
            line_no = frame.f_lineno
 
71
            filename = co.co_filename
 
72
            exc_type, exc_value, exc_traceback = arg
 
73
            print '\033[91m%sERROR: %s %s on line %s of %s\033[0m' % \
 
74
                ('  ' * stack_depth, exc_type.__name__, exc_value, line_no,
 
75
                 func_name)
 
76
        if event != 'call':
 
77
            return
 
78
        co = frame.f_code
 
79
        func_name = co.co_name
 
80
        if func_name == 'write':
 
81
            # Ignore write() calls from print statements
 
82
            return
 
83
        func_filename = co.co_filename
 
84
        if func_filename == "<string>":
 
85
            return
 
86
        if func_filename.startswith("/System"):
 
87
            return
 
88
        if func_filename.startswith("/Library"):
 
89
            return
 
90
        if 'macosx' in func_filename:
 
91
            return
 
92
        func_line_no = frame.f_lineno
 
93
        # If ../../keystone/__init__.py exists, add ../ to Python search path,
 
94
        # so that it will override what happens to be installed in
 
95
        # /usr/(local/)lib/python...
 
96
        possible_topdir = os.path.normpath(os.path.join(
 
97
                                           os.path.abspath(sys.argv[0]),
 
98
                                           os.pardir,
 
99
                                           os.pardir))
 
100
        func_filename = func_filename.replace(possible_topdir, '')
 
101
        caller = frame.f_back
 
102
 
 
103
        if caller:
 
104
            caller_line_no = caller.f_lineno
 
105
            caller_filename = caller.f_code.co_filename.replace(
 
106
                                                        possible_topdir, '')
 
107
            print '%s%s::%s:%s      (from %s:%s)' % \
 
108
                ('  ' * stack_depth, func_filename, func_name, func_line_no,
 
109
                 caller_filename, caller_line_no)
 
110
 
 
111
        stack_depth = stack_depth + 1
 
112
        return localtrace
 
113
 
 
114
    sys.settrace(selectivetrace)
 
115
    print 'Starting OpenStack call tracer'