You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
1.5KB

  1. """
  2. Tracing utils
  3. """
  4. class TagTracer(object):
  5. def __init__(self):
  6. self._tags2proc = {}
  7. self._writer = None
  8. self.indent = 0
  9. def get(self, name):
  10. return TagTracerSub(self, (name,))
  11. def _format_message(self, tags, args):
  12. if isinstance(args[-1], dict):
  13. extra = args[-1]
  14. args = args[:-1]
  15. else:
  16. extra = {}
  17. content = " ".join(map(str, args))
  18. indent = " " * self.indent
  19. lines = ["%s%s [%s]\n" % (indent, content, ":".join(tags))]
  20. for name, value in extra.items():
  21. lines.append("%s %s: %s\n" % (indent, name, value))
  22. return "".join(lines)
  23. def _processmessage(self, tags, args):
  24. if self._writer is not None and args:
  25. self._writer(self._format_message(tags, args))
  26. try:
  27. processor = self._tags2proc[tags]
  28. except KeyError:
  29. pass
  30. else:
  31. processor(tags, args)
  32. def setwriter(self, writer):
  33. self._writer = writer
  34. def setprocessor(self, tags, processor):
  35. if isinstance(tags, str):
  36. tags = tuple(tags.split(":"))
  37. else:
  38. assert isinstance(tags, tuple)
  39. self._tags2proc[tags] = processor
  40. class TagTracerSub(object):
  41. def __init__(self, root, tags):
  42. self.root = root
  43. self.tags = tags
  44. def __call__(self, *args):
  45. self.root._processmessage(self.tags, args)
  46. def get(self, name):
  47. return self.__class__(self.root, self.tags + (name,))