redmine_airbrake_backend 0.5.4 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +6 -0
- data/{MIT-LICENSE → LICENSE.txt} +0 -0
- data/README.md +23 -18
- data/app/controllers/airbrake_controller.rb +16 -10
- data/app/controllers/airbrake_project_settings_controller.rb +7 -2
- data/app/helpers/airbrake_helper.rb +4 -8
- data/app/models/airbrake_project_setting.rb +1 -7
- data/app/views/airbrake/issue_description/default.erb +12 -21
- data/lib/redmine_airbrake_backend/engine.rb +5 -5
- data/lib/redmine_airbrake_backend/request/json.rb +26 -14
- data/lib/redmine_airbrake_backend/request/xml.rb +33 -32
- data/lib/redmine_airbrake_backend/version.rb +1 -1
- data/redmine_airbrake_backend.gemspec +2 -3
- metadata +8 -22
- data/Gemfile.lock +0 -91
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32a03ff4851b8529c9034cdecd783cca0582d59f
|
4
|
+
data.tar.gz: 6b60c2d7c6a1d88709f7e11244f87f63c037c94c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5af79b4d106c80114a277b7761124718c6d0d9dd90eeec046a89adea667a8d17c0d7dd0b646620808c49f73cb8497ccfa5e00b41dbac2d943d535be80f206e1
|
7
|
+
data.tar.gz: d53a8e9843aae8ff35a0dead5f20854db77b7d2bdca5ac9231585eb9e0684e15862e58b1afc64de3f9299f8e7ae3bbc5b85f13333de4e62bd92bdab855a7001c
|
data/.gitignore
CHANGED
data/CHANGELOG.md
ADDED
data/{MIT-LICENSE → LICENSE.txt}
RENAMED
File without changes
|
data/README.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
[](https://rubygems.org/gems/redmine_airbrake_backend)
|
2
|
+
[](https://gemnasium.com/ydkn/redmine_airbrake_backend)
|
3
|
+
[](https://codeclimate.com/github/ydkn/redmine_airbrake_backend)
|
4
|
+
|
1
5
|
# Redmine Airbrake Backend
|
2
6
|
|
3
7
|
This plugin provides the necessary API to use Redmine as an Airbrake backend.
|
@@ -7,27 +11,34 @@ This plugin provides the necessary API to use Redmine as an Airbrake backend.
|
|
7
11
|
Apply this [patch](http://www.redmine.org/issues/14402) to Redmine.
|
8
12
|
|
9
13
|
Add this line to your Redmine Gemfile:
|
10
|
-
|
11
|
-
|
14
|
+
```ruby
|
15
|
+
gem 'redmine_airbrake_backend'
|
16
|
+
```
|
12
17
|
|
13
18
|
And then execute:
|
14
|
-
|
15
|
-
|
16
|
-
|
19
|
+
```
|
20
|
+
$ bundle install
|
21
|
+
$ rake redmine:plugins:migrate
|
22
|
+
```
|
17
23
|
|
18
24
|
## Integration
|
19
25
|
|
20
|
-
1.
|
21
|
-
|
22
|
-
*
|
23
|
-
|
24
|
-
3.
|
25
|
-
4.
|
26
|
+
1. Enable REST web service authentication
|
27
|
+
2. Create the following custom fields for issues:
|
28
|
+
* Airbrake hash (String) (required)
|
29
|
+
* Number of occurrences (Integer) (optional)
|
30
|
+
3. Configure the plugin to use these 2 custom fields (Administration -> Plugins -> Airbrake -> Configure)
|
31
|
+
4. Enable the project module (Airbrake) in your project settings (don't forget to add at least the Airbrake hash field to your project)
|
32
|
+
5. Configure additional defaults under the settings tab (Airbrake)
|
26
33
|
|
27
34
|
## Client configuration
|
28
35
|
|
29
|
-
For a Rails application
|
36
|
+
For a Rails application add the airbrake gem to your Gemfile:
|
37
|
+
```ruby
|
38
|
+
gem 'airbrake'
|
39
|
+
```
|
30
40
|
|
41
|
+
And configure it, e.g. with a initializer `config/initializers/airbrake.rb`:
|
31
42
|
```ruby
|
32
43
|
Airbrake.configure do |config|
|
33
44
|
config.api_key = {
|
@@ -48,12 +59,6 @@ end
|
|
48
59
|
|
49
60
|
Based on https://github.com/milgner/redmine_airbrake_server
|
50
61
|
|
51
|
-
## Code Status
|
52
|
-
|
53
|
-
* [](http://badge.fury.io/rb/redmine_airbrake_backend)
|
54
|
-
* [](https://gemnasium.com/ydkn/redmine_airbrake_backend)
|
55
|
-
* [](https://codeclimate.com/github/ydkn/redmine_airbrake_backend)
|
56
|
-
|
57
62
|
## Contributing
|
58
63
|
|
59
64
|
1. Fork it
|
@@ -26,6 +26,8 @@ class AirbrakeController < ::ApplicationController
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def parse_xml_request
|
29
|
+
request.body.rewind
|
30
|
+
|
29
31
|
@request = RedmineAirbrakeBackend::Request::XML.parse(request.body)
|
30
32
|
|
31
33
|
params[:key] = @request.api_key
|
@@ -66,22 +68,26 @@ class AirbrakeController < ::ApplicationController
|
|
66
68
|
|
67
69
|
return issue if issue.present?
|
68
70
|
|
69
|
-
issue =
|
70
|
-
subject: error.subject,
|
71
|
-
project: @request.project,
|
72
|
-
tracker: @request.tracker,
|
73
|
-
author: User.current,
|
74
|
-
category: @request.category,
|
75
|
-
priority: @request.priority,
|
76
|
-
description: render_description(error),
|
77
|
-
assigned_to: @request.assignee
|
78
|
-
)
|
71
|
+
issue = initialize_issue(error)
|
79
72
|
|
80
73
|
add_error_attachments_to_issue(issue, error)
|
81
74
|
|
82
75
|
issue
|
83
76
|
end
|
84
77
|
|
78
|
+
def initialize_issue(error)
|
79
|
+
Issue.new(
|
80
|
+
subject: error.subject,
|
81
|
+
project: @request.project,
|
82
|
+
tracker: @request.tracker,
|
83
|
+
author: User.current,
|
84
|
+
category: @request.category,
|
85
|
+
priority: @request.priority,
|
86
|
+
description: render_description(error),
|
87
|
+
assigned_to: @request.assignee
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
85
91
|
def set_custom_field_values(issue, request, airbrake_hash)
|
86
92
|
custom_field_values = {}
|
87
93
|
|
@@ -6,7 +6,11 @@ class AirbrakeProjectSettingsController < ::ApplicationController
|
|
6
6
|
menu_item :settings
|
7
7
|
|
8
8
|
def update
|
9
|
-
@airbrake_project_setting.
|
9
|
+
@airbrake_project_setting.tracker_id = params[:airbrake_project_setting][:tracker_id]
|
10
|
+
@airbrake_project_setting.category_id = params[:airbrake_project_setting][:category_id]
|
11
|
+
@airbrake_project_setting.priority_id = params[:airbrake_project_setting][:priority_id]
|
12
|
+
@airbrake_project_setting.reopen_regexp = params[:airbrake_project_setting][:reopen_regexp]
|
13
|
+
@airbrake_project_setting.reopen_repeat_description = params[:airbrake_project_setting][:reopen_repeat_description]
|
10
14
|
|
11
15
|
if @airbrake_project_setting.save
|
12
16
|
flash[:notice] = l(:notice_successful_update)
|
@@ -22,6 +26,7 @@ class AirbrakeProjectSettingsController < ::ApplicationController
|
|
22
26
|
end
|
23
27
|
|
24
28
|
def find_airbrake_setting
|
25
|
-
@airbrake_project_setting = @project.airbrake_settings || AirbrakeProjectSetting.new
|
29
|
+
@airbrake_project_setting = @project.airbrake_settings || AirbrakeProjectSetting.new
|
30
|
+
@airbrake_project_setting.project = @project
|
26
31
|
end
|
27
32
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'htmlentities'
|
2
|
-
|
3
1
|
module AirbrakeHelper
|
4
2
|
# Wiki markup for a table
|
5
3
|
def format_table(data)
|
@@ -30,18 +28,16 @@ module AirbrakeHelper
|
|
30
28
|
|
31
29
|
# Wiki markup for backtrace element with link to repository if possible
|
32
30
|
def format_backtrace_element(element)
|
33
|
-
@htmlentities ||= HTMLEntities.new
|
34
|
-
|
35
31
|
repository = repository_for_backtrace_element(element)
|
36
32
|
|
37
33
|
if repository.blank?
|
38
34
|
if element[:number].blank?
|
39
|
-
markup = "@#{
|
35
|
+
markup = "@#{element[:file]}@"
|
40
36
|
else
|
41
|
-
markup = "@#{
|
37
|
+
markup = "@#{element[:file]}:#{element[:number]}@"
|
42
38
|
end
|
43
39
|
else
|
44
|
-
filename =
|
40
|
+
filename = filename_for_backtrace_element(element)
|
45
41
|
|
46
42
|
if repository.identifier.blank?
|
47
43
|
markup = "source:\"#{filename}#L#{element[:number]}\""
|
@@ -50,7 +46,7 @@ module AirbrakeHelper
|
|
50
46
|
end
|
51
47
|
end
|
52
48
|
|
53
|
-
markup + " in ??<notextile>#{
|
49
|
+
markup + " in ??<notextile>#{element[:method]}</notextile>??"
|
54
50
|
end
|
55
51
|
|
56
52
|
private
|
@@ -1,15 +1,9 @@
|
|
1
|
-
require 'redmine/safe_attributes'
|
2
|
-
|
3
1
|
# Project-specific settings for airbrake
|
4
2
|
class AirbrakeProjectSetting < ActiveRecord::Base
|
5
|
-
include Redmine::SafeAttributes
|
6
|
-
|
7
3
|
belongs_to :project
|
8
4
|
belongs_to :tracker
|
9
5
|
belongs_to :category, class_name: IssueCategory.name
|
10
6
|
belongs_to :priority, class_name: IssuePriority.name
|
11
7
|
|
12
|
-
|
13
|
-
|
14
|
-
safe_attributes :tracker_id, :category_id, :priority_id, :reopen_regexp, :reopen_repeat_description
|
8
|
+
validates :project_id, presence: true
|
15
9
|
end
|
@@ -4,56 +4,47 @@ h1. <%= error.message %>
|
|
4
4
|
<% if error.application.present? %>
|
5
5
|
h2. Application:
|
6
6
|
|
7
|
-
<%=format_list_item('Name', error.application[:name]) %>
|
8
|
-
<%=format_list_item('Version', error.application[:version]) %>
|
7
|
+
<%= format_list_item('Name', error.application[:name]) %>
|
8
|
+
<%= format_list_item('Version', error.application[:version]) %>
|
9
9
|
<% end %>
|
10
10
|
|
11
11
|
<% if error.backtrace.present? %>
|
12
12
|
h2. Stacktrace:
|
13
13
|
|
14
|
-
p((. <%=raw error.backtrace.collect { |e| format_backtrace_element(e) }.join("\n") %>
|
14
|
+
p((. <%= raw error.backtrace.collect { |e| format_backtrace_element(e) }.join("\n") %>
|
15
15
|
<% end %>
|
16
16
|
<% end %>
|
17
17
|
|
18
18
|
<% if request.request.present? %>
|
19
19
|
h2. Request:
|
20
20
|
|
21
|
-
<%=format_list_item('URL', request.request[:url]) %>
|
22
|
-
<%=format_list_item('Component', request.request[:component]) %>
|
23
|
-
<%=format_list_item('Action', request.request[:action]) %>
|
21
|
+
<%= format_list_item('URL', request.request[:url]) %>
|
22
|
+
<%= format_list_item('Component', request.request[:component]) %>
|
23
|
+
<%= format_list_item('Action', request.request[:action]) %>
|
24
24
|
|
25
25
|
<% if request.request[:params].present? %>
|
26
26
|
h2. Parameters:
|
27
27
|
|
28
|
-
<%=format_table(request.request[:params]) %>
|
28
|
+
<%= format_table(request.request[:params]) %>
|
29
29
|
<% end %>
|
30
30
|
|
31
31
|
<% if request.request[:cgi_data].present? %>
|
32
32
|
h2. Headers:
|
33
33
|
|
34
|
-
<%=format_table(request.request[:cgi_data]) %>
|
34
|
+
<%= format_table(request.request[:cgi_data]) %>
|
35
35
|
<% end %>
|
36
36
|
|
37
|
-
<% log = request.request[:session].delete(:log) if request.request[:session].present? %>
|
38
37
|
<% if request.request[:session].present? %>
|
39
38
|
h2. Session:
|
40
39
|
|
41
|
-
<%=format_table(request.request[:session]) %>
|
42
|
-
<% end %>
|
43
|
-
|
44
|
-
<% if log.present? %>
|
45
|
-
h2. Log:
|
46
|
-
|
47
|
-
<pre>
|
48
|
-
<%=format_log(log) %>
|
49
|
-
</pre>
|
40
|
+
<%= format_table(request.request[:session]) %>
|
50
41
|
<% end %>
|
51
42
|
<% end %>
|
52
43
|
|
53
44
|
<% if request.env.present? %>
|
54
45
|
h2. Environment
|
55
46
|
|
56
|
-
<%=format_list_item('Name', request.environment_name) %>
|
57
|
-
<%=format_list_item('Directory', request.env[:project_root]) %>
|
58
|
-
<%=format_list_item('Hostname', request.env[:hostname]) %>
|
47
|
+
<%= format_list_item('Name', request.environment_name) %>
|
48
|
+
<%= format_list_item('Directory', request.env[:project_root]) %>
|
49
|
+
<%= format_list_item('Hostname', request.env[:hostname]) %>
|
59
50
|
<% end %>
|
@@ -8,11 +8,11 @@ module RedmineAirbrakeBackend
|
|
8
8
|
|
9
9
|
initializer 'redmine_airbrake_backend.apply_patches', after: 'redmine_airbrake_backend.register_redmine_plugin' do |app|
|
10
10
|
ActionDispatch::Callbacks.to_prepare do
|
11
|
-
require_dependency 'redmine_airbrake_backend/patches/project'
|
12
|
-
require_dependency 'redmine_airbrake_backend/patches/tracker'
|
13
|
-
require_dependency 'redmine_airbrake_backend/patches/issue_category'
|
14
|
-
require_dependency 'redmine_airbrake_backend/patches/issue_priority'
|
15
|
-
require_dependency 'redmine_airbrake_backend/patches/projects_helper'
|
11
|
+
require_dependency 'redmine_airbrake_backend/patches/project' unless defined?(RedmineAirbrakeBackend::Patches::Project)
|
12
|
+
require_dependency 'redmine_airbrake_backend/patches/tracker' unless defined?(RedmineAirbrakeBackend::Patches::Tracker)
|
13
|
+
require_dependency 'redmine_airbrake_backend/patches/issue_category' unless defined?(RedmineAirbrakeBackend::Patches::IssueCategory)
|
14
|
+
require_dependency 'redmine_airbrake_backend/patches/issue_priority' unless defined?(RedmineAirbrakeBackend::Patches::IssuePriority)
|
15
|
+
require_dependency 'redmine_airbrake_backend/patches/projects_helper' unless defined?(RedmineAirbrakeBackend::Patches::ProjectsHelper)
|
16
16
|
|
17
17
|
RedmineAirbrakeBackend::Engine.apply_patch(Project, RedmineAirbrakeBackend::Patches::Project)
|
18
18
|
RedmineAirbrakeBackend::Engine.apply_patch(Tracker, RedmineAirbrakeBackend::Patches::Tracker)
|
@@ -15,16 +15,9 @@ module RedmineAirbrakeBackend
|
|
15
15
|
env = parse_plain_section(parsed_json_data[:environment])
|
16
16
|
config = parsed_json_data[:key]
|
17
17
|
|
18
|
-
errors
|
19
|
-
|
20
|
-
(parsed_json_data[:
|
21
|
-
error = parse_error(error_data)
|
22
|
-
errors << ::RedmineAirbrakeBackend::Error.new(error) if error.present?
|
23
|
-
end
|
24
|
-
|
25
|
-
report = parse_report(parsed_json_data[:type], parsed_json_data[:report])
|
26
|
-
errors << ::RedmineAirbrakeBackend::Error.new(report) if report.present?
|
27
|
-
|
18
|
+
errors = []
|
19
|
+
errors += parse_errors(parsed_json_data[:errors])
|
20
|
+
errors << parse_report(parsed_json_data[:type], parsed_json_data[:report])
|
28
21
|
errors.compact!
|
29
22
|
|
30
23
|
raise Invalid.new('No error or report found') if errors.blank?
|
@@ -40,11 +33,22 @@ module RedmineAirbrakeBackend
|
|
40
33
|
section_data.symbolize_keys
|
41
34
|
end
|
42
35
|
|
36
|
+
def self.parse_errors(errors)
|
37
|
+
errors = []
|
38
|
+
|
39
|
+
(errors || []).each do |error_data|
|
40
|
+
error = parse_error(error_data)
|
41
|
+
errors << ::RedmineAirbrakeBackend::Error.new(error) if error.present?
|
42
|
+
end
|
43
|
+
|
44
|
+
errors
|
45
|
+
end
|
46
|
+
|
43
47
|
def self.parse_error(error_data)
|
44
48
|
return nil if error_data.blank?
|
45
49
|
|
46
50
|
error = {}
|
47
|
-
error[:type] = error_data[:type]
|
51
|
+
error[:type] = secure_type(error_data[:type])
|
48
52
|
error[:message] = error_data[:message]
|
49
53
|
error[:backtrace] = error_data[:backtrace].map do |backtrace_element|
|
50
54
|
{
|
@@ -60,13 +64,21 @@ module RedmineAirbrakeBackend
|
|
60
64
|
def self.parse_report(type, report_data)
|
61
65
|
return nil if report_data.blank?
|
62
66
|
|
63
|
-
|
67
|
+
sec_type = secure_type(type)
|
64
68
|
|
65
|
-
|
69
|
+
require "redmine_airbrake_backend/report/#{sec_type}" rescue nil
|
70
|
+
|
71
|
+
clazz = "RedmineAirbrakeBackend::Report::#{sec_type.camelize}".constantize rescue nil
|
66
72
|
|
67
73
|
return nil if clazz.blank?
|
68
74
|
|
69
|
-
clazz.parse(report_data)
|
75
|
+
report = clazz.parse(report_data)
|
76
|
+
|
77
|
+
report.present? ? ::RedmineAirbrakeBackend::Error.new(report) : nil
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.secure_type(type)
|
81
|
+
type.to_s.gsub(/[^a-zA-Z0-9_-]/, '')
|
70
82
|
end
|
71
83
|
end
|
72
84
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'json'
|
2
|
-
require '
|
2
|
+
require 'nokogiri'
|
3
3
|
require 'redmine_airbrake_backend/request'
|
4
4
|
|
5
5
|
module RedmineAirbrakeBackend
|
@@ -13,25 +13,25 @@ module RedmineAirbrakeBackend
|
|
13
13
|
|
14
14
|
# Creates a notice from an airbrake xml request
|
15
15
|
def self.parse(xml_data)
|
16
|
-
doc =
|
16
|
+
doc = Nokogiri::XML(xml_data) rescue nil
|
17
17
|
raise Invalid if doc.blank?
|
18
18
|
|
19
|
-
notice = doc.at('notice')
|
19
|
+
notice = doc.at('//notice')
|
20
20
|
raise Invalid if notice.blank?
|
21
21
|
|
22
22
|
# Version
|
23
23
|
version = notice.attributes['version']
|
24
|
-
raise Invalid.new('No version') if version.blank?
|
25
|
-
raise UnsupportedVersion.new(version) unless SUPPORTED_API_VERSIONS.include?(version)
|
24
|
+
raise Invalid.new('No version') if version.blank? || version.value.blank?
|
25
|
+
raise UnsupportedVersion.new(version) unless SUPPORTED_API_VERSIONS.include?(version.value)
|
26
26
|
|
27
27
|
error_data = parse_error(notice)
|
28
28
|
raise Invalid.new('No error found') if error_data.blank?
|
29
29
|
error = RedmineAirbrakeBackend::Error.new(error_data)
|
30
30
|
|
31
|
-
notifier = convert_element(notice.at('notifier'))
|
31
|
+
notifier = convert_element(notice.at('//notifier'))
|
32
32
|
request = parse_request(notice)
|
33
|
-
env = convert_element(notice.at('server-environment'))
|
34
|
-
config = notice.at('api-key').inner_text
|
33
|
+
env = convert_element(notice.at('//server-environment'))
|
34
|
+
config = notice.at('//api-key').inner_text
|
35
35
|
|
36
36
|
new(config, notifier: notifier, errors: [error], request: request, env: env)
|
37
37
|
end
|
@@ -39,7 +39,7 @@ module RedmineAirbrakeBackend
|
|
39
39
|
private
|
40
40
|
|
41
41
|
def self.parse_error(notice_doc)
|
42
|
-
error = convert_element(notice_doc.at('error'))
|
42
|
+
error = convert_element(notice_doc.at('//error'))
|
43
43
|
|
44
44
|
# map class to type
|
45
45
|
error[:type] ||= error[:class]
|
@@ -51,24 +51,27 @@ module RedmineAirbrakeBackend
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def self.parse_request(notice_doc)
|
54
|
-
|
55
|
-
|
56
|
-
if request.present? && request[:session].present?
|
57
|
-
request[:session][:log] = request[:session][:log].present? ? format_session_log(request[:session][:log]) : nil
|
58
|
-
end
|
59
|
-
|
60
|
-
request
|
54
|
+
convert_element(notice_doc.at('//request'))
|
61
55
|
end
|
62
56
|
|
63
57
|
def self.convert_element(elem)
|
64
58
|
return nil if elem.nil?
|
65
|
-
|
66
|
-
return elem.
|
59
|
+
|
60
|
+
return elem.children.first.inner_text if elem.children.count == 1 && elem.children.first.is_a?(Nokogiri::XML::Text)
|
61
|
+
return convert_attributes(elem.attributes) if elem.children.blank?
|
67
62
|
return convert_var_elements(elem.children) if elem.children.count == elem.children.select { |c| c.name == 'var' }.count
|
68
63
|
|
64
|
+
h = convert_children(elem)
|
65
|
+
h.delete_if { |k, v| k.strip.blank? }
|
66
|
+
h.symbolize_keys
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.convert_children(elem)
|
69
70
|
h = {}
|
71
|
+
|
70
72
|
elem.children.each do |e|
|
71
73
|
key = format_hash_key(e.name)
|
74
|
+
|
72
75
|
if h.key?(key)
|
73
76
|
h[key] = [h[key]] unless h[key].is_a?(Array)
|
74
77
|
h[key] << convert_element(e)
|
@@ -76,8 +79,8 @@ module RedmineAirbrakeBackend
|
|
76
79
|
h[key] = convert_element(e)
|
77
80
|
end
|
78
81
|
end
|
79
|
-
|
80
|
-
h
|
82
|
+
|
83
|
+
h
|
81
84
|
end
|
82
85
|
|
83
86
|
def self.convert_var_elements(elements)
|
@@ -93,6 +96,16 @@ module RedmineAirbrakeBackend
|
|
93
96
|
key.to_s.gsub(/-/, '_')
|
94
97
|
end
|
95
98
|
|
99
|
+
def self.convert_attributes(attributes)
|
100
|
+
attrs = {}
|
101
|
+
|
102
|
+
attributes.each do |k, v|
|
103
|
+
attrs[k] = v.value
|
104
|
+
end
|
105
|
+
|
106
|
+
attrs.symbolize_keys
|
107
|
+
end
|
108
|
+
|
96
109
|
def self.ensure_hash_array(data)
|
97
110
|
return nil if data.blank?
|
98
111
|
|
@@ -104,18 +117,6 @@ module RedmineAirbrakeBackend
|
|
104
117
|
def self.format_backtrace(backtrace)
|
105
118
|
ensure_hash_array(backtrace).first[:line] rescue nil
|
106
119
|
end
|
107
|
-
|
108
|
-
def self.format_session_log(log)
|
109
|
-
log = ::JSON.parse(log) rescue nil
|
110
|
-
|
111
|
-
log = ensure_hash_array(log)
|
112
|
-
return nil if log.blank?
|
113
|
-
|
114
|
-
log.map! { |l| l.symbolize_keys!; l[:time] = (Time.parse(l[:time]) rescue nil); l }
|
115
|
-
log.reject! { |l| l[:time].blank? }
|
116
|
-
|
117
|
-
log.blank? ? nil : log
|
118
|
-
end
|
119
120
|
end
|
120
121
|
end
|
121
122
|
end
|
@@ -18,9 +18,8 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.require_paths = ['lib']
|
19
19
|
|
20
20
|
spec.add_dependency 'rails'
|
21
|
-
spec.add_dependency '
|
22
|
-
spec.add_dependency 'htmlentities'
|
21
|
+
spec.add_dependency 'nokogiri'
|
23
22
|
|
24
|
-
spec.add_development_dependency 'bundler'
|
23
|
+
spec.add_development_dependency 'bundler'
|
25
24
|
spec.add_development_dependency 'rake'
|
26
25
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redmine_airbrake_backend
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Florian Schwab
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-04-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: nokogiri
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -39,33 +39,19 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
|
-
type: :
|
48
|
+
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
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
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: rake
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -88,9 +74,9 @@ extensions: []
|
|
88
74
|
extra_rdoc_files: []
|
89
75
|
files:
|
90
76
|
- ".gitignore"
|
77
|
+
- CHANGELOG.md
|
91
78
|
- Gemfile
|
92
|
-
-
|
93
|
-
- MIT-LICENSE
|
79
|
+
- LICENSE.txt
|
94
80
|
- README.md
|
95
81
|
- Rakefile
|
96
82
|
- app/controllers/airbrake_controller.rb
|
@@ -145,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
131
|
version: '0'
|
146
132
|
requirements: []
|
147
133
|
rubyforge_project:
|
148
|
-
rubygems_version: 2.
|
134
|
+
rubygems_version: 2.4.6
|
149
135
|
signing_key:
|
150
136
|
specification_version: 4
|
151
137
|
summary: This plugin provides the necessary API to use Redmine as a Airbrake backend
|
data/Gemfile.lock
DELETED
@@ -1,91 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
redmine_airbrake_backend (0.5.4)
|
5
|
-
hpricot
|
6
|
-
htmlentities
|
7
|
-
rails
|
8
|
-
|
9
|
-
GEM
|
10
|
-
remote: https://rubygems.org/
|
11
|
-
specs:
|
12
|
-
actionmailer (4.1.6)
|
13
|
-
actionpack (= 4.1.6)
|
14
|
-
actionview (= 4.1.6)
|
15
|
-
mail (~> 2.5, >= 2.5.4)
|
16
|
-
actionpack (4.1.6)
|
17
|
-
actionview (= 4.1.6)
|
18
|
-
activesupport (= 4.1.6)
|
19
|
-
rack (~> 1.5.2)
|
20
|
-
rack-test (~> 0.6.2)
|
21
|
-
actionview (4.1.6)
|
22
|
-
activesupport (= 4.1.6)
|
23
|
-
builder (~> 3.1)
|
24
|
-
erubis (~> 2.7.0)
|
25
|
-
activemodel (4.1.6)
|
26
|
-
activesupport (= 4.1.6)
|
27
|
-
builder (~> 3.1)
|
28
|
-
activerecord (4.1.6)
|
29
|
-
activemodel (= 4.1.6)
|
30
|
-
activesupport (= 4.1.6)
|
31
|
-
arel (~> 5.0.0)
|
32
|
-
activesupport (4.1.6)
|
33
|
-
i18n (~> 0.6, >= 0.6.9)
|
34
|
-
json (~> 1.7, >= 1.7.7)
|
35
|
-
minitest (~> 5.1)
|
36
|
-
thread_safe (~> 0.1)
|
37
|
-
tzinfo (~> 1.1)
|
38
|
-
arel (5.0.1.20140414130214)
|
39
|
-
builder (3.2.2)
|
40
|
-
erubis (2.7.0)
|
41
|
-
hike (1.2.3)
|
42
|
-
hpricot (0.8.6)
|
43
|
-
htmlentities (4.3.2)
|
44
|
-
i18n (0.6.11)
|
45
|
-
json (1.8.1)
|
46
|
-
mail (2.6.1)
|
47
|
-
mime-types (>= 1.16, < 3)
|
48
|
-
mime-types (2.4.2)
|
49
|
-
minitest (5.4.2)
|
50
|
-
multi_json (1.10.1)
|
51
|
-
rack (1.5.2)
|
52
|
-
rack-test (0.6.2)
|
53
|
-
rack (>= 1.0)
|
54
|
-
rails (4.1.6)
|
55
|
-
actionmailer (= 4.1.6)
|
56
|
-
actionpack (= 4.1.6)
|
57
|
-
actionview (= 4.1.6)
|
58
|
-
activemodel (= 4.1.6)
|
59
|
-
activerecord (= 4.1.6)
|
60
|
-
activesupport (= 4.1.6)
|
61
|
-
bundler (>= 1.3.0, < 2.0)
|
62
|
-
railties (= 4.1.6)
|
63
|
-
sprockets-rails (~> 2.0)
|
64
|
-
railties (4.1.6)
|
65
|
-
actionpack (= 4.1.6)
|
66
|
-
activesupport (= 4.1.6)
|
67
|
-
rake (>= 0.8.7)
|
68
|
-
thor (>= 0.18.1, < 2.0)
|
69
|
-
rake (10.3.2)
|
70
|
-
sprockets (2.12.2)
|
71
|
-
hike (~> 1.2)
|
72
|
-
multi_json (~> 1.0)
|
73
|
-
rack (~> 1.0)
|
74
|
-
tilt (~> 1.1, != 1.3.0)
|
75
|
-
sprockets-rails (2.2.0)
|
76
|
-
actionpack (>= 3.0)
|
77
|
-
activesupport (>= 3.0)
|
78
|
-
sprockets (>= 2.8, < 4.0)
|
79
|
-
thor (0.19.1)
|
80
|
-
thread_safe (0.3.4)
|
81
|
-
tilt (1.4.1)
|
82
|
-
tzinfo (1.2.2)
|
83
|
-
thread_safe (~> 0.1)
|
84
|
-
|
85
|
-
PLATFORMS
|
86
|
-
ruby
|
87
|
-
|
88
|
-
DEPENDENCIES
|
89
|
-
bundler (~> 1.3)
|
90
|
-
rake
|
91
|
-
redmine_airbrake_backend!
|