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 from typing import List # noqa
import blinker import blinker
from mitmproxy import command
from mitmproxy.log import LogEntry from mitmproxy.log import LogEntry
@ -10,10 +12,14 @@ class EventStore:
self.sig_add = blinker.Signal() self.sig_add = blinker.Signal()
self.sig_refresh = blinker.Signal() self.sig_refresh = blinker.Signal()
def log(self, entry: LogEntry): def log(self, entry: LogEntry) -> None:
self.data.append(entry) self.data.append(entry)
self.sig_add.send(self, entry=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.data.clear()
self.sig_refresh.send(self) 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: class UnsupportedLog:
""" """
A small addon to dump info on flow types we don't support yet. A small addon to dump info on flow types we don't support yet.
""" """
def websocket_message(self, f): def websocket_message(self, f):
message = f.messages[-1] message = f.messages[-1]
signals.add_log(f.message_info(message), "info") ctx.log.info(f.message_info(message))
signals.add_log(message.content if isinstance(message.content, str) else strutils.bytes_to_escaped_str(message.content), "debug") ctx.log.debug(message.content if isinstance(message.content, str) else strutils.bytes_to_escaped_str(message.content))
def websocket_end(self, f): 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_sender,
f.close_code, f.close_code,
f.close_message, f.close_message,
f.close_reason), "info") f.close_reason))
def tcp_message(self, f): def tcp_message(self, f):
message = f.messages[-1] message = f.messages[-1]
direction = "->" if message.from_client else "<-" 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_host=f.client_conn.address[0],
client_port=f.client_conn.address[1], client_port=f.client_conn.address[1],
server_host=f.server_conn.address[0], server_host=f.server_conn.address[0],
server_port=f.server_conn.address[1], server_port=f.server_conn.address[1],
direction=direction, 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: 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") @command.command("console.key.contexts")
def key_contexts(self) -> typing.Sequence[str]: def key_contexts(self) -> typing.Sequence[str]:
""" """

View File

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

View File

@ -11,9 +11,8 @@ from mitmproxy.tools.console import common
from mitmproxy.tools.console import layoutwidget from mitmproxy.tools.console import layoutwidget
from mitmproxy.tools.console import flowdetailview from mitmproxy.tools.console import flowdetailview
from mitmproxy.tools.console import searchable from mitmproxy.tools.console import searchable
from mitmproxy.tools.console import signals
from mitmproxy.tools.console import tabs from mitmproxy.tools.console import tabs
import mitmproxy.tools.console.master # noqa import mitmproxy.tools.console.master # noqa
class SearchError(Exception): class SearchError(Exception):
@ -117,7 +116,7 @@ class FlowDetails(tabs.Tabs):
viewmode, message viewmode, message
) )
if error: if error:
signals.add_log(error, "error") self.master.add_log(error, "error")
# Give hint that you have to tab for the response. # Give hint that you have to tab for the response.
if description == "No content" and isinstance(message, http.HTTPRequest): if description == "No content" and isinstance(message, http.HTTPRequest):
description = "No request content (press tab to view response)" 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 master
from mitmproxy import log from mitmproxy import log
from mitmproxy.addons import intercept from mitmproxy.addons import intercept
from mitmproxy.addons import eventstore
from mitmproxy.addons import readfile from mitmproxy.addons import readfile
from mitmproxy.addons import view from mitmproxy.addons import view
from mitmproxy.tools.console import consoleaddons from mitmproxy.tools.console import consoleaddons
@ -32,6 +33,9 @@ class ConsoleMaster(master.Master):
super().__init__(opts) super().__init__(opts)
self.view = view.View() # type: view.View 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.stream_path = None
self.keymap = keymap.Keymap(self) self.keymap = keymap.Keymap(self)
defaultkeys.map(self.keymap) defaultkeys.map(self.keymap)
@ -40,12 +44,11 @@ class ConsoleMaster(master.Master):
self.view_stack = [] self.view_stack = []
signals.call_in.connect(self.sig_call_in) 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(*addons.default_addons())
self.addons.add( self.addons.add(
intercept.Intercept(), intercept.Intercept(),
self.view, self.view,
self.events,
consoleaddons.UnsupportedLog(), consoleaddons.UnsupportedLog(),
readfile.ReadFile(), readfile.ReadFile(),
consoleaddons.ConsoleAddon(self), consoleaddons.ConsoleAddon(self),
@ -79,12 +82,12 @@ class ConsoleMaster(master.Master):
callback = self.quit, callback = self.quit,
) )
def sig_add_log(self, sender, e, level): def sig_add_log(self, event_store, entry: log.LogEntry):
if log.log_tier(self.options.verbosity) < log.log_tier(level): if log.log_tier(self.options.verbosity) < log.log_tier(entry.level):
return return
if level in ("error", "warn"): if entry.level in ("error", "warn"):
signals.status_message.send( 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=()): def sig_call_in(self, sender, seconds, callback, args=()):

View File

@ -1,19 +1,5 @@
import blinker 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 # Show a status message in the action bar
status_message = blinker.Signal() status_message = blinker.Signal()