1616from datetime import timedelta
1717from datetime import timezone
1818import logging
19+ import numbers
1920import os
2021import pytest
2122import unittest
23+ import uuid
2224
2325from google .api_core .exceptions import BadGateway
2426from google .api_core .exceptions import Conflict
3638from google .cloud .logging_v2 import client
3739from google .cloud .logging_v2 .resource import Resource
3840
41+ from google .protobuf .struct_pb2 import Struct , Value , ListValue , NullValue
42+
3943from test_utils .retry import RetryErrors
4044from test_utils .retry import RetryResult
4145from test_utils .system import unique_resource_id
@@ -142,32 +146,119 @@ def tearDown(self):
142146 def _logger_name (prefix ):
143147 return prefix + unique_resource_id ("-" )
144148
145- def test_list_entry_with_unregistered (self ):
146- from google .protobuf import any_pb2
149+ @staticmethod
150+ def _to_value (data ):
151+ if data is None :
152+ return Value (null_value = NullValue .NULL_VALUE )
153+ elif isinstance (data , numbers .Number ):
154+ return Value (number_value = data )
155+ elif isinstance (data , str ):
156+ return Value (string_value = data )
157+ elif isinstance (data , bool ):
158+ return Value (bool_value = data )
159+ elif isinstance (data , (list , tuple , set )):
160+ return Value (
161+ list_value = ListValue (values = (TestLogging ._to_value (e ) for e in data ))
162+ )
163+ elif isinstance (data , dict ):
164+ return Value (struct_value = TestLogging ._dict_to_struct (data ))
165+ else :
166+ raise TypeError ("Unknown data type: %r" % type (data ))
167+
168+ @staticmethod
169+ def _dict_to_struct (data ):
170+ return Struct (fields = {k : TestLogging ._to_value (v ) for k , v in data .items ()})
171+
172+ def test_list_entry_with_auditlog (self ):
173+ """
174+ Test emitting and listing logs containing a google.cloud.audit.AuditLog proto message
175+ """
147176 from google .protobuf import descriptor_pool
148177 from google .cloud .logging_v2 import entries
149178
150179 pool = descriptor_pool .Default ()
151180 type_name = "google.cloud.audit.AuditLog"
152- # Make sure the descriptor is not known in the registry.
153- with self .assertRaises (KeyError ):
154- pool .FindMessageTypeByName (type_name )
155-
156181 type_url = "type.googleapis.com/" + type_name
157- filter_ = self .TYPE_FILTER .format (type_url ) + f" AND { _time_filter } "
158- entry_iter = iter (Config .CLIENT .list_entries (page_size = 1 , filter_ = filter_ ))
182+ # Make sure the descriptor is known in the registry.
183+ # Raises KeyError if unknown
184+ pool .FindMessageTypeByName (type_name )
185+
186+ # create log
187+ audit_dict = {
188+ "@type" : type_url ,
189+ "methodName" : "test" ,
190+ "requestMetadata" : {"callerIp" : "::1" , "callerSuppliedUserAgent" : "test" },
191+ "resourceName" : "test" ,
192+ "serviceName" : "test" ,
193+ "status" : {"code" : 0 },
194+ }
195+ audit_struct = self ._dict_to_struct (audit_dict )
196+
197+ logger = Config .CLIENT .logger (f"audit-proto-{ uuid .uuid1 ()} " )
198+ logger .log_proto (audit_struct )
199+
200+ # retrieve log
201+ retry = RetryErrors ((TooManyRequests , StopIteration ), max_tries = 8 )
202+ protobuf_entry = retry (lambda : next (logger .list_entries ()))()
159203
160- retry = RetryErrors (TooManyRequests )
161- protobuf_entry = retry (lambda : next (entry_iter ))()
204+ self .assertIsInstance (protobuf_entry , entries .ProtobufEntry )
205+ self .assertIsNone (protobuf_entry .payload_pb )
206+ self .assertIsInstance (protobuf_entry .payload_json , dict )
207+ self .assertEqual (protobuf_entry .payload_json ["@type" ], type_url )
208+ self .assertEqual (
209+ protobuf_entry .payload_json ["methodName" ], audit_dict ["methodName" ]
210+ )
211+ self .assertEqual (
212+ protobuf_entry .to_api_repr ()["protoPayload" ]["@type" ], type_url
213+ )
214+ self .assertEqual (
215+ protobuf_entry .to_api_repr ()["protoPayload" ]["methodName" ],
216+ audit_dict ["methodName" ],
217+ )
218+
219+ def test_list_entry_with_requestlog (self ):
220+ """
221+ Test emitting and listing logs containing a google.appengine.logging.v1.RequestLog proto message
222+ """
223+ from google .protobuf import descriptor_pool
224+ from google .cloud .logging_v2 import entries
225+
226+ pool = descriptor_pool .Default ()
227+ type_name = "google.appengine.logging.v1.RequestLog"
228+ type_url = "type.googleapis.com/" + type_name
229+ # Make sure the descriptor is known in the registry.
230+ # Raises KeyError if unknown
231+ pool .FindMessageTypeByName (type_name )
232+
233+ # create log
234+ req_dict = {
235+ "@type" : type_url ,
236+ "ip" : "0.0.0.0" ,
237+ "appId" : "test" ,
238+ "versionId" : "test" ,
239+ "requestId" : "12345" ,
240+ "latency" : "500.0s" ,
241+ "method" : "GET" ,
242+ "status" : 500 ,
243+ "resource" : "test" ,
244+ "httpVersion" : "HTTP/1.1" ,
245+ }
246+ req_struct = self ._dict_to_struct (req_dict )
247+
248+ logger = Config .CLIENT .logger (f"req-proto-{ uuid .uuid1 ()} " )
249+ logger .log_proto (req_struct )
250+
251+ # retrieve log
252+ retry = RetryErrors ((TooManyRequests , StopIteration ), max_tries = 8 )
253+ protobuf_entry = retry (lambda : next (logger .list_entries ()))()
162254
163255 self .assertIsInstance (protobuf_entry , entries .ProtobufEntry )
164- if Config .CLIENT ._use_grpc :
165- self .assertIsNone (protobuf_entry .payload_json )
166- self .assertIsInstance (protobuf_entry .payload_pb , any_pb2 .Any )
167- self .assertEqual (protobuf_entry .payload_pb .type_url , type_url )
168- else :
169- self .assertIsNone (protobuf_entry .payload_pb )
170- self .assertEqual (protobuf_entry .payload_json ["@type" ], type_url )
256+ self .assertIsNone (protobuf_entry .payload_pb )
257+ self .assertIsInstance (protobuf_entry .payload_json , dict )
258+ self .assertEqual (protobuf_entry .payload_json ["@type" ], type_url )
259+ self .assertEqual (
260+ protobuf_entry .to_api_repr ()["protoPayload" ]["@type" ], type_url
261+ )
171262
172263 def test_log_text (self ):
173264 TEXT_PAYLOAD = "System test: test_log_text"
@@ -288,7 +379,7 @@ def test_log_handler_async(self):
288379
289380 cloud_logger = logging .getLogger (handler .name )
290381 cloud_logger .addHandler (handler )
291- cloud_logger .warn (LOG_MESSAGE )
382+ cloud_logger .warning (LOG_MESSAGE )
292383 handler .flush ()
293384 entries = _list_entries (logger )
294385 expected_payload = {"message" : LOG_MESSAGE , "python_logger" : handler .name }
@@ -310,7 +401,7 @@ def test_log_handler_sync(self):
310401 LOGGER_NAME = "mylogger"
311402 cloud_logger = logging .getLogger (LOGGER_NAME )
312403 cloud_logger .addHandler (handler )
313- cloud_logger .warn (LOG_MESSAGE )
404+ cloud_logger .warning (LOG_MESSAGE )
314405
315406 entries = _list_entries (logger )
316407 expected_payload = {"message" : LOG_MESSAGE , "python_logger" : LOGGER_NAME }
@@ -342,7 +433,7 @@ def test_handlers_w_extras(self):
342433 "resource" : Resource (type = "cloudiot_device" , labels = {}),
343434 "labels" : {"test-label" : "manual" },
344435 }
345- cloud_logger .warn (LOG_MESSAGE , extra = extra )
436+ cloud_logger .warning (LOG_MESSAGE , extra = extra )
346437
347438 entries = _list_entries (logger )
348439 self .assertEqual (len (entries ), 1 )
@@ -363,7 +454,7 @@ def test_log_root_handler(self):
363454 self .to_delete .append (logger )
364455
365456 google .cloud .logging .handlers .handlers .setup_logging (handler )
366- logging .warn (LOG_MESSAGE )
457+ logging .warning (LOG_MESSAGE )
367458
368459 entries = _list_entries (logger )
369460 expected_payload = {"message" : LOG_MESSAGE , "python_logger" : "root" }
0 commit comments