stackify-api-ruby 1.0.15 → 1.2.9

Sign up to get free protection for your applications and to get access to all the features.
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