stackify-api-ruby 1.0.15 → 1.2.9

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.
@@ -14,16 +14,20 @@ module Stackify::Authorizable
14
14
  end
15
15
 
16
16
  def auth_task attempts
17
- properties = {
18
- limit: 1,
19
- attempts: attempts,
20
- success_condition: lambda do |result|
21
- result.try(:status) == 200
17
+ begin
18
+ properties = {
19
+ limit: 1,
20
+ attempts: attempts,
21
+ success_condition: lambda do |result|
22
+ result.try(:status) == 200
23
+ end
24
+ }
25
+ Stackify::ScheduleTask.new properties do
26
+ Stackify.internal_log :debug, '[AuthorizationClient] trying to authorize...'
27
+ send_request BASE_URI, Stackify::EnvDetails.instance.auth_info.to_json
22
28
  end
23
- }
24
- Stackify::ScheduleTask.new properties do
25
- Stackify.internal_log :debug, '[AuthorizationClient] trying to authorize...'
26
- send_request BASE_URI, Stackify::EnvDetails.instance.auth_info.to_json
29
+ rescue => exception
30
+ Stackify.log_internal_error "[AuthorizationClient]: An error occured in auth_task!"
27
31
  end
28
32
  end
29
33
  end
@@ -4,7 +4,32 @@ module Stackify
4
4
 
5
5
  if Rails.version > '3.1'
6
6
  initializer 'Stackify set up of logger', group: :all do
7
+ if Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new('4.0')
8
+ # check if the client app is using the ActiveSupport::Logger
9
+ is_activesupport_logger = ::Rails.logger.is_a?(ActiveSupport::Logger)
10
+ elsif Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new('3.0')
11
+ Stackify::Utils.check_buffered_logger
12
+ end
13
+
14
+ # Check if the log output is STDOUT
15
+ Stackify::Utils.check_log_output
16
+
17
+ # Proxy the client Rails logger and write logs to its default log_path.
18
+ # At the same time, we send the log messages to the LoggerClient.
7
19
  ::Rails.logger = ::Stackify::LoggerProxy.new ::Rails.logger
20
+
21
+ if Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new('6.0')
22
+ set_console_logs ::Rails.logger
23
+ elsif Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new('4.0')
24
+ if is_activesupport_logger && Stackify.configuration.stdout_output
25
+ set_console_logs ::Rails.logger
26
+ end
27
+ # Another checking if the client app is using the default logger and not STDOUT
28
+ if Stackify.configuration.stdout_output == false
29
+ set_console_logs ::Rails.logger
30
+ end
31
+ end
32
+
8
33
  Stackify.run
9
34
  end
10
35
 
@@ -14,6 +39,16 @@ module Stackify
14
39
  end
15
40
  end
16
41
 
42
+ def set_console_logs logger
43
+ # Handle the stdout logs from Action Controller
44
+ ActionController::Base.logger = logger
45
+
46
+ # Handle the stdout logs from Action View
47
+ ActionView::Base.logger = logger
48
+
49
+ # Handle the stdout logs from Active Record
50
+ ActiveRecord::Base.logger = logger
51
+ end
17
52
  end
18
53
 
19
54
  end
@@ -31,12 +31,16 @@ module Stackify
31
31
  end
32
32
 
33
33
  def error_type
34
- @exception.class
34
+ if @exception.class.to_s == 'StringException'
35
+ @exception.message.split(" ")[0].to_s
36
+ else
37
+ @exception.class
38
+ end
35
39
  end
36
40
 
37
41
  def to_h
38
42
  env = Stackify::EnvDetails.instance
39
- {
43
+ data = {
40
44
  'OccurredEpochMillis' => Time.now.to_f*1000,
41
45
  'Error' => {
42
46
  'InnerError' => @exception.try(:cause),
@@ -48,11 +52,20 @@ module Stackify
48
52
  'SourceMethod' => source_method,
49
53
  },
50
54
  'EnvironmentDetail' => env.auth_info,
51
- 'WebRequestDetail' => env.request_details.try{ |d| d.fetch('webrequest_details', '') },
52
- 'ServerVariables' => env.request_details.try{ |d| d.fetch('server_variables', '') },
53
55
  'CustomerName' => 'Customer',
54
56
  'UserName' => @context.fetch('user', '')
55
57
  }
58
+ web_request_details = env.request_details.try{ |d| d.fetch('webrequest_details', '') }
59
+ if web_request_details.nil?
60
+ data['WebRequestDetail'] = web_request_details
61
+ end
62
+
63
+ server_variables = env.request_details.try{ |d| d.fetch('server_variables', '') }
64
+ if server_variables.nil?
65
+ data['ServerVariables'] = server_variables
66
+ end
67
+
68
+ data
56
69
  end
57
70
 
58
71
  end
@@ -25,6 +25,7 @@ module Stackify
25
25
  req.headers = headers
26
26
  req.body = body
27
27
  end
28
+ return @response
28
29
  rescue => ex
29
30
  @errors << ex
30
31
  Stackify.log_internal_error('HttpClient: ' + ex.message+ ' Backtrace: '+ Stackify::Backtrace.backtrace_in_line(ex.backtrace))
@@ -2,36 +2,57 @@ module Stackify
2
2
  class LoggerClient
3
3
 
4
4
  def initialize
5
- @@errors_governor = Stackify::ErrorsGovernor.new
6
- end
7
-
8
- def log level, msg, call_trace
9
- Stackify::Utils.do_only_if_authorized_and_mode_is_on Stackify::MODES[:logging] do
10
- if acceptable?(level, msg) && Stackify.working?
11
- worker = Stackify::AddMsgWorker.new
12
- task = log_message_task level, msg, call_trace
13
- worker.async_perform ScheduleDelay.new, task
14
- end
5
+ begin
6
+ @@errors_governor = Stackify::ErrorsGovernor.new
7
+ @@transport = Stackify::TransportSelector.new(Stackify.configuration.transport).transport
8
+ Stackify.internal_log :info, "[LoggerClient] initialize: #{@@transport}"
9
+ return if @@transport.nil?
10
+ rescue => ex
11
+ Stackify.log_internal_error "[LoggerClient] initialize exception = #{ex.inspect}"
15
12
  end
16
13
  end
17
14
 
18
- def log_exception level= :error, ex
19
- if ex.is_a?(Stackify::StackifiedError)
20
- Stackify::Utils.do_only_if_authorized_and_mode_is_on Stackify::MODES[:logging] do
21
- if acceptable?(level, ex.message) && Stackify.working?
22
- if @@errors_governor.can_send? ex
23
- worker = Stackify::AddMsgWorker.new
24
- task = log_exception_task level, ex
25
- worker.async_perform ScheduleDelay.new, task
26
- else
27
- Stackify.internal_log :warn,
28
- "LoggerClient: logging of exception with message \"#{ex.message}\" is skipped - flood_limit is exceeded"
15
+ # This function is responsible in displaying log messages based on the level criteria
16
+ # @param num_level [Integer] level of the clients Rails.logger
17
+ # @param level [String] level coming from array of levels(debug info warn error fatal unknown) that we are going to filter with num_level
18
+ # So we filter all logs from num_level up to this level
19
+ # @param msg [Integer] log messages
20
+ # @param call_trace [Object] return the current execution stack
21
+ def log num_level, level, msg, call_trace
22
+ display_log = true
23
+ log_appender = false
24
+ buffer_log = false
25
+ if defined? Rails
26
+ display_log = false if Stackify.configuration.stdout_output
27
+ log_appender = true if defined?(Logging)
28
+ buffer_log = true if Stackify.configuration.buffered_logger
29
+ unless buffer_log
30
+ if Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new('4.0')
31
+ if display_log && log_appender
32
+ puts msg if num_level <= Logger.const_get(level.upcase).to_i
33
+ elsif display_log && log_appender == false
34
+ puts msg if num_level <= Logger.const_get(level.upcase).to_i
29
35
  end
30
36
  end
31
37
  end
32
38
  else
33
- Stackify.log_internal_error 'LoggerClient: log_exception should get StackifiedError object'
39
+ puts msg if num_level <= Logger.const_get(level.upcase).to_i
34
40
  end
41
+
42
+ return if @@transport.nil?
43
+ task = log_message_task level, msg, call_trace
44
+ @@transport.log level, msg, call_trace, task
45
+ end
46
+
47
+ def log_exception level= :error, ex
48
+ return if @@transport.nil?
49
+ task = log_exception_task level, ex
50
+ @@transport.log_exception level, ex, task
51
+ end
52
+
53
+ def get_transport
54
+ return if @@transport.nil?
55
+ @@transport
35
56
  end
36
57
 
37
58
  private
@@ -52,39 +73,13 @@ module Stackify
52
73
  end
53
74
 
54
75
  def log_message_task level, msg, call_trace, trans_id=nil, log_uuid=nil
55
- Stackify::ScheduleTask.new ({limit: 1}) do
56
- if %w(error fatal).include?(level)
57
- ex = if ruby_exception?(msg) && msg.class != Class
58
- msg.set_backtrace(call_trace)
59
- msg
60
- else
61
- e = StringException.new(msg)
62
- e.set_backtrace(call_trace)
63
- e
64
- end
65
- ex = StackifiedError.new(ex, binding())
66
- Stackify.msgs_queue << Stackify::MsgObject.new(level, ex.message, caller[0], trans_id, log_uuid, ex).to_h
67
- else
68
- Stackify.msgs_queue << Stackify::MsgObject.new(level, msg, caller[0], trans_id, log_uuid).to_h
69
- end
70
- end
76
+ return if @@transport.nil?
77
+ @@transport.log_message_task level, msg, call_trace, trans_id, log_uuid
71
78
  end
72
79
 
73
80
  def log_exception_task level, ex, trans_id=nil, log_uuid=nil
74
- Stackify::ScheduleTask.new ({limit: 1}) do
75
- Stackify.msgs_queue << Stackify::MsgObject.new(level, ex.message, caller[0], trans_id, log_uuid, ex).to_h
76
- end
77
- end
78
-
79
- def ruby_exception? klass
80
- klass = klass.class == Class ? klass : klass.class
81
- klasses = [klass]
82
- while klass != Object do
83
- klasses << klass.superclass
84
- klass = klass.superclass
85
- end
86
- klasses.include?(Exception)
81
+ return if @@transport.nil?
82
+ @@transport.log_exception_task level, ex, trans_id, log_uuid
87
83
  end
88
84
  end
89
-
90
85
  end
@@ -1,14 +1,16 @@
1
+
1
2
  module Stackify
2
3
  class LoggerProxy < Object
3
4
 
4
5
  def initialize logger
5
- @logger = logger
6
- @logger.level = Logger.const_get(Stackify.configuration.log_level.to_s.upcase)
6
+ rails_logger = logger
7
+ num_level = logger.level
8
+ @logger = rails_logger
7
9
  %w(debug info warn error fatal unknown).each do |level|
8
10
  stackify_logger = if level == 'debug'
9
- -> (msg, caller) { Stackify.logger_client.log(level.downcase, msg, caller) unless msg.to_s.empty? }
11
+ -> (msg, caller) { Stackify.logger_client.log(num_level, level.downcase, msg, caller) unless msg.to_s.empty? }
10
12
  else
11
- -> (msg, caller) { Stackify.logger_client.log(level.downcase, msg, caller) }
13
+ -> (msg, caller) { Stackify.logger_client.log(num_level, level.downcase, msg, caller) }
12
14
  end
13
15
  LoggerProxy.class_eval do
14
16
  define_method level.to_sym do |*args , &block|
@@ -3,13 +3,102 @@ module Stackify
3
3
 
4
4
  LOGS_URI = URI("#{Stackify.configuration.base_api_url}/Log/Save")
5
5
 
6
+ def initialize
7
+ @@errors_governor = Stackify::ErrorsGovernor.new
8
+ end
9
+
10
+ def log level, msg, call_trace, task
11
+ Stackify::Utils.do_only_if_authorized_and_mode_is_on Stackify::MODES[:logging] do
12
+ if acceptable?(level, msg) && Stackify.working?
13
+ worker = Stackify::AddMsgWorker.new
14
+ worker.async_perform ScheduleDelay.new, task
15
+ end
16
+ end
17
+ end
18
+
19
+ def log_exception level= :error, ex, task
20
+ if ex.is_a?(Stackify::StackifiedError)
21
+ Stackify::Utils.do_only_if_authorized_and_mode_is_on Stackify::MODES[:logging] do
22
+ if acceptable?(level, ex.message) && Stackify.working?
23
+ if @@errors_governor.can_send? ex
24
+ worker = Stackify::AddMsgWorker.new
25
+ worker.async_perform ScheduleDelay.new, task
26
+ else
27
+ Stackify.internal_log :warn,
28
+ "LoggerClient: logging of exception with message \"#{ex.message}\" is skipped - flood_limit is exceeded"
29
+ end
30
+ end
31
+ end
32
+ else
33
+ Stackify.log_internal_error 'LoggerClient: log_exception should get StackifiedError object'
34
+ end
35
+ end
36
+
37
+ def has_error msg
38
+ !msg['Ex'].nil?
39
+ end
40
+
41
+ def get_epoch msg
42
+ msg['EpochMs']
43
+ end
44
+
45
+ def log_message_task level, msg, call_trace, trans_id=nil, log_uuid=nil
46
+ Stackify::ScheduleTask.new ({limit: 1}) do
47
+ if %w(error fatal).include?(level)
48
+ ex = if ruby_exception?(msg) && msg.class != Class
49
+ msg.set_backtrace(call_trace)
50
+ msg
51
+ else
52
+ e = StringException.new(msg)
53
+ e.set_backtrace(call_trace)
54
+ e
55
+ end
56
+ ex = StackifiedError.new(ex, binding())
57
+ Stackify.msgs_queue << Stackify::MsgObject.new(level, ex.message, caller[0], trans_id, log_uuid, ex).to_h
58
+ else
59
+ Stackify.msgs_queue << Stackify::MsgObject.new(level, msg, caller[0], trans_id, log_uuid).to_h
60
+ end
61
+ end
62
+ end
63
+
64
+ def log_exception_task level, ex, trans_id=nil, log_uuid=nil
65
+ Stackify::ScheduleTask.new ({limit: 1}) do
66
+ Stackify.msgs_queue << Stackify::MsgObject.new(level, ex.message, caller[0], trans_id, log_uuid, ex).to_h
67
+ end
68
+ end
69
+
6
70
  def send_logs msgs, attempts = 3
7
71
  worker = Stackify::LogsSenderWorker.new
8
72
  task = send_logs_task attempts, msgs
9
73
  worker.async_perform ScheduleDelay.new, task
10
74
  end
11
75
 
12
- private
76
+ private
77
+
78
+ def acceptable? level, msg
79
+ Stackify.is_valid? && is_correct_log_level?(level) &&
80
+ is_not_internal_log_message?(msg)
81
+ end
82
+
83
+ def is_not_internal_log_message? msg
84
+ msg.try(:index, ::Stackify::INTERNAL_LOG_PREFIX).nil?
85
+ end
86
+
87
+ def is_correct_log_level? level
88
+ config_level = Logger.const_get Stackify.configuration.log_level.to_s.upcase
89
+ current_level = Logger.const_get level.to_s.upcase
90
+ current_level >= config_level
91
+ end
92
+
93
+ def ruby_exception? klass
94
+ klass = klass.class == Class ? klass : klass.class
95
+ klasses = [klass]
96
+ while klass != Object do
97
+ klasses << klass.superclass
98
+ klass = klass.superclass
99
+ end
100
+ klasses.include?(Exception)
101
+ end
13
102
 
14
103
  def properties
15
104
  {
@@ -1,6 +1,6 @@
1
1
  module Stackify::Metrics
2
2
  class MetricsClient
3
-
3
+ TEN_MINUTES = 600
4
4
  attr_reader :metrics_queue
5
5
 
6
6
  def initialize
@@ -57,7 +57,7 @@ module Stackify::Metrics
57
57
 
58
58
  def start_upload_metrics
59
59
  current_time = Stackify::Utils.rounded_current_time
60
- purge_older_than = current_time - 10.minutes
60
+ purge_older_than = current_time - TEN_MINUTES
61
61
  #read everything up to the start of the current minute
62
62
  read_queued_metrics_batch current_time
63
63
  handle_zero_reports current_time
@@ -67,7 +67,7 @@ module Stackify::Metrics
67
67
  if first_50_metrics.length > 0
68
68
  #only getting metrics less than 10 minutes old to drop old data in case we get backed up
69
69
  #they are removed from the @aggregated_metrics in the upload function upon success
70
- upload_aggregates(first_50_metrics.select { |_key, aggr| aggr.occurred_utc > current_time - 10.minutes })
70
+ upload_aggregates(first_50_metrics.select { |_key, aggr| aggr.occurred_utc > current_time - TEN_MINUTES })
71
71
  end
72
72
  @aggregate_metrics.delete_if { |_key, aggr| aggr.occurred_utc < purge_older_than }
73
73
  end
@@ -34,7 +34,7 @@ module Stackify
34
34
  Stackify.internal_log :info, '[MsgsQueue] All remained logs are going to be sent'
35
35
  Stackify.shutdown_all
36
36
  if self.length > 0
37
- Stackify.logs_sender.send_logs(pop_all)
37
+ Stackify.get_transport.send_logs(pop_all)
38
38
  Stackify.status = Stackify::STATUSES[:terminated]
39
39
  end
40
40
  end
@@ -47,7 +47,12 @@ module Stackify
47
47
  Stackify.internal_log :debug, "[MsgsQueue] add_msg() Newly created worker <#{@worker.name}>"
48
48
  end
49
49
  self.synchronize do
50
- Stackify::Utils.do_only_if_authorized_and_mode_is_on Stackify::MODES[:logging] do
50
+ case Stackify.configuration.transport
51
+ when Stackify::DEFAULT
52
+ Stackify::Utils.do_only_if_authorized_and_mode_is_on Stackify::MODES[:logging] do
53
+ old_push(msg)
54
+ end
55
+ when Stackify::UNIX_SOCKET, Stackify::AGENT_HTTP
51
56
  old_push(msg)
52
57
  end
53
58
  end
@@ -109,13 +114,13 @@ module Stackify
109
114
  if length > 0
110
115
  msg = pop
111
116
  chunk << msg
112
- chunk_weight += (msg['Ex'].nil? ? LOG_SIZE : ERROR_SIZE)
113
- break if msg['EpochMs'] > started_at || CHUNK_MIN_WEIGHT > 50
117
+ chunk_weight += Stackify.get_transport.has_error(msg) ? ERROR_SIZE : LOG_SIZE
118
+ break if Stackify.get_transport.get_epoch(msg) > started_at || CHUNK_MIN_WEIGHT > 50
114
119
  else
115
120
  break
116
121
  end
117
122
  end
118
- Stackify.logs_sender.send_logs(chunk) if chunk.length > 0
123
+ Stackify.get_transport.send_logs(chunk) if chunk.length > 0
119
124
  chunk_weight
120
125
  end
121
126
  end
@@ -0,0 +1,15 @@
1
+ module Stackify
2
+ class TransportSelector
3
+
4
+ attr_reader :transport
5
+
6
+ def initialize type
7
+ case type
8
+ when Stackify::DEFAULT
9
+ @transport = Stackify::LogsSender.new
10
+ when Stackify::UNIX_SOCKET, Stackify::AGENT_HTTP
11
+ @transport = Stackify::AgentClient.new
12
+ end
13
+ end
14
+ end
15
+ end