Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/google/cloud/logging_v2/client.py: 48%
108 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:45 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:45 +0000
1# Copyright 2016 Google LLC
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
15"""Client for interacting with the Google Cloud Logging API."""
17import logging
18import os
19import sys
22import google.api_core.client_options
23from google.cloud.client import ClientWithProject
24from google.cloud.environment_vars import DISABLE_GRPC
25from google.cloud.logging_v2._helpers import _add_defaults_to_filter
26from google.cloud.logging_v2._http import Connection
27from google.cloud.logging_v2._http import _LoggingAPI as JSONLoggingAPI
28from google.cloud.logging_v2._http import _MetricsAPI as JSONMetricsAPI
29from google.cloud.logging_v2._http import _SinksAPI as JSONSinksAPI
30from google.cloud.logging_v2.handlers import CloudLoggingHandler
31from google.cloud.logging_v2.handlers import StructuredLogHandler
32from google.cloud.logging_v2.handlers import setup_logging
33from google.cloud.logging_v2.handlers.handlers import EXCLUDED_LOGGER_DEFAULTS
34from google.cloud.logging_v2.resource import Resource
35from google.cloud.logging_v2.handlers._monitored_resources import detect_resource
38from google.cloud.logging_v2.logger import Logger
39from google.cloud.logging_v2.metric import Metric
40from google.cloud.logging_v2.sink import Sink
43_DISABLE_GRPC = os.getenv(DISABLE_GRPC, False)
44_HAVE_GRPC = False
46try:
47 if not _DISABLE_GRPC:
48 # only import if DISABLE_GRPC is not set
49 from google.cloud.logging_v2 import _gapic
51 _HAVE_GRPC = True
52except ImportError: # pragma: NO COVER
53 # could not import gapic library. Fall back to HTTP mode
54 _HAVE_GRPC = False
55 _gapic = None
57_USE_GRPC = _HAVE_GRPC and not _DISABLE_GRPC
59_GAE_RESOURCE_TYPE = "gae_app"
60_GKE_RESOURCE_TYPE = "k8s_container"
61_GCF_RESOURCE_TYPE = "cloud_function"
62_RUN_RESOURCE_TYPE = "cloud_run_revision"
65class Client(ClientWithProject):
66 """Client to bundle configuration needed for API requests."""
68 _logging_api = None
69 _sinks_api = None
70 _metrics_api = None
72 SCOPE = (
73 "https://www.googleapis.com/auth/logging.read",
74 "https://www.googleapis.com/auth/logging.write",
75 "https://www.googleapis.com/auth/logging.admin",
76 "https://www.googleapis.com/auth/cloud-platform",
77 )
78 """The scopes required for authenticating as a Logging consumer."""
80 def __init__(
81 self,
82 *,
83 project=None,
84 credentials=None,
85 _http=None,
86 _use_grpc=None,
87 client_info=None,
88 client_options=None,
89 ):
90 """
91 Args:
92 project (Optional[str]): the project which the client acts on behalf of.
93 If not passed, falls back to the default inferred
94 from the environment.
95 credentials (Optional[google.auth.credentials.Credentials]):
96 Thehe OAuth2 Credentials to use for this
97 client. If not passed (and if no ``_http`` object is
98 passed), falls back to the default inferred from the
99 environment.
100 _http (Optional[requests.Session]): HTTP object to make requests.
101 Can be any object that defines ``request()`` with the same interface as
102 :meth:`requests.Session.request`. If not passed, an
103 ``_http`` object is created that is bound to the
104 ``credentials`` for the current object.
105 This parameter should be considered private, and could
106 change in the future.
107 _use_grpc (Optional[bool]): Explicitly specifies whether
108 to use the gRPC transport or HTTP. If unset,
109 falls back to the ``GOOGLE_CLOUD_DISABLE_GRPC``
110 environment variable
111 This parameter should be considered private, and could
112 change in the future.
113 client_info (Optional[Union[google.api_core.client_info.ClientInfo, google.api_core.gapic_v1.client_info.ClientInfo]]):
114 The client info used to send a user-agent string along with API
115 requests. If ``None``, then default info will be used. Generally,
116 you only need to set this if you're developing your own library
117 or partner tool.
118 client_options (Optional[Union[dict, google.api_core.client_options.ClientOptions]]):
119 Client options used to set user options
120 on the client. API Endpoint should be set through client_options.
121 """
122 super(Client, self).__init__(
123 project=project,
124 credentials=credentials,
125 _http=_http,
126 client_options=client_options,
127 )
129 kw_args = {"client_info": client_info}
130 if client_options:
131 if isinstance(client_options, dict):
132 client_options = google.api_core.client_options.from_dict(
133 client_options
134 )
135 if client_options.api_endpoint:
136 api_endpoint = client_options.api_endpoint
137 kw_args["api_endpoint"] = api_endpoint
139 self._connection = Connection(self, **kw_args)
140 if client_info is None:
141 # if client info not passed in, use the discovered
142 # client info from _connection object
143 client_info = self._connection._client_info
145 self._client_info = client_info
146 self._client_options = client_options
147 if _use_grpc is None:
148 self._use_grpc = _USE_GRPC
149 else:
150 self._use_grpc = _use_grpc
152 @property
153 def logging_api(self):
154 """Helper for logging-related API calls.
156 See
157 https://cloud.google.com/logging/docs/reference/v2/rest/v2/entries
158 https://cloud.google.com/logging/docs/reference/v2/rest/v2/projects.logs
159 """
160 if self._logging_api is None:
161 if self._use_grpc:
162 self._logging_api = _gapic.make_logging_api(self)
163 else:
164 self._logging_api = JSONLoggingAPI(self)
165 return self._logging_api
167 @property
168 def sinks_api(self):
169 """Helper for log sink-related API calls.
171 See
172 https://cloud.google.com/logging/docs/reference/v2/rest/v2/projects.sinks
173 """
174 if self._sinks_api is None:
175 if self._use_grpc:
176 self._sinks_api = _gapic.make_sinks_api(self)
177 else:
178 self._sinks_api = JSONSinksAPI(self)
179 return self._sinks_api
181 @property
182 def metrics_api(self):
183 """Helper for log metric-related API calls.
185 See
186 https://cloud.google.com/logging/docs/reference/v2/rest/v2/projects.metrics
187 """
188 if self._metrics_api is None:
189 if self._use_grpc:
190 self._metrics_api = _gapic.make_metrics_api(self)
191 else:
192 self._metrics_api = JSONMetricsAPI(self)
193 return self._metrics_api
195 def logger(self, name, *, labels=None, resource=None):
196 """Creates a logger bound to the current client.
198 Args:
199 name (str): The name of the logger to be constructed.
200 resource (Optional[~logging_v2.Resource]): a monitored resource object
201 representing the resource the code was run on. If not given, will
202 be inferred from the environment.
203 labels (Optional[dict]): Mapping of default labels for entries written
204 via this logger.
206 Returns:
207 ~logging_v2.logger.Logger: Logger created with the current client.
208 """
209 return Logger(name, client=self, labels=labels, resource=resource)
211 def list_entries(
212 self,
213 *,
214 resource_names=None,
215 filter_=None,
216 order_by=None,
217 max_results=None,
218 page_size=None,
219 page_token=None,
220 ):
221 """Return a generator of log entry resources.
223 Args:
224 resource_names (Sequence[str]): Names of one or more parent resources
225 from which to retrieve log entries:
227 ::
229 "projects/[PROJECT_ID]"
230 "organizations/[ORGANIZATION_ID]"
231 "billingAccounts/[BILLING_ACCOUNT_ID]"
232 "folders/[FOLDER_ID]"
234 If not passed, defaults to the project bound to the API's client.
236 filter_ (str): a filter expression. See
237 https://cloud.google.com/logging/docs/view/advanced_filters
238 order_by (str) One of :data:`~logging_v2.ASCENDING`
239 or :data:`~logging_v2.DESCENDING`.
240 max_results (Optional[int]):
241 Optional. The maximum number of entries to return.
242 Non-positive values are treated as 0. If None, uses API defaults.
243 page_size (int): number of entries to fetch in each API call. Although
244 requests are paged internally, logs are returned by the generator
245 one at a time. If not passed, defaults to a value set by the API.
246 page_token (str): opaque marker for the starting "page" of entries. If not
247 passed, the API will return the first page of entries.
249 Returns:
250 Generator[~logging_v2.LogEntry]
251 """
252 if resource_names is None:
253 resource_names = [f"projects/{self.project}"]
254 filter_ = _add_defaults_to_filter(filter_)
256 return self.logging_api.list_entries(
257 resource_names=resource_names,
258 filter_=filter_,
259 order_by=order_by,
260 max_results=max_results,
261 page_size=page_size,
262 page_token=page_token,
263 )
265 def sink(self, name, *, filter_=None, destination=None):
266 """Creates a sink bound to the current client.
268 Args:
269 name (str): the name of the sink to be constructed.
270 filter_ (Optional[str]): the advanced logs filter expression
271 defining the entries exported by the sink. If not
272 passed, the instance should already exist, to be
273 refreshed via :meth:`Sink.reload`.
274 destination (str): destination URI for the entries exported by
275 the sink. If not passed, the instance should
276 already exist, to be refreshed via
277 :meth:`Sink.reload`.
279 Returns:
280 ~logging_v2.sink.Sink: Sink created with the current client.
281 """
282 return Sink(name, filter_=filter_, destination=destination, client=self)
284 def list_sinks(
285 self, *, parent=None, max_results=None, page_size=None, page_token=None
286 ):
287 """List sinks for the a parent resource.
289 See
290 https://cloud.google.com/logging/docs/reference/v2/rest/v2/projects.sinks/list
292 Args:
293 parent (Optional[str]): The parent resource whose sinks are to be listed:
295 ::
297 "projects/[PROJECT_ID]"
298 "organizations/[ORGANIZATION_ID]"
299 "billingAccounts/[BILLING_ACCOUNT_ID]"
300 "folders/[FOLDER_ID]".
302 If not passed, defaults to the project bound to the API's client.
303 max_results (Optional[int]):
304 Optional. The maximum number of entries to return.
305 Non-positive values are treated as 0. If None, uses API defaults.
306 page_size (int): number of entries to fetch in each API call. Although
307 requests are paged internally, logs are returned by the generator
308 one at a time. If not passed, defaults to a value set by the API.
309 page_token (str): opaque marker for the starting "page" of entries. If not
310 passed, the API will return the first page of entries.
312 Returns:
313 Generator[~logging_v2.Sink]
314 """
315 if parent is None:
316 parent = f"projects/{self.project}"
317 return self.sinks_api.list_sinks(
318 parent=parent,
319 max_results=max_results,
320 page_size=page_size,
321 page_token=page_token,
322 )
324 def metric(self, name, *, filter_=None, description=""):
325 """Creates a metric bound to the current client.
327 Args:
328 name (str): The name of the metric to be constructed.
329 filter_(Optional[str]): The advanced logs filter expression defining the
330 entries tracked by the metric. If not
331 passed, the instance should already exist, to be
332 refreshed via :meth:`Metric.reload`.
333 description (Optional[str]): The description of the metric to be constructed.
334 If not passed, the instance should already exist,
335 to be refreshed via :meth:`Metric.reload`.
337 Returns:
338 ~logging_v2.metric.Metric: Metric created with the current client.
339 """
340 return Metric(name, filter_=filter_, client=self, description=description)
342 def list_metrics(self, *, max_results=None, page_size=None, page_token=None):
343 """List metrics for the project associated with this client.
345 See
346 https://cloud.google.com/logging/docs/reference/v2/rest/v2/projects.metrics/list
348 Args:
349 max_results (Optional[int]):
350 Optional. The maximum number of entries to return.
351 Non-positive values are treated as 0. If None, uses API defaults.
352 page_size (int): number of entries to fetch in each API call. Although
353 requests are paged internally, logs are returned by the generator
354 one at a time. If not passed, defaults to a value set by the API.
355 page_token (str): opaque marker for the starting "page" of entries. If not
356 passed, the API will return the first page of entries.
358 Returns:
359 Generator[logging_v2.Metric]
360 """
361 return self.metrics_api.list_metrics(
362 self.project,
363 max_results=max_results,
364 page_size=page_size,
365 page_token=page_token,
366 )
368 def get_default_handler(self, **kw):
369 """Return the default logging handler based on the local environment.
371 Args:
372 kw (dict): keyword args passed to handler constructor
374 Returns:
375 logging.Handler: The default log handler based on the environment
376 """
377 monitored_resource = kw.pop("resource", detect_resource(self.project))
379 if isinstance(monitored_resource, Resource):
380 if monitored_resource.type == _GAE_RESOURCE_TYPE:
381 return CloudLoggingHandler(self, resource=monitored_resource, **kw)
382 elif monitored_resource.type == _GKE_RESOURCE_TYPE:
383 return StructuredLogHandler(**kw, project_id=self.project)
384 elif monitored_resource.type == _GCF_RESOURCE_TYPE:
385 # __stdout__ stream required to support structured logging on Python 3.7
386 kw["stream"] = kw.get("stream", sys.__stdout__)
387 return StructuredLogHandler(**kw, project_id=self.project)
388 elif monitored_resource.type == _RUN_RESOURCE_TYPE:
389 return StructuredLogHandler(**kw, project_id=self.project)
390 return CloudLoggingHandler(self, resource=monitored_resource, **kw)
392 def setup_logging(
393 self, *, log_level=logging.INFO, excluded_loggers=EXCLUDED_LOGGER_DEFAULTS, **kw
394 ):
395 """Attach default Cloud Logging handler to the root logger.
397 This method uses the default log handler, obtained by
398 :meth:`~get_default_handler`, and attaches it to the root Python
399 logger, so that a call such as ``logging.warn``, as well as all child
400 loggers, will report to Cloud Logging.
402 Args:
403 log_level (Optional[int]): Python logging log level. Defaults to
404 :const:`logging.INFO`.
405 excluded_loggers (Optional[Tuple[str]]): The loggers to not attach the
406 handler to. This will always include the
407 loggers in the path of the logging client
408 itself.
409 Returns:
410 dict: keyword args passed to handler constructor
411 """
412 handler = self.get_default_handler(**kw)
413 setup_logging(handler, log_level=log_level, excluded_loggers=excluded_loggers)