fluent-plugin-google-cloud 0.5.3.grpc.alpha.4 → 0.5.3.grpc.alpha.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 29718f443dea67bcf817ee44390e61373a307db7
4
- data.tar.gz: 54b6472916c8657230db649ff339ab1d31b5362d
3
+ metadata.gz: af37e8c845023885ae3cec2dcef35368f30e7ee3
4
+ data.tar.gz: 57cd2c566bb2c89ee063dbb12fbd02a75e8744c9
5
5
  SHA512:
6
- metadata.gz: 1d5695d8834eafc6f059c5a591ff9d3188739814fd7dcc4e2dc976324c8e45f3b5f0b7d914062c9581b2242f76dfd75d0356178c5a6b7f2cbadd3d49b064ec61
7
- data.tar.gz: 46c8d492364314a4220f3ea61a81814fbd9db64c3af06331e025853582404d33806a5bcacc7be64379aa2a646f415d5e6507e6fcae6d95085fafe838b4f5e19a
6
+ metadata.gz: c8ca9cfcb3c564822cfd06870010e21358352612a401bdfda9c0d49f4715f9a0831e3daab338a69d9b584a2b568255aa2bae35e512771cfb837de74b64712be0
7
+ data.tar.gz: 43fa64e97398e3526a6153db587806b9a56291c330b6b066f5a7a106abf769c040cd4bb6a849a4d6bf7b8ba65427dc1a3b5cd5ff3a3ed156ee01e56f790005cf
@@ -10,7 +10,7 @@ eos
10
10
  gem.homepage = \
11
11
  'https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud'
12
12
  gem.license = 'Apache-2.0'
13
- gem.version = '0.5.3.grpc.alpha.4'
13
+ gem.version = '0.5.3.grpc.alpha.5'
14
14
  gem.authors = ['Todd Derr', 'Alex Robinson']
15
15
  gem.email = ['salty@google.com']
16
16
  gem.required_ruby_version = Gem::Requirement.new('>= 2.0')
@@ -39,7 +39,7 @@ module Fluent
39
39
  Fluent::Plugin.register_output('google_cloud', self)
40
40
 
41
41
  PLUGIN_NAME = 'Fluentd Google Cloud Logging plugin'
42
- PLUGIN_VERSION = '0.5.3.grpc.alpha.4'
42
+ PLUGIN_VERSION = '0.5.3.grpc.alpha.5'
43
43
 
44
44
  # Constants for service names.
45
45
  APPENGINE_SERVICE = 'appengine.googleapis.com'
@@ -599,338 +599,6 @@ module Fluent
599
599
  end
600
600
  end
601
601
 
602
- # def old_write(chunk)
603
- # # Group the entries since we have to make one call per tag.
604
- # grouped_entries = {}
605
- # chunk.msgpack_each do |tag, *arr|
606
- # grouped_entries[tag] = [] unless grouped_entries.key?(tag)
607
- # grouped_entries[tag].push(arr)
608
- # end
609
- #
610
- # grouped_entries.each do |tag, arr|
611
- # entries = []
612
- # labels = @common_labels.clone
613
- #
614
- # if @running_cloudfunctions
615
- # # If the current group of entries is coming from a Cloud Functions
616
- # # function, the function name can be extracted from the tag.
617
- # match_data = @cloudfunctions_tag_regexp.match(tag)
618
- # if match_data
619
- # # Service name is set to Cloud Functions only for logs actually
620
- # # coming from a function.
621
- # @service_name = CLOUDFUNCTIONS_SERVICE
622
- # labels["#{CLOUDFUNCTIONS_SERVICE}/region"] = @gcf_region
623
- # labels["#{CLOUDFUNCTIONS_SERVICE}/function_name"] =
624
- # decode_cloudfunctions_function_name(
625
- # match_data['encoded_function_name'])
626
- # else
627
- # # Other logs are considered as coming from the Container Engine
628
- # # service.
629
- # @service_name = CONTAINER_SERVICE
630
- # end
631
- # end
632
- # if @service_name == CONTAINER_SERVICE && \
633
- # @compiled_kubernetes_tag_regexp
634
- # # Container logs in Kubernetes are tagged based on where they came
635
- # # from, so we can extract useful metadata from the tag.
636
- # # Do this here to avoid having to repeat it for each record.
637
- # match_data = @compiled_kubernetes_tag_regexp.match(tag)
638
- # if match_data
639
- # %w(namespace_name pod_name container_name).each do |field|
640
- # labels["#{CONTAINER_SERVICE}/#{field}"] = match_data[field]
641
- # end
642
- # end
643
- # end
644
- #
645
- # if @use_grpc
646
- # arr.each do |time, record|
647
- # next unless record.is_a?(Hash)
648
- #
649
- # entry = Google::Logging::V1::LogEntry.new(
650
- # metadata: Google::Logging::V1::LogEntryMetadata.new(
651
- # service_name: @service_name.encode('utf-8'),
652
- # project_id: @project_id.encode('utf-8'),
653
- # zone: @zone.encode('utf-8'),
654
- # labels: {}
655
- # ))
656
- #
657
- # if @service_name == CLOUDFUNCTIONS_SERVICE && record.key?('log')
658
- # @cloudfunctions_log_match =
659
- # @cloudfunctions_log_regexp.match(record['log'])
660
- # end
661
- # if @service_name == CONTAINER_SERVICE
662
- # # Move the stdout/stderr annotation from the record into a
663
- # # label.
664
- # field_to_label(record, 'stream', entry.metadata.labels,
665
- # "#{CONTAINER_SERVICE}/stream")
666
- # # If the record has been annotated by the
667
- # # kubernetes_metadata_filter
668
- # # plugin, then use that metadata. Otherwise, rely on
669
- # # commonLabels
670
- # # populated at the grouped_entries level from the group's tag.
671
- # if record.key?('kubernetes')
672
- # handle_container_metadata(record, entry)
673
- # end
674
- #
675
- # # Save the timestamp if available, then clear it out to allow
676
- # # for determining whether we should parse the log or message
677
- # # field.
678
- # timestamp = record.key?('time') ? record['time'] : nil
679
- # record.delete('time')
680
- # # If the log is json, we want to export it as a structured log
681
- # # unless there is additional metadata that would be lost.
682
- # is_json = false
683
- # if record.length == 1 && record.key?('log')
684
- # record_json = parse_json_or_nil(record['log'])
685
- # end
686
- # if record.length == 1 && record.key?('message')
687
- # record_json = parse_json_or_nil(record['message'])
688
- # end
689
- # unless record_json.nil?
690
- # record = record_json
691
- # is_json = true
692
- # end
693
- # # Restore timestamp if necessary.
694
- # unless record.key?('time') || timestamp.nil?
695
- # record['time'] = timestamp
696
- # end
697
- # end
698
- #
699
- # ts_secs, ts_nanos = compute_timestamp(record, time)
700
- # entry.metadata.timestamp = Google::Protobuf::Timestamp.new(
701
- # seconds: ts_secs,
702
- # nanos: ts_nanos
703
- # )
704
- #
705
- # entry.metadata.severity =
706
- # grpc_severity(compute_severity(record, entry))
707
- #
708
- # set_http_request_grpc(record, entry) # FIXME
709
- #
710
- # # If a field is present in the label_map, send its value as a
711
- # # label
712
- # # (mapping the field name to label name as specified in the
713
- # # config)
714
- # # and do not send that field as part of the payload.
715
- # if @label_map
716
- # @label_map.each do |field, label|
717
- # field_to_label(record, field, entry.metadata.labels, label)
718
- # end
719
- # end
720
- #
721
- # if @service_name == CLOUDFUNCTIONS_SERVICE &&
722
- # @cloudfunctions_log_match &&
723
- # @cloudfunctions_log_match['execution_id']
724
- # entry.metadata.labels['execution_id'] =
725
- # @cloudfunctions_log_match['execution_id']
726
- # end
727
- #
728
- # set_payload_grpc(record, entry, is_json)
729
- #
730
- # entries.push(entry)
731
- # end
732
- # # Don't send an empty request if we rejected all the entries.
733
- # next if entries.empty?
734
- #
735
- # log_name = log_name(tag, labels)
736
- #
737
- # begin
738
- # # Does the actual write to the cloud logging api.
739
- #
740
- # client = api_client
741
- #
742
- # labels_utf8_pairs = labels.map do |k, v|
743
- # [k.encode('utf-8'), v.encode('utf-8')]
744
- # end
745
- #
746
- # write_request = Google::Logging::V1::WriteLogEntriesRequest.new(
747
- # log_name: log_name.encode('utf-8'),
748
- # common_labels: Hash[labels_utf8_pairs],
749
- # entries: entries
750
- # )
751
- #
752
- # client.write_log_entries(write_request)
753
- #
754
- # # Let the user explicitly know when the first call succeeded,
755
- # # to aid with verification and troubleshooting.
756
- # unless @successful_call
757
- # @successful_call = true
758
- # @log.info 'Successfully sent gRPC to Stackdriver Logging API.'
759
- # end
760
- #
761
- # rescue GRPC::Cancelled => error
762
- # # RPC cancelled, so retry via re-raising the error.
763
- # raise error
764
- #
765
- # rescue GRPC::BadStatus => error
766
- # case error.code
767
- # when GRPC::Core::StatusCodes::CANCELLED,
768
- # GRPC::Core::StatusCodes::UNAVAILABLE,
769
- # GRPC::Core::StatusCodes::DEADLINE_EXCEEDED,
770
- # GRPC::Core::StatusCodes::INTERNAL,
771
- # GRPC::Core::StatusCodes::UNKNOWN
772
- # # TODO
773
- # # Server error, so retry via re-raising the error.
774
- # raise error
775
- # when GRPC::Core::StatusCodes::UNIMPLEMENTED,
776
- # GRPC::Core::StatusCodes::RESOURCE_EXHAUSTED
777
- # # Most client errors indicate a problem with the request itself
778
- # # and should not be retried.
779
- # dropped = entries.length
780
- # @log.warn "Dropping #{dropped} log message(s)",
781
- # error: error.to_s, error_code: error.code.to_s
782
- # when GRPC::Core::StatusCodes::UNAUTHENTICATED
783
- # # Authorization error.
784
- # # These are usually solved via a `gcloud auth` call, or by
785
- # # modifying the permissions on the Google Cloud project.
786
- # dropped = entries.length
787
- # @log.warn "Dropping #{dropped} log message(s)",
788
- # error: error.to_s, error_code: error.code.to_s
789
- # else
790
- # @log.error "Unknown response code #{error.code} from the " \
791
- # "server",
792
- # error: error.to_s, error_code: error.code.to_s
793
- # end
794
- # end
795
- # else
796
- # arr.each do |time, record|
797
- # next unless record.is_a?(Hash)
798
- #
799
- # entry = Google::Apis::LoggingV1beta3::LogEntry.new(
800
- # metadata: Google::Apis::LoggingV1beta3::LogEntryMetadata.new(
801
- # service_name: @service_name,
802
- # project_id: @project_id,
803
- # zone: @zone,
804
- # labels: {}
805
- # ))
806
- #
807
- # if @service_name == CLOUDFUNCTIONS_SERVICE && record.key?('log')
808
- # @cloudfunctions_log_match =
809
- # @cloudfunctions_log_regexp.match(record['log'])
810
- # end
811
- # if @service_name == CONTAINER_SERVICE
812
- # # Move the stdout/stderr annotation from the record into a label
813
- # field_to_label(record, 'stream', entry.metadata.labels,
814
- # "#{CONTAINER_SERVICE}/stream")
815
- # # If the record has been annotated by the
816
- # # kubernetes_metadata_filter
817
- # # plugin, then use that metadata. Otherwise, rely on
818
- # # commonLabels
819
- # # populated at the grouped_entries level from the group's tag.
820
- # if record.key?('kubernetes')
821
- # handle_container_metadata(record, entry)
822
- # end
823
- #
824
- # # Save the timestamp if available, then clear it out to allow
825
- # # for determining whether we should parse the log or message
826
- # # field.
827
- # timestamp = record.key?('time') ? record['time'] : nil
828
- # record.delete('time')
829
- # # If the log is json, we want to export it as a structured log
830
- # # unless there is additional metadata that would be lost.
831
- # is_json = false
832
- # if record.length == 1 && record.key?('log')
833
- # record_json = parse_json_or_nil(record['log'])
834
- # end
835
- # if record.length == 1 && record.key?('message')
836
- # record_json = parse_json_or_nil(record['message'])
837
- # end
838
- # unless record_json.nil?
839
- # record = record_json
840
- # is_json = true
841
- # end
842
- # # Restore timestamp if necessary.
843
- # unless record.key?('time') || timestamp.nil?
844
- # record['time'] = timestamp
845
- # end
846
- # end
847
- #
848
- # ts_secs, ts_nanos = compute_timestamp(record, time)
849
- # entry.metadata.timestamp = {
850
- # seconds: ts_secs,
851
- # nanos: ts_nanos
852
- # }
853
- #
854
- # entry.metadata.severity = compute_severity(record, entry)
855
- #
856
- # set_http_request(record, entry)
857
- #
858
- # # If a field is present in the label_map, send its value as a
859
- # # label
860
- # # (mapping the field name to label name as specified in the
861
- # # config)
862
- # # and do not send that field as part of the payload.
863
- # if @label_map
864
- # @label_map.each do |field, label|
865
- # field_to_label(record, field, entry.metadata.labels, label)
866
- # end
867
- # end
868
- #
869
- # if @service_name == CLOUDFUNCTIONS_SERVICE &&
870
- # @cloudfunctions_log_match &&
871
- # @cloudfunctions_log_match['execution_id']
872
- # entry.metadata.labels['execution_id'] =
873
- # @cloudfunctions_log_match['execution_id']
874
- # end
875
- #
876
- # set_payload(record, entry, is_json)
877
- # entry.metadata.labels = nil if entry.metadata.labels.empty?
878
- #
879
- # entries.push(entry)
880
- # end
881
- # # Don't send an empty request if we rejected all the entries.
882
- # next if entries.empty?
883
- #
884
- # log_name = log_name(tag, labels)
885
- #
886
- # begin
887
- # # Does the actual write to the cloud logging api.
888
- # # The URI of the write is constructed by the Google::Api request;
889
- # # it is equivalent to this URL:
890
- # # 'https://logging.googleapis.com/v1beta3/projects/' \
891
- # # "#{@project_id}/logs/#{log_name}/entries:write"
892
- #
893
- # client = api_client
894
- #
895
- # write_request = \
896
- # Google::Apis::LoggingV1beta3::WriteLogEntriesRequest.new(
897
- # common_labels: labels,
898
- # entries: entries)
899
- #
900
- # # TODO: RequestOptions
901
- # client.write_log_entries(@project_id, log_name, write_request)
902
- #
903
- # # Let the user explicitly know when the first call succeeded,
904
- # # to aid with verification and troubleshooting.
905
- # unless @successful_call
906
- # @successful_call = true
907
- # @log.info 'Successfully sent to Stackdriver Logging API.'
908
- # end
909
- #
910
- # rescue Google::Apis::ServerError => error
911
- # # Server error, so retry via re-raising the error.
912
- # raise error
913
- #
914
- # rescue Google::Apis::AuthorizationError => error
915
- # # Authorization error.
916
- # # These are usually solved via a `gcloud auth` call, or by
917
- # # modifying
918
- # # the permissions on the Google Cloud project.
919
- # dropped = entries.length
920
- # @log.warn "Dropping #{dropped} log message(s)",
921
- # error_class: error.class.to_s, error: error.to_s
922
- #
923
- # rescue Google::Apis::ClientError => error
924
- # # Most ClientErrors indicate a problem with the request itself and
925
- # # should not be retried.
926
- # dropped = entries.length
927
- # @log.warn "Dropping #{dropped} log message(s)",
928
- # error_class: error.class.to_s, error: error.to_s
929
- # end
930
- # end
931
- # end
932
- # end
933
-
934
602
  private
935
603
 
936
604
  def parse_json_or_nil(input)
@@ -1159,27 +827,32 @@ module Fluent
1159
827
  return nil unless record['httpRequest'].is_a?(Hash)
1160
828
  input = record['httpRequest']
1161
829
  output = Google::Logging::Type::HttpRequest.new
1162
- output.request_method = input.delete('requestMethod') if
1163
- input.key?('requestMethod')
1164
- output.request_url = input.delete('requestUrl') if
1165
- input.key?('requestUrl')
1166
- output.request_size = input.delete('requestSize').to_i if
1167
- input.key?('requestSize')
1168
- output.status = input.delete('status').to_i if
1169
- input.key?('status')
1170
- output.response_size = input.delete('responseSize').to_i if
1171
- input.key?('responseSize')
1172
- output.user_agent = input.delete('userAgent') if
1173
- input.key?('userAgent')
1174
- output.remote_ip = input.delete('remoteIp') if
1175
- input.key?('remoteIp')
1176
- output.referer = input.delete('referer') if
1177
- input.key?('referer')
1178
- output.cache_hit = input.delete('cacheHit') if
1179
- input.key?('cacheHit')
830
+ # We need to delete each field from 'httpRequest' even if its value is
831
+ # nil. However we do not want to assign this nil value to proto fields
832
+ # defined as strings / integers.
833
+ request_method = input.delete('requestMethod')
834
+ output.request_method = request_method unless request_method.nil?
835
+ request_url = input.delete('requestUrl')
836
+ output.request_url = request_url unless request_url.nil?
837
+ request_size = input.delete('requestSize')
838
+ output.request_size = request_size.to_i unless request_size.nil?
839
+ status = input.delete('status')
840
+ output.status = status.to_i unless status.nil?
841
+ response_size = input.delete('responseSize')
842
+ output.response_size = response_size.to_i unless response_size.nil?
843
+ user_agent = input.delete('userAgent')
844
+ output.user_agent = user_agent unless user_agent.nil?
845
+ remote_ip = input.delete('remoteIp')
846
+ output.remote_ip = remote_ip unless remote_ip.nil?
847
+ referer = input.delete('referer')
848
+ output.referer = referer unless referer.nil?
849
+ cache_hit = input.delete('cacheHit')
850
+ output.cache_hit = cache_hit unless cache_hit.nil?
851
+ cache_validated_with_origin_server = \
852
+ input.delete('cacheValidatedWithOriginServer')
1180
853
  output.cache_validated_with_origin_server = \
1181
- input.delete('cacheValidatedWithOriginServer') if
1182
- input.key?('cacheValidatedWithOriginServer')
854
+ cache_validated_with_origin_server \
855
+ unless cache_validated_with_origin_server.nil?
1183
856
  record.delete('httpRequest') if input.empty?
1184
857
  entry.http_request = output
1185
858
  end
@@ -307,6 +307,19 @@ module BaseTest
307
307
  }
308
308
  }
309
309
 
310
+ HTTP_REQUEST_MESSAGE = {
311
+ 'requestMethod' => 'POST',
312
+ 'requestUrl' => 'http://example/',
313
+ 'requestSize' => 210,
314
+ 'status' => 200,
315
+ 'responseSize' => 65,
316
+ 'userAgent' => 'USER AGENT 1.0',
317
+ 'remoteIp' => '55.55.55.55',
318
+ 'referer' => 'http://referer/',
319
+ 'cacheHit' => true,
320
+ 'cacheValidatedWithOriginServer' => true
321
+ }
322
+
310
323
  # Shared tests.
311
324
 
312
325
  def test_configure_service_account_application_default
@@ -517,15 +530,17 @@ module BaseTest
517
530
  setup_gce_metadata_stubs
518
531
  setup_logging_stubs do
519
532
  d = create_driver
520
- d.emit('msg' => log_entry(0), 'tag2' => 'test', 'data' => 5000)
533
+ d.emit('msg' => log_entry(0), 'tag2' => 'test', 'data' => 5000,
534
+ 'some_null_field' => nil)
521
535
  d.run
522
536
  end
523
537
  verify_log_entries(1, COMPUTE_PARAMS, 'structPayload') do |entry|
524
538
  fields = get_fields(entry['structPayload'])
525
- assert_equal 3, fields.size, entry
539
+ assert_equal 4, fields.size, entry
526
540
  assert_equal 'test log entry 0', get_string(fields['msg']), entry
527
541
  assert_equal 'test', get_string(fields['tag2']), entry
528
542
  assert_equal 5000, get_number(fields['data']), entry
543
+ assert_equal null_value, fields['some_null_field'], entry
529
544
  end
530
545
  end
531
546
 
@@ -550,7 +565,8 @@ module BaseTest
550
565
  setup_container_metadata_stubs
551
566
  setup_logging_stubs do
552
567
  d = create_driver(APPLICATION_DEFAULT_CONFIG, CONTAINER_TAG)
553
- json_string = '{"msg": "test log entry 0", "tag2": "test", "data": 5000}'
568
+ json_string = '{"msg": "test log entry 0", "tag2": "test", ' \
569
+ '"data": 5000, "some_null_field": null}'
554
570
  d.emit(container_log_entry_with_metadata('notJSON' + json_string))
555
571
  d.emit(container_log_entry_with_metadata(json_string))
556
572
  d.emit(container_log_entry_with_metadata(" \r\n \t" + json_string))
@@ -565,10 +581,11 @@ module BaseTest
565
581
  else
566
582
  assert entry.key?('structPayload'), 'Entry did not have structPayload'
567
583
  fields = get_fields(entry['structPayload'])
568
- assert_equal 3, fields.size, entry
584
+ assert_equal 4, fields.size, entry
569
585
  assert_equal 'test log entry 0', get_string(fields['msg']), entry
570
586
  assert_equal 'test', get_string(fields['tag2']), entry
571
587
  assert_equal 5000, get_number(fields['data']), entry
588
+ assert_equal null_value, fields['some_null_field'], entry
572
589
  end
573
590
  end
574
591
  end
@@ -1025,20 +1042,6 @@ module BaseTest
1025
1042
  end
1026
1043
  end
1027
1044
 
1028
- def test_http_request_without_referer_from_record
1029
- setup_gce_metadata_stubs
1030
- setup_logging_stubs do
1031
- d = create_driver
1032
- d.emit('httpRequest' => http_request_message_without_referer)
1033
- d.run
1034
- end
1035
- verify_log_entries(1, COMPUTE_PARAMS, 'httpRequest') do |entry|
1036
- assert_equal http_request_message_without_referer, entry['httpRequest'],
1037
- entry
1038
- assert_nil get_fields(entry['structPayload'])['httpRequest'], entry
1039
- end
1040
- end
1041
-
1042
1045
  def test_http_request_when_not_hash
1043
1046
  setup_gce_metadata_stubs
1044
1047
  setup_logging_stubs do
@@ -1241,6 +1244,16 @@ module BaseTest
1241
1244
  assert i == n, "Number of entries #{i} does not match expected number #{n}"
1242
1245
  end
1243
1246
 
1247
+ # The http request message to test against.
1248
+ def http_request_message
1249
+ HTTP_REQUEST_MESSAGE
1250
+ end
1251
+
1252
+ # Replace the 'referer' field with nil.
1253
+ def http_request_message_with_nil_referer
1254
+ http_request_message.merge('referer' => nil)
1255
+ end
1256
+
1244
1257
  # This module expects the methods below to be overridden.
1245
1258
 
1246
1259
  # Create a Fluentd output test driver with the Google Cloud Output plugin.
@@ -1269,19 +1282,6 @@ module BaseTest
1269
1282
  _undefined
1270
1283
  end
1271
1284
 
1272
- # A wrapper around the constant HTTP_REQUEST_MESSAGE, so the definition can be
1273
- # skipped in the shared module here and defined in the test class later.
1274
- def http_request_message
1275
- _undefined
1276
- end
1277
-
1278
- # A wrapper around the constant HTTP_REQUEST_MESSAGE_WITHOUT_REFERER, so the
1279
- # definition can be skipped in the shared module and defined in the test
1280
- # classes later.
1281
- def http_request_message_without_referer
1282
- _undefined
1283
- end
1284
-
1285
1285
  # Get the fields of the struct payload.
1286
1286
  def get_fields(_struct_payload)
1287
1287
  _undefined
@@ -1302,6 +1302,11 @@ module BaseTest
1302
1302
  _undefined
1303
1303
  end
1304
1304
 
1305
+ # The null value.
1306
+ def null_value(_field)
1307
+ _undefined
1308
+ end
1309
+
1305
1310
  def _undefined
1306
1311
  fail "Method #{__callee__} is unimplemented and needs to be overridden."
1307
1312
  end
@@ -70,6 +70,24 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
70
70
  assert_equal 1, exception_count
71
71
  end
72
72
 
73
+ def test_http_request_from_record_with_referer_nil
74
+ setup_gce_metadata_stubs
75
+ setup_logging_stubs do
76
+ d = create_driver
77
+ d.emit('httpRequest' => http_request_message_with_nil_referer)
78
+ d.run
79
+ end
80
+ verify_log_entries(1, COMPUTE_PARAMS, 'httpRequest') do |entry|
81
+ # The request we send to Logging API has json like:
82
+ # "httpRequest": { "referer": null }, but eventually the stored LogEntry
83
+ # would be "httpRequest": {}, since 'referer' is defined as a string in
84
+ # the proto.
85
+ assert_equal http_request_message_with_nil_referer,
86
+ entry['httpRequest'], entry
87
+ assert_nil get_fields(entry['structPayload'])['httpRequest'], entry
88
+ end
89
+ end
90
+
73
91
  # This test looks similar between the grpc and non-grpc paths except that when
74
92
  # parsing "105", the grpc path responds with "DEBUG", while the non-grpc path
75
93
  # responds with "100".
@@ -175,25 +193,16 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
175
193
 
176
194
  private
177
195
 
178
- # The non-grpc path has a unique field 'validatedWithOriginServer', while
179
- # the grpc path has a unique field 'cacheValidatedWithOriginServer'.
180
- HTTP_REQUEST_MESSAGE = {
181
- 'requestMethod' => 'POST',
182
- 'requestUrl' => 'http://example/',
183
- 'requestSize' => 210,
184
- 'status' => 200,
185
- 'responseSize' => 65,
186
- 'userAgent' => 'USER AGENT 1.0',
187
- 'remoteIp' => '55.55.55.55',
188
- 'referer' => 'http://referer/',
189
- 'cacheHit' => false,
190
- 'validatedWithOriginServer' => true
191
- }
192
-
193
- # In the non-grpc path 'referer' is nil, while in the grpc path 'referer' is
194
- # absent.
195
- HTTP_REQUEST_MESSAGE_WITHOUT_REFERER = HTTP_REQUEST_MESSAGE.merge(
196
- 'referer' => nil)
196
+ def rename_key(hash, old_key, new_key)
197
+ hash.merge(new_key => hash[old_key]).reject { |k, _| k == old_key }
198
+ end
199
+
200
+ # The REST path uses old bindings that were generated prior to the field
201
+ # rename, and has to use the old name, which is 'validatedWithOriginServer'.
202
+ def http_request_message
203
+ rename_key(super, 'cacheValidatedWithOriginServer',
204
+ 'validatedWithOriginServer')
205
+ end
197
206
 
198
207
  # Set up http stubs to mock the external calls.
199
208
  def setup_logging_stubs
@@ -234,18 +243,6 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
234
243
  end
235
244
  end
236
245
 
237
- # A wrapper around the constant HTTP_REQUEST_MESSAGE, so the definition can be
238
- # skipped in the shared module and defined here.
239
- def http_request_message
240
- HTTP_REQUEST_MESSAGE
241
- end
242
-
243
- # A wrapper around the constant HTTP_REQUEST_MESSAGE_WITHOUT_REFERER, so the
244
- # definition can be skipped in the shared module and defined here.
245
- def http_request_message_without_referer
246
- HTTP_REQUEST_MESSAGE_WITHOUT_REFERER
247
- end
248
-
249
246
  # Get the fields of the struct payload.
250
247
  def get_fields(struct_payload)
251
248
  struct_payload
@@ -265,4 +262,9 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
265
262
  def get_number(field)
266
263
  field
267
264
  end
265
+
266
+ # The null value.
267
+ def null_value
268
+ nil
269
+ end
268
270
  end
@@ -72,6 +72,34 @@ class GoogleCloudOutputGRPCTest < Test::Unit::TestCase
72
72
  end
73
73
  end
74
74
 
75
+ def test_http_request_from_record_with_referer_nil
76
+ setup_gce_metadata_stubs
77
+ setup_logging_stubs do
78
+ d = create_driver
79
+ d.emit('httpRequest' => http_request_message_with_nil_referer)
80
+ d.run
81
+ end
82
+ verify_log_entries(1, COMPUTE_PARAMS, 'httpRequest') do |entry|
83
+ assert_equal http_request_message_with_absent_referer,
84
+ entry['httpRequest'], entry
85
+ assert_nil get_fields(entry['structPayload'])['httpRequest'], entry
86
+ end
87
+ end
88
+
89
+ def test_http_request_from_record_with_referer_absent
90
+ setup_gce_metadata_stubs
91
+ setup_logging_stubs do
92
+ d = create_driver
93
+ d.emit('httpRequest' => http_request_message_with_absent_referer)
94
+ d.run
95
+ end
96
+ verify_log_entries(1, COMPUTE_PARAMS, 'httpRequest') do |entry|
97
+ assert_equal http_request_message_with_absent_referer,
98
+ entry['httpRequest'], entry
99
+ assert_nil get_fields(entry['structPayload'])['httpRequest'], entry
100
+ end
101
+ end
102
+
75
103
  # This test looks similar between the grpc and non-grpc paths except that when
76
104
  # parsing "105", the grpc path responds with "DEBUG", while the non-grpc path
77
105
  # responds with "100".
@@ -114,27 +142,6 @@ class GoogleCloudOutputGRPCTest < Test::Unit::TestCase
114
142
  use_grpc true
115
143
  )
116
144
 
117
- # The non-grpc path has a unique field 'validatedWithOriginServer', while
118
- # the grpc path has a unique field 'cacheValidatedWithOriginServer'.
119
- HTTP_REQUEST_MESSAGE = {
120
- 'requestMethod' => 'POST',
121
- 'requestUrl' => 'http://example/',
122
- 'requestSize' => 210,
123
- 'status' => 200,
124
- 'responseSize' => 65,
125
- 'userAgent' => 'USER AGENT 1.0',
126
- 'remoteIp' => '55.55.55.55',
127
- 'referer' => 'http://referer/',
128
- 'cacheHit' => true,
129
- 'cacheValidatedWithOriginServer' => true
130
- }
131
-
132
- # In the non-grpc path 'referer' is nil, while in the grpc path 'referer' is
133
- # absent.
134
- HTTP_REQUEST_MESSAGE_WITHOUT_REFERER = HTTP_REQUEST_MESSAGE.reject do |k, _|
135
- k == 'referer'
136
- end
137
-
138
145
  # Create a Fluentd output test driver with the Google Cloud Output plugin with
139
146
  # grpc enabled. The signature of this method is different between the grpc
140
147
  # path and the non-grpc path. For grpc, an additional grpc stub class can be
@@ -275,16 +282,11 @@ class GoogleCloudOutputGRPCTest < Test::Unit::TestCase
275
282
  end
276
283
  end
277
284
 
278
- # A wrapper around the constant HTTP_REQUEST_MESSAGE, so the definition can be
279
- # skipped in the shared module and defined here.
280
- def http_request_message
281
- HTTP_REQUEST_MESSAGE
282
- end
283
-
284
- # A wrapper around the constant HTTP_REQUEST_MESSAGE_WITHOUT_REFERER, so the
285
- # definition can be skipped in the shared module and defined here.
286
- def http_request_message_without_referer
287
- HTTP_REQUEST_MESSAGE_WITHOUT_REFERER
285
+ # Unset the 'referer' field.
286
+ def http_request_message_with_absent_referer
287
+ http_request_message.reject do |k, _|
288
+ k == 'referer'
289
+ end
288
290
  end
289
291
 
290
292
  # Get the fields of the struct payload.
@@ -306,4 +308,9 @@ class GoogleCloudOutputGRPCTest < Test::Unit::TestCase
306
308
  def get_number(field)
307
309
  field['numberValue']
308
310
  end
311
+
312
+ # The null value.
313
+ def null_value
314
+ { 'nullValue' => 'NULL_VALUE' }
315
+ end
309
316
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-google-cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3.grpc.alpha.4
4
+ version: 0.5.3.grpc.alpha.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Todd Derr
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-12-12 00:00:00.000000000 Z
12
+ date: 2016-12-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fluentd