sqreen 1.18.2-java → 1.19.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +35 -0
  3. data/LICENSE +3 -0
  4. data/lib/sqreen.rb +2 -0
  5. data/lib/sqreen/actions.rb +13 -337
  6. data/lib/sqreen/actions/actions_index.rb +16 -0
  7. data/lib/sqreen/actions/base.rb +104 -0
  8. data/lib/sqreen/actions/block_ip.rb +34 -0
  9. data/lib/sqreen/actions/block_user.rb +46 -0
  10. data/lib/sqreen/actions/ip_range_indexed_action_class.rb +16 -0
  11. data/lib/sqreen/actions/ip_ranges_index.rb +57 -0
  12. data/lib/sqreen/actions/redirect_ip.rb +42 -0
  13. data/lib/sqreen/actions/redirect_user.rb +47 -0
  14. data/lib/sqreen/actions/repository.rb +43 -0
  15. data/lib/sqreen/actions/unknown_action_type.rb +20 -0
  16. data/lib/sqreen/actions/user_action_class.rb +16 -0
  17. data/lib/sqreen/actions/users_index.rb +35 -0
  18. data/lib/sqreen/agent.rb +6 -2
  19. data/lib/sqreen/attack_blocked.rb +19 -0
  20. data/lib/sqreen/backport.rb +2 -0
  21. data/lib/sqreen/backport/clock_gettime.rb +74 -0
  22. data/lib/sqreen/backport/original_name.rb +2 -0
  23. data/lib/sqreen/binding_accessor.rb +11 -102
  24. data/lib/sqreen/binding_accessor/path_elem.rb +10 -0
  25. data/lib/sqreen/binding_accessor/transforms.rb +114 -0
  26. data/lib/sqreen/call_countable.rb +2 -0
  27. data/lib/sqreen/capped_queue.rb +4 -0
  28. data/lib/sqreen/{callbacks.rb → cb.rb} +3 -53
  29. data/lib/sqreen/{callback_tree.rb → cb_tree.rb} +4 -2
  30. data/lib/sqreen/condition_evaluator.rb +24 -5
  31. data/lib/sqreen/conditionable.rb +2 -0
  32. data/lib/sqreen/configuration.rb +19 -0
  33. data/lib/sqreen/context.rb +2 -0
  34. data/lib/sqreen/default_cb.rb +22 -0
  35. data/lib/sqreen/deferred_logger.rb +65 -0
  36. data/lib/sqreen/deliveries.rb +12 -0
  37. data/lib/sqreen/deliveries/batch.rb +9 -1
  38. data/lib/sqreen/deliveries/simple.rb +7 -0
  39. data/lib/sqreen/dependency.rb +3 -1
  40. data/lib/sqreen/dependency/detector.rb +22 -14
  41. data/lib/sqreen/dependency/libsqreen.rb +32 -0
  42. data/lib/sqreen/dependency/new_relic.rb +2 -0
  43. data/lib/sqreen/dependency/rack.rb +10 -5
  44. data/lib/sqreen/dependency/rails.rb +8 -0
  45. data/lib/sqreen/dependency/sentry.rb +2 -0
  46. data/lib/sqreen/dependency/sinatra.rb +58 -14
  47. data/lib/sqreen/encoding_sanitizer.rb +2 -0
  48. data/lib/sqreen/error_handling_middleware.rb +32 -0
  49. data/lib/sqreen/event.rb +4 -0
  50. data/lib/sqreen/events/attack.rb +4 -0
  51. data/lib/sqreen/events/remote_exception.rb +2 -0
  52. data/lib/sqreen/events/request_record.rb +13 -56
  53. data/lib/sqreen/exception.rb +11 -40
  54. data/lib/sqreen/formatter_with_tid.rb +47 -0
  55. data/lib/sqreen/framework_cb.rb +30 -0
  56. data/lib/sqreen/frameworks.rb +9 -0
  57. data/lib/sqreen/frameworks/generic.rb +22 -2
  58. data/lib/sqreen/frameworks/rails.rb +3 -0
  59. data/lib/sqreen/frameworks/rails3.rb +2 -0
  60. data/lib/sqreen/frameworks/request_recorder.rb +5 -0
  61. data/lib/sqreen/frameworks/sinatra.rb +4 -0
  62. data/lib/sqreen/frameworks/sqreen_test.rb +4 -0
  63. data/lib/sqreen/graft.rb +12 -0
  64. data/lib/sqreen/graft/call.rb +150 -0
  65. data/lib/sqreen/{dependency → graft}/callback.rb +12 -4
  66. data/lib/sqreen/graft/hook.rb +316 -0
  67. data/lib/sqreen/{dependency → graft}/hook_point.rb +152 -33
  68. data/lib/sqreen/graft/hook_point_error.rb +10 -0
  69. data/lib/sqreen/invalid_signature_exception.rb +10 -0
  70. data/lib/sqreen/js.rb +11 -0
  71. data/lib/sqreen/js/call_context.rb +12 -0
  72. data/lib/sqreen/js/context_pool.rb +62 -0
  73. data/lib/sqreen/js/exec_js_runnable.rb +22 -0
  74. data/lib/sqreen/js/execjs_adapter.rb +8 -47
  75. data/lib/sqreen/js/executable_js.rb +14 -0
  76. data/lib/sqreen/js/js_service.rb +4 -22
  77. data/lib/sqreen/js/js_service_adapter.rb +20 -0
  78. data/lib/sqreen/js/mini_racer_adapter.rb +8 -180
  79. data/lib/sqreen/js/mini_racer_executable_js.rb +144 -0
  80. data/lib/sqreen/js/thread_local_exec_js_runnable.rb +49 -0
  81. data/lib/{sqreen-alt.rb → sqreen/legacy.rb} +5 -1
  82. data/lib/sqreen/{instrumentation.rb → legacy/instrumentation.rb} +44 -15
  83. data/lib/sqreen/log.rb +10 -188
  84. data/lib/sqreen/log/loggable.rb +28 -0
  85. data/lib/sqreen/logger.rb +85 -0
  86. data/lib/sqreen/metrics.rb +2 -0
  87. data/lib/sqreen/metrics/average.rb +2 -0
  88. data/lib/sqreen/metrics/base.rb +2 -0
  89. data/lib/sqreen/metrics/binning.rb +2 -0
  90. data/lib/sqreen/metrics/collect.rb +2 -0
  91. data/lib/sqreen/metrics/sum.rb +2 -0
  92. data/lib/sqreen/metrics_store.rb +5 -11
  93. data/lib/sqreen/metrics_store/already_registered_metric.rb +13 -0
  94. data/lib/sqreen/metrics_store/unknown_metric.rb +13 -0
  95. data/lib/sqreen/metrics_store/unregistered_metric.rb +13 -0
  96. data/lib/sqreen/middleware.rb +2 -34
  97. data/lib/sqreen/mono_time.rb +4 -0
  98. data/lib/sqreen/node.rb +46 -0
  99. data/lib/sqreen/not_implemented_yet.rb +10 -0
  100. data/lib/sqreen/null_logger.rb +26 -0
  101. data/lib/sqreen/payload_creator.rb +4 -19
  102. data/lib/sqreen/payload_creator/header_section.rb +30 -0
  103. data/lib/sqreen/performance_notifications.rb +2 -0
  104. data/lib/sqreen/performance_notifications/binned_metrics.rb +2 -0
  105. data/lib/sqreen/performance_notifications/log.rb +2 -0
  106. data/lib/sqreen/performance_notifications/log_performance.rb +2 -0
  107. data/lib/sqreen/performance_notifications/metrics.rb +2 -0
  108. data/lib/sqreen/performance_notifications/newrelic.rb +2 -0
  109. data/lib/sqreen/prefix.rb +35 -0
  110. data/lib/sqreen/rails_middleware.rb +16 -0
  111. data/lib/sqreen/remote_command.rb +3 -8
  112. data/lib/sqreen/remote_command/failure_output.rb +16 -0
  113. data/lib/sqreen/rules.rb +34 -2
  114. data/lib/sqreen/{rule_attributes.rb → rules/attrs.rb} +2 -0
  115. data/lib/sqreen/{rules_callbacks/sdk_auth_track.rb → rules/auth_track_cb.rb} +4 -2
  116. data/lib/sqreen/{rules_callbacks/binding_accessor_matcher.rb → rules/binding_accessor_matcher_cb.rb} +6 -8
  117. data/lib/sqreen/{rules_callbacks → rules}/binding_accessor_metrics.rb +3 -1
  118. data/lib/sqreen/{rules_callbacks/blacklist_ips.rb → rules/blacklist_ips_cb.rb} +5 -2
  119. data/lib/sqreen/{rules_callbacks → rules}/count_http_codes.rb +4 -2
  120. data/lib/sqreen/{rules_callbacks/crawler_user_agent_matches.rb → rules/crawler_user_agent_matches_cb.rb} +3 -1
  121. data/lib/sqreen/{rules_callbacks/crawler_user_agent_matches_metrics.rb → rules/crawler_user_agent_matches_metrics_cb.rb} +3 -1
  122. data/lib/sqreen/{rules_callbacks/custom_error.rb → rules/custom_error_cb.rb} +3 -1
  123. data/lib/sqreen/{rules_callbacks/devise_auth_track.rb → rules/devise_auth_track_cb.rb} +4 -2
  124. data/lib/sqreen/{rules_callbacks/devise_signup_track.rb → rules/devise_signup_track_cb.rb} +4 -2
  125. data/lib/sqreen/{rules_callbacks/execjs.rb → rules/execjs_cb.rb} +51 -50
  126. data/lib/sqreen/{rules_callbacks/headers_insert.rb → rules/headers_insert_cb.rb} +8 -1
  127. data/lib/sqreen/{rules_callbacks → rules}/matcher_rule.rb +4 -2
  128. data/lib/sqreen/{rules_callbacks/not_found.rb → rules/not_found_cb.rb} +7 -2
  129. data/lib/sqreen/{rules_callbacks/rails_parameters.rb → rules/rails_parameters_cb.rb} +3 -1
  130. data/lib/sqreen/{rules_callbacks → rules}/record_request_context.rb +3 -1
  131. data/lib/sqreen/{rules_callbacks/regexp_rule.rb → rules/regexp_rule_cb.rb} +3 -1
  132. data/lib/sqreen/{rule_callback.rb → rules/rule_cb.rb} +4 -2
  133. data/lib/sqreen/{rules_callbacks → rules}/run_req_start_actions.rb +7 -3
  134. data/lib/sqreen/{rules_callbacks → rules}/run_user_actions.rb +4 -2
  135. data/lib/sqreen/{rules_callbacks/shell_env.rb → rules/shell_env_cb.rb} +3 -1
  136. data/lib/sqreen/{rules_callbacks/sdk_signup_track.rb → rules/signup_track_cb.rb} +4 -2
  137. data/lib/sqreen/rules/update_request_context.rb +22 -0
  138. data/lib/sqreen/{rules_callbacks/url_matches.rb → rules/url_matches_cb.rb} +3 -1
  139. data/lib/sqreen/{rules_callbacks/user_agent_matches.rb → rules/user_agent_matches_cb.rb} +3 -1
  140. data/lib/sqreen/{rules_callbacks/waf.rb → rules/waf_cb.rb} +41 -21
  141. data/lib/sqreen/{rules_callbacks/reflected_xss.rb → rules/xss_cb.rb} +12 -7
  142. data/lib/sqreen/run_when_called_cb.rb +23 -0
  143. data/lib/sqreen/runner.rb +25 -7
  144. data/lib/sqreen/runtime_infos.rb +4 -9
  145. data/lib/sqreen/safe_json.rb +2 -0
  146. data/lib/sqreen/sdk.rb +4 -0
  147. data/lib/sqreen/sensitive_data_redactor.rb +113 -0
  148. data/lib/sqreen/serializer.rb +2 -0
  149. data/lib/sqreen/session.rb +2 -0
  150. data/lib/sqreen/shared_storage.rb +2 -0
  151. data/lib/sqreen/shared_storage23.rb +2 -0
  152. data/lib/sqreen/shrink_wrap.rb +16 -0
  153. data/lib/sqreen/signature_verifier.rb +22 -0
  154. data/lib/sqreen/sinatra_middleware.rb +16 -0
  155. data/lib/sqreen/{rules_signature.rb → sqreen_signed_verifier.rb} +7 -17
  156. data/lib/sqreen/token_invalid_exception.rb +10 -0
  157. data/lib/sqreen/token_not_found_exception.rb +11 -0
  158. data/lib/sqreen/trie.rb +5 -64
  159. data/lib/sqreen/unauthorized.rb +10 -0
  160. data/lib/sqreen/util.rb +7 -0
  161. data/lib/sqreen/util/capped_array.rb +35 -0
  162. data/lib/sqreen/util/capped_hash.rb +41 -0
  163. data/lib/sqreen/util/capped_string.rb +26 -0
  164. data/lib/sqreen/util/capper.rb +67 -0
  165. data/lib/sqreen/version.rb +3 -1
  166. data/lib/sqreen/waf_error.rb +20 -0
  167. data/lib/sqreen/weave.rb +12 -0
  168. data/lib/sqreen/weave/hardcoded.rb +19 -0
  169. data/lib/sqreen/weave/instrumentor.rb +48 -0
  170. data/lib/sqreen/weave/legacy.rb +12 -0
  171. data/lib/sqreen/weave/legacy/instrumentation.rb +406 -0
  172. data/lib/sqreen/web_server.rb +2 -0
  173. data/lib/sqreen/web_server/generic.rb +2 -0
  174. data/lib/sqreen/web_server/passenger.rb +2 -0
  175. data/lib/sqreen/web_server/puma.rb +2 -0
  176. data/lib/sqreen/web_server/rainbows.rb +2 -0
  177. data/lib/sqreen/web_server/thin.rb +2 -0
  178. data/lib/sqreen/web_server/unicorn.rb +2 -0
  179. data/lib/sqreen/web_server/webrick.rb +2 -0
  180. data/lib/sqreen/worker.rb +2 -0
  181. metadata +105 -39
  182. data/lib/sqreen/dependency/hook.rb +0 -102
  183. data/lib/sqreen/rules_callbacks.rb +0 -35
  184. data/lib/sqreen/rules_callbacks/inspect_rule.rb +0 -25
@@ -1,4 +1,8 @@
1
+ # typed: strong
2
+
1
3
  # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
4
  # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
5
 
4
- require "sqreen"
6
+ module Sqreen
7
+ module Legacy; end
8
+ end
@@ -1,17 +1,20 @@
1
+ # typed: ignore
2
+
1
3
  # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
4
  # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
5
 
4
- require 'sqreen/callback_tree'
6
+ require 'sqreen/legacy'
7
+ require 'sqreen/cb_tree'
5
8
  require 'sqreen/log'
6
9
  require 'sqreen/exception'
7
10
  require 'sqreen/performance_notifications'
8
11
  require 'sqreen/call_countable'
9
12
  require 'sqreen/events/remote_exception'
10
- require 'sqreen/rules_signature'
13
+ require 'sqreen/sqreen_signed_verifier'
11
14
  require 'sqreen/shared_storage'
12
- require 'sqreen/rules_callbacks/record_request_context'
13
- require 'sqreen/rules_callbacks/run_req_start_actions'
14
- require 'sqreen/rules_callbacks/run_user_actions'
15
+ require 'sqreen/rules/record_request_context'
16
+ require 'sqreen/rules/run_req_start_actions'
17
+ require 'sqreen/rules/run_user_actions'
15
18
  require 'sqreen/mono_time'
16
19
  require 'set'
17
20
 
@@ -36,6 +39,8 @@ require 'set'
36
39
  # end
37
40
 
38
41
  module Sqreen
42
+
43
+ module Legacy
39
44
  class Instrumentation
40
45
  OVERTIME_METRIC = 'request_overtime'.freeze
41
46
 
@@ -84,6 +89,7 @@ module Sqreen
84
89
  start = Sqreen.time
85
90
  res = cb.pre(instance, args, budget, &block)
86
91
  stop = Sqreen.time
92
+ Sqreen.log.debug { "ran pre cb #{cb} => #{res.inspect}" }
87
93
  # The first few pre callbacks could not have a request & hence a budget just yet so we try harder to find it
88
94
  budget = framework.remaining_perf_budget if framework && !budget && Sqreen.performance_budget
89
95
  if budget
@@ -139,6 +145,7 @@ module Sqreen
139
145
  start = Sqreen.time
140
146
  res = cb.post(return_val, instance, args, budget, &block)
141
147
  stop = Sqreen.time
148
+ Sqreen.log.debug { "ran post cb #{cb} => #{res.inspect}" }
142
149
  if budget
143
150
  budget -= (stop - start)
144
151
  cb.overtime! if budget <= 0.0
@@ -193,6 +200,7 @@ module Sqreen
193
200
  start = Sqreen.time
194
201
  res = cb.failing(exception, instance, args, budget, &block)
195
202
  stop = Sqreen.time
203
+ Sqreen.log.debug { "ran failing cb #{cb} => #{res.inspect}" }
196
204
  if budget
197
205
  budget -= (stop - start)
198
206
  cb.overtime! if budget <= 0.0
@@ -237,7 +245,7 @@ module Sqreen
237
245
  key = [method]
238
246
  args.each { |e| key.push(e.object_id) }
239
247
  if key && @sqreen_multi_instr && @sqreen_multi_instr[instance.object_id].member?(key)
240
- return instance.send(original_method, *args, &block)
248
+ return instance.__send__(original_method, *args, &block)
241
249
  end
242
250
  @sqreen_multi_instr ||= Hash.new { |h, k| h[k] = Set.new } # TODO: this should probably be a thread local
243
251
  @sqreen_multi_instr[instance.object_id].add(key)
@@ -273,7 +281,7 @@ module Sqreen
273
281
  skip_call = true
274
282
  end
275
283
  # If we are already overbudget let's not work at all
276
- return send(original_meth, *args, &block) if skip_call
284
+ return __send__(original_meth, *args, &block) if skip_call
277
285
  Instrumentation.guard_multi_call(self, meth, original_meth, args, block) do
278
286
  precbs, postcbs, failcbs = Instrumentation.callbacks.get(klass_name, meth)
279
287
  Thread.current[:sqreen_in_use] = true
@@ -328,7 +336,7 @@ module Sqreen
328
336
  Thread.current[:sqreen_in_use] = false
329
337
  return result if skip
330
338
  begin
331
- result = send(original_meth, *args, &block)
339
+ result = __send__(original_meth, *args, &block)
332
340
  rescue StandardError => e
333
341
  Thread.current[:sqreen_in_use] = true
334
342
  budget = Sqreen.performance_budget && framework && framework.remaining_perf_budget
@@ -401,7 +409,7 @@ module Sqreen
401
409
  Sqreen::PerformanceNotifications::BinnedMetrics.start_request if has_notifications
402
410
 
403
411
  begin
404
- send(original_meth, *args, &block)
412
+ __send__(original_meth, *args, &block)
405
413
  ensure
406
414
  if has_notifications
407
415
  Sqreen::PerformanceNotifications.instrument('next_req_notifs', PRE_CB) do
@@ -437,7 +445,7 @@ module Sqreen
437
445
  end
438
446
 
439
447
  alias_method original, new_method
440
- send(method_kind, original)
448
+ __send__(method_kind, original)
441
449
  private saved_meth_name
442
450
  end
443
451
  end
@@ -456,7 +464,7 @@ module Sqreen
456
464
  method_kind = :private
457
465
  end
458
466
  alias_method meth, saved_meth_name
459
- send(method_kind, meth)
467
+ __send__(method_kind, meth)
460
468
 
461
469
  remove_method saved_meth_name
462
470
  end
@@ -503,11 +511,12 @@ module Sqreen
503
511
  alias_method meth, new_method
504
512
  private saved_meth_name
505
513
  private new_method
506
- send(method_kind, meth)
514
+ __send__(method_kind, meth)
507
515
  end
508
516
  saved_meth_name
509
517
  end
510
518
 
519
+ ### bad idea anyway
511
520
  # WARNING We do not actually remove `meth`
512
521
  def unoverride_class_method(klass, meth)
513
522
  saved_meth_name = get_saved_method_name(meth)
@@ -522,10 +531,11 @@ module Sqreen
522
531
  method_kind = :private
523
532
  end
524
533
  alias_method meth.to_sym, saved_meth_name.to_sym
525
- send(method_kind, meth.to_sym)
534
+ __send__(method_kind, meth.to_sym)
526
535
  end
527
536
  end
528
537
 
538
+ ### useless now
529
539
  if RUBY_VERSION < '1.9'
530
540
  def adjust_method_name(method)
531
541
  method.to_s
@@ -554,6 +564,8 @@ module Sqreen
554
564
  is_instance_method?(obj, method)
555
565
  end
556
566
 
567
+ ### is that actually used?
568
+ ### if so, do not attempt to alter frozen instances
557
569
  # Override a singleton method on an instance
558
570
  def override_singleton_method(instance, klass_name, meth)
559
571
  @@overriden_singleton_methods = true
@@ -647,8 +659,7 @@ module Sqreen
647
659
 
648
660
  already_overriden = @@overriden_methods.include? key
649
661
  unless already_overriden
650
- Sqreen.log.debug "#{key} not overriden, returning"
651
- return
662
+ Sqreen.log.debug "#{key} apparently not overridden"
652
663
  end
653
664
 
654
665
  defined_cbs = @@registered_callbacks.get(klass, method).flatten
@@ -674,6 +685,7 @@ module Sqreen
674
685
  elsif is_instance_method?(klass, method)
675
686
  unoverride_instance_method(klass, method)
676
687
  else
688
+ ### Module#prepend will take care of that
677
689
  # FIXME: Override define_method and other dynamic ways to
678
690
  # The following should be monitored to make sure we
679
691
  # don't forget dynamically added methods:
@@ -701,8 +713,13 @@ module Sqreen
701
713
  # @return [Array<Sqreen::CB>]
702
714
  def hardcoded_callbacks(framework)
703
715
  [
716
+ ### callback for performing sec responses based on ip
717
+ ### init redefined to implement smartass way to hook it upon the
718
+ ### framework's middleware #call
704
719
  Sqreen::Rules::RunReqStartActions.new(framework),
720
+ ### callback for performing sec responses based on user
705
721
  Sqreen::Rules::RunUserActions.new(Sqreen, :identify, 0),
722
+ ### callback for performing sec responses based on user
706
723
  Sqreen::Rules::RunUserActions.new(Sqreen, :auth_track, 1),
707
724
  ]
708
725
  end
@@ -711,6 +728,7 @@ module Sqreen
711
728
  # @param rules [Array<Hash>] Rules to instrument
712
729
  # @param framework [Sqreen::Frameworks::GenericFramework]
713
730
  def instrument!(rules, framework)
731
+ ### set up rule signature verifier
714
732
  verifier = nil
715
733
  if Sqreen.features['rules_signature'] &&
716
734
  Sqreen.config_get(:rules_verify_signature) == true &&
@@ -720,33 +738,44 @@ module Sqreen
720
738
  Sqreen.log.debug('Rules signature is not enabled')
721
739
  end
722
740
 
741
+ ### force clean instrumentation callback list
723
742
  remove_all_callbacks # Force cb tree to be empty before instrumenting
724
743
 
744
+ ### for each rule description, transform into format for adding callback
725
745
  rules.each do |rule|
726
746
  rcb = Sqreen::Rules.cb_from_rule(rule, self, metrics_engine, verifier)
727
747
  next unless rcb
748
+ ### attach framework to callback
728
749
  rcb.framework = framework
750
+ ### add callback
729
751
  add_callback(rcb)
730
752
  end
731
753
 
732
754
  # add hardcoded callbacks, observing priority
733
755
  hardcoded_callbacks(framework).each { |cb| add_callback(cb) }
734
756
 
757
+ ### globally declare instrumentation ready
758
+ ### from within instance method? not even thread local?
735
759
  Sqreen.instrumentation_ready = true
736
760
  end
737
761
 
738
762
  def initialize(metrics_engine = nil)
739
763
  self.metrics_engine = metrics_engine
740
764
  return if metrics_engine.nil?
765
+ ### init metric to count calls to sqreen
741
766
  metrics_engine.create_metric('name' => CallCountable::COUNT_CALLS,
742
767
  'period' => 60,
743
768
  'kind' => 'Sum')
769
+ ### init metric to count request whitelist matches (ip or path whitelist)
744
770
  metrics_engine.create_metric('name' => Sqreen::Rules::RecordRequestContext::WHITELISTED_METRIC,
745
771
  'period' => 60,
746
772
  'kind' => 'Sum')
773
+ ### init metric to count over budget hits
747
774
  metrics_engine.create_metric('name' => OVERTIME_METRIC,
748
775
  'period' => 60,
749
776
  'kind' => 'Sum')
750
777
  end
751
778
  end
752
779
  end
780
+
781
+ end
@@ -1,207 +1,29 @@
1
+ # typed: ignore
2
+
1
3
  # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
4
  # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
5
 
4
- require 'logger'
5
- require 'singleton'
6
-
7
6
  require 'sqreen/performance_notifications/log'
8
7
  require 'sqreen/performance_notifications/log_performance'
9
8
  require 'sqreen/configuration'
10
9
 
10
+ require 'sqreen/logger'
11
+ require 'sqreen/deferred_logger'
12
+
13
+ # TODO: fold into Sqreen::Logger
14
+
11
15
  module Sqreen
12
16
  def self.log_init
13
- @logger = Logger.new(
17
+ @logger = Sqreen::Logger.new(
14
18
  Sqreen.config_get(:log_level).to_s.upcase,
15
19
  Sqreen.config_get(:log_location)
16
20
  )
17
- DeferredLogger.instance.flush_to(@logger.instance_eval { @logger })
21
+ Sqreen::DeferredLogger.instance.flush_to(@logger.instance_eval { @logger })
18
22
  rescue => e
19
23
  warn "Sqreen logger exception: #{e}"
20
24
  end
21
25
 
22
26
  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
27
+ @logger || Sqreen::DeferredLogger.instance
206
28
  end
207
29
  end