Vehicle-Anti-Theft-Face-Rec.../venv/Lib/site-packages/gcloud/logging/logger.py

443 lines
16 KiB
Python

# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Define API Loggers."""
import json
from google.protobuf.json_format import MessageToJson
class Logger(object):
"""Loggers represent named targets for log entries.
See:
https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/projects.logs
:type name: string
:param name: the name of the logger
:type client: :class:`gcloud.logging.client.Client`
:param client: A client which holds credentials and project configuration
for the logger (which requires a project).
:type labels: dict or :class:`NoneType`
:param labels: (optional) mapping of default labels for entries written
via this logger.
"""
def __init__(self, name, client, labels=None):
self.name = name
self._client = client
self.labels = labels
@property
def client(self):
"""Clent bound to the logger."""
return self._client
@property
def project(self):
"""Project bound to the logger."""
return self._client.project
@property
def full_name(self):
"""Fully-qualified name used in logging APIs"""
return 'projects/%s/logs/%s' % (self.project, self.name)
@property
def path(self):
"""URI path for use in logging APIs"""
return '/%s' % (self.full_name,)
def _require_client(self, client):
"""Check client or verify over-ride.
:type client: :class:`gcloud.logging.client.Client` or ``NoneType``
:param client: the client to use. If not passed, falls back to the
``client`` stored on the current logger.
:rtype: :class:`gcloud.logging.client.Client`
:returns: The client passed in or the currently bound client.
"""
if client is None:
client = self._client
return client
def batch(self, client=None):
"""Return a batch to use as a context manager.
:type client: :class:`gcloud.logging.client.Client` or ``NoneType``
:param client: the client to use. If not passed, falls back to the
``client`` stored on the current topic.
:rtype: :class:`Batch`
:returns: A batch to use as a context manager.
"""
client = self._require_client(client)
return Batch(self, client)
def _make_entry_resource(self, text=None, info=None, message=None,
labels=None, insert_id=None, severity=None,
http_request=None):
"""Return a log entry resource of the appropriate type.
Helper for :meth:`log_text`, :meth:`log_struct`, and :meth:`log_proto`.
Only one of ``text``, ``info``, or ``message`` should be passed.
:type text: string or :class:`NoneType`
:param text: text payload
:type info: dict or :class:`NoneType`
:param info: struct payload
:type message: Protobuf message or :class:`NoneType`
:param message: protobuf payload
:type labels: dict or :class:`NoneType`
:param labels: labels passed in to calling method.
:type insert_id: string or :class:`NoneType`
:param insert_id: (optional) unique ID for log entry.
:type severity: string or :class:`NoneType`
:param severity: (optional) severity of event being logged.
:type http_request: dict or :class:`NoneType`
:param http_request: (optional) info about HTTP request associated with
the entry
"""
resource = {
'logName': self.full_name,
'resource': {'type': 'global'},
}
if text is not None:
resource['textPayload'] = text
if info is not None:
resource['jsonPayload'] = info
if message is not None:
as_json_str = MessageToJson(message)
as_json = json.loads(as_json_str)
resource['protoPayload'] = as_json
if labels is None:
labels = self.labels
if labels is not None:
resource['labels'] = labels
if insert_id is not None:
resource['insertId'] = insert_id
if severity is not None:
resource['severity'] = severity
if http_request is not None:
resource['httpRequest'] = http_request
return resource
def log_text(self, text, client=None, labels=None, insert_id=None,
severity=None, http_request=None):
"""API call: log a text message via a POST request
See:
https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/entries/write
:type text: text
:param text: the log message.
:type client: :class:`gcloud.logging.client.Client` or ``NoneType``
:param client: the client to use. If not passed, falls back to the
``client`` stored on the current logger.
:type labels: dict or :class:`NoneType`
:param labels: (optional) mapping of labels for the entry.
:type insert_id: string or :class:`NoneType`
:param insert_id: (optional) unique ID for log entry.
:type severity: string or :class:`NoneType`
:param severity: (optional) severity of event being logged.
:type http_request: dict or :class:`NoneType`
:param http_request: (optional) info about HTTP request associated with
the entry
"""
client = self._require_client(client)
entry_resource = self._make_entry_resource(
text=text, labels=labels, insert_id=insert_id, severity=severity,
http_request=http_request)
client.logging_api.write_entries([entry_resource])
def log_struct(self, info, client=None, labels=None, insert_id=None,
severity=None, http_request=None):
"""API call: log a structured message via a POST request
See:
https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/entries/write
:type info: dict
:param info: the log entry information
:type client: :class:`gcloud.logging.client.Client` or ``NoneType``
:param client: the client to use. If not passed, falls back to the
``client`` stored on the current logger.
:type labels: dict or :class:`NoneType`
:param labels: (optional) mapping of labels for the entry.
:type insert_id: string or :class:`NoneType`
:param insert_id: (optional) unique ID for log entry.
:type severity: string or :class:`NoneType`
:param severity: (optional) severity of event being logged.
:type http_request: dict or :class:`NoneType`
:param http_request: (optional) info about HTTP request associated with
the entry
"""
client = self._require_client(client)
entry_resource = self._make_entry_resource(
info=info, labels=labels, insert_id=insert_id, severity=severity,
http_request=http_request)
client.logging_api.write_entries([entry_resource])
def log_proto(self, message, client=None, labels=None, insert_id=None,
severity=None, http_request=None):
"""API call: log a protobuf message via a POST request
See:
https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/entries/write
:type message: Protobuf message
:param message: the message to be logged
:type client: :class:`gcloud.logging.client.Client` or ``NoneType``
:param client: the client to use. If not passed, falls back to the
``client`` stored on the current logger.
:type labels: dict or :class:`NoneType`
:param labels: (optional) mapping of labels for the entry.
:type insert_id: string or :class:`NoneType`
:param insert_id: (optional) unique ID for log entry.
:type severity: string or :class:`NoneType`
:param severity: (optional) severity of event being logged.
:type http_request: dict or :class:`NoneType`
:param http_request: (optional) info about HTTP request associated with
the entry
"""
client = self._require_client(client)
entry_resource = self._make_entry_resource(
message=message, labels=labels, insert_id=insert_id,
severity=severity, http_request=http_request)
client.logging_api.write_entries([entry_resource])
def delete(self, client=None):
"""API call: delete all entries in a logger via a DELETE request
See:
https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/projects.logs/delete
:type client: :class:`gcloud.logging.client.Client` or ``NoneType``
:param client: the client to use. If not passed, falls back to the
``client`` stored on the current logger.
"""
client = self._require_client(client)
client.logging_api.logger_delete(self.project, self.name)
def list_entries(self, projects=None, filter_=None, order_by=None,
page_size=None, page_token=None):
"""Return a page of log entries.
See:
https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/entries/list
:type projects: list of strings
:param projects: project IDs to include. If not passed,
defaults to the project bound to the client.
:type filter_: string
:param filter_: a filter expression. See:
https://cloud.google.com/logging/docs/view/advanced_filters
:type order_by: string
:param order_by: One of :data:`gcloud.logging.ASCENDING` or
:data:`gcloud.logging.DESCENDING`.
:type page_size: int
:param page_size: maximum number of entries to return, If not passed,
defaults to a value set by the API.
:type page_token: string
:param page_token: opaque marker for the next "page" of entries. If not
passed, the API will return the first page of
entries.
:rtype: tuple, (list, str)
:returns: list of :class:`gcloud.logging.entry.TextEntry`, plus a
"next page token" string: if not None, indicates that
more entries can be retrieved with another call (pass that
value as ``page_token``).
"""
log_filter = 'logName=%s' % (self.full_name,)
if filter_ is not None:
filter_ = '%s AND %s' % (filter_, log_filter)
else:
filter_ = log_filter
return self.client.list_entries(
projects=projects, filter_=filter_, order_by=order_by,
page_size=page_size, page_token=page_token)
class Batch(object):
"""Context manager: collect entries to log via a single API call.
Helper returned by :meth:`Logger.batch`
:type logger: :class:`gcloud.logging.logger.Logger`
:param logger: the logger to which entries will be logged.
:type client: :class:`gcloud.logging.client.Client`
:param client: The client to use.
"""
def __init__(self, logger, client):
self.logger = logger
self.entries = []
self.client = client
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type is None:
self.commit()
def log_text(self, text, labels=None, insert_id=None, severity=None,
http_request=None):
"""Add a text entry to be logged during :meth:`commit`.
:type text: string
:param text: the text entry
:type labels: dict or :class:`NoneType`
:param labels: (optional) mapping of labels for the entry.
:type insert_id: string or :class:`NoneType`
:param insert_id: (optional) unique ID for log entry.
:type severity: string or :class:`NoneType`
:param severity: (optional) severity of event being logged.
:type http_request: dict or :class:`NoneType`
:param http_request: (optional) info about HTTP request associated with
the entry.
"""
self.entries.append(
('text', text, labels, insert_id, severity, http_request))
def log_struct(self, info, labels=None, insert_id=None, severity=None,
http_request=None):
"""Add a struct entry to be logged during :meth:`commit`.
:type info: dict
:param info: the struct entry
:type labels: dict or :class:`NoneType`
:param labels: (optional) mapping of labels for the entry.
:type insert_id: string or :class:`NoneType`
:param insert_id: (optional) unique ID for log entry.
:type severity: string or :class:`NoneType`
:param severity: (optional) severity of event being logged.
:type http_request: dict or :class:`NoneType`
:param http_request: (optional) info about HTTP request associated with
the entry.
"""
self.entries.append(
('struct', info, labels, insert_id, severity, http_request))
def log_proto(self, message, labels=None, insert_id=None, severity=None,
http_request=None):
"""Add a protobuf entry to be logged during :meth:`commit`.
:type message: protobuf message
:param message: the protobuf entry
:type labels: dict or :class:`NoneType`
:param labels: (optional) mapping of labels for the entry.
:type insert_id: string or :class:`NoneType`
:param insert_id: (optional) unique ID for log entry.
:type severity: string or :class:`NoneType`
:param severity: (optional) severity of event being logged.
:type http_request: dict or :class:`NoneType`
:param http_request: (optional) info about HTTP request associated with
the entry.
"""
self.entries.append(
('proto', message, labels, insert_id, severity, http_request))
def commit(self, client=None):
"""Send saved log entries as a single API call.
:type client: :class:`gcloud.logging.client.Client` or ``NoneType``
:param client: the client to use. If not passed, falls back to the
``client`` stored on the current batch.
"""
if client is None:
client = self.client
kwargs = {
'logger_name': self.logger.path,
'resource': {'type': 'global'},
}
if self.logger.labels is not None:
kwargs['labels'] = self.logger.labels
entries = []
for entry_type, entry, labels, iid, severity, http_req in self.entries:
if entry_type == 'text':
info = {'textPayload': entry}
elif entry_type == 'struct':
info = {'jsonPayload': entry}
elif entry_type == 'proto':
as_json_str = MessageToJson(entry)
as_json = json.loads(as_json_str)
info = {'protoPayload': as_json}
else:
raise ValueError('Unknown entry type: %s' % (entry_type,))
if labels is not None:
info['labels'] = labels
if iid is not None:
info['insertId'] = iid
if severity is not None:
info['severity'] = severity
if http_req is not None:
info['httpRequest'] = http_req
entries.append(info)
client.logging_api.write_entries(entries, **kwargs)
del self.entries[:]