@@ -311,6 +311,20 @@ def test_emit(self):
311
311
),
312
312
)
313
313
314
+ def test_emit_minimal (self ):
315
+ from google .cloud .logging_v2 .logger import _GLOBAL_RESOURCE
316
+
317
+ client = _Client (self .PROJECT )
318
+ handler = self ._make_one (
319
+ client , transport = _Transport , resource = _GLOBAL_RESOURCE
320
+ )
321
+ record = logging .LogRecord (None , logging .INFO , None , None , None , None , None )
322
+ handler .handle (record )
323
+ self .assertEqual (
324
+ handler .transport .send_called_with ,
325
+ (record , None , _GLOBAL_RESOURCE , None , None , None , None , None ,),
326
+ )
327
+
314
328
def test_emit_manual_field_override (self ):
315
329
from google .cloud .logging_v2 .logger import _GLOBAL_RESOURCE
316
330
from google .cloud .logging_v2 .resource import Resource
@@ -401,6 +415,70 @@ def test_emit_with_custom_formatter(self):
401
415
),
402
416
)
403
417
418
+ def test_emit_dict (self ):
419
+ """
420
+ Handler should support logging dictionaries
421
+ """
422
+ from google .cloud .logging_v2 .logger import _GLOBAL_RESOURCE
423
+
424
+ client = _Client (self .PROJECT )
425
+ handler = self ._make_one (
426
+ client , transport = _Transport , resource = _GLOBAL_RESOURCE ,
427
+ )
428
+ message = {"x" : "test" }
429
+ logname = "logname"
430
+ expected_label = {"python_logger" : logname }
431
+ record = logging .LogRecord (
432
+ logname , logging .INFO , None , None , message , None , None
433
+ )
434
+ handler .handle (record )
435
+
436
+ self .assertEqual (
437
+ handler .transport .send_called_with ,
438
+ (
439
+ record ,
440
+ message ,
441
+ _GLOBAL_RESOURCE ,
442
+ expected_label ,
443
+ None ,
444
+ None ,
445
+ None ,
446
+ None ,
447
+ ),
448
+ )
449
+
450
+ def test_emit_with_encoded_json (self ):
451
+ """
452
+ Handler should parse json encoded as a string
453
+ """
454
+ from google .cloud .logging_v2 .logger import _GLOBAL_RESOURCE
455
+
456
+ client = _Client (self .PROJECT )
457
+ handler = self ._make_one (
458
+ client , transport = _Transport , resource = _GLOBAL_RESOURCE ,
459
+ )
460
+ logFormatter = logging .Formatter (fmt = '{ "x" : "%(name)s" }' )
461
+ handler .setFormatter (logFormatter )
462
+ logname = "logname"
463
+ expected_result = {"x" : logname }
464
+ expected_label = {"python_logger" : logname }
465
+ record = logging .LogRecord (logname , logging .INFO , None , None , None , None , None )
466
+ handler .handle (record )
467
+
468
+ self .assertEqual (
469
+ handler .transport .send_called_with ,
470
+ (
471
+ record ,
472
+ expected_result ,
473
+ _GLOBAL_RESOURCE ,
474
+ expected_label ,
475
+ None ,
476
+ None ,
477
+ None ,
478
+ None ,
479
+ ),
480
+ )
481
+
404
482
def test_format_with_arguments (self ):
405
483
"""
406
484
Handler should support format string arguments
@@ -425,6 +503,112 @@ def test_format_with_arguments(self):
425
503
)
426
504
427
505
506
+ class TestFormatAndParseMessage (unittest .TestCase ):
507
+ def test_none (self ):
508
+ """
509
+ None messages with no special formatting should return
510
+ None after formatting
511
+ """
512
+ from google .cloud .logging_v2 .handlers .handlers import _format_and_parse_message
513
+
514
+ message = None
515
+ record = logging .LogRecord (None , None , None , None , message , None , None )
516
+ handler = logging .StreamHandler ()
517
+ result = _format_and_parse_message (record , handler )
518
+ self .assertEqual (result , None )
519
+
520
+ def test_none_formatted (self ):
521
+ """
522
+ None messages with formatting rules should return formatted string
523
+ """
524
+ from google .cloud .logging_v2 .handlers .handlers import _format_and_parse_message
525
+
526
+ message = None
527
+ record = logging .LogRecord ("logname" , None , None , None , message , None , None )
528
+ handler = logging .StreamHandler ()
529
+ formatter = logging .Formatter ("name: %(name)s" )
530
+ handler .setFormatter (formatter )
531
+ result = _format_and_parse_message (record , handler )
532
+ self .assertEqual (result , "name: logname" )
533
+
534
+ def test_unformatted_string (self ):
535
+ """
536
+ Unformated strings should be returned unchanged
537
+ """
538
+ from google .cloud .logging_v2 .handlers .handlers import _format_and_parse_message
539
+
540
+ message = '"test"'
541
+ record = logging .LogRecord ("logname" , None , None , None , message , None , None )
542
+ handler = logging .StreamHandler ()
543
+ result = _format_and_parse_message (record , handler )
544
+ self .assertEqual (result , message )
545
+
546
+ def test_empty_string (self ):
547
+ """
548
+ Empty strings should be returned unchanged
549
+ """
550
+ from google .cloud .logging_v2 .handlers .handlers import _format_and_parse_message
551
+
552
+ message = ""
553
+ record = logging .LogRecord ("logname" , None , None , None , message , None , None )
554
+ handler = logging .StreamHandler ()
555
+ result = _format_and_parse_message (record , handler )
556
+ self .assertEqual (result , message )
557
+
558
+ def test_string_formatted_with_args (self ):
559
+ """
560
+ string messages should properly apply formatting and arguments
561
+ """
562
+ from google .cloud .logging_v2 .handlers .handlers import _format_and_parse_message
563
+
564
+ message = "argument: %s"
565
+ arg = "test"
566
+ record = logging .LogRecord ("logname" , None , None , None , message , arg , None )
567
+ handler = logging .StreamHandler ()
568
+ formatter = logging .Formatter ("name: %(name)s :: message: %(message)s" )
569
+ handler .setFormatter (formatter )
570
+ result = _format_and_parse_message (record , handler )
571
+ self .assertEqual (result , "name: logname :: message: argument: test" )
572
+
573
+ def test_dict (self ):
574
+ """
575
+ dict messages should be unchanged
576
+ """
577
+ from google .cloud .logging_v2 .handlers .handlers import _format_and_parse_message
578
+
579
+ message = {"a" : "b" }
580
+ record = logging .LogRecord ("logname" , None , None , None , message , None , None )
581
+ handler = logging .StreamHandler ()
582
+ formatter = logging .Formatter ("name: %(name)s" )
583
+ handler .setFormatter (formatter )
584
+ result = _format_and_parse_message (record , handler )
585
+ self .assertEqual (result , message )
586
+
587
+ def test_string_encoded_dict (self ):
588
+ """
589
+ dicts should be extracted from string messages
590
+ """
591
+ from google .cloud .logging_v2 .handlers .handlers import _format_and_parse_message
592
+
593
+ message = '{ "x": { "y" : "z" } }'
594
+ record = logging .LogRecord ("logname" , None , None , None , message , None , None )
595
+ handler = logging .StreamHandler ()
596
+ result = _format_and_parse_message (record , handler )
597
+ self .assertEqual (result , {"x" : {"y" : "z" }})
598
+
599
+ def test_broken_encoded_dict (self ):
600
+ """
601
+ unparseable encoded dicts should be kept as strings
602
+ """
603
+ from google .cloud .logging_v2 .handlers .handlers import _format_and_parse_message
604
+
605
+ message = '{ "x": { "y" : '
606
+ record = logging .LogRecord ("logname" , None , None , None , message , None , None )
607
+ handler = logging .StreamHandler ()
608
+ result = _format_and_parse_message (record , handler )
609
+ self .assertEqual (result , message )
610
+
611
+
428
612
class TestSetupLogging (unittest .TestCase ):
429
613
def _call_fut (self , handler , excludes = None ):
430
614
from google .cloud .logging .handlers import setup_logging
0 commit comments