Module: NewRelic::Agent::Hostname

Defined in:
lib/new_relic/agent/hostname.rb

Constant Summary collapse

CLOUD_RUN_REVISION =
'K_REVISION'
GCP_INSTANCE_ID_URI =
'http://metadata.google.internal/computeMetadata/v1/instance/id'
GCP_METADATA_HEADERS =
{'Metadata-Flavor' => 'Google'}.freeze
LOCALHOST =
%w[
  localhost
  0.0.0.0
  127.0.0.1
  0:0:0:0:0:0:0:1
  0:0:0:0:0:0:0:0
  ::1
  ::
].freeze

Class Method Summary collapse

Class Method Details

.gcp_cloud_run?Boolean

Returns:

  • (Boolean)


28
29
30
31
# File 'lib/new_relic/agent/hostname.rb', line 28

def self.gcp_cloud_run?
  ENV.key?(CLOUD_RUN_REVISION) &&
    ::NewRelic::Agent.config[:'utilization.gcp_cloud_run.use_instance_as_host']
end

.gcp_cloud_run_hostObject



33
34
35
36
37
38
39
40
41
42
# File 'lib/new_relic/agent/hostname.rb', line 33

def self.gcp_cloud_run_host
  instance_id = gcp_instance_id
  return Socket.gethostname.force_encoding(Encoding::UTF_8) unless instance_id

  if ::NewRelic::Agent.config[:'utilization.gcp_cloud_run.include_revision_in_host']
    "#{ENV[CLOUD_RUN_REVISION]}-#{instance_id}"
  else
    instance_id
  end
end

.gcp_instance_idObject



44
45
46
47
48
49
50
51
52
53
# File 'lib/new_relic/agent/hostname.rb', line 44

def self.gcp_instance_id
  response = NewRelic::Helper.(GCP_INSTANCE_ID_URI, GCP_METADATA_HEADERS)
  return unless response&.code == '200'

  id = response.body.to_s.strip
  id.empty? ? nil : id
rescue => e
  NewRelic::Agent.logger.debug("Unable to fetch GCP Cloud Run instance id: #{e.class} - #{e.message}")
  nil
end

.getObject



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/new_relic/agent/hostname.rb', line 15

def self.get
  dyno_name = ENV['DYNO']
  @hostname ||= if dyno_name && ::NewRelic::Agent.config[:'heroku.use_dyno_names']
    matching_prefix = heroku_dyno_name_prefix(dyno_name)
    dyno_name = "#{matching_prefix}.*" if matching_prefix
    dyno_name
  elsif gcp_cloud_run?
    gcp_cloud_run_host
  else
    Socket.gethostname.force_encoding(Encoding::UTF_8)
  end
end

.get_dyno_prefixesObject



79
80
81
# File 'lib/new_relic/agent/hostname.rb', line 79

def self.get_dyno_prefixes
  ::NewRelic::Agent.config[:'heroku.dyno_name_prefixes_to_shorten']
end

.get_external(host_or_ip) ⇒ Object



97
98
99
# File 'lib/new_relic/agent/hostname.rb', line 97

def self.get_external(host_or_ip)
  local?(host_or_ip) ? get : host_or_ip
end

.get_fqdnObject

Pass '-f' to the external executable 'hostname' to request the fully qualified domain name (fqdn). For implementations of 'hostname' that do not support '-f' (such as the one OpenBSD ships with), fall back to calling 'hostname' without the '-f'. If both ways of calling 'hostname' fail, or in a context where 'hostname' is not even available (within an AWS Lambda function, for example), call the 'get' method which uses Socket instead of an external executable.



62
63
64
65
66
67
68
69
70
71
# File 'lib/new_relic/agent/hostname.rb', line 62

def self.get_fqdn
  begin
    NewRelic::Helper.run_command('hostname -f')
  rescue NewRelic::CommandRunFailedError
    NewRelic::Helper.run_command('hostname')
  end
rescue NewRelic::CommandExecutableNotFoundError, NewRelic::CommandRunFailedError => e
  NewRelic::Agent.logger.debug("#{e.class} - #{e.message}")
  get
end

.heroku_dyno_name_prefix(dyno_name) ⇒ Object



73
74
75
76
77
# File 'lib/new_relic/agent/hostname.rb', line 73

def self.heroku_dyno_name_prefix(dyno_name)
  get_dyno_prefixes.find do |dyno_prefix|
    dyno_name.start_with?(dyno_prefix + '.')
  end
end

.local?(host_or_ip) ⇒ Boolean

Returns:

  • (Boolean)


93
94
95
# File 'lib/new_relic/agent/hostname.rb', line 93

def self.local?(host_or_ip)
  LOCALHOST.include?(host_or_ip)
end