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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ea5ba9a31d299f90a015b6fddb06b635e543709
|
4
|
+
data.tar.gz: abc9e443b816d759b577560e9973411df7ecb4d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 => "
|
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,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
|
-
|
15
|
-
|
16
|
-
|
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
|
22
|
-
env
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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.
|
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
|