16
16
from datetime import timedelta
17
17
from datetime import timezone
18
18
import logging
19
+ import numbers
19
20
import os
20
21
import pytest
21
22
import unittest
23
+ import uuid
22
24
23
25
from google .api_core .exceptions import BadGateway
24
26
from google .api_core .exceptions import Conflict
36
38
from google .cloud .logging_v2 import client
37
39
from google .cloud .logging_v2 .resource import Resource
38
40
41
+ from google .protobuf .struct_pb2 import Struct , Value , ListValue , NullValue
42
+
39
43
from test_utils .retry import RetryErrors
40
44
from test_utils .retry import RetryResult
41
45
from test_utils .system import unique_resource_id
@@ -142,32 +146,119 @@ def tearDown(self):
142
146
def _logger_name (prefix ):
143
147
return prefix + unique_resource_id ("-" )
144
148
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
+ """
147
176
from google .protobuf import descriptor_pool
148
177
from google .cloud .logging_v2 import entries
149
178
150
179
pool = descriptor_pool .Default ()
151
180
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
-
156
181
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 ()))()
159
203
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 ()))()
162
254
163
255
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
+ )
171
262
172
263
def test_log_text (self ):
173
264
TEXT_PAYLOAD = "System test: test_log_text"
@@ -288,7 +379,7 @@ def test_log_handler_async(self):
288
379
289
380
cloud_logger = logging .getLogger (handler .name )
290
381
cloud_logger .addHandler (handler )
291
- cloud_logger .warn (LOG_MESSAGE )
382
+ cloud_logger .warning (LOG_MESSAGE )
292
383
handler .flush ()
293
384
entries = _list_entries (logger )
294
385
expected_payload = {"message" : LOG_MESSAGE , "python_logger" : handler .name }
@@ -310,7 +401,7 @@ def test_log_handler_sync(self):
310
401
LOGGER_NAME = "mylogger"
311
402
cloud_logger = logging .getLogger (LOGGER_NAME )
312
403
cloud_logger .addHandler (handler )
313
- cloud_logger .warn (LOG_MESSAGE )
404
+ cloud_logger .warning (LOG_MESSAGE )
314
405
315
406
entries = _list_entries (logger )
316
407
expected_payload = {"message" : LOG_MESSAGE , "python_logger" : LOGGER_NAME }
@@ -342,7 +433,7 @@ def test_handlers_w_extras(self):
342
433
"resource" : Resource (type = "cloudiot_device" , labels = {}),
343
434
"labels" : {"test-label" : "manual" },
344
435
}
345
- cloud_logger .warn (LOG_MESSAGE , extra = extra )
436
+ cloud_logger .warning (LOG_MESSAGE , extra = extra )
346
437
347
438
entries = _list_entries (logger )
348
439
self .assertEqual (len (entries ), 1 )
@@ -363,7 +454,7 @@ def test_log_root_handler(self):
363
454
self .to_delete .append (logger )
364
455
365
456
google .cloud .logging .handlers .handlers .setup_logging (handler )
366
- logging .warn (LOG_MESSAGE )
457
+ logging .warning (LOG_MESSAGE )
367
458
368
459
entries = _list_entries (logger )
369
460
expected_payload = {"message" : LOG_MESSAGE , "python_logger" : "root" }
0 commit comments