log_printer.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import sys
  2. from itertools import cycle
  3. from .multiplexer import Multiplexer
  4. from . import colors
  5. class LogPrinter(object):
  6. def __init__(self, containers, attach_params=None):
  7. self.containers = containers
  8. self.attach_params = attach_params or {}
  9. self.generators = self._make_log_generators()
  10. def run(self):
  11. mux = Multiplexer(self.generators)
  12. for line in mux.loop():
  13. sys.stdout.write(line)
  14. def _make_log_generators(self):
  15. color_fns = cycle(colors.rainbow())
  16. generators = []
  17. for container in self.containers:
  18. color_fn = color_fns.next()
  19. generators.append(self._make_log_generator(container, color_fn))
  20. return generators
  21. def _make_log_generator(self, container, color_fn):
  22. prefix = color_fn(container.name + " | ")
  23. websocket = self._attach(container)
  24. return (prefix + line for line in split_buffer(read_websocket(websocket), '\n'))
  25. def _attach(self, container):
  26. params = {
  27. 'stdin': False,
  28. 'stdout': True,
  29. 'stderr': True,
  30. 'logs': False,
  31. 'stream': True,
  32. }
  33. params.update(self.attach_params)
  34. params = dict((name, 1 if value else 0) for (name, value) in params.items())
  35. return container.attach_socket(params=params, ws=True)
  36. def read_websocket(websocket):
  37. while True:
  38. data = websocket.recv()
  39. if data:
  40. yield data
  41. else:
  42. break
  43. def split_buffer(reader, separator):
  44. buffered = ''
  45. for data in reader:
  46. lines = (buffered + data).split(separator)
  47. for line in lines[:-1]:
  48. yield line + separator
  49. if len(lines) > 1:
  50. buffered = lines[-1]
  51. if len(buffered) > 0:
  52. yield buffered