Skip to content

Commit

Permalink
Add memory profiler
Browse files Browse the repository at this point in the history
  • Loading branch information
mborho committed Jan 24, 2018
1 parent 98e0bc3 commit 92195e9
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 1 deletion.
3 changes: 3 additions & 0 deletions livebridge/config.py
Expand Up @@ -52,3 +52,6 @@
"password": os.environ.get("LB_WEB_PWD")
}
}

PROFILER_INTERVAL = int(os.environ.get("LB_PROFILER_INTERVAL", 0))

84 changes: 84 additions & 0 deletions livebridge/profiler.py
@@ -0,0 +1,84 @@
# -*- coding: utf-8 -*-
#
# Copyright 2017 dpa-infocom GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import asyncio
import tracemalloc
import os
import linecache
import pprint
import logging
from collections import OrderedDict

tracemalloc.start()


async def run_profiler(interval):
while 1:
await show_traces()
await asyncio.sleep(interval)

snapshot_prev = None
async def show_traces():
if tracemalloc.is_tracing():
snapshot = tracemalloc.take_snapshot()
snapshot = snapshot.filter_traces((
tracemalloc.Filter(False, "<frozen importlib._bootstrap>"),
tracemalloc.Filter(False, "<frozen importlib._bootstrap_external>"),
tracemalloc.Filter(False, linecache.__file__),
tracemalloc.Filter(False, tracemalloc.__file__),
tracemalloc.Filter(False, "<unknown>"),
))
await display_top(snapshot)
await display_diff(snapshot)

async def display_top(snapshot, key_type='lineno', limit=15):
top_stats = snapshot.statistics(key_type)

logging.debug("\n\n")
logging.debug("Top %s lines" % limit)
for index, stat in enumerate(top_stats[:limit], 1):
frame = stat.traceback[0]
# replace "/path/to/module/file.py" with "module/file.py"
filename = os.sep.join(frame.filename.split(os.sep)[-2:])
logging.debug("#%s: %s:%s: %.1f KiB %dx"
% (index, filename, frame.lineno, stat.size / 1024, stat.count))
line = linecache.getline(frame.filename, frame.lineno).strip()
if line:
logging.debug(' %s' % line)

other = top_stats[limit:]
if other:
size = sum(stat.size for stat in other)
logging.debug("%s other: %.1f KiB" % (len(other), size / 1024))
total = sum(stat.size for stat in top_stats)
logging.debug("Total allocated size: %.1f KiB\n\n" % (total / 1024))

async def display_diff(snapshot, key_type='lineno', limit=15):
global snapshot_prev
if snapshot_prev:
logging.debug("Top %s differences" % limit)
top_diffs= snapshot.compare_to(snapshot_prev, 'lineno')
for x, stat in enumerate([x for x in top_diffs[:limit]], 1):
frame = stat.traceback[0]
# replace "/path/to/module/file.py" with "module/file.py"
filename = os.sep.join(frame.filename.split(os.sep)[-2:])
logging.debug("#{}: {}:{} {:.1f} KiB {}x (+{})".format(
x, filename, frame.lineno, stat.size / 1024, stat.count, stat.count_diff))
line = linecache.getline(frame.filename, frame.lineno).strip()
if line:
logging.debug(' %s' % line)
logging.debug("\n\n")
snapshot_prev = snapshot

6 changes: 5 additions & 1 deletion livebridge/run.py
Expand Up @@ -26,7 +26,6 @@
from livebridge.web import WebApi
from livebridge.loader import load_extensions


def read_args(**kwargs):
"""Read controlfile parameter."""
if kwargs.get("control"):
Expand Down Expand Up @@ -67,6 +66,11 @@ def main(**kwargs):
controller = Controller(config=config, control_file=args.control)
asyncio.ensure_future(controller.run())

if config.PROFILER_INTERVAL > 0:
# do some profiling
from livebridge.profiler import run_profiler
asyncio.ensure_future(run_profiler(config.PROFILER_INTERVAL))

# start http api
if config.WEB.get("host") and config.WEB.get("port"):
server = WebApi(config=config.WEB, controller=controller, loop=loop)
Expand Down

0 comments on commit 92195e9

Please sign in to comment.