@@ -379,6 +379,107 @@ def test_log_struct_w_explicit(self):
379
379
380
380
self .assertEqual (api ._write_entries_called_with , (ENTRIES , None , None , None ))
381
381
382
+ def test_log_struct_inference (self ):
383
+ """
384
+ LogEntry fields in _STRUCT_EXTRACTABLE_FIELDS should be inferred from
385
+ the payload data if not passed as a parameter
386
+ """
387
+ from google .cloud .logging_v2 .handlers ._monitored_resources import (
388
+ detect_resource ,
389
+ )
390
+
391
+ STRUCT = {
392
+ "message" : "System test: test_log_struct_logentry_data" ,
393
+ "severity" : "warning" ,
394
+ "trace" : "123" ,
395
+ "span_id" : "456" ,
396
+ }
397
+ RESOURCE = detect_resource (self .PROJECT )._to_dict ()
398
+ ENTRIES = [
399
+ {
400
+ "logName" : "projects/%s/logs/%s" % (self .PROJECT , self .LOGGER_NAME ),
401
+ "jsonPayload" : STRUCT ,
402
+ "severity" : "WARNING" ,
403
+ "trace" : "123" ,
404
+ "spanId" : "456" ,
405
+ "resource" : RESOURCE ,
406
+ }
407
+ ]
408
+ client = _Client (self .PROJECT )
409
+ api = client .logging_api = _DummyLoggingAPI ()
410
+ logger = self ._make_one (self .LOGGER_NAME , client = client )
411
+
412
+ logger .log_struct (STRUCT , resource = RESOURCE )
413
+
414
+ self .assertEqual (api ._write_entries_called_with , (ENTRIES , None , None , None ))
415
+
416
+ def test_log_w_dict_resource (self ):
417
+ """
418
+ Users should be able to input a dictionary with type and labels instead
419
+ of a Resource object
420
+ """
421
+ import pytest
422
+
423
+ MESSAGE = "hello world"
424
+ client = _Client (self .PROJECT )
425
+ api = client .logging_api = _DummyLoggingAPI ()
426
+ logger = self ._make_one (self .LOGGER_NAME , client = client )
427
+ broken_resource_dicts = [{}, {"type" : "" }, {"labels" : "" }]
428
+ for resource in broken_resource_dicts :
429
+ # ensure bad inputs result in a helpful error
430
+ with pytest .raises (TypeError ):
431
+ logger .log (MESSAGE , resource = resource )
432
+ # ensure well-formed dict is converted to a resource
433
+ resource = {"type" : "gae_app" , "labels" : []}
434
+ ENTRIES = [
435
+ {
436
+ "logName" : "projects/%s/logs/%s" % (self .PROJECT , self .LOGGER_NAME ),
437
+ "textPayload" : MESSAGE ,
438
+ "resource" : resource ,
439
+ }
440
+ ]
441
+ logger .log (MESSAGE , resource = resource )
442
+ self .assertEqual (api ._write_entries_called_with , (ENTRIES , None , None , None ))
443
+
444
+ def test_log_lowercase_severity (self ):
445
+ """
446
+ lower case severity strings should be accepted
447
+ """
448
+ from google .cloud .logging_v2 .handlers ._monitored_resources import (
449
+ detect_resource ,
450
+ )
451
+
452
+ for lower_severity in [
453
+ "default" ,
454
+ "debug" ,
455
+ "info" ,
456
+ "notice" ,
457
+ "warning" ,
458
+ "error" ,
459
+ "critical" ,
460
+ "alert" ,
461
+ "emergency" ,
462
+ ]:
463
+ MESSAGE = "hello world"
464
+ RESOURCE = detect_resource (self .PROJECT )._to_dict ()
465
+ ENTRIES = [
466
+ {
467
+ "logName" : "projects/%s/logs/%s" % (self .PROJECT , self .LOGGER_NAME ),
468
+ "textPayload" : MESSAGE ,
469
+ "resource" : RESOURCE ,
470
+ "severity" : lower_severity .upper (),
471
+ }
472
+ ]
473
+ client = _Client (self .PROJECT )
474
+ api = client .logging_api = _DummyLoggingAPI ()
475
+ logger = self ._make_one (self .LOGGER_NAME , client = client )
476
+
477
+ logger .log (MESSAGE , severity = lower_severity )
478
+
479
+ self .assertEqual (
480
+ api ._write_entries_called_with , (ENTRIES , None , None , None )
481
+ )
482
+
382
483
def test_log_proto_defaults (self ):
383
484
from google .cloud .logging_v2 .handlers ._monitored_resources import (
384
485
detect_resource ,
0 commit comments