newrelic_rpm 6.6.0.358 → 6.7.0.359

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d39324de06656b928892edc72296e459eb2737929e20f054514c2ddc980bfb0
4
- data.tar.gz: 3752b1d5dbcd79b38a808460c68141926ae627f0c50ec8cc6ded103285719844
3
+ metadata.gz: e0981d305747247f1ac56c96ff7268cfd8b9bd7d419e8b800f2daf9193ae1dee
4
+ data.tar.gz: 9b4ca44ed6641fe4ea5f71296d8042f3ed5024a9d8d1dc3230241f02cab529fd
5
5
  SHA512:
6
- metadata.gz: 6f277cc9660dde4ef818de176ad156202ad1993594416882e678b31786386f547b200a96444be1a84bfa53e8385700f07b837d3c500a1e8529d2e4c5d9bbf3ab
7
- data.tar.gz: 258bd06b3feaf43c29e8007a6d97003d2d7879b719fc818ba1a374a2167f336f1b4b4352b31d938af24afb0c917751649e62eddaaab41a7955ef55e10f56e84d
6
+ metadata.gz: 8596846993859508c5acf8fc54155572332a75258f1970b01b9d89974ec7a4f935d5f728f2826bbac8190e49f368e51d961b6754f2742248a228458fa225763d
7
+ data.tar.gz: b07bc5d7dbd98faec43a76514ac6314f5f9c8667941db20b68ac4f13fddbf69656c7b75d1d3b02f4c1d46873aecf528bd5062c96f4895bf2a4234bd48da5999d
@@ -6,7 +6,10 @@ services:
6
6
 
7
7
  language: ruby
8
8
 
9
+ dist: precise
9
10
  sudo: required
11
+ jdk:
12
+ - oraclejdk8
10
13
 
11
14
  before_install:
12
15
  # RUBY-2072 Prevent Travis setup failure before our test even starts
@@ -15,6 +18,7 @@ before_install:
15
18
  - gem --version
16
19
  - ./test/script/before_install/update_rubygems.sh
17
20
  - rvm @global do gem uninstall bundler --all --executables || true
21
+ - gem uninstall bundler --all --executables || true
18
22
  - gem install bundler -v=1.17.3
19
23
  - ./test/script/before_install/gemstash_mirror.sh
20
24
  - bundle --version
@@ -51,6 +55,9 @@ rvm:
51
55
  - 2.1.10
52
56
  - 2.0.0-p648
53
57
 
58
+ jdk:
59
+ - oraclejdk8
60
+
54
61
  env:
55
62
  global:
56
63
  - BUNDLE_PATH=/home/travis/bundle
@@ -85,6 +92,9 @@ env:
85
92
  - TYPE=NULLVERSE
86
93
 
87
94
  matrix:
95
+ allow_failures:
96
+ - rvm: jruby-9.2.6.0
97
+ env: TYPE=FUNCTIONAL GROUP=agent
88
98
  fast_finish: true
89
99
  exclude:
90
100
  # Unsupported Rails/Ruby combinations
@@ -1,5 +1,33 @@
1
1
  # New Relic Ruby Agent Release Notes #
2
2
 
3
+ ## v6.7.0
4
+
5
+ * **Trace and Entity Metadata API**
6
+
7
+ Several new API methods have been added to the agent:
8
+ * [`Agent#linking_metadata`](https://www.rubydoc.info/github/newrelic/rpm/NewRelic/Agent#linking_metadata-instance_method)
9
+ * [`Tracer#trace_id`](https://www.rubydoc.info/github/newrelic/rpm/NewRelic/Agent/Tracer#trace_id-class_method)
10
+ * [`Tracer#span_id`](https://www.rubydoc.info/github/newrelic/rpm/NewRelic/Agent/Tracer#span_id-class_method)
11
+ * [`Tracer#sampled?`](https://www.rubydoc.info/github/newrelic/rpm/NewRelic/Agent/Tracer#sampled?-class_method)
12
+
13
+ These API methods allow you to access information that can be used to link data of your choosing to a trace or entity.
14
+
15
+ * **Logs in Context**
16
+
17
+ This version of the agent includes a logger, which can be used in place of `::Logger`
18
+ from the standard library, or `ActiveSupport::Logger` from Rails. This logger
19
+ leverages the new trace and entity metadata API to decorate log statements with entity
20
+ and trace metadata, so they can be correlated together in the New Relic UI.
21
+
22
+ For more information on how to use logs in context, see https://docs.newrelic.com/docs/enable-logs-context-ruby
23
+
24
+ * **Project metadata in Gemspec**
25
+
26
+ Project metadata has been added to the gemspec file. This means our Rubygems page will allow users to more easily
27
+ access the agent's source code, raise issues, and read the changelog.
28
+
29
+ Thanks to Orien Madgwick for the contribution!
30
+
3
31
  ## v6.6.0
4
32
 
5
33
  * **Bugfix for ActionCable Instrumentation**
@@ -55,6 +55,7 @@ module NewRelic
55
55
  require 'new_relic/agent/system_info'
56
56
  require 'new_relic/agent/external'
57
57
  require 'new_relic/agent/deprecator'
58
+ require 'new_relic/agent/logging'
58
59
 
59
60
  require 'new_relic/agent/instrumentation/controller_instrumentation'
60
61
 
@@ -660,6 +661,54 @@ module NewRelic
660
661
  NewRelic::Agent.logger.debug "Ignoring exception during %p event notification" % [event_type]
661
662
  end
662
663
 
664
+ # @!group Trace and Entity metadata
665
+
666
+ TRACE_ID_KEY = 'trace.id'.freeze
667
+ SPAN_ID_KEY = 'span.id'.freeze
668
+ ENTITY_NAME_KEY = 'entity.name'.freeze
669
+ ENTITY_TYPE_KEY = 'entity.type'.freeze
670
+ ENTITY_GUID_KEY = 'entity.guid'.freeze
671
+ HOSTNAME_KEY = 'hostname'.freeze
672
+
673
+ ENTITY_TYPE = 'SERVICE'.freeze
674
+
675
+ # Returns a new hash containing trace and entity metadata that can be used
676
+ # to relate data to a trace or to an entity in APM.
677
+ #
678
+ # This hash includes:
679
+ # * trace.id - The current trace id, if there is a current trace id. This
680
+ # value may be omitted.
681
+ # * span.id - The current span id, if there is a current span. This
682
+ # value may be omitted.
683
+ # * entity.name - The name of the current application. This is read from
684
+ # the +app_name+ key in your config. If there are multiple application
685
+ # names, the first one is used.
686
+ # * entity.type - The entity type is hardcoded to the string +'SERVICE'+.
687
+ # * entity.guid - The guid of the current entity.
688
+ # * hostname - The fully qualified hostname.
689
+ #
690
+ # @api public
691
+ def linking_metadata
692
+ metadata = Hash.new
693
+ metadata[ENTITY_NAME_KEY] = config[:app_name][0]
694
+ metadata[ENTITY_TYPE_KEY] = ENTITY_TYPE
695
+ metadata[HOSTNAME_KEY] = Hostname.get
696
+
697
+ if entity_guid = config[:entity_guid]
698
+ metadata[ENTITY_GUID_KEY] = entity_guid
699
+ end
700
+
701
+ if trace_id = Tracer.current_trace_id
702
+ metadata[TRACE_ID_KEY] = trace_id
703
+ end
704
+ if span_id = Tracer.current_span_id
705
+ metadata[SPAN_ID_KEY] = span_id
706
+ end
707
+ metadata
708
+ end
709
+
710
+ #@!endgroup
711
+
663
712
  # @!group Manual browser monitoring configuration
664
713
 
665
714
  # This method returns a string suitable for inclusion in a page - known as
@@ -332,7 +332,7 @@ module NewRelic
332
332
  end
333
333
 
334
334
  def log_app_name
335
- ::NewRelic::Agent.logger.info "Application: #{Agent.config.app_names.join(", ")}"
335
+ ::NewRelic::Agent.logger.info "Application: #{Agent.config[:app_name].join(", ")}"
336
336
  end
337
337
 
338
338
  def log_ignore_url_regexes
@@ -345,7 +345,7 @@ module NewRelic
345
345
 
346
346
  # Logs the configured application names
347
347
  def app_name_configured?
348
- names = Agent.config.app_names
348
+ names = Agent.config[:app_name]
349
349
  return names.respond_to?(:any?) && names.any?
350
350
  end
351
351
 
@@ -561,7 +561,10 @@ module NewRelic
561
561
  def flush_pipe_data
562
562
  if connected? && @service.is_a?(::NewRelic::Agent::PipeService)
563
563
  transmit_data
564
- transmit_event_data
564
+ transmit_analytic_event_data
565
+ transmit_custom_event_data
566
+ transmit_error_event_data
567
+ transmit_span_event_data
565
568
  end
566
569
  end
567
570
 
@@ -577,20 +580,46 @@ module NewRelic
577
580
 
578
581
  LOG_ONCE_KEYS_RESET_PERIOD = 60.0
579
582
 
583
+ # Certain event types may sometimes need to be on the same interval as metrics,
584
+ # so we will check config assigned in EventHarvestConfig to determine the interval
585
+ # on which to report them
586
+ def interval_for event_type
587
+ interval = Agent.config[:"event_report_period.#{event_type}"]
588
+ :"#{interval}_second_harvest"
589
+ end
590
+
591
+ ANALYTIC_EVENT_DATA = "analytic_event_data".freeze
592
+ CUSTOM_EVENT_DATA = "custom_event_data".freeze
593
+ ERROR_EVENT_DATA = "error_event_data".freeze
594
+ SPAN_EVENT_DATA = "span_event_data".freeze
595
+
580
596
  def create_and_run_event_loop
597
+ data_harvest = :"#{Agent.config[:data_report_period]}_second_harvest"
598
+ event_harvest = :"#{Agent.config[:event_report_period]}_second_harvest"
599
+
581
600
  @event_loop = create_event_loop
582
- @event_loop.on(:report_data) do
601
+ @event_loop.on(data_harvest) do
583
602
  transmit_data
584
603
  end
585
- @event_loop.on(:report_event_data) do
586
- transmit_event_data
604
+
605
+ @event_loop.on(interval_for ANALYTIC_EVENT_DATA) do
606
+ transmit_analytic_event_data
607
+ end
608
+ @event_loop.on(interval_for CUSTOM_EVENT_DATA) do
609
+ transmit_custom_event_data
610
+ end
611
+ @event_loop.on(interval_for ERROR_EVENT_DATA) do
612
+ transmit_error_event_data
613
+ end
614
+ @event_loop.on(interval_for SPAN_EVENT_DATA) do
615
+ transmit_span_event_data
587
616
  end
588
617
  @event_loop.on(:reset_log_once_keys) do
589
618
  ::NewRelic::Agent.logger.clear_already_logged
590
619
  end
591
- @event_loop.fire_every(Agent.config[:data_report_period], :report_data)
592
- @event_loop.fire_every(Agent.config[:event_report_period], :report_event_data)
593
- @event_loop.fire_every(LOG_ONCE_KEYS_RESET_PERIOD, :reset_log_once_keys)
620
+ @event_loop.fire_every(Agent.config[:data_report_period], data_harvest)
621
+ @event_loop.fire_every(Agent.config[:event_report_period], event_harvest)
622
+ @event_loop.fire_every(LOG_ONCE_KEYS_RESET_PERIOD, :reset_log_once_keys)
594
623
 
595
624
  @event_loop.run
596
625
  end
@@ -763,14 +792,14 @@ module NewRelic
763
792
  Agent.config[:send_environment_info] ? Array(EnvironmentReport.new) : []
764
793
  end
765
794
 
766
- # Constructs and memoizes an event_harvest_config hash to be used in
795
+ # Constructs and memoizes an event_harvest_config hash to be used in
767
796
  # the payload sent during connect (and reconnect)
768
797
  def event_harvest_config
769
798
  @event_harvest_config ||= Configuration::EventHarvestConfig.from_config(Agent.config)
770
799
  end
771
800
 
772
801
  # Builds the payload to send to the connect service,
773
- # connects, then configures the agent using the response from
802
+ # connects, then configures the agent using the response from
774
803
  # the connect service
775
804
  def connect_to_server
776
805
  request_builder = ::NewRelic::Agent::Connect::RequestBuilder.new \
@@ -1019,17 +1048,20 @@ module NewRelic
1019
1048
  def harvest_and_send_analytic_event_data
1020
1049
  harvest_and_send_from_container(transaction_event_aggregator, :analytic_event_data)
1021
1050
  harvest_and_send_from_container(synthetics_event_aggregator, :analytic_event_data)
1022
- harvest_and_send_from_container(@custom_event_aggregator, :custom_event_data)
1023
1051
  end
1024
1052
 
1025
- def harvest_and_send_span_event_data
1026
- harvest_and_send_from_container(span_event_aggregator, :span_event_data)
1053
+ def harvest_and_send_custom_event_data
1054
+ harvest_and_send_from_container(@custom_event_aggregator, :custom_event_data)
1027
1055
  end
1028
1056
 
1029
1057
  def harvest_and_send_error_event_data
1030
1058
  harvest_and_send_from_container @error_collector.error_event_aggregator, :error_event_data
1031
1059
  end
1032
1060
 
1061
+ def harvest_and_send_span_event_data
1062
+ harvest_and_send_from_container(span_event_aggregator, :span_event_data)
1063
+ end
1064
+
1033
1065
  def check_for_and_handle_agent_commands
1034
1066
  begin
1035
1067
  @agent_command_router.check_for_and_handle_agent_commands
@@ -1050,18 +1082,30 @@ module NewRelic
1050
1082
  NewRelic::Agent.record_metric("Supportability/remote_unavailable/#{endpoint.to_s}", 0.0)
1051
1083
  end
1052
1084
 
1053
- def transmit_event_data
1054
- transmit_single_data_type(:harvest_and_send_analytic_event_data, "TransactionEvent")
1085
+ TRANSACTION_EVENT = "TransactionEvent".freeze
1086
+ def transmit_analytic_event_data
1087
+ transmit_single_data_type(:harvest_and_send_analytic_event_data, TRANSACTION_EVENT)
1088
+ end
1089
+
1090
+ CUSTOM_EVENT = "CustomEvent".freeze
1091
+ def transmit_custom_event_data
1092
+ transmit_single_data_type(:harvest_and_send_custom_event_data, CUSTOM_EVENT)
1093
+ end
1094
+
1095
+ ERROR_EVENT = "ErrorEvent".freeze
1096
+ def transmit_error_event_data
1097
+ transmit_single_data_type(:harvest_and_send_error_event_data, ERROR_EVENT)
1055
1098
  end
1056
1099
 
1100
+ SPAN_EVENT = "SpanEvent".freeze
1057
1101
  def transmit_span_event_data
1058
- transmit_single_data_type(:harvest_and_send_span_event_data, "SpanEvent")
1102
+ transmit_single_data_type(:harvest_and_send_span_event_data, SPAN_EVENT)
1059
1103
  end
1060
1104
 
1061
1105
  def transmit_single_data_type(harvest_method, supportability_name)
1062
1106
  now = Time.now
1063
1107
 
1064
- msg = "Sending #{harvest_method.to_s.gsub("harvest_and_send_", "")} to New Relic Service"
1108
+ msg = "Sending #{supportability_name} data to New Relic Service"
1065
1109
  ::NewRelic::Agent.logger.debug msg
1066
1110
 
1067
1111
  @service.session do # use http keep-alive
@@ -1108,7 +1152,10 @@ module NewRelic
1108
1152
 
1109
1153
  @events.notify(:before_shutdown)
1110
1154
  transmit_data
1111
- transmit_event_data
1155
+ transmit_analytic_event_data
1156
+ transmit_custom_event_data
1157
+ transmit_error_event_data
1158
+ transmit_span_event_data
1112
1159
 
1113
1160
  if @connected_pid == $$ && !@service.kind_of?(NewRelic::Agent::NewRelicService)
1114
1161
  ::NewRelic::Agent.logger.debug "Sending New Relic service agent run shutdown message"
@@ -196,6 +196,15 @@ module NewRelic
196
196
  end
197
197
  end
198
198
 
199
+ SEMICOLON = ';'.freeze
200
+ def self.convert_to_list_on_semicolon value
201
+ case value
202
+ when Array then value
203
+ when String then value.split(SEMICOLON)
204
+ else []
205
+ end
206
+ end
207
+
199
208
  def self.convert_to_constant_list(raw_value)
200
209
  const_names = convert_to_list(raw_value)
201
210
  const_names.map! do |class_name|
@@ -291,8 +300,17 @@ module NewRelic
291
300
  :public => true,
292
301
  :type => String,
293
302
  :allowed_from_server => false,
303
+ :transform => DefaultSource.method(:convert_to_list_on_semicolon),
294
304
  :description => 'Specify the <a href="https://docs.newrelic.com/docs/apm/new-relic-apm/installation-configuration/name-your-application">application name</a> used to aggregate data in the New Relic UI. To report data to <a href="https://docs.newrelic.com/docs/apm/new-relic-apm/installation-configuration/using-multiple-names-app">multiple apps at the same time</a>, specify a list of names separated by a semicolon <code>;</code>. For example, <code>MyApp</code> or <code>MyStagingApp;Instance1</code>.'
295
305
  },
306
+ :entity_guid => {
307
+ :default => nil,
308
+ :allow_nil => true,
309
+ :public => true,
310
+ :type => String,
311
+ :allowed_from_server => true,
312
+ :description => 'The <a href="https://docs.newrelic.com/attribute-dictionary/span/entityguid">Entity GUID</a> for the entity running this agent.'
313
+ },
296
314
  :monitor_mode => {
297
315
  :default => value_of(:enabled),
298
316
  :public => true,
@@ -568,6 +586,38 @@ module NewRelic
568
586
  :allowed_from_server => true,
569
587
  :description => 'Number of seconds betwixt connections to the New Relic event collection services.'
570
588
  },
589
+ :'event_report_period.analytic_event_data' => {
590
+ :default => 60,
591
+ :public => false,
592
+ :type => Integer,
593
+ :dynamic_name => true,
594
+ :allowed_from_server => true,
595
+ :description => 'Number of seconds betwixt connections to the New Relic analytic event collection services.'
596
+ },
597
+ :'event_report_period.custom_event_data' => {
598
+ :default => 60,
599
+ :public => false,
600
+ :type => Integer,
601
+ :dynamic_name => true,
602
+ :allowed_from_server => true,
603
+ :description => 'Number of seconds betwixt connections to the New Relic custom event collection services.'
604
+ },
605
+ :'event_report_period.error_event_data' => {
606
+ :default => 60,
607
+ :public => false,
608
+ :type => Integer,
609
+ :dynamic_name => true,
610
+ :allowed_from_server => true,
611
+ :description => 'Number of seconds betwixt connections to the New Relic error event collection services.'
612
+ },
613
+ :'event_report_period.span_event_data' => {
614
+ :default => 60,
615
+ :public => false,
616
+ :type => Integer,
617
+ :dynamic_name => true,
618
+ :allowed_from_server => true,
619
+ :description => 'Number of seconds betwixt connections to the New Relic span event collection services.'
620
+ },
571
621
  :'data_report_periods.analytic_event_data' => {
572
622
  :default => 60,
573
623
  :public => false,
@@ -12,7 +12,8 @@ module NewRelic
12
12
  EVENT_HARVEST_CONFIG_KEY_MAPPING = {
13
13
  :analytic_event_data => :'analytics_events.max_samples_stored',
14
14
  :custom_event_data => :'custom_insights_events.max_samples_stored',
15
- :error_event_data => :'error_collector.max_event_samples_stored'
15
+ :error_event_data => :'error_collector.max_event_samples_stored',
16
+ :span_event_data => :'span_events.max_samples_stored'
16
17
  }
17
18
 
18
19
  def from_config(config)
@@ -25,15 +26,20 @@ module NewRelic
25
26
  end
26
27
 
27
28
  def to_config_hash(connect_reply)
28
- config_hash = EVENT_HARVEST_CONFIG_KEY_MAPPING.inject({}) do
29
+ event_harvest_interval = connect_reply['event_harvest_config']['report_period_ms'] / 1000
30
+ config_hash = EVENT_HARVEST_CONFIG_KEY_MAPPING.inject({}) do
29
31
  |event_harvest_config, (connect_payload_key, config_key)|
30
- event_harvest_config[config_key] = connect_reply['event_harvest_config']['harvest_limits'][connect_payload_key.to_s]
32
+ if harvest_limit = connect_reply['event_harvest_config']['harvest_limits'][connect_payload_key.to_s]
33
+ event_harvest_config[config_key] = harvest_limit
34
+ report_period_key = :"event_report_period.#{connect_payload_key}"
35
+ event_harvest_config[report_period_key] = event_harvest_interval
36
+ end
31
37
  event_harvest_config
32
38
  end
33
- config_hash[:event_report_period] = connect_reply['event_harvest_config']['report_period_ms'] / 1000
39
+ config_hash[:event_report_period] = event_harvest_interval
34
40
  config_hash
35
41
  end
36
42
  end
37
43
  end
38
44
  end
39
- end
45
+ end
@@ -228,14 +228,6 @@ module NewRelic
228
228
  end
229
229
  end
230
230
 
231
- def app_names
232
- case NewRelic::Agent.config[:app_name]
233
- when Array then NewRelic::Agent.config[:app_name]
234
- when String then NewRelic::Agent.config[:app_name].split(';')
235
- else []
236
- end
237
- end
238
-
239
231
  MALFORMED_LABELS_WARNING = "Skipping malformed labels configuration"
240
232
  PARSING_LABELS_FAILURE = "Failure during parsing labels. Ignoring and carrying on with connect."
241
233
 
@@ -21,6 +21,7 @@ module NewRelic
21
21
  "cross_process_id",
22
22
  "data_report_period",
23
23
  "encoding_key",
24
+ "entity_guid",
24
25
  "error_beacon",
25
26
  "js_agent_file",
26
27
  "js_agent_loader",
@@ -78,6 +79,7 @@ module NewRelic
78
79
  :'analytics_events.max_samples_stored' => 'Supportability/EventHarvest/AnalyticEventData/HarvestLimit',
79
80
  :'custom_insights_events.max_samples_stored' => 'Supportability/EventHarvest/CustomEventData/HarvestLimit',
80
81
  :'error_collector.max_event_samples_stored'=> 'Supportability/EventHarvest/ErrorEventData/HarvestLimit',
82
+ :'span_events.max_samples_stored'=> 'Supportability/EventHarvest/SpanEventData/HarvestLimit',
81
83
  :event_report_period => 'Supportability/EventHarvest/ReportPeriod'
82
84
  }
83
85
 
@@ -100,7 +102,6 @@ module NewRelic
100
102
  || (event_harvest_config['report_period_ms'] / 1000) <= 0
101
103
  NewRelic::Agent.logger.warn "Invalid event harvest config found " \
102
104
  "in connect response; using default event report period."
103
- NewRelic::Agent.record_metric('Supportability/Agent/Collector/MissingEventHarvestConfig', 1)
104
105
  false
105
106
  else
106
107
  true
@@ -25,7 +25,7 @@ module NewRelic
25
25
  :pid => $$,
26
26
  :host => local_host,
27
27
  :display_host => Agent.config[:'process_host.display_name'],
28
- :app_name => Agent.config.app_names,
28
+ :app_name => Agent.config[:app_name],
29
29
  :language => 'ruby',
30
30
  :labels => Agent.config.parsed_labels,
31
31
  :agent_version => NewRelic::VERSION::STRING,
@@ -34,7 +34,7 @@ module NewRelic
34
34
  :settings => Agent.config.to_collector_hash,
35
35
  :high_security => Agent.config[:high_security],
36
36
  :utilization => UtilizationData.new.to_collector_hash,
37
- :identifier => "ruby:#{local_host}:#{Agent.config.app_names.sort.join(',')}",
37
+ :identifier => "ruby:#{local_host}:#{Agent.config[:app_name].sort.join(',')}",
38
38
  :event_harvest_config => @event_harvest_config
39
39
  }
40
40
  end
@@ -28,7 +28,7 @@ module NewRelic
28
28
 
29
29
  def path_hash(txn_name, seed)
30
30
  rotated = ((seed << 1) | (seed >> 31)) & 0xffffffff
31
- app_name = NewRelic::Agent.config.app_names.first
31
+ app_name = NewRelic::Agent.config[:app_name].first
32
32
  identifier = "#{app_name};#{txn_name}"
33
33
  sprintf("%08x", rotated ^ hash_transaction_name(identifier))
34
34
  end
@@ -0,0 +1,125 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ require 'json'
6
+ require 'new_relic/agent/hostname'
7
+
8
+ module NewRelic
9
+ module Agent
10
+ module Logging
11
+
12
+ # This class can be used as the formatter for an existing logger. It
13
+ # decorates log messages with trace and entity metadata, and formats each
14
+ # log messages as a JSON object.
15
+ #
16
+ # It can be added to a Rails application like this:
17
+ #
18
+ # require 'newrelic_rpm'
19
+ #
20
+ # Rails.application.configure do
21
+ # config.log_formatter = ::NewRelic::Agent::Logging::DecoratingFormatter.new
22
+ # end
23
+ #
24
+ # @api public
25
+ class DecoratingFormatter < ::Logger::Formatter
26
+ TIMESTAMP_KEY = 'timestamp'.freeze
27
+ MESSAGE_KEY = 'message'.freeze
28
+ LOG_LEVEL_KEY = 'log.level'.freeze
29
+ LOG_NAME_KEY = 'logger.name'.freeze
30
+ NEWLINE = "\n".freeze
31
+
32
+ QUOTE = '"'.freeze
33
+ COLON = ':'.freeze
34
+ COMMA = ','.freeze
35
+ CLOSING_BRACE = '}'.freeze
36
+
37
+ def initialize
38
+ Agent.config.register_callback :app_name do
39
+ @app_name = nil
40
+ end
41
+ end
42
+
43
+ def call severity, time, progname, msg
44
+ message = '{'
45
+ if app_name
46
+ add_key_value message, ENTITY_NAME_KEY, app_name
47
+ message << COMMA
48
+ end
49
+ add_key_value message, ENTITY_TYPE_KEY, ENTITY_TYPE
50
+ message << COMMA
51
+ add_key_value message, HOSTNAME_KEY, Hostname.get
52
+
53
+ if entity_guid = Agent.config[:entity_guid]
54
+ message << COMMA
55
+ add_key_value message, ENTITY_GUID_KEY, entity_guid
56
+ end
57
+
58
+ if trace_id = Tracer.trace_id
59
+ message << COMMA
60
+ add_key_value message, TRACE_ID_KEY, trace_id
61
+ end
62
+ if span_id = Tracer.span_id
63
+ message << COMMA
64
+ add_key_value message, SPAN_ID_KEY, span_id
65
+ end
66
+
67
+ message << COMMA
68
+ message << QUOTE << MESSAGE_KEY << QUOTE << COLON << escape(msg)
69
+ message << COMMA
70
+ add_key_value message, LOG_LEVEL_KEY, severity
71
+ if progname
72
+ message << COMMA
73
+ add_key_value message, LOG_NAME_KEY, progname
74
+ end
75
+
76
+ message << COMMA
77
+ message << QUOTE << TIMESTAMP_KEY << QUOTE << COLON << time.to_f.to_s
78
+ message << CLOSING_BRACE << NEWLINE
79
+ end
80
+
81
+ def app_name
82
+ @app_name ||= Agent.config[:app_name][0]
83
+ end
84
+
85
+ def add_key_value message, key, value
86
+ message << QUOTE << key << QUOTE << COLON << QUOTE << value << QUOTE
87
+ end
88
+
89
+ def escape message
90
+ if String === message
91
+ message.to_json
92
+ else
93
+ message.inspect.to_json
94
+ end
95
+ end
96
+ end
97
+
98
+
99
+ # This logger decorates logs with trace and entity metadata, and emits log
100
+ # messages formatted as JSON objects. It extends the Logger class from
101
+ # the Ruby standard library, and accepts the same constructor parameters.
102
+ #
103
+ # It aliases the `:info` message to overwrite the `:write` method, so it
104
+ # can be used in Rack applications that expect the logger to be a file-like
105
+ # object.
106
+ #
107
+ # It can be added to an application like this:
108
+ #
109
+ # require 'newrelic_rpm'
110
+ #
111
+ # config.logger = NewRelic::Agent::Logging::DecoratingLogger.new "log/application.log"
112
+ #
113
+ # @api public
114
+ class DecoratingLogger < (defined?(::ActiveSupport) && defined?(::ActiveSupport::Logger) ? ::ActiveSupport::Logger : ::Logger)
115
+
116
+ alias :write :info
117
+
118
+ def initialize *args
119
+ super
120
+ self.formatter = DecoratingFormatter.new
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
@@ -39,6 +39,38 @@ module NewRelic
39
39
  state.current_transaction
40
40
  end
41
41
 
42
+ # Returns the trace_id of the current_transaction, or +nil+ if
43
+ # none exists.
44
+ #
45
+ # @api public
46
+ def current_trace_id
47
+ if txn = current_transaction
48
+ txn.trace_id
49
+ end
50
+ end
51
+ alias_method :trace_id, :current_trace_id
52
+
53
+ # Returns the id of the current span, or +nil+ if none exists.
54
+ #
55
+ # @api public
56
+ def current_span_id
57
+ if span = current_segment
58
+ span.guid
59
+ end
60
+ end
61
+ alias_method :span_id, :current_span_id
62
+
63
+ # Returns a boolean indicating whether the current_transaction
64
+ # is sampled, or +nil+ if there is no current transaction.
65
+ #
66
+ # @api public
67
+ def transaction_sampled?
68
+ if txn = current_transaction
69
+ txn.sampled?
70
+ end
71
+ end
72
+ alias_method :sampled?, :transaction_sampled?
73
+
42
74
  # Runs the given block of code in a transaction.
43
75
  #
44
76
  # @param [String] name reserved for New Relic internal use
@@ -39,7 +39,7 @@ class NewRelic::Cli::Deployments < NewRelic::Cli::Command
39
39
  control.env = @environment if @environment
40
40
 
41
41
  load_yaml_from_env(control.env)
42
- @appname ||= NewRelic::Agent.config.app_names[0] || control.env || 'development'
42
+ @appname ||= NewRelic::Agent.config[:app_name][0] || control.env || 'development'
43
43
  @license_key ||= NewRelic::Agent.config[:license_key]
44
44
 
45
45
  setup_logging(control.env)
@@ -11,7 +11,7 @@ module NewRelic
11
11
  end
12
12
 
13
13
  MAJOR = 6
14
- MINOR = 6
14
+ MINOR = 7
15
15
  TINY = 0
16
16
 
17
17
  begin
@@ -31,6 +31,13 @@ EOS
31
31
  "newrelic.yml"
32
32
  ]
33
33
 
34
+ s.metadata = {
35
+ 'bug_tracker_uri' => 'https://support.newrelic.com/',
36
+ 'changelog_uri' => 'https://github.com/newrelic/rpm/blob/master/CHANGELOG.md',
37
+ 'documentation_uri' => 'https://docs.newrelic.com/docs/agents/ruby-agent',
38
+ 'source_code_uri' => 'https://github.com/newrelic/rpm'
39
+ }
40
+
34
41
  file_list = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/(?!agent_helper.rb)}) }
35
42
  build_file_path = 'lib/new_relic/build.rb'
36
43
  file_list << build_file_path if File.exist?(build_file_path)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newrelic_rpm
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.6.0.358
4
+ version: 6.7.0.359
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Wear
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2019-08-29 00:00:00.000000000 Z
14
+ date: 2019-09-25 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rake
@@ -297,6 +297,7 @@ files:
297
297
  - lib/new_relic/agent/internal_agent_error.rb
298
298
  - lib/new_relic/agent/javascript_instrumentor.rb
299
299
  - lib/new_relic/agent/log_once.rb
300
+ - lib/new_relic/agent/logging.rb
300
301
  - lib/new_relic/agent/memory_logger.rb
301
302
  - lib/new_relic/agent/messaging.rb
302
303
  - lib/new_relic/agent/method_tracer.rb
@@ -441,7 +442,11 @@ files:
441
442
  homepage: https://github.com/newrelic/rpm
442
443
  licenses:
443
444
  - New Relic
444
- metadata: {}
445
+ metadata:
446
+ bug_tracker_uri: https://support.newrelic.com/
447
+ changelog_uri: https://github.com/newrelic/rpm/blob/master/CHANGELOG.md
448
+ documentation_uri: https://docs.newrelic.com/docs/agents/ruby-agent
449
+ source_code_uri: https://github.com/newrelic/rpm
445
450
  post_install_message:
446
451
  rdoc_options: []
447
452
  require_paths: