Class: AppMap::DetectEnabled

Inherits:
Object
  • Object
show all
Defined in:
lib/appmap/detect_enabled.rb

Overview

Detects whether AppMap recording should be enabled. This test can be performed generally, or for a particular recording method. Recording can be enabled explicitly, for example via APPMAP=true, or it can be enabled implicitly, by running in a dev or test web application environment. Recording can also disabled explicitly, using environment variables.

Constant Summary collapse

@@detected_for_method =
{}

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(recording_method) ⇒ DetectEnabled



45
46
47
# File 'lib/appmap/detect_enabled.rb', line 45

def initialize(recording_method)
  @recording_method = recording_method
end

Class Method Details

.clear_cacheObject



40
41
42
# File 'lib/appmap/detect_enabled.rb', line 40

def clear_cache
  @@detected_for_method = {}
end

.discourage_conflicting_recording_methods(recording_method) ⇒ Object

rubocop:disable Metrics/MethodLength



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/appmap/detect_enabled.rb', line 13

def discourage_conflicting_recording_methods(recording_method)
  return if ENV["APPMAP_DISCOURAGE_CONFLICTING_RECORDING_METHODS"] == "false"

  return unless enabled?(recording_method.to_sym) && enabled?(:requests)

  warn Util.color "    AppMap recording is enabled for both 'requests' and '\#{recording_method}'. This is not recommended\n    because the recordings will contain duplicitive information, and in some case may conflict with each other.\n  MSG\n\n  return unless ENV[\"APPMAP\"] == \"true\"\n\n  warn Util.color <<~MSG, :yellow\n    The environment contains APPMAP=true, which is not recommended in this application environment because\n    it enables all recording methods. Consider letting AppMap detect the appropriate recording method,\n    or explicitly enabling only the recording methods you want to use using environment variables like\n    APPMAP_RECORD_REQUESTS, APPMAP_RECORD_RSPEC, etc.\n    \n    See https://appmap.io/docs/reference/appmap-ruby.html#advanced-runtime-options for more information.\n  MSG\nend\n", :yellow

.enabled?(recording_method) ⇒ Boolean

rubocop:enable Metrics/MethodLength



36
37
38
# File 'lib/appmap/detect_enabled.rb', line 36

def enabled?(recording_method)
  new(recording_method).enabled?
end

Instance Method Details

#detect_app_envObject



102
103
104
105
106
107
108
# File 'lib/appmap/detect_enabled.rb', line 102

def detect_app_env
  if rails_env
    ["RAILS_ENV", rails_env]
  elsif ENV["APP_ENV"]
    ["APP_ENV", ENV["APP_ENV"]]
  end
end

#detect_enabledObject



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/appmap/detect_enabled.rb', line 69

def detect_enabled
  detection_functions = i[
    globally_disabled?
    recording_method_disabled?
    enabled_by_testing?
    enabled_by_app_env?
    recording_method_enabled?
    globally_enabled?
  ]

  message, enabled = []
  message, enabled = method(detection_functions.shift).call while enabled.nil? && !detection_functions.empty?

  return ["it is not enabled by any configuration or framework", false, false] if enabled.nil?

  _, enabled_by_env = enabled_by_app_env?
  [message, enabled, enabled_by_env]
end

#enabled?Boolean



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/appmap/detect_enabled.rb', line 49

def enabled?
  return @@detected_for_method[@recording_method] unless @@detected_for_method[@recording_method].nil?

  if @recording_method && !AppMap::RECORDING_METHODS.member?(@recording_method)
    raise "Unrecognized recording method: #{@recording_method}"
  end

  message, enabled, enabled_by_env = detect_enabled

  @@detected_for_method[@recording_method] = enabled

  if @recording_method && (enabled && enabled_by_app_env?)
    warn AppMap::Util.color(
      "AppMap #{@recording_method.nil? ? "" : "#{@recording_method} "}recording is enabled because #{message}", :magenta
    )
  end

  enabled
end

#enabled_by_app_env?Boolean



94
95
96
97
98
99
100
# File 'lib/appmap/detect_enabled.rb', line 94

def enabled_by_app_env?
  env_name, app_env = detect_app_env
  return ["#{env_name} is '#{app_env}'", true] if @recording_method.nil? && %w[test development].member?(app_env)

  return unless i[remote requests].member?(@recording_method)
  ["#{env_name} is '#{app_env}'", true] if app_env == "development"
end

#enabled_by_testing?Boolean



88
89
90
91
92
# File 'lib/appmap/detect_enabled.rb', line 88

def enabled_by_testing?
  return unless i[rspec minitest cucumber].member?(@recording_method)

  ["running tests with #{@recording_method}", true]
end

#globally_disabled?Boolean



117
118
119
# File 'lib/appmap/detect_enabled.rb', line 117

def globally_disabled?
  ["APPMAP=false", false] if ENV["APPMAP"] == "false"
end

#globally_enabled?Boolean



110
111
112
113
114
115
# File 'lib/appmap/detect_enabled.rb', line 110

def globally_enabled?
  # Don't auto-enable request recording in the 'test' environment, because users probably don't want
  # AppMaps of both test cases and requests. Requests recording can always be enabled by APPMAP_RECORD_REQUESTS=true.
  requests_recording_in_test = -> { [:requests].member?(@recording_method) && detect_app_env == "test" }
  ["APPMAP=true", true] if ENV["APPMAP"] == "true" && !requests_recording_in_test.call
end

#rails_envObject



135
136
137
138
139
# File 'lib/appmap/detect_enabled.rb', line 135

def rails_env
  return Rails.env if defined?(::Rails::Railtie)

  ENV.fetch("RAILS_ENV", nil)
end

#recording_method_disabled?Boolean



121
122
123
124
125
126
# File 'lib/appmap/detect_enabled.rb', line 121

def recording_method_disabled?
  return false unless @recording_method

  env_var = ["APPMAP", "RECORD", @recording_method.upcase].join("_")
  ["#{["APPMAP", "RECORD", @recording_method.upcase].join("_")}=false", false] if ENV[env_var] == "false"
end

#recording_method_enabled?Boolean



128
129
130
131
132
133
# File 'lib/appmap/detect_enabled.rb', line 128

def recording_method_enabled?
  return false unless @recording_method

  env_var = ["APPMAP", "RECORD", @recording_method.upcase].join("_")
  ["#{["APPMAP", "RECORD", @recording_method.upcase].join("_")}=true", true] if ENV[env_var] == "true"
end