|
27 | 27 | # /appengine-vmruntime/vmruntime/cloud_logging.py |
28 | 28 |
|
29 | 29 | import logging.handlers |
30 | | -import os |
31 | 30 |
|
32 | | -from google.cloud.logging.handlers._helpers import format_stackdriver_json |
| 31 | +from google.cloud.logging.handlers.handlers import CloudLoggingHandler |
| 32 | +from google.cloud.logging.handlers.transports import BackgroundThreadTransport |
| 33 | +from google.cloud.logging.resource import Resource |
33 | 34 |
|
34 | | -_LOG_PATH_TEMPLATE = '/var/log/app_engine/app.{pid}.json' |
35 | | -_MAX_LOG_BYTES = 128 * 1024 * 1024 |
36 | | -_LOG_FILE_COUNT = 3 |
| 35 | +DEFAULT_LOGGER_NAME = 'python' |
37 | 36 |
|
| 37 | +EXCLUDED_LOGGER_DEFAULTS = ('google.cloud', 'oauth2client') |
38 | 38 |
|
39 | | -class AppEngineHandler(logging.handlers.RotatingFileHandler): |
40 | | - """A handler that writes to the App Engine fluentd Stackdriver log file. |
| 39 | +_GLOBAL_RESOURCE = Resource(type='global', labels={}) |
41 | 40 |
|
42 | | - Writes to the file that the fluentd agent on App Engine Flexible is |
43 | | - configured to discover logs and send them to Stackdriver Logging. |
44 | | - Log entries are wrapped in JSON and with appropriate metadata. The |
45 | | - process of converting the user's formatted logs into a JSON payload for |
46 | | - Stackdriver Logging consumption is implemented as part of the handler |
47 | | - itself, and not as a formatting step, so as not to interfere with |
48 | | - user-defined logging formats. |
| 41 | + |
| 42 | +class AppEngineHandler(CloudLoggingHandler): |
| 43 | + """A handler that directly makes Stackdriver logging API calls. |
| 44 | +
|
| 45 | + This handler can be used to route Python standard logging messages directly |
| 46 | + to the Stackdriver Logging API. |
| 47 | +
|
| 48 | + This handler supports both an asynchronous and synchronous transport. |
| 49 | +
|
| 50 | + :type client: :class:`google.cloud.logging.client` |
| 51 | + :param client: the authenticated Google Cloud Logging client for this |
| 52 | + handler to use |
| 53 | +
|
| 54 | + :type name: str |
| 55 | + :param name: the name of the custom log in Stackdriver Logging. Defaults |
| 56 | + to 'python'. The name of the Python logger will be represented |
| 57 | + in the ``python_logger`` field. |
| 58 | +
|
| 59 | + :type transport: type |
| 60 | + :param transport: Class for creating new transport objects. It should |
| 61 | + extend from the base :class:`.Transport` type and |
| 62 | + implement :meth`.Transport.send`. Defaults to |
| 63 | + :class:`.BackgroundThreadTransport`. The other |
| 64 | + option is :class:`.SyncTransport`. |
| 65 | +
|
| 66 | + :type resource: :class:`~google.cloud.logging.resource.Resource` |
| 67 | + :param resource: Monitored resource of the entry, defaults |
| 68 | + to the global resource type. |
49 | 69 | """ |
50 | 70 |
|
51 | | - def __init__(self): |
52 | | - """Construct the handler |
| 71 | + def __init__(self, client, |
| 72 | + name=DEFAULT_LOGGER_NAME, |
| 73 | + transport=BackgroundThreadTransport, |
| 74 | + resource=_GLOBAL_RESOURCE): |
| 75 | + super(AppEngineHandler, self).__init__(client, name, transport) |
| 76 | + self.resource=resource |
53 | 77 |
|
54 | | - Large log entries will get mangled if multiple workers write to the |
55 | | - same file simultaneously, so we'll use the worker's PID to pick a log |
56 | | - filename. |
57 | | - """ |
58 | | - self.filename = _LOG_PATH_TEMPLATE.format(pid=os.getpid()) |
59 | | - super(AppEngineHandler, self).__init__(self.filename, |
60 | | - maxBytes=_MAX_LOG_BYTES, |
61 | | - backupCount=_LOG_FILE_COUNT) |
| 78 | + def emit(self, record): |
| 79 | + """Actually log the specified logging record. |
62 | 80 |
|
63 | | - def format(self, record): |
64 | | - """Format the specified record into the expected JSON structure. |
| 81 | + Overrides the default emit behavior of ``StreamHandler``. |
65 | 82 |
|
66 | | - :type record: :class:`~logging.LogRecord` |
67 | | - :param record: the log record |
| 83 | + See: https://docs.python.org/2/library/logging.html#handler-objects |
68 | 84 |
|
69 | | - :rtype: str |
70 | | - :returns: JSON str to be written to the log file |
| 85 | + :type record: :class:`logging.LogRecord` |
| 86 | + :param record: The record to be logged. |
71 | 87 | """ |
72 | | - message = super(AppEngineHandler, self).format(record) |
73 | | - return format_stackdriver_json(record, message) |
| 88 | + message = super(CloudLoggingHandler, self).format(record) |
| 89 | + self.transport.send(record, message, self.resource) |
0 commit comments