streamline console logging, fix #2667

This commit is contained in:
Maximilian Hils 2017-12-14 23:03:52 +01:00
parent 21324086c3
commit 18f34fe88e
6 changed files with 38 additions and 60 deletions

View File

@ -1,6 +1,8 @@
from typing import List # noqa
import blinker
from mitmproxy import command
from mitmproxy.log import LogEntry
@ -10,10 +12,14 @@ class EventStore:
self.sig_add = blinker.Signal()
self.sig_refresh = blinker.Signal()
def log(self, entry: LogEntry):
def log(self, entry: LogEntry) -> None:
self.data.append(entry)
self.sig_add.send(self, entry=entry)
def clear(self):
@command.command("eventstore.clear")
def clear(self) -> None:
"""
Clear the event log.
"""
self.data.clear()
self.sig_refresh.send(self)

View File

@ -32,43 +32,33 @@ console_layouts = [
]
class Logger:
def log(self, evt):
signals.add_log(evt.msg, evt.level)
if evt.level == "alert":
signals.status_message.send(
message=str(evt.msg),
expire=2
)
class UnsupportedLog:
"""
A small addon to dump info on flow types we don't support yet.
"""
def websocket_message(self, f):
message = f.messages[-1]
signals.add_log(f.message_info(message), "info")
signals.add_log(message.content if isinstance(message.content, str) else strutils.bytes_to_escaped_str(message.content), "debug")
ctx.log.info(f.message_info(message))
ctx.log.debug(message.content if isinstance(message.content, str) else strutils.bytes_to_escaped_str(message.content))
def websocket_end(self, f):
signals.add_log("WebSocket connection closed by {}: {} {}, {}".format(
ctx.log.info("WebSocket connection closed by {}: {} {}, {}".format(
f.close_sender,
f.close_code,
f.close_message,
f.close_reason), "info")
f.close_reason))
def tcp_message(self, f):
message = f.messages[-1]
direction = "->" if message.from_client else "<-"
signals.add_log("{client_host}:{client_port} {direction} tcp {direction} {server_host}:{server_port}".format(
ctx.log.info("{client_host}:{client_port} {direction} tcp {direction} {server_host}:{server_port}".format(
client_host=f.client_conn.address[0],
client_port=f.client_conn.address[1],
server_host=f.server_conn.address[0],
server_port=f.server_conn.address[1],
direction=direction,
), "info")
signals.add_log(strutils.bytes_to_escaped_str(message.content), "debug")
))
ctx.log.debug(strutils.bytes_to_escaped_str(message.content))
class ConsoleAddon:
@ -477,13 +467,6 @@ class ConsoleAddon:
]
)
@command.command("console.eventlog.clear")
def eventlog_clear(self) -> None:
"""
Clear the event log.
"""
signals.sig_clear_log.send(self)
@command.command("console.key.contexts")
def key_contexts(self) -> typing.Sequence[str]:
"""

View File

@ -1,7 +1,5 @@
import urwid
from mitmproxy.tools.console import signals
from mitmproxy.tools.console import layoutwidget
from mitmproxy import ctx
from mitmproxy import log
EVENTLOG_SIZE = 10000
@ -18,9 +16,10 @@ class EventLog(urwid.ListBox, layoutwidget.LayoutWidget):
def __init__(self, master):
self.walker = LogBufferWalker([])
self.master = master
urwid.ListBox.__init__(self, self.walker)
signals.sig_add_log.connect(self.sig_add_log)
signals.sig_clear_log.connect(self.sig_clear_log)
super().__init__(self.walker)
master.events.sig_add.connect(self.add_entry)
master.events.sig_refresh.connect(self.refresh_entries)
self.refresh_entries(None)
def load(self, loader):
loader.add_option(
@ -39,12 +38,12 @@ class EventLog(urwid.ListBox, layoutwidget.LayoutWidget):
self.set_focus(0)
return urwid.ListBox.keypress(self, size, key)
def sig_add_log(self, sender, e, level):
if log.log_tier(ctx.options.verbosity) < log.log_tier(level):
def add_entry(self, event_store, entry: log.LogEntry):
if log.log_tier(self.master.options.verbosity) < log.log_tier(entry.level):
return
txt = "%s: %s" % (level, str(e))
if level in ("error", "warn"):
e = urwid.Text((level, txt))
txt = "%s: %s" % (entry.level, str(entry.msg))
if entry.level in ("error", "warn"):
e = urwid.Text((entry.level, txt))
else:
e = urwid.Text(txt)
self.walker.append(e)
@ -53,5 +52,7 @@ class EventLog(urwid.ListBox, layoutwidget.LayoutWidget):
if self.master.options.console_focus_follow:
self.walker.set_focus(len(self.walker) - 1)
def sig_clear_log(self, sender):
def refresh_entries(self, event_store):
self.walker[:] = []
for event in self.master.events.data:
self.add_entry(None, event)

View File

@ -11,7 +11,6 @@ from mitmproxy.tools.console import common
from mitmproxy.tools.console import layoutwidget
from mitmproxy.tools.console import flowdetailview
from mitmproxy.tools.console import searchable
from mitmproxy.tools.console import signals
from mitmproxy.tools.console import tabs
import mitmproxy.tools.console.master # noqa
@ -117,7 +116,7 @@ class FlowDetails(tabs.Tabs):
viewmode, message
)
if error:
signals.add_log(error, "error")
self.master.add_log(error, "error")
# Give hint that you have to tab for the response.
if description == "No content" and isinstance(message, http.HTTPRequest):
description = "No request content (press tab to view response)"

View File

@ -16,6 +16,7 @@ from mitmproxy import addons
from mitmproxy import master
from mitmproxy import log
from mitmproxy.addons import intercept
from mitmproxy.addons import eventstore
from mitmproxy.addons import readfile
from mitmproxy.addons import view
from mitmproxy.tools.console import consoleaddons
@ -32,6 +33,9 @@ class ConsoleMaster(master.Master):
super().__init__(opts)
self.view = view.View() # type: view.View
self.events = eventstore.EventStore()
self.events.sig_add.connect(self.sig_add_log)
self.stream_path = None
self.keymap = keymap.Keymap(self)
defaultkeys.map(self.keymap)
@ -40,12 +44,11 @@ class ConsoleMaster(master.Master):
self.view_stack = []
signals.call_in.connect(self.sig_call_in)
signals.sig_add_log.connect(self.sig_add_log)
self.addons.add(consoleaddons.Logger())
self.addons.add(*addons.default_addons())
self.addons.add(
intercept.Intercept(),
self.view,
self.events,
consoleaddons.UnsupportedLog(),
readfile.ReadFile(),
consoleaddons.ConsoleAddon(self),
@ -79,12 +82,12 @@ class ConsoleMaster(master.Master):
callback = self.quit,
)
def sig_add_log(self, sender, e, level):
if log.log_tier(self.options.verbosity) < log.log_tier(level):
def sig_add_log(self, event_store, entry: log.LogEntry):
if log.log_tier(self.options.verbosity) < log.log_tier(entry.level):
return
if level in ("error", "warn"):
if entry.level in ("error", "warn"):
signals.status_message.send(
message = "{}: {}".format(level.title(), e)
message="{}: {}".format(entry.level.title(), entry.msg)
)
def sig_call_in(self, sender, seconds, callback, args=()):

View File

@ -1,19 +1,5 @@
import blinker
# Clear the eventlog
sig_clear_log = blinker.Signal()
# Add an entry to the eventlog
sig_add_log = blinker.Signal()
def add_log(e, level):
sig_add_log.send(
None,
e=e,
level=level
)
# Show a status message in the action bar
status_message = blinker.Signal()