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,
]
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)



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

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).



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

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

#application_nameObject



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

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

#background_job_integrationsObject



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

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



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

def database_engine
  framework_integration.database_engine
end

#envObject



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

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)


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

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

#frameworkObject



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

def framework
  framework_integration.name
end

#framework_integrationObject



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

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

#framework_rootObject



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

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



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

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

#hostnameObject



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

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)


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

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

#jruby?Boolean

Returns:

  • (Boolean)


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

def jruby?
  defined?(JRuby)
end

#osObject

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



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

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



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

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

#processorsObject



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

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



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

def raw_database_adapter
  framework_integration.raw_database_adapter
end

#rootObject



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

def root
  @root ||= framework_root
end

#rubinius?Boolean

ruby checks

Returns:

  • (Boolean)


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

def rubinius?
  RUBY_VERSION =~ /rubinius/i
end

#ruby_187?Boolean

Returns:

  • (Boolean)


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

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)


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

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)


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

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

#scm_subdirectoryObject



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

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)


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

def sinatra?
  framework_integration.name == :sinatra
end

#supports_module_prepend?Boolean

Returns true if this Ruby version supports Module#prepend.

Returns:

  • (Boolean)


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

def supports_module_prepend?
  ruby_2?
end