0

I'm implementing logging function in a static period, and getting id to identify where the function is called is necessary for this. Currently the id is computed with serialization of 'inspect.stack()[1][1:]' by 'pickle' and I have created below python script for testing this feature. I'm currently using 'inspect' module but it returns only filename, linenumber, source at that line.

import inspect
import hashlib


def loginfo_throttle():
    frame = inspect.stack()[1][0]
    print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
    print(hashlib.md5(pickle.dumps(inspect.stack()[1][1:])).hexdigest())
    print(inspect.getframeinfo(frame))
    print('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<')


def main():
    loginfo_throttle();loginfo_throttle()
    loginfo_throttle()


if __name__ == '__main__':
    main()

The output is as below, and the first and second output is exactly same and this is the problem.

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
9ab15e3e3d106afca16e4155ac571152
Traceback(filename='spam.py', lineno=20, function='main', code_context=['    loginfo_throttle();loginfo_throttle()\n'], index=0)
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
9ab15e3e3d106afca16e4155ac571152
Traceback(filename='spam.py', lineno=20, function='main', code_context=['    loginfo_throttle();loginfo_throttle()\n'], index=0)
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2d63d9b94b68ba14989ffebed0b70ab2
Traceback(filename='spam.py', lineno=21, function='main', code_context=['    loginfo_throttle()\n'], index=0)
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Update

What I'd like to do in actual is as below, so distinguishing functions in same line using the called time is difficult.

import inspect
import pickle
import time


class LoggingThrottle(object):

    time_table = {}

    def __call__(self, period, msg):
        id = pickle.dumps(inspect.stack()[1][1:])
        now = time.time()
        last_time = self.time_table.get(id)
        if (last_time is None) or ((now - last_time) > period):
            print(msg)
            self.time_table[id] = now


logging_throttle = LoggingThrottle()


def main():
    for i in xrange(1000):
        logging_throttle(3, 'foo'); logging_throttle(3, 'spam')
        logging_throttle(3, 'bar')
        time.sleep(0.1)


if __name__ == '__main__':
    main()

This outputs only 'foo' and 'bar'.

foo
bar
foo
bar
Kentaro Wada
  • 505
  • 1
  • 4
  • 13

2 Answers2

0

You can add time() to distinguish functions called within one line.

import inspect
import hashlib
import pickle
from time import time


def loginfo_throttle():
    frame = inspect.stack()[1][0]
    print('>'*30)
    t = time()
    print(hashlib.md5(pickle.dumps((t, inspect.stack()[1][1:]))).hexdigest())
    print(t, inspect.getframeinfo(frame))
    print('<'*30)


def main():
    loginfo_throttle();loginfo_throttle()
    loginfo_throttle()


if __name__ == '__main__':
    main()

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
5576395790524ffafbc8e3c257580697
(1464942290.227, Traceback(filename='<ipython-input-70-f8a8af94e830>', lineno=16, function='main', code_context=[u'    loginfo_throttle();loginfo_throttle()\n'], index=0))
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
a56f921a23caef7f5d40713141a53b55
(1464942290.354, Traceback(filename='<ipython-input-70-f8a8af94e830>', lineno=16, function='main', code_context=[u'    loginfo_throttle();loginfo_throttle()\n'], index=0))
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
16e9e10e253c42a4eeb5b5c42911de19
(1464942290.482, Traceback(filename='<ipython-input-70-f8a8af94e830>', lineno=17, function='main', code_context=[u'    loginfo_throttle()\n'], index=0))
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Vadim Shkaberda
  • 2,807
  • 19
  • 35
0

I found the solution, by getting column in source code as below, seeing this post. How to find column number in Python code

import inspect
import pickle
import time


class LoggingThrottle(object):

    time_table = {}

    def __call__(self, period, msg):
        caller = inspect.stack()[1]
        frame, _, lineno, _, code, _ = caller
        caller_id = (
            inspect.getabsfile(frame),
            code,
            lineno,
            frame.f_lasti,
        )
        # print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
        # print(caller_id)
        # print('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<')
        caller_id = pickle.dumps(caller_id)
        now = time.time()
        last_time = self.time_table.get(caller_id)
        if (last_time is None) or ((now - last_time) > period):
            print(msg)
            self.time_table[caller_id] = now


logging_throttle = LoggingThrottle()


def main():
    for i in xrange(1000):
        logging_throttle(3, 'foo'); logging_throttle(3, 'spam')
        logging_throttle(3, 'bar')
        time.sleep(0.1)


if __name__ == '__main__':
    main()
Community
  • 1
  • 1
Kentaro Wada
  • 505
  • 1
  • 4
  • 13