stackify-api-ruby 1.0.0
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 +7 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +30 -0
- data/LICENSE.txt +22 -0
- data/README.md +157 -0
- data/Rakefile +2 -0
- data/lib/generators/stackify/stackify_generator.rb +13 -0
- data/lib/generators/stackify/templates/stackify.rb +17 -0
- data/lib/stackify-api-ruby.rb +166 -0
- data/lib/stackify/authorization/authorizable.rb +61 -0
- data/lib/stackify/authorization/authorization_client.rb +31 -0
- data/lib/stackify/engine.rb +21 -0
- data/lib/stackify/env_details.rb +108 -0
- data/lib/stackify/error.rb +56 -0
- data/lib/stackify/errors_governor.rb +65 -0
- data/lib/stackify/http_client.rb +50 -0
- data/lib/stackify/logger_client.rb +71 -0
- data/lib/stackify/logger_proxy.rb +35 -0
- data/lib/stackify/logs_sender.rb +78 -0
- data/lib/stackify/metrics/metric.rb +68 -0
- data/lib/stackify/metrics/metric_aggregate.rb +52 -0
- data/lib/stackify/metrics/metrics.rb +88 -0
- data/lib/stackify/metrics/metrics_client.rb +238 -0
- data/lib/stackify/metrics/metrics_queue.rb +26 -0
- data/lib/stackify/metrics/metrics_sender.rb +32 -0
- data/lib/stackify/metrics/monitor.rb +34 -0
- data/lib/stackify/msgs_queue.rb +78 -0
- data/lib/stackify/rack/errors_catcher.rb +17 -0
- data/lib/stackify/schedule_task.rb +23 -0
- data/lib/stackify/scheduler.rb +79 -0
- data/lib/stackify/utils/backtrace.rb +36 -0
- data/lib/stackify/utils/configuration.rb +78 -0
- data/lib/stackify/utils/methods.rb +27 -0
- data/lib/stackify/utils/msg_object.rb +22 -0
- data/lib/stackify/version.rb +3 -0
- data/lib/stackify/workers/add_msg_worker.rb +9 -0
- data/lib/stackify/workers/auth_worker.rb +18 -0
- data/lib/stackify/workers/logs_sender_worker.rb +17 -0
- data/lib/stackify/workers/worker.rb +65 -0
- data/spec/spec_helper.rb +17 -0
- data/stackify-api-ruby.gemspec +25 -0
- metadata +137 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3058e14cea1be8ce39a5f5d8d76c6dd914421dba
|
4
|
+
data.tar.gz: 95d0089689b0fc904b05ac1cc8dedd4f3be392cc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f0705aeca8ccfad2067d6ccb429a451a58f86e2d039f48d3de30fe9999f76746b8ce1f87e3ccedd85f9e1b16deaee50884ca47e124d69d96b26daec050b20854
|
7
|
+
data.tar.gz: c0a6af825600cb6c52ac130bd14b9841ecea688be13c25779ccc65275329b564982ad322f014bb1db62b319402f4293b817eebcee9e94460713575a067b2797b
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
stackify-api-ruby (1.0.0)
|
5
|
+
activesupport (~> 4.1, >= 4.1.1)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
activesupport (4.1.4)
|
11
|
+
i18n (~> 0.6, >= 0.6.9)
|
12
|
+
json (~> 1.7, >= 1.7.7)
|
13
|
+
minitest (~> 5.1)
|
14
|
+
thread_safe (~> 0.1)
|
15
|
+
tzinfo (~> 1.1)
|
16
|
+
i18n (0.6.11)
|
17
|
+
json (1.8.1)
|
18
|
+
minitest (5.4.0)
|
19
|
+
rake (0.9.6)
|
20
|
+
thread_safe (0.3.4)
|
21
|
+
tzinfo (1.2.1)
|
22
|
+
thread_safe (~> 0.1)
|
23
|
+
|
24
|
+
PLATFORMS
|
25
|
+
ruby
|
26
|
+
|
27
|
+
DEPENDENCIES
|
28
|
+
bundler (~> 1.6)
|
29
|
+
rake (~> 0)
|
30
|
+
stackify-api-ruby!
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Dolgishev Victor
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
# Stackify
|
2
|
+
|
3
|
+
Stackify Logs and Metrics API for Ruby
|
4
|
+
|
5
|
+
|
6
|
+
Rails Installation
|
7
|
+
------------------
|
8
|
+
|
9
|
+
### Rails 3.x/4.x
|
10
|
+
|
11
|
+
Add the stackify gem to your Gemfile. In Gemfile:
|
12
|
+
|
13
|
+
gem 'stackify-api-ruby'
|
14
|
+
|
15
|
+
Run the bundle command to install it:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it manually:
|
20
|
+
|
21
|
+
$ gem install stackify-api-ruby
|
22
|
+
|
23
|
+
After you install stackify-api-ruby you need to run the generator:
|
24
|
+
|
25
|
+
$ rails g stackify --api_key=your_api_key
|
26
|
+
|
27
|
+
The generator creates a file under config/initializers/stackify.rb configuring stackify-api-ruby with your API key. You can change default settings there.
|
28
|
+
|
29
|
+
Usage: Logging
|
30
|
+
------------------
|
31
|
+
|
32
|
+
### Rails Environment
|
33
|
+
|
34
|
+
stackify-api-ruby starts working with start of Rails. Every occured error will be cought and sent to Stackify automatically. The same situation with logs - you just use the Rails logger as usual:
|
35
|
+
|
36
|
+
Rails.logger.info "Some log message"
|
37
|
+
|
38
|
+
### Other Environment
|
39
|
+
|
40
|
+
For using stackify-api-ruby gem within any Ruby application add to top of your main file:
|
41
|
+
|
42
|
+
require 'stackify-api-ruby'
|
43
|
+
|
44
|
+
After that you need to make base configuration:
|
45
|
+
|
46
|
+
Stackify.setup do |config|
|
47
|
+
config.api_key = "your_api_key"
|
48
|
+
config.env = :development
|
49
|
+
config.app_name = "Your's app name"
|
50
|
+
config.app_location = "/somewhere/public"
|
51
|
+
end
|
52
|
+
|
53
|
+
"api_key" - it's you key for Stackify. "app-location" - it's location of your application for Nginx/Apache(for Nginx it's value of 'root', for Apache it's value of 'DocumentRoot' at config files).
|
54
|
+
|
55
|
+
Gem has 3 modes of work - "both", "logging", "metrics". Mode "both" turns on both parts of gem - logging and metrics.
|
56
|
+
If you need ONLY logging or metrics use "logging" or "metrics" mode accordingly.
|
57
|
+
|
58
|
+
config.mode = :metrics
|
59
|
+
|
60
|
+
You can set minimal level of logs, which should be caught by gem:
|
61
|
+
|
62
|
+
config.log_level = :error
|
63
|
+
|
64
|
+
By default, gem sends logs to Stackify every 60 seconds, you can increase this value to higher if need:
|
65
|
+
|
66
|
+
config.send_interval = 60 #value in seconds, could not be less than 60 seconds
|
67
|
+
|
68
|
+
All logs, errors, and metrics are queued within the gem and uploaded on a background thread. By default, the maximum amount of logs is 1,000 log items, you can decrease this value:
|
69
|
+
|
70
|
+
config.queue_max_size = 600
|
71
|
+
|
72
|
+
To help prevent flooding the system there is a parameter - max amount of the same error per minute:
|
73
|
+
|
74
|
+
config.flood_limit = 100
|
75
|
+
|
76
|
+
If you want to use proxy for sendig request, you can do it in such way:
|
77
|
+
|
78
|
+
config.with_proxy = true
|
79
|
+
config.proxy_host = "127.0.0.1"
|
80
|
+
config.proxy_port = "8118"
|
81
|
+
config.proxy_user = nil
|
82
|
+
config.proxy_pass = nil
|
83
|
+
|
84
|
+
For logging own work stackify-api-rubystackify-api-rubygem uses such logger:
|
85
|
+
|
86
|
+
config.logger = Logger.new(File.join(Rails.root, "log", "stackify.log"))
|
87
|
+
|
88
|
+
After set up of logs you should wrap up your logger:
|
89
|
+
|
90
|
+
logger = Logger.new('mylog.log')
|
91
|
+
logger = Stackify::LoggerProxy.new(logger)
|
92
|
+
|
93
|
+
|
94
|
+
And last thing you need to do - call method "run":
|
95
|
+
|
96
|
+
Stackify.run #remember that this call is running in the background of your main script
|
97
|
+
|
98
|
+
Usage: Metrics
|
99
|
+
------------------
|
100
|
+
|
101
|
+
There are four different types of metrics:
|
102
|
+
|
103
|
+
- **Gauge**: Keeps track of the last value that was set in the current minute
|
104
|
+
|
105
|
+
Stackify::Metrics.set_gauge "MyCategory", "MyGauge", 100
|
106
|
+
|
107
|
+
- **Counter**: Calculates the rate per minute
|
108
|
+
|
109
|
+
Stackify::Metrics.count "MyCategory", "MyCounter"
|
110
|
+
|
111
|
+
- **Average**: Calculates the average of all values in the current minute
|
112
|
+
|
113
|
+
Stackify::Metrics.average "MyCategory", "AverageSpeed", 200
|
114
|
+
|
115
|
+
- **Timer**: Calculates the average elapsed time for an operation in the current minute
|
116
|
+
|
117
|
+
t = Time.now
|
118
|
+
Stackify::Metrics.time "MyCategory", "ElapsedTime", t
|
119
|
+
|
120
|
+
- **Counter and Timer**: Composite of the Counter and Timer metrics for convenience
|
121
|
+
|
122
|
+
t = Time.now
|
123
|
+
Stackify::Metrics.count_and_time "Metric", "CounterWithTime", t
|
124
|
+
|
125
|
+
We can configure every metric with settings:
|
126
|
+
|
127
|
+
settings = MetricSettings.new
|
128
|
+
settings.autoreport_zero_if_nothing_reported = true
|
129
|
+
# or
|
130
|
+
settings.autoreport_last_value_if_nothing_reported = true
|
131
|
+
Stackify::Metrics.set_gauge "MyCategory", "MyGauge", 100 , settings
|
132
|
+
|
133
|
+
Note, "autoreport_last_value_if_nothing_reported" property has influence only on "average" metric.
|
134
|
+
|
135
|
+
Also there are two methods for getting last values of metrics:
|
136
|
+
|
137
|
+
- get_latest - return last value of certain metric
|
138
|
+
|
139
|
+
``` Stackify::Metrics.get_latest "MyCategory", "MyCounter" ```
|
140
|
+
|
141
|
+
- get_latest_all_metrics - return all values of existed metrics
|
142
|
+
|
143
|
+
``` Stackify::Metrics.get_latest_all_metrics```
|
144
|
+
|
145
|
+
## Requirements
|
146
|
+
Ruby: 1.9/2.0/2.1
|
147
|
+
|
148
|
+
Rails: 3.x/4.x
|
149
|
+
|
150
|
+
Contributing
|
151
|
+
------------------
|
152
|
+
|
153
|
+
1. Fork it ( https://github.com/[my-github-username]/stackify/fork )
|
154
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
155
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
156
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
157
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
class StackifyGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path('../../stackify/templates', __FILE__)
|
5
|
+
|
6
|
+
class_option :api_key, type: :string, required: true
|
7
|
+
|
8
|
+
desc 'Creates a Stackify initializer'
|
9
|
+
def copy_initializer
|
10
|
+
template 'stackify.rb', 'config/initializers/stackify.rb'
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Stackify.setup do |config|
|
2
|
+
config.api_key = '<%= options[:api_key] %>'
|
3
|
+
#config.mode = :both
|
4
|
+
#config.app_name = "Your's app name"
|
5
|
+
#config.env = :development
|
6
|
+
#config.flood_limit = 100
|
7
|
+
#config.queue_max_size = 1000
|
8
|
+
#config.send_interval = 60 #sec
|
9
|
+
#config.log_level = :error
|
10
|
+
#config.logger = Logger.new(File.join(Rails.root, 'log', 'stackify.log'))
|
11
|
+
#config.logger.level = Logger::INFO
|
12
|
+
#config.with_proxy = false
|
13
|
+
#config.proxy_host = '127.0.0.1'
|
14
|
+
#config.proxy_port = '8118'
|
15
|
+
#config.proxy_user = nil
|
16
|
+
#config.proxy_pass = nil
|
17
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'stackify/version'
|
2
|
+
require 'stackify/utils/methods'
|
3
|
+
require 'active_support/core_ext' unless defined? Rails
|
4
|
+
|
5
|
+
module Stackify
|
6
|
+
|
7
|
+
INTERNAL_LOG_PREFIX = '[Stackify]'.freeze
|
8
|
+
STATUSES = { working: 'working', terminating: 'terminating', terminated: 'terminated'}
|
9
|
+
MODES = { logging: :logging, metrics: :metrics, both: :both }
|
10
|
+
|
11
|
+
autoload :Backtrace, 'stackify/utils/backtrace'
|
12
|
+
autoload :MsgObject, 'stackify/utils/msg_object'
|
13
|
+
autoload :Configuration, 'stackify/utils/configuration'
|
14
|
+
autoload :HttpClient, 'stackify/http_client'
|
15
|
+
autoload :Authorizable, 'stackify/authorization/authorizable'
|
16
|
+
autoload :EnvDetails, 'stackify/env_details'
|
17
|
+
autoload :Scheduler, 'stackify/scheduler'
|
18
|
+
autoload :ScheduleTask, 'stackify/schedule_task'
|
19
|
+
autoload :Worker, 'stackify/workers/worker'
|
20
|
+
autoload :AuthWorker, 'stackify/workers/auth_worker'
|
21
|
+
autoload :LogsSenderWorker, 'stackify/workers/logs_sender_worker'
|
22
|
+
autoload :AddMsgWorker, 'stackify/workers/add_msg_worker'
|
23
|
+
autoload :MsgsQueue, 'stackify/msgs_queue'
|
24
|
+
autoload :LoggerClient, 'stackify/logger_client'
|
25
|
+
autoload :LogsSender, 'stackify/logs_sender'
|
26
|
+
autoload :LoggerProxy, 'stackify/logger_proxy'
|
27
|
+
autoload :StackifiedError, 'stackify/error'
|
28
|
+
autoload :ErrorsGovernor, 'stackify/errors_governor'
|
29
|
+
autoload :Metrics, 'stackify/metrics/metrics'
|
30
|
+
|
31
|
+
include Authorizable
|
32
|
+
|
33
|
+
class << self
|
34
|
+
|
35
|
+
attr_writer :config
|
36
|
+
|
37
|
+
def configuration
|
38
|
+
@config ||= Stackify::Configuration.new
|
39
|
+
end
|
40
|
+
|
41
|
+
def setup
|
42
|
+
yield(configuration) if block_given?
|
43
|
+
if configuration.is_valid?
|
44
|
+
@status = STATUSES[:working]
|
45
|
+
@workers = []
|
46
|
+
else
|
47
|
+
msg = "Stackify's configuration is not valid!"
|
48
|
+
configuration.errors.each do |error_msg|
|
49
|
+
msg += "\n"+error_msg
|
50
|
+
end
|
51
|
+
raise msg
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
def msgs_queue
|
57
|
+
@msgs_queue ||= Stackify::MsgsQueue.new
|
58
|
+
end
|
59
|
+
|
60
|
+
def logger_client
|
61
|
+
@logger_client ||= Stackify::LoggerClient.new
|
62
|
+
end
|
63
|
+
|
64
|
+
def logs_sender
|
65
|
+
@logs_sender ||= Stackify::LogsSender.new
|
66
|
+
end
|
67
|
+
|
68
|
+
def logger
|
69
|
+
self.configuration.logger
|
70
|
+
end
|
71
|
+
|
72
|
+
def shutdown_all caller_obj=nil
|
73
|
+
@workers.each do |worker|
|
74
|
+
worker.shutdown! unless worker.equal? caller_obj
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def alive_adding_msg_workers
|
79
|
+
@workers.select{ |w| w.alive? && w.type == :add_msg }
|
80
|
+
end
|
81
|
+
|
82
|
+
def delete_worker worker
|
83
|
+
@workers.delete worker
|
84
|
+
end
|
85
|
+
|
86
|
+
def add_dependant_worker worker
|
87
|
+
@workers << worker
|
88
|
+
end
|
89
|
+
|
90
|
+
def status
|
91
|
+
@status
|
92
|
+
end
|
93
|
+
|
94
|
+
def log_internal_error msg
|
95
|
+
Stackify.logger.error (::Stackify::INTERNAL_LOG_PREFIX){ msg }
|
96
|
+
end
|
97
|
+
|
98
|
+
def internal_log level, msg
|
99
|
+
Stackify.logger.send(level.downcase.to_sym, Stackify::INTERNAL_LOG_PREFIX){ msg }
|
100
|
+
end
|
101
|
+
|
102
|
+
def run async = true
|
103
|
+
if Stackify.is_valid?
|
104
|
+
at_exit { make_remained_job }
|
105
|
+
t1 = Thread.new { Stackify.authorize }
|
106
|
+
case Stackify.configuration.mode
|
107
|
+
when MODES[:both]
|
108
|
+
t2 = start_logging
|
109
|
+
t3 = start_metrics
|
110
|
+
when MODES[:logging]
|
111
|
+
t2 = start_logging
|
112
|
+
when MODES[:metrics]
|
113
|
+
t3 = start_metrics
|
114
|
+
end
|
115
|
+
unless async
|
116
|
+
t1.join
|
117
|
+
t2.join if t2
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def start_logging
|
123
|
+
Thread.new { Stackify.logs_sender.start}
|
124
|
+
end
|
125
|
+
|
126
|
+
def start_metrics
|
127
|
+
Thread.new { Stackify::Metrics.metrics_client.start }
|
128
|
+
end
|
129
|
+
|
130
|
+
def workers
|
131
|
+
@workers
|
132
|
+
end
|
133
|
+
|
134
|
+
def make_remained_job
|
135
|
+
@status = STATUSES[:terminating]
|
136
|
+
Stackify.msgs_queue.push_remained_msgs
|
137
|
+
end
|
138
|
+
|
139
|
+
def is_valid?
|
140
|
+
configuration.is_valid?
|
141
|
+
end
|
142
|
+
|
143
|
+
def terminating?
|
144
|
+
@status == STATUSES[:terminating]
|
145
|
+
end
|
146
|
+
|
147
|
+
def terminated?
|
148
|
+
@status == STATUSES[:terminated]
|
149
|
+
end
|
150
|
+
|
151
|
+
def working?
|
152
|
+
@status == STATUSES[:working]
|
153
|
+
end
|
154
|
+
|
155
|
+
def status= status
|
156
|
+
if STATUSES.has_value? status
|
157
|
+
@status = status
|
158
|
+
else
|
159
|
+
raise "method 'status=' should get one of arguments #{STATUSES.values}, not a #{status}"
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
require 'stackify/engine' if defined? Rails
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Stackify::Authorizable
|
2
|
+
autoload :AuthorizationClient, 'stackify/authorization/authorization_client'
|
3
|
+
|
4
|
+
def self.included(klass)
|
5
|
+
klass.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
@@authorized = false
|
10
|
+
@@auth_lock = Mutex.new
|
11
|
+
@@auth_client = nil
|
12
|
+
|
13
|
+
def authorize attempts=3, delay_time = 20
|
14
|
+
@@auth_lock.synchronize do
|
15
|
+
return unless @@auth_client.nil?
|
16
|
+
@@auth_client = Stackify::Authorizable::AuthorizationClient.new
|
17
|
+
@@auth_client.auth attempts, delay_time
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def authorized?
|
22
|
+
@@auth_lock.synchronize do
|
23
|
+
@@authorized
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def authorized!
|
28
|
+
@@authorized = true
|
29
|
+
end
|
30
|
+
|
31
|
+
def successfull_authorisation response
|
32
|
+
Stackify::EnvDetails.instance.update_auth_info JSON.parse(response.body)
|
33
|
+
Stackify.internal_log :info, 'Authorisation is finished successfully.'
|
34
|
+
end
|
35
|
+
|
36
|
+
def unsuccessfull_authorisation response, caller
|
37
|
+
Stackify.log_internal_error "Authorisation finally failed: #{response_string(response)}"
|
38
|
+
Stackify.shutdown_all caller unless @@authorized
|
39
|
+
end
|
40
|
+
|
41
|
+
def if_not_authorized failure_msg, &block
|
42
|
+
failure_msg += ', but Stackify module is not authorized'
|
43
|
+
if Stackify.authorized?
|
44
|
+
begin
|
45
|
+
block.call
|
46
|
+
rescue => e
|
47
|
+
Stackify.log_internal_error e.message
|
48
|
+
end
|
49
|
+
else
|
50
|
+
Stackify.log_internal_error failure_msg
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def response_string r
|
55
|
+
return '' if r.nil?
|
56
|
+
"Code: #{r.try(:code)}, Message: '#{r.try(:msg)}'"
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|