fluent-plugin-google-cloud 0.12.10 → 0.12.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -85,6 +85,7 @@ require 'strptime'
85
85
  # Dummy Strptime class.
86
86
  class Strptime
87
87
  def self.new(_)
88
+ # empty
88
89
  end
89
90
  end
90
91
 
@@ -130,22 +131,22 @@ module Fluent
130
131
  # Map from subfields' names to their types.
131
132
  [
132
133
  # subfield key in the payload, destination key, cast lambda (opt)
133
- %w(cacheFillBytes cache_fill_bytes parse_int),
134
- %w(cacheHit cache_hit parse_bool),
135
- %w(cacheLookup cache_lookup parse_bool),
136
- %w(cacheValidatedWithOriginServer
137
- cache_validated_with_origin_server parse_bool),
138
- %w(latency latency parse_latency),
139
- %w(protocol protocol parse_string),
140
- %w(referer referer parse_string),
141
- %w(remoteIp remote_ip parse_string),
142
- %w(responseSize response_size parse_int),
143
- %w(requestMethod request_method parse_string),
144
- %w(requestSize request_size parse_int),
145
- %w(requestUrl request_url parse_string),
146
- %w(serverIp server_ip parse_string),
147
- %w(status status parse_int),
148
- %w(userAgent user_agent parse_string)
134
+ %w[cacheFillBytes cache_fill_bytes parse_int],
135
+ %w[cacheHit cache_hit parse_bool],
136
+ %w[cacheLookup cache_lookup parse_bool],
137
+ %w[cacheValidatedWithOriginServer
138
+ cache_validated_with_origin_server parse_bool],
139
+ %w[latency latency parse_latency],
140
+ %w[protocol protocol parse_string],
141
+ %w[referer referer parse_string],
142
+ %w[remoteIp remote_ip parse_string],
143
+ %w[responseSize response_size parse_int],
144
+ %w[requestMethod request_method parse_string],
145
+ %w[requestSize request_size parse_int],
146
+ %w[requestUrl request_url parse_string],
147
+ %w[serverIp server_ip parse_string],
148
+ %w[status status parse_int],
149
+ %w[userAgent user_agent parse_string]
149
150
  ],
150
151
  # The grpc version class name.
151
152
  'Google::Logging::Type::HttpRequest',
@@ -155,10 +156,10 @@ module Fluent
155
156
  'operation' => [
156
157
  '@operation_key',
157
158
  [
158
- %w(id id parse_string),
159
- %w(producer producer parse_string),
160
- %w(first first parse_bool),
161
- %w(last last parse_bool)
159
+ %w[id id parse_string],
160
+ %w[producer producer parse_string],
161
+ %w[first first parse_bool],
162
+ %w[last last parse_bool]
162
163
  ],
163
164
  'Google::Logging::V2::LogEntryOperation',
164
165
  'Google::Apis::LoggingV2::LogEntryOperation'
@@ -166,9 +167,9 @@ module Fluent
166
167
  'source_location' => [
167
168
  '@source_location_key',
168
169
  [
169
- %w(file file parse_string),
170
- %w(function function parse_string),
171
- %w(line line parse_int)
170
+ %w[file file parse_string],
171
+ %w[function function parse_string],
172
+ %w[line line parse_int]
172
173
  ],
173
174
  'Google::Logging::V2::LogEntrySourceLocation',
174
175
  'Google::Apis::LoggingV2::LogEntrySourceLocation'
@@ -195,7 +196,8 @@ module Fluent
195
196
  PLUGIN_VERSION = begin
196
197
  # Extract plugin version from file path.
197
198
  match_data = __FILE__.match(
198
- %r{fluent-plugin-google-cloud-(?<version>[^/]*)/})
199
+ %r{fluent-plugin-google-cloud-(?<version>[^/]*)/}
200
+ )
199
201
  if match_data
200
202
  match_data['version']
201
203
  else
@@ -203,9 +205,10 @@ module Fluent
203
205
  dependency = Gem::Dependency.new('fluent-plugin-google-cloud')
204
206
  all_specs, = Gem::SpecFetcher.fetcher.spec_for_dependency(dependency)
205
207
  matching_version, = all_specs.grep(
206
- proc { |spec,| __FILE__.include?(spec.full_gem_path) }) do |spec,|
207
- spec.version.to_s
208
- end
208
+ proc { |spec,| __FILE__.include?(spec.full_gem_path) }
209
+ ) do |spec,|
210
+ spec.version.to_s
211
+ end
209
212
  # If no matching version was found, return a valid but obviously wrong
210
213
  # value.
211
214
  matching_version || '0.0.0-unknown'
@@ -323,7 +326,7 @@ module Fluent
323
326
  # Whether to enable gRPC compression when communicating with the Stackdriver
324
327
  # Logging API. Only used if 'use_grpc' is set to true.
325
328
  config_param :grpc_compression_algorithm, :enum,
326
- list: [:none, :gzip],
329
+ list: %i[none gzip],
327
330
  :default => nil
328
331
 
329
332
  # Whether valid entries should be written even if some other entries fail
@@ -428,12 +431,7 @@ module Fluent
428
431
 
429
432
  # Expose attr_readers to make testing of metadata more direct than only
430
433
  # testing it indirectly through metadata sent with logs.
431
- attr_reader :project_id
432
- attr_reader :zone
433
- attr_reader :vm_id
434
- attr_reader :resource
435
- attr_reader :common_labels
436
- attr_reader :monitoring_resource
434
+ attr_reader :project_id, :zone, :vm_id, :resource, :common_labels, :monitoring_resource
437
435
 
438
436
  def initialize
439
437
  super
@@ -496,13 +494,15 @@ module Fluent
496
494
 
497
495
  # All metadata parameters must now be set.
498
496
  @utils.check_required_metadata_variables(
499
- @platform, @project_id, @zone, @vm_id)
497
+ @platform, @project_id, @zone, @vm_id
498
+ )
500
499
 
501
500
  # Retrieve monitored resource.
502
501
  # Fail over to retrieve monitored resource via the legacy path if we fail
503
502
  # to get it from Metadata Agent.
504
503
  @resource ||= @utils.determine_agent_level_monitored_resource_via_legacy(
505
- @platform, @subservice_name, @detect_subservice, @vm_id, @zone)
504
+ @platform, @subservice_name, @detect_subservice, @vm_id, @zone
505
+ )
506
506
 
507
507
  if @metrics_resource
508
508
  unless @metrics_resource[:type].is_a?(String)
@@ -517,7 +517,7 @@ module Fluent
517
517
  " #{@metrics_resource}."
518
518
  end
519
519
  extra_keys = @metrics_resource.reject do |k, _|
520
- k == :type || k == :labels
520
+ %i[type labels].include?(k)
521
521
  end
522
522
  unless extra_keys.empty?
523
523
  raise Fluent::ConfigError,
@@ -545,16 +545,18 @@ module Fluent
545
545
  # and store metric objects for future use.
546
546
  if @enable_monitoring
547
547
  unless Monitoring::MonitoringRegistryFactory.supports_monitoring_type(
548
- @monitoring_type)
548
+ @monitoring_type
549
+ )
549
550
  @log.warn "monitoring_type '#{@monitoring_type}' is unknown; "\
550
551
  'there will be no metrics'
551
552
  end
552
- if @metrics_resource
553
- @monitoring_resource = @utils.create_monitored_resource(
554
- @metrics_resource[:type], @metrics_resource[:labels])
555
- else
556
- @monitoring_resource = @resource
557
- end
553
+ @monitoring_resource = if @metrics_resource
554
+ @utils.create_monitored_resource(
555
+ @metrics_resource[:type], @metrics_resource[:labels]
556
+ )
557
+ else
558
+ @resource
559
+ end
558
560
  @registry = Monitoring::MonitoringRegistryFactory
559
561
  .create(@monitoring_type, @project_id,
560
562
  @monitoring_resource, @gcm_service_address)
@@ -564,37 +566,43 @@ module Fluent
564
566
  # we can't change it.
565
567
  @uptime_metric = @registry.counter(
566
568
  :uptime, [:version], 'Uptime of Logging agent',
567
- 'agent.googleapis.com/agent', 'CUMULATIVE')
569
+ 'agent.googleapis.com/agent', 'CUMULATIVE'
570
+ )
568
571
  update_uptime
569
572
  timer_execute(:update_uptime, 1) { update_uptime }
570
573
  @successful_requests_count = @registry.counter(
571
574
  :stackdriver_successful_requests_count,
572
- [:grpc, :code],
575
+ %i[grpc code],
573
576
  'A number of successful requests to the Stackdriver Logging API',
574
- 'agent.googleapis.com/agent', 'CUMULATIVE')
577
+ 'agent.googleapis.com/agent', 'CUMULATIVE'
578
+ )
575
579
  @failed_requests_count = @registry.counter(
576
580
  :stackdriver_failed_requests_count,
577
- [:grpc, :code],
581
+ %i[grpc code],
578
582
  'A number of failed requests to the Stackdriver Logging '\
579
583
  'API, broken down by the error code',
580
- 'agent.googleapis.com/agent', 'CUMULATIVE')
584
+ 'agent.googleapis.com/agent', 'CUMULATIVE'
585
+ )
581
586
  @ingested_entries_count = @registry.counter(
582
587
  :stackdriver_ingested_entries_count,
583
- [:grpc, :code],
588
+ %i[grpc code],
584
589
  'A number of log entries ingested by Stackdriver Logging',
585
- 'agent.googleapis.com/agent', 'CUMULATIVE')
590
+ 'agent.googleapis.com/agent', 'CUMULATIVE'
591
+ )
586
592
  @dropped_entries_count = @registry.counter(
587
593
  :stackdriver_dropped_entries_count,
588
- [:grpc, :code],
594
+ %i[grpc code],
589
595
  'A number of log entries dropped by the Stackdriver output plugin',
590
- 'agent.googleapis.com/agent', 'CUMULATIVE')
596
+ 'agent.googleapis.com/agent', 'CUMULATIVE'
597
+ )
591
598
  @retried_entries_count = @registry.counter(
592
599
  :stackdriver_retried_entries_count,
593
- [:grpc, :code],
600
+ %i[grpc code],
594
601
  'The number of log entries that failed to be ingested by '\
595
602
  'the Stackdriver output plugin due to a transient error '\
596
603
  'and were retried',
597
- 'agent.googleapis.com/agent', 'CUMULATIVE')
604
+ 'agent.googleapis.com/agent', 'CUMULATIVE'
605
+ )
598
606
  @ok_code = @use_grpc ? GRPC::Core::StatusCodes::OK : 200
599
607
  end
600
608
 
@@ -625,12 +633,12 @@ module Fluent
625
633
  @write_request = method(:write_request_via_rest)
626
634
  end
627
635
 
628
- if [Common::Platform::GCE, Common::Platform::EC2].include?(@platform)
629
- # Log an informational message containing the Logs viewer URL
630
- @log.info 'Logs viewer address: https://console.cloud.google.com/logs/',
631
- "viewer?project=#{@project_id}&resource=#{@resource.type}/",
632
- "instance_id/#{@vm_id}"
633
- end
636
+ return unless [Common::Platform::GCE, Common::Platform::EC2].include?(@platform)
637
+
638
+ # Log an informational message containing the Logs viewer URL
639
+ @log.info 'Logs viewer address: https://console.cloud.google.com/logs/',
640
+ "viewer?project=#{@project_id}&resource=#{@resource.type}/",
641
+ "instance_id/#{@vm_id}"
634
642
  end
635
643
 
636
644
  def start
@@ -639,16 +647,16 @@ module Fluent
639
647
  @successful_call = false
640
648
  @timenanos_warning = false
641
649
 
642
- if @statusz_port > 0
643
- @log.info "Starting statusz server on port #{@statusz_port}"
644
- server_create(:out_google_cloud_statusz,
645
- @statusz_port,
646
- bind: '127.0.0.1') do |data, conn|
647
- if data.split(' ')[1] == '/statusz'
648
- write_html_response(data, conn, 200, Statusz.response(self))
649
- else
650
- write_html_response(data, conn, 404, "Not found\n")
651
- end
650
+ return unless @statusz_port.positive?
651
+
652
+ @log.info "Starting statusz server on port #{@statusz_port}"
653
+ server_create(:out_google_cloud_statusz,
654
+ @statusz_port,
655
+ bind: '127.0.0.1') do |data, conn|
656
+ if data.split(' ')[1] == '/statusz'
657
+ write_html_response(data, conn, 200, Statusz.response(self))
658
+ else
659
+ write_html_response(data, conn, 404, "Not found\n")
652
660
  end
653
661
  end
654
662
  end
@@ -657,7 +665,7 @@ module Fluent
657
665
  super
658
666
  # Export metrics on shutdown. This is a best-effort attempt, and it might
659
667
  # fail, for instance if there was a recent write to the same time series.
660
- @registry.export unless @registry.nil?
668
+ @registry&.export
661
669
  end
662
670
 
663
671
  def write(chunk)
@@ -668,12 +676,14 @@ module Fluent
668
676
  entries = []
669
677
  group_level_resource, group_level_common_labels =
670
678
  determine_group_level_monitored_resource_and_labels(
671
- tag, local_resource_id)
679
+ tag, local_resource_id
680
+ )
672
681
 
673
682
  arr.each do |time, record|
674
683
  entry_level_resource, entry_level_common_labels =
675
684
  determine_entry_level_monitored_resource_and_labels(
676
- group_level_resource, group_level_common_labels, record)
685
+ group_level_resource, group_level_common_labels, record
686
+ )
677
687
 
678
688
  is_json = false
679
689
  if @detect_json
@@ -703,10 +713,8 @@ module Fluent
703
713
  # unless there is additional metadata that would be lost.
704
714
  record_json = nil
705
715
  if (record.keys - preserved_keys).length == 1
706
- %w(log message msg).each do |field|
707
- if record.key?(field)
708
- record_json = parse_json_or_nil(record[field])
709
- end
716
+ %w[log message msg].each do |field|
717
+ record_json = parse_json_or_nil(record[field]) if record.key?(field)
710
718
  end
711
719
  end
712
720
  unless record_json.nil?
@@ -727,12 +735,16 @@ module Fluent
727
735
  if @adjust_invalid_timestamps && timestamp
728
736
 
729
737
  severity = compute_severity(
730
- entry_level_resource.type, record, entry_level_common_labels)
738
+ entry_level_resource.type, record, entry_level_common_labels
739
+ )
731
740
 
732
741
  dynamic_labels_from_payload = parse_labels(record)
733
742
 
734
- entry_level_common_labels = entry_level_common_labels.merge!(
735
- dynamic_labels_from_payload) if dynamic_labels_from_payload
743
+ if dynamic_labels_from_payload
744
+ entry_level_common_labels.merge!(
745
+ dynamic_labels_from_payload
746
+ )
747
+ end
736
748
 
737
749
  entry = @construct_log_entry.call(entry_level_common_labels,
738
750
  entry_level_resource,
@@ -759,7 +771,8 @@ module Fluent
759
771
  next if entries.empty?
760
772
 
761
773
  log_name = "projects/#{@project_id}/logs/#{log_name(
762
- tag, group_level_resource)}"
774
+ tag, group_level_resource
775
+ )}"
763
776
 
764
777
  requests_to_send << {
765
778
  entries: entries,
@@ -803,7 +816,8 @@ module Fluent
803
816
  now = Time.now.to_i
804
817
  @uptime_metric.increment(
805
818
  by: now - @uptime_update_time,
806
- labels: { version: Fluent::GoogleCloudOutput.version_string })
819
+ labels: { version: Fluent::GoogleCloudOutput.version_string }
820
+ )
807
821
  @uptime_update_time = now
808
822
  end
809
823
 
@@ -823,6 +837,7 @@ module Fluent
823
837
  def compute_trace(trace)
824
838
  return trace unless @autoformat_stackdriver_trace &&
825
839
  STACKDRIVER_TRACE_ID_REGEXP.match(trace)
840
+
826
841
  "projects/#{@project_id}/traces/#{trace}"
827
842
  end
828
843
 
@@ -901,10 +916,9 @@ module Fluent
901
916
  @successful_call = true
902
917
  @log.info 'Successfully sent gRPC to Stackdriver Logging API.'
903
918
  end
904
-
905
- rescue Google::Gax::GaxError => gax_error
919
+ rescue Google::Gax::GaxError => e
906
920
  # GRPC::BadStatus is wrapped in error.cause.
907
- error = gax_error.cause
921
+ error = e.cause
908
922
 
909
923
  # See the mapping between HTTP status and gRPC status code at:
910
924
  # https://github.com/grpc/grpc/blob/master/src/core/lib/transport/status_conversion.cc
@@ -959,7 +973,7 @@ module Fluent
959
973
  GRPC::InvalidArgument,
960
974
  # HTTP status 403 (Forbidden).
961
975
  GRPC::PermissionDenied
962
- error_details_map = construct_error_details_map_grpc(gax_error)
976
+ error_details_map = construct_error_details_map_grpc(e)
963
977
  if error_details_map.empty?
964
978
  increment_failed_requests_count(error.code)
965
979
  increment_dropped_entries_count(entries_count, error.code)
@@ -995,13 +1009,13 @@ module Fluent
995
1009
 
996
1010
  # Got an unexpected error (not Google::Gax::GaxError) from the
997
1011
  # google-cloud-logging lib.
998
- rescue StandardError => error
1012
+ rescue StandardError => e
999
1013
  increment_failed_requests_count(GRPC::Core::StatusCodes::UNKNOWN)
1000
1014
  increment_dropped_entries_count(entries_count,
1001
1015
  GRPC::Core::StatusCodes::UNKNOWN)
1002
- @log.error "Unexpected error type #{error.class.name} from the client" \
1016
+ @log.error "Unexpected error type #{e.class.name} from the client" \
1003
1017
  " library, dropping #{entries_count} log message(s)",
1004
- error: error.to_s
1018
+ error: e.to_s
1005
1019
  end
1006
1020
 
1007
1021
  def write_request_via_rest(entries:,
@@ -1029,32 +1043,29 @@ module Fluent
1029
1043
  @successful_call = true
1030
1044
  @log.info 'Successfully sent to Stackdriver Logging API.'
1031
1045
  end
1032
-
1033
- rescue Google::Apis::ServerError => error
1046
+ rescue Google::Apis::ServerError => e
1034
1047
  # 5xx server errors. Retry via re-raising the error.
1035
- increment_retried_entries_count(entries_count, error.status_code)
1048
+ increment_retried_entries_count(entries_count, e.status_code)
1036
1049
  @log.debug "Retrying #{entries_count} log message(s) later.",
1037
- error: error.to_s, error_code: error.status_code.to_s
1038
- raise error
1039
-
1040
- rescue Google::Apis::AuthorizationError => error
1050
+ error: e.to_s, error_code: e.status_code.to_s
1051
+ raise e
1052
+ rescue Google::Apis::AuthorizationError => e
1041
1053
  # 401 authorization error.
1042
1054
  # These are usually solved via a `gcloud auth` call, or by modifying
1043
1055
  # the permissions on the Google Cloud project.
1044
- increment_failed_requests_count(error.status_code)
1045
- increment_dropped_entries_count(entries_count, error.status_code)
1056
+ increment_failed_requests_count(e.status_code)
1057
+ increment_dropped_entries_count(entries_count, e.status_code)
1046
1058
  @log.warn "Dropping #{entries_count} log message(s)",
1047
- error: error.to_s, error_code: error.status_code.to_s
1048
-
1049
- rescue Google::Apis::ClientError => error
1059
+ error: e.to_s, error_code: e.status_code.to_s
1060
+ rescue Google::Apis::ClientError => e
1050
1061
  # 4xx client errors. Most client errors indicate a problem with the
1051
1062
  # request itself and should not be retried.
1052
- error_details_map = construct_error_details_map(error)
1063
+ error_details_map = construct_error_details_map(e)
1053
1064
  if error_details_map.empty?
1054
- increment_failed_requests_count(error.status_code)
1055
- increment_dropped_entries_count(entries_count, error.status_code)
1065
+ increment_failed_requests_count(e.status_code)
1066
+ increment_dropped_entries_count(entries_count, e.status_code)
1056
1067
  @log.warn "Dropping #{entries_count} log message(s)",
1057
- error: error.to_s, error_code: error.status_code.to_s
1068
+ error: e.to_s, error_code: e.status_code.to_s
1058
1069
  else
1059
1070
  error_details_map.each do |(error_code, error_message), indexes|
1060
1071
  partial_errors_count = indexes.length
@@ -1086,9 +1097,9 @@ module Fluent
1086
1097
  # in which case we continue to look for a left curly bracket.
1087
1098
  # Whitespace as per the JSON spec are: tabulation (U+0009),
1088
1099
  # line feed (U+000A), carriage return (U+000D), and space (U+0020).
1089
- break unless c == 9 || c == 10 || c == 13 || c == 32
1090
- end # case
1091
- end # do
1100
+ break unless [9, 10, 13, 32].include?(c)
1101
+ end
1102
+ end
1092
1103
  nil
1093
1104
  end
1094
1105
 
@@ -1191,7 +1202,8 @@ module Fluent
1191
1202
  # "k8s_container.<namespace_name>.<pod_name>.<container_name>"
1192
1203
  if local_resource_id
1193
1204
  converted_resource = monitored_resource_from_local_resource_id(
1194
- local_resource_id)
1205
+ local_resource_id
1206
+ )
1195
1207
  resource = converted_resource if converted_resource
1196
1208
  end
1197
1209
 
@@ -1213,13 +1225,17 @@ module Fluent
1213
1225
  # constants like GKE_CONSTANTS[:extra_resource_labels].
1214
1226
  'container_name' => 'container_name',
1215
1227
  'namespace_name' => 'namespace_id',
1216
- 'pod_name' => 'pod_id'))
1228
+ 'pod_name' => 'pod_id'
1229
+ )
1230
+ )
1217
1231
 
1218
1232
  common_labels.merge!(
1219
1233
  delete_and_extract_labels(
1220
1234
  common_labels_candidates,
1221
1235
  GKE_CONSTANTS[:extra_common_labels]
1222
- .map { |l| [l, "#{GKE_CONSTANTS[:service]}/#{l}"] }.to_h))
1236
+ .map { |l| [l, "#{GKE_CONSTANTS[:service]}/#{l}"] }.to_h
1237
+ )
1238
+ )
1223
1239
  end
1224
1240
 
1225
1241
  # TODO(qingling128): Temporary fallback for metadata agent restarts.
@@ -1237,10 +1253,13 @@ module Fluent
1237
1253
  # e.g. "dataflow.googleapis.com/job_id" => "job_id"
1238
1254
  [DATAFLOW_CONSTANTS, ML_CONSTANTS].each do |service_constants|
1239
1255
  next unless resource.type == service_constants[:resource_type]
1256
+
1240
1257
  resource.labels.merge!(
1241
1258
  delete_and_extract_labels(
1242
1259
  common_labels, service_constants[:extra_resource_labels]
1243
- .map { |l| ["#{service_constants[:service]}/#{l}", l] }.to_h))
1260
+ .map { |l| ["#{service_constants[:service]}/#{l}", l] }.to_h
1261
+ )
1262
+ )
1244
1263
  end
1245
1264
 
1246
1265
  resource.freeze
@@ -1253,7 +1272,8 @@ module Fluent
1253
1272
  # Extract entry level monitored resource and common labels that should be
1254
1273
  # applied to individual entries.
1255
1274
  def determine_entry_level_monitored_resource_and_labels(
1256
- group_level_resource, group_level_common_labels, record)
1275
+ group_level_resource, group_level_common_labels, record
1276
+ )
1257
1277
  resource = group_level_resource.dup
1258
1278
  resource.labels = group_level_resource.labels.dup
1259
1279
  common_labels = group_level_common_labels.dup
@@ -1264,7 +1284,9 @@ module Fluent
1264
1284
  # Move the stdout/stderr annotation from the record into a label.
1265
1285
  common_labels.merge!(
1266
1286
  delete_and_extract_labels(
1267
- record, 'stream' => "#{GKE_CONSTANTS[:service]}/stream"))
1287
+ record, 'stream' => "#{GKE_CONSTANTS[:service]}/stream"
1288
+ )
1289
+ )
1268
1290
 
1269
1291
  # If the record has been annotated by the kubernetes_metadata_filter
1270
1292
  # plugin, then use that metadata. Otherwise, rely on commonLabels
@@ -1273,17 +1295,23 @@ module Fluent
1273
1295
  resource.labels.merge!(
1274
1296
  delete_and_extract_labels(
1275
1297
  record['kubernetes'], GKE_CONSTANTS[:extra_resource_labels]
1276
- .map { |l| [l, l] }.to_h))
1298
+ .map { |l| [l, l] }.to_h
1299
+ )
1300
+ )
1277
1301
  common_labels.merge!(
1278
1302
  delete_and_extract_labels(
1279
1303
  record['kubernetes'], GKE_CONSTANTS[:extra_common_labels]
1280
- .map { |l| [l, "#{GKE_CONSTANTS[:service]}/#{l}"] }.to_h))
1304
+ .map { |l| [l, "#{GKE_CONSTANTS[:service]}/#{l}"] }.to_h
1305
+ )
1306
+ )
1281
1307
  # Prepend label/ to all user-defined labels' keys.
1282
1308
  if record['kubernetes'].key?('labels')
1283
1309
  common_labels.merge!(
1284
1310
  delete_and_extract_labels(
1285
1311
  record['kubernetes']['labels'], record['kubernetes']['labels']
1286
- .map { |key, _| [key, "label/#{key}"] }.to_h))
1312
+ .map { |key, _| [key, "label/#{key}"] }.to_h
1313
+ )
1314
+ )
1287
1315
  end
1288
1316
  # We've explicitly consumed all the fields we care about -- don't
1289
1317
  # litter the log entries with the remaining fields that the kubernetes
@@ -1304,10 +1332,13 @@ module Fluent
1304
1332
  # e.g. "dataflow.googleapis.com/job_id" => "job_id"
1305
1333
  [DATAFLOW_CONSTANTS, ML_CONSTANTS].each do |service_constants|
1306
1334
  next unless resource.type == service_constants[:resource_type]
1335
+
1307
1336
  resource.labels.merge!(
1308
1337
  delete_and_extract_labels(
1309
1338
  common_labels, service_constants[:extra_resource_labels]
1310
- .map { |l| ["#{service_constants[:service]}/#{l}", l] }.to_h))
1339
+ .map { |l| ["#{service_constants[:service]}/#{l}", l] }.to_h
1340
+ )
1341
+ )
1311
1342
  end
1312
1343
 
1313
1344
  [resource, common_labels]
@@ -1350,7 +1381,7 @@ module Fluent
1350
1381
  # k8s ISO8601 timestamp
1351
1382
  begin
1352
1383
  timestamp = Time.iso8601(record.delete('time'))
1353
- rescue
1384
+ rescue StandardError
1354
1385
  timestamp = Time.at(time)
1355
1386
  end
1356
1387
  ts_secs = timestamp.tv_sec
@@ -1361,15 +1392,15 @@ module Fluent
1361
1392
  ts_nanos = timestamp.tv_nsec
1362
1393
  end
1363
1394
  ts_secs = begin
1364
- Integer ts_secs
1365
- rescue ArgumentError, TypeError
1366
- ts_secs
1367
- end
1395
+ Integer ts_secs
1396
+ rescue ArgumentError, TypeError
1397
+ ts_secs
1398
+ end
1368
1399
  ts_nanos = begin
1369
- Integer ts_nanos
1370
- rescue ArgumentError, TypeError
1371
- ts_nanos
1372
- end
1400
+ Integer ts_nanos
1401
+ rescue ArgumentError, TypeError
1402
+ ts_nanos
1403
+ end
1373
1404
 
1374
1405
  [ts_secs, ts_nanos, timestamp]
1375
1406
  end
@@ -1420,6 +1451,7 @@ module Fluent
1420
1451
  stream = entry_level_common_labels["#{GKE_CONSTANTS[:service]}/stream"]
1421
1452
  return GKE_CONSTANTS[:stream_severity_map].fetch(stream, 'DEFAULT')
1422
1453
  end
1454
+
1423
1455
  'DEFAULT'
1424
1456
  end
1425
1457
 
@@ -1440,6 +1472,7 @@ module Fluent
1440
1472
  do |(original_key, destination_key, cast_fn), extracted_fields|
1441
1473
  value = fields.delete(original_key)
1442
1474
  next if value.nil?
1475
+
1443
1476
  begin
1444
1477
  casted_value = send(cast_fn, value)
1445
1478
  rescue TypeError
@@ -1448,6 +1481,7 @@ module Fluent
1448
1481
  next
1449
1482
  end
1450
1483
  next if casted_value.nil?
1484
+
1451
1485
  extracted_fields[destination_key] = casted_value
1452
1486
  end
1453
1487
 
@@ -1465,8 +1499,8 @@ module Fluent
1465
1499
  record.delete(payload_key) if fields.empty?
1466
1500
 
1467
1501
  entry.send("#{field_name}=", output)
1468
- rescue StandardError => err
1469
- @log.error "Failed to set log entry field for #{field_name}.", err
1502
+ rescue StandardError => e
1503
+ @log.error "Failed to set log entry field for #{field_name}.", e
1470
1504
  end
1471
1505
  end
1472
1506
  end
@@ -1475,6 +1509,7 @@ module Fluent
1475
1509
  def parse_labels(record)
1476
1510
  payload_labels = record.delete(@labels_key)
1477
1511
  return nil unless payload_labels
1512
+
1478
1513
  unless payload_labels.is_a?(Hash)
1479
1514
  @log.error "Invalid value of '#{@labels_key}' in the payload: " \
1480
1515
  "#{payload_labels}. Labels need to be a JSON object."
@@ -1491,14 +1526,14 @@ module Fluent
1491
1526
  return nil
1492
1527
  end
1493
1528
  payload_labels
1494
- rescue StandardError => err
1495
- @log.error "Failed to extract '#{@labels_key}' from payload.", err
1496
- return nil
1529
+ rescue StandardError => e
1530
+ @log.error "Failed to extract '#{@labels_key}' from payload.", e
1531
+ nil
1497
1532
  end
1498
1533
 
1499
1534
  # Values permitted by the API for 'severity' (which is an enum).
1500
1535
  VALID_SEVERITIES = Set.new(
1501
- %w(DEFAULT DEBUG INFO NOTICE WARNING ERROR CRITICAL ALERT EMERGENCY)
1536
+ %w[DEFAULT DEBUG INFO NOTICE WARNING ERROR CRITICAL ALERT EMERGENCY]
1502
1537
  ).freeze
1503
1538
 
1504
1539
  # Translates other severity strings to one of the valid values above.
@@ -1544,22 +1579,20 @@ module Fluent
1544
1579
  begin
1545
1580
  numeric_severity = (severity.to_i / 100) * 100
1546
1581
  case
1547
- when numeric_severity < 0
1582
+ when numeric_severity.negative?
1548
1583
  return 0
1549
1584
  when numeric_severity > 800
1550
1585
  return 800
1551
1586
  else
1552
1587
  return numeric_severity
1553
1588
  end
1554
- rescue
1589
+ rescue StandardError
1555
1590
  return 'DEFAULT'
1556
1591
  end
1557
1592
  end
1558
1593
 
1559
1594
  # Try to translate the severity.
1560
- if SEVERITY_TRANSLATIONS.key?(severity)
1561
- return SEVERITY_TRANSLATIONS[severity]
1562
- end
1595
+ return SEVERITY_TRANSLATIONS[severity] if SEVERITY_TRANSLATIONS.key?(severity)
1563
1596
 
1564
1597
  # If all else fails, use 'DEFAULT'.
1565
1598
  'DEFAULT'
@@ -1591,9 +1624,8 @@ module Fluent
1591
1624
  # if severity.is_a? String
1592
1625
  # return Google::Logging::Type::LogSeverity.resolve(severity)
1593
1626
  # end
1594
- if GRPC_SEVERITY_MAPPING.key?(severity)
1595
- return GRPC_SEVERITY_MAPPING[severity]
1596
- end
1627
+ return GRPC_SEVERITY_MAPPING[severity] if GRPC_SEVERITY_MAPPING.key?(severity)
1628
+
1597
1629
  severity
1598
1630
  end
1599
1631
 
@@ -1624,15 +1656,15 @@ module Fluent
1624
1656
  seconds = match['seconds'].to_i
1625
1657
  nanos = (match['decimal'].to_f * 1000 * 1000 * 1000).round
1626
1658
  if @use_grpc
1627
- return Google::Protobuf::Duration.new(
1659
+ Google::Protobuf::Duration.new(
1628
1660
  seconds: seconds,
1629
1661
  nanos: nanos
1630
1662
  )
1631
1663
  else
1632
- return {
1664
+ {
1633
1665
  seconds: seconds,
1634
1666
  nanos: nanos
1635
- }.delete_if { |_, v| v == 0 }
1667
+ }.delete_if { |_, v| v.zero? }
1636
1668
  end
1637
1669
  end
1638
1670
 
@@ -1653,6 +1685,7 @@ module Fluent
1653
1685
  (!tag.is_a?(String) || tag == '' || convert_to_utf8(tag) != tag)
1654
1686
  return nil
1655
1687
  end
1688
+
1656
1689
  tag = convert_to_utf8(tag.to_s)
1657
1690
  tag = '_' if tag == ''
1658
1691
  tag
@@ -1664,6 +1697,7 @@ module Fluent
1664
1697
  def delete_and_extract_labels(hash, label_map)
1665
1698
  return {} if label_map.nil? || !label_map.is_a?(Hash) ||
1666
1699
  hash.nil? || !hash.is_a?(Hash)
1700
+
1667
1701
  label_map.each_with_object({}) \
1668
1702
  do |(original_label, new_label), extracted_labels|
1669
1703
  value = hash.delete(original_label)
@@ -1758,13 +1792,12 @@ module Fluent
1758
1792
  elsif resource.type == GKE_CONSTANTS[:resource_type]
1759
1793
  # For Kubernetes logs, use just the container name as the log name
1760
1794
  # if we have it.
1761
- if resource.labels && resource.labels.key?('container_name')
1795
+ if resource.labels&.key?('container_name')
1762
1796
  sanitized_tag = sanitize_tag(resource.labels['container_name'])
1763
1797
  tag = sanitized_tag unless sanitized_tag.nil?
1764
1798
  end
1765
1799
  end
1766
- tag = ERB::Util.url_encode(tag)
1767
- tag
1800
+ ERB::Util.url_encode(tag)
1768
1801
  end
1769
1802
 
1770
1803
  def init_api_client
@@ -1781,7 +1814,8 @@ module Fluent
1781
1814
  if @grpc_compression_algorithm
1782
1815
  compression_options =
1783
1816
  GRPC::Core::CompressionOptions.new(
1784
- default_algorithm: @grpc_compression_algorithm)
1817
+ default_algorithm: @grpc_compression_algorithm
1818
+ )
1785
1819
  compression_channel_args = compression_options.to_channel_arg_hash
1786
1820
  else
1787
1821
  compression_channel_args = {}
@@ -1802,14 +1836,17 @@ module Fluent
1802
1836
  .merge!(compression_channel_args)
1803
1837
  @client = Google::Cloud::Logging::V2::LoggingServiceV2Client.new(
1804
1838
  credentials: GRPC::Core::Channel.new(
1805
- "#{host}#{port}", channel_args, creds))
1839
+ "#{host}#{port}", channel_args, creds
1840
+ )
1841
+ )
1806
1842
  else
1807
1843
  # TODO: Use a non-default ClientOptions object.
1808
1844
  Google::Apis::ClientOptions.default.application_name = PLUGIN_NAME
1809
1845
  Google::Apis::ClientOptions.default.application_version = PLUGIN_VERSION
1810
1846
  @client = Google::Apis::LoggingV2::LoggingService.new
1811
1847
  @client.authorization = Google::Auth.get_application_default(
1812
- Common::LOGGING_SCOPE)
1848
+ Common::LOGGING_SCOPE
1849
+ )
1813
1850
  end
1814
1851
  end
1815
1852
 
@@ -1839,7 +1876,8 @@ module Fluent
1839
1876
  'utf-8',
1840
1877
  invalid: :replace,
1841
1878
  undef: :replace,
1842
- replace: @non_utf8_replacement_string)
1879
+ replace: @non_utf8_replacement_string
1880
+ )
1843
1881
  else
1844
1882
  begin
1845
1883
  input.encode('utf-8')
@@ -1932,19 +1970,22 @@ module Fluent
1932
1970
  error_details_map = Hash.new { |h, k| h[k] = [] }
1933
1971
 
1934
1972
  error_details = ensure_array(
1935
- ensure_hash(ensure_hash(JSON.parse(error.body))['error'])['details'])
1973
+ ensure_hash(ensure_hash(JSON.parse(error.body))['error'])['details']
1974
+ )
1936
1975
  partial_errors = error_details.detect(
1937
1976
  -> { raise JSON::ParserError, "No type #{PARTIAL_ERROR_FIELD}." }
1938
1977
  ) do |error_detail|
1939
1978
  ensure_hash(error_detail)['@type'] == PARTIAL_ERROR_FIELD
1940
1979
  end
1941
1980
  log_entry_errors = ensure_hash(
1942
- ensure_hash(partial_errors)['logEntryErrors'])
1981
+ ensure_hash(partial_errors)['logEntryErrors']
1982
+ )
1943
1983
  log_entry_errors.each do |index, log_entry_error|
1944
1984
  error_hash = ensure_hash(log_entry_error)
1945
- raise JSON::ParserError,
1946
- "Entry #{index} is missing 'code' or 'message'." unless
1947
- error_hash['code'] && error_hash['message']
1985
+ unless error_hash['code'] && error_hash['message']
1986
+ raise JSON::ParserError,
1987
+ "Entry #{index} is missing 'code' or 'message'."
1988
+ end
1948
1989
  error_key = [error_hash['code'], error_hash['message']].freeze
1949
1990
  # TODO(qingling128): Convert indexes to integers.
1950
1991
  error_details_map[error_key] << index
@@ -2003,7 +2044,9 @@ module Fluent
2003
2044
  error_details.empty?
2004
2045
  raise JSON::ParserError, 'No partial error info in error details.' unless
2005
2046
  error_details[0].is_a?(
2006
- Google::Logging::V2::WriteLogEntriesPartialErrors)
2047
+ Google::Logging::V2::WriteLogEntriesPartialErrors
2048
+ )
2049
+
2007
2050
  log_entry_errors = ensure_hash(error_details[0].log_entry_errors)
2008
2051
  log_entry_errors.each do |index, log_entry_error|
2009
2052
  error_key = [log_entry_error[:code], log_entry_error[:message]].freeze
@@ -2039,9 +2082,11 @@ module Fluent
2039
2082
 
2040
2083
  begin
2041
2084
  @k8s_cluster_name ||= @utils.fetch_gce_metadata(
2042
- @platform, 'instance/attributes/cluster-name')
2085
+ @platform, 'instance/attributes/cluster-name'
2086
+ )
2043
2087
  @k8s_cluster_location ||= @utils.fetch_gce_metadata(
2044
- @platform, 'instance/attributes/cluster-location')
2088
+ @platform, 'instance/attributes/cluster-location'
2089
+ )
2045
2090
  rescue StandardError => e
2046
2091
  @log.error 'Failed to retrieve k8s cluster name and location.', \
2047
2092
  error: e
@@ -2080,7 +2125,8 @@ module Fluent
2080
2125
  end
2081
2126
  constructed_resource = Google::Apis::LoggingV2::MonitoredResource.new(
2082
2127
  type: resource_type,
2083
- labels: labels)
2128
+ labels: labels
2129
+ )
2084
2130
  @log.debug("Constructed #{resource_type} resource locally: " \
2085
2131
  "#{constructed_resource.inspect}")
2086
2132
  constructed_resource
@@ -2099,40 +2145,50 @@ module Fluent
2099
2145
  # Increment the metric for the number of successful requests.
2100
2146
  def increment_successful_requests_count
2101
2147
  return unless @successful_requests_count
2148
+
2102
2149
  @successful_requests_count.increment(
2103
- labels: { grpc: @use_grpc, code: @ok_code })
2150
+ labels: { grpc: @use_grpc, code: @ok_code }
2151
+ )
2104
2152
  end
2105
2153
 
2106
2154
  # Increment the metric for the number of failed requests, labeled by
2107
2155
  # the provided status code.
2108
2156
  def increment_failed_requests_count(code)
2109
2157
  return unless @failed_requests_count
2158
+
2110
2159
  @failed_requests_count.increment(
2111
- labels: { grpc: @use_grpc, code: code })
2160
+ labels: { grpc: @use_grpc, code: code }
2161
+ )
2112
2162
  end
2113
2163
 
2114
2164
  # Increment the metric for the number of log entries, successfully
2115
2165
  # ingested by the Stackdriver Logging API.
2116
2166
  def increment_ingested_entries_count(count)
2117
2167
  return unless @ingested_entries_count
2168
+
2118
2169
  @ingested_entries_count.increment(
2119
- labels: { grpc: @use_grpc, code: @ok_code }, by: count)
2170
+ labels: { grpc: @use_grpc, code: @ok_code }, by: count
2171
+ )
2120
2172
  end
2121
2173
 
2122
2174
  # Increment the metric for the number of log entries that were dropped
2123
2175
  # and not ingested by the Stackdriver Logging API.
2124
2176
  def increment_dropped_entries_count(count, code)
2125
2177
  return unless @dropped_entries_count
2178
+
2126
2179
  @dropped_entries_count.increment(
2127
- labels: { grpc: @use_grpc, code: code }, by: count)
2180
+ labels: { grpc: @use_grpc, code: code }, by: count
2181
+ )
2128
2182
  end
2129
2183
 
2130
2184
  # Increment the metric for the number of log entries that were dropped
2131
2185
  # and not ingested by the Stackdriver Logging API.
2132
2186
  def increment_retried_entries_count(count, code)
2133
2187
  return unless @retried_entries_count
2188
+
2134
2189
  @retried_entries_count.increment(
2135
- labels: { grpc: @use_grpc, code: code }, by: count)
2190
+ labels: { grpc: @use_grpc, code: code }, by: count
2191
+ )
2136
2192
  end
2137
2193
  end
2138
2194
  end