Class: ScoutApm::Environment

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/scout_apm/environment.rb

Constant Summary collapse

STDOUT_LOGGER =
begin
  l = Logger.new(STDOUT)
  l.level = Logger::INFO
  l
end
SERVER_INTEGRATIONS =

I’ve put Thin and Webrick last as they are often used in development and included in Gemfiles but less likely used in production.

[
  ScoutApm::ServerIntegrations::Passenger.new(STDOUT_LOGGER),
  ScoutApm::ServerIntegrations::Unicorn.new(STDOUT_LOGGER),
  ScoutApm::ServerIntegrations::Rainbows.new(STDOUT_LOGGER),
  ScoutApm::ServerIntegrations::Puma.new(STDOUT_LOGGER),
  ScoutApm::ServerIntegrations::Thin.new(STDOUT_LOGGER),
  ScoutApm::ServerIntegrations::Webrick.new(STDOUT_LOGGER),
  ScoutApm::ServerIntegrations::Null.new(STDOUT_LOGGER), # must be last
]
BACKGROUND_JOB_INTEGRATIONS =
[
  ScoutApm::BackgroundJobIntegrations::Resque.new,
  ScoutApm::BackgroundJobIntegrations::Sidekiq.new,
  ScoutApm::BackgroundJobIntegrations::Shoryuken.new,
  ScoutApm::BackgroundJobIntegrations::Sneakers.new,
  ScoutApm::BackgroundJobIntegrations::DelayedJob.new,
  ScoutApm::BackgroundJobIntegrations::Que.new,
]
FRAMEWORK_INTEGRATIONS =
[
  ScoutApm::FrameworkIntegrations::Rails2.new,
  ScoutApm::FrameworkIntegrations::Rails3Or4.new,
  ScoutApm::FrameworkIntegrations::Sinatra.new,
  ScoutApm::FrameworkIntegrations::Ruby.new, # Fallback if none match
]
PLATFORM_INTEGRATIONS =
[
  ScoutApm::PlatformIntegrations::Heroku.new,
  ScoutApm::PlatformIntegrations::CloudFoundry.new,
  ScoutApm::PlatformIntegrations::Server.new,
]

Instance Method Summary collapse

Instance Method Details

#app_serverObject

App server’s name (symbol)



137
138
139
# File 'lib/scout_apm/environment.rb', line 137

def app_server
  app_server_integration.name
end

#app_server_integration(force = false) ⇒ Object

Returns the whole integration object This needs to be improved. Frequently, multiple app servers gem are present and which ever is checked first becomes the designated app server.

Next step: (1) list out all detected app servers (2) install hooks for those that need it (passenger, rainbows, unicorn).



131
132
133
134
# File 'lib/scout_apm/environment.rb', line 131

def app_server_integration(force=false)
  @app_server = nil if force
  @app_server ||= SERVER_INTEGRATIONS.detect{ |integration| integration.present? }
end

#application_nameObject



64
65
66
67
68
# File 'lib/scout_apm/environment.rb', line 64

def application_name
  Agent.instance.context.config.value("name") ||
    framework_integration.application_name ||
    "App"
end

#background_job_integrationsObject



147
148
149
150
151
152
153
# File 'lib/scout_apm/environment.rb', line 147

def background_job_integrations
  if Agent.instance.context.config.value("enable_background_jobs")
    @background_job_integrations ||= BACKGROUND_JOB_INTEGRATIONS.select {|integration| integration.present?}
  else
    []
  end
end

#database_engineObject



70
71
72
# File 'lib/scout_apm/environment.rb', line 70

def database_engine
  framework_integration.database_engine
end

#envObject



48
49
50
# File 'lib/scout_apm/environment.rb', line 48

def env
  @env ||= framework_integration.env
end

#forking?Boolean

If forking, don’t start worker thread in the master process. Since it’s started as a Thread, it won’t survive the fork.

Returns:

  • (Boolean)


143
144
145
# File 'lib/scout_apm/environment.rb', line 143

def forking?
  app_server_integration.forking? || (background_job_integration && background_job_integration.forking?)
end

#frameworkObject



52
53
54
# File 'lib/scout_apm/environment.rb', line 52

def framework
  framework_integration.name
end

#framework_integrationObject



56
57
58
# File 'lib/scout_apm/environment.rb', line 56

def framework_integration
  @framework ||= FRAMEWORK_INTEGRATIONS.detect{ |integration| integration.present? }
end

#framework_rootObject



103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/scout_apm/environment.rb', line 103

def framework_root
  if override_root = Agent.instance.context.config.value("application_root")
    return override_root
  end
  if framework == :rails
    RAILS_ROOT.to_s
  elsif framework == :rails3_or_4
    Rails.root
  elsif framework == :sinatra
    Sinatra::Application.root || "."
  else
    '.'
  end
end

#git_revisionObject



122
123
124
# File 'lib/scout_apm/environment.rb', line 122

def git_revision
  @git_revision ||= ScoutApm::GitRevision.new(Agent.instance.context)
end

#hostnameObject



118
119
120
# File 'lib/scout_apm/environment.rb', line 118

def hostname
  @hostname ||= Agent.instance.context.config.value("hostname") || platform_integration.hostname
end

#interactive?Boolean

If both stdin & stdout are interactive and the Rails::Console constant is defined

Returns:

  • (Boolean)


156
157
158
# File 'lib/scout_apm/environment.rb', line 156

def interactive?
  defined?(::Rails::Console) && $stdout.isatty && $stdin.isatty
end

#jruby?Boolean

Returns:

  • (Boolean)


166
167
168
# File 'lib/scout_apm/environment.rb', line 166

def jruby?
  defined?(JRuby)
end

#osObject

Returns a string representation of the OS (ex: darwin, linux)



191
192
193
194
195
196
197
198
199
200
# File 'lib/scout_apm/environment.rb', line 191

def os
  return @os if @os
  raw_os = RbConfig::CONFIG['target_os']
  match = raw_os.match(/([a-z]+)/)
  if match
    @os = match[1]
  else
    @os = raw_os
  end
end

#platform_integrationObject



60
61
62
# File 'lib/scout_apm/environment.rb', line 60

def platform_integration
  @platform ||= PLATFORM_INTEGRATIONS.detect{ |integration| integration.present? }
end

#processorsObject



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/scout_apm/environment.rb', line 78

def processors
  @processors ||= begin
                    proc_file = '/proc/cpuinfo'
                    processors = if !File.exist?(proc_file)
                                   1
                                 else
                                   lines = File.read("/proc/cpuinfo").lines.to_a
                                   lines.grep(/^processor\s*:/i).size
                                 end
                    [processors, 1].compact.max
                  end
end

#raw_database_adapterObject



74
75
76
# File 'lib/scout_apm/environment.rb', line 74

def raw_database_adapter
  framework_integration.raw_database_adapter
end

#rootObject



99
100
101
# File 'lib/scout_apm/environment.rb', line 99

def root
  @root ||= framework_root
end

#rubinius?Boolean

ruby checks

Returns:

  • (Boolean)


162
163
164
# File 'lib/scout_apm/environment.rb', line 162

def rubinius?
  RUBY_VERSION =~ /rubinius/i
end

#ruby_187?Boolean

Returns:

  • (Boolean)


175
176
177
178
# File 'lib/scout_apm/environment.rb', line 175

def ruby_187?
  return @ruby_187 if defined?(@ruby_187)
  @ruby_187 = defined?(RUBY_VERSION) && RUBY_VERSION.match(/^1\.8\.7/)
end

#ruby_19?Boolean

Returns:

  • (Boolean)


170
171
172
173
# File 'lib/scout_apm/environment.rb', line 170

def ruby_19?
  return @ruby_19 if defined?(@ruby_19)
  @ruby_19 = defined?(RUBY_ENGINE) && RUBY_ENGINE == "ruby" && RUBY_VERSION.match(/^1\.9/)
end

#ruby_2?Boolean

Returns:

  • (Boolean)


180
181
182
183
# File 'lib/scout_apm/environment.rb', line 180

def ruby_2?
  return @ruby_2 if defined?(@ruby_2)
  @ruby_2 = defined?(RUBY_VERSION) && RUBY_VERSION.match(/^2/)
end

#scm_subdirectoryObject



91
92
93
94
95
96
97
# File 'lib/scout_apm/environment.rb', line 91

def scm_subdirectory
  @scm_subdirectory ||= if Agent.instance.context.config.value('scm_subdirectory').empty?
    ''
  else
    Agent.instance.context.config.value('scm_subdirectory').sub(/^\//, '') # Trim any leading slash
  end
end

#sinatra?Boolean

framework checks

Returns:

  • (Boolean)


204
205
206
# File 'lib/scout_apm/environment.rb', line 204

def sinatra?
  framework_integration.name == :sinatra
end

#supports_module_prepend?Boolean

Returns true if this Ruby version supports Module#prepend.

Returns:

  • (Boolean)


186
187
188
# File 'lib/scout_apm/environment.rb', line 186

def supports_module_prepend?
  ruby_2?
end