blazer 2.4.8 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of blazer might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +21 -39
- data/lib/blazer/adapters/sql_adapter.rb +4 -1
- data/lib/blazer/engine.rb +1 -0
- data/lib/blazer/result.rb +4 -0
- data/lib/blazer/slack_notifier.rb +16 -4
- data/lib/blazer/version.rb +1 -1
- data/lib/blazer.rb +10 -1
- data/lib/generators/blazer/templates/config.yml.tt +1 -1
- data/lib/tasks/blazer.rake +5 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fad6bd2d76ea45a8ec72956177648848a6dede796354a01f27359b4cb7cfeedb
|
4
|
+
data.tar.gz: a8f81985d77b110c850d421ac86376bbf71cf5f2b318cfea496e8cedb1f1a108
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6fd612ec162dc5b6a23ef1f6b3580da0de7f1cec8788520557e8a25ef0bdf4337df775b0cacb4e292003e1a4565460c411a67951a5ea27048a994fb1178463d7
|
7
|
+
data.tar.gz: 4a5e760ca38fb96fa54df64469f3fd3223d6b23698da0491c43dc8bc3ef92f7f83b14bea028821ba5708adf209bc147975edaf6d4dc76ecb5916d51905e7f2f0
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -10,6 +10,8 @@ Blazer is also available as a [Docker image](https://github.com/ankane/blazer-do
|
|
10
10
|
|
11
11
|
:tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
|
12
12
|
|
13
|
+
[![Build Status](https://github.com/ankane/blazer/workflows/build/badge.svg?branch=master)](https://github.com/ankane/blazer/actions)
|
14
|
+
|
13
15
|
## Features
|
14
16
|
|
15
17
|
- **Multiple data sources** - PostgreSQL, MySQL, Redshift, and [many more](#full-list)
|
@@ -37,7 +39,7 @@ Blazer is also available as a [Docker image](https://github.com/ankane/blazer-do
|
|
37
39
|
Add this line to your application’s Gemfile:
|
38
40
|
|
39
41
|
```ruby
|
40
|
-
gem
|
42
|
+
gem "blazer"
|
41
43
|
```
|
42
44
|
|
43
45
|
Run:
|
@@ -412,7 +414,7 @@ SELECT users.id AS user_id, orders.created_at AS conversion_time, users.created_
|
|
412
414
|
FROM users LEFT JOIN orders ON orders.user_id = users.id
|
413
415
|
```
|
414
416
|
|
415
|
-
This feature requires PostgreSQL or MySQL.
|
417
|
+
This feature requires PostgreSQL or MySQL 8.
|
416
418
|
|
417
419
|
## Anomaly Detection
|
418
420
|
|
@@ -423,7 +425,7 @@ Blazer supports three different approaches to anomaly detection.
|
|
423
425
|
Add [prophet-rb](https://github.com/ankane/prophet) to your Gemfile:
|
424
426
|
|
425
427
|
```ruby
|
426
|
-
gem
|
428
|
+
gem "prophet-rb"
|
427
429
|
```
|
428
430
|
|
429
431
|
And add to `config/blazer.yml`:
|
@@ -439,7 +441,7 @@ anomaly_checks: prophet
|
|
439
441
|
Add [trend](https://github.com/ankane/trend) to your Gemfile:
|
440
442
|
|
441
443
|
```ruby
|
442
|
-
gem
|
444
|
+
gem "trend"
|
443
445
|
```
|
444
446
|
|
445
447
|
And add to `config/blazer.yml`:
|
@@ -454,46 +456,20 @@ For the [self-hosted API](https://github.com/ankane/trend-api), create an initia
|
|
454
456
|
Trend.url = "http://localhost:8000"
|
455
457
|
```
|
456
458
|
|
457
|
-
###
|
458
|
-
|
459
|
-
R uses Twitter’s [AnomalyDetection](https://github.com/twitter/AnomalyDetection) library.
|
459
|
+
### AnomalyDetection.rb (experimental)
|
460
460
|
|
461
|
-
|
461
|
+
Add [anomaly_detection](https://github.com/ankane/AnomalyDetection.rb) to your Gemfile:
|
462
462
|
|
463
|
-
```
|
464
|
-
|
465
|
-
remotes::install_github("twitter/AnomalyDetection")
|
463
|
+
```ruby
|
464
|
+
gem "anomaly_detection"
|
466
465
|
```
|
467
466
|
|
468
467
|
And add to `config/blazer.yml`:
|
469
468
|
|
470
469
|
```yml
|
471
|
-
anomaly_checks:
|
472
|
-
```
|
473
|
-
|
474
|
-
If upgrading from version 1.4 or below, also follow the [upgrade instructions](#15).
|
475
|
-
|
476
|
-
If you’re on Heroku, follow the additional instructions below.
|
477
|
-
|
478
|
-
### R on Heroku
|
479
|
-
|
480
|
-
Add the [R buildpack](https://github.com/virtualstaticvoid/heroku-buildpack-r) to your app.
|
481
|
-
|
482
|
-
```sh
|
483
|
-
heroku buildpacks:add --index 1 https://github.com/virtualstaticvoid/heroku-buildpack-r.git
|
470
|
+
anomaly_checks: anomaly_detection
|
484
471
|
```
|
485
472
|
|
486
|
-
And create an `init.R` with:
|
487
|
-
|
488
|
-
```r
|
489
|
-
if (!"AnomalyDetection" %in% installed.packages()) {
|
490
|
-
install.packages("remotes")
|
491
|
-
remotes::install_github("twitter/AnomalyDetection")
|
492
|
-
}
|
493
|
-
```
|
494
|
-
|
495
|
-
Commit and deploy away. The first deploy may take a few minutes.
|
496
|
-
|
497
473
|
## Forecasting
|
498
474
|
|
499
475
|
Blazer supports for two different forecasting methods. [Example](https://blazer.dokkuapp.com/queries/18-forecast?forecast=t)
|
@@ -502,10 +478,10 @@ A forecast link will appear for queries that return 2 columns with types timesta
|
|
502
478
|
|
503
479
|
### Prophet
|
504
480
|
|
505
|
-
Add [prophet](https://github.com/ankane/prophet) to your Gemfile:
|
481
|
+
Add [prophet-rb](https://github.com/ankane/prophet) to your Gemfile:
|
506
482
|
|
507
483
|
```ruby
|
508
|
-
gem
|
484
|
+
gem "prophet-rb", ">= 0.2.1"
|
509
485
|
```
|
510
486
|
|
511
487
|
And add to `config/blazer.yml`:
|
@@ -516,12 +492,12 @@ forecasting: prophet
|
|
516
492
|
|
517
493
|
### Trend
|
518
494
|
|
519
|
-
[Trend](https://trendapi.org/) uses an external service.
|
495
|
+
[Trend](https://trendapi.org/) uses an external service by default, but you can run it on your own infrastructure as well.
|
520
496
|
|
521
497
|
Add [trend](https://github.com/ankane/trend) to your Gemfile:
|
522
498
|
|
523
499
|
```ruby
|
524
|
-
gem
|
500
|
+
gem "trend"
|
525
501
|
```
|
526
502
|
|
527
503
|
And add to `config/blazer.yml`:
|
@@ -530,6 +506,12 @@ And add to `config/blazer.yml`:
|
|
530
506
|
forecasting: trend
|
531
507
|
```
|
532
508
|
|
509
|
+
For the [self-hosted API](https://github.com/ankane/trend-api), create an initializer with:
|
510
|
+
|
511
|
+
```ruby
|
512
|
+
Trend.url = "http://localhost:8000"
|
513
|
+
```
|
514
|
+
|
533
515
|
## Uploads
|
534
516
|
|
535
517
|
Creating database tables from CSV files. [Example](https://blazer.dokkuapp.com/uploads)
|
@@ -146,7 +146,7 @@ module Blazer
|
|
146
146
|
date_sql = "CAST(DATE_FORMAT(#{time_sql}, '%Y-%m-01') AS DATE)"
|
147
147
|
date_params = [tzname]
|
148
148
|
end
|
149
|
-
bucket_sql = "CAST(CEIL(TIMESTAMPDIFF(SECOND, cohorts.cohort_time, query.conversion_time) / ?) AS
|
149
|
+
bucket_sql = "CAST(CEIL(TIMESTAMPDIFF(SECOND, cohorts.cohort_time, query.conversion_time) / ?) AS SIGNED)"
|
150
150
|
else
|
151
151
|
date_sql = "date_trunc(?, cohorts.cohort_time::timestamptz AT TIME ZONE ?)::date"
|
152
152
|
date_params = [period, tzname]
|
@@ -238,6 +238,9 @@ module Blazer
|
|
238
238
|
if settings["schemas"]
|
239
239
|
where = "table_schema IN (?)"
|
240
240
|
schemas = settings["schemas"]
|
241
|
+
elsif mysql?
|
242
|
+
where = "table_schema IN (?)"
|
243
|
+
schemas = [default_schema]
|
241
244
|
else
|
242
245
|
where = "table_schema NOT IN (?)"
|
243
246
|
schemas = ["information_schema"]
|
data/lib/blazer/engine.rb
CHANGED
@@ -36,6 +36,7 @@ module Blazer
|
|
36
36
|
|
37
37
|
Blazer.images = Blazer.settings["images"] || false
|
38
38
|
Blazer.override_csp = Blazer.settings["override_csp"] || false
|
39
|
+
Blazer.slack_oauth_token = Blazer.settings["slack_oauth_token"] || ENV["BLAZER_SLACK_OAUTH_TOKEN"]
|
39
40
|
Blazer.slack_webhook_url = Blazer.settings["slack_webhook_url"] || ENV["BLAZER_SLACK_WEBHOOK_URL"]
|
40
41
|
Blazer.mapbox_access_token = Blazer.settings["mapbox_access_token"] || ENV["MAPBOX_ACCESS_TOKEN"]
|
41
42
|
end
|
data/lib/blazer/result.rb
CHANGED
@@ -189,6 +189,10 @@ module Blazer
|
|
189
189
|
when "trend"
|
190
190
|
anomalies = Trend.anomalies(Hash[series])
|
191
191
|
anomalies.include?(series.last[0])
|
192
|
+
when "anomaly_detection"
|
193
|
+
period = 7 # TODO determine period
|
194
|
+
anomalies = AnomalyDetection.detect(Hash[series], period: period)
|
195
|
+
anomalies.include?(series.last[0])
|
192
196
|
else
|
193
197
|
csv_str =
|
194
198
|
CSV.generate do |csv|
|
@@ -23,7 +23,7 @@ module Blazer
|
|
23
23
|
]
|
24
24
|
}
|
25
25
|
|
26
|
-
post(
|
26
|
+
post(payload)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -44,7 +44,7 @@ module Blazer
|
|
44
44
|
]
|
45
45
|
}
|
46
46
|
|
47
|
-
post(
|
47
|
+
post(payload)
|
48
48
|
end
|
49
49
|
|
50
50
|
# https://api.slack.com/docs/message-formatting#how_to_escape_characters
|
@@ -67,13 +67,25 @@ module Blazer
|
|
67
67
|
Blazer::Engine.routes.url_helpers.query_url(id, ActionMailer::Base.default_url_options)
|
68
68
|
end
|
69
69
|
|
70
|
-
def self.post(
|
70
|
+
def self.post(payload)
|
71
|
+
if Blazer.slack_webhook_url.present?
|
72
|
+
post_api(Blazer.slack_webhook_url, payload, {})
|
73
|
+
else
|
74
|
+
headers = {
|
75
|
+
"Authorization" => "Bearer #{Blazer.slack_oauth_token}",
|
76
|
+
"Content-type" => "application/json"
|
77
|
+
}
|
78
|
+
post_api("https://slack.com/api/chat.postMessage", payload, headers)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.post_api(url, payload, headers)
|
71
83
|
uri = URI.parse(url)
|
72
84
|
http = Net::HTTP.new(uri.host, uri.port)
|
73
85
|
http.use_ssl = true
|
74
86
|
http.open_timeout = 3
|
75
87
|
http.read_timeout = 5
|
76
|
-
http.post(uri.request_uri, payload.to_json)
|
88
|
+
http.post(uri.request_uri, payload.to_json, headers)
|
77
89
|
end
|
78
90
|
end
|
79
91
|
end
|
data/lib/blazer/version.rb
CHANGED
data/lib/blazer.rb
CHANGED
@@ -63,6 +63,7 @@ module Blazer
|
|
63
63
|
attr_accessor :query_viewable
|
64
64
|
attr_accessor :query_editable
|
65
65
|
attr_accessor :override_csp
|
66
|
+
attr_accessor :slack_oauth_token
|
66
67
|
attr_accessor :slack_webhook_url
|
67
68
|
attr_accessor :mapbox_access_token
|
68
69
|
end
|
@@ -213,7 +214,7 @@ module Blazer
|
|
213
214
|
end
|
214
215
|
|
215
216
|
def self.slack?
|
216
|
-
slack_webhook_url.present?
|
217
|
+
slack_oauth_token.present? || slack_webhook_url.present?
|
217
218
|
end
|
218
219
|
|
219
220
|
def self.uploads?
|
@@ -240,6 +241,14 @@ module Blazer
|
|
240
241
|
def self.register_adapter(name, adapter)
|
241
242
|
adapters[name] = adapter
|
242
243
|
end
|
244
|
+
|
245
|
+
def self.archive_queries
|
246
|
+
raise "Audits must be enabled to archive" unless Blazer.audit
|
247
|
+
raise "Missing status column - see https://github.com/ankane/blazer#23" unless Blazer::Query.column_names.include?("status")
|
248
|
+
|
249
|
+
viewed_query_ids = Blazer::Audit.where("created_at > ?", 90.days.ago).group(:query_id).count.keys.compact
|
250
|
+
Blazer::Query.active.where.not(id: viewed_query_ids).update_all(status: "archived")
|
251
|
+
end
|
243
252
|
end
|
244
253
|
|
245
254
|
Blazer.register_adapter "athena", Blazer::Adapters::AthenaAdapter
|
@@ -63,7 +63,7 @@ check_schedules:
|
|
63
63
|
|
64
64
|
# enable anomaly detection
|
65
65
|
# note: with trend, time series are sent to https://trendapi.org
|
66
|
-
# anomaly_checks: prophet / trend /
|
66
|
+
# anomaly_checks: prophet / trend / anomaly_detection
|
67
67
|
|
68
68
|
# enable forecasting
|
69
69
|
# note: with trend, time series are sent to https://trendapi.org
|
data/lib/tasks/blazer.rake
CHANGED
@@ -11,10 +11,10 @@ namespace :blazer do
|
|
11
11
|
|
12
12
|
desc "archive queries"
|
13
13
|
task archive_queries: :environment do
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
begin
|
15
|
+
Blazer.archive_queries
|
16
|
+
rescue => e
|
17
|
+
abort e.message
|
18
|
+
end
|
19
19
|
end
|
20
20
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blazer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|