newshound 0.1.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b5541adbc8e4ccb311bcce9a185946affc52cddc3d6c253779722a4901627401
4
- data.tar.gz: 06c86ac9f83a00ce6e6e77063131a29eaf2fb7e6643528e65e6f0b3c329d1309
3
+ metadata.gz: ed2c9eae65ac8681fc1c72890cbd421ca9dd73130c37fa86c04643cb74c03856
4
+ data.tar.gz: 7ccb875f08607e1478245384376a621243fdd44e40443fb191064210cff94ba6
5
5
  SHA512:
6
- metadata.gz: 3d3e875cb30e1e3c27cd932f5f66fa8f9a6269d7e03c7cbb5428ce5ba47dd53acacb80721d5f51452b0d97a3d46a7005e93fec24c9954a96452ee861df6c962a
7
- data.tar.gz: a5041975aab52ff2c50527f9f5050014d086908923b7f15830dce201f43a234a9086b3ba2d7747de90797ef07af0d769badbe431bd92105abd8b9e254f6b4499
6
+ metadata.gz: a78bd31f883c89116c83b7c77b680faba172b41e0bc3f375e4a81a075503d33860ebd4778e71f11d868a794fe04effd815e240ebd3d5c6135b0ed80599c87469
7
+ data.tar.gz: 4985d3d128688284f4734391b12e7f6e34d1c69857d713d3995d2078cc4df210b64ca5f84d889841e52b1b3a9086bcf0f19e7d35bef646b60e08020379527ad6
data/README.md CHANGED
@@ -1,187 +1,192 @@
1
1
  # Newshound 🐕
2
2
 
3
- A Ruby gem that sniffs out exceptions and job statuses in your Rails app and reports them daily to Slack or other notification services.
3
+ A Ruby gem that displays real-time exceptions and job statuses in a collapsible banner for authorized users in your Rails application.
4
4
 
5
5
  ## Features
6
6
 
7
- - 📊 Daily Que job status reports (counts by job type, queue health)
8
- - 🚨 Last 4 exceptions from exception-track
9
- - 💬 Multiple transport options: Direct Slack or Amazon SNS
10
- - Automatic daily scheduling with que-scheduler
11
- - 🔧 Configurable report times and limits
12
- - 🔄 Environment-based transport switching (SNS for production, Slack for development)
7
+ - 🎯 **Real-time Web UI Banner** - Shows exceptions and job statuses at the top of every page
8
+ - 🔐 **Role-Based Access** - Only visible to authorized users (developers, admins, etc.)
9
+ - 📊 **Que Job Monitoring** - Real-time queue health and job status
10
+ - 🚨 **Exception Tracking** - Recent exceptions from exception-track
11
+ - 🎨 **Collapsible UI** - Clean, non-intrusive banner that expands on click
12
+ - **Zero Configuration** - Automatically injects into HTML responses
13
+ - 🔧 **Highly Customizable** - Configure roles and authorization logic
13
14
 
14
15
  ## Installation
15
16
 
16
17
  Add to your Gemfile:
17
18
 
18
19
  ```ruby
19
- gem 'newshound', path: 'path/to/newshound' # or from git/rubygems when published
20
-
21
- # Optional: Add AWS SDK if using SNS transport
22
- gem 'aws-sdk-sns', '~> 1.0' # Only needed for SNS transport
20
+ gem 'newshound'
23
21
  ```
24
22
 
25
23
  Then:
26
24
 
27
25
  ```bash
28
26
  bundle install
27
+ rails generate newshound:install
29
28
  ```
30
29
 
31
- ## Configuration
30
+ The generator will create `config/initializers/newshound.rb` with default configuration.
32
31
 
33
- Create an initializer `config/initializers/newshound.rb`:
32
+ ## Configuration
34
33
 
35
- ### Basic Configuration (Slack Direct)
34
+ ### Basic Configuration
36
35
 
37
36
  ```ruby
37
+ # config/initializers/newshound.rb
38
38
  Newshound.configure do |config|
39
- # Transport selection (optional, defaults to :slack)
40
- config.transport_adapter = :slack
41
-
42
- # Slack configuration (choose one method)
43
- config.slack_webhook_url = ENV['SLACK_WEBHOOK_URL'] # Option 1: Webhook
44
- # OR set ENV['SLACK_API_TOKEN'] for Web API # Option 2: Web API
45
-
46
- config.slack_channel = "#ops-alerts" # Default: "#general"
47
- config.report_time = "09:00" # Default: "09:00" (24-hour format)
48
- config.exception_limit = 4 # Default: 4 (last N exceptions)
49
- config.time_zone = "America/New_York" # Default: "America/New_York"
50
- config.enabled = true # Default: true
39
+ # Enable or disable the banner
40
+ config.enabled = true
41
+
42
+ # Maximum number of exceptions to show in banner
43
+ config.exception_limit = 10
44
+
45
+ # User roles that can view the banner
46
+ config.authorized_roles = [:developer, :super_user]
47
+
48
+ # Method to call to get current user (most apps use :current_user)
49
+ config.current_user_method = :current_user
51
50
  end
52
51
  ```
53
52
 
54
- ### Production Configuration with SNS
53
+ ### Advanced: Custom Authorization
54
+
55
+ If the default role-based authorization doesn't fit your needs, you can provide custom logic:
55
56
 
56
57
  ```ruby
57
- Newshound.configure do |config|
58
- if Rails.env.production?
59
- # Use SNS in production to route through AWS
60
- config.transport_adapter = :sns
61
- config.sns_topic_arn = ENV['SNS_TOPIC_ARN']
62
- config.aws_region = ENV['AWS_REGION'] || 'us-east-1'
63
-
64
- # Optional: Explicit AWS credentials (uses IAM role by default)
65
- config.aws_access_key_id = ENV['AWS_ACCESS_KEY_ID']
66
- config.aws_secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
67
- else
68
- # Use direct Slack in development/staging
69
- config.transport_adapter = :slack
70
- config.slack_webhook_url = ENV['SLACK_WEBHOOK_URL']
71
- end
58
+ # config/initializers/newshound.rb
59
+ Newshound.authorize_with do |controller|
60
+ # Your custom authorization logic
61
+ # Return true to show banner, false to hide
62
+ user = controller.current_user
63
+ user&.admin? || user&.developer?
64
+ end
65
+ ```
72
66
 
73
- # Common settings
74
- config.slack_channel = "#ops-alerts"
75
- config.report_time = "09:00"
76
- config.exception_limit = 4
77
- config.time_zone = "America/New_York"
78
- config.enabled = true
67
+ ### Example Authorization Scenarios
68
+
69
+ ```ruby
70
+ # Only show in development
71
+ Newshound.authorize_with do |controller|
72
+ Rails.env.development?
73
+ end
74
+
75
+ # Check multiple conditions
76
+ Newshound.authorize_with do |controller|
77
+ user = controller.current_user
78
+ user.present? &&
79
+ (user.has_role?(:admin) || user.email.ends_with?('@yourcompany.com'))
80
+ end
81
+
82
+ # Use your existing authorization system
83
+ Newshound.authorize_with do |controller|
84
+ controller.current_user&.can?(:view_newshound)
79
85
  end
80
86
  ```
81
87
 
82
- ## Transport Setup
83
-
84
- ### Slack Setup (Direct Integration)
85
-
86
- #### Option 1: Webhook URL (Simpler)
87
- 1. Go to https://api.slack.com/apps
88
- 2. Create a new app or select existing
89
- 3. Enable "Incoming Webhooks"
90
- 4. Add a new webhook for your channel
91
- 5. Copy the webhook URL to your config
92
-
93
- #### Option 2: Web API Token (More features)
94
- 1. Create a Slack app at https://api.slack.com/apps
95
- 2. Add OAuth scopes: `chat:write`, `chat:write.public`
96
- 3. Install to workspace
97
- 4. Copy the Bot User OAuth Token
98
- 5. Set as `ENV['SLACK_API_TOKEN']`
99
-
100
- ### AWS SNS Setup (Production Routing)
101
-
102
- 1. **Create SNS Topic**:
103
- ```bash
104
- aws sns create-topic --name newshound-notifications
105
- ```
106
-
107
- 2. **Subscribe Slack Webhook to Topic**:
108
- ```bash
109
- aws sns subscribe \
110
- --topic-arn arn:aws:sns:us-east-1:123456789:newshound-notifications \
111
- --protocol https \
112
- --notification-endpoint YOUR_SLACK_WEBHOOK_URL
113
- ```
114
-
115
- 3. **Configure IAM Permissions**:
116
- ```json
117
- {
118
- "Version": "2012-10-17",
119
- "Statement": [{
120
- "Effect": "Allow",
121
- "Action": "sns:Publish",
122
- "Resource": "arn:aws:sns:us-east-1:*:newshound-*"
123
- }]
124
- }
125
- ```
126
-
127
- 4. **Set Environment Variables**:
128
- ```bash
129
- export SNS_TOPIC_ARN="arn:aws:sns:us-east-1:123456789:newshound-notifications"
130
- export AWS_REGION="us-east-1"
131
- ```
132
-
133
- ## Usage
134
-
135
- ### Automatic Daily Reports
136
-
137
- If you have `que-scheduler` configured, Newshound will automatically schedule daily reports at your configured time.
138
-
139
- ### Manual Reports
88
+ ## How It Works
89
+
90
+ Newshound uses Rails middleware to automatically inject a banner into HTML responses for authorized users. The banner:
91
+
92
+ 1. Appears automatically on all HTML pages
93
+ 2. 🔒 Only visible to users with authorized roles
94
+ 3. 📊 Shows real-time data from your exception and job queues
95
+ 4. 🎨 Collapses to save space, expands on click
96
+ 5. 🚀 No JavaScript dependencies, pure CSS animations
97
+
98
+ ## Banner Content
99
+
100
+ The banner displays:
101
+
102
+ ### Exception Section
103
+ - Recent exceptions from exception-track
104
+ - Exception class and message
105
+ - Controller/action where it occurred
106
+ - Timestamp
107
+ - Visual indicators (🟢 all clear / 🔴 errors)
108
+
109
+ ### Job Queue Section
110
+ - **Ready to Run**: Jobs waiting to execute
111
+ - **Scheduled**: Jobs scheduled for future execution
112
+ - **Failed**: Jobs in retry queue
113
+ - **Completed Today**: Successfully finished jobs
114
+ - Color-coded health status
115
+
116
+ ## User Requirements
117
+
118
+ Your User model should have a `role` attribute that matches one of the configured `authorized_roles`. Common patterns:
140
119
 
141
120
  ```ruby
142
- # Send report immediately
143
- Newshound.report!
121
+ # String enum
122
+ class User < ApplicationRecord
123
+ enum role: { user: 'user', developer: 'developer', admin: 'admin' }
124
+ end
125
+
126
+ # Symbol enum
127
+ class User < ApplicationRecord
128
+ enum role: { user: 0, developer: 1, super_user: 2 }
129
+ end
130
+
131
+ # String column
132
+ class User < ApplicationRecord
133
+ def role
134
+ @role ||= read_attribute(:role)&.to_sym
135
+ end
136
+ end
137
+ ```
138
+
139
+ If your User model uses different attribute names, you can customize the authorization logic using `Newshound.authorize_with`.
140
+
141
+ ## Testing
142
+
143
+ ### Test Reporters
144
144
 
145
- # Or via rake task
146
- rake newshound:report_now
145
+ ```bash
146
+ # Test exception reporter
147
+ rake newshound:test_exceptions
147
148
 
148
- # Enqueue for background processing
149
- rake newshound:schedule
149
+ # Test job queue reporter
150
+ rake newshound:test_jobs
150
151
 
151
- # Check configuration
152
+ # Show current configuration
152
153
  rake newshound:config
153
154
  ```
154
155
 
155
- ### Integration with que-scheduler
156
-
157
- Add to your `config/que_schedule.yml`:
156
+ ### Test in Rails Console
158
157
 
159
- ```yaml
160
- newshound_daily_report:
161
- class: "Newshound::DailyReportJob"
162
- cron: "0 9 * * *" # 9:00 AM daily
163
- queue: default
158
+ ```ruby
159
+ # Check if banner would show for a specific user
160
+ user = User.find(123)
161
+ controller = ApplicationController.new
162
+ controller.instance_variable_set(:@current_user, user)
163
+ Newshound::Authorization.authorized?(controller)
164
+ # => true or false
164
165
  ```
165
166
 
166
- Or let Newshound auto-configure based on your settings.
167
+ ## Troubleshooting
167
168
 
168
- ## Report Format
169
+ ### Banner not appearing
169
170
 
170
- The daily report includes:
171
+ 1. **Check if enabled**: `rake newshound:config`
172
+ 2. **Verify user role**: Make sure your user has an authorized role
173
+ 3. **Check current_user method**: Ensure your app provides the configured method
174
+ 4. **Restart server**: Changes to initializers require a restart
171
175
 
172
- ### Exception Section
173
- - Last 4 exceptions (configurable)
174
- - Exception class, message, controller/action
175
- - Count of same exception type in last 24 hours
176
- - Timestamp
176
+ ### No exceptions showing
177
+
178
+ - Ensure `exception-track` gem is installed and logging exceptions
179
+ - Check that exceptions exist: `rake newshound:test_exceptions`
177
180
 
178
- ### Que Jobs Section
179
- - Job counts by type (success/failed/total)
180
- - Queue health status
181
- - Ready to run count
182
- - Scheduled jobs count
183
- - Failed jobs in retry queue
184
- - Jobs completed today
181
+ ### No job data
182
+
183
+ - Verify Que is configured and `que_jobs` table exists
184
+ - Check job data: `rake newshound:test_jobs`
185
+
186
+ ### Banner appears for wrong users
187
+
188
+ - Review `authorized_roles` configuration
189
+ - Consider using custom authorization with `Newshound.authorize_with`
185
190
 
186
191
  ## Development
187
192
 
@@ -196,30 +201,22 @@ bundle exec rubocop
196
201
  bin/console
197
202
  ```
198
203
 
199
- ## Testing in Your App
204
+ ## Dependencies
200
205
 
201
- ```ruby
202
- # In rails console
206
+ - **Rails** >= 6.0
207
+ - **que** >= 1.0 (for job monitoring)
208
+ - **exception-track** >= 0.1 (for exception tracking)
203
209
 
204
- # Test Slack transport
205
- Newshound.configuration.transport_adapter = :slack
206
- Newshound.configuration.slack_webhook_url = "your-webhook"
207
- Newshound.report! # Should post to Slack immediately
210
+ ## Upgrading from 0.1.x
208
211
 
209
- # Test SNS transport
210
- Newshound.configuration.transport_adapter = :sns
211
- Newshound.configuration.sns_topic_arn = "your-topic-arn"
212
- Newshound.report! # Should publish to SNS
213
- ```
212
+ If you were using the previous Slack-based version:
214
213
 
215
- ## Troubleshooting
214
+ 1. Remove Slack/SNS configuration from your initializer
215
+ 2. Remove `que-scheduler` if only used for Newshound
216
+ 3. Update to new configuration format (see above)
217
+ 4. Restart your Rails server
216
218
 
217
- - **No reports sent**: Check `rake newshound:config` to verify configuration
218
- - **No exceptions showing**: Ensure `exception-track` gem is installed and logging
219
- - **No job data**: Verify Que is configured and `que_jobs` table exists
220
- - **Slack not receiving**: Verify webhook URL or API token is correct
221
- - **SNS not publishing**: Check IAM permissions and topic ARN configuration
222
- - **AWS SDK errors**: Ensure `aws-sdk-sns` gem is installed when using SNS transport
219
+ The banner will now appear automatically for authorized users instead of sending Slack notifications.
223
220
 
224
221
  ## License
225
222
 
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rails/generators"
4
- require "yaml"
5
4
 
6
5
  module Newshound
7
6
  module Generators
@@ -14,62 +13,22 @@ module Newshound
14
13
  template "newshound.rb", "config/initializers/newshound.rb"
15
14
  end
16
15
 
17
- def add_to_que_schedule
18
- que_schedule_path = "config/que_schedule.yml"
19
-
20
- if File.exist?(que_schedule_path)
21
- say_status :info, "Adding Newshound job to #{que_schedule_path}", :blue
22
-
23
- # Read existing YAML
24
- existing_config = YAML.load_file(que_schedule_path) || {}
25
-
26
- # Add Newshound job if not already present
27
- unless existing_config.key?("Newshound::DailyReportJob")
28
- # Append the configuration to the file
29
- append_to_file que_schedule_path do
30
- <<~YAML
31
-
32
- # Newshound daily report job - sends exception and queue reports to Slack
33
- Newshound::DailyReportJob:
34
- cron: "0 9 * * *" # Daily at 9:00 AM - adjust as needed
35
- queue: default
36
- args: []
37
- YAML
38
- end
39
-
40
- say_status :success, "Added Newshound::DailyReportJob to que_schedule.yml", :green
41
- else
42
- say_status :skip, "Newshound::DailyReportJob already exists in que_schedule.yml", :yellow
43
- end
44
- else
45
- say_status :warning, "#{que_schedule_path} not found. Creating it with Newshound job.", :yellow
46
- create_file que_schedule_path do
47
- <<~YAML
48
- # Que-scheduler configuration
49
- # See https://github.com/hlascelles/que-scheduler for more information
50
-
51
- # Newshound daily report job - sends exception and queue reports to Slack
52
- Newshound::DailyReportJob:
53
- cron: "0 9 * * *" # Daily at 9:00 AM - adjust as needed
54
- queue: default
55
- args: []
56
- YAML
57
- end
58
- end
59
- end
60
-
61
16
  def display_post_install_message
62
17
  say ""
63
18
  say "===============================================================================", :green
64
19
  say " Newshound has been successfully installed!", :green
65
20
  say ""
66
21
  say " Next steps:", :yellow
67
- say " 1. Configure your Slack webhook URL in config/initializers/newshound.rb"
68
- say " 2. Adjust the report schedule in config/que_schedule.yml if needed"
69
- say " 3. Restart your Rails server and Que workers"
22
+ say " 1. Configure authorized roles in config/initializers/newshound.rb"
23
+ say " 2. Make sure your User model has a role attribute (or customize authorization)"
24
+ say " 3. Restart your Rails server"
25
+ say ""
26
+ say " The Newshound banner will automatically appear at the top of pages for"
27
+ say " authorized users (developers and super_users by default)."
70
28
  say ""
71
- say " To test your configuration, run:", :cyan
72
- say " rails runner 'Newshound.report!'"
29
+ say " To test the reporters, run:", :cyan
30
+ say " rake newshound:test_exceptions"
31
+ say " rake newshound:test_jobs"
73
32
  say ""
74
33
  say " For more information, visit:", :blue
75
34
  say " https://github.com/salbanez/newshound"
@@ -1,38 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Newshound.configure do |config|
4
- # Slack webhook URL for sending reports (required)
5
- # You can get this from your Slack app settings
6
- config.slack_webhook_url = ENV.fetch("NEWSHOUND_SLACK_WEBHOOK_URL", nil)
7
-
8
- # Channel to post reports to
9
- # Default is "#general"
10
- config.slack_channel = "#engineering"
11
-
12
- # Time to send daily report (24-hour format)
13
- # Default is "09:00" (9:00 AM)
14
- config.report_time = "09:00"
15
-
16
- # Maximum number of exceptions to include in report
17
- # Default is 4
18
- config.exception_limit = 4
19
-
20
- # Time zone for scheduling reports
21
- # Default is "America/New_York"
22
- config.time_zone = "America/New_York"
23
-
24
4
  # Enable or disable Newshound completely
25
- # Useful for disabling in development/test environments
5
+ # When enabled, the banner will be shown to authorized users
26
6
  # Default is true
27
- config.enabled = Rails.env.production?
28
-
29
- # Transport adapter (:slack or :sns)
30
- # Default is :slack
31
- config.transport_adapter = :slack
32
-
33
- # AWS SNS Configuration (only needed if transport_adapter is :sns)
34
- # config.sns_topic_arn = ENV.fetch("NEWSHOUND_SNS_TOPIC_ARN", nil)
35
- # config.aws_region = ENV.fetch("AWS_REGION", "us-east-1")
36
- # config.aws_access_key_id = ENV.fetch("AWS_ACCESS_KEY_ID", nil)
37
- # config.aws_secret_access_key = ENV.fetch("AWS_SECRET_ACCESS_KEY", nil)
38
- end
7
+ config.enabled = true
8
+
9
+ # Maximum number of exceptions to include in banner
10
+ # Default is 10
11
+ config.exception_limit = 10
12
+
13
+ # User roles that are authorized to view the Newshound banner
14
+ # These should match the role values in your User model
15
+ # Default is [:developer, :super_user]
16
+ config.authorized_roles = [:developer, :super_user]
17
+
18
+ # Method name to call to get the current user
19
+ # Most apps use :current_user (Devise, etc.)
20
+ # Default is :current_user
21
+ config.current_user_method = :current_user
22
+ end
23
+
24
+ # Advanced: Custom authorization logic
25
+ # If the default role-based authorization doesn't fit your needs,
26
+ # you can provide a custom authorization block:
27
+ #
28
+ # Newshound.authorize_with do |controller|
29
+ # # Your custom logic here
30
+ # # Return true to show the banner, false to hide it
31
+ # controller.current_user&.admin?
32
+ # end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Newshound
4
+ module Authorization
5
+ class << self
6
+ # Check if the current user/controller is authorized to view Newshound data
7
+ def authorized?(controller)
8
+ return false unless Newshound.configuration.enabled
9
+
10
+ # Use custom authorization block if provided
11
+ if Newshound.configuration.authorization_block
12
+ return Newshound.configuration.authorization_block.call(controller)
13
+ end
14
+
15
+ # Default authorization: check if current_user has an authorized role
16
+ user = current_user_from(controller)
17
+ return false unless user
18
+
19
+ user_role = user_role_from(user)
20
+ return false unless user_role
21
+
22
+ Newshound.configuration.authorized_roles.include?(user_role.to_sym)
23
+ end
24
+
25
+ private
26
+
27
+ def current_user_from(controller)
28
+ method_name = Newshound.configuration.current_user_method
29
+ return nil unless controller.respond_to?(method_name)
30
+
31
+ controller.send(method_name)
32
+ end
33
+
34
+ def user_role_from(user)
35
+ return nil unless user
36
+
37
+ # Try common role attribute names
38
+ [:role, :user_role, :type].each do |attr|
39
+ return user.send(attr) if user.respond_to?(attr)
40
+ end
41
+
42
+ nil
43
+ end
44
+ end
45
+ end
46
+ end
@@ -2,30 +2,24 @@
2
2
 
3
3
  module Newshound
4
4
  class Configuration
5
- attr_accessor :slack_webhook_url, :slack_channel, :report_time,
6
- :exception_limit, :time_zone, :enabled,
7
- :transport_adapter, :sns_topic_arn, :aws_region,
8
- :aws_access_key_id, :aws_secret_access_key
5
+ attr_accessor :exception_limit, :enabled, :authorized_roles,
6
+ :current_user_method, :authorization_block
9
7
 
10
8
  def initialize
11
- @slack_webhook_url = nil
12
- @slack_channel = "#general"
13
- @report_time = "09:00"
14
- @exception_limit = 4
15
- @time_zone = "America/New_York"
9
+ @exception_limit = 10
16
10
  @enabled = true
17
- @transport_adapter = :slack
18
- @sns_topic_arn = nil
19
- @aws_region = nil
20
- @aws_access_key_id = nil
21
- @aws_secret_access_key = nil
11
+ @authorized_roles = [:developer, :super_user]
12
+ @current_user_method = :current_user
13
+ @authorization_block = nil
14
+ end
15
+
16
+ # Allow custom authorization logic
17
+ def authorize_with(&block)
18
+ @authorization_block = block
22
19
  end
23
20
 
24
21
  def valid?
25
- return false unless enabled
26
- return false if slack_webhook_url.nil? || slack_webhook_url.empty?
27
-
28
- true
22
+ enabled
29
23
  end
30
24
  end
31
25
  end