exception_notification-redmine 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a4f3e09e0c4a178a42ea58d78ca5c39744463531
4
- data.tar.gz: f671f36eb35d3f4d158453e41ff417d289e2baa0
3
+ metadata.gz: 7ea5ba9a31d299f90a015b6fddb06b635e543709
4
+ data.tar.gz: abc9e443b816d759b577560e9973411df7ecb4d3
5
5
  SHA512:
6
- metadata.gz: 6c43bfbfef407ea3cdd04fee98175149dd282980c2c76f77348b1811f743435ee99dd47de39894d7d14636c1b96568efcfe8d43287a4779e1c695946f17a4a4b
7
- data.tar.gz: a42974a96adac7a09128174eb1c83047b121a4a722e22e22598f3ddb169f0cef74d66d9d7b86f02698deff8b1debb9e3aaefcb41005d54ccc0b43c0bf86656aa
6
+ metadata.gz: b495d7d0926c6b2ffcd94fd31dea5800f4243d1b27ea76822d31f7df77c276774a9435acc17e14ce232bf3484727d9994afd901391d484a3a5d477f65df44b9d
7
+ data.tar.gz: db0682b400dd395e92a13e09f8710d5d2be1562c95db26d8d0d64a2df661401a43dbcdb9f77d9064a26a6f4a5524f01177c5c91418373b143e4f32aca1323f65
data/CHANGELOG CHANGED
@@ -2,3 +2,6 @@ Version 0.0.1: Initial release
2
2
  Version 0.0.2: Use a custom field to avoid creation of same issue multiple times
3
3
  Version 0.1.0: Version bump, add README.md, TODO.md and LICENCE
4
4
  Version 0.1.1: Update README.md
5
+ Version 0.2.0:
6
+ - Add issue fomatting in Redmine
7
+ - Add default issue prefix title
data/README.md CHANGED
@@ -4,6 +4,8 @@ This gem add a Redmine notifier to Exception Notification.
4
4
 
5
5
  This Ruby gem is an extension of the [exception_notification gem](http://rubygems.org/gems/exception_notification) to support creating issues in Redmine.
6
6
 
7
+ [![Gem Version](https://badge.fury.io/rb/exception_notification-redmine.svg)](http://badge.fury.io/rb/exception_notification-redmine)
8
+
7
9
  ## Installation
8
10
 
9
11
  Add this line to your application's Gemfile:
@@ -30,6 +32,7 @@ As of Rails 3 ExceptionNotification-Redmine is used as a rack middleware, or in
30
32
  Whatever::Application.config.middleware.use ExceptionNotification::Rack,
31
33
  # host_url: url of your Redmine host
32
34
  # issues_url: issues.json (Redmine REST API)
35
+ # issues_prefix: text prepended to the issue title (default: "[Error]")
33
36
  # api_key: the api key of the user that will be used to create the Redmine issue
34
37
  # project_id: create issues in the project with the given id, where id is either project_id or project identifier
35
38
  # tracker_id: create issues with the given tracker_id
@@ -39,8 +42,9 @@ Whatever::Application.config.middleware.use ExceptionNotification::Rack,
39
42
  # x_checksum_cf_id: custom field used to avoid creation of the same issue multiple times. You must use the DOM id assigned by Redmine to this field in the issue form. You can find it by creating an issue manually in your project and inspecting the HTML form, you should see something like name="issue[custom_field_values][19]", in this case the id would be 19.
40
43
 
41
44
  :redmine => {
42
- :host_url => "http://redmine.example.com",
45
+ :host_url => "https://redmine.example.com",
43
46
  :issues_url => "issues.json",
47
+ :issues_prefix => "[Error]",
44
48
  :api_key => "123456",
45
49
  :project_id => "test-project",
46
50
  :tracker_id => "1", # Bug
@@ -1,5 +1,5 @@
1
1
  module ExceptionNotification
2
2
  module Redmine
3
- VERSION = "0.1.1"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -1,59 +1,72 @@
1
1
  require 'action_dispatch'
2
2
  require 'httparty'
3
3
  require 'json'
4
+ require 'erb'
5
+ require 'pp'
4
6
 
5
7
  module ExceptionNotifier
6
8
 
7
9
  class RedmineNotifier
8
-
10
+
11
+ module Redmine
12
+ class MissingController
13
+ def method_missing(*args, &block)
14
+ end
15
+ end
16
+ end
17
+
9
18
  def initialize(config)
10
19
  @config = config
11
20
  end
12
21
 
13
22
  def call(exception, options={})
14
- env = options[:env]
15
- issue = compose_issue(options, exception)
16
- create_issue(issue) unless issue_exist?(issue)
23
+ unless options[:env].nil?
24
+ compose_data(options[:env], exception, options)
25
+ issue = compose_issue
26
+ create_issue(issue) unless issue_exist?(issue)
27
+ end
17
28
  end
18
-
29
+
19
30
  private
20
31
 
21
- def compose_issue(options, exception)
22
- env = options[:env]
23
-
24
- unless env.nil?
25
- options[:body] ||= {}
26
- options[:body][:server] = Socket.gethostname
27
- options[:body][:process] = $$
28
- options[:body][:rails_root] = Rails.root if defined?(Rails)
29
- options[:body][:exception] = { :error_class => exception.class.to_s,
30
- :message => exception.message.inspect,
31
- :backtrace => exception.backtrace }
32
- options[:body][:data] = (env['exception_notifier.exception_data'] || {}).merge(options[:data] || {})
33
-
34
- issue = {}
35
- issue[:project_id] = @config[:project_id]
36
- issue[:tracker_id] = @config[:tracker_id]
37
- issue[:status_id] = @config[:status_id]
38
- issue[:priority_id] = @config[:priority_id]
39
- issue[:assigned_to_id] = @config[:assigned_to_id]
40
- issue[:subject] = compose_subject(options, exception)
41
- issue[:custom_fields] = [{ :id => @config[:x_checksum_cf_id],
42
- :value => encode_subject(issue[:subject])}]
43
- issue[:description] = options[:body][:exception].inspect
44
- issue
45
- end
32
+ def compose_data(env, exception, options = {})
33
+ @env = env
34
+ @exception = exception
35
+ @options = options
36
+ @kontroller = env['action_controller.instance'] || MissingController.new
37
+ @request = ActionDispatch::Request.new(env)
38
+ @backtrace = exception.backtrace ? clean_backtrace(exception) : []
39
+ @data = (env['exception_notifier.exception_data'] || {}).merge(options[:data] || {})
46
40
  end
47
-
48
- def compose_subject(options, exception)
49
- env = options[:env]
50
- kontroller = env['action_controller.instance'] || MissingController.new
51
- subject = "#{kontroller.controller_name}##{kontroller.action_name}" if kontroller
52
- subject << " (#{exception.class})"
53
- subject << " #{exception.message.inspect}" if options[:verbose_subject]
41
+
42
+ def compose_issue
43
+ issue = {}
44
+ issue[:project_id] = @config[:project_id]
45
+ issue[:tracker_id] = @config[:tracker_id]
46
+ issue[:status_id] = @config[:status_id]
47
+ issue[:priority_id] = @config[:priority_id]
48
+ issue[:assigned_to_id] = @config[:assigned_to_id]
49
+ issue[:subject] = compose_subject
50
+ issue[:custom_fields] = [{ :id => @config[:x_checksum_cf_id],
51
+ :value => encode_subject(issue[:subject])}]
52
+ issue[:description] = compose_description
53
+ issue
54
+ end
55
+
56
+ def compose_subject
57
+ subject = "#{@config[:issues_prefix]} " || "[Error] "
58
+ subject << "#{@kontroller.controller_name}##{@kontroller.action_name}" if @kontroller
59
+ subject << " (#{@exception.class})"
60
+ subject << " #{@exception.message.inspect}" if @options[:verbose_subject]
54
61
  subject.length > 120 ? subject[0...120] + "..." : subject
55
62
  end
56
63
 
64
+ def compose_description
65
+ template_path = "#{File.dirname(__FILE__)}/views/exception_notifier/issue.text.erb"
66
+ template = File.open(template_path, "r").read
67
+ ERB.new(template, nil, '-').result(binding)
68
+ end
69
+
57
70
  def issues_url(params = {})
58
71
  default_params = { :key => @config[:api_key] }
59
72
  encoded_params = URI.encode_www_form(default_params.merge(params))
@@ -77,5 +90,13 @@ module ExceptionNotifier
77
90
  def encode_subject(subject)
78
91
  Digest::SHA2.hexdigest(subject)
79
92
  end
93
+
94
+ def clean_backtrace(exception)
95
+ if defined?(Rails) && Rails.respond_to?(:backtrace_cleaner)
96
+ Rails.backtrace_cleaner.send(:filter, exception.backtrace)
97
+ else
98
+ exception.backtrace
99
+ end
100
+ end
80
101
  end
81
102
  end
@@ -0,0 +1,35 @@
1
+ <%= @exception.class.to_s =~ /^[aeiou]/i ? 'An' : 'A' %> <%= @exception.class %> occurred in <%= @kontroller.controller_name %>#<%= @kontroller.action_name %>:
2
+
3
+ <%= @exception.message %>
4
+ <%= @backtrace.first %>
5
+
6
+ h1. Request
7
+
8
+ * URL : <%= @request.url %>
9
+ * HTTP Method: <%= @request.request_method %>
10
+ * IP address : <%= @request.remote_ip %>
11
+ * Parameters : <%= @request.filtered_parameters.inspect %>
12
+ * Timestamp : <%= Time.current %>
13
+ * Server : <%= Socket.gethostname %>
14
+ <% if defined?(Rails) -%>
15
+ * Rails root : <%= Rails.root %>
16
+ <% end -%>
17
+ * Process: <%= $$ %>
18
+
19
+ h1. Session
20
+
21
+ * session id: <%= @request.ssl? ? "[FILTERED]" : (@request.session['session_id'] || (@request.env["rack.session.options"] && @request.env["rack.session.options"][:id])).inspect %>
22
+ * data: <%= PP.pp(@request.session.to_hash, "") %>
23
+
24
+ h1. Environment
25
+
26
+ <% filtered_env = @request.filtered_env -%>
27
+ <% max = filtered_env.keys.map(&:to_s).max { |a, b| a.length <=> b.length } -%>
28
+ <% filtered_env.keys.map(&:to_s).sort.each do |key| -%>
29
+ <% inspect_object = filtered_env[key].is_a?(Hash) || filtered_env[key].is_a?(Array) ? filtered_env[key].inspect : filtered_env[key].to_s -%>
30
+ * <%= "%-*s: %s" % [max.length, key, inspect_object] %>
31
+ <% end -%>
32
+
33
+ h1. Backtrace
34
+
35
+ <%= @backtrace.join("\n") %>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exception_notification-redmine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Piacentini
@@ -102,6 +102,7 @@ files:
102
102
  - lib/exception_notification/redmine/version.rb
103
103
  - lib/exception_notifier/redmine.rb
104
104
  - lib/exception_notifier/redmine/redmine.rb
105
+ - lib/exception_notifier/redmine/views/exception_notifier/issue.text.erb
105
106
  homepage: https://github.com/Nuxos-Asia/exception_notification-redmine
106
107
  licenses:
107
108
  - MIT