nadir 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5b93c780f42b2e97c85747a4c3560197c9aee46c47abce5a7e65deb277ae06d5
4
+ data.tar.gz: 4a1a7078989569d698c10ba805f0cce123bf54986a3adfc133abf9f79666aab1
5
+ SHA512:
6
+ metadata.gz: 878144a8aee1841c7c32097e671a4c9515f5772aeae73afba5e19e09010312bd29199b7bc0f92c818f42fbd7e165fd190adbdb88da0798521bc96a6a1b3848c2
7
+ data.tar.gz: a3ed93ffe788804d9d1d7e78fced5bb5a2a9097be2e8a73027d9675ceeb1ec529fb3c6d8f7da299536d939b870b181b9852e19bac4a523ac7320a393d5973b7a
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ *.gem
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.5.3
7
+ before_install: gem install bundler -v 1.17.3
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,41 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ nadir (0.2.2)
5
+ commander (~> 4.4)
6
+ concurrent-ruby (~> 1.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ commander (4.4.7)
12
+ highline (~> 2.0.0)
13
+ concurrent-ruby (1.1.5)
14
+ diff-lcs (1.3)
15
+ highline (2.0.1)
16
+ rake (10.5.0)
17
+ rspec (3.8.0)
18
+ rspec-core (~> 3.8.0)
19
+ rspec-expectations (~> 3.8.0)
20
+ rspec-mocks (~> 3.8.0)
21
+ rspec-core (3.8.0)
22
+ rspec-support (~> 3.8.0)
23
+ rspec-expectations (3.8.2)
24
+ diff-lcs (>= 1.2.0, < 2.0)
25
+ rspec-support (~> 3.8.0)
26
+ rspec-mocks (3.8.0)
27
+ diff-lcs (>= 1.2.0, < 2.0)
28
+ rspec-support (~> 3.8.0)
29
+ rspec-support (3.8.0)
30
+
31
+ PLATFORMS
32
+ ruby
33
+
34
+ DEPENDENCIES
35
+ bundler (~> 1.17)
36
+ nadir!
37
+ rake (~> 10.0)
38
+ rspec (~> 3.0)
39
+
40
+ BUNDLED WITH
41
+ 1.17.3
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Georgi Mitrev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # Nadir Ruby client
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/nadir/rb`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'nadir'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install nadir
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/gmitrev/nadir-rb. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
36
+
37
+ ## License
38
+
39
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
40
+
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
8
+ task :console do
9
+ require 'irb'
10
+ require 'irb/completion'
11
+ require 'nadir'
12
+ ARGV.clear
13
+ IRB.start
14
+ end
data/bin/console ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require_relative '../lib/nadir'
5
+
6
+ require 'irb'
7
+ IRB.start(__FILE__)
data/bin/nadir ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../lib/nadir/cli'
3
+
4
+ Nadir::CLI.new.run
data/lib/nadir/cli.rb ADDED
@@ -0,0 +1,92 @@
1
+ require 'commander'
2
+ require_relative './version'
3
+
4
+ module Nadir
5
+ class NadirtException < StandardError; end
6
+ class CLI
7
+ include Commander::Methods
8
+
9
+ def run
10
+ program :name, 'nadir'
11
+ program :version, Nadir::VERSION
12
+ program :description, 'Ruby/Rails client for Nadir'
13
+
14
+ never_trace!
15
+
16
+ command 'setup' do |c|
17
+ c.syntax = 'nadir setup API-KEY'
18
+ c.description = 'Creates Nadir\'s configuration file config/nadir.yml and populates it with the provided API-KEY.'
19
+ c.action do |args, _options|
20
+ api_key = args[0]
21
+
22
+ if File.exist? config_file_path
23
+ say_error 'Nadir config file already exists.'
24
+
25
+ exit(0)
26
+ end
27
+
28
+ unless api_key
29
+ say_error 'Please provide an API KEY.'
30
+
31
+ exit(0)
32
+ end
33
+
34
+ configuration_file = <<~YAML
35
+ ---
36
+ api_key: #{api_key}
37
+ YAML
38
+
39
+ File.open(config_file_path, 'w') { |file| file.write(configuration_file) }
40
+
41
+ say_success <<~MSG
42
+ Nadir client configured successfully!
43
+
44
+ Test the integration by sending a test notification:
45
+
46
+ bundle exec nadir test-notify
47
+
48
+ If all is well, you'll see the test notification in https://nadir.dev.
49
+ MSG
50
+ end
51
+ end
52
+
53
+ command 'test-notify' do |c|
54
+ c.syntax = 'nadir test-notify'
55
+ c.description = 'Send a test notification to Nadir'
56
+ c.action do |args, _options|
57
+ require File.expand_path('config/environment')
58
+
59
+ Nadir.configure do |config|
60
+ config.enabled_for << 'development'
61
+ end
62
+
63
+ begin
64
+ raise NadirTestException.new('Test message')
65
+ rescue NadirTestException => e
66
+ if Nadir.notify e, location: 'nadir test-notify'
67
+ say_success 'Test notification sent successfully.'
68
+ else
69
+ say_error 'Test notification could not be delivered.'
70
+ end
71
+
72
+ Nadir::Transport::HTTPAsync.shut_down
73
+ end
74
+ end
75
+ end
76
+
77
+ run!
78
+ end
79
+
80
+ def config_file_path
81
+ File.expand_path 'config/nadir.yml'
82
+ end
83
+
84
+ def say_success(message)
85
+ say color(message, :green)
86
+ end
87
+
88
+ def say_error(message)
89
+ say color(message, :red)
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,50 @@
1
+ require 'yaml'
2
+
3
+ module Nadir
4
+ class Config
5
+ attr_accessor :api_key,
6
+ :api_url,
7
+ :env,
8
+ :logger,
9
+ :root,
10
+ :enabled_for
11
+
12
+ def initialize
13
+ @env = ENV['NADIR_ENV'] || ENV['RAILS_ENV'] || ENV['RACK_ENV']
14
+ @api_key = ENV['NADIR_API_KEY']
15
+ @api_url = 'https://nadir.dev/api'.freeze
16
+ @enabled_for = %w(production staging)
17
+
18
+ @logger = Logger.new(STDOUT)
19
+ end
20
+
21
+ def validate
22
+ unless @api_key
23
+ logger.warn '[Nadir] API-KEY not set, skipping notifications.'
24
+
25
+ return false
26
+ end
27
+
28
+ unless @enabled_for.include? @env.to_s
29
+ logger.warn "[Nadir] Reporting disabled for environment '#{@env}', skipping notification."
30
+
31
+ return false
32
+ end
33
+
34
+ true
35
+ end
36
+
37
+ def load_for(app)
38
+ @env ||= Rails.env
39
+ @root = app.root
40
+
41
+ config_file = @root.join 'config/nadir.yml'
42
+
43
+ file_config = YAML.safe_load File.read config_file
44
+
45
+ @api_key = file_config['api_key'] if file_config['api_key']
46
+ @api_url = file_config['api_url'] if file_config['api_url']
47
+ @enabled_for = file_config['enabled_for'] if file_config['enabled_for']
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,35 @@
1
+ module Nadir
2
+ module Middleware
3
+ class Rack
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ begin
10
+ response = @app.call(env)
11
+ rescue Exception => exception
12
+ request = ActionDispatch::Request.new env
13
+
14
+ headers = request.headers.env.select{|k, _| k.in?(ActionDispatch::Http::Headers::CGI_VARIABLES) || k =~ /^HTTP_/}
15
+ location = request.parameters.values_at('controller', 'action').compact.join('#')
16
+ location = location.presence || "#{headers['REQUEST_METHOD']} #{headers['PATH_INFO']}"
17
+
18
+ request_params = {
19
+ params: request.parameters,
20
+ remote_ip: request.remote_ip,
21
+ headers: headers,
22
+ }
23
+
24
+ Nadir.notify exception, location: location, request: request_params
25
+
26
+ raise
27
+ end
28
+
29
+ response
30
+ ensure
31
+ # Nadir.clear_request_data
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,55 @@
1
+ module Nadir
2
+ class Notification
3
+ def initialize(exception, params = {})
4
+ @exception = exception
5
+ @params = params
6
+ end
7
+
8
+ def to_params
9
+ {
10
+ class: @exception.class.name,
11
+ message: @exception.message,
12
+ location: location,
13
+ backtrace: backtrace.join("\n"),
14
+ environment: Nadir.config.env,
15
+ timestamp: Time.current,
16
+ fingerprint: fingerprint,
17
+ host: Socket.gethostname,
18
+ pid: Process.pid,
19
+ request_params: @params.dig(:request, :params),
20
+ request_remote_ip: @params.dig(:request, :remote_ip),
21
+ request_headers: @params.dig(:request, :headers),
22
+ }
23
+ end
24
+
25
+ private
26
+
27
+ def location
28
+ @params[:location] || $PROGRAM_NAME
29
+ end
30
+
31
+ def backtrace
32
+ @_backtrace ||=
33
+ begin
34
+ cleaner = ActiveSupport::BacktraceCleaner.new
35
+ gem_paths.each { |gem_path| cleaner.add_filter { |line| line.sub(gem_path, '') } }
36
+ cleaner.add_filter { |line| line.sub(Nadir.config.root.to_s, '') }
37
+ cleaner.add_filter { |line| line.sub('/', '') }
38
+
39
+ cleaner.clean(@exception.backtrace)
40
+ end
41
+ end
42
+
43
+ def fingerprint
44
+ first_backtrace_line = backtrace.find { |trace| trace !~ /pry|irb/ }
45
+ checksum = [first_backtrace_line, @exception.class].join('|')
46
+
47
+ Digest::SHA1.hexdigest checksum
48
+ end
49
+
50
+ def gem_paths
51
+ @gem_paths ||= Gem.path | [Gem.default_dir]
52
+ end
53
+ end
54
+ end
55
+
@@ -0,0 +1,15 @@
1
+ module Nadir
2
+ class Railtie < Rails::Railtie
3
+ initializer 'Nadir.use_rack_middleware' do |app|
4
+ if defined? ActionDispatch::DebugExceptions
5
+ app.middleware.insert_after ActionDispatch::DebugExceptions, Nadir::Middleware::Rack
6
+ else
7
+ app.middleware.use Nadir::Middleware::Rack
8
+ end
9
+ end
10
+
11
+ initializer 'Nadir.configuration' do |app|
12
+ Nadir.config.load_for app
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,40 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'uri'
4
+ require 'concurrent'
5
+
6
+ module Nadir
7
+ module Transport
8
+ class HTTPAsync
9
+ def initialize
10
+ @api_key = Nadir.config.api_key
11
+ @api_url = Nadir.config.api_url
12
+ end
13
+
14
+ class << self
15
+ def thread_pool
16
+ @thread_pool ||= Concurrent::ThreadPoolExecutor.new(max_threads: 5)
17
+ end
18
+
19
+ def shut_down
20
+ thread_pool.shutdown
21
+ thread_pool.wait_for_termination
22
+ end
23
+ end
24
+
25
+ def deliver(params)
26
+ self.class.thread_pool.post do
27
+ uri = URI("#{@api_url}/faults")
28
+ post = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
29
+ post.body = {fault: params, api_key: @api_key}.to_json
30
+
31
+ request = Net::HTTP.new(uri.hostname, uri.port)
32
+ request.use_ssl = true
33
+ response = request.start do |http|
34
+ http.request post
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module Nadir
2
+ VERSION = '1.0.0'
3
+ end
data/lib/nadir.rb ADDED
@@ -0,0 +1,43 @@
1
+ require 'nadir/config'
2
+ require 'nadir/middleware/rack'
3
+ require 'nadir/notification'
4
+ require 'nadir/transport/http_async'
5
+ require 'nadir/version'
6
+
7
+ module Nadir
8
+ extend self
9
+
10
+ def config
11
+ @config ||= Config.new
12
+ end
13
+
14
+ def configure
15
+ yield config if block_given?
16
+ end
17
+
18
+ def logger
19
+ config.logger
20
+ end
21
+
22
+ def notify(exception, params = {})
23
+ return false unless config.validate
24
+
25
+ notification = Notification.new exception, params
26
+
27
+ transport.deliver notification.to_params
28
+
29
+ true
30
+ rescue => e
31
+ logger.error "[Nadir] Internal error: #{e.inspect}"
32
+
33
+ false
34
+ end
35
+
36
+ private
37
+
38
+ def transport
39
+ @_transport ||= Nadir::Transport::HTTPAsync.new
40
+ end
41
+ end
42
+
43
+ require 'nadir/plugins/rails' if defined? Rails::Railtie
data/nadir.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ lib = File.expand_path 'lib', __dir__
2
+ $LOAD_PATH.unshift lib unless $LOAD_PATH.include? lib
3
+
4
+ require 'nadir/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'nadir'
8
+ spec.version = Nadir::VERSION
9
+ spec.authors = ['Georgi Mitrev']
10
+ spec.email = ['gvmitrev@gmail.com']
11
+ spec.summary = %q{Ruby library for Nadir}
12
+ spec.description = %q{A client library for Nadir integration}
13
+ spec.homepage = 'https://github.com/gmitrev/nadir-rb'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
17
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ end
19
+
20
+ spec.require_paths = ['lib']
21
+ spec.bindir = 'bin'
22
+ spec.executables << 'nadir'
23
+
24
+ spec.add_dependency 'concurrent-ruby', '~> 1.0'
25
+ spec.add_dependency 'commander', '~> 4.4'
26
+
27
+ spec.add_development_dependency 'bundler', '~> 1.17'
28
+ spec.add_development_dependency 'rake', '~> 10.0'
29
+ spec.add_development_dependency 'rspec', '~> 3.0'
30
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nadir
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Georgi Mitrev
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-03-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: concurrent-ruby
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: commander
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.17'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.17'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ description: A client library for Nadir integration
84
+ email:
85
+ - gvmitrev@gmail.com
86
+ executables:
87
+ - nadir
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".rspec"
93
+ - ".travis.yml"
94
+ - Gemfile
95
+ - Gemfile.lock
96
+ - LICENSE.txt
97
+ - README.md
98
+ - Rakefile
99
+ - bin/console
100
+ - bin/nadir
101
+ - lib/nadir.rb
102
+ - lib/nadir/cli.rb
103
+ - lib/nadir/config.rb
104
+ - lib/nadir/middleware/rack.rb
105
+ - lib/nadir/notification.rb
106
+ - lib/nadir/plugins/rails.rb
107
+ - lib/nadir/transport/http_async.rb
108
+ - lib/nadir/version.rb
109
+ - nadir.gemspec
110
+ homepage: https://github.com/gmitrev/nadir-rb
111
+ licenses:
112
+ - MIT
113
+ metadata: {}
114
+ post_install_message:
115
+ rdoc_options: []
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ requirements: []
129
+ rubyforge_project:
130
+ rubygems_version: 2.7.6
131
+ signing_key:
132
+ specification_version: 4
133
+ summary: Ruby library for Nadir
134
+ test_files: []