sidekiq-statistic 1.2.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +7 -7
- data/CHANGELOG.md +6 -0
- data/LICENSE.txt +1 -1
- data/README.md +12 -4
- data/Rakefile +2 -0
- data/bin/console +1 -1
- data/lib/sidekiq-statistic.rb +2 -0
- data/lib/sidekiq/statistic.rb +4 -1
- data/lib/sidekiq/statistic/base.rb +5 -3
- data/lib/sidekiq/statistic/configuration.rb +5 -1
- data/lib/sidekiq/statistic/helpers/color.rb +28 -0
- data/lib/sidekiq/statistic/locales/de.yml +2 -0
- data/lib/sidekiq/statistic/locales/en.yml +2 -0
- data/lib/sidekiq/statistic/locales/fr.yml +29 -0
- data/lib/sidekiq/statistic/locales/it.yml +2 -0
- data/lib/sidekiq/statistic/locales/jp.yml +29 -0
- data/lib/sidekiq/statistic/locales/pt-br.yml +33 -0
- data/lib/sidekiq/statistic/locales/ru.yml +8 -6
- data/lib/sidekiq/statistic/locales/uk.yml +29 -0
- data/lib/sidekiq/statistic/log_parser.rb +17 -5
- data/lib/sidekiq/statistic/middleware.rb +19 -9
- data/lib/sidekiq/statistic/statistic/charts.rb +9 -19
- data/lib/sidekiq/statistic/statistic/realtime.rb +6 -4
- data/lib/sidekiq/statistic/statistic/runtime.rb +6 -4
- data/lib/sidekiq/statistic/statistic/workers.rb +2 -0
- data/lib/sidekiq/statistic/version.rb +3 -1
- data/lib/sidekiq/statistic/views/c3.js +5 -0
- data/lib/sidekiq/statistic/views/realtime.erb +10 -4
- data/lib/sidekiq/statistic/views/realtime_statistic.js +38 -37
- data/lib/sidekiq/statistic/views/sidekiq-statistic.css +471 -66
- data/lib/sidekiq/statistic/views/statistic.erb +8 -6
- data/lib/sidekiq/statistic/views/statistic.js +50 -60
- data/lib/sidekiq/statistic/views/worker.erb +15 -7
- data/lib/sidekiq/statistic/web_api_extension.rb +3 -1
- data/lib/sidekiq/statistic/web_extension.rb +23 -20
- data/lib/sidekiq/statistic/web_extension_helper.rb +14 -5
- data/sidekiq-statistic.gemspec +3 -2
- metadata +31 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a32f2de3dc5fe06de39827e46f0b182a20f9221eeac4ddd03f01cf7d1038d699
|
4
|
+
data.tar.gz: f47b057b32feb27d543d936661cbcd440a0f5562d75f005d5bdaf53d9805d800
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b70d66e91a305176f3044fb66441430a3064404a9929089e9090c92692f154ad1b180696317d0c9bd03920b95a5d7785bb7f802ced621083321a210144449d71
|
7
|
+
data.tar.gz: b825025d90d0f899f83b347a16f217703c75037bcc9605c041a72cb48828b9ef2aca15593c09d16980f0ecee9558c0154f4af1ef64a5e384a454725d2561322a
|
data/.travis.yml
CHANGED
@@ -3,15 +3,15 @@ sudo: false
|
|
3
3
|
cache: bundler
|
4
4
|
services:
|
5
5
|
- redis-server
|
6
|
+
before_install:
|
7
|
+
- gem install bundler
|
8
|
+
- gem update bundler
|
6
9
|
rvm:
|
7
|
-
- 2.
|
8
|
-
- 2.
|
9
|
-
- 2.
|
10
|
-
- jruby-
|
11
|
-
- jruby
|
10
|
+
- 2.3.8
|
11
|
+
- 2.4.5
|
12
|
+
- 2.5.3
|
13
|
+
- jruby-head
|
12
14
|
- rbx-2
|
13
15
|
matrix:
|
14
16
|
allow_failures:
|
15
17
|
- rvm: rbx-2
|
16
|
-
- rvm: jruby
|
17
|
-
bundler_args: --without test --jobs 3 --retry 3
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,10 @@
|
|
1
1
|
## HEAD
|
2
|
+
* 08.03.2019: Change LogParser regexp (#81) *Kirill Tatchihin*
|
3
|
+
* 03.02.02019: Change storing of last_runtime from date to timestamp (#87) *Kirill Tatchihin*
|
4
|
+
* 30.03.2017: Prevent excessive Redis memory usage (#107) *Gareth du Plooy*
|
5
|
+
* 08.04.2016: Add new option for displaying last N lines of log file (#91) *Nick Zhebrun*
|
6
|
+
* 20.11.2015: Convert value in redis time array to float (#76) *Anton Davydov*
|
7
|
+
* 20.11.2015: Add Ukrainian Localization (#85) *@POStroi*
|
2
8
|
|
3
9
|
## v1.2
|
4
10
|
* 15.11.2015: Update gemspec to allow usage with sidekiq 4 (#83) *Felix Bünemann*
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -39,16 +39,19 @@ require 'sidekiq/web'
|
|
39
39
|
require 'sidekiq-statistic'
|
40
40
|
|
41
41
|
use Rack::Session::Cookie, secret: 'some unique secret string here'
|
42
|
-
Sidekiq::Web.instance_eval { @middleware.reverse! } # Last added, First Run
|
43
42
|
run Sidekiq::Web
|
44
43
|
```
|
45
44
|
|
46
45
|
## Configuration
|
47
|
-
Sidekiq statistic gem have `log_file`
|
46
|
+
Sidekiq statistic gem have `log_file` and `last_log_lines` options.
|
47
|
+
`log_file` option lets you specify a custom path to sidekiq log file. By default this option equal `log/sidekiq.log`
|
48
|
+
`last_log lines` option lets you specify a custom count of last logger file lines which will be displayed. By default this option equal 1000.
|
48
49
|
|
49
50
|
``` ruby
|
50
51
|
Sidekiq::Statistic.configure do |config|
|
51
52
|
config.log_file = 'test/helpers/logfile.log'
|
53
|
+
config.last_log_lines = 10_000
|
54
|
+
config.max_timelist_length = 500_000
|
52
55
|
end
|
53
56
|
```
|
54
57
|
|
@@ -126,7 +129,7 @@ $ curl http://example.com/sidekiq/api/statistic/Worker.json?dateFrom=2015-07-30&
|
|
126
129
|
## Update statistic inside middleware
|
127
130
|
You can update your worker statistic inside middleware. For this you should to update `sidekiq:statistic` redis hash.
|
128
131
|
This hash has the following structure:
|
129
|
-
* `
|
132
|
+
* `sidekiq:statistic` - redis hash with all statistic
|
130
133
|
- `yyyy-mm-dd:WorkerName:passed` - count of passed jobs for Worker name on yyyy-mm-dd
|
131
134
|
- `yyyy-mm-dd:WorkerName:failed` - count of failed jobs for Worker name on yyyy-mm-dd
|
132
135
|
- `yyyy-mm-dd:WorkerName:failed` - count of failed jobs for Worker name on yyyy-mm-dd
|
@@ -137,7 +140,12 @@ This hash has the following structure:
|
|
137
140
|
For time information you should push the runtime value to `yyyy-mm-dd:WorkerName:timeslist` redis list.
|
138
141
|
|
139
142
|
## How it works
|
140
|
-
|
143
|
+
<details>
|
144
|
+
<summary>Big image 'how it works'</summary>
|
145
|
+
|
146
|
+
![how-it-works](https://cloud.githubusercontent.com/assets/1147484/8802272/fc0a1302-2fc8-11e5-86a5-817409259338.png)
|
147
|
+
|
148
|
+
</details>
|
141
149
|
|
142
150
|
## Contributing
|
143
151
|
1. Fork it ( https://github.com/davydovanton/sidekiq-statistic/fork )
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
data/lib/sidekiq-statistic.rb
CHANGED
data/lib/sidekiq/statistic.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
begin
|
2
4
|
require 'sidekiq/web'
|
3
5
|
rescue LoadError
|
@@ -17,10 +19,11 @@ require 'sidekiq/statistic/version'
|
|
17
19
|
require 'sidekiq/statistic/web_extension'
|
18
20
|
require 'sidekiq/statistic/web_api_extension'
|
19
21
|
require 'sidekiq/statistic/web_extension_helper'
|
22
|
+
require 'sidekiq/statistic/helpers/color'
|
20
23
|
|
21
24
|
module Sidekiq
|
22
25
|
module Statistic
|
23
|
-
REDIS_HASH = 'sidekiq:statistic'
|
26
|
+
REDIS_HASH = 'sidekiq:statistic'
|
24
27
|
|
25
28
|
class << self
|
26
29
|
attr_writer :configuration
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Sidekiq
|
2
4
|
module Statistic
|
3
5
|
class Base
|
4
|
-
KEY_SEPARATOR = /(?<!:):(?!:)
|
6
|
+
KEY_SEPARATOR = /(?<!:):(?!:)/
|
5
7
|
|
6
8
|
def initialize(days_previous, start_date = nil)
|
7
9
|
@start_date = start_date || Time.now.utc.to_date
|
@@ -56,8 +58,8 @@ module Sidekiq
|
|
56
58
|
|
57
59
|
def to_number(value)
|
58
60
|
case value
|
59
|
-
when /\A
|
60
|
-
when /\A
|
61
|
+
when /\A-?\d+\.\d+\z/ then value.to_f
|
62
|
+
when /\A-?\d+\z/ then value.to_i
|
61
63
|
else value
|
62
64
|
end
|
63
65
|
end
|
@@ -1,10 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Sidekiq
|
2
4
|
module Statistic
|
3
5
|
class Configuration
|
4
|
-
attr_accessor :log_file
|
6
|
+
attr_accessor :log_file, :last_log_lines, :max_timelist_length
|
5
7
|
|
6
8
|
def initialize
|
7
9
|
@log_file = 'log/sidekiq.log'
|
10
|
+
@last_log_lines = 1_000
|
11
|
+
@max_timelist_length = 250_000
|
8
12
|
end
|
9
13
|
end
|
10
14
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sidekiq
|
4
|
+
module Statistic
|
5
|
+
module Helpers
|
6
|
+
class Color
|
7
|
+
class << self
|
8
|
+
def for(worker_name, format = :rgb)
|
9
|
+
rgb = Digest::MD5.hexdigest(worker_name)[0..5]
|
10
|
+
.scan(/../)
|
11
|
+
.map { |color| color.to_i(16) }
|
12
|
+
.join(',')
|
13
|
+
|
14
|
+
return to_hex(rgb) if format == :hex
|
15
|
+
|
16
|
+
rgb
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def to_hex(rgb)
|
22
|
+
'#' + rgb.split(',').map { |v| v.to_i.to_s(16).rjust(2, '0').upcase }.join
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# elements like %{queue} are variables and should not be translated
|
2
|
+
fr: # <---- change this to your locale code
|
3
|
+
Queue: Queue
|
4
|
+
Exclude: Exclure
|
5
|
+
Index: Indice
|
6
|
+
RealtimeStatistic: Statistique en temps réel
|
7
|
+
Statistic: Statistique
|
8
|
+
Start: Début
|
9
|
+
End: Fin
|
10
|
+
Failed: Échoué
|
11
|
+
Passed: Passé
|
12
|
+
WorkersTable: Workers Table
|
13
|
+
Worker: Worker
|
14
|
+
Date: Date
|
15
|
+
Success: Succès
|
16
|
+
Failure: Échec
|
17
|
+
Total: Total
|
18
|
+
TimeSec: Temps (sec)
|
19
|
+
AverageSec: Moyenne (sec)
|
20
|
+
MinTimeSec: Min temps (sec)
|
21
|
+
MaxTimeSec: Max temps (sec)
|
22
|
+
LastJobStatus: Dernier statut job
|
23
|
+
WorkerInformation: '%{worker} information'
|
24
|
+
InformationTable: Information table
|
25
|
+
WorkerLog: Journaux Worker
|
26
|
+
WorkerTablePerDay: Worker Table (par jour)
|
27
|
+
LastRun: Dernier Exécution
|
28
|
+
EmptyLogs: Jornaux Vides
|
29
|
+
SearchLogs: Journaux de recherche
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# elements like %{queue} are variables and should not be translated
|
2
|
+
jp: # <---- change this to your locale code
|
3
|
+
Queue: キュー
|
4
|
+
Exclude: 削除
|
5
|
+
Index: 索引
|
6
|
+
RealtimeStatistic: リアルタイム統計
|
7
|
+
Statistic: 統計
|
8
|
+
Start: 開始
|
9
|
+
End: 終了
|
10
|
+
Failed: 失敗
|
11
|
+
Passed: 成功
|
12
|
+
WorkersTable: ワーカー表
|
13
|
+
Worker: ワーカー
|
14
|
+
Date: 日付
|
15
|
+
Success: 成功
|
16
|
+
Failure: 失敗
|
17
|
+
Total: 合計
|
18
|
+
TimeSec: 時間(秒)
|
19
|
+
AverageSec: 平均時間(秒)
|
20
|
+
MinTimeSec: 最小時間(秒)
|
21
|
+
MaxTimeSec: 最長時間(秒)
|
22
|
+
LastJobStatus: 最後の状態
|
23
|
+
WorkerInformation: '%{worker}の情報'
|
24
|
+
InformationTable: 情報表
|
25
|
+
WorkerLog: ワーカーログ
|
26
|
+
WorkerTablePerDay: ワーカー表 (日)
|
27
|
+
LastRun: 最後の実行
|
28
|
+
EmptyLogs: データがありません
|
29
|
+
SearchLogs: ログファイルにて検索
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# elements like %{queue} are variables and should not be translated
|
2
|
+
pt-br: # <---- change this to your locale code
|
3
|
+
Queue: Fila
|
4
|
+
Exclude: Excluir
|
5
|
+
Index: Índice
|
6
|
+
RealtimeStatistic: Estatística em tempo real
|
7
|
+
Statistic: Estatística
|
8
|
+
Start: Início
|
9
|
+
End: Fim
|
10
|
+
Failed: Falhou
|
11
|
+
Passed: Passou
|
12
|
+
WorkersTable: Tabela de Workers
|
13
|
+
Worker: Worker
|
14
|
+
Date: Data
|
15
|
+
Success: Successo
|
16
|
+
Failure: Falha
|
17
|
+
Total: Total
|
18
|
+
TimeSec: Tempo(s)
|
19
|
+
AverageSec: Média(s)
|
20
|
+
MinTimeSec: Tempo Min(s)
|
21
|
+
MaxTimeSec: Tempo Max(s)
|
22
|
+
LastJobStatus: Status do último trabalho
|
23
|
+
WorkerInformation: 'Informações do %{worker}'
|
24
|
+
InformationTable: Tabela de informação
|
25
|
+
WorkerLog: Log do Worker
|
26
|
+
WorkerTablePerDay: Tabela do Worker (por dia)
|
27
|
+
LastRun: Última execução
|
28
|
+
EmptyLogs: Nenhum resultado
|
29
|
+
SearchLogs: Pesquisar no arquivo de logs
|
30
|
+
date:
|
31
|
+
formats:
|
32
|
+
default: "%d/%m/%Y"
|
33
|
+
datetime: "%d/%m/%Y - %T"
|
@@ -7,21 +7,23 @@ ru: # <---- change this to your locale code
|
|
7
7
|
Statistic: Статистика
|
8
8
|
Start: Начало
|
9
9
|
End: Конец
|
10
|
-
Failed: Не
|
11
|
-
Passed:
|
10
|
+
Failed: Не выполненные
|
11
|
+
Passed: Выполненные
|
12
12
|
WorkersTable: Таблица воркеров
|
13
13
|
Worker: Воркер
|
14
14
|
Date: Дата
|
15
15
|
Success: Успешно
|
16
16
|
Failure: Неудачно
|
17
|
-
Total:
|
17
|
+
Total: Суммарно
|
18
18
|
TimeSec: Время(сек)
|
19
|
-
AverageSec: Среднее(сек)
|
20
|
-
MinTimeSec:
|
21
|
-
MaxTimeSec:
|
19
|
+
AverageSec: Среднее время(сек)
|
20
|
+
MinTimeSec: 'Мин. время(сек)'
|
21
|
+
MaxTimeSec: 'Макс. время(сек)'
|
22
22
|
LastJobStatus: Статус последнего джоба
|
23
23
|
WorkerInformation: 'Информация о %{worker}'
|
24
24
|
InformationTable: Таблица с информацией
|
25
25
|
WorkerLog: Лог воркера
|
26
26
|
WorkerTablePerDay: Таблица воркера (по дням)
|
27
27
|
LastRun: Последний запуск
|
28
|
+
EmptyLogs: Нет результатов
|
29
|
+
SearchLogs: Поиск в лог-файле
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# elements like %{queue} are variables and should not be translated
|
2
|
+
uk: # <---- change this to your locale code
|
3
|
+
Queue: Черга
|
4
|
+
Exclude: Вилучити
|
5
|
+
Index: Головна
|
6
|
+
RealtimeStatistic: Статистика у реальному часі
|
7
|
+
Statistic: Статистика
|
8
|
+
Start: Початок
|
9
|
+
End: Кінець
|
10
|
+
Failed: Невиконані
|
11
|
+
Passed: Виконані
|
12
|
+
WorkersTable: Таблиця обробників
|
13
|
+
Worker: Обробник
|
14
|
+
Date: Дата
|
15
|
+
Success: Успішно
|
16
|
+
Failure: Невдало
|
17
|
+
Total: Сумарно
|
18
|
+
TimeSec: Час(сек)
|
19
|
+
AverageSec: Середнє(сек)
|
20
|
+
MinTimeSec: Мін. час(сек)
|
21
|
+
MaxTimeSec: Макс. час(сек)
|
22
|
+
LastJobStatus: Стан останнього обробника
|
23
|
+
WorkerInformation: 'Інформація про %{worker}'
|
24
|
+
InformationTable: Таблиця з інформацією
|
25
|
+
WorkerLog: Журнал обробника
|
26
|
+
WorkerTablePerDay: Таблиця обробника (по днях)
|
27
|
+
LastRun: Останній запуск
|
28
|
+
EmptyLogs: немає результатів
|
29
|
+
SearchLogs: Пошук у файлі журналу
|
@@ -1,28 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Sidekiq
|
2
4
|
module Statistic
|
3
5
|
# Heroku have read only file system. See more in this link:
|
4
6
|
# https://devcenter.heroku.com/articles/read-only-filesystem
|
5
7
|
class LogParser
|
6
|
-
|
8
|
+
WORKER_INFO_REGEXP_TEMPLATE = "([\\W]+|^)%{worker_name}([\\W]+|$)"
|
9
|
+
|
7
10
|
def initialize(worker_name)
|
8
11
|
@worker_name = worker_name
|
9
12
|
@logfile = log_file
|
13
|
+
@worker_info_regexp = Regexp.compile(WORKER_INFO_REGEXP_TEMPLATE % { worker_name: @worker_name })
|
14
|
+
@jid_tag_regexp = Regexp.compile('(JID-[\\w]+)')
|
10
15
|
end
|
11
16
|
|
12
17
|
def parse
|
13
|
-
return [] unless File.
|
18
|
+
return [] unless File.exist?(@logfile)
|
14
19
|
|
15
20
|
File
|
16
21
|
.readlines(@logfile)
|
17
|
-
.
|
18
|
-
.map{ |line| sub_line(line) if line
|
22
|
+
.last(last_log_lines)
|
23
|
+
.map{ |line| sub_line(line) if line.match(worker_info_regexp) }
|
19
24
|
.compact
|
20
25
|
end
|
21
26
|
|
22
27
|
def sub_line(line)
|
23
28
|
line
|
24
29
|
.sub(/\n/, '')
|
25
|
-
.sub(
|
30
|
+
.sub(jid_tag_regexp) { jid_tag($1) }
|
26
31
|
end
|
27
32
|
|
28
33
|
def jid_tag(jid)
|
@@ -47,11 +52,18 @@ module Sidekiq
|
|
47
52
|
end
|
48
53
|
|
49
54
|
private
|
55
|
+
|
56
|
+
attr_reader :worker_info_regexp, :jid_tag_regexp
|
57
|
+
|
50
58
|
def log_file
|
51
59
|
Sidekiq.options[:logfile] ||
|
52
60
|
Sidekiq.logger.instance_variable_get(:@logdev).filename ||
|
53
61
|
Sidekiq::Statistic.configuration.log_file
|
54
62
|
end
|
63
|
+
|
64
|
+
def last_log_lines
|
65
|
+
Sidekiq::Statistic.configuration.last_log_lines
|
66
|
+
end
|
55
67
|
end
|
56
68
|
end
|
57
69
|
end
|