sidekiq-statistic 1.0.0 → 1.1.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.
Potentially problematic release.
This version of sidekiq-statistic might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -0
- data/README.md +2 -1
- data/lib/sidekiq/statistic/base.rb +3 -1
- data/lib/sidekiq/statistic/locales/de.yml +27 -0
- data/lib/sidekiq/statistic/locales/en.yml +1 -0
- data/lib/sidekiq/statistic/locales/it.yml +27 -0
- data/lib/sidekiq/statistic/locales/ru.yml +1 -0
- data/lib/sidekiq/statistic/log_parser.rb +18 -3
- data/lib/sidekiq/statistic/middleware.rb +6 -1
- data/lib/sidekiq/statistic/statistic/realtime.rb +1 -1
- data/lib/sidekiq/statistic/statistic/workers.rb +5 -0
- data/lib/sidekiq/statistic/version.rb +1 -1
- data/lib/sidekiq/statistic/views/realtime_statistic.js +4 -2
- data/lib/sidekiq/statistic/views/sidekiq-statistic.css +31 -0
- data/lib/sidekiq/statistic/views/statistic.erb +3 -0
- data/lib/sidekiq/statistic/views/statistic.js +45 -6
- data/lib/sidekiq/statistic/views/worker.erb +1 -1
- data/lib/sidekiq/statistic/web_extension.rb +2 -2
- data/{sidekiq-history.gemspec → sidekiq-statistic.gemspec} +0 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5f72d1a3e51a38a18b09adb0e47f53c9aee1bc7
|
4
|
+
data.tar.gz: a56f6a9f5f4873da709b241cc2f58a0f15be0cb3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b2dddcaa90e5ec6452edb082e9723ecd4dd77f27d611591a6c891d0078ca92ebbdb2cbbcd399123116c0683e95874b8544e2991626d3ed0a2b297640027350e
|
7
|
+
data.tar.gz: a6ac2d8b346e7a8f9cee3c85b81dddf72e4a10b72b91aa6f1810edda33b60996dc1d68550675ec9c8180e96c626e4f50812b4c7b43c659eeb05e422d84e01147
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,32 @@
|
|
1
|
+
## HEAD
|
2
|
+
|
3
|
+
## v1.1
|
4
|
+
* 29.08.2015: Create custom tooltip for charts on index page (fix #63)
|
5
|
+
|
6
|
+
*Anton Davydov*
|
7
|
+
* 26.08.2015: Add queue to workers table in index page
|
8
|
+
|
9
|
+
*Anton Davydov*
|
10
|
+
* 25.08.2015: Italian localization
|
11
|
+
|
12
|
+
*Fabio Napoleoni*
|
13
|
+
* 25.08.2015: Fix worker naming for AJ mailers (fix #59)
|
14
|
+
|
15
|
+
*Anton Davydov*
|
16
|
+
* 21.08.2015: Use dynamic path generation for json requests (fix #56)
|
17
|
+
|
18
|
+
*Anton Davydov*
|
19
|
+
* 21.08.2015: Add button in log page for display only special job (#40)
|
20
|
+
|
21
|
+
*Anton Davydov*
|
22
|
+
* 20.08.2015: Add German Localization (#54)
|
23
|
+
|
24
|
+
*Felix Bünemann*
|
25
|
+
|
26
|
+
* 20.08.2015: Fix statistics display for nested worker classes (#48)
|
27
|
+
|
28
|
+
*Felix Bünemann*
|
29
|
+
|
1
30
|
## v1.0
|
2
31
|
* 19.08.2015: Middleware refactoring (#45)
|
3
32
|
|
data/README.md
CHANGED
@@ -21,7 +21,7 @@ Also you can check <a href="https://sidekiq-history-gem.herokuapp.com/sidekiq/st
|
|
21
21
|
## Installation
|
22
22
|
Add this line to your application's Gemfile:
|
23
23
|
|
24
|
-
gem 'sidekiq-statistic'
|
24
|
+
gem 'sidekiq-statistic'
|
25
25
|
|
26
26
|
And then execute:
|
27
27
|
|
@@ -40,6 +40,7 @@ require 'sidekiq/web'
|
|
40
40
|
require 'sidekiq-statistic'
|
41
41
|
|
42
42
|
use Rack::Session::Cookie, secret: 'some unique secret string here'
|
43
|
+
Sidekiq::Web.instance_eval { @middleware.reverse! } # Last added, First Run
|
43
44
|
run Sidekiq::Web
|
44
45
|
```
|
45
46
|
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Sidekiq
|
2
2
|
module Statistic
|
3
3
|
class Base
|
4
|
+
KEY_SEPARATOR = /(?<!:):(?!:)/.freeze
|
5
|
+
|
4
6
|
def initialize(days_previous, start_date = nil)
|
5
7
|
@start_date = start_date || Time.now.utc.to_date
|
6
8
|
@end_date = @start_date - days_previous
|
@@ -29,7 +31,7 @@ module Sidekiq
|
|
29
31
|
conn
|
30
32
|
.hgetall(REDIS_HASH)
|
31
33
|
.each do |keys, value|
|
32
|
-
*keys, last = keys.split(
|
34
|
+
*keys, last = keys.split(KEY_SEPARATOR)
|
33
35
|
keys.inject(redis_hash, &key_or_empty_hash)[last.to_sym] = to_number(value)
|
34
36
|
end
|
35
37
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# elements like %{queue} are variables and should not be translated
|
2
|
+
de: # <---- change this to your locale code
|
3
|
+
Queue: Queue
|
4
|
+
Exclude: Ausblenden
|
5
|
+
Index: Übersicht
|
6
|
+
RealtimeStatistic: Echtzeitstatistik
|
7
|
+
Statistic: Statistik
|
8
|
+
Start: Beginn
|
9
|
+
End: Ende
|
10
|
+
Failed: Fehlgeschlagen
|
11
|
+
Passed: Erfolgreich
|
12
|
+
WorkersTable: Arbeiter-Tabelle
|
13
|
+
Worker: Arbeiter
|
14
|
+
Date: Datum
|
15
|
+
Success: Erfolg
|
16
|
+
Failure: Fehler
|
17
|
+
Total: Gesamt
|
18
|
+
TimeSec: Zeit(sek)
|
19
|
+
AverageSec: Durchschnitt(sek)
|
20
|
+
MinTimeSec: Min. Zeit(sek)
|
21
|
+
MaxTimeSec: Max. Zeit(sek)
|
22
|
+
LastJobStatus: Letzter Job Status
|
23
|
+
WorkerInformation: '%{worker} Information'
|
24
|
+
InformationTable: Info-Tabelle
|
25
|
+
WorkerLog: Arbeiter-Log
|
26
|
+
WorkerTablePerDay: Arbeiter-Tabelle (pro Tag)
|
27
|
+
LastRun: Letzte Ausführung
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# elements like %{queue} are variables and should not be translated
|
2
|
+
it: # <---- change this to your locale code
|
3
|
+
Queue: Fila
|
4
|
+
Exclude: Escludi
|
5
|
+
Index: Indice
|
6
|
+
RealtimeStatistic: Statistiche in Tempo Reale
|
7
|
+
Statistic: Statistiche
|
8
|
+
Start: Inizio
|
9
|
+
End: Fine
|
10
|
+
Failed: Fallito
|
11
|
+
Passed: Passato
|
12
|
+
WorkersTable: Tabella Worker
|
13
|
+
Worker: Worker
|
14
|
+
Date: Data
|
15
|
+
Success: Successo
|
16
|
+
Failure: Fallito
|
17
|
+
Total: Totale
|
18
|
+
TimeSec: Tempo (sec)
|
19
|
+
AverageSec: Media (sec)
|
20
|
+
MinTimeSec: Minimo (sec)
|
21
|
+
MaxTimeSec: Massimo (sec)
|
22
|
+
LastJobStatus: Stato Ultimo Job
|
23
|
+
WorkerInformation: 'Informazioni %{worker}'
|
24
|
+
InformationTable: Tabella Informazioni
|
25
|
+
WorkerLog: Worker log
|
26
|
+
WorkerTablePerDay: Tabella Worker (per giorno)
|
27
|
+
LastRun: Ultima Esecuzione
|
@@ -15,12 +15,27 @@ module Sidekiq
|
|
15
15
|
File
|
16
16
|
.readlines(@logfile)
|
17
17
|
.first(FILE_LINES_COUNT)
|
18
|
-
.map{ |line|
|
18
|
+
.map{ |line| sub_line(line) if line[/\W?#@worker_name\W?/] }
|
19
19
|
.compact
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
23
|
-
|
22
|
+
def sub_line(line)
|
23
|
+
line
|
24
|
+
.sub(/\n/, '')
|
25
|
+
.sub(/(JID-[\w]+)/) { jid_tag($1) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def jid_tag(jid)
|
29
|
+
"<span class=\"statistic__jid js-jid__#{jid[4..-1]}\""\
|
30
|
+
"data-target=\".js-jid__#{jid[4..-1]}\" #{jid_style jid}>#{jid}</span>"
|
31
|
+
end
|
32
|
+
|
33
|
+
def jid_style(worker_jid)
|
34
|
+
return unless worker_jid
|
35
|
+
color = Digest::MD5.hexdigest(worker_jid)[4..9]
|
36
|
+
.scan(/../).map{ |c| c.to_i(16) }.join ','
|
37
|
+
|
38
|
+
"style=\"background-color: rgba(#{color},0.2);\""
|
24
39
|
end
|
25
40
|
|
26
41
|
def color(line)
|
@@ -14,9 +14,13 @@ module Sidekiq
|
|
14
14
|
raise e
|
15
15
|
ensure
|
16
16
|
finish = Time.now
|
17
|
+
worker_status[:queue] = msg['queue'.freeze]
|
17
18
|
worker_status[:last_runtime] = finish.utc
|
18
19
|
worker_status[:time] = (finish - start).to_f.round(3)
|
19
20
|
worker_status[:class] = msg['wrapped'.freeze] || worker.class.to_s
|
21
|
+
if worker_status[:class] == 'ActionMailer::DeliveryJob'.freeze
|
22
|
+
worker_status[:class] = msg['args'.freeze].first['arguments'.freeze].first
|
23
|
+
end
|
20
24
|
|
21
25
|
save_entry_for_worker worker_status
|
22
26
|
end
|
@@ -31,7 +35,8 @@ module Sidekiq
|
|
31
35
|
redis.pipelined do
|
32
36
|
redis.hincrby REDIS_HASH, "#{worker_key}:#{status[:last_job_status]}", 1
|
33
37
|
redis.hmset REDIS_HASH, "#{worker_key}:last_job_status", status[:last_job_status],
|
34
|
-
"#{worker_key}:last_time", status[:last_runtime]
|
38
|
+
"#{worker_key}:last_time", status[:last_runtime],
|
39
|
+
"#{worker_key}:queue", status[:queue]
|
35
40
|
redis.lpush "#{worker_key}:timeslist", status[:time]
|
36
41
|
|
37
42
|
redis.hincrby realtime_hash, "#{status[:last_job_status]}:#{worker_status[:class]}", 1
|
@@ -20,7 +20,7 @@ module Sidekiq
|
|
20
20
|
conn
|
21
21
|
.hgetall("#{REDIS_HASH}:realtime:#{Time.now.sec - 1}")
|
22
22
|
.each do |keys, value|
|
23
|
-
*keys, last = keys.split(
|
23
|
+
*keys, last = keys.split(KEY_SEPARATOR)
|
24
24
|
keys.inject(redis_hash, &key_or_empty_hash)[last] = value.to_i
|
25
25
|
end
|
26
26
|
|
@@ -9,6 +9,7 @@ module Sidekiq
|
|
9
9
|
name: worker,
|
10
10
|
last_job_status: last_job_status_for(worker),
|
11
11
|
number_of_calls: number_of_calls(worker),
|
12
|
+
queue: last_queue(worker),
|
12
13
|
runtime: runtime_statistic(worker).values_hash
|
13
14
|
}
|
14
15
|
end
|
@@ -60,6 +61,10 @@ module Sidekiq
|
|
60
61
|
.last[:last_job_status]
|
61
62
|
end
|
62
63
|
|
64
|
+
def last_queue(worker)
|
65
|
+
statistic_for(worker).last[:queue]
|
66
|
+
end
|
67
|
+
|
63
68
|
def runtime_statistic(worker, values = nil)
|
64
69
|
Runtime.new(self, worker, values)
|
65
70
|
end
|
@@ -13,6 +13,7 @@ return d.pie(d.filterTargetsToShow(d.data.targets)).forEach(function(b){f||b.dat
|
|
13
13
|
}).call(C,function(){var a,d=[],e=[],f=[];if(w){for(a=0;w>a;a++)d.push("."+l.shape+"-"+(v+a)),e.push("."+l.text+"-"+(v+a)),f.push("."+l.eventRect+"-"+(v+a));b.svg.selectAll("."+l.shapes).selectAll(d).remove(),b.svg.selectAll("."+l.texts).selectAll(e).remove(),b.svg.selectAll("."+l.eventRects).selectAll(f).remove(),b.svg.select("."+l.xgrid).remove()}D.attr("transform",null).attr(b.xgridAttr),E.attr("transform",null),E.select("line").attr("x1",c.axis_rotated?0:p).attr("x2",c.axis_rotated?b.width:p),E.select("text").attr("x",c.axis_rotated?b.width:0).attr("y",p),H.attr("transform",null).attr("d",j),I.attr("transform",null).attr("d",k),J.attr("transform",null).attr("d",m),K.attr("transform",null).attr("cx",n).attr("cy",o),G.attr("transform",null).attr("x",q).attr("y",r).style("fill-opacity",b.opacityForText.bind(b)),F.attr("transform",null),F.select("rect").filter(b.isRegionOnX).attr("x",b.regionX.bind(b)).attr("width",b.regionWidth.bind(b)),c.interaction_enabled&&b.redrawEventRect(),B(),b.flowing=!1})}},h.selected=function(a){var b=this.internal,c=b.d3;return c.merge(b.main.selectAll("."+l.shapes+b.getTargetSelectorSuffix(a)).selectAll("."+l.shape).filter(function(){return c.select(this).classed(l.SELECTED)}).map(function(a){return a.map(function(a){var b=a.__data__;return b.data?b.data:b})}))},h.select=function(a,b,c){var d=this.internal,e=d.d3,f=d.config;f.data_selection_enabled&&d.main.selectAll("."+l.shapes).selectAll("."+l.shape).each(function(g,h){var i=e.select(this),j=g.data?g.data.id:g.id,k=d.getToggle(this,g).bind(d),m=f.data_selection_grouped||!a||a.indexOf(j)>=0,n=!b||b.indexOf(h)>=0,o=i.classed(l.SELECTED);i.classed(l.line)||i.classed(l.area)||(m&&n?f.data_selection_isselectable(g)&&!o&&k(!0,i.classed(l.SELECTED,!0),g,h):q(c)&&c&&o&&k(!1,i.classed(l.SELECTED,!1),g,h))})},h.unselect=function(a,b){var c=this.internal,d=c.d3,e=c.config;e.data_selection_enabled&&c.main.selectAll("."+l.shapes).selectAll("."+l.shape).each(function(f,g){var h=d.select(this),i=f.data?f.data.id:f.id,j=c.getToggle(this,f).bind(c),k=e.data_selection_grouped||!a||a.indexOf(i)>=0,m=!b||b.indexOf(g)>=0,n=h.classed(l.SELECTED);h.classed(l.line)||h.classed(l.area)||k&&m&&e.data_selection_isselectable(f)&&n&&j(!1,h.classed(l.SELECTED,!1),f,g)})},h.transform=function(a,b){var c=this.internal,d=["pie","donut"].indexOf(a)>=0?{withTransform:!0}:null;c.transformTo(b,a,d)},i.transformTo=function(a,b,c){var d=this,e=!d.hasArcType(),f=c||{withTransitionForAxis:e};f.withTransitionForTransform=!1,d.transiting=!1,d.setTargetType(a,b),d.updateTargets(d.data.targets),d.updateAndRedraw(f)},h.groups=function(a){var b=this.internal,c=b.config;return p(a)?c.data_groups:(c.data_groups=a,b.redraw(),c.data_groups)},h.xgrids=function(a){var b=this.internal,c=b.config;return a?(c.grid_x_lines=a,b.redrawWithoutRescale(),c.grid_x_lines):c.grid_x_lines},h.xgrids.add=function(a){var b=this.internal;return this.xgrids(b.config.grid_x_lines.concat(a?a:[]))},h.xgrids.remove=function(a){var b=this.internal;b.removeGridLines(a,!0)},h.ygrids=function(a){var b=this.internal,c=b.config;return a?(c.grid_y_lines=a,b.redrawWithoutRescale(),c.grid_y_lines):c.grid_y_lines},h.ygrids.add=function(a){var b=this.internal;return this.ygrids(b.config.grid_y_lines.concat(a?a:[]))},h.ygrids.remove=function(a){var b=this.internal;b.removeGridLines(a,!1)},h.regions=function(a){var b=this.internal,c=b.config;return a?(c.regions=a,b.redrawWithoutRescale(),c.regions):c.regions},h.regions.add=function(a){var b=this.internal,c=b.config;return a?(c.regions=c.regions.concat(a),b.redrawWithoutRescale(),c.regions):c.regions},h.regions.remove=function(a){var b,c,d,e=this.internal,f=e.config;return a=a||{},b=e.getOption(a,"duration",f.transition_duration),c=e.getOption(a,"classes",[l.region]),d=e.main.select("."+l.regions).selectAll(c.map(function(a){return"."+a})),(b?d.transition().duration(b):d).style("opacity",0).remove(),f.regions=f.regions.filter(function(a){var b=!1;return a["class"]?(a["class"].split(" ").forEach(function(a){c.indexOf(a)>=0&&(b=!0)}),!b):!0}),f.regions},h.data=function(a){var b=this.internal.data.targets;return"undefined"==typeof a?b:b.filter(function(b){return[].concat(a).indexOf(b.id)>=0})},h.data.shown=function(a){return this.internal.filterTargetsToShow(this.data(a))},h.data.values=function(a){var b,c=null;return a&&(b=this.data(a),c=b[0]?b[0].values.map(function(a){return a.value}):null),c},h.data.names=function(a){return this.internal.clearLegendItemTextBoxCache(),this.internal.updateDataAttributes("names",a)},h.data.colors=function(a){return this.internal.updateDataAttributes("colors",a)},h.data.axes=function(a){return this.internal.updateDataAttributes("axes",a)},h.category=function(a,b){var c=this.internal,d=c.config;return arguments.length>1&&(d.axis_x_categories[a]=b,c.redraw()),d.axis_x_categories[a]},h.categories=function(a){var b=this.internal,c=b.config;return arguments.length?(c.axis_x_categories=a,b.redraw(),c.axis_x_categories):c.axis_x_categories},h.color=function(a){var b=this.internal;return b.color(a)},h.x=function(a){var b=this.internal;return arguments.length&&(b.updateTargetX(b.data.targets,a),b.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0})),b.data.xs},h.xs=function(a){var b=this.internal;return arguments.length&&(b.updateTargetXs(b.data.targets,a),b.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0})),b.data.xs},h.axis=function(){},h.axis.labels=function(a){var b=this.internal;arguments.length&&(Object.keys(a).forEach(function(c){b.axis.setLabelText(c,a[c])}),b.axis.updateLabels())},h.axis.max=function(a){var b=this.internal,c=b.config;return arguments.length?("object"==typeof a?(m(a.x)&&(c.axis_x_max=a.x),m(a.y)&&(c.axis_y_max=a.y),m(a.y2)&&(c.axis_y2_max=a.y2)):c.axis_y_max=c.axis_y2_max=a,void b.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0})):{x:c.axis_x_max,y:c.axis_y_max,y2:c.axis_y2_max}},h.axis.min=function(a){var b=this.internal,c=b.config;return arguments.length?("object"==typeof a?(m(a.x)&&(c.axis_x_min=a.x),m(a.y)&&(c.axis_y_min=a.y),m(a.y2)&&(c.axis_y2_min=a.y2)):c.axis_y_min=c.axis_y2_min=a,void b.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0})):{x:c.axis_x_min,y:c.axis_y_min,y2:c.axis_y2_min}},h.axis.range=function(a){return arguments.length?(q(a.max)&&this.axis.max(a.max),void(q(a.min)&&this.axis.min(a.min))):{max:this.axis.max(),min:this.axis.min()}},h.legend=function(){},h.legend.show=function(a){var b=this.internal;b.showLegend(b.mapToTargetIds(a)),b.updateAndRedraw({withLegend:!0})},h.legend.hide=function(a){var b=this.internal;b.hideLegend(b.mapToTargetIds(a)),b.updateAndRedraw({withLegend:!0})},h.resize=function(a){var b=this.internal,c=b.config;c.size_width=a?a.width:null,c.size_height=a?a.height:null,this.flush()},h.flush=function(){var a=this.internal;a.updateAndRedraw({withLegend:!0,withTransition:!1,withTransitionForTransform:!1})},h.destroy=function(){var b=this.internal;return a.clearInterval(b.intervalForObserveInserted),a.onresize=null,b.selectChart.classed("c3",!1).html(""),Object.keys(b).forEach(function(a){b[a]=null}),null},h.tooltip=function(){},h.tooltip.show=function(a){var b,c,d=this.internal;a.mouse&&(c=a.mouse),a.data?d.isMultipleX()?(c=[d.x(a.data.x),d.getYScale(a.data.id)(a.data.value)],b=null):b=m(a.data.index)?a.data.index:d.getIndexByX(a.data.x):"undefined"!=typeof a.x?b=d.getIndexByX(a.x):"undefined"!=typeof a.index&&(b=a.index),d.dispatchEvent("mouseover",b,c),d.dispatchEvent("mousemove",b,c)},h.tooltip.hide=function(){this.internal.dispatchEvent("mouseout",0)};var z;i.isSafari=function(){var b=a.navigator.userAgent;return b.indexOf("Safari")>=0&&b.indexOf("Chrome")<0},i.isChrome=function(){var b=a.navigator.userAgent;return b.indexOf("Chrome")>=0},Function.prototype.bind||(Function.prototype.bind=function(a){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var b=Array.prototype.slice.call(arguments,1),c=this,d=function(){},e=function(){return c.apply(this instanceof d?this:a,b.concat(Array.prototype.slice.call(arguments)))};return d.prototype=this.prototype,e.prototype=new d,e}),"function"==typeof define&&define.amd?define("c3",["d3"],k):"undefined"!=typeof exports&&"undefined"!=typeof module?module.exports=k:a.c3=k}(window);
|
14
14
|
|
15
15
|
$(function () {
|
16
|
+
var path = window.location.pathname
|
16
17
|
var failedChart
|
17
18
|
var passedChart
|
18
19
|
var excludedWorkers = []
|
@@ -43,14 +44,15 @@ $(function () {
|
|
43
44
|
}
|
44
45
|
});
|
45
46
|
|
46
|
-
|
47
|
+
|
48
|
+
$.getJSON(path + '/charts_initializer.json', function (data) {
|
47
49
|
initializeChart['data']['columns'] = data
|
48
50
|
}).done(function () {
|
49
51
|
failedChart = c3.generate($.extend(initializeChart, { bindto: '.realtime__failed-chart' }))
|
50
52
|
passedChart = c3.generate($.extend(initializeChart, { bindto: '.realtime__passed-chart' }))
|
51
53
|
|
52
54
|
setInterval(function () {
|
53
|
-
$.getJSON('/
|
55
|
+
$.getJSON(path + '/charts.json', { excluded: excludedWorkers })
|
54
56
|
.done(function (data) {
|
55
57
|
failedChart.flow(data['failed'])
|
56
58
|
passedChart.flow(data['passed'])
|
@@ -35,6 +35,13 @@
|
|
35
35
|
.statistic__log {
|
36
36
|
display: none;
|
37
37
|
}
|
38
|
+
.statistic__jid {
|
39
|
+
cursor: pointer;
|
40
|
+
background-color: red;
|
41
|
+
}
|
42
|
+
.statistic__jid:hover {
|
43
|
+
background-color: inherit;
|
44
|
+
}
|
38
45
|
.statistic__table {
|
39
46
|
margin-top: 25px;
|
40
47
|
}
|
@@ -43,6 +50,30 @@
|
|
43
50
|
width: 300px;
|
44
51
|
}
|
45
52
|
|
53
|
+
#chartjs-tooltip {
|
54
|
+
opacity: 1;
|
55
|
+
position: absolute;
|
56
|
+
background: rgba(0, 0, 0, .7);
|
57
|
+
color: white;
|
58
|
+
padding: 3px;
|
59
|
+
border-radius: 3px;
|
60
|
+
-webkit-transition: all .1s ease;
|
61
|
+
transition: all .1s ease;
|
62
|
+
pointer-events: none;
|
63
|
+
-webkit-transform: translate(-50%, 0);
|
64
|
+
transform: translate(-50%, 0);
|
65
|
+
}
|
66
|
+
.chartjs-tooltip-title{
|
67
|
+
font-weight: 800;
|
68
|
+
margin-bottom: 5px;
|
69
|
+
}
|
70
|
+
.chartjs-tooltip-key{
|
71
|
+
display: inline-block;
|
72
|
+
width: 10px;
|
73
|
+
height: 10px;
|
74
|
+
margin: 0 2px 0 5px;
|
75
|
+
}
|
76
|
+
|
46
77
|
/*!
|
47
78
|
* jQuery UI Datepicker @VERSION
|
48
79
|
* http://jqueryui.com
|
@@ -23,6 +23,7 @@
|
|
23
23
|
<canvas id="js-failed-chart" width="800" height="200"></canvas>
|
24
24
|
<h2><%= t('Passed') %></h2>
|
25
25
|
<canvas id="js-passed-chart" width="800" height="200"></canvas>
|
26
|
+
<div id="chartjs-tooltip"></div>
|
26
27
|
</div>
|
27
28
|
|
28
29
|
<h2><%= t('WorkersTable') %></h2>
|
@@ -31,6 +32,7 @@
|
|
31
32
|
<thead>
|
32
33
|
<th><%= t('Worker') %></th>
|
33
34
|
<th><%= t('Date') %></th>
|
35
|
+
<th><%= t('Queue') %></th>
|
34
36
|
<th><%= t('Success') %></th>
|
35
37
|
<th><%= t('Failure') %></th>
|
36
38
|
<th><%= t('Total') %></th>
|
@@ -44,6 +46,7 @@
|
|
44
46
|
<tr>
|
45
47
|
<td class="worker"><a href="<%= root_path %>statistic/<%= worker[:name] %>"><%= worker[:name] %></a></td>
|
46
48
|
<td class="worker"><%= formate_date worker[:runtime][:last] %></td>
|
49
|
+
<td class="worker"><%= worker[:queue] %></td>
|
47
50
|
<td class="worker"><%= worker[:number_of_calls][:success] %></td>
|
48
51
|
<td class="worker"><%= worker[:number_of_calls][:failure] %></td>
|
49
52
|
<td class="worker"><%= worker[:number_of_calls][:total] %></td>
|
@@ -25,6 +25,39 @@ else{for(c=i&&i.getFullYear()===a,o=s&&s.getFullYear()===a,y+="<select class='ui
|
|
25
25
|
$(function () {
|
26
26
|
Chart.defaults.global.responsive = true
|
27
27
|
Chart.defaults.global.scaleLineColor = 'rgba(0,0,0,.4)'
|
28
|
+
Chart.defaults.global.customTooltips = function(tooltip) {
|
29
|
+
var tooltipEl = $('#chartjs-tooltip')
|
30
|
+
|
31
|
+
if (!tooltip) {
|
32
|
+
tooltipEl.css({
|
33
|
+
opacity: 0
|
34
|
+
});
|
35
|
+
return;
|
36
|
+
}
|
37
|
+
|
38
|
+
tooltipEl.removeClass('above below')
|
39
|
+
tooltipEl.addClass(tooltip.yAlign)
|
40
|
+
|
41
|
+
var innerHtml = '<div class="chartjs-tooltip-title">' + tooltip.title + ':</div>'
|
42
|
+
for (var i = tooltip.labels.length - 1; i >= 0; i--) {
|
43
|
+
innerHtml += [
|
44
|
+
'<div class="chartjs-tooltip-section">',
|
45
|
+
' <span class="chartjs-tooltip-key" style="background-color:' + tooltip.legendColors[i].fill.replace('0.2', '1.0') + '"></span>',
|
46
|
+
' <span class="chartjs-tooltip-value">' + tooltip.labels[i] + '</span>',
|
47
|
+
'</div>'
|
48
|
+
].join('')
|
49
|
+
}
|
50
|
+
tooltipEl.html(innerHtml)
|
51
|
+
|
52
|
+
tooltipEl.css({
|
53
|
+
opacity: 1,
|
54
|
+
left: tooltip.chart.canvas.offsetLeft + tooltip.x + 'px',
|
55
|
+
top: tooltip.chart.canvas.offsetTop + tooltip.y + 'px',
|
56
|
+
fontFamily: tooltip.fontFamily,
|
57
|
+
fontSize: tooltip.fontSize,
|
58
|
+
fontStyle: tooltip.fontStyle,
|
59
|
+
})
|
60
|
+
}
|
28
61
|
|
29
62
|
var datePickerFrom, datePickerTo
|
30
63
|
initializeDatePickers()
|
@@ -38,22 +71,27 @@ $(function () {
|
|
38
71
|
}, parseInt(localStorage.timeInterval) || 2000)
|
39
72
|
})
|
40
73
|
|
41
|
-
$(document).on('click', '.
|
74
|
+
$(document).on('click', '.statistic__tab', function (e) {
|
42
75
|
var $this = $(this)
|
43
76
|
$('.nav-tabs li').removeClass('active')
|
44
77
|
$this.parent().toggleClass('active')
|
45
78
|
|
46
|
-
$('.
|
79
|
+
$('.statistic__container').children().hide()
|
47
80
|
$($this.data('target')).show()
|
48
81
|
})
|
49
82
|
|
50
|
-
$('
|
83
|
+
$(document).on('click', '.statistic__jid', function (e) {
|
84
|
+
$('.statistic__i').toggle()
|
85
|
+
$($(this).data('target')).parent().show()
|
86
|
+
})
|
87
|
+
|
88
|
+
$('#statistic__search').keyup(function() {
|
51
89
|
var $this = $(this)
|
52
90
|
delay(function(){
|
53
91
|
if ($this.val().length) {
|
54
|
-
$('.
|
92
|
+
$('.statistic__i:not(:contains('+ $this.val() +'))').hide()
|
55
93
|
} else {
|
56
|
-
$('.
|
94
|
+
$('.statistic__i').show()
|
57
95
|
}
|
58
96
|
}, 200 )
|
59
97
|
});
|
@@ -67,7 +105,8 @@ $(function () {
|
|
67
105
|
})()
|
68
106
|
|
69
107
|
function initializeChars(data) {
|
70
|
-
|
108
|
+
var path = window.location.pathname
|
109
|
+
$.getJSON(path + '/charts.json', data, function (data) {
|
71
110
|
createChart('failed', data, data.failed_datasets)
|
72
111
|
createChart('passed', data, data.passed_datasets)
|
73
112
|
})
|
@@ -55,7 +55,7 @@
|
|
55
55
|
<div class="statistic__log">
|
56
56
|
<input type='text' name='' id='statistic__search' value='' placeholder='Search text in log file'/>
|
57
57
|
<% @worker_log.each do |line| %>
|
58
|
-
<p class="statistic__i
|
58
|
+
<p class="statistic__i"><%= line %></p>
|
59
59
|
<% end %>
|
60
60
|
</div>
|
61
61
|
</div>
|
@@ -49,14 +49,14 @@ module Sidekiq
|
|
49
49
|
render(:erb, File.read(File.join(view_path, 'realtime.erb')))
|
50
50
|
end
|
51
51
|
|
52
|
-
app.get '/statistic/
|
52
|
+
app.get '/statistic/realtime/charts.json' do
|
53
53
|
content_type :json
|
54
54
|
|
55
55
|
realtime = Sidekiq::Statistic::Realtime.new
|
56
56
|
Sidekiq.dump_json realtime.statistic(params)
|
57
57
|
end
|
58
58
|
|
59
|
-
app.get '/statistic/
|
59
|
+
app.get '/statistic/realtime/charts_initializer.json' do
|
60
60
|
content_type :json
|
61
61
|
Sidekiq.dump_json Sidekiq::Statistic::Realtime.charts_initializer
|
62
62
|
end
|
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-statistic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anton Davydov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-08-
|
11
|
+
date: 2015-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sidekiq
|
@@ -140,7 +140,9 @@ files:
|
|
140
140
|
- lib/sidekiq/statistic.rb
|
141
141
|
- lib/sidekiq/statistic/base.rb
|
142
142
|
- lib/sidekiq/statistic/configuration.rb
|
143
|
+
- lib/sidekiq/statistic/locales/de.yml
|
143
144
|
- lib/sidekiq/statistic/locales/en.yml
|
145
|
+
- lib/sidekiq/statistic/locales/it.yml
|
144
146
|
- lib/sidekiq/statistic/locales/ru.yml
|
145
147
|
- lib/sidekiq/statistic/log_parser.rb
|
146
148
|
- lib/sidekiq/statistic/middleware.rb
|
@@ -158,7 +160,7 @@ files:
|
|
158
160
|
- lib/sidekiq/statistic/web_api_extension.rb
|
159
161
|
- lib/sidekiq/statistic/web_extension.rb
|
160
162
|
- lib/sidekiq/statistic/web_extension_helper.rb
|
161
|
-
- sidekiq-
|
163
|
+
- sidekiq-statistic.gemspec
|
162
164
|
homepage: https://github.com/davydovanton/sidekiq-statistic
|
163
165
|
licenses:
|
164
166
|
- MIT
|