Пример #1
0
        def track_memory_wrapper(*args, **kwargs):

            memory_info = {}
            tracker = ClassTracker()
            for cls in apps.get_models() + [Context, Template]:
                # track all models from registered apps, plus some standard Django ones
                tracker.track_class(cls)

            try:
                tracker.create_snapshot("before")
                memory_info["before"] = ProcessMemoryInfo()
                result = fn(*args, **kwargs)
                memory_info["after"] = ProcessMemoryInfo()
                tracker.create_snapshot("after")
                memory_info["stats"] = tracker.stats
                memory_info["stats"].annotate()
                return result

            finally:

                # record a whole bunch of memory statistics...
                resources = [
                    ("resident set size", memory_info["after"].rss),
                    ("virtual size", memory_info["after"].vsz),
                ]
                resources.extend(memory_info["after"] - memory_info["before"])
                resources = [(k, pp(v)) for k, v in resources]
                resources.extend(memory_info["after"].os_specific)

                # record each tracked class as of the final snapshot...
                classes_stats = []
                snapshot = memory_info["stats"].snapshots[-1]
                for class_name in memory_info["stats"].tracked_classes:
                    # history is a list of tuples that is updated on every creation/deletions: (timestamp, n_instances)
                    history = [
                        n for _, n in memory_info["stats"].history[class_name]
                    ]
                    if history:
                        classes_stats.append({
                            "name":
                            class_name,
                            "n_instances":
                            len(history),
                            "min_instances":
                            min(history),
                            "max_instances":
                            max(history),
                            "size":
                            pp(
                                snapshot.classes.get(class_name,
                                                     {}).get("sum", 0)),
                        })

                if not path:
                    stream = sys.stdout
                else:
                    stream = open(path, "w")

                print("\nRESOURCES", file=stream)
                for k, v in resources:
                    print(f"{k:<26}: {v:>10}", file=stream)
                print("\nCLASSES", file=stream)
                for class_stats in classes_stats:
                    print(
                        "{name}: created/deleted {n_instances} times for a min/max of {min_instances}/{max_instances} instances: {size:>10}"
                        .format(**class_stats),
                        file=stream,
                    )

                stream.closed
                tracker.detach_all_classes()
Пример #2
0
class MemoryPanel(Panel):

    name = 'pympler'

    title = 'Memory'

    template = 'memory_panel.html'

    classes = [Context, Template]

    def process_request(self, request):
        self._tracker = ClassTracker()
        for cls in apps.get_models() + self.classes:
            self._tracker.track_class(cls)
        self._tracker.create_snapshot('before')
        self.record_stats({'before': ProcessMemoryInfo()})

    def process_response(self, request, response):
        self.record_stats({'after': ProcessMemoryInfo()})
        self._tracker.create_snapshot('after')
        stats = self._tracker.stats
        stats.annotate()
        self.record_stats({'stats': stats})

    def enable_instrumentation(self):
        self._tracker = ClassTracker()
        for cls in apps.get_models() + self.classes:
            self._tracker.track_class(cls)

    def disable_instrumentation(self):
        self._tracker.detach_all_classes()

    def nav_subtitle(self):
        context = self.get_stats()
        before = context['before']
        after = context['after']
        rss = after.rss
        delta = rss - before.rss
        delta = ('(+%s)' % pp(delta)) if delta > 0 else ''
        return "%s %s" % (pp(rss), delta)

    @property
    def content(self):
        context = self.get_stats()
        before = context['before']
        after = context['after']
        stats = context['stats']
        rows = [
            ('Resident set size', after.rss),
            ('Virtual size', after.vsz),
        ]
        rows.extend(after - before)
        rows = [(key, pp(value)) for key, value in rows]
        rows.extend(after.os_specific)

        classes = []
        snapshot = stats.snapshots[-1]
        for model in stats.tracked_classes:
            history = [cnt for _, cnt in stats.history[model]]
            size = snapshot.classes.get(model, {}).get('sum', 0)
            if history and history[-1] > 0:
                classes.append((model, history, pp(size)))
        context.update({'rows': rows, 'classes': classes})
        return render_to_string(self.template, context)
Пример #3
0
class MemoryPanel(Panel):

    name = 'pympler'

    title = 'Memory'

    template = 'memory_panel.html'

    classes = [Context, Template]

    def process_request(self, request):
        self._tracker = ClassTracker()
        for cls in get_models() + self.classes:
            self._tracker.track_class(cls)
        self._tracker.create_snapshot('before')
        self.record_stats({'before': ProcessMemoryInfo()})

    def process_response(self, request, response):
        self.record_stats({'after': ProcessMemoryInfo()})
        self._tracker.create_snapshot('after')
        stats = self._tracker.stats
        stats.annotate()
        self.record_stats({'stats': stats})

    def enable_instrumentation(self):
        self._tracker = ClassTracker()
        for cls in get_models() + self.classes:
            self._tracker.track_class(cls)

    def disable_instrumentation(self):
        self._tracker.detach_all_classes()

    def nav_subtitle(self):
        context = self.get_stats()
        before = context['before']
        after = context['after']
        rss = after.rss
        delta = rss - before.rss
        delta = ('(+%s)' % pp(delta)) if delta > 0 else ''
        return "%s %s" % (pp(rss), delta)

    @property
    def content(self):
        context = self.get_stats()
        before = context['before']
        after = context['after']
        stats = context['stats']
        rows = [('Resident set size', after.rss),
                ('Virtual size', after.vsz),
                ]
        rows.extend(after - before)
        rows = [(key, pp(value)) for key, value in rows]
        rows.extend(after.os_specific)

        classes = []
        snapshot = stats.snapshots[-1]
        for model in stats.tracked_classes:
            history = [cnt for _, cnt in stats.history[model]]
            size = snapshot.classes.get(model, {}).get('sum', 0)
            if cnt > 0:
                classes.append((model, history, pp(size)))
        context.update({'rows': rows, 'classes': classes})
        return render_to_string(self.template, context)