RaygunRuby 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 RaygunRuby.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 j-mcnally
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.
@@ -0,0 +1,43 @@
1
+ # RaygunRuby
2
+
3
+ Integrate rails with the Raygun.io service.
4
+
5
+ I, nor kohactive are in anyway associated with the offical raygun.io, we just couldn't wait for them to develop a rails solution so we rolled our own.
6
+
7
+ Throwing exceptions has never been so much fun.
8
+
9
+
10
+
11
+
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ gem 'RaygunRuby', '0.9.7'
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install RaygunRuby
26
+
27
+ Also generate a raygun.yml with
28
+
29
+ $ rake raygun:install
30
+
31
+ ## Usage
32
+
33
+ Add the following to which ever config/environment files you want to use with raygun
34
+
35
+ config.middleware.use RaygunRuby::Middleware
36
+
37
+ ## Contributing
38
+
39
+ 1. Fork it
40
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
41
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
42
+ 4. Push to the branch (`git push origin my-new-feature`)
43
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'RaygunRuby/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "RaygunRuby"
8
+ gem.version = RaygunRuby::VERSION
9
+ gem.authors = ["j-mcnally"]
10
+ gem.email = ["justin@kohactive.com"]
11
+ gem.description = "Raygun api implementation for rails"
12
+ gem.summary = "Allows usage of raygun and rails"
13
+ gem.homepage = "http://www.kohactive.com"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_runtime_dependency "thor"
21
+ gem.add_runtime_dependency "faraday"
22
+ gem.add_runtime_dependency "awesome_print"
23
+
24
+ end
@@ -0,0 +1,26 @@
1
+ require "RaygunRuby/version"
2
+ require "RaygunRuby/RaygunClientMessage"
3
+ require "RaygunRuby/RaygunMessageDetails"
4
+ require "RaygunRuby/RaygunRequestMessage"
5
+ require "RaygunRuby/RaygunExceptionMessage"
6
+ require "RaygunRuby/RaygunExceptionTraceLineMessage"
7
+ require "RaygunRuby/RaygunMessage"
8
+ require "RaygunRuby/RaygunClient"
9
+ require "RaygunRuby/base"
10
+
11
+
12
+
13
+ module RaygunRuby
14
+ class Middleware
15
+ include RaygunRuby::Base
16
+ end
17
+ class Config
18
+ def self.read
19
+ my_env = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || "development"
20
+ YAML.load_file("#{Rails.root}/config/raygun.yml")["#{my_env}"]
21
+ end
22
+ end
23
+ end
24
+
25
+ require "RaygunRuby/thor_stuff"
26
+ require "RaygunRuby/railties"
@@ -0,0 +1,50 @@
1
+ require "faraday"
2
+
3
+ module RaygunRuby
4
+ class RaygunClient
5
+
6
+
7
+ def self.send_exception(exception, tags=nil, userCustomData=nil, env=nil)
8
+ msg = self.build_message(exception, env)
9
+ self.send_msg(msg)
10
+
11
+ end
12
+
13
+ def self.build_message(errorException, env)
14
+
15
+ message = RaygunMessage.new()
16
+ message.build(errorException, env)
17
+
18
+ end
19
+
20
+ def self.send_msg(message)
21
+ begin
22
+ apiKey = RaygunRuby::Config::read["apiKey"]
23
+ rescue
24
+ raise "API_KEY not valid, cannot send message to Raygun"
25
+ end
26
+ bdy = message.api_attributes.to_json
27
+
28
+ connection = Faraday.new 'https://api.raygun.io', :ssl => {:ca_file => "../../vendor/cacert.crt"} do |faraday|
29
+ faraday.response :logger # log requests to STDOUT
30
+ faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
31
+ end
32
+
33
+ request = connection.post do |req|
34
+ req.url "/entries"
35
+ req.headers["X-ApiKey"] = apiKey
36
+ req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
37
+ req.headers['User-Agent'] = "Hai Raygun"
38
+ req.body = bdy
39
+
40
+ end
41
+
42
+ puts request.body
43
+
44
+
45
+
46
+ end
47
+
48
+
49
+ end
50
+ end
@@ -0,0 +1,20 @@
1
+ module RaygunRuby
2
+ class RaygunClientMessage
3
+ attr_accessor :name, :version, :clientUrl
4
+
5
+ def initialize
6
+ self.name = "RaygunRuby"
7
+ self.version = RaygunRuby::VERSION
8
+ self.clientUrl = "https://github.com/j-mcnally/RaygunRuby"
9
+ self
10
+ end
11
+
12
+ def api_attributes
13
+ {
14
+ name: self.name,
15
+ version: self.version,
16
+ clientUrl: self.clientUrl
17
+ }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,29 @@
1
+ module RaygunRuby
2
+ class RaygunExceptionMessage
3
+ attr_accessor :message, :classname, :stacktrace, :filename, :data
4
+ def initialize(exception)
5
+ exceptionClass = exception.class.name
6
+ self.message = "#{exceptionClass}: #{exception.message}"
7
+ begin
8
+ backTraceLine = exception.backtrace.first
9
+ self.filename = File::basename(backTraceLine.split(":").first)
10
+ self.classname = File.basename(self.filename, ".rb").camelize
11
+ rescue
12
+ self.filename = "Unknown"
13
+ self.classname = "Unknown"
14
+ end
15
+ self.stacktrace = exception.backtrace.collect{|bt| RaygunExceptionTraceLineMessage.new(bt) }
16
+ self.data = nil
17
+ self
18
+ end
19
+ def api_attributes
20
+ {
21
+ "Message" => self.message,
22
+ "ClassName" => self.classname,
23
+ "StackTrace" => self.stacktrace.collect{|s| s.api_attributes},
24
+ "FileName" => self.filename,
25
+ "Data" => self.data
26
+ }
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,23 @@
1
+ module RaygunRuby
2
+ class RaygunExceptionTraceLineMessage
3
+ attr_accessor :lineNumber, :className, :fileName, :methodName
4
+
5
+ def initialize (logline)
6
+ line = logline.split(":")
7
+ self.lineNumber = line[1]
8
+ self.fileName = line[0]
9
+ self.methodName = line[2]
10
+ self.className = File.basename(self.fileName, ".rb")
11
+ end
12
+
13
+ def api_attributes
14
+ {
15
+ "LineNumber" => self.lineNumber.to_i,
16
+ "ClassName" => self.className,
17
+ "FileName" => self.fileName,
18
+ "MethodName" => self.methodName
19
+ }
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ require "socket"
2
+
3
+ module RaygunRuby
4
+ class RaygunMessage
5
+ attr_accessor :occurredOn, :details
6
+ def initialize
7
+ self.occurredOn = Time.now.gmtime.strftime("%Y-%m-%d\T%H:%M:%S")
8
+ self.details = RaygunMessageDetails.new
9
+ self
10
+ end
11
+ def build(exception,env=nil)
12
+ self.details.machineName = Socket.gethostname
13
+ self.details.error = RaygunExceptionMessage.new(exception)
14
+ self.details.request = RaygunRequestMessage.new(env)
15
+ self.details.client = RaygunClientMessage.new
16
+ self
17
+ end
18
+ def api_attributes
19
+ {
20
+ "Details" => self.details.api_attributes,
21
+ "OccurredOn" => self.occurredOn
22
+ }
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ module RaygunRuby
2
+ class RaygunMessageDetails
3
+ attr_accessor :error, :machineName, :request, :client, :version, :tags, :userCustomData
4
+ def initialize
5
+ self.tags=[]
6
+ self
7
+ end
8
+ def api_attributes
9
+ {
10
+ "Error" => self.error.api_attributes,
11
+ "MachineName" => self.machineName,
12
+ "Request" => self.request.api_attributes,
13
+ "Client" => self.client.api_attributes,
14
+ "Version" => self.version,
15
+ "Tags" => self.tags.to_json,
16
+ "UserCustomData" => self.userCustomData
17
+ }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,38 @@
1
+ require "awesome_print"
2
+
3
+ module RaygunRuby
4
+ class RaygunRequestMessage
5
+ attr_accessor :hostName, :url, :httpMethod, :ipAddress, :queryString, :headers, :data, :form, :rawData
6
+ def initialize(env)
7
+ return nil if env.nil?
8
+ self.hostName = env["HTTP_HOST"]
9
+ self.url = env["PATH_INFO"]
10
+ self.httpMethod = env["REQUEST_METHOD"]
11
+ self.ipAddress = env["REMOTE_ADDR"]
12
+ self.queryString = env["QUERY_STRING"].present? ? env["QUERY_STRING"] : nil
13
+ header_hash = env.keys.reject{|x| !x.include?("HTTP")}.map{|k| {"#{k}" => env[k]} }.map(&:to_a).flatten(1).reduce({}) {|h,(k,v)| h[k] = v; h}
14
+ hash_out = header_hash.dup
15
+ header_hash.each { |k, v| hash_out[k.to_s.sub("HTTP_", "").sub("_", " ").titleize.sub(" ", "-")] = v; hash_out.delete(k) }
16
+ header_hash = hash_out
17
+ self.headers = header_hash
18
+ self.data = env.inspect.to_s
19
+ self.form = env["action_dispatch.request.parameters"] rescue {}
20
+ self.rawData = nil
21
+ end
22
+
23
+ def api_attributes
24
+ {
25
+ hostName: self.hostName,
26
+ url: self.url,
27
+ httpMethod: self.httpMethod,
28
+ ipAddress: self.ipAddress,
29
+ queryString: self.queryString,
30
+ headers: self.headers,
31
+ data: self.data,
32
+ form: self.form,
33
+ rawData: self.rawData
34
+ }
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,51 @@
1
+ require "awesome_print"
2
+
3
+ module RaygunRuby
4
+ module Base
5
+ def self.included(base)
6
+ base.class_eval do
7
+ include Includes
8
+ end
9
+ end
10
+ end
11
+ module Includes
12
+
13
+ def initialize(app)
14
+ @ready = false
15
+ begin
16
+ key = RaygunRuby::Config::read["apiKey"]
17
+ puts "RayGun is charged"
18
+ @ready = true
19
+ rescue
20
+ puts "RayGun API Key is not configured::: run 'rake raygun:install'"
21
+ end
22
+
23
+
24
+
25
+ @app = app
26
+
27
+ end
28
+
29
+ def call(env)
30
+ dup._call(env) if @ready
31
+ end
32
+
33
+ def _call(env)
34
+ begin
35
+ @app.call(env)
36
+ rescue Exception => exception
37
+ raygun_handle_and_rethrow(exception,env)
38
+ end
39
+ end
40
+ def raygun_handle_and_rethrow(exception, env)
41
+ backtrace = exception.backtrace.join("\n")
42
+ message = exception.message
43
+ #ap env
44
+
45
+ RaygunRuby::RaygunClient::send_exception(exception, nil, nil, env)
46
+
47
+ raise exception
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,5 @@
1
+ class LoadTasks < Rails::Railtie
2
+ rake_tasks do
3
+ Dir[File.join(File.dirname(__FILE__),'tasks/*.rake')].each { |f| load f }
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ namespace :raygun do
2
+ desc "install raygun into project"
3
+ task :install => [:environment] do
4
+ ts = RaygunRuby::ThorStuff.new
5
+ ts.invoke :create_raygun_config
6
+ end
7
+ end
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'thor'
3
+ module RaygunRuby
4
+ class ThorStuff < Thor
5
+ include Thor::Actions
6
+
7
+ def self.source_root
8
+ File.dirname(__FILE__)
9
+ end
10
+
11
+
12
+ desc "create_raygun_config", "Create a raygun config"
13
+ def create_raygun_config
14
+ @apiKey = ask "What is your RayGun api key?:"
15
+ template "../../templates/raygun_yaml.tt", "#{Rails.root}/config/raygun.yml"
16
+ puts "Generating raygun.yml"
17
+ puts "You can edit the configuration in config/raygun.yml"
18
+ end
19
+
20
+ end
21
+ end