stackify-api-ruby 1.2.4 → 1.3.0.beta1

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: d6e7d47c5f5d7eba2a6326a4efdc6823d57aec456a946bc3eefd7694a29a8078
4
- data.tar.gz: d2b022c023a0593391e7e190ca1e5784cdb56c4afacd010fa73d40fa581f9189
3
+ metadata.gz: ae96dffa800668cd0f8ab55fc62232c43951fbe5bf9700992698ece32bbbf006
4
+ data.tar.gz: 7e44e75717ecb342cdb632766708bb765793df1a92b534e689d59079c43d2bbd
5
5
  SHA512:
6
- metadata.gz: 5d3ac89a398d1bf3192c6ed4a4cf8ab27e0523f67839ce17ff3d2fe41243bce977fe4d46a8dd8a23d684603aaf2dc6cc0ede38877ae16456c83b4d2693ce1af6
7
- data.tar.gz: 61f4ded1b2cef4c418333adcfe893b999b637acc7a055a08b0c3664f95637414b21510718bd9f3a86f9e037f8dec241eeb2fb9c5b8f32afb5a924aaf46dcaac4
6
+ metadata.gz: 032502e0aff449fa9ad239f282751ee0699cffcca713f14dff414eaac255cbabba348bcbabc5f5800be8aadecd787c1a7ba9d92620a86cb41ee7f579a1f6d56b
7
+ data.tar.gz: 8e93149a91583a7f9accc6d6ba1e87767ea8daa96049fc25941b89b27f4a1c459e4d6cce050126306b8097d979b993b5ddfe0c984191b7f503a6bc3af50948a3
data/Gemfile CHANGED
@@ -1,4 +1,11 @@
1
- source 'https://rubygems.org'
1
+ group :test do
2
+ if ENV['STACKIFY_RUBY_TEST']
3
+ gem 'stackify-ruby-apm', '~> 1.15', source: ENV['STACKIFY_RUBY_TEST_REPO']
4
+ else
5
+ gem 'stackify-ruby-apm', '~> 1.15'
6
+ end
7
+ end
2
8
 
9
+ source 'https://rubygems.org'
3
10
  # Specify your gem's dependencies in stackify.gemspec
4
11
  gemspec
data/Gemfile.lock CHANGED
@@ -1,24 +1,62 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- stackify-api-ruby (1.1.0)
4
+ stackify-api-ruby (1.3.0.beta1)
5
5
  faraday (~> 0.8)
6
+ net_http_unix (~> 0.2)
6
7
 
7
8
  GEM
8
9
  remote: https://rubygems.org/
9
10
  specs:
10
- faraday (0.15.4)
11
+ concurrent-ruby (1.1.9)
12
+ diff-lcs (1.4.4)
13
+ et-orbi (1.2.4)
14
+ tzinfo
15
+ faraday (0.17.4)
11
16
  multipart-post (>= 1.2, < 3)
12
- multipart-post (2.0.0)
17
+ fugit (1.5.0)
18
+ et-orbi (~> 1.1, >= 1.1.8)
19
+ raabro (~> 1.4)
20
+ multipart-post (2.1.1)
21
+ net_http_unix (0.2.2)
22
+ raabro (1.4.0)
13
23
  rake (0.9.6)
24
+ rspec (3.10.0)
25
+ rspec-core (~> 3.10.0)
26
+ rspec-expectations (~> 3.10.0)
27
+ rspec-mocks (~> 3.10.0)
28
+ rspec-core (3.10.1)
29
+ rspec-support (~> 3.10.0)
30
+ rspec-expectations (3.10.1)
31
+ diff-lcs (>= 1.2.0, < 2.0)
32
+ rspec-support (~> 3.10.0)
33
+ rspec-mocks (3.10.2)
34
+ diff-lcs (>= 1.2.0, < 2.0)
35
+ rspec-support (~> 3.10.0)
36
+ rspec-support (3.10.2)
37
+ rufus-scheduler (3.8.0)
38
+ fugit (~> 1.1, >= 1.1.6)
39
+ stackify-ruby-apm (1.15.1)
40
+ concurrent-ruby (~> 1.0)
41
+ faraday (~> 0.8)
42
+ net_http_unix (~> 0.2)
43
+ rufus-scheduler (~> 3.0)
44
+ tzinfo (2.0.4)
45
+ concurrent-ruby (~> 1.0)
46
+ tzinfo-data (1.2021.1)
47
+ tzinfo (>= 1.0.0)
14
48
 
15
49
  PLATFORMS
16
50
  ruby
51
+ x86-mingw32
17
52
 
18
53
  DEPENDENCIES
19
54
  bundler (~> 1.6)
20
55
  rake (~> 0)
56
+ rspec (~> 3.0)
21
57
  stackify-api-ruby!
58
+ stackify-ruby-apm (~> 1.15)
59
+ tzinfo-data
22
60
 
23
61
  BUNDLED WITH
24
- 1.17.3
62
+ 1.17.13
data/README.md CHANGED
@@ -124,6 +124,23 @@ We can configure every metric with settings:
124
124
 
125
125
  Note, "autoreport_last_value_if_nothing_reported" property has influence only on "average" metric.
126
126
 
127
+ ### **Real User Monitoring (RUM)**
128
+
129
+ Real user monitoring injects a script tag containing the [RUM JS](https://stackify.com/retrace-real-user-monitoring/) that is responsible for capturing information about the http requests on the browser. This approach is manual and needs to be configured.
130
+
131
+ #### RUM - Setup
132
+
133
+ ```ruby
134
+ # Configuration - Standard API
135
+ Stackify.setup do |config|
136
+ ...
137
+ config.rum_key = "YourRumKey"
138
+ end
139
+
140
+ # Use this to apply on views
141
+ Stackify.rum.insert_rum_script
142
+ ```
143
+
127
144
  ## Troubleshooting
128
145
 
129
146
  If there are problems, you can enable internal logging of the stackify-api-ruby project. Uncomment out the config.logger and config.logger.level lines in the 'config/initializers/stackify.rb' file:
@@ -1,3 +1,2 @@
1
1
  require 'json'
2
2
  require 'core_ext/object'
3
- require 'core_ext/fixnum'
@@ -2,8 +2,6 @@ require 'stackify/version'
2
2
  require 'stackify/utils/methods'
3
3
  require 'core_ext/core_ext' unless defined? Rails
4
4
 
5
- require 'google/protobuf'
6
- require 'proto/stackify-agent.rb'
7
5
 
8
6
  module Stackify
9
7
 
@@ -14,7 +12,6 @@ module Stackify
14
12
 
15
13
  autoload :Backtrace, 'stackify/utils/backtrace'
16
14
  autoload :MsgObject, 'stackify/utils/msg_object'
17
- autoload :ProtobufLogObject, 'stackify/utils/protobuf_log_object'
18
15
  autoload :Configuration, 'stackify/utils/configuration'
19
16
  autoload :HttpClient, 'stackify/http_client'
20
17
  autoload :Authorizable, 'stackify/authorization/authorizable'
@@ -40,6 +37,7 @@ module Stackify
40
37
  autoload :StringException, 'stackify/error'
41
38
  autoload :ErrorsGovernor, 'stackify/errors_governor'
42
39
  autoload :Metrics, 'stackify/metrics/metrics'
40
+ autoload :Rum, 'stackify/rum'
43
41
 
44
42
  include Authorizable
45
43
 
@@ -51,6 +49,10 @@ module Stackify
51
49
  @config ||= Stackify::Configuration.new
52
50
  end
53
51
 
52
+ def rum
53
+ @rum ||= Stackify::Rum.new(configuration)
54
+ end
55
+
54
56
  def setup
55
57
  @workers = []
56
58
  yield(configuration) if block_given?
@@ -123,7 +125,7 @@ module Stackify
123
125
 
124
126
  def run
125
127
  Stackify::Utils.is_api_enabled
126
- Stackify.internal_log :info, "Stackify.run() transportType = #{Stackify.configuration.transport} | API version: #{Stackify::VERSION}"
128
+ Stackify.internal_log :info, "Stackify.run() transportType: #{Stackify.configuration.transport} | API version: #{Stackify::VERSION} | Ruby version: #{RUBY_VERSION}"
127
129
  if Stackify.configuration.api_enabled
128
130
  if Stackify.is_valid?
129
131
  # check transport types
@@ -1,5 +1,5 @@
1
1
  #
2
- # This class will handle the sending of protobuf message to agent
2
+ # This class will handle the sending of log group message to agent
3
3
  #
4
4
  module Stackify
5
5
  class AgentBaseSender < Worker
@@ -23,28 +23,27 @@ module Stackify
23
23
  def send_logs_task attempts = nil, msgs
24
24
  properties[:attempts] = attempts if attempts
25
25
  Stackify::ScheduleTask.new properties do
26
- data = create_log_group msgs
26
+ data = gather_and_pack_data(msgs).to_json
27
27
  send_request data
28
28
  end
29
29
  end
30
30
 
31
- # create_log_group() This function will create a log group protobuf object
32
- # @msgs {Object} Protobuf message
33
- # return {Object} Return an object
34
- def create_log_group msgs
35
- # @details {Object} it will return the properties based in Stackify.setup() configuration
36
- details = Stackify::Utils.get_app_settings
37
- log_group = Stackify::LogGroup.new
38
- msgs.each do |msg|
39
- log_group.logs << msg
40
- end
41
- log_group.environment = details['env'].to_s
42
- log_group.server_name = details['server_name'].to_s
43
- log_group.application_name = details['app_name'].to_s
44
- log_group.application_location = details['app_location'].to_s
45
- log_group.logger = 'Ruby logger'
46
- log_group.platform = 'ruby'
47
- log_group
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
+ }
48
47
  end
49
48
 
50
49
  def send_request log_group
@@ -36,11 +36,11 @@ module Stackify
36
36
  end
37
37
 
38
38
  def has_error msg
39
- !msg.error.nil?
39
+ !msg['Ex'].nil?
40
40
  end
41
41
 
42
42
  def get_epoch msg
43
- msg.date_millis
43
+ msg['EpochMs']
44
44
  end
45
45
 
46
46
  def send_logs msgs, attempts = 3
@@ -59,16 +59,16 @@ module Stackify
59
59
  e
60
60
  end
61
61
  ex = StackifiedError.new(ex, binding())
62
- Stackify.msgs_queue << Stackify::ProtobufLogObject.new(level, ex.message, caller[0], trans_id, log_uuid, ex).to_obj
62
+ Stackify.msgs_queue << Stackify::MsgObject.new(level, ex.message, caller[0], trans_id, log_uuid, ex).to_h
63
63
  else
64
- Stackify.msgs_queue << Stackify::ProtobufLogObject.new(level, msg, caller[0], trans_id, log_uuid).to_obj
64
+ Stackify.msgs_queue << Stackify::MsgObject.new(level, msg, caller[0], trans_id, log_uuid).to_h
65
65
  end
66
66
  end
67
67
  end
68
68
 
69
69
  def log_exception_task level, ex, trans_id=nil, log_uuid=nil
70
70
  Stackify::ScheduleTask.new ({limit: 1}) do
71
- Stackify.msgs_queue << Stackify::ProtobufLogObject.new(level, ex.message, caller[0], trans_id, log_uuid, ex).to_obj
71
+ Stackify.msgs_queue << Stackify::MsgObject.new(level, ex.message, caller[0], trans_id, log_uuid, ex).to_h
72
72
  end
73
73
  end
74
74
 
@@ -3,27 +3,25 @@ require 'faraday'
3
3
  require 'ostruct'
4
4
 
5
5
  #
6
- # This class will handle the sending of protobuf message to agent using http request
6
+ # This class will handle the sending of log messages to agent using http request
7
7
  #
8
8
  module Stackify
9
9
  class AgentHTTPSender < AgentBaseSender
10
10
 
11
11
  HEADERS = {
12
- 'Content-Type' => 'application/x-protobuf'
12
+ 'Content-Type' => 'application/json'
13
13
  }
14
14
 
15
15
  # send_request() This function will post an http request
16
- # @msgs {Object} Protobuf message
16
+ # @msgs {Object} log group message
17
17
  # return {Object} Return an object {status, message}
18
18
  def send_request log_group
19
19
  begin
20
- # Convert data into binary and send it to agent
21
- message = Stackify::LogGroup.encode(log_group)
22
20
  conn = Faraday.new(proxy: Stackify.configuration.proxy, ssl: { verify: false })
23
21
  @response = conn.post do |req|
24
22
  req.url URI(Stackify.configuration.http_endpoint + Stackify.configuration.agent_log_url)
25
23
  req.headers = HEADERS
26
- req.body = message
24
+ req.body = log_group
27
25
  end
28
26
  if @response.try(:status) == 200
29
27
  Stackify.internal_log :debug, "[AgentHTTPSender]: Successfully send message via http request."
@@ -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
@@ -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,28 @@ module Stackify
14
39
  end
15
40
  end
16
41
 
42
+ def set_console_logs new_logger
43
+ if Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new('6.0')
44
+ ActiveSupport.on_load(:action_controller_base) do
45
+ logger = new_logger
46
+ end
47
+ ActiveSupport.on_load(:action_view) do
48
+ logger = new_logger
49
+ end
50
+ ActiveSupport.on_load(:active_record) do
51
+ logger = new_logger
52
+ end
53
+ else
54
+ # Handle the stdout logs from Action Controller
55
+ ActionController::Base.logger = new_logger
56
+
57
+ # Handle the stdout logs from Action View
58
+ ActionView::Base.logger = new_logger
59
+
60
+ # Handle the stdout logs from Active Record
61
+ ActiveRecord::Base.logger = new_logger
62
+ end
63
+ end
17
64
  end
18
65
 
19
66
  end
@@ -40,7 +40,7 @@ module Stackify
40
40
 
41
41
  def to_h
42
42
  env = Stackify::EnvDetails.instance
43
- {
43
+ data = {
44
44
  'OccurredEpochMillis' => Time.now.to_f*1000,
45
45
  'Error' => {
46
46
  'InnerError' => @exception.try(:cause),
@@ -52,11 +52,20 @@ module Stackify
52
52
  'SourceMethod' => source_method,
53
53
  },
54
54
  'EnvironmentDetail' => env.auth_info,
55
- 'WebRequestDetail' => env.request_details.try{ |d| d.fetch('webrequest_details', '') },
56
- 'ServerVariables' => env.request_details.try{ |d| d.fetch('server_variables', '') },
57
55
  'CustomerName' => 'Customer',
58
56
  'UserName' => @context.fetch('user', '')
59
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
60
69
  end
61
70
 
62
71
  end
@@ -12,7 +12,33 @@ module Stackify
12
12
  end
13
13
  end
14
14
 
15
- def log level, msg, call_trace
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
35
+ end
36
+ end
37
+ end
38
+ else
39
+ puts msg if num_level <= Logger.const_get(level.upcase).to_i
40
+ end
41
+
16
42
  return if @@transport.nil?
17
43
  task = log_message_task level, msg, call_trace
18
44
  @@transport.log level, msg, call_trace, task
@@ -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|
@@ -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
@@ -0,0 +1,72 @@
1
+ $apmLoaded = false
2
+
3
+ begin
4
+ require 'stackify-ruby-apm'
5
+ $apmLoaded = true
6
+ rescue LoadError
7
+ end
8
+
9
+ module Stackify
10
+ class Rum
11
+ def initialize(config)
12
+ @config = config
13
+ end
14
+
15
+ def insert_rum_script()
16
+ return StackifyRubyAPM.inject_rum_script if Rum.apm_loaded && defined?(StackifyRubyAPM) && StackifyRubyAPM.respond_to?(:inject_rum_script)
17
+
18
+ return '' unless @config
19
+
20
+ config = @config
21
+
22
+ return '' if config.rum_script_url.to_s.empty? || config.rum_key.to_s.empty?
23
+
24
+ transaction_id = get_transaction_id().to_s
25
+ return '' if transaction_id.empty?
26
+
27
+ reporting_url = get_reporting_url().to_s
28
+ return '' if reporting_url.empty?
29
+
30
+ environment_name = defined?(config.env) ? config.env.to_s : 'Development'
31
+ return '' if environment_name.empty?
32
+
33
+ application_name = defined?(config.app_name) ? config.app_name.to_s : ''
34
+ return '' if application_name.empty?
35
+
36
+ rum_settings = {
37
+ "ID" => transaction_id
38
+ }
39
+
40
+ if !environment_name.empty?
41
+ rum_settings["Env"] = Base64.strict_encode64(environment_name.encode('utf-8'))
42
+ end
43
+
44
+ if !application_name.empty?
45
+ rum_settings["Name"] = Base64.strict_encode64(application_name.strip.encode('utf-8'))
46
+ end
47
+
48
+ if !reporting_url.empty?
49
+ rum_settings["Trans"] = Base64.strict_encode64(reporting_url.encode('utf-8'))
50
+ end
51
+
52
+ rum_content = "<script type=\"text/javascript\">(window.StackifySettings || (window.StackifySettings = #{rum_settings.to_json}))</script><script src=\"#{config.rum_script_url}\" data-key=\"#{config.rum_key}\" async></script>"
53
+ if rum_content.respond_to?(:html_safe)
54
+ rum_content.html_safe
55
+ else
56
+ rum_content
57
+ end
58
+ end
59
+
60
+ def self.apm_loaded
61
+ $apmLoaded
62
+ end
63
+
64
+ def get_reporting_url
65
+ ''
66
+ end
67
+
68
+ def get_transaction_id
69
+ ''
70
+ end
71
+ end
72
+ end
@@ -2,22 +2,20 @@ require 'net_http_unix'
2
2
  require 'ostruct'
3
3
 
4
4
  #
5
- # This class will handle the sending of protobuf message to unix domain socket
5
+ # This class will handle the sending of log messages to unix domain socket
6
6
  #
7
7
  module Stackify
8
8
  class UnixSocketSender < AgentBaseSender
9
9
 
10
10
  # send_request() This function will send http request via unix domain socket
11
- # @msgs {Object} Protobuf message
11
+ # @msgs {Object} log group message
12
12
  # return {Object} Return an object {status, message}
13
13
  def send_request log_group
14
14
  begin
15
- # Convert data into binary and send it to unix domain socket
16
- message = Stackify::LogGroup.encode(log_group)
17
15
  client = NetX::HTTPUnix.new('unix://' + Stackify.configuration.unix_socket_path)
18
16
  req = Net::HTTP::Post.new(Stackify.configuration.agent_log_url)
19
- req.set_content_type('application/x-protobuf')
20
- req.body = message
17
+ req.set_content_type('application/json')
18
+ req.body = log_group
21
19
  response = client.request(req)
22
20
  Stackify.internal_log :debug, "[UnixSocketSender] status_code = #{response.code}"
23
21
  if response.code.to_i == 200
@@ -3,6 +3,7 @@ module Stackify::Backtrace
3
3
  ALL_TEXT_FROM_START_TO_FIRST_COLON_REGEXP = /\A([^:]+)/
4
4
  NUMBER_BETWEEN_TWO_COLONS_REGEXP = /:(\d+):/
5
5
  TEXT_AFTER_IN_BEFORE_END_REGEXP = /in\s`(\S+)'\z/
6
+ TEXT_AFTER_IN_BEFORE_END_REGEXP_ = /in\s(\S+)'\z/
6
7
 
7
8
  def self.line_number backtrace_str
8
9
  backtrace_str[NUMBER_BETWEEN_TWO_COLONS_REGEXP, 1]
@@ -10,7 +11,7 @@ module Stackify::Backtrace
10
11
 
11
12
  def self.method_name backtrace_str
12
13
  return nil unless backtrace_str
13
- backtrace_str[TEXT_AFTER_IN_BEFORE_END_REGEXP, 1]
14
+ backtrace_str[TEXT_AFTER_IN_BEFORE_END_REGEXP, 1] || backtrace_str[TEXT_AFTER_IN_BEFORE_END_REGEXP_, 1]
14
15
  end
15
16
 
16
17
  def self.file_name backtrace_str
@@ -3,9 +3,10 @@ module Stackify
3
3
  class Configuration
4
4
 
5
5
  attr_accessor :api_key, :app_name, :app_location, :env, :log_level, :logger,
6
- :proxy, :mode, :base_api_url, :api_enabled, :transport, :errors, :http_endpoint
6
+ :proxy, :mode, :base_api_url, :api_enabled, :transport, :errors, :http_endpoint, :stdout_output, :buffered_logger
7
7
 
8
- attr_reader :send_interval, :flood_limit, :queue_max_size, :agent_log_url, :unix_socket_path, :http_endpoint
8
+ attr_reader :send_interval, :flood_limit, :queue_max_size, :agent_log_url, :unix_socket_path, :http_endpoint,
9
+ :rum_key, :rum_script_url
9
10
 
10
11
  def initialize
11
12
  @base_api_url = 'https://api.stackify.com'
@@ -25,6 +26,13 @@ module Stackify
25
26
  @agent_log_url = '/log'
26
27
  @unix_socket_path = '/usr/local/stackify/stackify.sock'
27
28
  @http_endpoint = get_env 'STACKIFY_TRANSPORT_HTTP_ENDPOINT', 'https://localhost:10601'
29
+ @stdout_output = false
30
+ @buffered_logger = false
31
+ @default_rum_script_url = 'https://stckjs.stackify.com/stckjs.js'
32
+ @default_rum_key = ''
33
+
34
+ self.rum_key = get_env 'RETRACE_RUM_KEY', @default_rum_key
35
+ self.rum_script_url = get_env 'RETRACE_RUM_SCRIPT_URL', @default_rum_script_url
28
36
  end
29
37
 
30
38
  def get_env env_key, default
@@ -50,6 +58,28 @@ module Stackify
50
58
  @errors << 'Transport should be one of these values: [agent_socket, agent_http, default]. Should be a String.'
51
59
  end
52
60
 
61
+ def rum_script_url=(rum_script_url)
62
+ if rum_script_url.empty?
63
+ @rum_script_url = @default_rum_script_url
64
+ return
65
+ end
66
+
67
+ if validate_rum_script_url(rum_script_url)
68
+ @rum_script_url = rum_script_url
69
+ end
70
+ end
71
+
72
+ def rum_key=(rum_key)
73
+ if rum_key.empty?
74
+ @rum_key = @default_rum_key
75
+ return
76
+ end
77
+
78
+ if validate_rum_key(rum_key)
79
+ @rum_key = rum_key
80
+ end
81
+ end
82
+
53
83
  private
54
84
 
55
85
  def validate_config_types
@@ -108,5 +138,27 @@ module Stackify
108
138
  return true if MODES.has_value? @mode
109
139
  @errors << 'Mode should be one of these values: [:both, :logging, :metrics]'
110
140
  end
141
+
142
+ def validate_rum_script_url(rum_script_url)
143
+ result = false
144
+ if rum_script_url.is_a?(String) && !rum_script_url.empty?
145
+ result = rum_script_url =~ /^((((https?|ftps?|gopher|telnet|nntp):\/\/)|(mailto:|news:))(%[0-9A-Fa-f]{2}|[\-\(\)_\.!~*';\/?:@&=+$,A-Za-z0-9])+)([\)\.!';\/?:,][\[:blank:|:blank:\]])?$/
146
+ end
147
+ if !result
148
+ @errors << 'RUM Script URL is in invalid format.'
149
+ end
150
+ result
151
+ end
152
+
153
+ def validate_rum_key(rum_key)
154
+ result = false
155
+ if rum_key.is_a?(String) && !rum_key.empty?
156
+ result = rum_key =~ %r{^[A-Za-z0-9_-]+$}
157
+ end
158
+ if !result
159
+ @errors << 'RUM Key is in invalid format.'
160
+ end
161
+ result
162
+ end
111
163
  end
112
164
  end
@@ -46,4 +46,29 @@ module Stackify::Utils
46
46
  'app_location' => Stackify.configuration.app_location || Dir.pwd
47
47
  }
48
48
  end
49
- end
49
+
50
+ # Check if the app is running on rails and the logger output is using STDOUT
51
+ def self.check_log_output
52
+ if defined? Rails
53
+ if Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new('5.0')
54
+ Stackify.configuration.stdout_output = ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDOUT)
55
+ else
56
+ Stackify.configuration.stdout_output = self.logger_stdout
57
+ end
58
+ end
59
+ end
60
+
61
+ def self.logger_stdout
62
+ logdev = ::Rails.logger.instance_variable_get(:@logdev)
63
+ logger_source = logdev.dev if logdev.respond_to?(:dev)
64
+ sources = [$stdout]
65
+ found = sources.any? { |source| source == logger_source }
66
+ end
67
+
68
+ # Check if the rails version 3 and it's using the buffered logger
69
+ def self.check_buffered_logger
70
+ is_buffered_logger = false
71
+ is_buffered_logger = true if ::Rails.logger.is_a?(ActiveSupport::BufferedLogger)
72
+ Stackify.configuration.buffered_logger = is_buffered_logger
73
+ end
74
+ end
@@ -1,3 +1,3 @@
1
1
  module Stackify
2
- VERSION = '1.2.4'
2
+ VERSION = '1.3.0.beta1'
3
3
  end
@@ -3,6 +3,14 @@ module Stackify
3
3
 
4
4
  def initialize name = 'LogsSender worker'
5
5
  super
6
+ case Stackify.configuration.transport
7
+ when Stackify::DEFAULT
8
+ name = 'LogsSender worker'
9
+ when Stackify::UNIX_SOCKET
10
+ name = 'UnixSocketSender worker'
11
+ when Stackify::AGENT_HTTP
12
+ name = 'AgentHTTPSender worker'
13
+ end
6
14
  @name = name
7
15
  @name += " ##{self.id}"
8
16
  @type = :logs_send
data/spec/rum_spec.rb ADDED
@@ -0,0 +1,291 @@
1
+ require 'spec_helper'
2
+ require 'stackify-api-ruby'
3
+
4
+ module Stackify
5
+ RSpec.describe 'Rum - APM not loaded - Normal' do
6
+ it 'returns rum script with complete information from ENV' do
7
+ ENV['RETRACE_RUM_KEY'] = 'test-key'
8
+ ENV['RETRACE_RUM_SCRIPT_URL'] = 'https://test.com/test.js'
9
+
10
+ config = Stackify::Configuration.new
11
+ config.app_name = 'test'
12
+ config.env = 'test-env'
13
+
14
+ rum = Stackify::Rum.new(config)
15
+ reporting_url = "test reporting url"
16
+ transaction_id = "123-id"
17
+ rum_script_url = 'https://test.com/test.js'
18
+
19
+ rum_settings = {
20
+ "ID" => '123-id',
21
+ "Env" => Base64.strict_encode64('test-env'.encode('utf-8')),
22
+ "Name" => Base64.strict_encode64('test'.strip.encode('utf-8')), # TODO: Add helper function
23
+ "Trans" => Base64.strict_encode64('test reporting url'.encode('utf-8'))
24
+ }
25
+
26
+ expected_rum_script = "<script type=\"text/javascript\">(window.StackifySettings || (window.StackifySettings = #{rum_settings.to_json()}))<\/script><script src=\"#{rum_script_url}\" data-key=\"#{config.rum_key}\" async></script>"
27
+
28
+ allow(rum).to receive(:get_reporting_url).and_return(reporting_url)
29
+ allow(rum).to receive(:get_transaction_id).and_return(transaction_id)
30
+ allow(Rum).to receive(:apm_loaded).and_return(false)
31
+
32
+ rum_script = rum.insert_rum_script
33
+
34
+ expect(rum.get_reporting_url).to eq reporting_url
35
+ expect(rum.get_transaction_id).to eq transaction_id
36
+ expect(rum_script.to_s).not_to be_empty
37
+ expect(rum_script).to eq expected_rum_script
38
+
39
+ ENV.delete('RETRACE_RUM_KEY')
40
+ ENV.delete('RETRACE_RUM_SCRIPT_URL')
41
+ end
42
+
43
+ it 'returns rum script with complete information from Config' do
44
+ config = Stackify::Configuration.new
45
+ config.app_name = 'test'
46
+ config.env = 'test-env'
47
+ config.rum_script_url = 'https://test.com/test.js'
48
+ config.rum_key = 'asd'
49
+
50
+ rum = Stackify::Rum.new(config)
51
+ reporting_url = "test reporting url"
52
+ transaction_id = "123-id"
53
+ rum_script_url = 'https://test.com/test.js'
54
+ rum_key = 'asd'
55
+
56
+ rum_settings = {
57
+ "ID" => '123-id',
58
+ "Env" => Base64.strict_encode64('test-env'.encode('utf-8')),
59
+ "Name" => Base64.strict_encode64('test'.strip.encode('utf-8')), # TODO: Add helper function
60
+ "Trans" => Base64.strict_encode64('test reporting url'.encode('utf-8'))
61
+ }
62
+
63
+ expected_rum_script = "<script type=\"text/javascript\">(window.StackifySettings || (window.StackifySettings = #{rum_settings.to_json()}))<\/script><script src=\"#{rum_script_url}\" data-key=\"#{rum_key}\" async></script>"
64
+
65
+ allow(rum).to receive(:get_reporting_url).and_return(reporting_url)
66
+ allow(rum).to receive(:get_transaction_id).and_return(transaction_id)
67
+ allow(Rum).to receive(:apm_loaded).and_return(false)
68
+
69
+ rum_script = rum.insert_rum_script
70
+
71
+ expect(rum.get_reporting_url).to eq reporting_url
72
+ expect(rum.get_transaction_id).to eq transaction_id
73
+ expect(rum_script.to_s).not_to be_empty
74
+ expect(rum_script).to eq expected_rum_script
75
+ end
76
+ end
77
+
78
+ RSpec.describe 'Rum - APM not loaded - Invalid' do
79
+ it 'returns rum script with invalid rum script url from Config' do
80
+ config = Stackify::Configuration.new
81
+ config.app_name = 'test'
82
+ config.env = 'test-env'
83
+ config.rum_script_url = 'test.js'
84
+ config.rum_key = 'asd'
85
+
86
+ rum = Stackify::Rum.new(config)
87
+ reporting_url = "test reporting url"
88
+ transaction_id = "123-id"
89
+ rum_script_url = 'https://stckjs.stackify.com/stckjs.js'
90
+ rum_key = 'asd'
91
+
92
+ rum_settings = {
93
+ "ID" => '123-id',
94
+ "Env" => Base64.strict_encode64('test-env'.encode('utf-8')),
95
+ "Name" => Base64.strict_encode64('test'.strip.encode('utf-8')), # TODO: Add helper function
96
+ "Trans" => Base64.strict_encode64('test reporting url'.encode('utf-8'))
97
+ }
98
+
99
+ expected_rum_script = "<script type=\"text/javascript\">(window.StackifySettings || (window.StackifySettings = #{rum_settings.to_json()}))<\/script><script src=\"#{rum_script_url}\" data-key=\"#{rum_key}\" async></script>"
100
+
101
+ allow(rum).to receive(:get_reporting_url).and_return(reporting_url)
102
+ allow(rum).to receive(:get_transaction_id).and_return(transaction_id)
103
+ allow(Rum).to receive(:apm_loaded).and_return(false)
104
+
105
+ rum_script = rum.insert_rum_script
106
+
107
+ expect(rum.get_reporting_url).to eq reporting_url
108
+ expect(rum.get_transaction_id).to eq transaction_id
109
+ expect(rum_script.to_s).not_to be_empty
110
+ expect(rum_script).to eq expected_rum_script
111
+ end
112
+
113
+ it 'returns rum script with invalid rum key from Config' do
114
+ config = Stackify::Configuration.new
115
+ config.app_name = 'test'
116
+ config.env = 'test-env'
117
+ config.rum_script_url = 'test.js'
118
+ config.rum_key = '`asd'
119
+
120
+ rum = Stackify::Rum.new(config)
121
+ reporting_url = "test reporting url"
122
+ transaction_id = "123-id"
123
+ rum_script_url = 'https://stckjs.stackify.com/stckjs.js'
124
+ rum_key = 'asd'
125
+
126
+ rum_settings = {
127
+ "ID" => '123-id',
128
+ "Env" => Base64.strict_encode64('test-env'.encode('utf-8')),
129
+ "Name" => Base64.strict_encode64('test'.strip.encode('utf-8')), # TODO: Add helper function
130
+ "Trans" => Base64.strict_encode64('test reporting url'.encode('utf-8'))
131
+ }
132
+
133
+ expected_rum_script = "<script type=\"text/javascript\">(window.StackifySettings || (window.StackifySettings = #{rum_settings.to_json()}))<\/script><script src=\"#{rum_script_url}\" data-key=\"#{rum_key}\" async></script>"
134
+
135
+ allow(rum).to receive(:get_reporting_url).and_return(reporting_url)
136
+ allow(rum).to receive(:get_transaction_id).and_return(transaction_id)
137
+ allow(Rum).to receive(:apm_loaded).and_return(false)
138
+
139
+ rum_script = rum.insert_rum_script
140
+
141
+ expect(rum.get_reporting_url).to eq reporting_url
142
+ expect(rum.get_transaction_id).to eq transaction_id
143
+ expect(rum_script.to_s).to be_empty
144
+ expect(rum_script).not_to eq expected_rum_script
145
+ expect(config.rum_key).to be_empty
146
+ end
147
+
148
+ it 'returns rum script with no app name' do
149
+ config = Stackify::Configuration.new
150
+ config.app_name = ''
151
+ config.env = 'test-env'
152
+ config.rum_script_url = 'test.js'
153
+ config.rum_key = '`asd'
154
+
155
+ rum = Stackify::Rum.new(config)
156
+
157
+ reporting_url = "test reporting url"
158
+ transaction_id = "123-id"
159
+
160
+ allow(rum).to receive(:get_reporting_url).and_return(reporting_url)
161
+ allow(rum).to receive(:get_transaction_id).and_return(transaction_id)
162
+ allow(Rum).to receive(:apm_loaded).and_return(false)
163
+
164
+ rum_script = rum.insert_rum_script
165
+
166
+ expect(rum.get_reporting_url).to eq reporting_url
167
+ expect(rum.get_transaction_id).to eq transaction_id
168
+ expect(rum_script.to_s).to be_empty
169
+ expect(config.rum_key).to be_empty
170
+ expect(config.app_name).to be_empty
171
+ end
172
+
173
+ it 'returns rum script with no env' do
174
+ config = Stackify::Configuration.new
175
+ config.app_name = 'test'
176
+ config.rum_script_url = 'test.js'
177
+ config.rum_key = 'asd'
178
+
179
+ rum = Stackify::Rum.new(config)
180
+ reporting_url = "test reporting url"
181
+ transaction_id = "123-id"
182
+ rum_script_url = 'https://stckjs.stackify.com/stckjs.js'
183
+ rum_key = 'asd'
184
+
185
+ rum_settings = {
186
+ "ID" => '123-id',
187
+ "Env" => Base64.strict_encode64('production'.encode('utf-8')),
188
+ "Name" => Base64.strict_encode64('test'.strip.encode('utf-8')), # TODO: Add helper function
189
+ "Trans" => Base64.strict_encode64('test reporting url'.encode('utf-8'))
190
+ }
191
+
192
+ expected_rum_script = "<script type=\"text/javascript\">(window.StackifySettings || (window.StackifySettings = #{rum_settings.to_json()}))<\/script><script src=\"#{rum_script_url}\" data-key=\"#{rum_key}\" async></script>"
193
+
194
+ allow(rum).to receive(:get_reporting_url).and_return(reporting_url)
195
+ allow(rum).to receive(:get_transaction_id).and_return(transaction_id)
196
+ allow(Rum).to receive(:apm_loaded).and_return(false)
197
+
198
+ rum_script = rum.insert_rum_script
199
+
200
+ expect(rum.get_reporting_url).to eq reporting_url
201
+ expect(rum.get_transaction_id).to eq transaction_id
202
+ expect(rum_script.to_s).not_to be_empty
203
+ expect(rum_script).to eq expected_rum_script
204
+ expect(config.env).to eq :production
205
+ end
206
+
207
+ it 'returns rum script with no transaction id' do
208
+ config = Stackify::Configuration.new
209
+ config.app_name = 'test'
210
+ config.env = 'test-env'
211
+ config.rum_script_url = 'test.js'
212
+ config.rum_key = 'asd'
213
+
214
+ rum = Stackify::Rum.new(config)
215
+
216
+ reporting_url = "test reporting url"
217
+ transaction_id = ""
218
+
219
+ allow(rum).to receive(:get_reporting_url).and_return(reporting_url)
220
+ allow(rum).to receive(:get_transaction_id).and_return(transaction_id)
221
+ allow(Rum).to receive(:apm_loaded).and_return(false)
222
+
223
+ rum_script = rum.insert_rum_script
224
+
225
+ expect(rum.get_reporting_url).to eq reporting_url
226
+ expect(rum.get_transaction_id).to eq ""
227
+ expect(rum_script.to_s).to be_empty
228
+ end
229
+
230
+ it 'returns rum script with no reporting url' do
231
+ config = Stackify::Configuration.new
232
+ config.app_name = 'test'
233
+ config.env = 'test-env'
234
+ config.rum_script_url = 'test.js'
235
+ config.rum_key = 'asd'
236
+
237
+ rum = Stackify::Rum.new(config)
238
+
239
+ reporting_url = ""
240
+ transaction_id = "test-123"
241
+
242
+ allow(rum).to receive(:get_reporting_url).and_return(reporting_url)
243
+ allow(rum).to receive(:get_transaction_id).and_return(transaction_id)
244
+ allow(Rum).to receive(:apm_loaded).and_return(false)
245
+
246
+ rum_script = rum.insert_rum_script
247
+
248
+ expect(rum.get_reporting_url).to eq ""
249
+ expect(rum.get_transaction_id).to eq transaction_id
250
+ expect(rum_script.to_s).to be_empty
251
+ end
252
+ end
253
+
254
+ RSpec.describe 'Rum - APM loaded - Normal' do
255
+ it 'returns rum script with complete information from ENV' do
256
+ ENV['RETRACE_RUM_KEY'] = 'test-key'
257
+ ENV['RETRACE_RUM_SCRIPT_URL'] = 'https://test.com/test.js'
258
+ ENV['TZ'] = 'Europe/Paris' # For error
259
+
260
+ config = Stackify::Configuration.new
261
+ rum = Stackify::Rum.new(config)
262
+ reporting_url = "test reporting url"
263
+ transaction_id = "123-id"
264
+ rum_script_url = 'https://test.com/test.js'
265
+ rum_script = ""
266
+
267
+ StackifyRubyAPM.start
268
+ transaction = StackifyRubyAPM.transaction 'RUM Script Injection test' do
269
+ rum_script = rum.insert_rum_script
270
+ end.submit 200
271
+ StackifyRubyAPM.stop
272
+
273
+ rum_settings = {
274
+ "ID" => transaction.id(),
275
+ "Env" => Base64.strict_encode64('test'.encode('utf-8')),
276
+ "Name" => Base64.strict_encode64('Ruby Application'.strip.encode('utf-8')), # TODO: Add helper function
277
+ "Trans" => Base64.strict_encode64('RUM Script Injection test'.encode('utf-8'))
278
+ }
279
+
280
+ expected_rum_script = "<script type=\"text/javascript\">(window.StackifySettings || (window.StackifySettings = #{rum_settings.to_json()}))<\/script><script src=\"#{rum_script_url}\" data-key=\"#{config.rum_key}\" async></script>"
281
+
282
+ ENV.delete('TZ')
283
+ ENV.delete('RETRACE_RUM_KEY')
284
+ ENV.delete('RETRACE_RUM_SCRIPT_URL')
285
+
286
+ expect(rum_script.to_s).not_to be_empty
287
+ expect(rum_script).to eq expected_rum_script
288
+ end
289
+ end
290
+ end
291
+
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,12 @@
1
+ ENV['RAILS_ENV'] = ENV['RACK_ENV'] = 'test'
2
+ require 'bundler/setup'
3
+
4
+ # auto-require default gems + gems under test
5
+ Bundler.require :default, 'test'
6
+
7
+ require 'logger'
8
+ require 'stackify_ruby_apm'
9
+
1
10
  RSpec.configure do |config|
2
11
 
3
12
  config.filter_run :focus
@@ -21,7 +21,12 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.add_development_dependency 'bundler', '~> 1.6'
23
23
  spec.add_development_dependency 'rake', '~> 0'
24
+ spec.add_development_dependency 'rspec', '~> 3.0'
25
+
26
+ if RUBY_PLATFORM == 'i386-mingw32'
27
+ spec.add_development_dependency 'tzinfo-data'
28
+ end
29
+
24
30
  spec.add_runtime_dependency 'faraday', '~> 0.8'
25
- spec.add_runtime_dependency 'google-protobuf', '~> 3.0'
26
31
  spec.add_runtime_dependency 'net_http_unix', '~> 0.2'
27
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stackify-api-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ version: 1.3.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stackify
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-03 00:00:00.000000000 Z
11
+ date: 2021-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -39,33 +39,33 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: faraday
42
+ name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0.8'
48
- type: :runtime
47
+ version: '3.0'
48
+ type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0.8'
54
+ version: '3.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: google-protobuf
56
+ name: faraday
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '3.0'
61
+ version: '0.8'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '3.0'
68
+ version: '0.8'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: net_http_unix
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -95,7 +95,6 @@ files:
95
95
  - README.md
96
96
  - Rakefile
97
97
  - lib/core_ext/core_ext.rb
98
- - lib/core_ext/fixnum.rb
99
98
  - lib/core_ext/object.rb
100
99
  - lib/generators/stackify/stackify_generator.rb
101
100
  - lib/generators/stackify/templates/stackify.rb
@@ -123,6 +122,7 @@ files:
123
122
  - lib/stackify/metrics/monitor.rb
124
123
  - lib/stackify/msgs_queue.rb
125
124
  - lib/stackify/rack/errors_catcher.rb
125
+ - lib/stackify/rum.rb
126
126
  - lib/stackify/schedule_delay.rb
127
127
  - lib/stackify/schedule_task.rb
128
128
  - lib/stackify/scheduler.rb
@@ -139,6 +139,7 @@ files:
139
139
  - lib/stackify/workers/logs_sender_worker.rb
140
140
  - lib/stackify/workers/msgs_queue_worker.rb
141
141
  - lib/stackify/workers/worker.rb
142
+ - spec/rum_spec.rb
142
143
  - spec/spec_helper.rb
143
144
  - stackify-api-ruby.gemspec
144
145
  homepage: http://www.stackify.com/
@@ -156,13 +157,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
156
157
  version: '1.9'
157
158
  required_rubygems_version: !ruby/object:Gem::Requirement
158
159
  requirements:
159
- - - ">="
160
+ - - ">"
160
161
  - !ruby/object:Gem::Version
161
- version: '0'
162
+ version: 1.3.1
162
163
  requirements: []
163
164
  rubygems_version: 3.0.1
164
165
  signing_key:
165
166
  specification_version: 4
166
167
  summary: Stackify API for Ruby
167
168
  test_files:
169
+ - spec/rum_spec.rb
168
170
  - spec/spec_helper.rb
@@ -1,17 +0,0 @@
1
- class Fixnum
2
- SECONDS_IN_MINUTE = 60
3
- SECONDS_IN_HOUR = 60 * SECONDS_IN_MINUTE
4
- SECONDS_IN_DAY = 24 * SECONDS_IN_HOUR
5
-
6
- def days
7
- self * SECONDS_IN_DAY
8
- end
9
-
10
- def minutes
11
- self * SECONDS_IN_MINUTE
12
- end
13
-
14
- def ago
15
- Time.now - self
16
- end
17
- end