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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd19881ee793a2b23b9137218fd184427d9a9502efd1b81ba2064f23626d1228
4
- data.tar.gz: 9c3757c006c8f013afb097cf8a0cb7e016f1b1314375dfacfe3bd2d87403a9c8
3
+ metadata.gz: 371cb99e1d47ff1680b37a4e4a8b69a992787ef047c3973e923bb08032486239
4
+ data.tar.gz: 379714698256d7614a12b1e07e996e5a0256f868df5db33e103ec136fd8eec01
5
5
  SHA512:
6
- metadata.gz: bee61b9d0b9b18a3ad4db32dd6b7680b3e6c7db50979cdf1a8f9f222c97465c295474f05c757c734fa26b2082a4e5cbdf541083173c295d0bb48071bc64f04db
7
- data.tar.gz: 87ac37dd7b3ec51fc91f79eadad7316c587e25ee2e55844a974437cd4ad731c9ece070178ff51366f6132696cc93bd21c2cdb5eaa8c92df46d8b586ef265415d
6
+ metadata.gz: f7aff04aee12c3a8346c39fb32f34965f360e969e960607053685c3081b2a27a333e4e7842d87f486d3ddb2341b49f18107276c96d8090d1b90e6ea258b766ab
7
+ data.tar.gz: 7e2d3a430f5794f6e29689255adc9be0dd36b4bddc9504507161c1a0d0edd4699bfa1df675c803f0bc1c4bd4090d2b080bf78886837f89f0b84d74e7f673f050
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- stackify-api-ruby (1.0.15)
4
+ stackify-api-ruby (1.1.0)
5
5
  faraday (~> 0.8)
6
6
 
7
7
  GEM
@@ -1,3 +1,2 @@
1
1
  require 'json'
2
2
  require 'core_ext/object'
3
- require 'core_ext/fixnum'
@@ -0,0 +1,102 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: stackify-agent.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ Google::Protobuf::DescriptorPool.generated_pool.build do
7
+ add_message "stackify.LogGroup" do
8
+ optional :environment, :string, 1
9
+ optional :server_name, :string, 2
10
+ optional :application_name, :string, 3
11
+ optional :application_location, :string, 4
12
+ optional :logger, :string, 5
13
+ optional :platform, :string, 6
14
+ repeated :logs, :message, 7, "stackify.LogGroup.Log"
15
+ optional :container, :message, 8, "stackify.LogGroup.Container"
16
+ optional :kubernetes, :message, 9, "stackify.LogGroup.Kubernetes"
17
+ end
18
+ add_message "stackify.LogGroup.Container" do
19
+ optional :image_id, :string, 1
20
+ optional :image_repository, :string, 2
21
+ optional :image_tag, :string, 3
22
+ optional :container_id, :string, 4
23
+ optional :container_name, :string, 5
24
+ end
25
+ add_message "stackify.LogGroup.Kubernetes" do
26
+ optional :pod_name, :string, 1
27
+ optional :pod_namespace, :string, 2
28
+ optional :cluster_name, :string, 3
29
+ end
30
+ add_message "stackify.LogGroup.Log" do
31
+ optional :message, :string, 1
32
+ optional :data, :string, 2
33
+ optional :thread_name, :string, 3
34
+ optional :date_millis, :int64, 4
35
+ optional :level, :string, 5
36
+ optional :transaction_id, :string, 6
37
+ optional :source_method, :string, 7
38
+ optional :source_line, :int32, 8
39
+ optional :id, :string, 9
40
+ repeated :tags, :string, 10
41
+ optional :error, :message, 11, "stackify.LogGroup.Log.Error"
42
+ end
43
+ add_message "stackify.LogGroup.Log.Error" do
44
+ optional :environment_detail, :message, 1, "stackify.LogGroup.Log.Error.EnvironmentDetail"
45
+ optional :date_millis, :int64, 2
46
+ optional :error_item, :message, 3, "stackify.LogGroup.Log.Error.ErrorItem"
47
+ optional :web_request_detail, :message, 4, "stackify.LogGroup.Log.Error.WebRequestDetail"
48
+ map :server_variables, :string, :string, 5
49
+ optional :customer_name, :string, 6
50
+ optional :username, :string, 7
51
+ end
52
+ add_message "stackify.LogGroup.Log.Error.EnvironmentDetail" do
53
+ optional :device_name, :string, 1
54
+ optional :application_name, :string, 2
55
+ optional :application_location, :string, 3
56
+ optional :configured_application_name, :string, 4
57
+ optional :configured_environment_name, :string, 5
58
+ end
59
+ add_message "stackify.LogGroup.Log.Error.ErrorItem" do
60
+ optional :message, :string, 1
61
+ optional :error_type, :string, 2
62
+ optional :error_type_code, :string, 3
63
+ map :data, :string, :string, 4
64
+ optional :source_method, :string, 5
65
+ repeated :stacktrace, :message, 6, "stackify.LogGroup.Log.Error.ErrorItem.TraceFrame"
66
+ optional :inner_error, :message, 7, "stackify.LogGroup.Log.Error.ErrorItem"
67
+ end
68
+ add_message "stackify.LogGroup.Log.Error.ErrorItem.TraceFrame" do
69
+ optional :code_filename, :string, 1
70
+ optional :line_number, :int32, 2
71
+ optional :method, :string, 3
72
+ end
73
+ add_message "stackify.LogGroup.Log.Error.WebRequestDetail" do
74
+ optional :user_ip_address, :string, 1
75
+ optional :http_method, :string, 2
76
+ optional :request_protocol, :string, 3
77
+ optional :request_url, :string, 4
78
+ optional :request_url_root, :string, 5
79
+ optional :referral_url, :string, 6
80
+ map :headers, :string, :string, 7
81
+ map :cookies, :string, :string, 8
82
+ map :querystring, :string, :string, 9
83
+ map :post_data, :string, :string, 10
84
+ map :session_data, :string, :string, 11
85
+ optional :post_data_raw, :string, 12
86
+ optional :mvc_action, :string, 13
87
+ optional :mvc_controller, :string, 14
88
+ optional :mvc_area, :string, 15
89
+ end
90
+ end
91
+
92
+ module Stackify
93
+ LogGroup = Google::Protobuf::DescriptorPool.generated_pool.lookup("stackify.LogGroup").msgclass
94
+ LogGroup::Container = Google::Protobuf::DescriptorPool.generated_pool.lookup("stackify.LogGroup.Container").msgclass
95
+ LogGroup::Kubernetes = Google::Protobuf::DescriptorPool.generated_pool.lookup("stackify.LogGroup.Kubernetes").msgclass
96
+ LogGroup::Log = Google::Protobuf::DescriptorPool.generated_pool.lookup("stackify.LogGroup.Log").msgclass
97
+ LogGroup::Log::Error = Google::Protobuf::DescriptorPool.generated_pool.lookup("stackify.LogGroup.Log.Error").msgclass
98
+ LogGroup::Log::Error::EnvironmentDetail = Google::Protobuf::DescriptorPool.generated_pool.lookup("stackify.LogGroup.Log.Error.EnvironmentDetail").msgclass
99
+ LogGroup::Log::Error::ErrorItem = Google::Protobuf::DescriptorPool.generated_pool.lookup("stackify.LogGroup.Log.Error.ErrorItem").msgclass
100
+ LogGroup::Log::Error::ErrorItem::TraceFrame = Google::Protobuf::DescriptorPool.generated_pool.lookup("stackify.LogGroup.Log.Error.ErrorItem.TraceFrame").msgclass
101
+ LogGroup::Log::Error::WebRequestDetail = Google::Protobuf::DescriptorPool.generated_pool.lookup("stackify.LogGroup.Log.Error.WebRequestDetail").msgclass
102
+ end
@@ -2,11 +2,13 @@ require 'stackify/version'
2
2
  require 'stackify/utils/methods'
3
3
  require 'core_ext/core_ext' unless defined? Rails
4
4
 
5
+
5
6
  module Stackify
6
7
 
7
8
  INTERNAL_LOG_PREFIX = '[Stackify]'.freeze
8
9
  STATUSES = { working: 'working', terminating: 'terminating', terminated: 'terminated'}
9
10
  MODES = { logging: :logging, metrics: :metrics, both: :both }
11
+ TRANSPORT = [DEFAULT = 'default', UNIX_SOCKET = 'agent_socket', AGENT_HTTP = 'agent_http']
10
12
 
11
13
  autoload :Backtrace, 'stackify/utils/backtrace'
12
14
  autoload :MsgObject, 'stackify/utils/msg_object'
@@ -24,7 +26,12 @@ module Stackify
24
26
  autoload :AddMsgWorker, 'stackify/workers/add_msg_worker'
25
27
  autoload :MsgsQueue, 'stackify/msgs_queue'
26
28
  autoload :LoggerClient, 'stackify/logger_client'
29
+ autoload :AgentClient, 'stackify/agent_client'
30
+ autoload :TransportSelector, 'stackify/transport_selector'
27
31
  autoload :LogsSender, 'stackify/logs_sender'
32
+ autoload :AgentBaseSender, 'stackify/agent_base_sender'
33
+ autoload :UnixSocketSender, 'stackify/unix_socket_sender'
34
+ autoload :AgentHTTPSender, 'stackify/agent_http_sender'
28
35
  autoload :LoggerProxy, 'stackify/logger_proxy'
29
36
  autoload :StackifiedError, 'stackify/error'
30
37
  autoload :StringException, 'stackify/error'
@@ -44,6 +51,7 @@ module Stackify
44
51
  def setup
45
52
  @workers = []
46
53
  yield(configuration) if block_given?
54
+ configuration.validate_transport_type
47
55
  if configuration.is_valid?
48
56
  @status = STATUSES[:working]
49
57
  else
@@ -53,7 +61,6 @@ module Stackify
53
61
  end
54
62
  raise msg
55
63
  end
56
-
57
64
  end
58
65
 
59
66
  def msgs_queue
@@ -64,8 +71,16 @@ module Stackify
64
71
  @logger_client ||= Stackify::LoggerClient.new
65
72
  end
66
73
 
67
- def logs_sender
68
- @logs_sender ||= Stackify::LogsSender.new
74
+ def agent_client
75
+ @agent_client ||= Stackify::AgentClient.new
76
+ end
77
+
78
+ def get_transport
79
+ @logger_client.get_transport
80
+ end
81
+
82
+ def send_unix_socket
83
+ @unix_socket ||= Stackify::UnixSocketSender.new
69
84
  end
70
85
 
71
86
  def logger
@@ -105,24 +120,42 @@ module Stackify
105
120
 
106
121
  def run
107
122
  Stackify::Utils.is_api_enabled
123
+ Stackify.internal_log :info, "Stackify.run() transportType: #{Stackify.configuration.transport} | API version: #{Stackify::VERSION} | Ruby version: #{RUBY_VERSION}"
108
124
  if Stackify.configuration.api_enabled
109
125
  if Stackify.is_valid?
110
- at_exit { make_remained_job }
111
- t1 = Thread.new { Stackify.authorize }
112
- case Stackify.configuration.mode
113
- when MODES[:both]
114
- t2 = start_logging
115
- t3 = start_metrics
116
- when MODES[:logging]
117
- t2 = start_logging
118
- when MODES[:metrics]
119
- t3 = start_metrics
126
+ # check transport types
127
+ case Stackify.configuration.transport
128
+ when Stackify::DEFAULT
129
+ if Stackify.is_valid?
130
+ at_exit { make_remained_job }
131
+ t1 = Thread.new { Stackify.authorize }
132
+ case Stackify.configuration.mode
133
+ when MODES[:both]
134
+ t2 = start_logging
135
+ t3 = start_metrics
136
+ when MODES[:logging]
137
+ t2 = start_logging
138
+ when MODES[:metrics]
139
+ t3 = start_metrics
140
+ end
141
+ t1.join
142
+ t3.join if t3
143
+ else
144
+ Stackify.log_internal_error "Stackify is not properly configured! Errors: #{Stackify.configuration.errors}"
145
+ end
146
+ when Stackify::UNIX_SOCKET, Stackify::AGENT_HTTP
147
+ case Stackify.configuration.mode
148
+ when MODES[:logging]
149
+ start_logging
150
+ when MODES[:both]
151
+ start_logging
152
+ start_metrics
153
+ when MODES[:metrics]
154
+ start_metrics
155
+ end
156
+ else
157
+ Stackify.log_internal_error "Stackify is not properly configured! Errors: #{Stackify.configuration.errors}"
120
158
  end
121
-
122
- t1.join
123
- t3.join if t3
124
- else
125
- Stackify.log_internal_error "Stackify is not properly configured! Errors: #{Stackify.configuration.errors}"
126
159
  end
127
160
  end
128
161
  end
@@ -0,0 +1,53 @@
1
+ #
2
+ # This class will handle the sending of log group message to agent
3
+ #
4
+ module Stackify
5
+ class AgentBaseSender < Worker
6
+
7
+ # send_logs() Function to put the msg in the Worker
8
+ def send_logs msgs, attempts = 3
9
+ worker = Stackify::LogsSenderWorker.new('UnixSocketSender worker')
10
+ task = send_logs_task attempts, msgs
11
+ worker.async_perform ScheduleDelay.new, task
12
+ end
13
+
14
+ private
15
+
16
+ def properties
17
+ {
18
+ success_condition: lambda { |result| result.try(:status) == 200 },
19
+ limit: 1
20
+ }.dup
21
+ end
22
+
23
+ def send_logs_task attempts = nil, msgs
24
+ properties[:attempts] = attempts if attempts
25
+ Stackify::ScheduleTask.new properties do
26
+ data = gather_and_pack_data(msgs).to_json
27
+ send_request data
28
+ end
29
+ end
30
+
31
+ def gather_and_pack_data msgs
32
+ details = Stackify::EnvDetails.instance.auth_info
33
+ {
34
+ 'CDID' => details['DeviceID'],
35
+ 'CDAppID' => details['DeviceAppID'],
36
+ 'Logger' => 'Rails logger',
37
+ 'AppName' => details['AppName'],
38
+ 'AppNameID' => details['AppNameID'],
39
+ 'Env' => details['Env'],
40
+ 'EnvID' => details['EnvID'],
41
+ 'AppEnvID' => details['AppEnvID'],
42
+ 'ServerName' => details['DeviceName'],
43
+ 'Msgs' => msgs,
44
+ 'AppLoc' => details['AppLocation'],
45
+ 'Platform' => 'Ruby'
46
+ }
47
+ end
48
+
49
+ def send_request log_group
50
+ raise NotImplementedError
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,102 @@
1
+ module Stackify
2
+ class AgentClient
3
+
4
+ def initialize
5
+ Stackify.internal_log :info, '[AgentClient]: initialize()'
6
+ @@errors_governor = Stackify::ErrorsGovernor.new
7
+ case Stackify.configuration.transport
8
+ when Stackify::UNIX_SOCKET
9
+ @@sender = Stackify::UnixSocketSender.new
10
+ when Stackify::AGENT_HTTP
11
+ @@sender = Stackify::AgentHTTPSender.new
12
+ end
13
+ end
14
+
15
+ def log level, msg, call_trace, task
16
+ if acceptable?(level, msg) && Stackify.working?
17
+ worker = Stackify::AddMsgWorker.new
18
+ worker.async_perform ScheduleDelay.new, task
19
+ end
20
+ end
21
+
22
+ def log_exception level= :error, ex, task
23
+ if ex.is_a?(Stackify::StackifiedError)
24
+ if acceptable?(level, ex.message) && Stackify.working?
25
+ if @@errors_governor.can_send? ex
26
+ worker = Stackify::AddMsgWorker.new
27
+ worker.async_perform ScheduleDelay.new, task
28
+ else
29
+ Stackify.internal_log :warn,
30
+ "AgentClient: logging of exception with message \"#{ex.message}\" is skipped - flood_limit is exceeded"
31
+ end
32
+ end
33
+ else
34
+ Stackify.log_internal_error 'AgentClient: log_exception should get StackifiedError object'
35
+ end
36
+ end
37
+
38
+ def has_error msg
39
+ !msg['Ex'].nil?
40
+ end
41
+
42
+ def get_epoch msg
43
+ msg['EpochMs']
44
+ end
45
+
46
+ def send_logs msgs, attempts = 3
47
+ @@sender.send_logs msgs, attempts
48
+ end
49
+
50
+ def log_message_task level, msg, call_trace, trans_id=nil, log_uuid=nil
51
+ Stackify::ScheduleTask.new ({limit: 1}) do
52
+ if %w(error fatal).include?(level)
53
+ ex = if ruby_exception?(msg) && msg.class != Class
54
+ msg.set_backtrace(call_trace)
55
+ msg
56
+ else
57
+ e = StringException.new(msg)
58
+ e.set_backtrace(call_trace)
59
+ e
60
+ end
61
+ ex = StackifiedError.new(ex, binding())
62
+ Stackify.msgs_queue << Stackify::MsgObject.new(level, ex.message, caller[0], trans_id, log_uuid, ex).to_h
63
+ else
64
+ Stackify.msgs_queue << Stackify::MsgObject.new(level, msg, caller[0], trans_id, log_uuid).to_h
65
+ end
66
+ end
67
+ end
68
+
69
+ def log_exception_task level, ex, trans_id=nil, log_uuid=nil
70
+ Stackify::ScheduleTask.new ({limit: 1}) do
71
+ Stackify.msgs_queue << Stackify::MsgObject.new(level, ex.message, caller[0], trans_id, log_uuid, ex).to_h
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ def acceptable? level, msg
78
+ Stackify.is_valid? && is_correct_log_level?(level) &&
79
+ is_not_internal_log_message?(msg)
80
+ end
81
+
82
+ def is_not_internal_log_message? msg
83
+ msg.try(:index, ::Stackify::INTERNAL_LOG_PREFIX).nil?
84
+ end
85
+
86
+ def is_correct_log_level? level
87
+ config_level = Logger.const_get Stackify.configuration.log_level.to_s.upcase
88
+ current_level = Logger.const_get level.to_s.upcase
89
+ current_level >= config_level
90
+ end
91
+
92
+ def ruby_exception? klass
93
+ klass = klass.class == Class ? klass : klass.class
94
+ klasses = [klass]
95
+ while klass != Object do
96
+ klasses << klass.superclass
97
+ klass = klass.superclass
98
+ end
99
+ klasses.include?(Exception)
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,39 @@
1
+ require 'uri'
2
+ require 'faraday'
3
+ require 'ostruct'
4
+
5
+ #
6
+ # This class will handle the sending of log messages to agent using http request
7
+ #
8
+ module Stackify
9
+ class AgentHTTPSender < AgentBaseSender
10
+
11
+ HEADERS = {
12
+ 'Content-Type' => 'application/json'
13
+ }
14
+
15
+ # send_request() This function will post an http request
16
+ # @msgs {Object} log group message
17
+ # return {Object} Return an object {status, message}
18
+ def send_request log_group
19
+ begin
20
+ conn = Faraday.new(proxy: Stackify.configuration.proxy, ssl: { verify: false })
21
+ @response = conn.post do |req|
22
+ req.url URI(Stackify.configuration.http_endpoint + Stackify.configuration.agent_log_url)
23
+ req.headers = HEADERS
24
+ req.body = log_group
25
+ end
26
+ if @response.try(:status) == 200
27
+ Stackify.internal_log :debug, "[AgentHTTPSender]: Successfully send message via http request."
28
+ return OpenStruct.new({status: 200, msg: 'OK'})
29
+ else
30
+ Stackify.internal_log :debug, "[AgentHTTPSender] Sending failed."
31
+ return OpenStruct.new({status: 500, msg: 'Not OK'})
32
+ end
33
+ rescue => exception
34
+ Stackify.log_internal_error "[AgentHTTPSender] send_logs() Error: #{exception}"
35
+ return OpenStruct.new({status: 500, msg: exception})
36
+ end
37
+ end
38
+ end
39
+ end
@@ -11,7 +11,11 @@ module Stackify::Authorizable
11
11
  @@auth_client = nil
12
12
 
13
13
  def authorize attempts=3
14
- Stackify::EnvDetails.instance.set_rails_info
14
+ # Check if the ruby version is 2.0 we get the Rails info properties such as
15
+ # <Application root: e.g., /home/user/rails_app> which is required in authorization
16
+ if Gem::Version.new(RUBY_VERSION) <= Gem::Version.new('2.0')
17
+ Stackify::EnvDetails.instance.set_rails_info
18
+ end
15
19
  @@auth_lock.synchronize do
16
20
  return unless @@auth_client.nil?
17
21
  @@auth_client = Stackify::Authorizable::AuthorizationClient.new