source: main/waeup.sirp/trunk/src/waeup/sirp/utils/logger.py @ 6398

Last change on this file since 6398 was 6376, checked in by uli, 14 years ago

Use loggername as key.

File size: 9.7 KB
RevLine 
[6371]1##
2## logging.py
3## Login : <uli@pu.smp.net>
4## Started on  Mon Jun 13 01:25:07 2011 Uli Fouquet
5## $Id$
6##
7## Copyright (C) 2011 Uli Fouquet
8## This program is free software; you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published by
10## the Free Software Foundation; either version 2 of the License, or
11## (at your option) any later version.
12##
13## This program is distributed in the hope that it will be useful,
14## but WITHOUT ANY WARRANTY; without even the implied warranty of
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16## GNU General Public License for more details.
17##
18## You should have received a copy of the GNU General Public License
19## along with this program; if not, write to the Free Software
20## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21##
22"""
23Convenience stuff for logging.
24"""
25import os
26import grok
27import logging
28
29marker_ = object()
30
31def setup_logger(loggername, filename, site=marker_, logdir=marker_,
32                 handler=marker_, formatter=marker_, propagate=False,
33                 level=logging.DEBUG):
34    """Create a logger.
35    """
36    if site is marker_:
37        site = grok.getSite()
38    if '%s' in loggername:
39        name = getattr(site, '__name__', 'app')
40        loggername = loggername % (name,)
41    logger = logging.getLogger(loggername)
42    update_logger(logger, filename, site=site, logdir=logdir, handler=handler,
43                  formatter=formatter, propagate=propagate, level=level)
44    return logger, loggername
45
46def update_logger(logger, filename, site=marker_, logdir=marker_,
47                  handler=marker_, formatter=marker_, propagate=False,
48                  level=logging.DEBUG):
49    if site is marker_:
50        site = grok.getSite()
51    if logdir is marker_:
52        logdir = os.path.join(site['datacenter'].storage, 'logs')
53    if not os.path.exists(logdir):
54        os.mkdir(logdir)
55    filename = os.path.join(logdir, filename)
56
57    # Create a rotating file handler logger for datacenter.
58    if handler is marker_:
59        handler = logging.handlers.RotatingFileHandler(
60            filename, maxBytes=5*1024**1, backupCount=5)
61    if formatter is marker_:
62        formatter = logging.Formatter(
63            '%(asctime)s - %(levelname)s - %(message)s')
64    handler.setFormatter(formatter)
65
66    logger.propagate = propagate
67    logger.setLevel(level)
68    logger.addHandler(handler)
69    return logger
70
71def get_logger(loggername, filename, site=marker_, **kw):
72    """Get a logger.
73    """
74    if '%s' in loggername:
75        if site is marker_:
76            site = grok.getSite()
77        loggername = loggername % (
78            getattr(site, '__name__', 'app'))
79    logger = logging.getLogger(loggername)
80    if not logger.handlers:
81        kw.update(dict(site=site))
82        logger, loggername = setup_logger(
83            loggername, filename, **kw)
84    return logger
85
86class WAeUPLogger(object):
87
88    _logger = None
89
90    def __init__(self, loggername, filename, site=marker_, logdir=marker_,
91                 handlers=marker_, formatters=marker_, propagate=False,
92                 level=logging.DEBUG):
93        self.loggername = loggername
94        self.filename = filename
95        self.site = site
96        self.sitename = None
97        self.logdir = logdir
98        self.handlers = handlers
99        self.formatters = formatters
100        self.propagate = propagate
101        self.level = level
102        self._logger = None
103        return
104
105
106    @property
107    def logger(self):
108        if self._logger is not None:
109            if '__app' in self._logger.name:
110                if getattr(self.site, '__name__', None) is not None:
111                    self.setup()
112            return self._logger
113        self.setup()
114        return self._logger
115
116    def setup(self):
117        if self.site is marker_:
118            self.site = grok.getSite()
119        if '%s' in loggername:
120            name = getattr(site, '__name__', '__app')
121            loggername = loggername % (name,)
122        self.logger = logging.getLogger(loggername)
123        self.update()
124        return
125
126    def update(self):
127        if self.site is marker_:
128            self.site = grok.getSite()
129        if self.logdir is marker_:
130            self.logdir = os.path.join(site['datacenter'].storage, 'logs')
131        if not os.path.exists(self.logdir):
132            os.mkdir(self.logdir)
133        filename = os.path.join(self.logdir, self.filename)
134
135        # Create a rotating file handler logger for datacenter.
136        if self.handlers is marker_:
137            self.handlers = [logging.handlers.RotatingFileHandler(
138                    filename, maxBytes=5*1024**1, backupCount=5)]
139        if formatters is marker_:
140            formatters = [logging.Formatter(
141                    '%(asctime)s - %(levelname)s - %(message)s')]
142
143        self.logger.propagate = self.propagate
144        self.logger.setLevel(self.level)
145
146        for handler, formatter in map(lambda x, y: (x,y),
147                                     self.handlers, self.formatters):
148            handler.setFormatter(formatter)
149            self.logger.addHandler(handler)
150        return self.logger
151
152
153from zope import schema
154from zope.interface import Interface, Attribute
155
156class ISiteLoggers(Interface):
157
158    loggers = Attribute("A list or generator of registered WAeUPLoggers")
159
160    def register(name, filename=None, site=None, **options):
161        """Register a logger `name` which logs to `filename`.
162
163        If `filename` is not given, logfile will be `name` with
164        ``.log`` as filename extension.
165        """
166
167    def unregister(name):
168        """Unregister a once registered logger.
169        """
170
171class SiteLoggers(object):
172
173    grok.implements(ISiteLoggers)
174
175    @property
176    def loggers(self):
177        return self._loggers.values()
178
179    def __init__(self):
180        self._loggers = dict()
181
182    def getLogger(self, filename):
183        waeup_logger = self._loggers.get(filename, None)
184        return waeup_logger.logger
185
[6376]186    def register(self, loggername, filename=None, site=None, **kw):
187        if loggername in self._loggers.keys():
188            raise KeyError('Logger "%s" exists already.' % loggername)
189        self._loggers[loggername] = WAeUPLogger(
[6371]190            loggername, filename=filename, site=site, **kw)
191        return
192
193    def unregister(self, name):
194        if name in self._loggers.keys():
195            del self._loggers[name]
196        return
197
198class ILogger(Interface):
199    """A logger cares for setup, update and restarting of a Python logger.
200    """
201
202    logger = Attribute("""A :class:`logging.Logger` instance""")
203
204
205    def __init__(name, filename=None, site=None, **options):
206        """Create a WAeUP logger instance.
207        """
208        pass
209
210    def setup():
211        """Create a Python :class:`logging.Logger` instance.
212
213        The created logger is based on the params given by constructor.
214        """
215        pass
216
217    def update(**options):
218        """Update the logger.
219
220        Updates the logger respecting modified `options` and changed
221        paths.
222        """
223
224class WAeUPLogger(object):
225
226    grok.implements(ILogger)
227
228    _logger = None
229
230    def __init__(self, name, filename=None, site=None, **options):
231        self.name = name
232        self.filename = filename
233        if filename is None:
234            if '.' in name:
235                name = name.rsplit('.', 1)[1]
236            self.filename = "%s.log" % name
237        self.site = site
238        self.max_bytes = options.get('maxBytes', 5 * 1024 ** 2)
239        self.backup_count = options.get('backupCount', 5)
240        self.options = options
241        return
242
243    @property
244    def logger(self):
245        if self._needSetup():
246            self._setup()
247        return logging.getLogger(self._loggername)
248
249    def setup(self):
250        return self._setup()
251
252    def update(self, **options):
253        self._logger = None # unset to be set up again on next access.
254        # XXX: set options
255        pass
256
257    def _needSetup(self):
258        if self._logger is None:
259            return True
260        if not '__app' in self._logger.name:
261            return False
262        if getattr(self.site, '__name__', None) is not None:
263            return True
264        return False
265
266    def _removeHandlers(self):
267        handlers = self._logger.handlers
268        for handler in handlers:
269            self._logger.removeHandler(handler)
270
271    def _setup(self):
272        if self.site is None:
273            self.site = grok.getSite()
274        self._loggername = self.name
275        if not '.' in self._loggername:
276            self._loggername = 'waeup.sirp.%s.%s' % ('%s', self._loggername)
277        if '%s' in self._loggername:
278            site_name = getattr(self.site, '__name__', '__app')
279            if site_name is None:
280                site_name = '__app'
281            self._loggername = self._loggername % (site_name,)
282        self._logger = logging.getLogger(self._loggername)
283        return self._update()
284
285    def _update(self):
286        self._removeHandlers() # Remove any old handlers
287        self._logdir = os.path.join(self.site['datacenter'].storage, 'logs')
288        if not os.path.exists(self._logdir):
289            os.mkdir(self._logdir)
290        filename = os.path.join(self._logdir, self.filename)
291
292        # Create a rotating file handler logger for datacenter.
293        default_handler = logging.handlers.RotatingFileHandler(
294            filename, maxBytes=self.max_bytes, backupCount=self.backup_count)
295        self.handler = self.options.get('handler', default_handler)
296
297        default_formatter = logging.Formatter(
298            '%(asctime)s - %(levelname)s - %(message)s')
299        formatter = self.options.get('formatter', default_formatter)
300        self.handler.setFormatter(formatter)
301
302        self._logger.addHandler(self.handler)
303        self._logger.propagate = self.options.get('propagate', False)
304        self._logger.setLevel(self.options.get('level', logging.DEBUG))
305        return self._logger
Note: See TracBrowser for help on using the repository browser.