fluent-plugin-google-cloud 0.7.4 → 0.7.5.pre.multiworkers
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 +5 -5
- data/fluent-plugin-google-cloud.gemspec +1 -1
- data/lib/fluent/plugin/out_google_cloud.rb +77 -14
- data/test/plugin/base_test.rb +310 -52
- data/test/plugin/constants.rb +123 -0
- data/test/plugin/test_out_google_cloud.rb +4 -2
- data/test/plugin/test_out_google_cloud_grpc.rb +4 -2
- metadata +5 -7
- data/CUSTOM_SPONGE_CONFIG +0 -0
- data/Gemfile.lock +0 -160
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: be98011ce135e9570444d3c55967c316a96a858c
|
4
|
+
data.tar.gz: 88271c68f053f89f462ad8b5ed6b1fb2220e2bdc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 279c39e5dcb334c48894dc970234fe780dfde6bb342f76715988730e72731accade84a6fafdcbc39ddd65087609ac11d274d693047818786034c3219ebcc22cb
|
7
|
+
data.tar.gz: 34e85bc20d7abf886508d1036a00b4ff1296dcea427da2b3870ca858a11e3217a57a397d4d72c0cfc06c74f015ccf5eb9a9dcd4fede4930c2625968b74fd31a4
|
@@ -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.
|
13
|
+
gem.version = '0.7.5.pre.multiworkers'
|
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')
|
@@ -95,6 +95,9 @@ module Fluent
|
|
95
95
|
K8S_CONTAINER_CONSTANTS = {
|
96
96
|
resource_type: 'k8s_container'
|
97
97
|
}.freeze
|
98
|
+
K8S_POD_CONSTANTS = {
|
99
|
+
resource_type: 'k8s_pod'
|
100
|
+
}.freeze
|
98
101
|
K8S_NODE_CONSTANTS = {
|
99
102
|
resource_type: 'k8s_node'
|
100
103
|
}.freeze
|
@@ -143,12 +146,13 @@ module Fluent
|
|
143
146
|
# Default values for JSON payload keys to set the "httpRequest",
|
144
147
|
# "operation", "sourceLocation", "trace" fields in the LogEntry.
|
145
148
|
DEFAULT_HTTP_REQUEST_KEY = 'httpRequest'.freeze
|
149
|
+
DEFAULT_INSERT_ID_KEY = 'logging.googleapis.com/insertId'.freeze
|
150
|
+
DEFAULT_LABELS_KEY = 'logging.googleapis.com/labels'.freeze
|
146
151
|
DEFAULT_OPERATION_KEY = 'logging.googleapis.com/operation'.freeze
|
147
152
|
DEFAULT_SOURCE_LOCATION_KEY =
|
148
153
|
'logging.googleapis.com/sourceLocation'.freeze
|
149
|
-
DEFAULT_TRACE_KEY = 'logging.googleapis.com/trace'.freeze
|
150
154
|
DEFAULT_SPAN_ID_KEY = 'logging.googleapis.com/spanId'.freeze
|
151
|
-
|
155
|
+
DEFAULT_TRACE_KEY = 'logging.googleapis.com/trace'.freeze
|
152
156
|
|
153
157
|
DEFAULT_METADATA_AGENT_URL =
|
154
158
|
'http://local-metadata-agent.stackdriver.com:8000'.freeze
|
@@ -201,16 +205,6 @@ module Fluent
|
|
201
205
|
# The non-grpc version class name.
|
202
206
|
'Google::Apis::LoggingV2::HttpRequest'
|
203
207
|
],
|
204
|
-
'source_location' => [
|
205
|
-
'@source_location_key',
|
206
|
-
[
|
207
|
-
%w(file file parse_string),
|
208
|
-
%w(function function parse_string),
|
209
|
-
%w(line line parse_int)
|
210
|
-
],
|
211
|
-
'Google::Logging::V2::LogEntrySourceLocation',
|
212
|
-
'Google::Apis::LoggingV2::LogEntrySourceLocation'
|
213
|
-
],
|
214
208
|
'operation' => [
|
215
209
|
'@operation_key',
|
216
210
|
[
|
@@ -221,6 +215,16 @@ module Fluent
|
|
221
215
|
],
|
222
216
|
'Google::Logging::V2::LogEntryOperation',
|
223
217
|
'Google::Apis::LoggingV2::LogEntryOperation'
|
218
|
+
],
|
219
|
+
'source_location' => [
|
220
|
+
'@source_location_key',
|
221
|
+
[
|
222
|
+
%w(file file parse_string),
|
223
|
+
%w(function function parse_string),
|
224
|
+
%w(line line parse_int)
|
225
|
+
],
|
226
|
+
'Google::Logging::V2::LogEntrySourceLocation',
|
227
|
+
'Google::Apis::LoggingV2::LogEntrySourceLocation'
|
224
228
|
]
|
225
229
|
}.freeze
|
226
230
|
|
@@ -295,12 +299,13 @@ module Fluent
|
|
295
299
|
# Map keys from a JSON payload to corresponding LogEntry fields.
|
296
300
|
config_param :http_request_key, :string, :default =>
|
297
301
|
DEFAULT_HTTP_REQUEST_KEY
|
302
|
+
config_param :insert_id_key, :string, :default => DEFAULT_INSERT_ID_KEY
|
303
|
+
config_param :labels_key, :string, :default => DEFAULT_LABELS_KEY
|
298
304
|
config_param :operation_key, :string, :default => DEFAULT_OPERATION_KEY
|
299
305
|
config_param :source_location_key, :string, :default =>
|
300
306
|
DEFAULT_SOURCE_LOCATION_KEY
|
301
|
-
config_param :trace_key, :string, :default => DEFAULT_TRACE_KEY
|
302
307
|
config_param :span_id_key, :string, :default => DEFAULT_SPAN_ID_KEY
|
303
|
-
config_param :
|
308
|
+
config_param :trace_key, :string, :default => DEFAULT_TRACE_KEY
|
304
309
|
|
305
310
|
# Whether to try to detect if the record is a text log entry with JSON
|
306
311
|
# content that needs to be parsed.
|
@@ -617,6 +622,7 @@ module Fluent
|
|
617
622
|
'severity',
|
618
623
|
@http_request_key,
|
619
624
|
@insert_id_key,
|
625
|
+
@labels_key,
|
620
626
|
@operation_key,
|
621
627
|
@source_location_key,
|
622
628
|
@span_id_key,
|
@@ -650,6 +656,11 @@ module Fluent
|
|
650
656
|
severity = compute_severity(
|
651
657
|
entry_level_resource.type, record, entry_level_common_labels)
|
652
658
|
|
659
|
+
dynamic_labels_from_payload = parse_labels(record)
|
660
|
+
|
661
|
+
entry_level_common_labels = entry_level_common_labels.merge!(
|
662
|
+
dynamic_labels_from_payload) if dynamic_labels_from_payload
|
663
|
+
|
653
664
|
entry = @construct_log_entry.call(entry_level_common_labels,
|
654
665
|
entry_level_resource,
|
655
666
|
severity,
|
@@ -1178,6 +1189,8 @@ module Fluent
|
|
1178
1189
|
|
1179
1190
|
# GCE.
|
1180
1191
|
when COMPUTE_CONSTANTS[:resource_type]
|
1192
|
+
raise "Cannot construct a #{type} resource without vm_id and zone" \
|
1193
|
+
unless @vm_id && @zone
|
1181
1194
|
return {
|
1182
1195
|
'instance_id' => @vm_id,
|
1183
1196
|
'zone' => @zone
|
@@ -1185,6 +1198,8 @@ module Fluent
|
|
1185
1198
|
|
1186
1199
|
# GKE container.
|
1187
1200
|
when GKE_CONSTANTS[:resource_type]
|
1201
|
+
raise "Cannot construct a #{type} resource without vm_id and zone" \
|
1202
|
+
unless @vm_id && @zone
|
1188
1203
|
return {
|
1189
1204
|
'instance_id' => @vm_id,
|
1190
1205
|
'zone' => @zone,
|
@@ -1205,6 +1220,8 @@ module Fluent
|
|
1205
1220
|
|
1206
1221
|
# EC2.
|
1207
1222
|
when EC2_CONSTANTS[:resource_type]
|
1223
|
+
raise "Cannot construct a #{type} resource without vm_id and zone" \
|
1224
|
+
unless @vm_id && @zone
|
1208
1225
|
labels = {
|
1209
1226
|
'instance_id' => @vm_id,
|
1210
1227
|
'region' => @zone
|
@@ -1366,6 +1383,7 @@ module Fluent
|
|
1366
1383
|
# TODO(qingling128): Temporary fallback for metadata agent restarts.
|
1367
1384
|
# K8s resources.
|
1368
1385
|
when K8S_CONTAINER_CONSTANTS[:resource_type],
|
1386
|
+
K8S_POD_CONSTANTS[:resource_type],
|
1369
1387
|
K8S_NODE_CONSTANTS[:resource_type]
|
1370
1388
|
common_labels.delete("#{COMPUTE_CONSTANTS[:service]}/resource_name")
|
1371
1389
|
|
@@ -1685,6 +1703,10 @@ module Fluent
|
|
1685
1703
|
end
|
1686
1704
|
|
1687
1705
|
def set_log_entry_fields(record, entry)
|
1706
|
+
# TODO(qingling128) On the next major after 0.7.4, make all logEntry
|
1707
|
+
# subfields behave the same way: if the field is not in the correct
|
1708
|
+
# format, log an error in the Fluentd log and remove this field from
|
1709
|
+
# payload. This is the preferred behavior per PM decision.
|
1688
1710
|
LOG_ENTRY_FIELDS_MAP.each do |field_name, config|
|
1689
1711
|
payload_key, subfields, grpc_class, non_grpc_class = config
|
1690
1712
|
begin
|
@@ -1728,6 +1750,31 @@ module Fluent
|
|
1728
1750
|
end
|
1729
1751
|
end
|
1730
1752
|
|
1753
|
+
# Parse labels. Return nil if not set.
|
1754
|
+
def parse_labels(record)
|
1755
|
+
payload_labels = record.delete(@labels_key)
|
1756
|
+
return nil unless payload_labels
|
1757
|
+
unless payload_labels.is_a?(Hash)
|
1758
|
+
@log.error "Invalid value of '#{@labels_key}' in the payload: " \
|
1759
|
+
"#{payload_labels}. Labels need to be a JSON object."
|
1760
|
+
return nil
|
1761
|
+
end
|
1762
|
+
|
1763
|
+
non_string_keys = payload_labels.each_with_object([]) do |(k, v), a|
|
1764
|
+
a << k unless k.is_a?(String) && v.is_a?(String)
|
1765
|
+
end
|
1766
|
+
unless non_string_keys.empty?
|
1767
|
+
@log.error "Invalid value of '#{@labels_key}' in the payload: " \
|
1768
|
+
"#{payload_labels}. Labels need string values for all " \
|
1769
|
+
"keys; keys #{non_string_keys} don't."
|
1770
|
+
return nil
|
1771
|
+
end
|
1772
|
+
payload_labels
|
1773
|
+
rescue StandardError => err
|
1774
|
+
@log.error "Failed to extract '#{@labels_key}' from payload.", err
|
1775
|
+
return nil
|
1776
|
+
end
|
1777
|
+
|
1731
1778
|
# Values permitted by the API for 'severity' (which is an enum).
|
1732
1779
|
VALID_SEVERITIES = Set.new(
|
1733
1780
|
%w(DEFAULT DEBUG INFO NOTICE WARNING ERROR CRITICAL ALERT EMERGENCY)
|
@@ -1875,6 +1922,10 @@ module Fluent
|
|
1875
1922
|
.gsub('p.p', '.')
|
1876
1923
|
end
|
1877
1924
|
|
1925
|
+
def multi_workers_ready?
|
1926
|
+
true
|
1927
|
+
end
|
1928
|
+
|
1878
1929
|
def format(tag, time, record)
|
1879
1930
|
Fluent::Engine.msgpack_factory.packer.write([tag, time, record]).to_s
|
1880
1931
|
end
|
@@ -2260,6 +2311,10 @@ module Fluent
|
|
2260
2311
|
\.(?<namespace_name>[0-9a-z-]+)
|
2261
2312
|
\.(?<pod_name>[.0-9a-z-]+)
|
2262
2313
|
\.(?<container_name>[0-9a-z-]+)$/x =~ local_resource_id ||
|
2314
|
+
/^
|
2315
|
+
(?<resource_type>k8s_pod)
|
2316
|
+
\.(?<namespace_name>[0-9a-z-]+)
|
2317
|
+
\.(?<pod_name>[.0-9a-z-]+)$/x =~ local_resource_id ||
|
2263
2318
|
/^
|
2264
2319
|
(?<resource_type>k8s_node)
|
2265
2320
|
\.(?<node_name>[0-9a-z-]+)$/x =~ local_resource_id
|
@@ -2287,6 +2342,14 @@ module Fluent
|
|
2287
2342
|
'location' => @k8s_cluster_location
|
2288
2343
|
}
|
2289
2344
|
fallback_resource = GKE_CONSTANTS[:resource_type]
|
2345
|
+
when K8S_POD_CONSTANTS[:resource_type]
|
2346
|
+
labels = {
|
2347
|
+
'namespace_name' => namespace_name,
|
2348
|
+
'pod_name' => pod_name,
|
2349
|
+
'cluster_name' => @k8s_cluster_name,
|
2350
|
+
'location' => @k8s_cluster_location
|
2351
|
+
}
|
2352
|
+
fallback_resource = GKE_CONSTANTS[:resource_type]
|
2290
2353
|
when K8S_NODE_CONSTANTS[:resource_type]
|
2291
2354
|
labels = {
|
2292
2355
|
'node_name' => node_name,
|
data/test/plugin/base_test.rb
CHANGED
@@ -626,7 +626,9 @@ module BaseTest
|
|
626
626
|
end
|
627
627
|
d.run
|
628
628
|
end
|
629
|
-
|
629
|
+
expected_params = COMPUTE_PARAMS.merge(
|
630
|
+
labels: COMPUTE_PARAMS[:labels].merge(LABELS_MESSAGE))
|
631
|
+
verify_log_entries(3, expected_params, 'jsonPayload') do |entry|
|
630
632
|
fields = get_fields(entry['jsonPayload'])
|
631
633
|
assert_equal 4, fields.size, entry
|
632
634
|
assert_equal 'test log entry 0', get_string(fields['msg']), entry
|
@@ -1249,14 +1251,18 @@ module BaseTest
|
|
1249
1251
|
verify_subfields_from_record(DEFAULT_HTTP_REQUEST_KEY)
|
1250
1252
|
end
|
1251
1253
|
|
1252
|
-
def
|
1253
|
-
verify_subfields_from_record(
|
1254
|
+
def test_log_entry_labels_field_from_record
|
1255
|
+
verify_subfields_from_record(DEFAULT_LABELS_KEY, false)
|
1254
1256
|
end
|
1255
1257
|
|
1256
1258
|
def test_log_entry_operation_field_from_record
|
1257
1259
|
verify_subfields_from_record(DEFAULT_OPERATION_KEY)
|
1258
1260
|
end
|
1259
1261
|
|
1262
|
+
def test_log_entry_source_location_field_from_record
|
1263
|
+
verify_subfields_from_record(DEFAULT_SOURCE_LOCATION_KEY)
|
1264
|
+
end
|
1265
|
+
|
1260
1266
|
# Verify the subfields extraction of LogEntry fields when there are other
|
1261
1267
|
# fields.
|
1262
1268
|
|
@@ -1264,26 +1270,48 @@ module BaseTest
|
|
1264
1270
|
verify_subfields_partial_from_record(DEFAULT_HTTP_REQUEST_KEY)
|
1265
1271
|
end
|
1266
1272
|
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1273
|
+
# We don't need a test like 'test_log_entry_labels_field_partial_from_record'
|
1274
|
+
# because labels are free range strings. Everything in the labels field should
|
1275
|
+
# be in the resulting logEntry->labels field. There is no need to check
|
1276
|
+
# partial transformation (aka, some 'labels' fields are extracted, while
|
1277
|
+
# others are left as it is).
|
1270
1278
|
|
1271
1279
|
def test_log_entry_operation_field_partial_from_record
|
1272
1280
|
verify_subfields_partial_from_record(DEFAULT_OPERATION_KEY)
|
1273
1281
|
end
|
1274
1282
|
|
1283
|
+
def test_log_entry_source_location_field_partial_from_record
|
1284
|
+
verify_subfields_partial_from_record(DEFAULT_SOURCE_LOCATION_KEY)
|
1285
|
+
end
|
1286
|
+
|
1275
1287
|
# Verify the subfields extraction of LogEntry fields when they are not hashes.
|
1276
1288
|
|
1277
1289
|
def test_log_entry_http_request_field_when_not_hash
|
1278
|
-
|
1290
|
+
# TODO(qingling128) On the next major after 0.7.4, make all logEntry
|
1291
|
+
# subfields behave the same way: if the field is not in the correct format,
|
1292
|
+
# log an error in the Fluentd log and remove this field from payload. This
|
1293
|
+
# is the preferred behavior per PM decision.
|
1294
|
+
verify_subfields_untouched_when_not_hash(DEFAULT_HTTP_REQUEST_KEY)
|
1279
1295
|
end
|
1280
1296
|
|
1281
|
-
def
|
1282
|
-
|
1297
|
+
def test_log_entry_labels_field_when_not_hash
|
1298
|
+
verify_subfields_removed_when_not_hash(DEFAULT_LABELS_KEY)
|
1283
1299
|
end
|
1284
1300
|
|
1285
1301
|
def test_log_entry_operation_field_when_not_hash
|
1286
|
-
|
1302
|
+
# TODO(qingling128) On the next major after 0.7.4, make all logEntry
|
1303
|
+
# subfields behave the same way: if the field is not in the correct format,
|
1304
|
+
# log an error in the Fluentd log and remove this field from payload. This
|
1305
|
+
# is the preferred behavior per PM decision.
|
1306
|
+
verify_subfields_untouched_when_not_hash(DEFAULT_OPERATION_KEY)
|
1307
|
+
end
|
1308
|
+
|
1309
|
+
def test_log_entry_source_location_field_when_not_hash
|
1310
|
+
# TODO(qingling128) On the next major after 0.7.4, make all logEntry
|
1311
|
+
# subfields behave the same way: if the field is not in the correct format,
|
1312
|
+
# log an error in the Fluentd log and remove this field from payload. This
|
1313
|
+
# is the preferred behavior per PM decision.
|
1314
|
+
verify_subfields_untouched_when_not_hash(DEFAULT_SOURCE_LOCATION_KEY)
|
1287
1315
|
end
|
1288
1316
|
|
1289
1317
|
# Verify the subfields extraction of LogEntry fields when they are nil.
|
@@ -1292,14 +1320,18 @@ module BaseTest
|
|
1292
1320
|
verify_subfields_when_nil(DEFAULT_HTTP_REQUEST_KEY)
|
1293
1321
|
end
|
1294
1322
|
|
1295
|
-
def
|
1296
|
-
verify_subfields_when_nil(
|
1323
|
+
def test_log_entry_labels_field_when_nil
|
1324
|
+
verify_subfields_when_nil(DEFAULT_LABELS_KEY)
|
1297
1325
|
end
|
1298
1326
|
|
1299
1327
|
def test_log_entry_operation_field_when_nil
|
1300
1328
|
verify_subfields_when_nil(DEFAULT_OPERATION_KEY)
|
1301
1329
|
end
|
1302
1330
|
|
1331
|
+
def test_log_entry_source_location_field_when_nil
|
1332
|
+
verify_subfields_when_nil(DEFAULT_SOURCE_LOCATION_KEY)
|
1333
|
+
end
|
1334
|
+
|
1303
1335
|
def test_http_request_from_record_with_referer_nil_or_absent
|
1304
1336
|
setup_gce_metadata_stubs
|
1305
1337
|
[
|
@@ -1360,30 +1392,54 @@ module BaseTest
|
|
1360
1392
|
# Verify the default and customization of LogEntry field extraction key.
|
1361
1393
|
|
1362
1394
|
def test_log_entry_insert_id_field
|
1363
|
-
verify_field_key('insertId',
|
1364
|
-
|
1395
|
+
verify_field_key('insertId',
|
1396
|
+
default_key: DEFAULT_INSERT_ID_KEY,
|
1397
|
+
custom_key: 'custom_insert_id_key',
|
1398
|
+
custom_key_config: CONFIG_CUSTOM_INSERT_ID_KEY_SPECIFIED,
|
1399
|
+
sample_value: INSERT_ID)
|
1400
|
+
end
|
1401
|
+
|
1402
|
+
def test_log_entry_labels_field
|
1403
|
+
verify_field_key('labels',
|
1404
|
+
default_key: DEFAULT_LABELS_KEY,
|
1405
|
+
custom_key: 'custom_labels_key',
|
1406
|
+
custom_key_config: CONFIG_CUSTOM_LABELS_KEY_SPECIFIED,
|
1407
|
+
sample_value: COMPUTE_PARAMS[:labels].merge(
|
1408
|
+
LABELS_MESSAGE),
|
1409
|
+
default_value: COMPUTE_PARAMS[:labels])
|
1365
1410
|
end
|
1366
1411
|
|
1367
1412
|
def test_log_entry_operation_field
|
1368
|
-
verify_field_key('operation',
|
1369
|
-
|
1413
|
+
verify_field_key('operation',
|
1414
|
+
default_key: DEFAULT_OPERATION_KEY,
|
1415
|
+
custom_key: 'custom_operation_key',
|
1416
|
+
custom_key_config: CONFIG_CUSTOM_OPERATION_KEY_SPECIFIED,
|
1417
|
+
sample_value: OPERATION_MESSAGE)
|
1370
1418
|
end
|
1371
1419
|
|
1372
1420
|
def test_log_entry_source_location_field
|
1373
|
-
verify_field_key('sourceLocation',
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1421
|
+
verify_field_key('sourceLocation',
|
1422
|
+
default_key: DEFAULT_SOURCE_LOCATION_KEY,
|
1423
|
+
custom_key: 'custom_source_location_key',
|
1424
|
+
custom_key_config: \
|
1425
|
+
CONFIG_CUSTOM_SOURCE_LOCATION_KEY_SPECIFIED,
|
1426
|
+
sample_value: source_location_message)
|
1377
1427
|
end
|
1378
1428
|
|
1379
1429
|
def test_log_entry_span_id_field
|
1380
|
-
verify_field_key('spanId',
|
1381
|
-
|
1430
|
+
verify_field_key('spanId',
|
1431
|
+
default_key: DEFAULT_SPAN_ID_KEY,
|
1432
|
+
custom_key: 'custom_span_id_key',
|
1433
|
+
custom_key_config: CONFIG_CUSTOM_SPAN_ID_KEY_SPECIFIED,
|
1434
|
+
sample_value: SPAN_ID)
|
1382
1435
|
end
|
1383
1436
|
|
1384
1437
|
def test_log_entry_trace_field
|
1385
|
-
verify_field_key('trace',
|
1386
|
-
|
1438
|
+
verify_field_key('trace',
|
1439
|
+
default_key: DEFAULT_TRACE_KEY,
|
1440
|
+
custom_key: 'custom_trace_key',
|
1441
|
+
custom_key_config: CONFIG_CUSTOM_TRACE_KEY_SPECIFIED,
|
1442
|
+
sample_value: TRACE)
|
1387
1443
|
end
|
1388
1444
|
|
1389
1445
|
# Verify the cascading JSON detection of LogEntry fields.
|
@@ -1395,6 +1451,16 @@ module BaseTest
|
|
1395
1451
|
nested_level_value: INSERT_ID2)
|
1396
1452
|
end
|
1397
1453
|
|
1454
|
+
def test_cascading_json_detection_with_log_entry_labels_field
|
1455
|
+
verify_cascading_json_detection_with_log_entry_fields(
|
1456
|
+
'labels', DEFAULT_LABELS_KEY,
|
1457
|
+
root_level_value: LABELS_MESSAGE,
|
1458
|
+
nested_level_value: LABELS_MESSAGE2,
|
1459
|
+
expected_value_from_root: COMPUTE_PARAMS[:labels].merge(LABELS_MESSAGE),
|
1460
|
+
expected_value_from_nested: COMPUTE_PARAMS[:labels].merge(
|
1461
|
+
LABELS_MESSAGE2))
|
1462
|
+
end
|
1463
|
+
|
1398
1464
|
def test_cascading_json_detection_with_log_entry_operation_field
|
1399
1465
|
verify_cascading_json_detection_with_log_entry_fields(
|
1400
1466
|
'operation', DEFAULT_OPERATION_KEY,
|
@@ -1424,6 +1490,82 @@ module BaseTest
|
|
1424
1490
|
nested_level_value: TRACE2)
|
1425
1491
|
end
|
1426
1492
|
|
1493
|
+
# Verify that labels present in multiple inputs respect the expected priority
|
1494
|
+
# order:
|
1495
|
+
# 1. Labels from the field "logging.googleapis.com/labels" in payload.
|
1496
|
+
# 2. Labels from the config "label_map".
|
1497
|
+
# 3. Labels from the config "labels".
|
1498
|
+
def test_labels_order
|
1499
|
+
[
|
1500
|
+
# Labels from the config "labels".
|
1501
|
+
{
|
1502
|
+
config: CONFIG_LABELS,
|
1503
|
+
emitted_log: {},
|
1504
|
+
expected_labels: LABELS_FROM_LABELS_CONFIG
|
1505
|
+
},
|
1506
|
+
# Labels from the config "label_map".
|
1507
|
+
{
|
1508
|
+
config: CONFIG_LABEL_MAP,
|
1509
|
+
emitted_log: PAYLOAD_FOR_LABEL_MAP,
|
1510
|
+
expected_labels: LABELS_FROM_LABEL_MAP_CONFIG
|
1511
|
+
},
|
1512
|
+
# Labels from the field "logging.googleapis.com/labels" in payload.
|
1513
|
+
{
|
1514
|
+
config: APPLICATION_DEFAULT_CONFIG,
|
1515
|
+
emitted_log: { DEFAULT_LABELS_KEY => LABELS_MESSAGE },
|
1516
|
+
expected_labels: LABELS_MESSAGE
|
1517
|
+
},
|
1518
|
+
# All three types of labels that do not conflict.
|
1519
|
+
{
|
1520
|
+
config: CONFIG_LABLES_AND_LABLE_MAP,
|
1521
|
+
emitted_log: PAYLOAD_FOR_LABEL_MAP.merge(
|
1522
|
+
DEFAULT_LABELS_KEY => LABELS_MESSAGE),
|
1523
|
+
expected_labels: LABELS_MESSAGE.merge(LABELS_FROM_LABELS_CONFIG).merge(
|
1524
|
+
LABELS_FROM_LABEL_MAP_CONFIG)
|
1525
|
+
},
|
1526
|
+
# labels from the config "labels" and "label_map" conflict.
|
1527
|
+
{
|
1528
|
+
config: CONFIG_LABLES_AND_LABLE_MAP_CONFLICTING,
|
1529
|
+
emitted_log: PAYLOAD_FOR_LABEL_MAP_CONFLICTING,
|
1530
|
+
expected_labels: LABELS_FROM_LABEL_MAP_CONFIG_CONFLICTING
|
1531
|
+
},
|
1532
|
+
# labels from the config "labels" and labels from the field
|
1533
|
+
# "logging.googleapis.com/labels" in payload conflict.
|
1534
|
+
{
|
1535
|
+
config: CONFIG_LABELS_CONFLICTING,
|
1536
|
+
emitted_log: { DEFAULT_LABELS_KEY => LABELS_FROM_PAYLOAD_CONFLICTING },
|
1537
|
+
expected_labels: LABELS_FROM_PAYLOAD_CONFLICTING
|
1538
|
+
},
|
1539
|
+
# labels from the config "label_map" and labels from the field
|
1540
|
+
# "logging.googleapis.com/labels" in payload conflict.
|
1541
|
+
{
|
1542
|
+
config: CONFIG_LABEL_MAP_CONFLICTING,
|
1543
|
+
emitted_log: PAYLOAD_FOR_LABEL_MAP_CONFLICTING.merge(
|
1544
|
+
DEFAULT_LABELS_KEY => LABELS_FROM_PAYLOAD_CONFLICTING),
|
1545
|
+
expected_labels: LABELS_FROM_PAYLOAD_CONFLICTING
|
1546
|
+
},
|
1547
|
+
# All three types of labels conflict.
|
1548
|
+
{
|
1549
|
+
config: CONFIG_LABLES_AND_LABLE_MAP_CONFLICTING,
|
1550
|
+
emitted_log: PAYLOAD_FOR_LABEL_MAP_CONFLICTING.merge(
|
1551
|
+
DEFAULT_LABELS_KEY => LABELS_FROM_PAYLOAD_CONFLICTING),
|
1552
|
+
expected_labels: LABELS_FROM_PAYLOAD_CONFLICTING
|
1553
|
+
}
|
1554
|
+
].each do |test_params|
|
1555
|
+
new_stub_context do
|
1556
|
+
setup_gce_metadata_stubs
|
1557
|
+
setup_logging_stubs do
|
1558
|
+
d = create_driver(test_params[:config])
|
1559
|
+
d.emit({ 'message' => log_entry(0) }.merge(test_params[:emitted_log]))
|
1560
|
+
d.run
|
1561
|
+
end
|
1562
|
+
expected_params = COMPUTE_PARAMS.merge(
|
1563
|
+
labels: COMPUTE_PARAMS[:labels].merge(test_params[:expected_labels]))
|
1564
|
+
verify_log_entries(1, expected_params)
|
1565
|
+
end
|
1566
|
+
end
|
1567
|
+
end
|
1568
|
+
|
1427
1569
|
# Metadata Agent related tests.
|
1428
1570
|
|
1429
1571
|
# Test enable_metadata_agent not set or set to false.
|
@@ -1648,6 +1790,66 @@ module BaseTest
|
|
1648
1790
|
end
|
1649
1791
|
end
|
1650
1792
|
|
1793
|
+
# Test k8s_pod monitored resource including the fallback when Metadata Agent
|
1794
|
+
# restarts.
|
1795
|
+
def test_k8s_pod_monitored_resource_fallback
|
1796
|
+
[
|
1797
|
+
{
|
1798
|
+
config: APPLICATION_DEFAULT_CONFIG,
|
1799
|
+
setup_metadata_agent_stub: true,
|
1800
|
+
setup_k8s_stub: true,
|
1801
|
+
log_entry: k8s_pod_log_entry(log_entry(0)),
|
1802
|
+
expected_params: K8S_POD_PARAMS_FROM_LOCAL
|
1803
|
+
},
|
1804
|
+
{
|
1805
|
+
config: ENABLE_METADATA_AGENT_CONFIG,
|
1806
|
+
setup_metadata_agent_stub: false,
|
1807
|
+
setup_k8s_stub: true,
|
1808
|
+
log_entry: k8s_pod_log_entry(log_entry(0)),
|
1809
|
+
expected_params: K8S_POD_PARAMS_FROM_LOCAL
|
1810
|
+
},
|
1811
|
+
{
|
1812
|
+
config: CUSTOM_K8S_ENABLE_METADATA_AGENT_CONFIG,
|
1813
|
+
setup_metadata_agent_stub: false,
|
1814
|
+
setup_k8s_stub: false,
|
1815
|
+
log_entry: k8s_pod_log_entry(log_entry(0)),
|
1816
|
+
expected_params: K8S_POD_PARAMS_CUSTOM
|
1817
|
+
},
|
1818
|
+
{
|
1819
|
+
config: EMPTY_K8S_ENABLE_METADATA_AGENT_CONFIG,
|
1820
|
+
setup_metadata_agent_stub: true,
|
1821
|
+
setup_k8s_stub: true,
|
1822
|
+
log_entry: k8s_pod_log_entry(log_entry(0)),
|
1823
|
+
expected_params: K8S_POD_PARAMS
|
1824
|
+
},
|
1825
|
+
{
|
1826
|
+
config: ENABLE_METADATA_AGENT_CONFIG,
|
1827
|
+
setup_metadata_agent_stub: true,
|
1828
|
+
setup_k8s_stub: true,
|
1829
|
+
log_entry: k8s_pod_log_entry(log_entry(0)),
|
1830
|
+
expected_params: K8S_POD_PARAMS
|
1831
|
+
}
|
1832
|
+
].each do |test_params|
|
1833
|
+
new_stub_context do
|
1834
|
+
setup_gce_metadata_stubs
|
1835
|
+
setup_metadata_agent_stubs(test_params[:setup_metadata_agent_stub])
|
1836
|
+
setup_k8s_metadata_stubs(test_params[:setup_k8s_stub])
|
1837
|
+
setup_logging_stubs do
|
1838
|
+
d = create_driver(test_params[:config])
|
1839
|
+
d.emit(test_params[:log_entry])
|
1840
|
+
d.run
|
1841
|
+
end
|
1842
|
+
verify_log_entries(1, test_params[:expected_params],
|
1843
|
+
'jsonPayload') do |entry|
|
1844
|
+
fields = get_fields(entry['jsonPayload'])
|
1845
|
+
assert_equal 2, fields.size, entry
|
1846
|
+
assert_equal 'test log entry 0', get_string(fields['log']), entry
|
1847
|
+
assert_equal K8S_STREAM, get_string(fields['stream']), entry
|
1848
|
+
end
|
1849
|
+
end
|
1850
|
+
end
|
1851
|
+
end
|
1852
|
+
|
1651
1853
|
# Test k8s_node monitored resource including the fallback when Metadata Agent
|
1652
1854
|
# restarts.
|
1653
1855
|
def test_k8s_node_monitored_resource_fallback
|
@@ -2023,6 +2225,18 @@ module BaseTest
|
|
2023
2225
|
}
|
2024
2226
|
end
|
2025
2227
|
|
2228
|
+
def k8s_pod_log_entry(log)
|
2229
|
+
{
|
2230
|
+
log: log,
|
2231
|
+
stream: K8S_STREAM,
|
2232
|
+
time: K8S_TIMESTAMP,
|
2233
|
+
LOCAL_RESOURCE_ID_KEY =>
|
2234
|
+
"#{K8S_POD_LOCAL_RESOURCE_ID_PREFIX}" \
|
2235
|
+
".#{K8S_NAMESPACE_NAME}" \
|
2236
|
+
".#{K8S_POD_NAME}"
|
2237
|
+
}
|
2238
|
+
end
|
2239
|
+
|
2026
2240
|
def k8s_node_log_entry(log)
|
2027
2241
|
{
|
2028
2242
|
log: log,
|
@@ -2082,18 +2296,25 @@ module BaseTest
|
|
2082
2296
|
"test log entry #{i}"
|
2083
2297
|
end
|
2084
2298
|
|
2085
|
-
|
2086
|
-
|
2087
|
-
|
2088
|
-
|
2089
|
-
|
2090
|
-
|
2091
|
-
|
2092
|
-
|
2299
|
+
# If check_exact_labels is true, assert 'labels' and 'expected_labels' match
|
2300
|
+
# exactly. If check_exact_labels is false, assert 'labels' is a subset of
|
2301
|
+
# 'expected_labels'.
|
2302
|
+
def check_labels(expected_labels, labels, check_exact_labels = true)
|
2303
|
+
return if expected_labels.empty? && labels.empty?
|
2304
|
+
expected_labels.each do |expected_key, expected_value|
|
2305
|
+
assert labels.key?(expected_key), "Expected label #{expected_key} not" \
|
2306
|
+
" found. Got labels: #{labels}."
|
2307
|
+
actual_value = labels[expected_key]
|
2308
|
+
assert actual_value.is_a?(String), 'Value for label' \
|
2309
|
+
" #{expected_key} is not a string: #{actual_value}."
|
2310
|
+
assert_equal expected_value, actual_value, "Value for #{expected_key}" \
|
2311
|
+
" mismatch. Expected #{expected_value}. Got #{actual_value}"
|
2312
|
+
end
|
2313
|
+
if check_exact_labels
|
2314
|
+
assert_equal expected_labels.length, labels.length, 'Expected ' \
|
2315
|
+
"#{expected_labels.length} labels: #{expected_labels}, got " \
|
2316
|
+
"#{labels.length} labels: #{labels}"
|
2093
2317
|
end
|
2094
|
-
assert_equal expected_labels.length, labels.length, 'Expected ' \
|
2095
|
-
"#{expected_labels.length} labels: #{expected_labels}, got " \
|
2096
|
-
"#{labels.length} labels: #{labels}"
|
2097
2318
|
end
|
2098
2319
|
|
2099
2320
|
def verify_default_log_entry_text(text, i, entry)
|
@@ -2102,7 +2323,8 @@ module BaseTest
|
|
2102
2323
|
end
|
2103
2324
|
|
2104
2325
|
# The caller can optionally provide a block which is called for each entry.
|
2105
|
-
def verify_json_log_entries(n, params, payload_type = 'textPayload'
|
2326
|
+
def verify_json_log_entries(n, params, payload_type = 'textPayload',
|
2327
|
+
check_exact_entry_labels = true)
|
2106
2328
|
entry_count = 0
|
2107
2329
|
@logs_sent.each do |request|
|
2108
2330
|
request['entries'].each do |entry|
|
@@ -2127,8 +2349,10 @@ module BaseTest
|
|
2127
2349
|
log_name
|
2128
2350
|
end
|
2129
2351
|
assert_equal params[:resource][:type], resource['type']
|
2130
|
-
check_labels resource[
|
2131
|
-
|
2352
|
+
check_labels params[:resource][:labels], resource['labels']
|
2353
|
+
|
2354
|
+
check_labels params[:labels], labels, check_exact_entry_labels
|
2355
|
+
|
2132
2356
|
if block_given?
|
2133
2357
|
yield(entry, entry_count)
|
2134
2358
|
elsif payload_type == 'textPayload'
|
@@ -2170,14 +2394,16 @@ module BaseTest
|
|
2170
2394
|
# the subfield in LogEntry object and the expected value of that field.
|
2171
2395
|
DEFAULT_HTTP_REQUEST_KEY => [
|
2172
2396
|
'httpRequest', http_request_message],
|
2173
|
-
|
2174
|
-
'
|
2397
|
+
DEFAULT_LABELS_KEY => [
|
2398
|
+
'labels', COMPUTE_PARAMS[:labels].merge(LABELS_MESSAGE)],
|
2175
2399
|
DEFAULT_OPERATION_KEY => [
|
2176
|
-
'operation', OPERATION_MESSAGE]
|
2400
|
+
'operation', OPERATION_MESSAGE],
|
2401
|
+
DEFAULT_SOURCE_LOCATION_KEY => [
|
2402
|
+
'sourceLocation', source_location_message]
|
2177
2403
|
}
|
2178
2404
|
end
|
2179
2405
|
|
2180
|
-
def verify_subfields_from_record(payload_key)
|
2406
|
+
def verify_subfields_from_record(payload_key, check_exact_entry_labels = true)
|
2181
2407
|
destination_key, payload_value = log_entry_subfields_params[payload_key]
|
2182
2408
|
@logs_sent = []
|
2183
2409
|
setup_gce_metadata_stubs
|
@@ -2186,7 +2412,8 @@ module BaseTest
|
|
2186
2412
|
d.emit(payload_key => payload_value)
|
2187
2413
|
d.run
|
2188
2414
|
end
|
2189
|
-
verify_log_entries(1, COMPUTE_PARAMS, destination_key
|
2415
|
+
verify_log_entries(1, COMPUTE_PARAMS, destination_key,
|
2416
|
+
check_exact_entry_labels) do |entry|
|
2190
2417
|
assert_equal payload_value, entry[destination_key], entry
|
2191
2418
|
fields = get_fields(entry['jsonPayload'])
|
2192
2419
|
assert_nil fields[payload_key], entry
|
@@ -2210,7 +2437,7 @@ module BaseTest
|
|
2210
2437
|
end
|
2211
2438
|
end
|
2212
2439
|
|
2213
|
-
def
|
2440
|
+
def verify_subfields_removed_when_not_hash(payload_key)
|
2214
2441
|
destination_key = log_entry_subfields_params[payload_key][0]
|
2215
2442
|
@logs_sent = []
|
2216
2443
|
setup_gce_metadata_stubs
|
@@ -2220,6 +2447,25 @@ module BaseTest
|
|
2220
2447
|
d.run
|
2221
2448
|
end
|
2222
2449
|
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry|
|
2450
|
+
# The malformed field has been removed from the payload.
|
2451
|
+
assert_true get_fields(entry['jsonPayload']).empty?, entry
|
2452
|
+
# No additional labels.
|
2453
|
+
assert_equal COMPUTE_PARAMS[:labels].size,
|
2454
|
+
entry[destination_key].size, entry
|
2455
|
+
end
|
2456
|
+
end
|
2457
|
+
|
2458
|
+
def verify_subfields_untouched_when_not_hash(payload_key)
|
2459
|
+
destination_key = log_entry_subfields_params[payload_key][0]
|
2460
|
+
@logs_sent = []
|
2461
|
+
setup_gce_metadata_stubs
|
2462
|
+
setup_logging_stubs do
|
2463
|
+
d = create_driver
|
2464
|
+
d.emit(payload_key => 'a_string')
|
2465
|
+
d.run
|
2466
|
+
end
|
2467
|
+
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry|
|
2468
|
+
# Verify that we leave the malformed field as it is.
|
2223
2469
|
field = get_fields(entry['jsonPayload'])[payload_key]
|
2224
2470
|
assert_equal 'a_string', get_string(field), entry
|
2225
2471
|
assert_false entry.key?(destination_key), entry
|
@@ -2239,7 +2485,13 @@ module BaseTest
|
|
2239
2485
|
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry|
|
2240
2486
|
fields = get_fields(entry['jsonPayload'])
|
2241
2487
|
assert_false fields.key?(payload_key), entry
|
2242
|
-
|
2488
|
+
if payload_key == DEFAULT_LABELS_KEY
|
2489
|
+
# No additional labels.
|
2490
|
+
assert_equal COMPUTE_PARAMS[:labels].size,
|
2491
|
+
entry[destination_key].size, entry
|
2492
|
+
else
|
2493
|
+
assert_false entry.key?(destination_key), entry
|
2494
|
+
end
|
2243
2495
|
end
|
2244
2496
|
end
|
2245
2497
|
|
@@ -2302,7 +2554,7 @@ module BaseTest
|
|
2302
2554
|
d.emit(input_log_entry)
|
2303
2555
|
d.run
|
2304
2556
|
end
|
2305
|
-
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry|
|
2557
|
+
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload', false) do |entry|
|
2306
2558
|
assert_equal expected_value, entry[log_entry_field],
|
2307
2559
|
"Index #{index} failed. #{expected_value} is expected" \
|
2308
2560
|
" for #{log_entry_field} field."
|
@@ -2315,8 +2567,13 @@ module BaseTest
|
|
2315
2567
|
end
|
2316
2568
|
end
|
2317
2569
|
|
2318
|
-
def verify_field_key(log_entry_field,
|
2319
|
-
|
2570
|
+
def verify_field_key(log_entry_field, test_params)
|
2571
|
+
default_key = test_params[:default_key]
|
2572
|
+
custom_key = test_params[:custom_key]
|
2573
|
+
custom_key_config = test_params[:custom_key_config]
|
2574
|
+
sample_value = test_params[:sample_value]
|
2575
|
+
default_value = test_params.fetch(:default_value, nil)
|
2576
|
+
|
2320
2577
|
setup_gce_metadata_stubs
|
2321
2578
|
message = log_entry(0)
|
2322
2579
|
[
|
@@ -2325,7 +2582,7 @@ module BaseTest
|
|
2325
2582
|
driver_config: APPLICATION_DEFAULT_CONFIG,
|
2326
2583
|
emitted_log: { 'msg' => message },
|
2327
2584
|
expected_payload: { 'msg' => message },
|
2328
|
-
expected_field_value:
|
2585
|
+
expected_field_value: default_value
|
2329
2586
|
},
|
2330
2587
|
{
|
2331
2588
|
# By default, it sets log entry field via a default key.
|
@@ -2346,7 +2603,7 @@ module BaseTest
|
|
2346
2603
|
driver_config: custom_key_config,
|
2347
2604
|
emitted_log: { 'msg' => message, default_key => sample_value },
|
2348
2605
|
expected_payload: { 'msg' => message, default_key => sample_value },
|
2349
|
-
expected_field_value:
|
2606
|
+
expected_field_value: default_value
|
2350
2607
|
}
|
2351
2608
|
].each do |input|
|
2352
2609
|
setup_logging_stubs do
|
@@ -2355,7 +2612,7 @@ module BaseTest
|
|
2355
2612
|
d.emit(input[:emitted_log])
|
2356
2613
|
d.run
|
2357
2614
|
end
|
2358
|
-
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry|
|
2615
|
+
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload', false) do |entry|
|
2359
2616
|
assert_equal input[:expected_field_value], entry[log_entry_field], input
|
2360
2617
|
payload_fields = get_fields(entry['jsonPayload'])
|
2361
2618
|
assert_equal input[:expected_payload].size, payload_fields.size, input
|
@@ -2413,7 +2670,8 @@ module BaseTest
|
|
2413
2670
|
|
2414
2671
|
# Verify the number and the content of the log entries match the expectation.
|
2415
2672
|
# The caller can optionally provide a block which is called for each entry.
|
2416
|
-
def verify_log_entries(_n, _params, _payload_type = 'textPayload',
|
2673
|
+
def verify_log_entries(_n, _params, _payload_type = 'textPayload',
|
2674
|
+
_check_exact_entry_labels = true, &_block)
|
2417
2675
|
_undefined
|
2418
2676
|
end
|
2419
2677
|
|
data/test/plugin/constants.rb
CHANGED
@@ -156,6 +156,7 @@ module Constants
|
|
156
156
|
K8S_SECONDS_EPOCH = 1_234_567_890
|
157
157
|
K8S_NANOS = 987_654_321
|
158
158
|
K8S_CONTAINER_LOCAL_RESOURCE_ID_PREFIX = 'k8s_container'.freeze
|
159
|
+
K8S_POD_LOCAL_RESOURCE_ID_PREFIX = 'k8s_pod'.freeze
|
159
160
|
K8S_NODE_LOCAL_RESOURCE_ID_PREFIX = 'k8s_node'.freeze
|
160
161
|
K8S_TAG =
|
161
162
|
"var.log.containers.#{K8S_NAMESPACE_NAME}_#{K8S_POD_NAME}_" \
|
@@ -375,6 +376,10 @@ module Constants
|
|
375
376
|
insert_id_key custom_insert_id_key
|
376
377
|
).freeze
|
377
378
|
|
379
|
+
CONFIG_CUSTOM_LABELS_KEY_SPECIFIED = %(
|
380
|
+
labels_key custom_labels_key
|
381
|
+
).freeze
|
382
|
+
|
378
383
|
CONFIG_CUSTOM_OPERATION_KEY_SPECIFIED = %(
|
379
384
|
operation_key custom_operation_key
|
380
385
|
).freeze
|
@@ -391,6 +396,69 @@ module Constants
|
|
391
396
|
trace_key custom_trace_key
|
392
397
|
).freeze
|
393
398
|
|
399
|
+
# For 'labels' config.
|
400
|
+
LABELS_FROM_LABELS_CONFIG = {
|
401
|
+
'a_label_from_labels_config' => 'some_value',
|
402
|
+
'another_label_from_labels_config' => 'some_value'
|
403
|
+
}.freeze
|
404
|
+
CONFIG_LABELS = %(
|
405
|
+
labels #{LABELS_FROM_LABELS_CONFIG.to_json}
|
406
|
+
).freeze
|
407
|
+
|
408
|
+
# For 'label_map' config.
|
409
|
+
LABEL_MAP_HASH = {
|
410
|
+
'target_field_from_payload' => 'a_label_from_label_map_config',
|
411
|
+
'another_target_field_from_payload' => 'another_label_from_label_map_config'
|
412
|
+
}.freeze
|
413
|
+
PAYLOAD_FOR_LABEL_MAP = {
|
414
|
+
'target_field_from_payload' => 'a_value',
|
415
|
+
'another_target_field_from_payload' => 'b_value'
|
416
|
+
}.freeze
|
417
|
+
LABELS_FROM_LABEL_MAP_CONFIG = {
|
418
|
+
'a_label_from_label_map_config' => 'a_value',
|
419
|
+
'another_label_from_label_map_config' => 'b_value'
|
420
|
+
}.freeze
|
421
|
+
CONFIG_LABEL_MAP = %(
|
422
|
+
label_map #{LABEL_MAP_HASH.to_json}
|
423
|
+
).freeze
|
424
|
+
|
425
|
+
CONFIG_LABLES_AND_LABLE_MAP = %(
|
426
|
+
#{CONFIG_LABELS}
|
427
|
+
#{CONFIG_LABEL_MAP}
|
428
|
+
).freeze
|
429
|
+
|
430
|
+
# For conflicting labels.
|
431
|
+
CONFLICTING_LABEL_NAME = 'conflicting_label_key'.freeze
|
432
|
+
CONFLICTING_LABEL_VALUE1 = 'conflicting_value_1'.freeze
|
433
|
+
CONFLICTING_LABEL_VALUE2 = 'conflicting_value_2'.freeze
|
434
|
+
CONFLICTING_LABEL_VALUE3 = 'conflicting_value_3'.freeze
|
435
|
+
LABELS_FROM_PAYLOAD_CONFLICTING = {
|
436
|
+
CONFLICTING_LABEL_NAME => CONFLICTING_LABEL_VALUE1
|
437
|
+
}.freeze
|
438
|
+
LABELS_FROM_LABEL_MAP_CONFIG_CONFLICTING = {
|
439
|
+
CONFLICTING_LABEL_NAME => CONFLICTING_LABEL_VALUE2
|
440
|
+
}.freeze
|
441
|
+
LABELS_FROM_LABELS_CONFIG_CONFLICTING = {
|
442
|
+
CONFLICTING_LABEL_NAME => CONFLICTING_LABEL_VALUE3
|
443
|
+
}.freeze
|
444
|
+
|
445
|
+
LABEL_MAP_HASH_CONFLICTING = {
|
446
|
+
'target_field_from_payload' => CONFLICTING_LABEL_NAME
|
447
|
+
}.freeze
|
448
|
+
PAYLOAD_FOR_LABEL_MAP_CONFLICTING = {
|
449
|
+
'target_field_from_payload' => CONFLICTING_LABEL_VALUE2
|
450
|
+
}.freeze
|
451
|
+
CONFIG_LABEL_MAP_CONFLICTING = %(
|
452
|
+
label_map #{LABEL_MAP_HASH_CONFLICTING.to_json}
|
453
|
+
).freeze
|
454
|
+
CONFIG_LABELS_CONFLICTING = %(
|
455
|
+
labels #{LABELS_FROM_LABELS_CONFIG_CONFLICTING.to_json}
|
456
|
+
).freeze
|
457
|
+
CONFIG_LABLES_AND_LABLE_MAP_CONFLICTING = %(
|
458
|
+
#{CONFIG_LABELS_CONFLICTING}
|
459
|
+
#{CONFIG_LABEL_MAP_CONFLICTING}
|
460
|
+
).freeze
|
461
|
+
|
394
462
|
# Service configurations for various services.
|
395
463
|
|
396
464
|
# GCE.
|
@@ -543,6 +611,36 @@ module Constants
|
|
543
611
|
log_name: CONTAINER_TAG
|
544
612
|
).freeze
|
545
613
|
|
614
|
+
# K8s Pod.
|
615
|
+
K8S_POD_PARAMS = {
|
616
|
+
resource: {
|
617
|
+
type: K8S_POD_CONSTANTS[:resource_type],
|
618
|
+
labels: {
|
619
|
+
'namespace_name' => K8S_NAMESPACE_NAME,
|
620
|
+
'pod_name' => K8S_POD_NAME,
|
621
|
+
'cluster_name' => K8S_CLUSTER_NAME,
|
622
|
+
'location' => K8S_LOCATION
|
623
|
+
}
|
624
|
+
},
|
625
|
+
project_id: PROJECT_ID,
|
626
|
+
labels: {}
|
627
|
+
}.freeze
|
628
|
+
K8S_POD_PARAMS_FROM_LOCAL = K8S_POD_PARAMS.merge(
|
629
|
+
resource: K8S_POD_PARAMS[:resource].merge(
|
630
|
+
labels: K8S_POD_PARAMS[:resource][:labels].merge(
|
631
|
+
'location' => K8S_LOCATION2
|
632
|
+
)
|
633
|
+
)
|
634
|
+
).freeze
|
635
|
+
K8S_POD_PARAMS_CUSTOM = K8S_POD_PARAMS.merge(
|
636
|
+
resource: K8S_POD_PARAMS[:resource].merge(
|
637
|
+
labels: K8S_POD_PARAMS[:resource][:labels].merge(
|
638
|
+
'cluster_name' => CUSTOM_K8S_CLUSTER_NAME,
|
639
|
+
'location' => CUSTOM_K8S_LOCATION
|
640
|
+
)
|
641
|
+
)
|
642
|
+
).freeze
|
643
|
+
|
546
644
|
# K8s Node.
|
547
645
|
K8S_NODE_PARAMS = {
|
548
646
|
resource: {
|
@@ -781,6 +879,18 @@ module Constants
|
|
781
879
|
'last' => false
|
782
880
|
}.freeze
|
783
881
|
|
882
|
+
LABELS_MESSAGE = {
|
883
|
+
'component' => 'front-end',
|
884
|
+
'source' => 'user',
|
885
|
+
'app' => 'request-router'
|
886
|
+
}.freeze
|
887
|
+
|
888
|
+
LABELS_MESSAGE2 = {
|
889
|
+
'component' => 'front-end',
|
890
|
+
'source' => 'system',
|
891
|
+
'app' => 'request-router'
|
892
|
+
}.freeze
|
893
|
+
|
784
894
|
CUSTOM_LABELS_MESSAGE = {
|
785
895
|
'customKey' => 'value'
|
786
896
|
}.freeze
|
@@ -858,6 +968,18 @@ module Constants
|
|
858
968
|
'location' => K8S_LOCATION
|
859
969
|
}
|
860
970
|
}.to_json,
|
971
|
+
# K8s pod logs.
|
972
|
+
"#{K8S_POD_LOCAL_RESOURCE_ID_PREFIX}.#{K8S_NAMESPACE_NAME}" \
|
973
|
+
".#{K8S_POD_NAME}" =>
|
974
|
+
{
|
975
|
+
'type' => K8S_POD_CONSTANTS[:resource_type],
|
976
|
+
'labels' => {
|
977
|
+
'namespace_name' => K8S_NAMESPACE_NAME,
|
978
|
+
'pod_name' => K8S_POD_NAME,
|
979
|
+
'cluster_name' => K8S_CLUSTER_NAME,
|
980
|
+
'location' => K8S_LOCATION
|
981
|
+
}
|
982
|
+
}.to_json,
|
861
983
|
# K8s node logs.
|
862
984
|
"#{K8S_NODE_LOCAL_RESOURCE_ID_PREFIX}.#{K8S_NODE_NAME}" =>
|
863
985
|
{
|
@@ -980,6 +1102,7 @@ module Constants
|
|
980
1102
|
'severity' => CONTAINER_SEVERITY,
|
981
1103
|
DEFAULT_HTTP_REQUEST_KEY => HTTP_REQUEST_MESSAGE,
|
982
1104
|
DEFAULT_INSERT_ID_KEY => INSERT_ID,
|
1105
|
+
DEFAULT_LABELS_KEY => LABELS_MESSAGE,
|
983
1106
|
DEFAULT_OPERATION_KEY => OPERATION_MESSAGE,
|
984
1107
|
DEFAULT_SOURCE_LOCATION_KEY => SOURCE_LOCATION_MESSAGE,
|
985
1108
|
DEFAULT_SPAN_ID_KEY => SPAN_ID,
|
@@ -364,8 +364,10 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
|
|
364
364
|
|
365
365
|
# Verify the number and the content of the log entries match the expectation.
|
366
366
|
# The caller can optionally provide a block which is called for each entry.
|
367
|
-
def verify_log_entries(n, params, payload_type = 'textPayload',
|
368
|
-
|
367
|
+
def verify_log_entries(n, params, payload_type = 'textPayload',
|
368
|
+
check_exact_entry_labels = true, &block)
|
369
|
+
verify_json_log_entries(n, params, payload_type, check_exact_entry_labels,
|
370
|
+
&block)
|
369
371
|
end
|
370
372
|
|
371
373
|
# For an optional field with default values, Protobuf omits the field when it
|
@@ -413,7 +413,8 @@ class GoogleCloudOutputGRPCTest < Test::Unit::TestCase
|
|
413
413
|
|
414
414
|
# Verify the number and the content of the log entries match the expectation.
|
415
415
|
# The caller can optionally provide a block which is called for each entry.
|
416
|
-
def verify_log_entries(n, params, payload_type = 'textPayload',
|
416
|
+
def verify_log_entries(n, params, payload_type = 'textPayload',
|
417
|
+
check_exact_entry_labels = true, &block)
|
417
418
|
@requests_sent.each do |request|
|
418
419
|
@logs_sent << {
|
419
420
|
'entries' => request.entries.map { |entry| JSON.parse(entry.to_json) },
|
@@ -422,7 +423,8 @@ class GoogleCloudOutputGRPCTest < Test::Unit::TestCase
|
|
422
423
|
'logName' => request.log_name
|
423
424
|
}
|
424
425
|
end
|
425
|
-
verify_json_log_entries(n, params, payload_type,
|
426
|
+
verify_json_log_entries(n, params, payload_type, check_exact_entry_labels,
|
427
|
+
&block)
|
426
428
|
end
|
427
429
|
|
428
430
|
# Use the right single quotation mark as the sample non-utf8 character.
|
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.
|
4
|
+
version: 0.7.5.pre.multiworkers
|
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: 2019-02-
|
11
|
+
date: 2019-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|
@@ -218,9 +218,7 @@ extensions: []
|
|
218
218
|
extra_rdoc_files: []
|
219
219
|
files:
|
220
220
|
- CONTRIBUTING
|
221
|
-
- CUSTOM_SPONGE_CONFIG
|
222
221
|
- Gemfile
|
223
|
-
- Gemfile.lock
|
224
222
|
- LICENSE
|
225
223
|
- README.rdoc
|
226
224
|
- Rakefile
|
@@ -255,12 +253,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
255
253
|
version: '2.2'
|
256
254
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
257
255
|
requirements:
|
258
|
-
- - "
|
256
|
+
- - ">"
|
259
257
|
- !ruby/object:Gem::Version
|
260
|
-
version:
|
258
|
+
version: 1.3.1
|
261
259
|
requirements: []
|
262
260
|
rubyforge_project:
|
263
|
-
rubygems_version: 2.
|
261
|
+
rubygems_version: 2.6.14
|
264
262
|
signing_key:
|
265
263
|
specification_version: 4
|
266
264
|
summary: fluentd plugins for the Stackdriver Logging API
|
data/CUSTOM_SPONGE_CONFIG
DELETED
File without changes
|
data/Gemfile.lock
DELETED
@@ -1,160 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
fluent-plugin-google-cloud (0.7.4)
|
5
|
-
fluentd (= 1.2.5)
|
6
|
-
google-api-client (= 0.23.9)
|
7
|
-
google-cloud-logging (= 1.5.4)
|
8
|
-
google-protobuf (= 3.6.1)
|
9
|
-
googleapis-common-protos (= 1.3.7)
|
10
|
-
googleauth (= 0.6.6)
|
11
|
-
grpc (= 1.8.3)
|
12
|
-
json (= 2.1.0)
|
13
|
-
|
14
|
-
GEM
|
15
|
-
remote: https://rubygems.org/
|
16
|
-
specs:
|
17
|
-
addressable (2.6.0)
|
18
|
-
public_suffix (>= 2.0.2, < 4.0)
|
19
|
-
ast (2.4.0)
|
20
|
-
cool.io (1.5.3)
|
21
|
-
crack (0.4.3)
|
22
|
-
safe_yaml (~> 1.0.0)
|
23
|
-
declarative (0.0.10)
|
24
|
-
declarative-option (0.1.0)
|
25
|
-
dig_rb (1.0.1)
|
26
|
-
faraday (0.15.4)
|
27
|
-
multipart-post (>= 1.2, < 3)
|
28
|
-
fluentd (1.2.5)
|
29
|
-
cool.io (>= 1.4.5, < 2.0.0)
|
30
|
-
dig_rb (~> 1.0.0)
|
31
|
-
http_parser.rb (>= 0.5.1, < 0.7.0)
|
32
|
-
msgpack (>= 0.7.0, < 2.0.0)
|
33
|
-
serverengine (>= 2.0.4, < 3.0.0)
|
34
|
-
sigdump (~> 0.2.2)
|
35
|
-
strptime (>= 0.2.2, < 1.0.0)
|
36
|
-
tzinfo (~> 1.0)
|
37
|
-
tzinfo-data (~> 1.0)
|
38
|
-
yajl-ruby (~> 1.0)
|
39
|
-
google-api-client (0.23.9)
|
40
|
-
addressable (~> 2.5, >= 2.5.1)
|
41
|
-
googleauth (>= 0.5, < 0.7.0)
|
42
|
-
httpclient (>= 2.8.1, < 3.0)
|
43
|
-
mime-types (~> 3.0)
|
44
|
-
representable (~> 3.0)
|
45
|
-
retriable (>= 2.0, < 4.0)
|
46
|
-
signet (~> 0.9)
|
47
|
-
google-cloud-core (1.3.0)
|
48
|
-
google-cloud-env (~> 1.0)
|
49
|
-
google-cloud-env (1.0.5)
|
50
|
-
faraday (~> 0.11)
|
51
|
-
google-cloud-logging (1.5.4)
|
52
|
-
google-cloud-core (~> 1.2)
|
53
|
-
google-gax (~> 1.3)
|
54
|
-
googleapis-common-protos-types (>= 1.0.2)
|
55
|
-
stackdriver-core (~> 1.3)
|
56
|
-
google-gax (1.5.0)
|
57
|
-
google-protobuf (~> 3.2)
|
58
|
-
googleapis-common-protos (>= 1.3.5, < 2.0)
|
59
|
-
googleauth (>= 0.6.2, < 0.10.0)
|
60
|
-
grpc (>= 1.7.2, < 2.0)
|
61
|
-
rly (~> 0.2.3)
|
62
|
-
google-protobuf (3.6.1)
|
63
|
-
googleapis-common-protos (1.3.7)
|
64
|
-
google-protobuf (~> 3.0)
|
65
|
-
googleapis-common-protos-types (~> 1.0)
|
66
|
-
grpc (~> 1.0)
|
67
|
-
googleapis-common-protos-types (1.0.2)
|
68
|
-
google-protobuf (~> 3.0)
|
69
|
-
googleauth (0.6.6)
|
70
|
-
faraday (~> 0.12)
|
71
|
-
jwt (>= 1.4, < 3.0)
|
72
|
-
memoist (~> 0.12)
|
73
|
-
multi_json (~> 1.11)
|
74
|
-
os (>= 0.9, < 2.0)
|
75
|
-
signet (~> 0.7)
|
76
|
-
grpc (1.8.3)
|
77
|
-
google-protobuf (~> 3.1)
|
78
|
-
googleapis-common-protos-types (~> 1.0.0)
|
79
|
-
googleauth (>= 0.5.1, < 0.7)
|
80
|
-
hashdiff (0.3.8)
|
81
|
-
http_parser.rb (0.6.0)
|
82
|
-
httpclient (2.8.3)
|
83
|
-
json (2.1.0)
|
84
|
-
jwt (2.1.0)
|
85
|
-
memoist (0.16.0)
|
86
|
-
metaclass (0.0.4)
|
87
|
-
mime-types (3.2.2)
|
88
|
-
mime-types-data (~> 3.2015)
|
89
|
-
mime-types-data (3.2018.0812)
|
90
|
-
mocha (1.8.0)
|
91
|
-
metaclass (~> 0.0.1)
|
92
|
-
msgpack (1.2.6)
|
93
|
-
multi_json (1.13.1)
|
94
|
-
multipart-post (2.0.0)
|
95
|
-
os (1.0.0)
|
96
|
-
parser (2.6.0.0)
|
97
|
-
ast (~> 2.4.0)
|
98
|
-
power_assert (1.1.3)
|
99
|
-
powerpack (0.1.2)
|
100
|
-
prometheus-client (0.7.1)
|
101
|
-
quantile (~> 0.2.0)
|
102
|
-
public_suffix (3.0.3)
|
103
|
-
quantile (0.2.1)
|
104
|
-
rainbow (2.2.2)
|
105
|
-
rake
|
106
|
-
rake (10.5.0)
|
107
|
-
representable (3.0.4)
|
108
|
-
declarative (< 0.1.0)
|
109
|
-
declarative-option (< 0.2.0)
|
110
|
-
uber (< 0.2.0)
|
111
|
-
retriable (3.1.2)
|
112
|
-
rly (0.2.3)
|
113
|
-
rubocop (0.39.0)
|
114
|
-
parser (>= 2.3.0.7, < 3.0)
|
115
|
-
powerpack (~> 0.1)
|
116
|
-
rainbow (>= 1.99.1, < 3.0)
|
117
|
-
ruby-progressbar (~> 1.7)
|
118
|
-
unicode-display_width (~> 1.0, >= 1.0.1)
|
119
|
-
ruby-progressbar (1.10.0)
|
120
|
-
safe_yaml (1.0.4)
|
121
|
-
serverengine (2.1.0)
|
122
|
-
sigdump (~> 0.2.2)
|
123
|
-
sigdump (0.2.4)
|
124
|
-
signet (0.11.0)
|
125
|
-
addressable (~> 2.3)
|
126
|
-
faraday (~> 0.9)
|
127
|
-
jwt (>= 1.5, < 3.0)
|
128
|
-
multi_json (~> 1.10)
|
129
|
-
stackdriver-core (1.3.3)
|
130
|
-
google-cloud-core (~> 1.2)
|
131
|
-
strptime (0.2.3)
|
132
|
-
test-unit (3.3.0)
|
133
|
-
power_assert
|
134
|
-
thread_safe (0.3.6)
|
135
|
-
tzinfo (1.2.5)
|
136
|
-
thread_safe (~> 0.1)
|
137
|
-
tzinfo-data (1.2018.9)
|
138
|
-
tzinfo (>= 1.0.0)
|
139
|
-
uber (0.1.0)
|
140
|
-
unicode-display_width (1.4.1)
|
141
|
-
webmock (2.3.2)
|
142
|
-
addressable (>= 2.3.6)
|
143
|
-
crack (>= 0.3.2)
|
144
|
-
hashdiff
|
145
|
-
yajl-ruby (1.4.1)
|
146
|
-
|
147
|
-
PLATFORMS
|
148
|
-
ruby
|
149
|
-
|
150
|
-
DEPENDENCIES
|
151
|
-
fluent-plugin-google-cloud!
|
152
|
-
mocha (~> 1.1)
|
153
|
-
prometheus-client (~> 0.7.1)
|
154
|
-
rake (~> 10.3)
|
155
|
-
rubocop (~> 0.39.0)
|
156
|
-
test-unit (~> 3.0)
|
157
|
-
webmock (~> 2.3.1)
|
158
|
-
|
159
|
-
BUNDLED WITH
|
160
|
-
1.16.6
|