Skip to content

Commit

Permalink
Add record's __dict__ to structPayload
Browse files Browse the repository at this point in the history
  • Loading branch information
vmarkovtsev committed Aug 4, 2016
1 parent 930342a commit 48437c1
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 38 deletions.
43 changes: 41 additions & 2 deletions gcloud/logging/handlers/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

"""Python :mod:`logging` handlers for Google Cloud Logging."""

import itertools
import logging

from gcloud.logging.handlers.transports import BackgroundThreadTransport
Expand Down Expand Up @@ -52,6 +53,12 @@ class CloudLoggingHandler(logging.StreamHandler, object):
Defaults to BackgroundThreadTransport. The other
option is SyncTransport.
:type extra_fields: iterable, e.g. tuple, list, set
:param extra_fields: the container with LogRecord.__dict__ fields which
are forcefully submitted. Please note that some
whitelisted fields like process or threadName are
included by default.
Example:
.. doctest::
Expand All @@ -70,22 +77,54 @@ class CloudLoggingHandler(logging.StreamHandler, object):
"""

LOG_RECORD_DATA_WHITELIST = {
'process', 'processName', 'thread', 'threadName', 'created',
'relativeCreated', 'pathname', 'filename', 'lineno', 'module',
'funcName', 'levelno'
}

def __init__(self, client,
name=DEFAULT_LOGGER_NAME,
transport=BackgroundThreadTransport):
transport=BackgroundThreadTransport,
extra_fields=tuple()):
super(CloudLoggingHandler, self).__init__()
self.name = name
self.client = client
self.extra_fields = extra_fields
self.transport = transport(client, name)

def generate_log_struct_kwargs(self, record, message):
"""Produces the dictionary of chosen LogRecord fields. extra_fields
are taken into account.
:type record: :class:`logging.LogRecord`
:param record: Python log record
:type message: str
:param message: The formatted log message
:return: dict with keyword arguments for
:method:`gcloud.logging.Logger.log_struct()`.
"""
return {
'info': {
'message': message,
'python_logger': record.name,
'data': {k: getattr(record, k, None) for k in itertools.chain(
self.LOG_RECORD_DATA_WHITELIST, self.extra_fields)}
},
'severity': record.levelname
}

def emit(self, record):
"""
Overrides the default emit behavior of StreamHandler.
See: https://docs.python.org/2/library/logging.html#handler-objects
"""
message = super(CloudLoggingHandler, self).format(record)
self.transport.send(record, message)
kwargs = self.generate_log_struct_kwargs(record, message)
self.transport.send(kwargs)


def setup_logging(handler, excluded_loggers=EXCLUDE_LOGGER_DEFAULTS):
Expand Down
24 changes: 10 additions & 14 deletions gcloud/logging/handlers/transports/background_thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,16 +120,14 @@ def _stop(self):
self._stop_condition.release()
self.stopped = True

def enqueue(self, record, message):
def enqueue(self, kwargs):
"""enqueue queues up a log entry to be written by the background
thread. """
try:
self._entries_condition.acquire()
if self.stopping:
return
self.batch.log_struct({"message": message,
"python_logger": record.name},
severity=record.levelname)
self.batch.log_struct(**kwargs)
self._entries_condition.notify()
finally:
self._entries_condition.release()
Expand All @@ -149,15 +147,13 @@ def __init__(self, client, name):
logger = self.client.logger(name)
self.worker = _Worker(logger)

def send(self, record, message):
"""Overrides Transport.send(). record is the LogRecord
the handler was called with, message is the message from LogRecord
after being formatted by associated log formatters.
def send(self, kwargs):
"""Overrides Transport.send(). kwargs is the dictionary
with keyword arguments which will be passed to
:method:`gcloud.logging.Logger.log_struct()`.
:type record: :class:`logging.LogRecord`
:param record: Python log record
:type message: str
:param message: The formatted log message
:type kwargs: dict
:param kwargs: {'info': ..., 'severity': ...} - keyword arguments
passed to :method:`gcloud.logging.Logger.log_struct()`.
"""
self.worker.enqueue(record, message)
self.worker.enqueue(kwargs)
16 changes: 7 additions & 9 deletions gcloud/logging/handlers/transports/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,13 @@ class Transport(object):
def __init__(self, client, name):
pass # pragma: NO COVER

def send(self, record, message):
"""Must be overriden by transport options. record is the LogRecord
the handler was called with, message is the message from LogRecord
after being formatted by associated log formatters.
def send(self, kwargs):
"""Must be overriden by transport options. kwargs is the dictionary
with keyword arguments which will be passed to
:method:`gcloud.logging.Logger.log_struct()`.
:type record: :class:`logging.LogRecord`
:param record: Python log record
:type message: str
:param message: The formatted log message
:type kwargs: dict
:param kwargs: {'info': ..., 'severity': ...} - keyword arguments
passed to :method:`gcloud.logging.Logger.log_struct()`.
"""
raise NotImplementedError()
22 changes: 9 additions & 13 deletions gcloud/logging/handlers/transports/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,13 @@ def __init__(self, client, name):
super(SyncTransport, self).__init__(client, name)
self.logger = client.logger(name)

def send(self, record, message):
"""Overrides transport.send(). record is the LogRecord
the handler was called with, message is the message from LogRecord
after being formatted by associated log formatters.
:type record: :class:`logging.LogRecord`
:param record: Python log record
:type message: str
:param message: The formatted log message
def send(self, kwargs):
"""Overrides transport.send(). kwargs is the dictionary
with keyword arguments which will be passed to
:method:`gcloud.logging.Logger.log_struct()`.
:type kwargs: dict
:param kwargs: {'info': ..., 'severity': ...} - keyword arguments
passed to :method:`gcloud.logging.Logger.log_struct()`.
"""
self.logger.log_struct({"message": message,
"python_logger": record.name},
severity=record.levelname)
self.logger.log_struct(**kwargs)

0 comments on commit 48437c1

Please sign in to comment.