stackify-api-ruby 1.2.4 → 1.3.0.beta1

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: 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