1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
|
#------------------------------------------------------------------------------
# Copyright (c) 2005, Enthought, Inc.
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in enthought/LICENSE.txt and may be redistributed only
# under the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
# Thanks for using Enthought open source!
#
# Author: Enthought, Inc.
# Description: <Enthought logger package component>
#------------------------------------------------------------------------------
# Standard library imports
from datetime import datetime
import logging
# Enthought library imports.
from enthought.pyface.api import ImageResource, clipboard
from enthought.pyface.workbench.api import TraitsUIView
from enthought.traits.api import Button, Instance, List, Property, Str, \
cached_property, on_trait_change
from enthought.traits.ui.api import View, Group, Item, CodeEditor, \
TabularEditor, spring
from enthought.traits.ui.tabular_adapter import TabularAdapter
# Local imports
from enthought.logger.agent.quality_agent_view import QualityAgentView
from enthought.logger.plugin import view
from enthought.logger.plugin.logger_service import LoggerService
# Constants
_IMAGE_MAP = { logging.DEBUG: ImageResource('debug'),
logging.INFO: ImageResource('info'),
logging.WARNING: ImageResource('warning'),
logging.ERROR: ImageResource('error'),
logging.CRITICAL: ImageResource('crit_error') }
class LogRecordAdapter(TabularAdapter):
""" A TabularEditor adapter for logging.LogRecord objects.
"""
columns = [ ('Level', 'level'), ('Date', 'date'), ('Time', 'time'),
('Message', 'message') ]
column_widths = [ 80, 100, 120, -1 ]
level_image = Property
level_text = Property(Str)
date_text = Property(Str)
time_text = Property(Str)
message_text = Property(Str)
def get_width(self, object, trait, column):
return self.column_widths[column]
def _get_level_image(self):
return _IMAGE_MAP[self.item.levelno]
def _get_level_text(self):
return self.item.levelname.capitalize()
def _get_date_text(self):
dt = datetime.fromtimestamp(self.item.created)
return dt.date().isoformat()
def _get_time_text(self):
dt = datetime.fromtimestamp(self.item.created)
return dt.time().isoformat()
def _get_message_text(self):
# Just display the first line of multiline messages, like stacktraces.
msg = self.item.getMessage()
msgs = msg.strip().split('\n')
if len(msgs) > 1:
suffix = '... [double click for details]'
else:
suffix = ''
abbrev_msg = msgs[0] + suffix
return abbrev_msg
class LoggerView(TraitsUIView):
""" The Workbench View showing the list of log items.
"""
id = Str('enthought.logger.plugin.view.logger_view.LoggerView')
name = Str('Logger')
service = Instance(LoggerService)
log_records = List(Instance(logging.LogRecord))
formatted_records = Property(Str, depends_on='log_records')
activated = Instance(logging.LogRecord)
activated_text = Property(Str, depends_on='activated')
reset_button = Button("Reset Logs")
show_button = Button("Complete Text Log")
copy_button = Button("Copy Log to Clipboard")
code_editor = CodeEditor(lexer='null',
show_line_numbers=False)
log_records_editor = TabularEditor(adapter=LogRecordAdapter(),
editable=False,
activated='activated')
trait_view = View(Group(Item('log_records',
editor=log_records_editor),
Group(Item('reset_button'),
spring,
Item('show_button'),
Item('copy_button'),
orientation='horizontal',
show_labels=False),
show_labels=False))
###########################################################################
# LogQueueHandler view interface
###########################################################################
def update(self, force=False):
""" Update 'log_records' if our handler has new records or 'force' is
set.
"""
service = self.service
if service.handler.has_new_records() or force:
self.log_records = [ rec for rec in service.handler.get()
if rec.levelno >= service.preferences.level_ ]
###########################################################################
# Private interface
###########################################################################
@on_trait_change('service.preferences.level_')
def _update_log_records(self):
self.service.handler._view = self
self.update(force=True)
def _reset_button_fired(self):
self.service.handler.reset()
self.log_records = []
def _show_button_fired(self):
self.edit_traits(view=View(Item('formatted_records',
editor=self.code_editor,
style='readonly',
show_label=False),
width=800, height=600, resizable=True,
buttons=[ 'OK' ],
title='Complete Text Log'))
def _copy_button_fired(self):
clipboard.text_data = self.formatted_records
@cached_property
def _get_formatted_records(self):
return '\n'.join([ self.service.handler.formatter.format(record)
for record in self.log_records ])
def _activated_changed(self):
if self.activated is None:
return
msg = self.activated.getMessage()
if self.service.preferences.enable_agent:
dialog = QualityAgentView(msg=msg, service=self.service)
dialog.open()
else:
self.edit_traits(view=View(Item('activated_text',
editor=self.code_editor,
style='readonly',
show_label=False),
width=800, height=600, resizable=True,
buttons=[ 'OK' ],
title='Log Message Detail'))
@cached_property
def _get_activated_text(self):
if self.activated is None:
return ''
else:
return self.activated.getMessage()
#### EOF ######################################################################
|