logister-ruby 0.1.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/README.md +70 -0
- data/lib/generators/logister/install_generator.rb +13 -0
- data/lib/generators/logister/templates/logister.rb +23 -0
- data/lib/logister/client.rb +127 -0
- data/lib/logister/configuration.rb +31 -0
- data/lib/logister/middleware.rb +21 -0
- data/lib/logister/railtie.rb +40 -0
- data/lib/logister/reporter.rb +124 -0
- data/lib/logister/version.rb +3 -0
- data/lib/logister.rb +40 -0
- data/logister-ruby.gemspec +25 -0
- metadata +68 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 6f3dcdd4ed71335923f5b4fd3d77dfa4af74a4d958715eaaf0805d704739f1a4
|
|
4
|
+
data.tar.gz: 147df51a94bea770c1559f0186eb74d154cd7a6b109a3b4025496ca8043abd68
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: d1328c3bb4188794e62215e0e2fd7e0c50631d0d1b3c92fbe3fec5dc179510109cfb95b43629f588f74ef8efe790d4c190db494d4ab4527b9229701cf9c7bddf
|
|
7
|
+
data.tar.gz: 8e700cdfbf1ff0b1f0178c260270170f448165f6043e04bca8f7c6ef5365254819ce223db9adcb40cdd12b7f1ce7d6f11212921f2dd2bc73edd2f70dba7af82e
|
data/README.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# logister-ruby
|
|
2
|
+
|
|
3
|
+
`logister-ruby` sends application errors and custom metrics to `logister.org`.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
gem "logister-ruby"
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Then generate an initializer in Rails:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
bin/rails generate logister:install
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Configuration
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
Logister.configure do |config|
|
|
21
|
+
config.api_key = ENV.fetch("LOGISTER_API_KEY")
|
|
22
|
+
config.endpoint = "https://logister.org/api/v1/ingest_events"
|
|
23
|
+
config.environment = Rails.env
|
|
24
|
+
config.service = Rails.application.class.module_parent_name.underscore
|
|
25
|
+
config.release = ENV["RELEASE_SHA"]
|
|
26
|
+
end
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Reliability options
|
|
30
|
+
|
|
31
|
+
```ruby
|
|
32
|
+
Logister.configure do |config|
|
|
33
|
+
config.async = true
|
|
34
|
+
config.queue_size = 1000
|
|
35
|
+
config.max_retries = 3
|
|
36
|
+
config.retry_base_interval = 0.5
|
|
37
|
+
end
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Filtering and redaction
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
Logister.configure do |config|
|
|
44
|
+
config.ignore_environments = ["development", "test"]
|
|
45
|
+
config.ignore_exceptions = ["ActiveRecord::RecordNotFound"]
|
|
46
|
+
config.ignore_paths = [/health/, "/up"]
|
|
47
|
+
|
|
48
|
+
config.before_notify = lambda do |payload|
|
|
49
|
+
payload[:context]&.delete("authorization")
|
|
50
|
+
payload
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Rails auto-reporting
|
|
56
|
+
|
|
57
|
+
If Rails is present, the gem installs middleware that reports unhandled exceptions automatically.
|
|
58
|
+
|
|
59
|
+
## Manual reporting
|
|
60
|
+
|
|
61
|
+
```ruby
|
|
62
|
+
Logister.report_error(StandardError.new("Something failed"), tags: { area: "checkout" })
|
|
63
|
+
|
|
64
|
+
Logister.report_metric(
|
|
65
|
+
message: "checkout.completed",
|
|
66
|
+
level: "info",
|
|
67
|
+
context: { duration_ms: 123 },
|
|
68
|
+
tags: { region: "us-east-1" }
|
|
69
|
+
)
|
|
70
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'rails/generators'
|
|
2
|
+
|
|
3
|
+
module Logister
|
|
4
|
+
module Generators
|
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
|
6
|
+
source_root File.expand_path('templates', __dir__)
|
|
7
|
+
|
|
8
|
+
def create_initializer
|
|
9
|
+
template 'logister.rb', 'config/initializers/logister.rb'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Logister.configure do |config|
|
|
2
|
+
config.api_key = ENV['LOGISTER_API_KEY']
|
|
3
|
+
config.endpoint = ENV.fetch('LOGISTER_ENDPOINT', 'https://logister.org/api/v1/ingest_events')
|
|
4
|
+
config.environment = Rails.env
|
|
5
|
+
config.service = Rails.application.class.module_parent_name.underscore
|
|
6
|
+
config.release = ENV['LOGISTER_RELEASE']
|
|
7
|
+
|
|
8
|
+
config.enabled = true
|
|
9
|
+
config.timeout_seconds = 2
|
|
10
|
+
|
|
11
|
+
config.async = true
|
|
12
|
+
config.queue_size = 1000
|
|
13
|
+
config.max_retries = 3
|
|
14
|
+
config.retry_base_interval = 0.5
|
|
15
|
+
|
|
16
|
+
config.ignore_environments = []
|
|
17
|
+
config.ignore_exceptions = []
|
|
18
|
+
config.ignore_paths = []
|
|
19
|
+
|
|
20
|
+
config.before_notify = lambda do |payload|
|
|
21
|
+
payload
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'net/http'
|
|
3
|
+
require 'uri'
|
|
4
|
+
|
|
5
|
+
module Logister
|
|
6
|
+
class Client
|
|
7
|
+
def initialize(configuration)
|
|
8
|
+
@configuration = configuration
|
|
9
|
+
@worker_mutex = Mutex.new
|
|
10
|
+
@queue = SizedQueue.new(@configuration.queue_size)
|
|
11
|
+
@worker = nil
|
|
12
|
+
@running = false
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def publish(payload)
|
|
16
|
+
return false unless ready?
|
|
17
|
+
|
|
18
|
+
return publish_sync(payload) unless @configuration.async
|
|
19
|
+
|
|
20
|
+
ensure_worker_started
|
|
21
|
+
enqueue(payload)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def flush(timeout: 2)
|
|
25
|
+
return true unless @configuration.async
|
|
26
|
+
|
|
27
|
+
started_at = monotonic_now
|
|
28
|
+
while @queue.length.positive?
|
|
29
|
+
return false if monotonic_now - started_at > timeout
|
|
30
|
+
|
|
31
|
+
sleep(0.01)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def shutdown
|
|
38
|
+
return true unless @configuration.async
|
|
39
|
+
|
|
40
|
+
@running = false
|
|
41
|
+
begin
|
|
42
|
+
@queue.push(nil)
|
|
43
|
+
rescue StandardError
|
|
44
|
+
nil
|
|
45
|
+
end
|
|
46
|
+
@worker&.join(1)
|
|
47
|
+
true
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def enqueue(payload)
|
|
53
|
+
@queue.push(payload, true)
|
|
54
|
+
true
|
|
55
|
+
rescue ThreadError
|
|
56
|
+
@configuration.logger.warn('logister queue full; dropping event')
|
|
57
|
+
false
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def ensure_worker_started
|
|
61
|
+
return if @running && @worker&.alive?
|
|
62
|
+
|
|
63
|
+
@worker_mutex.synchronize do
|
|
64
|
+
return if @running && @worker&.alive?
|
|
65
|
+
|
|
66
|
+
@running = true
|
|
67
|
+
@worker = Thread.new { run_worker }
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def run_worker
|
|
72
|
+
while @running
|
|
73
|
+
payload = @queue.pop
|
|
74
|
+
break if payload.nil?
|
|
75
|
+
|
|
76
|
+
publish_sync(payload)
|
|
77
|
+
end
|
|
78
|
+
rescue StandardError => e
|
|
79
|
+
@configuration.logger.warn("logister worker crashed: #{e.class} #{e.message}")
|
|
80
|
+
@running = false
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def publish_sync(payload)
|
|
84
|
+
attempts = 0
|
|
85
|
+
begin
|
|
86
|
+
attempts += 1
|
|
87
|
+
send_request(payload)
|
|
88
|
+
rescue StandardError => e
|
|
89
|
+
if attempts <= @configuration.max_retries
|
|
90
|
+
sleep(@configuration.retry_base_interval * (2**(attempts - 1)))
|
|
91
|
+
retry
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
@configuration.logger.warn("logister publish failed: #{e.class} #{e.message}")
|
|
95
|
+
false
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def send_request(payload)
|
|
100
|
+
uri = URI.parse(@configuration.endpoint)
|
|
101
|
+
request = Net::HTTP::Post.new(uri)
|
|
102
|
+
request['Content-Type'] = 'application/json'
|
|
103
|
+
request['Authorization'] = "Bearer #{@configuration.api_key}"
|
|
104
|
+
request.body = { event: payload }.to_json
|
|
105
|
+
|
|
106
|
+
response = Net::HTTP.start(
|
|
107
|
+
uri.host,
|
|
108
|
+
uri.port,
|
|
109
|
+
use_ssl: uri.scheme == 'https',
|
|
110
|
+
open_timeout: @configuration.timeout_seconds,
|
|
111
|
+
read_timeout: @configuration.timeout_seconds
|
|
112
|
+
) { |http| http.request(request) }
|
|
113
|
+
|
|
114
|
+
return true if response.is_a?(Net::HTTPSuccess)
|
|
115
|
+
|
|
116
|
+
raise "HTTP #{response.code}"
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def monotonic_now
|
|
120
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def ready?
|
|
124
|
+
@configuration.enabled && @configuration.api_key.to_s != ''
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'logger'
|
|
2
|
+
|
|
3
|
+
module Logister
|
|
4
|
+
class Configuration
|
|
5
|
+
attr_accessor :api_key, :endpoint, :environment, :service, :release, :enabled, :timeout_seconds, :logger,
|
|
6
|
+
:ignore_exceptions, :ignore_environments, :ignore_paths, :before_notify,
|
|
7
|
+
:async, :queue_size, :max_retries, :retry_base_interval
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
@api_key = ENV['LOGISTER_API_KEY']
|
|
11
|
+
@endpoint = ENV.fetch('LOGISTER_ENDPOINT', 'https://logister.org/api/v1/ingest_events')
|
|
12
|
+
@environment = ENV.fetch('RAILS_ENV', ENV.fetch('RACK_ENV', 'development'))
|
|
13
|
+
@service = ENV.fetch('LOGISTER_SERVICE', 'ruby-app')
|
|
14
|
+
@release = ENV['LOGISTER_RELEASE']
|
|
15
|
+
@enabled = true
|
|
16
|
+
@timeout_seconds = 2
|
|
17
|
+
@logger = Logger.new($stdout)
|
|
18
|
+
@logger.level = Logger::WARN
|
|
19
|
+
|
|
20
|
+
@ignore_exceptions = []
|
|
21
|
+
@ignore_environments = []
|
|
22
|
+
@ignore_paths = []
|
|
23
|
+
@before_notify = nil
|
|
24
|
+
|
|
25
|
+
@async = true
|
|
26
|
+
@queue_size = 1000
|
|
27
|
+
@max_retries = 3
|
|
28
|
+
@retry_base_interval = 0.5
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Logister
|
|
2
|
+
class Middleware
|
|
3
|
+
def initialize(app)
|
|
4
|
+
@app = app
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def call(env)
|
|
8
|
+
@app.call(env)
|
|
9
|
+
rescue StandardError => e
|
|
10
|
+
Logister.report_error(
|
|
11
|
+
e,
|
|
12
|
+
context: {
|
|
13
|
+
request_id: env['action_dispatch.request_id'],
|
|
14
|
+
path: env['PATH_INFO'],
|
|
15
|
+
method: env['REQUEST_METHOD']
|
|
16
|
+
}
|
|
17
|
+
)
|
|
18
|
+
raise
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'rails/railtie'
|
|
2
|
+
|
|
3
|
+
module Logister
|
|
4
|
+
class Railtie < Rails::Railtie
|
|
5
|
+
config.logister = ActiveSupport::OrderedOptions.new
|
|
6
|
+
|
|
7
|
+
initializer 'logister.configure' do |app|
|
|
8
|
+
Logister.configure do |config|
|
|
9
|
+
copy_setting(app, config, :api_key)
|
|
10
|
+
copy_setting(app, config, :endpoint)
|
|
11
|
+
copy_setting(app, config, :environment)
|
|
12
|
+
copy_setting(app, config, :service)
|
|
13
|
+
copy_setting(app, config, :release)
|
|
14
|
+
copy_setting(app, config, :enabled)
|
|
15
|
+
copy_setting(app, config, :timeout_seconds)
|
|
16
|
+
copy_setting(app, config, :ignore_exceptions)
|
|
17
|
+
copy_setting(app, config, :ignore_environments)
|
|
18
|
+
copy_setting(app, config, :ignore_paths)
|
|
19
|
+
copy_setting(app, config, :before_notify)
|
|
20
|
+
copy_setting(app, config, :async)
|
|
21
|
+
copy_setting(app, config, :queue_size)
|
|
22
|
+
copy_setting(app, config, :max_retries)
|
|
23
|
+
copy_setting(app, config, :retry_base_interval)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
initializer 'logister.middleware' do |app|
|
|
28
|
+
app.middleware.use Logister::Middleware
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def copy_setting(app, config, key)
|
|
34
|
+
value = app.config.logister.send(key)
|
|
35
|
+
return if value.nil?
|
|
36
|
+
|
|
37
|
+
config.send("#{key}=", value)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
require 'digest'
|
|
2
|
+
require 'time'
|
|
3
|
+
|
|
4
|
+
module Logister
|
|
5
|
+
class Reporter
|
|
6
|
+
def initialize(configuration)
|
|
7
|
+
@configuration = configuration
|
|
8
|
+
@client = Client.new(configuration)
|
|
9
|
+
|
|
10
|
+
at_exit { shutdown }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def report_error(exception, context: {}, tags: {}, level: 'error', fingerprint: nil)
|
|
14
|
+
return false if ignored_exception?(exception)
|
|
15
|
+
return false if ignored_path?(context)
|
|
16
|
+
|
|
17
|
+
payload = build_payload(
|
|
18
|
+
event_type: 'error',
|
|
19
|
+
level: level,
|
|
20
|
+
message: "#{exception.class}: #{exception.message}",
|
|
21
|
+
fingerprint: fingerprint || default_fingerprint(exception),
|
|
22
|
+
context: context.merge(
|
|
23
|
+
exception: {
|
|
24
|
+
class: exception.class.to_s,
|
|
25
|
+
message: exception.message.to_s,
|
|
26
|
+
backtrace: Array(exception.backtrace).first(50)
|
|
27
|
+
},
|
|
28
|
+
tags: tags
|
|
29
|
+
)
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
payload = apply_before_notify(payload)
|
|
33
|
+
return false unless payload
|
|
34
|
+
|
|
35
|
+
@client.publish(payload)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def report_metric(message:, level: 'info', context: {}, tags: {}, fingerprint: nil)
|
|
39
|
+
return false if ignored_environment?
|
|
40
|
+
return false if ignored_path?(context)
|
|
41
|
+
|
|
42
|
+
payload = build_payload(
|
|
43
|
+
event_type: 'metric',
|
|
44
|
+
level: level,
|
|
45
|
+
message: message,
|
|
46
|
+
fingerprint: fingerprint || Digest::SHA256.hexdigest(message.to_s)[0, 32],
|
|
47
|
+
context: context.merge(tags: tags)
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
payload = apply_before_notify(payload)
|
|
51
|
+
return false unless payload
|
|
52
|
+
|
|
53
|
+
@client.publish(payload)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def flush(timeout: 2)
|
|
57
|
+
@client.flush(timeout: timeout)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def shutdown
|
|
61
|
+
@client.shutdown
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
def build_payload(event_type:, level:, message:, fingerprint:, context:)
|
|
67
|
+
{
|
|
68
|
+
event_type: event_type,
|
|
69
|
+
level: level,
|
|
70
|
+
message: message,
|
|
71
|
+
fingerprint: fingerprint,
|
|
72
|
+
occurred_at: Time.now.utc.iso8601,
|
|
73
|
+
context: context.merge(
|
|
74
|
+
environment: @configuration.environment,
|
|
75
|
+
service: @configuration.service,
|
|
76
|
+
release: @configuration.release
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def apply_before_notify(payload)
|
|
82
|
+
hook = @configuration.before_notify
|
|
83
|
+
return payload unless hook.respond_to?(:call)
|
|
84
|
+
|
|
85
|
+
result = hook.call(payload)
|
|
86
|
+
return nil if result == false || result.nil?
|
|
87
|
+
|
|
88
|
+
result
|
|
89
|
+
rescue StandardError => e
|
|
90
|
+
@configuration.logger.warn("logister before_notify failed: #{e.class} #{e.message}")
|
|
91
|
+
nil
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def ignored_exception?(exception)
|
|
95
|
+
return true if ignored_environment?
|
|
96
|
+
|
|
97
|
+
@configuration.ignore_exceptions.any? do |item|
|
|
98
|
+
if item.is_a?(Class)
|
|
99
|
+
exception.is_a?(item)
|
|
100
|
+
else
|
|
101
|
+
exception.class.name == item.to_s
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def ignored_environment?
|
|
107
|
+
env = @configuration.environment.to_s
|
|
108
|
+
@configuration.ignore_environments.map(&:to_s).include?(env)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def ignored_path?(context)
|
|
112
|
+
path = context[:path] || context['path']
|
|
113
|
+
return false if path.to_s.empty?
|
|
114
|
+
|
|
115
|
+
@configuration.ignore_paths.any? do |matcher|
|
|
116
|
+
matcher.is_a?(Regexp) ? matcher.match?(path.to_s) : path.to_s.include?(matcher.to_s)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def default_fingerprint(exception)
|
|
121
|
+
Digest::SHA256.hexdigest("#{exception.class}|#{exception.message}")[0, 32]
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
data/lib/logister.rb
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require_relative 'logister/version'
|
|
2
|
+
require_relative 'logister/configuration'
|
|
3
|
+
require_relative 'logister/client'
|
|
4
|
+
require_relative 'logister/reporter'
|
|
5
|
+
require_relative 'logister/middleware'
|
|
6
|
+
|
|
7
|
+
module Logister
|
|
8
|
+
class << self
|
|
9
|
+
def configuration
|
|
10
|
+
@configuration ||= Configuration.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def configure
|
|
14
|
+
yield(configuration)
|
|
15
|
+
@reporter = nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def reporter
|
|
19
|
+
@reporter ||= Reporter.new(configuration)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def report_error(exception, **kwargs)
|
|
23
|
+
reporter.report_error(exception, **kwargs)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def report_metric(**kwargs)
|
|
27
|
+
reporter.report_metric(**kwargs)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def flush(timeout: 2)
|
|
31
|
+
reporter.flush(timeout: timeout)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def shutdown
|
|
35
|
+
reporter.shutdown
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
require_relative 'logister/railtie' if defined?(Rails::Railtie)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require_relative 'lib/logister/version'
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new do |spec|
|
|
4
|
+
spec.name = 'logister-ruby'
|
|
5
|
+
spec.version = Logister::VERSION
|
|
6
|
+
spec.authors = ['Logister']
|
|
7
|
+
spec.email = ['support@logister.org']
|
|
8
|
+
|
|
9
|
+
spec.summary = 'Send Rails errors and metrics to logister.org'
|
|
10
|
+
spec.description = 'Client gem for reporting errors and custom metrics from Ruby and Rails apps to logister.org'
|
|
11
|
+
spec.homepage = 'https://logister.org'
|
|
12
|
+
spec.license = 'MIT'
|
|
13
|
+
spec.required_ruby_version = '>= 3.1.0'
|
|
14
|
+
|
|
15
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
16
|
+
spec.metadata['source_code_uri'] = 'https://logister.org'
|
|
17
|
+
|
|
18
|
+
spec.files = Dir.chdir(__dir__) do
|
|
19
|
+
Dir.glob('lib/**/*') + ['README.md', 'logister-ruby.gemspec']
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
spec.require_paths = ['lib']
|
|
23
|
+
|
|
24
|
+
spec.add_dependency 'activesupport', '>= 6.1'
|
|
25
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: logister-ruby
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Logister
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: activesupport
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '6.1'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '6.1'
|
|
26
|
+
description: Client gem for reporting errors and custom metrics from Ruby and Rails
|
|
27
|
+
apps to logister.org
|
|
28
|
+
email:
|
|
29
|
+
- support@logister.org
|
|
30
|
+
executables: []
|
|
31
|
+
extensions: []
|
|
32
|
+
extra_rdoc_files: []
|
|
33
|
+
files:
|
|
34
|
+
- README.md
|
|
35
|
+
- lib/generators/logister/install_generator.rb
|
|
36
|
+
- lib/generators/logister/templates/logister.rb
|
|
37
|
+
- lib/logister.rb
|
|
38
|
+
- lib/logister/client.rb
|
|
39
|
+
- lib/logister/configuration.rb
|
|
40
|
+
- lib/logister/middleware.rb
|
|
41
|
+
- lib/logister/railtie.rb
|
|
42
|
+
- lib/logister/reporter.rb
|
|
43
|
+
- lib/logister/version.rb
|
|
44
|
+
- logister-ruby.gemspec
|
|
45
|
+
homepage: https://logister.org
|
|
46
|
+
licenses:
|
|
47
|
+
- MIT
|
|
48
|
+
metadata:
|
|
49
|
+
homepage_uri: https://logister.org
|
|
50
|
+
source_code_uri: https://logister.org
|
|
51
|
+
rdoc_options: []
|
|
52
|
+
require_paths:
|
|
53
|
+
- lib
|
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - ">="
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: 3.1.0
|
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
|
+
requirements:
|
|
61
|
+
- - ">="
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: '0'
|
|
64
|
+
requirements: []
|
|
65
|
+
rubygems_version: 4.0.3
|
|
66
|
+
specification_version: 4
|
|
67
|
+
summary: Send Rails errors and metrics to logister.org
|
|
68
|
+
test_files: []
|