Module: NewRelicYML

Defined in:
lib/tasks/helpers/newrelicyml.rb

Constant Summary collapse

CRITICAL =
[:'agent_enabled', :'app_name', :'license_key', :'log_level']
DEFAULTS =
NewRelic::Agent::Configuration::DEFAULTS
SKIP =

Skip because not configurable via yml

[:'defer_rails_initialization']
PROCS =

Don’t evaluate Procs, instead use set values

{:'config_path' => 'newrelic.yml',
:'process_host.display_name' => 'default hostname',
:'transaction_tracer.transaction_threshold' => 1.0}
HEADER =
"#\n# This file configures the New Relic agent.  New Relic monitors Ruby, Java,\n# .NET, PHP, Python, Node, and Go applications with deep visibility and low\n# overhead.  For more information, visit www.newrelic.com.\n\n# Generated <%= Time.now.strftime('%B %d, %Y') %><%= \", for version \\\#{@agent_version}\" if @agent_version %>\n#<%= \"\\\\n# \\\#{generated_for_user}\\\\n#\" if generated_for_user %>\n# For full documentation of agent configuration options, please refer to\n# https://docs.newrelic.com/docs/agents/ruby-agent/installation-configuration/ruby-agent-configuration\n\ncommon: &default_settings\n  # Required license key associated with your New Relic account.\n  license_key: <%= license_key %>\n\n  # Your application name. Renaming here affects where data displays in New\n  # Relic. For more details, see https://docs.newrelic.com/docs/apm/new-relic-apm/maintenance/renaming-applications\n  app_name: <%= app_name %>\n\n  # To disable the agent regardless of other settings, uncomment the following:\n  # agent_enabled: false\n\n  # Logging level for log/newrelic_agent.log; options are error, warn, info, or\n  # debug.\n  log_level: info\n\n  # All of the following configuration options are optional. Review them, and\n  # uncomment or edit them if they appear relevant to your application needs.\n\n"
SECURITY_BEGIN =
"# BEGIN security agent\n#\n#   NOTE: At this time, the security agent is intended for use only within\n#         a dedicated security testing environment with data that can tolerate\n#         modification or deletion. The security agent is available as a\n#         separate Ruby gem, newrelic_security. It is recommended that this\n#         separate gem only be introduced to a security testing environment\n#         by leveraging Bundler grouping like so:\n#\n#         # Gemfile\n#         gem 'newrelic_rpm'               # New Relic APM observability agent\n#         gem 'newrelic-infinite_tracing'  # New Relic Infinite Tracing\n#\n#         group :security do\n#           gem 'newrelic_security', require: false # New Relic security agent\n#         end\n#\n#   NOTE: All \"security.*\" configuration parameters are related only to the\n#         security agent, and all other configuration parameters that may\n#         have \"security\" in the name somewhere are related to the APM agent.\n\n"
SECURITY_END =
"# END security agent\n"
"# Environment-specific settings are in this section.\n# RAILS_ENV or RACK_ENV (as appropriate) is used to determine the environment.\n# If your application has other named environments, configure them here.\ndevelopment:\n  <<: *default_settings\n  app_name: <%= app_name %> (Development)\n\ntest:\n  <<: *default_settings\n  # It doesn't make sense to report to New Relic from automated test runs.\n  monitor_mode: false\n\nstaging:\n  <<: *default_settings\n  app_name: <%= app_name %> (Staging)\n\nproduction:\n  <<: *default_settings\n"

Class Method Summary collapse

Class Method Details

.agent_configs_yml(agent_configs) ⇒ Object



180
181
182
183
184
185
186
187
# File 'lib/tasks/helpers/newrelicyml.rb', line 180

def self.agent_configs_yml(agent_configs)
  agent_yml = ''
  agent_configs.each do |key, value|
    agent_yml += "#{value[:description]}\n  # #{key}: #{value[:default]}\n\n"
  end

  agent_yml
end

.build_config(key, value) ⇒ Object



121
122
123
124
125
126
127
# File 'lib/tasks/helpers/newrelicyml.rb', line 121

def self.build_config(key, value)
  sanitized_description = sanitize_description(value[:description])
  description = format_description(sanitized_description)
  default = default_value(key, value)

  [description, default]
end

.build_string(defaults) ⇒ Object



198
199
200
201
202
203
204
# File 'lib/tasks/helpers/newrelicyml.rb', line 198

def self.build_string(defaults)
  agent_configs, security_configs = get_configs(defaults)
  agent_string = agent_configs_yml(agent_configs)
  security_string = security_configs_yml(security_configs)

  agent_string + SECURITY_BEGIN + security_string + SECURITY_END + "\n"
end

.default_value(key, config_hash) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
# File 'lib/tasks/helpers/newrelicyml.rb', line 168

def self.default_value(key, config_hash)
  if PROCS.include?(key)
    PROCS[key]
  else
    default = config_hash[:documentation_default].nil? ? config_hash[:default] : config_hash[:documentation_default]
    default = 'nil' if default.nil?
    default = '""' if default == ''

    default
  end
end

.deprecated?(value) ⇒ Boolean

Returns:

  • (Boolean)


133
134
135
# File 'lib/tasks/helpers/newrelicyml.rb', line 133

def self.deprecated?(value)
  value[:deprecated] == true
end

.format_description(description) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/tasks/helpers/newrelicyml.rb', line 154

def self.format_description(description)
  # remove all tab characters
  description.delete!("\t")
  # remove leading and trailing whitespace
  description.strip!
  # wrap text after 80 characters, assuming we're at one tabstop's (two
  # spaces') level of indentation already, keep leading whitespace
  description.gsub!(/(.{1,78})(\s|\Z)/, "\\1\n")
  # add hashtags to lines
  description = description.split("\n").map { |line| "  # #{line}" }.join("\n")

  description
end

.get_configs(defaults) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/tasks/helpers/newrelicyml.rb', line 97

def self.get_configs(defaults)
  agent_configs = {}
  security_configs = {}

  defaults.sort.each do |key, value|
    next if CRITICAL.include?(key) || SKIP.include?(key)

    next unless public_config?(value) && !deprecated?(value)

    # TODO: OLD RUBIES < 2.6
    # Remove `to_s`. `start_with?` doesn't accept symbols in Ruby <2.6
    if key.to_s.start_with?('security.')
      description, default = build_config(key, value)
      security_configs[key] = {description: description, default: default}
      next
    end

    description, default = build_config(key, value)
    agent_configs[key] = {description: description, default: default}
  end

  [agent_configs, security_configs]
end

.public_config?(value) ⇒ Boolean

Returns:

  • (Boolean)


129
130
131
# File 'lib/tasks/helpers/newrelicyml.rb', line 129

def self.public_config?(value)
  value[:public] == true
end

.sanitize_description(description) ⇒ Object



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/tasks/helpers/newrelicyml.rb', line 137

def self.sanitize_description(description)
  # remove callouts
  description = description.split("\n").reject { |line| line.match?('</?Callout') }.join("\n")
  # remove InlinePopover, keep the text inside type
  description.gsub!(/<InlinePopover type="(.*)" \/>/, '\1')
  # remove hyperlinks
  description.gsub!(/\[([^\]]+)\]\([^\)]+\)/, '\1')
  # delete lines with code fences including the language
  description.gsub!(/```[a-zA-Z0-9_]*\n(.*?)```/m, '\1')
  # remove single pairs of backticks
  description.gsub!(/`([^`]+)`/, '\1')
  # removed href links
  description.gsub!(/<a href="(.*)">(.*)<\/a>/, '\2')

  description
end

.security_configs_yml(security_configs) ⇒ Object



189
190
191
192
193
194
195
196
# File 'lib/tasks/helpers/newrelicyml.rb', line 189

def self.security_configs_yml(security_configs)
  security_yml = ''
  security_configs.each do |key, value|
    security_yml += "#{value[:description]}\n  # #{key}: #{value[:default]}\n\n"
  end

  security_yml
end

.write_file(defaults = DEFAULTS) ⇒ Object

:nocov:



207
208
209
# File 'lib/tasks/helpers/newrelicyml.rb', line 207

def self.write_file(defaults = DEFAULTS)
  File.write('newrelic.yml', HEADER + build_string(defaults) + FOOTER)
end