appsignal_report 0.1.0 → 0.1.1

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: d4d4507b1ca8ebdd01e7cb9f06ce189d3c93c7e8
4
- data.tar.gz: bce40d5abece6bcb5be025ac195e12120112ee79
3
+ metadata.gz: c8508bab60307495cb9596feb78d732807fedbb6
4
+ data.tar.gz: e73a769860e794be7b8778f2e2bb22ef4bef657d
5
5
  SHA512:
6
- metadata.gz: dca3d06438a1bd3678f0ff2aedad71abf4b6fed262231c772cb1c431f29260e84133ec4433aa0f86d8a05141143b54f440d585380e6a43505a5351907f0f733c
7
- data.tar.gz: 5109060c35dd4d591a4ed1bb575305687b35f71bda09d1da40f03ab1284235f6f4a853460fedb6a8de5489e9ad3f44342d2bfa0a2551c6d30f3f02ade3b5bc2e
6
+ metadata.gz: 1043721a87de2856a24660357e9485acdda70cbf392a1ed2e2fb983695c980138679abcd634034d6ae09af57bbabb77e4536b707c0cf008d9489d72c4c5e2a36
7
+ data.tar.gz: 0bca2b97f7f11aac1b60d34d61ecf44e3ade22593a7ae6651aae47b5df6eabdc1470df95aef86d2a62f83d6e35066db96c2e092d72b3e765b1f5cda5abb4b5e5
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ### 0.1.1
4
+ _August 21st 2017_
5
+
6
+ - refactored executables to share runner/options code
7
+ - display throughput resolution provided by AppSignal
8
+
3
9
  ### 0.1.0
4
10
  _August 14th, 2017_
5
11
 
data/README.md CHANGED
@@ -6,8 +6,51 @@ Elixir applications.
6
6
 
7
7
  ## Status
8
8
 
9
+ [![Gem Version](https://badge.fury.io/rb/appsignal_report.svg)](https://badge.fury.io/rb/appsignal_report)
9
10
  [![Build Status](https://travis-ci.org/dsager/appsignal_report.svg?branch=master)](https://travis-ci.org/dsager/appsignal_report)
10
11
 
12
+ ## Usage
13
+
14
+ Use `gem install appsignal_report` to get `appsignal_report` (or add
15
+ `gem 'appsignal_report'` to your Gemfile). That will provide two executables
16
+ `appsignal_report_deploy` and `appsignal_report_weekly`, they both support
17
+ the same set of options:
18
+
19
+ ```
20
+ $ appsignal_report_deploy -h
21
+ Usage: APPSIGNAL_API_TOKEN=XXX ./bin/appsignal_report_deploy [options]
22
+
23
+ Specific options:
24
+ -i, --app-id ID Specify Appsignal App Id
25
+ -n, --app-name NAME Specify a name for the Appsignal App
26
+ -s, --slack WEBHOOK_URL Post the report to a Slack Webhook
27
+
28
+ Common options:
29
+ -h, --help Show this message
30
+ ```
31
+
32
+ The option `--app-id` is the only required one, by default the tool will
33
+ output the report data in JSON format to STDOUT.
34
+
35
+ ## Posting to Slack
36
+
37
+ `appsignal_report` supports posting formatted messages about the report
38
+ to Slack, instead of printing the raw report data. To do so, you need to
39
+ provide the URL of a
40
+ [Slack webhook](https://api.slack.com/custom-integrations/incoming-webhooks)
41
+ using the CLI option `--slack`:
42
+
43
+ ```
44
+ $ APPSIGNAL_API_TOKEN=XXX ./bin/appsignal_report_weekly \
45
+ -app-id XYZ123 \
46
+ -app-name 'back-end' \
47
+ -slack https://hooks.slack.com/services/X/Y/Z
48
+ ```
49
+
50
+ This is an example of how the post looks on Slack:
51
+
52
+ ![Slack Post Example](img/slack-post.png?raw=true "Slack Post Example")
53
+
11
54
  ## Reports
12
55
 
13
56
  Currently the gem supports two kinds of reports, a deploy report and a weekly
@@ -25,25 +68,24 @@ This only works if you are using AppSignal's
25
68
  [deploy markers](https://docs.appsignal.com/push-api/deploy-marker.html) to
26
69
  record your deployments.
27
70
 
28
- ### Usage
71
+ ### Example
29
72
 
30
73
  ```
31
- $ gem install appsignal_report
32
- $ APPSIGNAL_API_TOKEN=ABC123 appsignal_report_deploy -i XYZ456
33
74
  {
34
75
  "title": "AppSignal Deploy Report",
35
76
  "last_deploy_time": "2017-08-10 09:47:52 UTC",
77
+ "resolution": "minutely",
36
78
  "before": {
37
79
  "data_points": 62,
38
80
  "error_rate": 0.4675038958657989,
39
81
  "response_time": 94.9387856438841,
40
- "hourly_throughput": 32727
82
+ "throughput": 32727
41
83
  },
42
84
  "after": {
43
85
  "data_points": 62,
44
86
  "error_rate": 0.0733371596199222,
45
87
  "response_time": 56.71109484008057,
46
- "hourly_throughput": 31362
88
+ "throughput": 31362
47
89
  },
48
90
  "data_samples_from": "2017-08-10 08:47:00 UTC",
49
91
  "data_samples_to": "2017-08-10 10:48:00 UTC",
@@ -52,14 +94,14 @@ $ APPSIGNAL_API_TOKEN=ABC123 appsignal_report_deploy -i XYZ456
52
94
  "error_rate_pct": -0.8431303775894644,
53
95
  "response_time": -38.22769080380353,
54
96
  "response_time_pct": -0.40265620151489834,
55
- "hourly_throughput": -1365,
56
- "hourly_throughput_pct": -0.041708680905674214
97
+ "throughput": -1365,
98
+ "throughput_pct": -0.041708680905674214
57
99
  },
58
100
  "messages": {
59
101
  "info": "The deploy finished at 2017-08-10 09:47:52 UTC",
60
102
  "error_rate": "The error rate decreased by 0.39% (from 0.47% to 0.07%, that is a change of -84.31%).",
61
103
  "response_time": "The response time decreased by 38.23ms (from 94.94ms to 56.71ms, that is a change of -40.27%).",
62
- "hourly_throughput": "The hourly throughput decreased by 1365.0 req/h (from 32727.0 req/h to 31362.0 req/h, that is a change of -4.17%)."
104
+ "throughput": "The hourly throughput decreased by 1365.0 req/m (from 32727.0 req/m to 31362.0 req/m, that is a change of -4.17%)."
63
105
  }
64
106
  }
65
107
  ```
@@ -70,27 +112,26 @@ The weekly report pulls metrics for the last two weeks. Based on these metrics
70
112
  it calculates changes in response time, error rate and throughput, comparing one
71
113
  week to the other.
72
114
 
73
- ### Usage
115
+ ### Example
74
116
 
75
117
  ```
76
- $ gem install appsignal_report
77
- $ APPSIGNAL_API_TOKEN=ABC123 appsignal_report_weekly -i XYZ456
78
118
  {
79
119
  "title": "AppSignal Weekly Report",
80
120
  "now": "2017-08-14 13:19:15 UTC",
81
121
  "one_week_ago": "2017-08-07 13:19:15 UTC",
82
122
  "two_weeks_ago": "2017-07-31 13:19:15 UTC",
123
+ "resolution": "hourly",
83
124
  "before": {
84
125
  "data_points": 168,
85
126
  "error_rate": 0.19637939102939866,
86
127
  "response_time": 74.6427894180237,
87
- "hourly_throughput": 34611.166666666664
128
+ "throughput": 34611.166666666664
88
129
  },
89
130
  "after": {
90
131
  "data_points": 168,
91
132
  "error_rate": 0.06227341986188213,
92
133
  "response_time": 61.364840452820985,
93
- "hourly_throughput": 30819.684523809523
134
+ "throughput": 30819.684523809523
94
135
  },
95
136
  "data_samples_from": "2017-07-31 14:00:00 UTC",
96
137
  "data_samples_to": "2017-08-14 13:00:00 UTC",
@@ -99,14 +140,14 @@ $ APPSIGNAL_API_TOKEN=ABC123 appsignal_report_weekly -i XYZ456
99
140
  "error_rate_pct": -0.6828922855119783,
100
141
  "response_time": -13.277948965202711,
101
142
  "response_time_pct": -0.17788655901967856,
102
- "hourly_throughput": -3791.4821428571413,
103
- "hourly_throughput_pct": -0.1095450546169726
143
+ "throughput": -3791.4821428571413,
144
+ "throughput_pct": -0.1095450546169726
104
145
  },
105
146
  "messages": {
106
147
  "info": "Comparing the weeks 2017-07-31-2017-08-07 and 2017-08-07-2017-08-14.",
107
148
  "error_rate": "The error rate decreased by 0.13% (from 0.2% to 0.06%, that is a change of -68.29%).",
108
149
  "response_time": "The response time decreased by 13.28ms (from 74.64ms to 61.36ms, that is a change of -17.79%).",
109
- "hourly_throughput": "The hourly throughput decreased by 3791.48 req/h (from 34611.17 req/h to 30819.68 req/h, that is a change of -10.95%)."
150
+ "throughput": "The hourly throughput decreased by 3791.48 req/h (from 34611.17 req/h to 30819.68 req/h, that is a change of -10.95%)."
110
151
  }
111
152
  }
112
153
  ```
@@ -125,9 +166,17 @@ application. If you look at the example URL
125
166
  `appsignal.com/devex/sites/XYZ456/web/exceptions`, the application ID is
126
167
  `XYZ456`.
127
168
 
169
+ ### How do I set up a Slack webhook?
170
+
171
+ Go to this [page](https://my.slack.com/services/new/incoming-webhook) to set up
172
+ a Slack webhook. You can specify some settings like user name or an avatar, and
173
+ should be provided a webhook URL in the format of
174
+ `https://hooks.slack.com/services/ABC/123/XYZ`.
175
+
128
176
  ## Maintainer
129
177
 
130
- [Daniel Sager](https://github.com/dsager)
178
+ - [Devex](https://github.com/orgs/Devex)
179
+ - [Daniel Sager](https://github.com/dsager)
131
180
 
132
181
  ## Contributing
133
182
 
@@ -18,55 +18,12 @@
18
18
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
19
19
 
20
20
  require 'appsignal_report'
21
- require 'optparse'
22
21
 
23
- options = { slack_webhook: nil, app_id: nil, app_name: nil }
24
- parser = OptionParser.new do |parser|
25
- parser.banner =
26
- 'Usage: APPSIGNAL_API_TOKEN=XXX ./bin/appsignal_report_deploy [options]'
27
- parser.separator ''
28
- parser.separator 'Specific options:'
29
- parser.on('-i ID',
30
- '--app-id ID',
31
- String,
32
- 'Specify Appsignal App Id') do |id|
33
- options[:app_id] = id
34
- end
35
- parser.on('-n NAME',
36
- '--app-name NAME',
37
- String,
38
- 'Specify a name for the Appsignal App') do |name|
39
- options[:app_name] = name
40
- end
41
- parser.on('-s WEBHOOK_URL',
42
- '--slack WEBHOOK_URL',
43
- String,
44
- 'Post the report to a Slack Webhook') do |url|
45
- options[:slack_webhook] = url
46
- end
47
- parser.separator ''
48
- parser.separator 'Common options:'
49
- parser.on_tail('-h', '--help', 'Show this message') do
50
- puts parser
51
- exit
52
- end
53
- end
54
- parser.parse!
22
+ option_parser = AppsignalReport::CLI::OptionParser
23
+ .new(type: :deploy, api_token: ENV['APPSIGNAL_API_TOKEN'])
55
24
 
56
- report = AppsignalReport::DeployReport.new(
57
- api_token: ENV['APPSIGNAL_API_TOKEN'],
58
- app_id: options[:app_id],
59
- app_name: options[:app_name]
60
- )
25
+ option_parser.parse
61
26
 
62
- report.generate
63
-
64
- unless options[:slack_webhook].nil?
65
- message = AppsignalReport::SlackMessage.new(
66
- report: report,
67
- webhook_url: options[:slack_webhook]
68
- )
69
- puts message.post
70
- else
71
- puts report.report.to_json
72
- end
27
+ AppsignalReport::CLI::Runner
28
+ .new(option_parser.options)
29
+ .run
@@ -15,55 +15,12 @@
15
15
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
16
16
 
17
17
  require 'appsignal_report'
18
- require 'optparse'
19
18
 
20
- options = { slack_webhook: nil, app_id: nil, app_name: nil }
21
- parser = OptionParser.new do |parser|
22
- parser.banner =
23
- 'Usage: APPSIGNAL_API_TOKEN=XXX ./bin/appsignal_report_weekly [options]'
24
- parser.separator ''
25
- parser.separator 'Specific options:'
26
- parser.on('-i ID',
27
- '--app-id ID',
28
- String,
29
- 'Specify Appsignal App Id') do |id|
30
- options[:app_id] = id
31
- end
32
- parser.on('-n NAME',
33
- '--app-name NAME',
34
- String,
35
- 'Specify a name for the Appsignal App') do |name|
36
- options[:app_name] = name
37
- end
38
- parser.on('-s WEBHOOK_URL',
39
- '--slack WEBHOOK_URL',
40
- String,
41
- 'Post the report to a Slack Webhook') do |url|
42
- options[:slack_webhook] = url
43
- end
44
- parser.separator ''
45
- parser.separator 'Common options:'
46
- parser.on_tail('-h', '--help', 'Show this message') do
47
- puts parser
48
- exit
49
- end
50
- end
51
- parser.parse!
19
+ option_parser = AppsignalReport::CLI::OptionParser
20
+ .new(type: :weekly, api_token: ENV['APPSIGNAL_API_TOKEN'])
52
21
 
53
- report = AppsignalReport::WeeklyReport.new(
54
- api_token: ENV['APPSIGNAL_API_TOKEN'],
55
- app_id: options[:app_id],
56
- app_name: options[:app_name]
57
- )
22
+ option_parser.parse
58
23
 
59
- report.generate
60
-
61
- unless options[:slack_webhook].nil?
62
- message = AppsignalReport::SlackMessage.new(
63
- report: report,
64
- webhook_url: options[:slack_webhook]
65
- )
66
- puts message.post
67
- else
68
- puts report.report.to_json
69
- end
24
+ AppsignalReport::CLI::Runner
25
+ .new(option_parser.options)
26
+ .run
@@ -37,13 +37,14 @@ module AppsignalReport
37
37
 
38
38
  def process_metrics
39
39
  api_response = perform_api_request(metrics_uri)
40
+ @report[:resolution] = api_response[:resolution]
40
41
  data = balance_samples(gather_samples(api_response[:data]))
41
42
  %i(before after).each do |key|
42
43
  @report[key] = {
43
44
  data_points: data[key].size,
44
45
  error_rate: get_average(data[key], :ex_rate),
45
46
  response_time: get_average(data[key], :mean),
46
- hourly_throughput: get_average(data[key], :count),
47
+ throughput: get_average(data[key], :count),
47
48
  }
48
49
  end
49
50
  @report.merge!(
@@ -60,7 +61,8 @@ module AppsignalReport
60
61
  info: info_message,
61
62
  error_rate: metric_message(:error_rate, '%'),
62
63
  response_time: metric_message(:response_time, 'ms'),
63
- hourly_throughput: metric_message(:hourly_throughput, ' req/h'),
64
+ throughput: metric_message(:throughput,
65
+ " req/#{@report[:resolution][0]}"),
64
66
  }
65
67
  end
66
68
 
@@ -91,8 +93,8 @@ module AppsignalReport
91
93
  error_rate_pct: pct_diff(:error_rate),
92
94
  response_time: abs_diff(:response_time),
93
95
  response_time_pct: pct_diff(:response_time),
94
- hourly_throughput: abs_diff(:hourly_throughput),
95
- hourly_throughput_pct: pct_diff(:hourly_throughput),
96
+ throughput: abs_diff(:throughput),
97
+ throughput_pct: pct_diff(:throughput),
96
98
  }
97
99
  end
98
100
 
@@ -0,0 +1,56 @@
1
+ module AppsignalReport
2
+ module CLI
3
+ class OptionParser
4
+ def initialize(additional_options = {})
5
+ @additional_options = additional_options
6
+ end
7
+
8
+ def parse
9
+ option_parser.parse!
10
+ end
11
+
12
+ def options
13
+ @options ||= {
14
+ slack_webhook: nil,
15
+ app_id: nil,
16
+ app_name: nil,
17
+ }.merge(@additional_options)
18
+ end
19
+
20
+ private
21
+
22
+ def option_parser
23
+ ::OptionParser.new do |parser|
24
+ parser.banner =
25
+ 'Usage: APPSIGNAL_API_TOKEN=XXX ./bin/appsignal_report_* [options]'
26
+ parser.separator ''
27
+ parser.separator 'Specific options:'
28
+ parser.on('-i ID',
29
+ '--app-id ID',
30
+ String,
31
+ 'Specify Appsignal App Id') do |id|
32
+ options[:app_id] = id
33
+ end
34
+ parser.on('-n NAME',
35
+ '--app-name NAME',
36
+ String,
37
+ 'Specify a name for the Appsignal App') do |name|
38
+ options[:app_name] = name
39
+ end
40
+ parser.on('-s WEBHOOK_URL',
41
+ '--slack WEBHOOK_URL',
42
+ String,
43
+ 'Post the report to a Slack Webhook') do |url|
44
+ options[:slack_webhook] = url
45
+ end
46
+ parser.separator ''
47
+ parser.separator 'Common options:'
48
+ parser.on_tail('-h', '--help', 'Show this message') do
49
+ puts parser
50
+ exit
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,50 @@
1
+ module AppsignalReport
2
+ module CLI
3
+ class Runner
4
+ attr_reader :options
5
+
6
+ def initialize(options)
7
+ @options = options
8
+ end
9
+
10
+ def run
11
+ report.generate
12
+ options[:slack_webhook] ? post_to_slack : print_json
13
+ end
14
+
15
+ def report
16
+ @report ||= report_class.new(
17
+ api_token: options[:api_token],
18
+ app_id: options[:app_id],
19
+ app_name: options[:app_name]
20
+ )
21
+ end
22
+
23
+ private
24
+
25
+ def report_class
26
+ case options[:type]
27
+ when :deploy
28
+ AppsignalReport::DeployReport
29
+ when :weekly
30
+ AppsignalReport::WeeklyReport
31
+ else
32
+ raise ArgumentError, "invalid report type: '#{options[:type]}'"
33
+ end
34
+ end
35
+
36
+
37
+ def print_json
38
+ puts report.report.to_json
39
+ end
40
+
41
+ def post_to_slack
42
+ message = AppsignalReport::SlackMessage.new(
43
+ report: report,
44
+ webhook_url: options[:slack_webhook]
45
+ )
46
+ puts message.post
47
+ end
48
+ end
49
+ end
50
+ end
@@ -36,7 +36,7 @@ module AppsignalReport
36
36
  ":information_source: #{report.report[:messages][:info]}",
37
37
  "#{error_rate_icon} #{report.report[:messages][:error_rate]}",
38
38
  "#{response_time_icon} #{report.report[:messages][:response_time]}",
39
- "#{throughput_icon} #{report.report[:messages][:hourly_throughput]}",
39
+ "#{throughput_icon} #{report.report[:messages][:throughput]}",
40
40
  ]
41
41
  end
42
42
 
@@ -50,11 +50,7 @@ module AppsignalReport
50
50
 
51
51
  def throughput_icon
52
52
  up_down =
53
- if report.report[:diff][:hourly_throughput].negative?
54
- 'downwards'
55
- else
56
- 'upwards'
57
- end
53
+ report.report[:diff][:throughput].negative? ? 'downwards' : 'upwards'
58
54
  ":chart_with_#{up_down}_trend:"
59
55
  end
60
56
  end
@@ -1,3 +1,3 @@
1
1
  module AppsignalReport
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
@@ -2,9 +2,12 @@ require 'uri'
2
2
  require 'net/http'
3
3
  require 'json'
4
4
  require 'time'
5
+ require 'optparse'
5
6
 
6
7
  require_relative 'appsignal_report/version'
7
8
  require_relative 'appsignal_report/base_report'
8
9
  require_relative 'appsignal_report/weekly_report'
9
10
  require_relative 'appsignal_report/deploy_report'
10
11
  require_relative 'appsignal_report/slack_message'
12
+ require_relative 'appsignal_report/cli/option_parser'
13
+ require_relative 'appsignal_report/cli/runner'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appsignal_report
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Sager
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-14 00:00:00.000000000 Z
11
+ date: 2017-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -53,6 +53,8 @@ files:
53
53
  - bin/appsignal_report_weekly
54
54
  - lib/appsignal_report.rb
55
55
  - lib/appsignal_report/base_report.rb
56
+ - lib/appsignal_report/cli/option_parser.rb
57
+ - lib/appsignal_report/cli/runner.rb
56
58
  - lib/appsignal_report/deploy_report.rb
57
59
  - lib/appsignal_report/slack_message.rb
58
60
  - lib/appsignal_report/version.rb
@@ -77,7 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
77
79
  version: '0'
78
80
  requirements: []
79
81
  rubyforge_project:
80
- rubygems_version: 2.5.2
82
+ rubygems_version: 2.6.11
81
83
  signing_key:
82
84
  specification_version: 4
83
85
  summary: Useful reports around your AppSignal metrics