sqreen 1.18.2-java → 1.18.3-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/LICENSE +3 -0
  4. data/lib/sqreen/actions.rb +11 -337
  5. data/lib/sqreen/actions/base.rb +110 -0
  6. data/lib/sqreen/actions/block_ip.rb +32 -0
  7. data/lib/sqreen/actions/block_user.rb +44 -0
  8. data/lib/sqreen/actions/ip_range_indexed_action_class.rb +36 -0
  9. data/lib/sqreen/actions/ip_ranges_index.rb +36 -0
  10. data/lib/sqreen/actions/redirect_ip.rb +40 -0
  11. data/lib/sqreen/actions/redirect_user.rb +45 -0
  12. data/lib/sqreen/actions/repository.rb +24 -0
  13. data/lib/sqreen/actions/unknown_action_type.rb +16 -0
  14. data/lib/sqreen/actions/user_action_class.rb +41 -0
  15. data/lib/sqreen/agent.rb +4 -1
  16. data/lib/sqreen/attack_blocked.rb +17 -0
  17. data/lib/sqreen/binding_accessor.rb +9 -102
  18. data/lib/sqreen/binding_accessor/path_elem.rb +8 -0
  19. data/lib/sqreen/binding_accessor/transforms.rb +107 -0
  20. data/lib/sqreen/capped_queue.rb +2 -0
  21. data/lib/sqreen/{callbacks.rb → cb.rb} +1 -53
  22. data/lib/sqreen/{callback_tree.rb → cb_tree.rb} +2 -2
  23. data/lib/sqreen/condition_evaluator.rb +22 -5
  24. data/lib/sqreen/configuration.rb +5 -0
  25. data/lib/sqreen/default_cb.rb +20 -0
  26. data/lib/sqreen/deferred_logger.rb +63 -0
  27. data/lib/sqreen/deliveries.rb +10 -0
  28. data/lib/sqreen/deliveries/batch.rb +7 -1
  29. data/lib/sqreen/deliveries/simple.rb +5 -0
  30. data/lib/sqreen/dependency/detector.rb +1 -1
  31. data/lib/sqreen/dependency/libsqreen.rb +28 -0
  32. data/lib/sqreen/dependency/rails.rb +4 -0
  33. data/lib/sqreen/dependency/sinatra.rb +47 -14
  34. data/lib/sqreen/error_handling_middleware.rb +30 -0
  35. data/lib/sqreen/event.rb +2 -0
  36. data/lib/sqreen/events/attack.rb +2 -0
  37. data/lib/sqreen/events/request_record.rb +11 -56
  38. data/lib/sqreen/exception.rb +9 -40
  39. data/lib/sqreen/formatter_with_tid.rb +45 -0
  40. data/lib/sqreen/framework_cb.rb +28 -0
  41. data/lib/sqreen/frameworks.rb +7 -0
  42. data/lib/sqreen/frameworks/generic.rb +20 -2
  43. data/lib/sqreen/frameworks/rails.rb +2 -0
  44. data/lib/sqreen/frameworks/request_recorder.rb +3 -0
  45. data/lib/sqreen/frameworks/sinatra.rb +2 -0
  46. data/lib/sqreen/frameworks/sqreen_test.rb +2 -0
  47. data/lib/sqreen/instrumentation.rb +5 -5
  48. data/lib/sqreen/invalid_signature_exception.rb +8 -0
  49. data/lib/{sqreen-alt.rb → sqreen/js.rb} +6 -1
  50. data/lib/sqreen/js/call_context.rb +10 -0
  51. data/lib/sqreen/js/context_pool.rb +60 -0
  52. data/lib/sqreen/js/exec_js_runnable.rb +20 -0
  53. data/lib/sqreen/js/execjs_adapter.rb +6 -47
  54. data/lib/sqreen/js/executable_js.rb +12 -0
  55. data/lib/sqreen/js/js_service.rb +2 -22
  56. data/lib/sqreen/js/js_service_adapter.rb +18 -0
  57. data/lib/sqreen/js/mini_racer_adapter.rb +6 -180
  58. data/lib/sqreen/js/mini_racer_executable_js.rb +142 -0
  59. data/lib/sqreen/js/thread_local_exec_js_runnable.rb +47 -0
  60. data/lib/sqreen/log.rb +8 -188
  61. data/lib/sqreen/logger.rb +83 -0
  62. data/lib/sqreen/metrics_store.rb +3 -11
  63. data/lib/sqreen/metrics_store/already_registered_metric.rb +11 -0
  64. data/lib/sqreen/metrics_store/unknown_metric.rb +11 -0
  65. data/lib/sqreen/metrics_store/unregistered_metric.rb +11 -0
  66. data/lib/sqreen/middleware.rb +0 -34
  67. data/lib/sqreen/mono_time.rb +2 -0
  68. data/lib/sqreen/node.rb +44 -0
  69. data/lib/sqreen/not_implemented_yet.rb +8 -0
  70. data/lib/sqreen/null_logger.rb +24 -0
  71. data/lib/sqreen/payload_creator.rb +2 -19
  72. data/lib/sqreen/payload_creator/header_section.rb +28 -0
  73. data/lib/sqreen/prefix.rb +33 -0
  74. data/lib/sqreen/rails_middleware.rb +14 -0
  75. data/lib/sqreen/remote_command.rb +1 -8
  76. data/lib/sqreen/remote_command/failure_output.rb +11 -0
  77. data/lib/sqreen/rules.rb +32 -2
  78. data/lib/sqreen/{rule_attributes.rb → rules/attrs.rb} +0 -0
  79. data/lib/sqreen/{rules_callbacks/sdk_auth_track.rb → rules/auth_track_cb.rb} +2 -2
  80. data/lib/sqreen/{rules_callbacks/binding_accessor_matcher.rb → rules/binding_accessor_matcher_cb.rb} +4 -8
  81. data/lib/sqreen/{rules_callbacks → rules}/binding_accessor_metrics.rb +1 -1
  82. data/lib/sqreen/{rules_callbacks/blacklist_ips.rb → rules/blacklist_ips_cb.rb} +3 -2
  83. data/lib/sqreen/{rules_callbacks → rules}/count_http_codes.rb +2 -2
  84. data/lib/sqreen/{rules_callbacks/crawler_user_agent_matches.rb → rules/crawler_user_agent_matches_cb.rb} +1 -1
  85. data/lib/sqreen/{rules_callbacks/crawler_user_agent_matches_metrics.rb → rules/crawler_user_agent_matches_metrics_cb.rb} +1 -1
  86. data/lib/sqreen/{rules_callbacks/custom_error.rb → rules/custom_error_cb.rb} +1 -1
  87. data/lib/sqreen/{rules_callbacks/devise_auth_track.rb → rules/devise_auth_track_cb.rb} +2 -2
  88. data/lib/sqreen/{rules_callbacks/devise_signup_track.rb → rules/devise_signup_track_cb.rb} +2 -2
  89. data/lib/sqreen/{rules_callbacks/execjs.rb → rules/execjs_cb.rb} +49 -50
  90. data/lib/sqreen/{rules_callbacks/headers_insert.rb → rules/headers_insert_cb.rb} +1 -1
  91. data/lib/sqreen/{rules_callbacks → rules}/matcher_rule.rb +2 -2
  92. data/lib/sqreen/{rules_callbacks/not_found.rb → rules/not_found_cb.rb} +2 -2
  93. data/lib/sqreen/{rules_callbacks/rails_parameters.rb → rules/rails_parameters_cb.rb} +1 -1
  94. data/lib/sqreen/{rules_callbacks → rules}/record_request_context.rb +1 -1
  95. data/lib/sqreen/{rules_callbacks/regexp_rule.rb → rules/regexp_rule_cb.rb} +1 -1
  96. data/lib/sqreen/{rule_callback.rb → rules/rule_cb.rb} +2 -2
  97. data/lib/sqreen/{rules_callbacks → rules}/run_req_start_actions.rb +4 -2
  98. data/lib/sqreen/{rules_callbacks → rules}/run_user_actions.rb +1 -1
  99. data/lib/sqreen/{rules_callbacks/shell_env.rb → rules/shell_env_cb.rb} +1 -1
  100. data/lib/sqreen/{rules_callbacks/sdk_signup_track.rb → rules/signup_track_cb.rb} +2 -2
  101. data/lib/sqreen/rules/update_request_context.rb +20 -0
  102. data/lib/sqreen/{rules_callbacks/url_matches.rb → rules/url_matches_cb.rb} +1 -1
  103. data/lib/sqreen/{rules_callbacks/user_agent_matches.rb → rules/user_agent_matches_cb.rb} +1 -1
  104. data/lib/sqreen/{rules_callbacks/waf.rb → rules/waf_cb.rb} +10 -14
  105. data/lib/sqreen/{rules_callbacks/reflected_xss.rb → rules/xss_cb.rb} +10 -7
  106. data/lib/sqreen/run_when_called_cb.rb +21 -0
  107. data/lib/sqreen/runtime_infos.rb +2 -9
  108. data/lib/sqreen/sensitive_data_redactor.rb +111 -0
  109. data/lib/sqreen/signature_verifier.rb +20 -0
  110. data/lib/sqreen/sinatra_middleware.rb +14 -0
  111. data/lib/sqreen/{rules_signature.rb → sqreen_signed_verifier.rb} +5 -17
  112. data/lib/sqreen/token_invalid_exception.rb +8 -0
  113. data/lib/sqreen/token_not_found_exception.rb +9 -0
  114. data/lib/sqreen/trie.rb +3 -64
  115. data/lib/sqreen/unauthorized.rb +8 -0
  116. data/lib/sqreen/util.rb +2 -0
  117. data/lib/sqreen/util/capped_array.rb +33 -0
  118. data/lib/sqreen/util/capped_hash.rb +39 -0
  119. data/lib/sqreen/util/capped_string.rb +24 -0
  120. data/lib/sqreen/util/capper.rb +65 -0
  121. data/lib/sqreen/version.rb +1 -1
  122. data/lib/sqreen/waf_error.rb +18 -0
  123. metadata +87 -35
  124. data/lib/sqreen/rules_callbacks.rb +0 -35
  125. data/lib/sqreen/rules_callbacks/inspect_rule.rb +0 -25
@@ -0,0 +1,142 @@
1
+ # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
+ # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
+
4
+ # TODO: => Sqreen::JS:MiniRacer
5
+ # TODO: remove class vars
6
+
7
+ require 'sqreen/log'
8
+
9
+ module Sqreen
10
+ module Js
11
+ class MiniRacerExecutableJs < ExecutableJs
12
+ @@ctx_defined = false # rubocop:disable Style/ClassVars
13
+
14
+ def ctx_defined?
15
+ @@ctx_defined
16
+ end
17
+
18
+ def define_ctx!
19
+ @@ctx_defined = true # rubocop:disable Style/ClassVars
20
+ end
21
+
22
+ def initialize(pool, code, vendored)
23
+ @pool = pool
24
+ @code = code
25
+ @code_id = self.class.code_id(code)
26
+
27
+ @module = vendored ? Sqreen::MiniRacer : MiniRacer
28
+
29
+ mod = vendored ? Sqreen::MiniRacer : MiniRacer
30
+
31
+ return if ctx_defined?
32
+
33
+ self.class.define_sqreen_context(mod)
34
+ define_ctx!
35
+ end
36
+
37
+ def run_js_cb(cb_name, budget, arguments)
38
+ @pool.with_context do |ctx|
39
+ if ctx.code_failed?(@code_id)
40
+ Sqreen.log.debug do
41
+ "Skipping execution of callback #{cb_name} (code md5 #{@code_id})" \
42
+ " due to prev failure of definition evaluation"
43
+ end
44
+ return nil
45
+ end
46
+
47
+ ctx.add_code(@code_id, @code) unless ctx.code?(@code_id)
48
+
49
+ # mini_racer expects timeout to be in ms
50
+ ctx.timeout = budget ? budget * 1000.0 : nil
51
+ begin
52
+ ctx.call("sqreen_#{@code_id}_#{cb_name}", *arguments)
53
+ rescue @module::ScriptTerminatedError
54
+ Sqreen.log.debug "ScriptTerminatedError/#{cb_name}"
55
+ nil
56
+ end
57
+ end
58
+ end
59
+
60
+ def self.code_id(code)
61
+ Digest::MD5.hexdigest(code)
62
+ end
63
+
64
+ class << self
65
+ def define_sqreen_context(modoole)
66
+ # Context specialized for Sqreen usage
67
+ Sqreen::Js.const_set 'SqreenContext', Class.new(modoole.const_get('Context'))
68
+ SqreenContext.class_eval do
69
+ attr_accessor :gc_threshold_in_bytes
70
+ attr_accessor :gc_load
71
+ attr_writer :timeout
72
+
73
+ def code?(code_id)
74
+ return false unless @code_ids
75
+ @code_ids.include?(code_id)
76
+ end
77
+
78
+ def code_failed?(code_id)
79
+ return false unless @failed_code_ids
80
+ @failed_code_ids.include?(code_id)
81
+ end
82
+
83
+ def add_code(code_id, code)
84
+ # It's important that the definition is run in its own scope (by executing it inside an anonymous function)
85
+ # Otherwise some auxiliary functions that the backend server sends will collide the name
86
+ # Because they're defined with `var`, running the definitions inside a function is enough
87
+ eval_unsafe "(function() { #{code} })()"
88
+ transf_global_funcs code_id
89
+ @code_ids ||= Set.new
90
+ @code_ids << code_id
91
+ rescue StandardError
92
+ @failed_code_ids ||= Set.new
93
+ @failed_code_ids << code_id
94
+ raise
95
+ end
96
+
97
+ def eval_unsafe(str, filename = nil, timeoutv = nil)
98
+ # Beware, timeout could be kept in the context
99
+ # if perf cap is removed after having been activated
100
+ # As it's unused by execjscb we are not cleaning it
101
+ return super(str, filename) if timeoutv.nil?
102
+ return if timeoutv <= 0.0
103
+ timeoutv *= 1000 # Timeout are currently expressed in seconds
104
+ @timeout = timeoutv
105
+ @eval_thread = Thread.current
106
+ timeout do
107
+ super(str, filename)
108
+ end
109
+ end
110
+
111
+ def possibly_gc
112
+ @gc_threshold_in_bytes ||= DEFAULT_GC_THRESHOLD
113
+ @gc_load ||= 0
114
+
115
+ # garbage collections max 1 in every 4 calls (avg)
116
+ if heap_stats[:total_heap_size] > @gc_threshold_in_bytes
117
+ low_memory_notification
118
+ @gc_load += 4
119
+ else
120
+ @gc_load = [0, @gc_load - 1].max
121
+ end
122
+ end
123
+
124
+ private
125
+
126
+ def transf_global_funcs(code_id)
127
+ # Multiple callbacks may share the same name. In order to avoid collisions, we rename them here.
128
+ eval_unsafe <<-JS
129
+ Object.keys(this).forEach(name => {
130
+ if (typeof this[name] === "function" && !name.startsWith("sqreen_")) {
131
+ this['sqreen_#{code_id}_' + name] = this[name];
132
+ this[name] = undefined;
133
+ }
134
+ });
135
+ JS
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,47 @@
1
+ # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
+ # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
+
4
+ # TODO: => Sqreen::JS:ExecJS
5
+
6
+ require 'sqreen/js/executable_js'
7
+
8
+ module Sqreen
9
+ module Js
10
+ class ThreadLocalExecJsRunnable < ExecutableJs
11
+ def initialize(code)
12
+ @code = code
13
+ @tl_key = "SQREEN_EXECJS_CONTEXT_#{object_id}".freeze
14
+ @runtimes = [] # place where to keep strong references
15
+ @runtimes_mutex = Mutex.new
16
+ end
17
+
18
+ def run_js_cb(cbname, _budget, arguments)
19
+ tl_exec_js_runnable.call(cbname, *arguments)
20
+ end
21
+
22
+ def with_runtimes_mutex
23
+ @runtimes_mutex.synchronize { yield }
24
+ end
25
+
26
+ private
27
+
28
+ def dispose_from_dead_threads
29
+ with_runtimes_mutex do
30
+ @runtimes.delete_if { |th, _runtime| !th.alive? }
31
+ end
32
+ end
33
+
34
+ def tl_exec_js_runnable
35
+ runnable = Thread.current[@tl_key]
36
+ return runnable if runnable && runnable.weakref_alive?
37
+
38
+ dispose_from_dead_threads
39
+ runtime = ExecJS.compile(@code)
40
+ with_runtimes_mutex do
41
+ @runtimes << [Thread.current, runtime]
42
+ end
43
+ Thread.current[@tl_key] = WeakRef.new(runtime)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,207 +1,27 @@
1
1
  # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
2
  # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
3
 
4
- require 'logger'
5
- require 'singleton'
6
-
7
4
  require 'sqreen/performance_notifications/log'
8
5
  require 'sqreen/performance_notifications/log_performance'
9
6
  require 'sqreen/configuration'
10
7
 
8
+ require 'sqreen/logger'
9
+ require 'sqreen/deferred_logger'
10
+
11
+ # TODO: fold into Sqreen::Logger
12
+
11
13
  module Sqreen
12
14
  def self.log_init
13
- @logger = Logger.new(
15
+ @logger = Sqreen::Logger.new(
14
16
  Sqreen.config_get(:log_level).to_s.upcase,
15
17
  Sqreen.config_get(:log_location)
16
18
  )
17
- DeferredLogger.instance.flush_to(@logger.instance_eval { @logger })
19
+ Sqreen::DeferredLogger.instance.flush_to(@logger.instance_eval { @logger })
18
20
  rescue => e
19
21
  warn "Sqreen logger exception: #{e}"
20
22
  end
21
23
 
22
24
  def self::log
23
- @logger || DeferredLogger.instance
24
- end
25
-
26
- # Ruby default formatter modified to display current thread_id
27
- class FormatterWithTid
28
- Format = "%s, [%s#%d.%s] %5s -- %s: %s\n".freeze
29
- DatetimeFormat = '%Y-%m-%dT%H:%M:%S.%6N '.freeze
30
-
31
- attr_accessor :datetime_format
32
-
33
- def initialize
34
- @datetime_format = nil
35
- end
36
-
37
- def call(severity, time, progname, msg)
38
- format(Format,
39
- severity[0..0], format_datetime(time), $$,
40
- Thread.current.object_id.to_s(36),
41
- severity, progname, msg2str(msg)
42
- )
43
- end
44
-
45
- private
46
-
47
- def format_datetime(time)
48
- time.strftime(DatetimeFormat)
49
- end
50
-
51
- def msg2str(msg)
52
- case msg
53
- when ::String
54
- msg
55
- when ::Exception
56
- "#{msg.message} (#{msg.class})\n" << (msg.backtrace || []).join("\n")
57
- else
58
- msg.inspect
59
- end
60
- end
61
- end
62
-
63
- # Wrapper class for sqreen logging
64
- class Logger
65
- SEVERITY_TO_METHOD = ::Logger::Severity.constants.each_with_object({}) do |s, h|
66
- h[::Logger::Severity.const_get(s)] = s.downcase
67
- end
68
-
69
- def initialize(desired_level, log_location, force_logger = nil)
70
- if force_logger
71
- @logger = force_logger
72
- else
73
- init_logger_output(log_location)
74
- end
75
- init_log_level(desired_level)
76
- enforce_log_format(@logger)
77
- create_error_logger
78
- end
79
-
80
- def debug(msg = nil, &block)
81
- @logger.debug(msg, &block)
82
- end
83
-
84
- def info(msg = nil, &block)
85
- @logger.info(msg, &block)
86
- end
87
-
88
- def warn(msg = nil, &block)
89
- @logger.warn(msg, &block)
90
- end
91
-
92
- def error(msg = nil, &block)
93
- @error_logger.error(msg, &block)
94
- @logger.error(msg, &block)
95
- end
96
-
97
- def add(severity, msg = nil, &block)
98
- send(SEVERITY_TO_METHOD[severity], msg, &block)
99
- end
100
-
101
- protected
102
-
103
- def init_logger_output(path)
104
- path = File.expand_path(path)
105
- if File.writable?(path) || File.writable?(File.dirname(path))
106
- @logger = ::Logger.new(path)
107
- else
108
- @logger = ::Logger.new(STDOUT)
109
- @logger.info("Cannot access #{path} for writing. Defaulting to stdout")
110
- end
111
- rescue => e
112
- @logger = ::Logger.new(STDOUT)
113
- @logger.error('Got error while trying to setting logger up, '\
114
- "falling back to stdout #{e.inspect}")
115
- end
116
-
117
- def init_log_level(level)
118
- log_level = ::Logger.const_get(level)
119
- @logger.level = log_level
120
- Sqreen::PerformanceNotifications::Log.enable if level == 'DEBUG'
121
- return if level != 'DEBUG' && !Sqreen.config_get(:report_perf)
122
- Sqreen::PerformanceNotifications::LogPerformance.enable
123
- end
124
-
125
- def create_error_logger
126
- @error_logger = Kernel.const_defined?('MiniTest') ? NullLogger.instance : ::Logger.new(STDERR)
127
- enforce_log_format(@error_logger)
128
- end
129
-
130
- def enforce_log_format(logger)
131
- logger.formatter = FormatterWithTid.new
132
- end
133
- end
134
-
135
- class NullLogger
136
- include Singleton
137
-
138
- def debug(_msg = nil); end
139
-
140
- def info(_msg = nil); end
141
-
142
- def warn(_msg = nil); end
143
-
144
- def error(_msg = nil); end
145
-
146
- def fatal(_msg = nil); end
147
-
148
- def add(_severity, _msg = nil); end
149
-
150
- def formatter=(_); end
151
- end
152
-
153
- class DeferredLogger
154
- include Singleton
155
-
156
- def initialize
157
- @buffer = StringIO.new
158
- @logger = ::Logger.new(@buffer)
159
- end
160
-
161
- def debug(msg = nil, &block)
162
- @logger.debug(msg, &block)
163
- end
164
-
165
- def info(msg = nil, &block)
166
- @logger.info(msg, &block)
167
- end
168
-
169
- def warn(msg = nil, &block)
170
- @logger.warn(msg, &block)
171
- end
172
-
173
- def error(msg = nil, &block)
174
- @logger.error(msg, &block)
175
- end
176
-
177
- def fatal(msg = nil, &block)
178
- @logger.error(msg, &block)
179
- end
180
-
181
- def add(severity, msg = nil, &block)
182
- send(Sqreen::Logger::SEVERITY_TO_METHOD[severity], msg, &block)
183
- end
184
-
185
- def formatter=(value)
186
- @logger.formatter = value
187
- end
188
-
189
- def flush_to(logger)
190
- logger.instance_eval { @logdev }.write(read).tap { reset }
191
- end
192
-
193
- private
194
-
195
- def read
196
- @buffer.rewind
197
- @buffer.read
198
- end
199
-
200
- def reset
201
- buffer = StringIO.new
202
- logger = ::Logger.new(buffer)
203
- logger.formatter = @logger.formatter
204
- @buffer, @logger = buffer, logger
205
- end
25
+ @logger || Sqreen::DeferredLogger.instance
206
26
  end
207
27
  end
@@ -0,0 +1,83 @@
1
+ # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
+ # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
+
4
+ require 'logger'
5
+ require 'sqreen/log'
6
+ require 'sqreen/formatter_with_tid'
7
+ require 'sqreen/null_logger'
8
+
9
+ # TODO: inherit from ::Logger
10
+
11
+ module Sqreen
12
+ # Wrapper class for sqreen logging
13
+ class Logger
14
+ SEVERITY_TO_METHOD = ::Logger::Severity.constants.each_with_object({}) do |s, h|
15
+ h[::Logger::Severity.const_get(s)] = s.downcase
16
+ end
17
+
18
+ def initialize(desired_level, log_location, force_logger = nil)
19
+ if force_logger
20
+ @logger = force_logger
21
+ else
22
+ init_logger_output(log_location)
23
+ end
24
+ init_log_level(desired_level)
25
+ enforce_log_format(@logger)
26
+ create_error_logger
27
+ end
28
+
29
+ def debug(msg = nil, &block)
30
+ @logger.debug(msg, &block)
31
+ end
32
+
33
+ def info(msg = nil, &block)
34
+ @logger.info(msg, &block)
35
+ end
36
+
37
+ def warn(msg = nil, &block)
38
+ @logger.warn(msg, &block)
39
+ end
40
+
41
+ def error(msg = nil, &block)
42
+ @error_logger.error(msg, &block)
43
+ @logger.error(msg, &block)
44
+ end
45
+
46
+ def add(severity, msg = nil, &block)
47
+ send(SEVERITY_TO_METHOD[severity], msg, &block)
48
+ end
49
+
50
+ protected
51
+
52
+ def init_logger_output(path)
53
+ path = File.expand_path(path)
54
+ if File.writable?(path) || File.writable?(File.dirname(path))
55
+ @logger = ::Logger.new(path)
56
+ else
57
+ @logger = ::Logger.new(STDOUT)
58
+ @logger.info("Cannot access #{path} for writing. Defaulting to stdout")
59
+ end
60
+ rescue StandardError => e
61
+ @logger = ::Logger.new(STDOUT)
62
+ @logger.error('Got error while trying to setting logger up, '\
63
+ "falling back to stdout #{e.inspect}")
64
+ end
65
+
66
+ def init_log_level(level)
67
+ log_level = ::Logger.const_get(level)
68
+ @logger.level = log_level
69
+ Sqreen::PerformanceNotifications::Log.enable if level == 'DEBUG'
70
+ return if level != 'DEBUG' && !Sqreen.config_get(:report_perf)
71
+ Sqreen::PerformanceNotifications::LogPerformance.enable
72
+ end
73
+
74
+ def create_error_logger
75
+ @error_logger = Kernel.const_defined?('MiniTest') ? NullLogger.instance : ::Logger.new(STDERR)
76
+ enforce_log_format(@error_logger)
77
+ end
78
+
79
+ def enforce_log_format(logger)
80
+ logger.formatter = Sqreen::FormatterWithTid.new
81
+ end
82
+ end
83
+ end