deviant 0.0.1

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
+ SHA1:
3
+ metadata.gz: 221dace94e2713ad166d84f30ba336a514068f25
4
+ data.tar.gz: b9b135325edacb4b1682d053b4a9c69df43223c2
5
+ SHA512:
6
+ metadata.gz: d13b19a14a96d24e9300907a46c116c818267fb145d8e7daf481dedade5a2bf2a587b8bb2f83681e5151fe6c62db2c00fc4c3949e8a7a3b415c202f4594b5eda
7
+ data.tar.gz: 97152e43912f6dd0cd2cdc830b354ea5cf7b1a91da1346d59fbf42be8dfec5528590555eba5ef805d706896ab2b364045264e074cfd9bc2197d10778fa4051c6
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in deviant.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Ryan LeFevre
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,73 @@
1
+ # Deviant
2
+
3
+ An application exception logger written in Ruby and backed by elasticsearch. It can be integrated directly into your application or as Rack middleware (coming soon). Search index updates can be performed asynchronously via Sidekiq.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'deviant'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install deviant
18
+
19
+ If you don't have elasticsearch yet, you will need to install it. Luckily it's super easy. If you're running OSX and using homebrew, simply run:
20
+
21
+ ```
22
+ brew install elasticsearch
23
+ elasticsearch -f -D es.config=/usr/local/opt/elasticsearch/config/elasticsearch.yml
24
+ ```
25
+
26
+ ## Configuration
27
+
28
+ ``` ruby
29
+ Deviant.configure do
30
+ application 'my_application'
31
+ redis Redis.current
32
+ elasticsearch 'http://localhost:9292'
33
+ sidekiq true
34
+ end
35
+ ```
36
+
37
+ ## Logging
38
+
39
+ ``` ruby
40
+ begin
41
+ my_broken_code
42
+ rescue => e
43
+ # Generic Usage
44
+ Deviant.exception(e)
45
+
46
+ # All methods can end with ! to re-raise the exception after logging
47
+ Deviant.exception!(e)
48
+
49
+ # Log extra metadata, such as HTTP statuses or User info
50
+ Deviant.exception(e, status: 401, user: user.email)
51
+ end
52
+ ```
53
+
54
+ ## Searching
55
+
56
+ ``` ruby
57
+ # Helper method
58
+ Deviant.client.fetch("Broken").results.map(&:message)
59
+ Deviant.client.fetch(email: 'example@example.com').results
60
+
61
+ # Directly access Tire search
62
+ Deviant.client.search do
63
+ query { string "email:example@example.com" }
64
+ end
65
+ ```
66
+
67
+ ## Contributing
68
+
69
+ 1. Fork it
70
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
71
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
72
+ 4. Push to the branch (`git push origin my-new-feature`)
73
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/deviant.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'deviant/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "deviant"
8
+ spec.version = Deviant::VERSION
9
+ spec.authors = ["Ryan LeFevre"]
10
+ spec.email = ["meltingice8917@gmail.com"]
11
+ spec.description = %q{Elasticsearch backed exception logging}
12
+ spec.summary = %q{Elasticsearch backed exception logging}
13
+ spec.homepage = "https://github.com/meltingice/deviant"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "sidekiq"
22
+ spec.add_dependency "tire"
23
+ spec.add_dependency "yajl-ruby"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.3"
26
+ spec.add_development_dependency "rake"
27
+ end
@@ -0,0 +1,13 @@
1
+ require 'deviant'
2
+
3
+ Deviant.configure do
4
+ application 'testing'
5
+ elasticsearch 'http://localhost:9200'
6
+ redis 'redis://localhost:6379'
7
+ # sidekiq true
8
+ end
9
+
10
+ Deviant.client.index { delete }
11
+ Deviant.exception(StandardError.new("Fail"), user: 1)
12
+ Deviant.exception(StandardError.new("Extra fail"), user: 2)
13
+ Deviant.client.index { refresh }
@@ -0,0 +1,8 @@
1
+ require 'deviant'
2
+
3
+ Deviant.configure do
4
+ application 'testing'
5
+ elasticsearch 'http://localhost:9200'
6
+ redis 'redis://localhost:6379'
7
+ sidekiq true
8
+ end
@@ -0,0 +1,49 @@
1
+ module Deviant
2
+ class Client
3
+ def initialize(options)
4
+ @options = options
5
+ end
6
+
7
+ def store(name, message, data = {})
8
+ entry = {name: name, message: message, date: Time.now}.merge(data)
9
+ return store_async(entry) if @options[:sidekiq][:enabled]
10
+
11
+ index { store(entry) }
12
+ end
13
+
14
+ def fetch(query, tags = [])
15
+ query = build_query(query)
16
+ search do
17
+ query { string query }
18
+ filter :terms, tags: tags if tags.size > 0
19
+ sort { by :date, 'desc' }
20
+ end
21
+ end
22
+
23
+ def index(&block)
24
+ Tire.index @options[:name], &block
25
+ end
26
+
27
+ def search(&block)
28
+ Tire.search @options[:name], &block
29
+ end
30
+
31
+ private
32
+
33
+ def store_async(entry)
34
+ DeviantWorker.perform_async(entry)
35
+ end
36
+
37
+ def build_query(query)
38
+ if query.is_a?(Hash)
39
+ return query.to_a.map { |item|
40
+ "#{item[0]}:#{item[1]}"
41
+ }.join(' AND ')
42
+ elsif query.is_a?(Array)
43
+ query.join(' AND ')
44
+ else
45
+ query
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,82 @@
1
+ module Deviant
2
+ DEFAULTS = {
3
+ name: nil,
4
+ redis_url: "redis://localhost:9292",
5
+ elasticsearch_url: nil,
6
+ sidekiq: {
7
+ enabled: false,
8
+ configure_server: false,
9
+ configure_client: false
10
+ }
11
+ }
12
+
13
+ def self.options
14
+ @options ||= DEFAULTS.dup
15
+ end
16
+
17
+ def self.options=(opts)
18
+ @options = opts
19
+ end
20
+
21
+ def self.configure(&block)
22
+ class_eval &block
23
+ setup!
24
+ end
25
+
26
+ def self.application(name)
27
+ options[:name] = name
28
+ end
29
+
30
+ def self.redis(config)
31
+ if config.is_a?(Redis)
32
+ client = config.client
33
+ options[:redis_url] = "#{client.scheme}://#{client.host}:#{client.port}"
34
+ else
35
+ options[:redis_url] = config
36
+ end
37
+ end
38
+
39
+ def self.elasticsearch(url)
40
+ options[:elasticsearch_url] = url
41
+ end
42
+
43
+ def self.sidekiq(enabled, opts={})
44
+ options[:sidekiq][:enabled] = enabled
45
+ options[:sidekiq][:configure_server] = opts[:configure_server] || false
46
+ options[:sidekiq][:configure_client] = opts[:configure_client] || false
47
+ end
48
+
49
+ private
50
+
51
+ # A lot of 3rd party libraries are singletons, so we want to make
52
+ # sure we don't blow away the main application's config.
53
+ def self.setup!
54
+ @client = nil
55
+
56
+ if options[:sidekiq][:enabled]
57
+ if options[:sidekiq][:configure_client]
58
+ Sidekiq.configure_client do |config|
59
+ config.redis = {
60
+ namespace: options[:name],
61
+ url: options[:redis_url]
62
+ }
63
+ end
64
+ end
65
+
66
+ if options[:sidekiq][:configure_server]
67
+ Sidekiq.configure_server do |config|
68
+ config.redis = {
69
+ namespace: options[:name],
70
+ url: options[:redis_url]
71
+ }
72
+ end
73
+ end
74
+ end
75
+
76
+ if options[:elasticsearch_url]
77
+ Tire.configure do
78
+ url Deviant.options[:elasticsearch_url]
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,14 @@
1
+ module Deviant
2
+ def self.exception(e, data = {})
3
+ client.store e.class.name, e.message, data
4
+ end
5
+
6
+ def self.method_missing(method, *args, &block)
7
+ if args.length > 0 && method.to_s[-1] == '!' && respond_to?(method.to_s[0...-1])
8
+ send method.to_s[0...-1], *args, &block
9
+ raise args.first
10
+ end
11
+
12
+ super
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module Deviant
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,9 @@
1
+ class DeviantWorker
2
+ include Sidekiq::Worker
3
+
4
+ def perform(data)
5
+ Tire.index Deviant.options[:name] do
6
+ store(data)
7
+ end
8
+ end
9
+ end
data/lib/deviant.rb ADDED
@@ -0,0 +1,15 @@
1
+ require "tire"
2
+ require "sidekiq"
3
+ require "yajl/json_gem"
4
+
5
+ require "deviant/configuration"
6
+ require "deviant/client"
7
+ require "deviant/log"
8
+ require "deviant/worker"
9
+ require "deviant/version"
10
+
11
+ module Deviant
12
+ def self.client
13
+ @client ||= Client.new(options)
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: deviant
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ryan LeFevre
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sidekiq
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: tire
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: yajl-ruby
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Elasticsearch backed exception logging
84
+ email:
85
+ - meltingice8917@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - .gitignore
91
+ - Gemfile
92
+ - LICENSE.txt
93
+ - README.md
94
+ - Rakefile
95
+ - deviant.gemspec
96
+ - examples/client.rb
97
+ - examples/worker.rb
98
+ - lib/deviant.rb
99
+ - lib/deviant/client.rb
100
+ - lib/deviant/configuration.rb
101
+ - lib/deviant/log.rb
102
+ - lib/deviant/version.rb
103
+ - lib/deviant/worker.rb
104
+ homepage: https://github.com/meltingice/deviant
105
+ licenses:
106
+ - MIT
107
+ metadata: {}
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - '>='
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubyforge_project:
124
+ rubygems_version: 2.0.8
125
+ signing_key:
126
+ specification_version: 4
127
+ summary: Elasticsearch backed exception logging
128
+ test_files: []