Skip to content

Commit 0b1a273

Browse files
committed
Merge pull request #95 from sagaru/master
Reporting for memory_profiler
2 parents 42f683f + 9627229 commit 0b1a273

5 files changed

Lines changed: 132 additions & 1 deletion

File tree

README.rst

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,47 @@ args, kw)``. For example::
227227
This will execute the code `f(1, n=int(1e6))` and return the memory
228228
consumption during this execution.
229229

230+
=====
231+
REPORTING
232+
=====
233+
234+
The output can be redirected to a log file by passing IO stream as
235+
parameter to the decorator like @profile(stream=fp)
236+
237+
>>> fp=open('memory_profiler.log','w+')
238+
>>> @profile(stream=fp)
239+
>>> def my_func():
240+
... a = [1] * (10 ** 6)
241+
... b = [2] * (2 * 10 ** 7)
242+
... del b
243+
... return a
244+
245+
For details refer: examples/reporting_file.py
246+
247+
``Reporting via logger Module:``
248+
249+
Sometime it would be very convenient to use logger module specially
250+
when we need to use RotatingFileHandler.
251+
252+
The output can be redirected to logger module by simply making use of
253+
LogFile of memory profiler module.
254+
255+
>>> from memory_profiler import LogFile
256+
>>> import sys
257+
>>> sys.stdout = LogFile('memory_profile_log')
258+
259+
``Customised reporting:``
260+
261+
Sending everything to the log file while running the memory_profiler
262+
could be cumbersome and one can choose only entries with increments
263+
by passing True to reportIncrementFlag, where reportIncrementFlag is
264+
a parameter to LogFile class of memory profiler module.
265+
266+
>>> from memory_profiler import LogFile
267+
>>> import sys
268+
>>> sys.stdout = LogFile('memory_profile_log', reportIncrementFlag=False)
269+
270+
For details refer: examples/reporting_logger.py
230271

231272
=====================
232273
IPython integration
@@ -348,6 +389,8 @@ cleanup.
348389

349390
`Thomas Kluyver <https://github.com/takluyver>`_ added the IPython extension.
350391

392+
`Sagar UDAY KUMAR <https://github.com/sagaru>`_ added Report generation feature and examples.
393+
351394

352395
=========
353396
License

examples/example.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
1+
from memory_profiler import profile
22
@profile
33
def my_func():
44
a = [1] * (10 ** 6)

examples/reporting_file.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from memory_profiler import profile
2+
3+
f=open('hi.txt','w+')
4+
5+
@profile(stream=f)
6+
def my_func():
7+
a = [1] * (10 ** 6)
8+
b = [2] * (2 * 10 ** 7)
9+
del b
10+
return a
11+
12+
@profile(stream=f)
13+
def my_func1():
14+
a = [2] * (10 ** 6)
15+
b = [3] * (2 * 10 ** 7)
16+
del b
17+
return a
18+
19+
if __name__ == '__main__':
20+
my_func()
21+
my_func1()

examples/reporting_logger.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from memory_profiler import profile
2+
import logging
3+
4+
# create logger
5+
logger = logging.getLogger('memory_profile_log')
6+
logger.setLevel(logging.DEBUG)
7+
8+
# create file handler which logs even debug messages
9+
fh = logging.FileHandler("memory_profile.log")
10+
fh.setLevel(logging.DEBUG)
11+
12+
# create formatter
13+
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
14+
fh.setFormatter(formatter)
15+
16+
# add the handlers to the logger
17+
logger.addHandler(fh)
18+
19+
from memory_profiler import LogFile
20+
import sys
21+
sys.stdout = LogFile('memory_profile_log', reportIncrementFlag=False)
22+
23+
@profile
24+
def my_func():
25+
a = [1] * (10 ** 6)
26+
b = [2] * (2 * 10 ** 7)
27+
del b
28+
return a
29+
30+
@profile
31+
def my_func1():
32+
a = [2] * (10 ** 6)
33+
b = [3] * (2 * 10 ** 7)
34+
del b
35+
return a
36+
37+
if __name__ == '__main__':
38+
my_func()
39+
my_func1()

memory_profiler.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import inspect
1717
import subprocess
1818
from copy import copy
19+
import logging
1920

2021
# TODO: provide alternative when multprocessing is not available
2122
try:
@@ -808,6 +809,33 @@ def inner_wrapper(f):
808809
return profile(f, stream=stream, precision=precision)
809810
return inner_wrapper
810811

812+
class LogFile(object):
813+
"""File-like object to log text using the `logging` module and the log report can be customised."""
814+
815+
def __init__(self, name=None, reportIncrementFlag=False):
816+
"""
817+
:param name: name of the logger module
818+
reportIncrementFlag: This must be set to True if only the steps with memory increments are to be reported
819+
820+
:type self: object
821+
name: string
822+
reportIncrementFlag: bool
823+
"""
824+
self.logger = logging.getLogger(name)
825+
self.reportIncrementFlag = reportIncrementFlag
826+
827+
def write(self, msg, level=logging.INFO):
828+
if self.reportIncrementFlag:
829+
if "MiB" in msg and float(msg.split("MiB")[1].strip())>0:
830+
self.logger.log(level, msg)
831+
elif msg.__contains__("Filename:") or msg.__contains__("Line Contents"):
832+
self.logger.log(level, msg)
833+
else:
834+
self.logger.log(level, msg)
835+
836+
def flush(self):
837+
for handler in self.logger.handlers:
838+
handler.flush()
811839

812840
if __name__ == '__main__':
813841
from optparse import OptionParser

0 commit comments

Comments
 (0)