appsignal 5.0.0.rc.1-java → 5.0.0.rc.2-java
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 +4 -4
- data/CHANGELOG.md +140 -0
- data/README.md +2 -1
- data/Rakefile +110 -6
- data/appsignal.gemspec +7 -0
- data/build_matrix.yml +7 -2
- data/ext/agent.rb +27 -27
- data/lib/appsignal/cli/demo.rb +5 -0
- data/lib/appsignal/cli/diagnose.rb +8 -48
- data/lib/appsignal/cli/helpers.rb +45 -0
- data/lib/appsignal/config.rb +262 -37
- data/lib/appsignal/demo.rb +11 -9
- data/lib/appsignal/helpers/instrumentation.rb +88 -0
- data/lib/appsignal/hooks/action_cable.rb +8 -2
- data/lib/appsignal/hooks/active_job.rb +189 -1
- data/lib/appsignal/integrations/delayed_job_plugin.rb +172 -32
- data/lib/appsignal/integrations/que.rb +41 -9
- data/lib/appsignal/integrations/railtie.rb +4 -2
- data/lib/appsignal/integrations/resque.rb +26 -3
- data/lib/appsignal/integrations/shoryuken.rb +21 -2
- data/lib/appsignal/integrations/sidekiq.rb +23 -2
- data/lib/appsignal/integrations/webmachine.rb +13 -5
- data/lib/appsignal/opentelemetry/http_server_request.rb +35 -1
- data/lib/appsignal/opentelemetry/proxied_exporter.rb +83 -0
- data/lib/appsignal/opentelemetry.rb +182 -24
- data/lib/appsignal/rack/abstract_middleware.rb +4 -1
- data/lib/appsignal/rack/event_handler.rb +9 -2
- data/lib/appsignal/rack/grape_middleware.rb +37 -7
- data/lib/appsignal/rack.rb +29 -1
- data/lib/appsignal/transaction/base_backend.rb +21 -0
- data/lib/appsignal/transaction/extension_backend.rb +26 -0
- data/lib/appsignal/transaction/opentelemetry_backend.rb +90 -39
- data/lib/appsignal/transaction.rb +189 -32
- data/lib/appsignal/utils/request_headers.rb +78 -0
- data/lib/appsignal/utils.rb +1 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +1 -0
- data/sig/appsignal.rbi +205 -1
- data/sig/appsignal.rbs +196 -0
- metadata +3 -1
|
@@ -243,7 +243,6 @@ module Appsignal
|
|
|
243
243
|
@error_set = nil
|
|
244
244
|
|
|
245
245
|
@session_data = Appsignal::SampleData.new(:session_data, Hash)
|
|
246
|
-
@headers = Appsignal::SampleData.new(:headers, Hash)
|
|
247
246
|
@custom_data = Appsignal::SampleData.new(:custom_data)
|
|
248
247
|
|
|
249
248
|
@backend = backend || Appsignal::Backends.transaction.new(
|
|
@@ -265,10 +264,19 @@ module Appsignal
|
|
|
265
264
|
# That symbol is also the sample-data key the backend receives, so it can
|
|
266
265
|
# route the bucket to the right storage.
|
|
267
266
|
@params_mapping = @backend.params_mapping
|
|
267
|
+
@params_options = @backend.params_options
|
|
268
268
|
@params_buckets = @params_mapping.values.uniq.to_h do |bucket|
|
|
269
269
|
[bucket, Appsignal::SampleData.new(bucket)]
|
|
270
270
|
end
|
|
271
271
|
|
|
272
|
+
@headers_mapping = @backend.headers_mapping
|
|
273
|
+
@headers_allowlist = @backend.headers_allowlist
|
|
274
|
+
@headers_buckets = @headers_mapping.each_value.map(&:first).uniq.to_h do |bucket|
|
|
275
|
+
[bucket, Appsignal::SampleData.new(bucket, Hash)]
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
@channels_set = []
|
|
279
|
+
|
|
272
280
|
run_after_create_hooks
|
|
273
281
|
end
|
|
274
282
|
|
|
@@ -433,7 +441,7 @@ module Appsignal
|
|
|
433
441
|
# Sample data guide
|
|
434
442
|
def add_params(given_params = nil, &block)
|
|
435
443
|
warn_params_deprecation
|
|
436
|
-
|
|
444
|
+
add_params_channel(:params, given_params, &block)
|
|
437
445
|
end
|
|
438
446
|
alias set_params add_params
|
|
439
447
|
|
|
@@ -491,7 +499,7 @@ module Appsignal
|
|
|
491
499
|
#
|
|
492
500
|
# @see #add_function_parameters
|
|
493
501
|
def add_request_payload(given_params = nil, &block)
|
|
494
|
-
|
|
502
|
+
add_params_channel(:request_payload, given_params, &block)
|
|
495
503
|
end
|
|
496
504
|
|
|
497
505
|
# Add the request payload to the transaction if not already set.
|
|
@@ -527,7 +535,7 @@ module Appsignal
|
|
|
527
535
|
#
|
|
528
536
|
# @see #add_request_payload
|
|
529
537
|
def add_function_parameters(given_params = nil, &block)
|
|
530
|
-
|
|
538
|
+
add_params_channel(:function_parameters, given_params, &block)
|
|
531
539
|
end
|
|
532
540
|
|
|
533
541
|
# Add the function parameters to the transaction if not already set.
|
|
@@ -564,7 +572,7 @@ module Appsignal
|
|
|
564
572
|
#
|
|
565
573
|
# @see #add_request_payload
|
|
566
574
|
def add_query_parameters(given_params = nil, &block)
|
|
567
|
-
|
|
575
|
+
add_params_channel(:query_parameters, given_params, &block)
|
|
568
576
|
end
|
|
569
577
|
|
|
570
578
|
# Add the query parameters to the transaction if not already set.
|
|
@@ -648,6 +656,10 @@ module Appsignal
|
|
|
648
656
|
|
|
649
657
|
# Add headers to the transaction.
|
|
650
658
|
#
|
|
659
|
+
# @deprecated Use {#add_request_headers} for request headers and
|
|
660
|
+
# {#add_request_environment} for the values a Rack environment holds that
|
|
661
|
+
# are not request headers. This method takes both kinds at once, so it
|
|
662
|
+
# has to work out which of them each value is.
|
|
651
663
|
# @since 4.0.0
|
|
652
664
|
# @param given_headers [Hash<String, Object>] A hash containing headers.
|
|
653
665
|
# @yield This block is called when the transaction is sampled. The block's
|
|
@@ -659,7 +671,19 @@ module Appsignal
|
|
|
659
671
|
# @see https://docs.appsignal.com/guides/custom-data/sample-data.html
|
|
660
672
|
# Sample data guide
|
|
661
673
|
def add_headers(given_headers = nil, &block)
|
|
662
|
-
|
|
674
|
+
if block
|
|
675
|
+
headers, environment = Appsignal::Utils::RequestHeaders.split_lazily(&block)
|
|
676
|
+
|
|
677
|
+
add_headers_channel(:request_headers, &headers)
|
|
678
|
+
add_headers_channel(:request_environment, &environment)
|
|
679
|
+
elsif given_headers.is_a?(Hash)
|
|
680
|
+
headers, environment = Appsignal::Utils::RequestHeaders.split(given_headers)
|
|
681
|
+
|
|
682
|
+
add_headers_channel(:request_headers, headers)
|
|
683
|
+
add_headers_channel(:request_environment, environment)
|
|
684
|
+
else
|
|
685
|
+
add_headers_channel(:request_environment, given_headers)
|
|
686
|
+
end
|
|
663
687
|
end
|
|
664
688
|
alias set_headers add_headers
|
|
665
689
|
|
|
@@ -668,6 +692,8 @@ module Appsignal
|
|
|
668
692
|
# When both the `given_headers` and a block is given to this method,
|
|
669
693
|
# the block is leading and the argument will _not_ be used.
|
|
670
694
|
#
|
|
695
|
+
# @deprecated Use {#add_request_headers_if_nil} or
|
|
696
|
+
# {#add_request_environment_if_nil}.
|
|
671
697
|
# @since 4.0.0
|
|
672
698
|
# @param given_headers [Hash<String, Object>] A hash containing headers.
|
|
673
699
|
# @yield This block is called when the transaction is sampled. The block's
|
|
@@ -680,10 +706,92 @@ module Appsignal
|
|
|
680
706
|
# @see https://docs.appsignal.com/guides/custom-data/sample-data.html
|
|
681
707
|
# Sample data guide
|
|
682
708
|
def add_headers_if_nil(given_headers = nil, &block)
|
|
683
|
-
|
|
709
|
+
return if channel_set?(:request_headers) || channel_set?(:request_environment)
|
|
710
|
+
|
|
711
|
+
add_headers(given_headers, &block)
|
|
684
712
|
end
|
|
685
713
|
alias set_headers_if_nil add_headers_if_nil
|
|
686
714
|
|
|
715
|
+
# Add request headers to the transaction.
|
|
716
|
+
#
|
|
717
|
+
# Name each header the way OpenTelemetry names it, in lowercase and with
|
|
718
|
+
# dashes, such as `accept` and `content-length`. In agent mode the names
|
|
719
|
+
# are converted to the Rack spellings the environment uses, such as
|
|
720
|
+
# `HTTP_ACCEPT`.
|
|
721
|
+
#
|
|
722
|
+
# Behaves like {#add_headers}: merges when called multiple times, and a
|
|
723
|
+
# block takes precedence over the argument.
|
|
724
|
+
#
|
|
725
|
+
# @param given_headers [Hash<String, Object>] A hash containing request
|
|
726
|
+
# headers.
|
|
727
|
+
# @yield This block is called when the transaction is sampled. The block's
|
|
728
|
+
# return value will become the new request headers.
|
|
729
|
+
# @yieldreturn [Hash<String, Object>]
|
|
730
|
+
# @return [void]
|
|
731
|
+
#
|
|
732
|
+
# @see #add_request_environment
|
|
733
|
+
# @see https://docs.appsignal.com/guides/custom-data/sample-data.html
|
|
734
|
+
# Sample data guide
|
|
735
|
+
def add_request_headers(given_headers = nil, &block)
|
|
736
|
+
add_headers_channel(:request_headers, given_headers, &block)
|
|
737
|
+
end
|
|
738
|
+
|
|
739
|
+
# Add request headers to the transaction if none are already set.
|
|
740
|
+
#
|
|
741
|
+
# @param given_headers [Hash<String, Object>] A hash containing request
|
|
742
|
+
# headers to set if none are already set.
|
|
743
|
+
# @yield This block is called when the transaction is sampled. The block's
|
|
744
|
+
# return value will become the new request headers.
|
|
745
|
+
# @yieldreturn [Hash<String, Object>]
|
|
746
|
+
# @return [void]
|
|
747
|
+
# @!visibility private
|
|
748
|
+
#
|
|
749
|
+
# @see #add_request_headers
|
|
750
|
+
def add_request_headers_if_nil(given_headers = nil, &block)
|
|
751
|
+
add_request_headers(given_headers, &block) unless channel_set?(:request_headers)
|
|
752
|
+
end
|
|
753
|
+
|
|
754
|
+
# Add values from the request environment to the transaction.
|
|
755
|
+
#
|
|
756
|
+
# These are the values a Rack environment holds that are not request
|
|
757
|
+
# headers, such as `REMOTE_ADDR` and `QUERY_STRING`. Name each one the way
|
|
758
|
+
# Rack names it. Use {#add_request_headers} for the request headers.
|
|
759
|
+
#
|
|
760
|
+
# Behaves like {#add_headers}: merges when called multiple times, and a
|
|
761
|
+
# block takes precedence over the argument.
|
|
762
|
+
#
|
|
763
|
+
# @param given_environment [Hash<String, Object>] A hash containing request
|
|
764
|
+
# environment values.
|
|
765
|
+
# @yield This block is called when the transaction is sampled. The block's
|
|
766
|
+
# return value will become the new request environment.
|
|
767
|
+
# @yieldreturn [Hash<String, Object>]
|
|
768
|
+
# @return [void]
|
|
769
|
+
#
|
|
770
|
+
# @see #add_request_headers
|
|
771
|
+
# @see https://docs.appsignal.com/guides/custom-data/sample-data.html
|
|
772
|
+
# Sample data guide
|
|
773
|
+
def add_request_environment(given_environment = nil, &block)
|
|
774
|
+
add_headers_channel(:request_environment, given_environment, &block)
|
|
775
|
+
end
|
|
776
|
+
|
|
777
|
+
# Add values from the request environment to the transaction if none are
|
|
778
|
+
# already set.
|
|
779
|
+
#
|
|
780
|
+
# @param given_environment [Hash<String, Object>] A hash containing request
|
|
781
|
+
# environment values to set if none are already set.
|
|
782
|
+
# @yield This block is called when the transaction is sampled. The block's
|
|
783
|
+
# return value will become the new request environment.
|
|
784
|
+
# @yieldreturn [Hash<String, Object>]
|
|
785
|
+
# @return [void]
|
|
786
|
+
# @!visibility private
|
|
787
|
+
#
|
|
788
|
+
# @see #add_request_environment
|
|
789
|
+
def add_request_environment_if_nil(given_environment = nil, &block)
|
|
790
|
+
return if channel_set?(:request_environment)
|
|
791
|
+
|
|
792
|
+
add_request_environment(given_environment, &block)
|
|
793
|
+
end
|
|
794
|
+
|
|
687
795
|
# Add custom data to the transaction.
|
|
688
796
|
#
|
|
689
797
|
# @since 4.0.0
|
|
@@ -984,7 +1092,7 @@ module Appsignal
|
|
|
984
1092
|
|
|
985
1093
|
# @!visibility private
|
|
986
1094
|
attr_writer :is_duplicate, :tags, :custom_data, :params_buckets,
|
|
987
|
-
:session_data, :
|
|
1095
|
+
:session_data, :headers_buckets, :channels_set
|
|
988
1096
|
|
|
989
1097
|
# @!visibility private
|
|
990
1098
|
def internal_set_error(error, &block)
|
|
@@ -1037,11 +1145,21 @@ module Appsignal
|
|
|
1037
1145
|
@params_buckets.fetch(@params_mapping.fetch(channel))
|
|
1038
1146
|
end
|
|
1039
1147
|
|
|
1040
|
-
|
|
1041
|
-
|
|
1148
|
+
PARAMS_CHANNEL_ALIASES = { :params => :request_payload }.freeze
|
|
1149
|
+
private_constant :PARAMS_CHANNEL_ALIASES
|
|
1150
|
+
|
|
1151
|
+
def params_channel(channel)
|
|
1152
|
+
PARAMS_CHANNEL_ALIASES.fetch(channel, channel)
|
|
1153
|
+
end
|
|
1154
|
+
|
|
1155
|
+
def add_params_channel(channel, given_params = nil, &block)
|
|
1156
|
+
sample = params_data(channel)
|
|
1157
|
+
sample.add(given_params, &block)
|
|
1158
|
+
mark_channel_set(params_channel(channel)) if sample.value?
|
|
1159
|
+
end
|
|
1160
|
+
|
|
1042
1161
|
def params_unset?(channel)
|
|
1043
|
-
|
|
1044
|
-
!bucket.value? && !bucket.empty?
|
|
1162
|
+
!channel_set?(params_channel(channel)) && !params_data(channel).empty?
|
|
1045
1163
|
end
|
|
1046
1164
|
|
|
1047
1165
|
# `add_params`/`set_params` don't say whether the params are a request
|
|
@@ -1222,18 +1340,21 @@ module Appsignal
|
|
|
1222
1340
|
end
|
|
1223
1341
|
|
|
1224
1342
|
def sample_data
|
|
1225
|
-
data = {
|
|
1226
|
-
|
|
1343
|
+
data = {}
|
|
1344
|
+
@headers_buckets.each do |bucket, sample|
|
|
1345
|
+
data[bucket] = sanitized_headers(bucket, sample)
|
|
1346
|
+
end
|
|
1347
|
+
data.merge!(
|
|
1227
1348
|
:session_data => sanitized_session_data,
|
|
1228
1349
|
:tags => sanitized_tags,
|
|
1229
1350
|
:custom_data => custom_data
|
|
1230
|
-
|
|
1351
|
+
)
|
|
1231
1352
|
# Each params bucket is emitted under its own key. The extension backend
|
|
1232
1353
|
# has a single `:params` bucket; the OpenTelemetry backend has separate
|
|
1233
1354
|
# `:request_payload` and `:function_parameters` buckets. The backend maps
|
|
1234
1355
|
# each key to its storage (C-extension slot or OpenTelemetry attribute).
|
|
1235
1356
|
@params_buckets.each do |bucket, sample|
|
|
1236
|
-
data[bucket] = sanitized_params(sample)
|
|
1357
|
+
data[bucket] = sanitized_params(bucket, sample)
|
|
1237
1358
|
end
|
|
1238
1359
|
data.each do |key, value|
|
|
1239
1360
|
set_sample_data(key, value)
|
|
@@ -1252,7 +1373,8 @@ module Appsignal
|
|
|
1252
1373
|
transaction.custom_data = @custom_data.dup
|
|
1253
1374
|
transaction.params_buckets = @params_buckets.transform_values(&:dup)
|
|
1254
1375
|
transaction.session_data = @session_data.dup
|
|
1255
|
-
transaction.
|
|
1376
|
+
transaction.headers_buckets = @headers_buckets.transform_values(&:dup)
|
|
1377
|
+
transaction.channels_set = @channels_set.dup
|
|
1256
1378
|
end
|
|
1257
1379
|
end
|
|
1258
1380
|
|
|
@@ -1260,10 +1382,11 @@ module Appsignal
|
|
|
1260
1382
|
params_value(params_data(:params))
|
|
1261
1383
|
end
|
|
1262
1384
|
|
|
1263
|
-
def sanitized_params(sample
|
|
1264
|
-
|
|
1385
|
+
def sanitized_params(bucket, sample)
|
|
1386
|
+
options = @params_options.fetch(bucket)
|
|
1387
|
+
return if Appsignal.config[options.fetch(:send)] == false
|
|
1265
1388
|
|
|
1266
|
-
filter_keys = Appsignal.config[:
|
|
1389
|
+
filter_keys = Appsignal.config[options.fetch(:filter)] || []
|
|
1267
1390
|
Appsignal::Utils::SampleDataSanitizer.sanitize(params_value(sample), filter_keys)
|
|
1268
1391
|
end
|
|
1269
1392
|
|
|
@@ -1305,32 +1428,66 @@ module Appsignal
|
|
|
1305
1428
|
)
|
|
1306
1429
|
end
|
|
1307
1430
|
|
|
1308
|
-
def
|
|
1309
|
-
@
|
|
1431
|
+
def add_headers_channel(channel, given_headers = nil, &block)
|
|
1432
|
+
bucket, transform = @headers_mapping.fetch(channel)
|
|
1433
|
+
sample = @headers_buckets.fetch(bucket)
|
|
1434
|
+
|
|
1435
|
+
if transform.nil?
|
|
1436
|
+
sample.add(given_headers, &block)
|
|
1437
|
+
elsif block
|
|
1438
|
+
sample.add { transform_headers(transform, block.call) }
|
|
1439
|
+
else
|
|
1440
|
+
sample.add(transform_headers(transform, given_headers))
|
|
1441
|
+
end
|
|
1442
|
+
|
|
1443
|
+
mark_channel_set(channel) if sample.value?
|
|
1444
|
+
end
|
|
1445
|
+
|
|
1446
|
+
def transform_headers(transform, headers)
|
|
1447
|
+
return headers unless headers.is_a?(Hash)
|
|
1448
|
+
|
|
1449
|
+
headers.to_h(&transform)
|
|
1450
|
+
end
|
|
1451
|
+
|
|
1452
|
+
def mark_channel_set(channel)
|
|
1453
|
+
@channels_set << channel unless @channels_set.include?(channel)
|
|
1454
|
+
end
|
|
1455
|
+
|
|
1456
|
+
def channel_set?(channel)
|
|
1457
|
+
@channels_set.include?(channel)
|
|
1458
|
+
end
|
|
1459
|
+
|
|
1460
|
+
def headers_value(sample)
|
|
1461
|
+
sample.value
|
|
1310
1462
|
rescue => e
|
|
1311
1463
|
Appsignal.internal_logger.error \
|
|
1312
1464
|
"Exception while fetching headers: #{e.class}: #{e}"
|
|
1313
1465
|
nil
|
|
1314
1466
|
end
|
|
1315
1467
|
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
# The environment of a transaction can contain a lot of information, not
|
|
1319
|
-
# all of it useful for debugging.
|
|
1320
|
-
#
|
|
1321
|
-
# @return [nil] if no environment is present.
|
|
1322
|
-
# @return [Hash<String, Object>]
|
|
1323
|
-
def sanitized_request_headers
|
|
1324
|
-
headers = request_headers
|
|
1468
|
+
def sanitized_headers(bucket, sample)
|
|
1469
|
+
headers = headers_value(sample)
|
|
1325
1470
|
return unless headers
|
|
1326
1471
|
|
|
1472
|
+
option, header_names = @headers_allowlist.fetch(bucket)
|
|
1473
|
+
allowlist = Appsignal.config[option]
|
|
1474
|
+
|
|
1475
|
+
headers = normalized_headers(headers) if header_names
|
|
1476
|
+
|
|
1327
1477
|
{}.tap do |out|
|
|
1328
|
-
|
|
1478
|
+
allowlist.each do |key|
|
|
1479
|
+
key = Appsignal::Utils::RequestHeaders.normalize(key) if header_names
|
|
1329
1480
|
out[key] = headers[key] if headers[key]
|
|
1330
1481
|
end
|
|
1331
1482
|
end
|
|
1332
1483
|
end
|
|
1333
1484
|
|
|
1485
|
+
def normalized_headers(headers)
|
|
1486
|
+
headers.to_h do |key, value|
|
|
1487
|
+
[Appsignal::Utils::RequestHeaders.normalize(key), value]
|
|
1488
|
+
end
|
|
1489
|
+
end
|
|
1490
|
+
|
|
1334
1491
|
# Only keep tags if they meet the following criteria:
|
|
1335
1492
|
# * Key is a symbol or string with less then 100 chars
|
|
1336
1493
|
# * Value is a symbol or string with less then 100 chars
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Appsignal
|
|
4
|
+
module Utils
|
|
5
|
+
class RequestHeaders
|
|
6
|
+
# The only two request headers Rack passes without the `HTTP_` prefix,
|
|
7
|
+
# because CGI reserves the prefixed spelling of them.
|
|
8
|
+
UNPREFIXED_HEADER_KEYS = %w[CONTENT_LENGTH CONTENT_TYPE].freeze
|
|
9
|
+
|
|
10
|
+
# `HTTP_VERSION` is a CGI variable holding the same value as
|
|
11
|
+
# `SERVER_PROTOCOL`, not a header.
|
|
12
|
+
NON_HEADER_KEYS = %w[HTTP_VERSION].freeze
|
|
13
|
+
|
|
14
|
+
# The environment keys the instrumentation already describes with a semantic
|
|
15
|
+
# convention attribute, read from the request itself.
|
|
16
|
+
TRANSLATED_ENV_KEYS = %w[
|
|
17
|
+
PATH_INFO REQUEST_METHOD REQUEST_PATH SERVER_NAME SERVER_PORT
|
|
18
|
+
SERVER_PROTOCOL
|
|
19
|
+
].freeze
|
|
20
|
+
|
|
21
|
+
HTTP_PREFIX = "HTTP_"
|
|
22
|
+
|
|
23
|
+
class << self
|
|
24
|
+
def split(env)
|
|
25
|
+
return [{}, env] unless env.is_a?(Hash)
|
|
26
|
+
|
|
27
|
+
headers = {}
|
|
28
|
+
environment = {}
|
|
29
|
+
|
|
30
|
+
env.each do |key, value|
|
|
31
|
+
name = header_name(key)
|
|
32
|
+
if name
|
|
33
|
+
headers[name] = value
|
|
34
|
+
else
|
|
35
|
+
environment[key] = value
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
[headers, environment]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def split_lazily(&block)
|
|
43
|
+
split = nil
|
|
44
|
+
splitter = lambda { split ||= split(block.call) }
|
|
45
|
+
|
|
46
|
+
[lambda { splitter.call.first }, lambda { splitter.call.last }]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def header_name(env_key)
|
|
50
|
+
env_key = env_key.to_s
|
|
51
|
+
return if NON_HEADER_KEYS.include?(env_key)
|
|
52
|
+
|
|
53
|
+
if env_key.start_with?(HTTP_PREFIX)
|
|
54
|
+
normalize(env_key.delete_prefix(HTTP_PREFIX))
|
|
55
|
+
elsif UNPREFIXED_HEADER_KEYS.include?(env_key)
|
|
56
|
+
normalize(env_key)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# A key does not always make the round trip as itself, because two Rack keys
|
|
61
|
+
# can name the same header: a server that sets both `CONTENT_LENGTH` and
|
|
62
|
+
# `HTTP_CONTENT_LENGTH` gets the second one back as the first.
|
|
63
|
+
def rack_name(header)
|
|
64
|
+
env_key = header.to_s.upcase.tr("-", "_")
|
|
65
|
+
return env_key if UNPREFIXED_HEADER_KEYS.include?(env_key)
|
|
66
|
+
|
|
67
|
+
"#{HTTP_PREFIX}#{env_key}"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Several OpenTelemetry SDKs write header attribute names with underscores,
|
|
71
|
+
# where the semantic conventions the collector compares against use dashes.
|
|
72
|
+
def normalize(name)
|
|
73
|
+
name.to_s.downcase.tr("_", "-")
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
data/lib/appsignal/utils.rb
CHANGED
|
@@ -10,6 +10,7 @@ require "appsignal/utils/integration_memory_logger"
|
|
|
10
10
|
require "appsignal/utils/stdout_and_logger_message"
|
|
11
11
|
require "appsignal/utils/data"
|
|
12
12
|
require "appsignal/utils/sample_data_sanitizer"
|
|
13
|
+
require "appsignal/utils/request_headers"
|
|
13
14
|
require "appsignal/utils/integration_logger"
|
|
14
15
|
require "appsignal/utils/json"
|
|
15
16
|
require "appsignal/utils/ndjson"
|
data/lib/appsignal/version.rb
CHANGED