Skip to content

Backlog predicate #78

Open
Open

Description

@ionelmc

A predicate that can show a stacktrace or store a number of events up to a certain point:

# defaults
class Backlog:
  def __init__(self, filter, action=CallPrinter, size=None, stack=30):
    self.filter = filter
    self.action = action
    self.queue = collections.deque(maxlen=size) if size else None
    self.stack = stack
    ....

Handling could be:

  • Backlog.__call__(event) predicate returns True if self.filter(event) returns True

  • If size is given it stores detached in a deque with that size

  • the first time[1] self.filter(event) returns True:

    • if there's a self.queue it calls self.action for each event from it up to a self.stack depth
    • otherwise it creates events from each frame from sys._getframe() up to self.stack depth and passes them to self.action
  • otherwise add events in self.queue

[1] similar to how From predicate works

Activity

  1. assigned and unassigned on Mar 25, 2020
  2. ionelmc commented on Mar 25, 2020

    @ionelmc
    OwnerAuthor
    trace(expression, action=SomePrinter) Meaning
    Backlog(function="foobar", size=10, action=CodePrinter) Show 10 events prior to the first match for "foobar" (usually a call) using CodePrinter. Afterwards (events from "foobar") are shown using SomePrinter.
    Backlog(function="foobar", size=10, action=CodePrinter).filter(stdlib=False) Show 10 events that aren't from stdlib prior to the first match for "foobar" (usually a call) using CodePrinter. Afterwards (events from "foobar") are shown using SomePrinter.
    Backlog(function="foobar", stack=10, size=0, action=CodePrinter).filter(stdlib=False) Show 10 fake events created from the current call stack that aren't from stdlib prior to the first match for "foobar" (usually a call) using CodePrinter. For all intents and purposes those 10 events will look like a call stack (they would only be call events). Afterwards (events from "foobar") are shown using SomePrinter.
    Backlog(function="foobar", kind="line", stack=10, size=0, action=CodePrinter) Show 10 fake events created from the current call stack prior to the first match for "foobar" (usually a call) using CodePrinter. Note that because the triggering event would not be a call event the call stack iterator would need to start from 0 instead of 1.
    Backlog(function="foobar", stack=10, size=20, action=CallPrinter) Show 20 events prior to the first match for "foobar" (usually a call) using CallPrinter. If those 20 events don't go deeper than 10 calls then prepend fake events from the current call stack up to that level. Afterwards (events from "foobar") are shown using SomePrinter.
    Backlog(function="foobar") Show 100 events prior to the first match for "foobar" (usually a call) using SomePrinter. Some helper code in trace would inject the main actions if they aren't already specified.
    Or(Q(function="test123"), Backlog(function="foobar")) The helper code in trace would need to smart enough to be able to examine the whole predicate tree.
    ~Backlog(function="foobar") Essentially translate to Backlog(Not(Q(function="foobar"))) as it doesn't make sense to negate backlog on the outside (eg: hunter would display events from backlog 2 times - undesirable).

    Perhaps stack=10, size=100, action=CallPrinter could be default.

  3. ionelmc commented on Mar 25, 2020

    @ionelmc
    OwnerAuthor

    There is a problem when creating fake events... the Event.__init__ wants a tracer (to fill depth/calls). Perhaps make it optional and add options for depth/calls. Value for "calls" in fake events is very problematic - nothing in hunter uses them now so maybe "-1" is a safe value. Value for "depth" should be computed by applying a stack delta to the dump-trigger event's depth.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions