fluent-plugin-google-cloud 0.7.28 → 0.7.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6557bd45ff7ce7fffe52375ece31a52e871c139465f799701fc2ce493cf1e0a7
4
- data.tar.gz: 25441416896fd09d2e3e8fd2ed95228772d2ee10a6ba5976c07b6499e0df67b5
3
+ metadata.gz: e47e2821d1838929cf6b2181462d8c2aed2d4a607b2ad4cd0711a7c2d25a5edd
4
+ data.tar.gz: 0c2d369dfad54166a1ca2f2810f72e69a252212e9b243a7bea97b2afa231481e
5
5
  SHA512:
6
- metadata.gz: ec86b91be90466150a1f7e2bdc21bdf64481586a7e860bf7dafdc1a5e0b1e7c6be085b2268ac33dfffc966ecd5e301ee073369086594493f1b4d121821ed2a2c
7
- data.tar.gz: ea9d2c7a0afbba9450f41759b1d371a39d63b1660a0e2a9d1186dded1d9a885fb00693dcb341ff705d26a0d09086c654c590ab4a3db33e61f57358dd4a30c632
6
+ metadata.gz: d528607184bfc1beb617f187919c2b390344137cc5c01c0506fede8bef2cd237faf645354d7a957962ffe8263d2c496d712544ce79d6a6c238b91de4942f3ddf
7
+ data.tar.gz: 96ce50ffcd3df259007bb3b73c1d7301d5ac95f93c4862627125dfcd6d20d43c8b75fa2b07578ad324fc430741f36d76457fd4098d01ec4f3d15437928c04c11
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fluent-plugin-google-cloud (0.7.28)
4
+ fluent-plugin-google-cloud (0.7.29)
5
5
  fluentd (= 1.6.3)
6
6
  google-api-client (= 0.30.8)
7
7
  google-cloud-logging (= 1.6.6)
@@ -52,10 +52,12 @@ GEM
52
52
  representable (~> 3.0)
53
53
  retriable (>= 2.0, < 4.0)
54
54
  signet (~> 0.10)
55
- google-cloud-core (1.4.1)
55
+ google-cloud-core (1.5.0)
56
56
  google-cloud-env (~> 1.0)
57
+ google-cloud-errors (~> 1.0)
57
58
  google-cloud-env (1.3.0)
58
59
  faraday (~> 0.11)
60
+ google-cloud-errors (1.0.0)
59
61
  google-cloud-logging (1.6.6)
60
62
  concurrent-ruby (~> 1.1)
61
63
  google-cloud-core (~> 1.2)
@@ -113,7 +115,7 @@ GEM
113
115
  google-cloud-trace (~> 0.33)
114
116
  opencensus (~> 0.5)
115
117
  os (1.0.1)
116
- parser (2.7.0.1)
118
+ parser (2.7.0.2)
117
119
  ast (~> 2.4.0)
118
120
  power_assert (1.1.5)
119
121
  powerpack (0.1.2)
@@ -161,14 +163,14 @@ GEM
161
163
  power_assert
162
164
  thor (1.0.1)
163
165
  thread_safe (0.3.6)
164
- tins (1.23.0)
166
+ tins (1.24.0)
165
167
  sync
166
168
  tzinfo (1.2.6)
167
169
  thread_safe (~> 0.1)
168
170
  tzinfo-data (1.2019.3)
169
171
  tzinfo (>= 1.0.0)
170
172
  uber (0.1.0)
171
- unicode-display_width (1.6.0)
173
+ unicode-display_width (1.6.1)
172
174
  webmock (3.6.2)
173
175
  addressable (>= 2.3.6)
174
176
  crack (>= 0.3.2)
@@ -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.7.28'
13
+ gem.version = '0.7.29'
14
14
  gem.authors = ['Stackdriver Agents Team']
15
15
  gem.email = ['stackdriver-agents@google.com']
16
16
  gem.required_ruby_version = Gem::Requirement.new('>= 2.2')
@@ -724,7 +724,10 @@ module Fluent
724
724
  end
725
725
  end
726
726
 
727
- ts_secs, ts_nanos = compute_timestamp(record, time)
727
+ ts_secs, ts_nanos, timestamp = compute_timestamp(record, time)
728
+ ts_secs, ts_nanos = adjust_timestamp_if_invalid(timestamp, Time.now) \
729
+ if @adjust_invalid_timestamps && timestamp
730
+
728
731
  severity = compute_severity(
729
732
  entry_level_resource.type, record, entry_level_common_labels)
730
733
 
@@ -1663,7 +1666,6 @@ module Fluent
1663
1666
  end
1664
1667
 
1665
1668
  def compute_timestamp(record, time)
1666
- current_time = Time.now
1667
1669
  if record.key?('timestamp') &&
1668
1670
  record['timestamp'].is_a?(Hash) &&
1669
1671
  record['timestamp'].key?('seconds') &&
@@ -1715,32 +1717,43 @@ module Fluent
1715
1717
  ts_nanos
1716
1718
  end
1717
1719
 
1718
- if @adjust_invalid_timestamps && timestamp
1719
- # Adjust timestamps from the future.
1720
- # There are two cases:
1721
- # 1. The parsed timestamp is later in the current year:
1722
- # This can happen when system log lines from previous years are missing
1723
- # the year, so the date parser assumes the current year.
1724
- # We treat these lines as coming from last year. This could label
1725
- # 2-year-old logs incorrectly, but this probably isn't super important.
1726
- #
1727
- # 2. The parsed timestamp is past the end of the current year:
1728
- # Since the year is different from the current year, this isn't the
1729
- # missing year in system logs. It is unlikely that users explicitly
1730
- # write logs at a future date. This could result from an unsynchronized
1731
- # clock on a VM, or some random value being parsed as the timestamp.
1732
- # We reset the timestamp on those lines to the default value and let the
1733
- # downstream API handle it.
1734
- next_year = Time.mktime(current_time.year + 1)
1735
- one_day_later = current_time.to_datetime.next_day.to_time
1736
- if timestamp >= next_year # Case 2.
1737
- ts_secs = 0
1738
- ts_nanos = 0
1739
- elsif timestamp >= one_day_later # Case 1.
1740
- adjusted_timestamp = timestamp.to_datetime.prev_year.to_time
1741
- ts_secs = adjusted_timestamp.tv_sec
1742
- # The value of ts_nanos should not change when subtracting a year.
1743
- end
1720
+ [ts_secs, ts_nanos, timestamp]
1721
+ end
1722
+
1723
+ # Adjust timestamps from the future.
1724
+ # The base case is:
1725
+ # 0. The parsed timestamp is less than one day into the future.
1726
+ # This is allowed by the API, and should be left unchanged.
1727
+ #
1728
+ # Beyond that, there are two cases:
1729
+ # 1. The parsed timestamp is later in the current year:
1730
+ # This can happen when system log lines from previous years are missing
1731
+ # the year, so the date parser assumes the current year.
1732
+ # We treat these lines as coming from last year. This could label
1733
+ # 2-year-old logs incorrectly, but this probably isn't super important.
1734
+ #
1735
+ # 2. The parsed timestamp is past the end of the current year:
1736
+ # Since the year is different from the current year, this isn't the
1737
+ # missing year in system logs. It is unlikely that users explicitly
1738
+ # write logs at a future date. This could result from an unsynchronized
1739
+ # clock on a VM, or some random value being parsed as the timestamp.
1740
+ # We reset the timestamp on those lines to the default value and let the
1741
+ # downstream API handle it.
1742
+ def adjust_timestamp_if_invalid(timestamp, current_time)
1743
+ ts_secs = timestamp.tv_sec
1744
+ ts_nanos = timestamp.tv_nsec
1745
+
1746
+ next_year = Time.mktime(current_time.year + 1)
1747
+ one_day_later = current_time.to_datetime.next_day.to_time
1748
+ if timestamp < one_day_later # Case 0.
1749
+ # Leave the timestamp as-is.
1750
+ elsif timestamp >= next_year # Case 2.
1751
+ ts_secs = 0
1752
+ ts_nanos = 0
1753
+ else # Case 1.
1754
+ adjusted_timestamp = timestamp.to_datetime.prev_year.to_time
1755
+ ts_secs = adjusted_timestamp.tv_sec
1756
+ # The value of ts_nanos should not change when subtracting a year.
1744
1757
  end
1745
1758
 
1746
1759
  [ts_secs, ts_nanos]
@@ -943,77 +943,206 @@ module BaseTest
943
943
  end
944
944
  end
945
945
 
946
- def test_timestamps
946
+ def test_compute_timestamp
947
947
  setup_gce_metadata_stubs
948
- current_time = Time.now
948
+ d = create_driver(APPLICATION_DEFAULT_CONFIG)
949
+
950
+ compute_timestamp = lambda do |driver, record, time|
951
+ driver.instance.send(:compute_timestamp, record, time)
952
+ end
953
+
954
+ current_time = Time.new(2019, 12, 29, 10, 23, 35, '-08:00')
955
+ one_day_later = current_time.to_datetime.next_day.to_time
956
+ just_under_one_day_later = one_day_later - 1
949
957
  next_year = Time.mktime(current_time.year + 1)
950
958
  one_second_before_next_year = next_year - 1
951
- adjusted_to_last_year =
952
- one_second_before_next_year.to_datetime.prev_year.to_time
953
959
  one_second_into_next_year = next_year + 1
954
- one_day_into_next_year = next_year.to_date.next_day.to_time
960
+ one_day_into_next_year = next_year.to_datetime.next_day.to_time
961
+
962
+ [
963
+ Time.at(123_456.789),
964
+ Time.at(0),
965
+ current_time,
966
+ just_under_one_day_later,
967
+ one_second_before_next_year,
968
+ next_year,
969
+ one_second_into_next_year,
970
+ one_day_into_next_year
971
+ ].each do |ts|
972
+ # Use record collection time.
973
+ ts_secs, ts_nanos, actual_ts = compute_timestamp[d, {
974
+ 'message' => ''
975
+ }, ts.to_f]
976
+ assert_timestamp_matches ts, ts_secs, ts_nanos, actual_ts.iso8601
977
+
978
+ # Use the (deprecated) timeNanos key.
979
+ ts_secs, ts_nanos, actual_ts = compute_timestamp[d, {
980
+ 'message' => '',
981
+ 'timeNanos' => ts.tv_sec * 1_000_000_000 + ts.tv_nsec
982
+ }, 1.0]
983
+ assert_timestamp_matches ts, ts_secs, ts_nanos, actual_ts.iso8601
984
+
985
+ # Use the structured timestamp key.
986
+ ts_secs, ts_nanos, actual_ts = compute_timestamp[d, {
987
+ 'message' => '',
988
+ 'timestamp' => { 'seconds' => ts.tv_sec, 'nanos' => ts.tv_nsec }
989
+ }, 1.0]
990
+ assert_timestamp_matches ts, ts_secs, ts_nanos, actual_ts.iso8601
991
+
992
+ # Use the timestampSeconds/timestampNanos keys.
993
+ ts_secs, ts_nanos, actual_ts = compute_timestamp[d, {
994
+ 'message' => '',
995
+ 'timestampSeconds' => ts.tv_sec,
996
+ 'timestampNanos' => ts.tv_nsec
997
+ }, 1.0]
998
+ assert_timestamp_matches ts, ts_secs, ts_nanos, actual_ts.iso8601
999
+
1000
+ # Use the string timestampSeconds/timestampNanos keys.
1001
+ ts_secs, ts_nanos, actual_ts = compute_timestamp[d, {
1002
+ 'message' => '',
1003
+ 'timestampSeconds' => ts.tv_sec.to_s,
1004
+ 'timestampNanos' => ts.tv_nsec.to_s
1005
+ }, 1.0]
1006
+ assert_timestamp_matches ts, ts_secs, ts_nanos, actual_ts.iso8601
1007
+ end
1008
+ end
1009
+
1010
+ def test_adjust_timestamp
1011
+ setup_gce_metadata_stubs
1012
+ d = create_driver(APPLICATION_DEFAULT_CONFIG)
1013
+
1014
+ adjust_timestamp_if_invalid = lambda do |driver, timestamp, current_time|
1015
+ driver.instance.send(:adjust_timestamp_if_invalid, timestamp,
1016
+ current_time)
1017
+ end
1018
+
1019
+ december_29 = Time.new(2019, 12, 29, 10, 23, 35, '-08:00')
1020
+ december_31 = Time.new(2019, 12, 31, 10, 23, 35, '-08:00')
1021
+ january_1 = Time.new(2020, 1, 1, 10, 23, 35, '-08:00')
1022
+
955
1023
  {
956
- APPLICATION_DEFAULT_CONFIG => {
957
- Time.at(123_456.789) => Time.at(123_456.789),
958
- Time.at(0) => Time.at(0),
959
- current_time => current_time,
960
- one_second_before_next_year => adjusted_to_last_year,
961
- next_year => Time.at(0),
962
- one_second_into_next_year => Time.at(0),
963
- one_day_into_next_year => Time.at(0)
964
- },
965
- NO_ADJUST_TIMESTAMPS_CONFIG => {
966
- Time.at(123_456.789) => Time.at(123_456.789),
967
- Time.at(0) => Time.at(0),
968
- current_time => current_time,
969
- one_second_before_next_year => one_second_before_next_year,
970
- next_year => next_year,
971
- one_second_into_next_year => one_second_into_next_year,
972
- one_day_into_next_year => one_day_into_next_year
973
- }
974
- }.each do |config, timestamps|
1024
+ # December 29, 2019 (normal operation).
1025
+ december_29 => begin
1026
+ one_day_later = Time.new(2019, 12, 30, 10, 23, 35, '-08:00')
1027
+ one_day_a_year_earlier = Time.new(2018, 12, 30, 10, 23, 35, '-08:00')
1028
+ just_under_one_day_later = Time.new(2019, 12, 30, 10, 23, 34, '-08:00')
1029
+ next_year = Time.new(2020, 1, 1, 0, 0, 0, '-08:00')
1030
+ one_second_before_next_year =
1031
+ Time.new(2019, 12, 31, 11, 59, 59, '-08:00')
1032
+ one_second_before_this_year =
1033
+ Time.new(2018, 12, 31, 11, 59, 59, '-08:00')
1034
+ one_second_into_next_year = Time.new(2020, 1, 1, 0, 0, 1, '-08:00')
1035
+ one_day_into_next_year = Time.new(2020, 1, 2, 0, 0, 0, '-08:00')
1036
+ {
1037
+ Time.at(123_456.789) => Time.at(123_456.789),
1038
+ Time.at(0) => Time.at(0),
1039
+ december_29 => december_29,
1040
+ one_day_later => one_day_a_year_earlier,
1041
+ just_under_one_day_later => just_under_one_day_later,
1042
+ one_second_before_next_year => one_second_before_this_year,
1043
+ next_year => Time.at(0),
1044
+ one_second_into_next_year => Time.at(0),
1045
+ one_day_into_next_year => Time.at(0)
1046
+ }
1047
+ end,
1048
+ # January 1, 2020 (normal operation).
1049
+ january_1 => begin
1050
+ one_day_later = Time.new(2020, 1, 2, 10, 23, 35, '-08:00')
1051
+ one_day_a_year_earlier = Time.new(2019, 1, 2, 10, 23, 35, '-08:00')
1052
+ just_under_one_day_later = Time.new(2020, 1, 2, 10, 23, 34, '-08:00')
1053
+ next_year = Time.new(2021, 1, 1, 0, 0, 0, '-08:00')
1054
+ one_second_before_next_year =
1055
+ Time.new(2020, 12, 31, 11, 59, 59, '-08:00')
1056
+ one_second_before_this_year =
1057
+ Time.new(2019, 12, 31, 11, 59, 59, '-08:00')
1058
+ one_second_into_next_year = Time.new(2021, 1, 1, 0, 0, 1, '-08:00')
1059
+ one_day_into_next_year = Time.new(2021, 1, 2, 0, 0, 0, '-08:00')
1060
+ {
1061
+ Time.at(123_456.789) => Time.at(123_456.789),
1062
+ Time.at(0) => Time.at(0),
1063
+ january_1 => january_1,
1064
+ one_day_later => one_day_a_year_earlier,
1065
+ just_under_one_day_later => just_under_one_day_later,
1066
+ one_second_before_next_year => one_second_before_this_year,
1067
+ next_year => Time.at(0),
1068
+ one_second_into_next_year => Time.at(0),
1069
+ one_day_into_next_year => Time.at(0)
1070
+ }
1071
+ end,
1072
+ # December 31, 2019 (next day overlaps new year).
1073
+ december_31 => begin
1074
+ one_day_later = Time.new(2020, 1, 1, 10, 23, 35, '-08:00')
1075
+ just_under_one_day_later = Time.new(2020, 1, 1, 10, 23, 34, '-08:00')
1076
+ next_year = Time.new(2020, 1, 1, 0, 0, 0, '-08:00')
1077
+ one_second_before_next_year =
1078
+ Time.new(2019, 12, 31, 11, 59, 59, '-08:00')
1079
+ one_second_into_next_year = Time.new(2020, 1, 1, 0, 0, 1, '-08:00')
1080
+ one_day_into_next_year = Time.new(2020, 1, 2, 0, 0, 0, '-08:00')
1081
+ {
1082
+ Time.at(123_456.789) => Time.at(123_456.789),
1083
+ Time.at(0) => Time.at(0),
1084
+ december_31 => december_31,
1085
+ one_day_later => Time.at(0), # Falls into the next year.
1086
+ just_under_one_day_later => just_under_one_day_later,
1087
+ one_second_before_next_year => one_second_before_next_year,
1088
+ next_year => next_year,
1089
+ one_second_into_next_year => one_second_into_next_year,
1090
+ one_day_into_next_year => Time.at(0)
1091
+ }
1092
+ end
1093
+ }.each do |current_time, timestamps|
975
1094
  timestamps.each do |ts, expected_ts|
976
- emit_index = 0
977
- setup_logging_stubs do
978
- @logs_sent = []
979
- d = create_driver(config)
980
- # Test the "native" fluentd timestamp as well as our nanosecond tags.
981
- d.emit({ 'message' => log_entry(emit_index) }, ts.to_f)
982
- emit_index += 1
983
- d.emit('message' => log_entry(emit_index),
984
- 'timeNanos' => ts.tv_sec * 1_000_000_000 + ts.tv_nsec)
985
- emit_index += 1
986
- d.emit('message' => log_entry(emit_index),
987
- 'timestamp' => { 'seconds' => ts.tv_sec,
988
- 'nanos' => ts.tv_nsec })
989
- emit_index += 1
990
- d.emit('message' => log_entry(emit_index),
991
- 'timestampSeconds' => ts.tv_sec,
992
- 'timestampNanos' => ts.tv_nsec)
993
- emit_index += 1
994
- d.emit('message' => log_entry(emit_index),
995
- 'timestampSeconds' => ts.tv_sec.to_s,
996
- 'timestampNanos' => ts.tv_nsec.to_s)
997
- emit_index += 1
998
- d.run
999
- verify_log_entries(emit_index, COMPUTE_PARAMS) do |entry, i|
1000
- verify_default_log_entry_text(entry['textPayload'], i, entry)
1001
- actual_timestamp = timestamp_parse(entry['timestamp'])
1002
- assert_equal actual_timestamp['seconds'], expected_ts.tv_sec, entry
1003
- # Fluentd v0.14 onwards supports nanosecond timestamp values.
1004
- # Added in 600 ns delta to avoid flaky tests introduced
1005
- # due to rounding error in double-precision floating-point numbers
1006
- # (to account for the missing 9 bits of precision ~ 512 ns).
1007
- # See http://wikipedia.org/wiki/Double-precision_floating-point_format.
1008
- assert_in_delta expected_ts.tv_nsec, actual_timestamp['nanos'],
1009
- 600, entry
1010
- end
1095
+ ts_secs, ts_nanos = adjust_timestamp_if_invalid[d, ts, current_time]
1096
+ adjusted_ts = Time.at(ts_secs, ts_nanos / 1_000.0)
1097
+ assert_timestamp_matches expected_ts, ts_secs, ts_nanos,
1098
+ adjusted_ts.iso8601
1099
+ end
1100
+ end
1101
+ end
1102
+
1103
+ def test_log_timestamps
1104
+ setup_gce_metadata_stubs
1105
+ current_time = Time.now
1106
+ {
1107
+ # Verify that timestamps make it through.
1108
+ Time.at(123_456.789) => Time.at(123_456.789),
1109
+ Time.at(0) => Time.at(0),
1110
+ current_time => current_time
1111
+ }.each do |ts, expected_ts|
1112
+ emit_index = 0
1113
+ setup_logging_stubs do
1114
+ @logs_sent = []
1115
+ d = create_driver(APPLICATION_DEFAULT_CONFIG)
1116
+ # Test the "native" fluentd timestamp as well as our nanosecond tags.
1117
+ d.emit({ 'message' => log_entry(emit_index) }, ts.to_f)
1118
+ emit_index += 1
1119
+ d.emit('message' => log_entry(emit_index),
1120
+ 'timeNanos' => ts.tv_sec * 1_000_000_000 + ts.tv_nsec)
1121
+ emit_index += 1
1122
+ d.emit('message' => log_entry(emit_index),
1123
+ 'timestamp' => { 'seconds' => ts.tv_sec,
1124
+ 'nanos' => ts.tv_nsec })
1125
+ emit_index += 1
1126
+ d.emit('message' => log_entry(emit_index),
1127
+ 'timestampSeconds' => ts.tv_sec,
1128
+ 'timestampNanos' => ts.tv_nsec)
1129
+ emit_index += 1
1130
+ d.emit('message' => log_entry(emit_index),
1131
+ 'timestampSeconds' => ts.tv_sec.to_s,
1132
+ 'timestampNanos' => ts.tv_nsec.to_s)
1133
+ emit_index += 1
1134
+ d.run
1135
+ verify_log_entries(emit_index, COMPUTE_PARAMS) do |entry, i|
1136
+ verify_default_log_entry_text(entry['textPayload'], i, entry)
1137
+ actual_timestamp = timestamp_parse(entry['timestamp'])
1138
+ assert_timestamp_matches expected_ts, actual_timestamp['seconds'],
1139
+ actual_timestamp['nanos'], entry
1011
1140
  end
1012
1141
  end
1013
1142
  end
1014
1143
  end
1015
1144
 
1016
- def test_malformed_timestamp
1145
+ def test_malformed_timestamp_field
1017
1146
  setup_gce_metadata_stubs
1018
1147
  setup_logging_stubs do
1019
1148
  d = create_driver
@@ -2749,6 +2878,17 @@ module BaseTest
2749
2878
  _undefined
2750
2879
  end
2751
2880
 
2881
+ # Compare the timestamp seconds and nanoseconds with the expected timestamp.
2882
+ def assert_timestamp_matches(expected_ts, ts_secs, ts_nanos, entry)
2883
+ assert_equal expected_ts.tv_sec, ts_secs, entry
2884
+ # Fluentd v0.14 onwards supports nanosecond timestamp values.
2885
+ # Added in 600 ns delta to avoid flaky tests introduced
2886
+ # due to rounding error in double-precision floating-point numbers
2887
+ # (to account for the missing 9 bits of precision ~ 512 ns).
2888
+ # See http://wikipedia.org/wiki/Double-precision_floating-point_format.
2889
+ assert_in_delta expected_ts.tv_nsec, ts_nanos, 600, entry
2890
+ end
2891
+
2752
2892
  def assert_prometheus_metric_value(metric_name, expected_value, labels = {})
2753
2893
  metric = Prometheus::Client.registry.get(metric_name)
2754
2894
  assert_not_nil(metric)
@@ -274,10 +274,6 @@ module Constants
274
274
  split_logs_by_tag true
275
275
  ).freeze
276
276
 
277
- NO_ADJUST_TIMESTAMPS_CONFIG = %(
278
- adjust_invalid_timestamps false
279
- ).freeze
280
-
281
277
  ENABLE_PROMETHEUS_CONFIG = %(
282
278
  enable_monitoring true
283
279
  monitoring_type prometheus
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-google-cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.28
4
+ version: 0.7.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stackdriver Agents Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-07 00:00:00.000000000 Z
11
+ date: 2020-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd