logster 2.4.2 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/Gemfile +2 -0
- data/Guardfile +2 -0
- data/README.md +1 -1
- data/Rakefile +2 -0
- data/assets/javascript/client-app.js +69 -53
- data/assets/javascript/vendor.js +580 -559
- data/assets/stylesheets/client-app.css +1 -1
- data/client-app/README.md +2 -2
- data/client-app/app/components/env-tab.js +16 -36
- data/client-app/app/components/message-row.js +1 -1
- data/client-app/app/components/page-nav.js +30 -0
- data/client-app/app/components/patterns-list.js +2 -1
- data/client-app/app/controllers/index.js +68 -92
- data/client-app/app/controllers/show.js +6 -0
- data/client-app/app/models/group.js +20 -0
- data/client-app/app/models/message-collection.js +159 -57
- data/client-app/app/routes/index.js +0 -2
- data/client-app/app/routes/settings.js +3 -1
- data/client-app/app/styles/app.css +17 -2
- data/client-app/app/templates/components/env-tab.hbs +5 -7
- data/client-app/app/templates/components/message-info.hbs +13 -8
- data/client-app/app/templates/components/page-nav.hbs +13 -0
- data/client-app/app/templates/components/patterns-list.hbs +6 -4
- data/client-app/app/templates/index.hbs +45 -11
- data/client-app/app/templates/settings.hbs +10 -1
- data/client-app/app/templates/show.hbs +2 -0
- data/client-app/package-lock.json +2817 -1215
- data/client-app/package.json +12 -12
- data/client-app/tests/integration/components/env-tab-test.js +29 -8
- data/client-app/tests/integration/components/message-info-test.js +10 -2
- data/lib/examples/sidekiq_logster_reporter.rb +2 -0
- data/lib/logster.rb +2 -2
- data/lib/logster/base_store.rb +40 -4
- data/lib/logster/cache.rb +9 -8
- data/lib/logster/defer_logger.rb +2 -0
- data/lib/logster/group.rb +124 -0
- data/lib/logster/grouping_pattern.rb +29 -0
- data/lib/logster/ignore_pattern.rb +2 -0
- data/lib/logster/logger.rb +2 -0
- data/lib/logster/message.rb +3 -1
- data/lib/logster/middleware/reporter.rb +2 -2
- data/lib/logster/middleware/viewer.rb +12 -1
- data/lib/logster/pattern.rb +13 -0
- data/lib/logster/redis_store.rb +99 -10
- data/lib/logster/scheduler.rb +2 -0
- data/lib/logster/suppression_pattern.rb +5 -2
- data/lib/logster/version.rb +1 -1
- data/lib/logster/web.rb +2 -0
- data/logster.gemspec +4 -1
- data/test/examples/test_sidekiq_reporter_example.rb +2 -0
- data/test/fake_data/Gemfile +2 -0
- data/test/fake_data/generate.rb +2 -0
- data/test/logster/middleware/test_viewer.rb +3 -1
- data/test/logster/test_base_store.rb +2 -0
- data/test/logster/test_cache.rb +19 -12
- data/test/logster/test_defer_logger.rb +2 -0
- data/test/logster/test_group.rb +92 -0
- data/test/logster/test_ignore_pattern.rb +2 -0
- data/test/logster/test_logger.rb +3 -1
- data/test/logster/test_message.rb +2 -0
- data/test/logster/test_pattern.rb +2 -2
- data/test/logster/test_redis_rate_limiter.rb +2 -0
- data/test/logster/test_redis_store.rb +253 -0
- data/test/test_helper.rb +6 -0
- metadata +26 -6
@@ -1 +1 @@
|
|
1
|
-
.divider,.message-info{border-bottom:1px solid #ddd}body{font-family:Arial,"Liberation Sans","DejaVu Sans",sans-serif;font-size:12px}body.mobile,body.mobile .message{font-size:14px}pre{font-family:"Roboto Mono",Consolas,Monaco,Ubuntu Mono,monospace}table.env-table tbody tr td{border-top:none;line-height:18px;height:18px;vertical-align:top}table.env-table,table.env-table table{border-spacing:0;border-collapse:collapse}table.env-table td{padding-right:5px}tbody tr{width:98%}.message-row{font-family:Roboto;display:flex}.pattern-wrapper .pattern-input,.settings-section .api-error{font-family:Consolas,"Roboto Mono",Monaco,Ubuntu Mono,monospace}.message-row .protected,.message-row .severity{text-align:center;width:25px;flex-grow:0;flex-shrink:0;font-size:12px}.message-row div{border-top:.5px #e9e9e9 solid;padding-top:1px;padding-bottom:1px;line-height:25px}.message-row .count{width:30px;flex-grow:0;flex-shrink:0;padding-right:4px;box-sizing:border-box;font-size:11px;font-weight:700;text-align:right}.message-row .message-body{flex-grow:1;flex-shrink:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:13px}.message-row .time{flex-grow:0;flex-shrink:0;color:#999;vertical-align:top;font-size:12px;padding-right:8px}.action-panel .search,.action-panel i.fa,.btn .fa,.btn span,.pattern-wrapper .shrink,.search-clear-all .clear,input,label span{vertical-align:middle}.message-row:hover{background-color:#f8f8f8;cursor:pointer}.message-row.selected{background-color:#dfdfdf}i.fatal{color:#e00}i.error{color:#900}i.warning{color:#feb800}.debug{color:#777}.btn,.tabs a{text-decoration:none;color:#333}.action-panel .search{border:1px solid #ddd;padding:3px;box-sizing:border-box}#log-table .show-more{text-align:center;height:30px;line-height:30px;text-decoration:none;background-color:#ddd;cursor:pointer;margin-top:8px}#overlay,.divider{cursor:row-resize}#bottom-panel{position:fixed;bottom:0;left:0;right:0;height:300px;background-color:#f1f1f1;padding:0 8px 8px;z-index:2}#bottom-panel.full{position:static;background-color:inherit;height:90%}#bottom-panel.full>div{padding-bottom:40px}#bottom-panel.full .tabs{display:none}#bottom-panel.full .message-info{position:static}#bottom-panel.full .message-info .content{display:block;position:static}#bottom-panel.full button.delete,.hidden{display:none}#bottom-panel.full .save,#bottom-panel.full .share{bottom:10px}#bottom-panel.full .message-actions button{margin-top:8px}#bottom-panel.full .message-actions{position:fixed;height:40px;width:100%;left:0;bottom:0;background-color:#eee;border-top:1px solid #dfdfdf;padding-left:10px}.divider,.tabs{border-top:1px solid #ddd}.message-actions{position:absolute;bottom:5px;right:0;margin-right:10px}.message-actions button{margin-left:5px}.divider{position:fixed;bottom:310px;left:0;right:0;height:15px;background-color:#fafafa}.divider div{margin:auto;width:24px;height:1px;background-color:#ccc;position:relative}.divider .line-1{top:5px}.divider .line-2{top:6px}.divider .line-3{top:7px}#top-panel{position:fixed;top:0;left:0;right:0;bottom:320px;overflow:auto}.action-panel,.message-info{position:absolute;left:0;right:0}.message-info{top:0}.action-panel{bottom:0;font-weight:700}.action-panel input{margin:0}.severity-filters label{margin-right:18px}.search-clear-all .clear{float:right}#log-table{margin:auto;width:99%}.message-info .env-table,.message-info pre{position:relative;margin:5px 10px 10px}#overlay{position:fixed;z-index:99999;top:0;bottom:0;left:0;right:0;opacity:0}.message-info .content,.tabs{position:absolute;left:0;right:0}.message-info .content{top:0;bottom:35px;overflow:auto;display:none}.message-info .content.active{display:block}.tabs{bottom:13px;list-style-type:none;margin:0 0 5px;padding:0 0 0 10px}.tabs a,.tabs li{position:relative}.tabs li{float:left;padding-right:5px;margin:0}.tabs a{top:6px;border:1px solid #ddd;border-top:none;border-bottom-left-radius:5px;border-bottom-right-radius:5px;padding:6px;background-color:#e1e1e1}.tabs a.active{border-top:1px solid #f1f1f1;background-color:#f1f1f1}.btn{display:inline-block;margin:0;padding:5px 12px;font-size:1em;line-height:0;text-align:center;cursor:pointer;transition:all .25s;background-color:#ddd;border:none;font-weight:400}.btn:hover{color:#000;background-color:#ccc}.btn .fa{margin-right:7px}.btn:active{text-shadow:none}.btn.danger:hover{background-color:#c63c1b;color:#eee}.btn.ok{background-color:#3781dc;color:#fff}.btn.ok:hover{background-color:#286dc2;color:#fff}.search-clear-all .clear,.search-clear-all .search{height:100%}.search-clear-all .clear,.search-clear-all .search,.severity-filters label{align-self:center}.search-clear-all .footer-btns .settings{margin:0 7px}.search-clear-all{display:flex;justify-content:space-between}.search-clear-all .search{min-width:0;flex-shrink:2}.footer-btns{flex-grow:0;flex-shrink:0}@media (min-width:770px){.search-clear-all,.severity-filters{height:100%}.more-wrapping,.severity-filters{display:flex}.severity-filters{float:left}.action-panel{padding:10px;box-sizing:border-box;height:42px}.message-info{bottom:42px}}@media (max-width:770px){.severity-filters{padding:10px}.search-clear-all{padding:0 10px 10px}.action-panel{height:69px}.message-info{bottom:69px}}@media (max-width:430px){.severity-filters{overflow-x:scroll;overflow-y:hidden;white-space:nowrap}.more-wrapping:after,.more-wrapping:before{content:"";position:absolute;height:18px}.more-wrapping:before{width:15px;margin-left:-10px;background:linear-gradient(to right,#f1f1f1 0,rgba(241,241,241,.001) 100%)}.more-wrapping:after{right:0;width:23px;background:linear-gradient(to left,#f1f1f1 0,rgba(241,241,241,.001) 100%)}}.btn.no-text .fa{margin:0}.btn[disabled]{opacity:.5}.actions-menu{position:absolute;background:#fafafa;display:inline-flex;flex-direction:column;bottom:27px;right:45px;width:115px;padding:5px 5px 0;box-shadow:0 4px 14px rgba(0,0,0,.15);z-index:3}.actions-menu button{margin:0 0 5px;height:27px}.nav-controls{padding:10px}#bottom-panel:not(.full) .nav-controls{position:sticky;position:-webkit-sticky;position:-moz-sticky;position:-ms-sticky;position:-o-sticky;top:0;background:#f1f1f1;z-index:1;border-bottom:1px solid #ddd}.
|
1
|
+
.divider,.message-info,.nav-controls.group-nav{border-bottom:1px solid #ddd}body{font-family:Arial,"Liberation Sans","DejaVu Sans",sans-serif;font-size:12px}body.mobile,body.mobile .message{font-size:14px}pre{font-family:"Roboto Mono",Consolas,Monaco,Ubuntu Mono,monospace}table.env-table tbody tr td{border-top:none;line-height:18px;height:18px;vertical-align:top}table.env-table,table.env-table table{border-spacing:0;border-collapse:collapse}table.env-table td{padding-right:5px}tbody tr{width:98%}.message-row{font-family:Roboto;display:flex}.pattern-wrapper .pattern-input,.settings-section .api-error{font-family:Consolas,"Roboto Mono",Monaco,Ubuntu Mono,monospace}.message-row .protected,.message-row .severity{text-align:center;width:25px;flex-grow:0;flex-shrink:0;font-size:12px}.message-row div{border-top:.5px #e9e9e9 solid;padding-top:1px;padding-bottom:1px;line-height:25px}.message-row .count{width:30px;flex-grow:0;flex-shrink:0;padding-right:4px;box-sizing:border-box;font-size:11px;font-weight:700;text-align:right}.message-row .message-body{flex-grow:1;flex-shrink:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:13px}.message-row .time{flex-grow:0;flex-shrink:0;color:#999;vertical-align:top;font-size:12px;padding-right:8px}.action-panel .search,.action-panel i.fa,.btn .fa,.btn span,.pattern-wrapper .shrink,.search-clear-all .clear,input,label span{vertical-align:middle}.message-row:hover{background-color:#f8f8f8;cursor:pointer}.message-row.selected{background-color:#dfdfdf}i.fatal{color:#e00}i.error{color:#900}i.warning{color:#feb800}.debug{color:#777}.btn,.tabs a{text-decoration:none;color:#333}.action-panel .search{border:1px solid #ddd;padding:3px;box-sizing:border-box}#log-table .show-more{text-align:center;height:30px;line-height:30px;text-decoration:none;background-color:#ddd;cursor:pointer;margin-top:8px}#overlay,.divider{cursor:row-resize}#bottom-panel{position:fixed;bottom:0;left:0;right:0;height:300px;background-color:#f1f1f1;padding:0 8px 8px;z-index:2}#bottom-panel.full{position:static;background-color:inherit;height:90%}#bottom-panel.full>div{padding-bottom:40px}#bottom-panel.full .tabs{display:none}#bottom-panel.full .message-info{position:static}#bottom-panel.full .message-info .content{display:block;position:static}#bottom-panel.full button.delete,.hidden{display:none}#bottom-panel.full .save,#bottom-panel.full .share{bottom:10px}#bottom-panel.full .message-actions button{margin-top:8px}#bottom-panel.full .message-actions{position:fixed;height:40px;width:100%;left:0;bottom:0;background-color:#eee;border-top:1px solid #dfdfdf;padding-left:10px}.divider,.tabs{border-top:1px solid #ddd}.message-actions{position:absolute;bottom:5px;right:0;margin-right:10px}.message-actions button{margin-left:5px}.divider{position:fixed;bottom:310px;left:0;right:0;height:15px;background-color:#fafafa}.divider div{margin:auto;width:24px;height:1px;background-color:#ccc;position:relative}.divider .line-1{top:5px}.divider .line-2{top:6px}.divider .line-3{top:7px}#top-panel{position:fixed;top:0;left:0;right:0;bottom:320px;overflow:auto}.action-panel,.message-info,.nav-controls.group-nav{position:absolute;left:0;right:0}.message-info{top:0}#bottom-panel.group-view .message-info{top:43px}.action-panel{bottom:0;font-weight:700}.action-panel input{margin:0}.severity-filters label{margin-right:18px}.search-clear-all .clear{float:right}#log-table{margin:auto;width:99%}.message-info .env-table,.message-info pre{position:relative;margin:5px 10px 10px}#overlay{position:fixed;z-index:99999;top:0;bottom:0;left:0;right:0;opacity:0}.message-info .content,.tabs{position:absolute;left:0;right:0}.message-info .content{top:0;bottom:35px;overflow:auto;display:none}.message-info .content.active{display:block}.tabs{bottom:13px;list-style-type:none;margin:0 0 5px;padding:0 0 0 10px}.tabs a,.tabs li{position:relative}.tabs li{float:left;padding-right:5px;margin:0}.tabs a{top:6px;border:1px solid #ddd;border-top:none;border-bottom-left-radius:5px;border-bottom-right-radius:5px;padding:6px;background-color:#e1e1e1}.tabs a.active{border-top:1px solid #f1f1f1;background-color:#f1f1f1}.btn{display:inline-block;margin:0;padding:5px 12px;font-size:1em;line-height:0;text-align:center;cursor:pointer;transition:all .25s;background-color:#ddd;border:none;font-weight:400}.btn:hover{color:#000;background-color:#ccc}.btn .fa{margin-right:7px}.btn:active{text-shadow:none}.btn.danger:hover{background-color:#c63c1b;color:#eee}.btn.ok{background-color:#3781dc;color:#fff}.btn.ok:hover{background-color:#286dc2;color:#fff}.search-clear-all .clear,.search-clear-all .search{height:100%}.search-clear-all .clear,.search-clear-all .search,.severity-filters label{align-self:center}.search-clear-all .footer-btns .settings{margin:0 7px}.search-clear-all{display:flex;justify-content:space-between}.search-clear-all .search{min-width:0;flex-shrink:2}.footer-btns{flex-grow:0;flex-shrink:0}@media (min-width:770px){.search-clear-all,.severity-filters{height:100%}.more-wrapping,.severity-filters{display:flex}.severity-filters{float:left}.action-panel{padding:10px;box-sizing:border-box;height:42px}.message-info{bottom:42px}}@media (max-width:770px){.severity-filters{padding:10px}.search-clear-all{padding:0 10px 10px}.action-panel{height:69px}.message-info{bottom:69px}}@media (max-width:430px){.severity-filters{overflow-x:scroll;overflow-y:hidden;white-space:nowrap}.more-wrapping:after,.more-wrapping:before{content:"";position:absolute;height:18px}.more-wrapping:before{width:15px;margin-left:-10px;background:linear-gradient(to right,#f1f1f1 0,rgba(241,241,241,.001) 100%)}.more-wrapping:after{right:0;width:23px;background:linear-gradient(to left,#f1f1f1 0,rgba(241,241,241,.001) 100%)}}.btn.no-text .fa{margin:0}.btn[disabled]{opacity:.5}.actions-menu{position:absolute;background:#fafafa;display:inline-flex;flex-direction:column;bottom:27px;right:45px;width:115px;padding:5px 5px 0;box-shadow:0 4px 14px rgba(0,0,0,.15);z-index:3}.actions-menu button{margin:0 0 5px;height:27px}.nav-controls{padding:10px}#bottom-panel:not(.full) .nav-controls.env-nav{position:sticky;position:-webkit-sticky;position:-moz-sticky;position:-ms-sticky;position:-o-sticky;top:0;background:#f1f1f1;z-index:1;border-bottom:1px solid #ddd}.current-number{margin:0 7px}.expand-list{text-decoration:underline;color:#00f;cursor:pointer}.settings-page{max-width:1110px;margin-right:auto;margin-left:auto;font-size:15px;padding:0 10px 70px}.settings-header{display:flex;align-items:center;margin-bottom:5px}.settings-header .header-title{flex-grow:1}.settings-header .header-logo{width:50px;height:50px}.settings-section{border-top:1px solid #ddd;padding-top:15px}.settings-section .section-title{margin-top:0}.settings-section .subsection-title{margin-bottom:10px}.settings-section .tip{font-style:italic;font-size:13px;color:grey}.settings-section .pattern-wrapper{margin-top:10px;font-size:16px;display:flex;height:33px}.settings-section .api-error{margin-top:5px;color:red}.pattern-wrapper .pattern-input{width:600px;font-size:inherit;padding:5px 0;height:100%;box-sizing:border-box;vertical-align:middle;flex-grow:1;flex-shrink:1}.retro-checkbox .checkbox{margin:0}.retro-checkbox{margin-top:7px;margin-bottom:15px}.btn.new-pattern{height:100%;line-height:18px}.pattern-wrapper .shrink{height:100%;width:40px;text-align:center;box-sizing:border-box;flex-grow:0;flex-shrink:0;margin-left:10px}.fa{opacity:.7}.pattern-wrapper .shrink.reset{background:unset;width:unset;padding:0;margin-left:8px}.grouping-patterns button.new-pattern{margin-top:10px}
|
data/client-app/README.md
CHANGED
@@ -21,8 +21,8 @@ You will need the following things properly installed on your computer.
|
|
21
21
|
## Running / Development
|
22
22
|
|
23
23
|
* `ember serve`
|
24
|
-
* Visit your app at [http://localhost:4200](http://localhost:4200).
|
25
|
-
* Visit your tests at [http://localhost:4200/tests](http://localhost:4200/tests).
|
24
|
+
* Visit your app at [http://localhost:4200/logs](http://localhost:4200).
|
25
|
+
* Visit your tests at [http://localhost:4200/logs/tests](http://localhost:4200/tests).
|
26
26
|
|
27
27
|
### Code Generators
|
28
28
|
|
@@ -4,32 +4,32 @@ import { buildHashString } from "client-app/lib/utilities";
|
|
4
4
|
import Preload from "client-app/lib/preload";
|
5
5
|
|
6
6
|
export default Component.extend({
|
7
|
-
current: 1,
|
8
|
-
|
9
7
|
didUpdateAttrs() {
|
10
|
-
this.
|
11
|
-
current: 1,
|
12
|
-
expanded: null
|
13
|
-
});
|
8
|
+
this.set("expanded", null);
|
14
9
|
},
|
15
10
|
|
11
|
+
currentEnv: computed("isEnvArray", "currentEnvPosition", function() {
|
12
|
+
if (this.isEnvArray) {
|
13
|
+
return this.message.env[this.currentEnvPosition];
|
14
|
+
} else {
|
15
|
+
return this.message.env;
|
16
|
+
}
|
17
|
+
}),
|
18
|
+
|
16
19
|
isEnvArray: computed("message.env", function() {
|
17
20
|
return Array.isArray(this.get("message.env"));
|
18
21
|
}),
|
19
22
|
|
20
|
-
html: computed("isEnvArray", "
|
21
|
-
if (!this.
|
23
|
+
html: computed("isEnvArray", "currentEnv", "expanded.[]", function() {
|
24
|
+
if (!this.isEnvArray) {
|
22
25
|
return buildHashString(this.get("message.env"));
|
23
26
|
} else {
|
24
|
-
const currentEnv = Em.$.extend(
|
25
|
-
{},
|
26
|
-
this.get("message.env")[this.get("current") - 1]
|
27
|
-
);
|
27
|
+
const currentEnv = Em.$.extend({}, this.currentEnv);
|
28
28
|
const expandableKeys = Preload.get("env_expandable_keys") || [];
|
29
29
|
expandableKeys.forEach(key => {
|
30
30
|
if (currentEnv.hasOwnProperty(key) && !Array.isArray(currentEnv[key])) {
|
31
31
|
const list = [currentEnv[key]];
|
32
|
-
this.
|
32
|
+
this.message.env.forEach(env => {
|
33
33
|
if (env[key] && list.indexOf(env[key]) === -1) {
|
34
34
|
list.push(env[key]);
|
35
35
|
}
|
@@ -37,7 +37,7 @@ export default Component.extend({
|
|
37
37
|
currentEnv[key] = list.length > 1 ? list : list[0];
|
38
38
|
}
|
39
39
|
});
|
40
|
-
return buildHashString(currentEnv, false, this.
|
40
|
+
return buildHashString(currentEnv, false, this.expanded || []);
|
41
41
|
}
|
42
42
|
}),
|
43
43
|
|
@@ -50,31 +50,11 @@ export default Component.extend({
|
|
50
50
|
$elem.hasClass("expand-list")
|
51
51
|
) {
|
52
52
|
e.preventDefault();
|
53
|
-
if (!this.
|
53
|
+
if (!this.expanded) {
|
54
54
|
this.set("expanded", [dataKey]);
|
55
55
|
} else {
|
56
|
-
this.
|
56
|
+
this.expanded.pushObject(dataKey);
|
57
57
|
}
|
58
58
|
}
|
59
|
-
},
|
60
|
-
|
61
|
-
disableBackButtons: computed("current", function() {
|
62
|
-
return this.get("current") === 1;
|
63
|
-
}),
|
64
|
-
|
65
|
-
disableForwardButtons: computed("current", "message.env.length", function() {
|
66
|
-
return this.get("current") === this.get("message.env.length");
|
67
|
-
}),
|
68
|
-
|
69
|
-
actions: {
|
70
|
-
takeStep(dir) {
|
71
|
-
const amount = dir === "back" ? -1 : 1;
|
72
|
-
this.set("current", this.get("current") + amount);
|
73
|
-
},
|
74
|
-
|
75
|
-
bigJump(dir) {
|
76
|
-
const newCurrent = dir === "back" ? 1 : this.get("message.env.length");
|
77
|
-
this.set("current", newCurrent);
|
78
|
-
}
|
79
59
|
}
|
80
60
|
});
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import Component from "@ember/component";
|
2
|
+
import { computed } from "@ember/object";
|
3
|
+
import { equal } from "@ember/object/computed";
|
4
|
+
|
5
|
+
export default Component.extend({
|
6
|
+
classNames: ["nav-controls"],
|
7
|
+
classNameBindings: ["extraClasses"],
|
8
|
+
disableBackButtons: equal("position", 0),
|
9
|
+
|
10
|
+
disableForwardButtons: computed("position", "list.length", function() {
|
11
|
+
return this.position === this.get("list.length") - 1;
|
12
|
+
}),
|
13
|
+
|
14
|
+
displayNumber: computed("position", function() {
|
15
|
+
return this.position + 1;
|
16
|
+
}),
|
17
|
+
|
18
|
+
actions: {
|
19
|
+
takeStep(dir) {
|
20
|
+
const amount = dir === "back" ? -1 : 1;
|
21
|
+
const newPos = this.position + amount;
|
22
|
+
this.navigate(newPos);
|
23
|
+
},
|
24
|
+
|
25
|
+
bigJump(dir) {
|
26
|
+
const newPos = dir === "back" ? 0 : this.get("list.length") - 1;
|
27
|
+
this.navigate(newPos);
|
28
|
+
}
|
29
|
+
}
|
30
|
+
});
|
@@ -1,11 +1,12 @@
|
|
1
1
|
import Component from "@ember/component";
|
2
|
-
import { not } from "@ember/object/computed";
|
2
|
+
import { not, equal } from "@ember/object/computed";
|
3
3
|
import { computed } from "@ember/object";
|
4
4
|
import Pattern from "client-app/models/pattern-item";
|
5
5
|
import { ajax } from "client-app/lib/utilities";
|
6
6
|
|
7
7
|
export default Component.extend({
|
8
8
|
immutable: not("mutable"),
|
9
|
+
showCounter: equal("key", "suppression"),
|
9
10
|
|
10
11
|
init() {
|
11
12
|
this._super(...arguments);
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import Controller from "@ember/controller";
|
2
2
|
import { ajax } from "client-app/lib/utilities";
|
3
|
-
import {
|
3
|
+
import { computed } from "@ember/object";
|
4
4
|
import Preload from "client-app/lib/preload";
|
5
5
|
import { debounce } from "@ember/runloop";
|
6
6
|
|
@@ -11,8 +11,7 @@ export default Controller.extend({
|
|
11
11
|
showErr: true,
|
12
12
|
showFatal: true,
|
13
13
|
search: "",
|
14
|
-
|
15
|
-
currentTab: null,
|
14
|
+
queryParams: ["search"],
|
16
15
|
|
17
16
|
showSettings: computed(function() {
|
18
17
|
return Preload.get("patterns_enabled");
|
@@ -27,131 +26,108 @@ export default Controller.extend({
|
|
27
26
|
return this.site.isMobile;
|
28
27
|
}),
|
29
28
|
|
30
|
-
fetchEnv() {
|
31
|
-
const message = this.get("currentMessage");
|
32
|
-
if (message) {
|
33
|
-
this.set("loadingEnv", true);
|
34
|
-
return ajax(`/fetch-env/${message.key}.json`)
|
35
|
-
.then(env => message.set("env", env))
|
36
|
-
.always(() => this.set("loadingEnv", false));
|
37
|
-
}
|
38
|
-
},
|
39
|
-
|
40
29
|
actions: {
|
41
30
|
expandMessage(message) {
|
42
31
|
message.expand();
|
43
32
|
},
|
44
33
|
|
45
|
-
|
46
|
-
|
47
|
-
if (old) {
|
48
|
-
old.set("selected", false);
|
49
|
-
}
|
50
|
-
|
51
|
-
message.set("selected", true);
|
52
|
-
this.setProperties({
|
53
|
-
currentMessage: message,
|
54
|
-
loadingEnv: false
|
55
|
-
});
|
56
|
-
if (!message.env && this.currentTab === "env") {
|
57
|
-
this.fetchEnv();
|
58
|
-
}
|
34
|
+
selectRowAction(row, opts = {}) {
|
35
|
+
this.model.selectRow(row, opts);
|
59
36
|
},
|
60
37
|
|
61
|
-
|
62
|
-
this.
|
63
|
-
currentTab: newTab,
|
64
|
-
loadingEnv: false
|
65
|
-
});
|
66
|
-
if (newTab === "env" && !this.get("currentMessage.env")) {
|
67
|
-
this.fetchEnv();
|
68
|
-
}
|
38
|
+
tabChangedAction(newTab) {
|
39
|
+
this.model.tabChanged(newTab);
|
69
40
|
},
|
70
41
|
|
71
42
|
showMoreBefore() {
|
72
|
-
this.
|
43
|
+
this.model.showMoreBefore();
|
73
44
|
},
|
74
45
|
|
75
46
|
loadMore() {
|
76
|
-
return this.
|
47
|
+
return this.model.loadMore();
|
77
48
|
},
|
78
49
|
|
79
50
|
clear() {
|
80
51
|
if (confirm("Clear the logs?\n\nCancel = No, OK = Clear")) {
|
81
52
|
ajax("/clear", { type: "POST" }).then(() => {
|
82
|
-
this.
|
53
|
+
this.model.reload();
|
83
54
|
});
|
84
55
|
}
|
85
56
|
},
|
86
57
|
|
87
58
|
removeMessage(msg) {
|
88
|
-
const
|
89
|
-
|
59
|
+
const group = this.model.currentRow.group ? this.model.currentRow : null;
|
60
|
+
const rows = this.model.rows;
|
61
|
+
const idx = group ? rows.indexOf(group) : rows.indexOf(msg);
|
62
|
+
|
63
|
+
msg.destroy();
|
64
|
+
msg.set("selected", false);
|
65
|
+
this.model.set("total", this.model.total - 1);
|
66
|
+
let removedRow = false;
|
67
|
+
let messageIndex = 0;
|
68
|
+
|
69
|
+
if (group) {
|
70
|
+
messageIndex = group.messages.indexOf(msg);
|
71
|
+
group.messages.removeObject(msg);
|
72
|
+
messageIndex = Math.min(messageIndex, group.messages.length - 1);
|
73
|
+
group.decrementProperty("count");
|
74
|
+
if (group.messages.length === 0) {
|
75
|
+
rows.removeObject(group);
|
76
|
+
removedRow = true;
|
77
|
+
}
|
78
|
+
} else {
|
79
|
+
rows.removeObject(msg);
|
80
|
+
removedRow = true;
|
81
|
+
}
|
82
|
+
|
83
|
+
if (removedRow) {
|
84
|
+
if (idx > 0) {
|
85
|
+
this.model.selectRow(rows[idx - 1]);
|
86
|
+
} else if (this.model.total > 0) {
|
87
|
+
this.model.selectRow(rows[0]);
|
88
|
+
} else {
|
89
|
+
this.model.reload();
|
90
|
+
}
|
91
|
+
} else if (group) {
|
92
|
+
this.model.selectRow(rows[idx], { messageIndex });
|
93
|
+
}
|
90
94
|
},
|
91
95
|
|
92
96
|
solveMessage(msg) {
|
93
|
-
|
94
|
-
|
95
|
-
}
|
96
|
-
},
|
97
|
+
this.model.solve(msg);
|
98
|
+
},
|
97
99
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
if (currentKey && messages) {
|
102
|
-
const match = messages.find(m => m.key === currentKey);
|
103
|
-
if (match) {
|
104
|
-
match.set("selected", true);
|
105
|
-
} else {
|
106
|
-
this.set("currentMessage", null);
|
107
|
-
}
|
108
|
-
}
|
109
|
-
},
|
100
|
+
groupedMessageChangedAction(newPosition) {
|
101
|
+
this.model.groupedMessageChanged(newPosition);
|
102
|
+
},
|
110
103
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
function() {
|
104
|
+
envChangedAction(newPosition) {
|
105
|
+
this.model.envChanged(newPosition);
|
106
|
+
},
|
107
|
+
|
108
|
+
updateFilter(name) {
|
109
|
+
this.toggleProperty(name);
|
118
110
|
const filter = [];
|
119
111
|
["Debug", "Info", "Warn", "Err", "Fatal"].forEach((severity, index) => {
|
120
112
|
if (this.get(`show${severity}`)) {
|
121
113
|
filter.push(index);
|
122
114
|
}
|
123
115
|
});
|
116
|
+
filter.push(5); // always show unknown, rare
|
117
|
+
this.model.set("filter", filter);
|
118
|
+
this.model.reload().then(() => this.model.updateSelectedRow());
|
119
|
+
},
|
124
120
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
filterChanged: observer("filter.length", function() {
|
132
|
-
const filter = this.get("filter");
|
133
|
-
const model = this.get("model");
|
134
|
-
model.set("filter", filter);
|
135
|
-
if (filter && this.get("initialized")) {
|
136
|
-
model.reload().then(() => this.updateSelectedMessage());
|
137
|
-
}
|
138
|
-
}),
|
139
|
-
|
140
|
-
doSearch(term) {
|
141
|
-
const model = this.get("model");
|
142
|
-
model.set("search", term);
|
143
|
-
|
144
|
-
if (this.get("initialized")) {
|
145
|
-
model.reload().then(() => this.updateSelectedMessage());
|
121
|
+
updateSearch(term) {
|
122
|
+
if (term && term.length === 1) {
|
123
|
+
return;
|
124
|
+
}
|
125
|
+
debounce(this, this.doSearch, term, 250);
|
146
126
|
}
|
147
127
|
},
|
148
128
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
return;
|
154
|
-
}
|
155
|
-
debounce(this, this.doSearch, term, 250);
|
156
|
-
})
|
129
|
+
doSearch(term) {
|
130
|
+
this.model.set("search", term);
|
131
|
+
this.model.reload().then(() => this.model.updateSelectedRow());
|
132
|
+
}
|
157
133
|
});
|
@@ -1,6 +1,8 @@
|
|
1
1
|
import Controller from "@ember/controller";
|
2
2
|
|
3
3
|
export default Controller.extend({
|
4
|
+
envPosition: 0,
|
5
|
+
|
4
6
|
actions: {
|
5
7
|
protect() {
|
6
8
|
this.get("model").protect();
|
@@ -8,6 +10,10 @@ export default Controller.extend({
|
|
8
10
|
|
9
11
|
unprotect() {
|
10
12
|
this.get("model").unprotect();
|
13
|
+
},
|
14
|
+
|
15
|
+
envChanged(newPosition) {
|
16
|
+
this.set("envPosition", newPosition);
|
11
17
|
}
|
12
18
|
}
|
13
19
|
});
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import Message from "client-app/models/message";
|
2
|
+
import { default as EmberObject, computed } from "@ember/object";
|
3
|
+
import { reads } from "@ember/object/computed";
|
4
|
+
|
5
|
+
export default EmberObject.extend({
|
6
|
+
selected: false,
|
7
|
+
showCount: true,
|
8
|
+
key: reads("regex"),
|
9
|
+
displayMessage: reads("messages.firstObject.message"),
|
10
|
+
|
11
|
+
init() {
|
12
|
+
this._super(...arguments);
|
13
|
+
const messages = this.messages.map(m => Message.create(m));
|
14
|
+
this.set("messages", messages);
|
15
|
+
},
|
16
|
+
|
17
|
+
glyph: computed(function() {
|
18
|
+
return "<i class='fa fa-clone group'></i>";
|
19
|
+
})
|
20
|
+
});
|
@@ -1,14 +1,43 @@
|
|
1
1
|
import { ajax, increaseTitleCount } from "client-app/lib/utilities";
|
2
2
|
import Message from "client-app/models/message";
|
3
|
+
import Group from "client-app/models/group";
|
3
4
|
import { compare } from "@ember/utils";
|
4
|
-
import { computed } from "@ember/object";
|
5
|
+
import { default as EmberObject, computed } from "@ember/object";
|
6
|
+
import { A } from "@ember/array";
|
5
7
|
|
6
8
|
const BATCH_SIZE = 50;
|
9
|
+
const DEFAULT_FILTER = [0, 1, 2, 3, 4, 5];
|
7
10
|
|
8
|
-
export default
|
9
|
-
messages: Em.A(),
|
10
|
-
currentMessage: null,
|
11
|
+
export default EmberObject.extend({
|
11
12
|
total: 0,
|
13
|
+
rows: null,
|
14
|
+
currentRow: null,
|
15
|
+
currentTab: null,
|
16
|
+
currentEnvPosition: 0,
|
17
|
+
currentGroupedMessagesPosition: 0,
|
18
|
+
|
19
|
+
init() {
|
20
|
+
this._super(...arguments);
|
21
|
+
this.setProperties({
|
22
|
+
filter: DEFAULT_FILTER,
|
23
|
+
search: "",
|
24
|
+
rows: A()
|
25
|
+
});
|
26
|
+
},
|
27
|
+
|
28
|
+
currentMessage: computed(
|
29
|
+
"currentRow",
|
30
|
+
"currentGroupedMessagesPosition",
|
31
|
+
function() {
|
32
|
+
const row = this.currentRow;
|
33
|
+
const position = this.currentGroupedMessagesPosition;
|
34
|
+
if (row && row.group) {
|
35
|
+
return row.messages[position];
|
36
|
+
} else {
|
37
|
+
return row;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
),
|
12
41
|
|
13
42
|
solve(message) {
|
14
43
|
message.solve().then(() => {
|
@@ -16,25 +45,85 @@ export default Em.Object.extend({
|
|
16
45
|
});
|
17
46
|
},
|
18
47
|
|
19
|
-
|
20
|
-
const
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
48
|
+
selectRow(row, opts = {}) {
|
49
|
+
const old = this.currentRow;
|
50
|
+
if (old) {
|
51
|
+
old.set("selected", false);
|
52
|
+
}
|
53
|
+
row.set("selected", true);
|
54
|
+
const currentGroupedMessagesPosition = opts["messageIndex"] || 0;
|
55
|
+
const shouldRefresh =
|
56
|
+
currentGroupedMessagesPosition === this.currentGroupedMessagesPosition;
|
57
|
+
this.setProperties({
|
58
|
+
currentRow: row,
|
59
|
+
loadingEnv: false,
|
60
|
+
currentGroupedMessagesPosition,
|
61
|
+
currentEnvPosition: 0
|
62
|
+
});
|
63
|
+
if (shouldRefresh)
|
64
|
+
this.notifyPropertyChange("currentGroupedMessagesPosition");
|
65
|
+
this.fetchEnv();
|
66
|
+
},
|
67
|
+
|
68
|
+
tabChanged(newTab) {
|
69
|
+
this.setProperties({
|
70
|
+
currentTab: newTab,
|
71
|
+
loadingEnv: false
|
72
|
+
});
|
73
|
+
this.fetchEnv();
|
74
|
+
},
|
75
|
+
|
76
|
+
groupedMessageChanged(newPosition) {
|
77
|
+
this.setProperties({
|
78
|
+
currentGroupedMessagesPosition: newPosition,
|
79
|
+
currentEnvPosition: 0
|
80
|
+
});
|
81
|
+
this.fetchEnv();
|
82
|
+
},
|
83
|
+
|
84
|
+
envChanged(newPosition) {
|
85
|
+
this.set("currentEnvPosition", newPosition);
|
86
|
+
this.fetchEnv();
|
87
|
+
},
|
88
|
+
|
89
|
+
fetchEnv() {
|
90
|
+
const message = this.currentMessage;
|
91
|
+
if (message && !message.env && this.currentTab === "env") {
|
92
|
+
this.set("loadingEnv", true);
|
93
|
+
return ajax(`/fetch-env/${message.key}.json`)
|
94
|
+
.then(env => message.set("env", env))
|
95
|
+
.always(() => this.set("loadingEnv", false));
|
96
|
+
}
|
97
|
+
},
|
98
|
+
|
99
|
+
findEquivalentMessageIndex(row) {
|
100
|
+
let messageIndex = 0;
|
101
|
+
if (
|
102
|
+
row &&
|
103
|
+
row.group &&
|
104
|
+
this.currentRow &&
|
105
|
+
this.currentRow.group &&
|
106
|
+
row.key === this.currentRow.key
|
107
|
+
) {
|
108
|
+
messageIndex = row.messages.mapBy("key").indexOf(this.currentMessage.key);
|
109
|
+
messageIndex = Math.max(0, messageIndex);
|
110
|
+
}
|
111
|
+
return messageIndex;
|
112
|
+
},
|
113
|
+
|
114
|
+
updateSelectedRow() {
|
115
|
+
const currentKey = this.get("currentRow.key");
|
116
|
+
if (currentKey && this.rows) {
|
117
|
+
const match = this.rows.find(m => m.key === currentKey);
|
118
|
+
if (match) {
|
119
|
+
const messageIndex = this.findEquivalentMessageIndex(match);
|
120
|
+
this.selectRow(match, { messageIndex });
|
36
121
|
} else {
|
37
|
-
this.
|
122
|
+
this.setProperties({
|
123
|
+
currentRow: null,
|
124
|
+
currentEnvPosition: 0,
|
125
|
+
currentGroupedMessagesPosition: 0
|
126
|
+
});
|
38
127
|
}
|
39
128
|
}
|
40
129
|
},
|
@@ -43,13 +132,12 @@ export default Em.Object.extend({
|
|
43
132
|
opts = opts || {};
|
44
133
|
|
45
134
|
const data = {
|
46
|
-
filter: this.
|
135
|
+
filter: this.filter.join("_")
|
47
136
|
};
|
48
137
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
const regexSearch = this.get("regexSearch");
|
138
|
+
if (!_.isEmpty(this.search)) {
|
139
|
+
data.search = this.search;
|
140
|
+
const regexSearch = this.regexSearch;
|
53
141
|
if (regexSearch) {
|
54
142
|
data.regex_search = "true";
|
55
143
|
}
|
@@ -57,6 +145,9 @@ export default Em.Object.extend({
|
|
57
145
|
|
58
146
|
if (opts.before) {
|
59
147
|
data.before = opts.before;
|
148
|
+
if (opts.knownGroups) {
|
149
|
+
data.known_groups = opts.knownGroups;
|
150
|
+
}
|
60
151
|
}
|
61
152
|
|
62
153
|
if (opts.after) {
|
@@ -70,32 +161,32 @@ export default Em.Object.extend({
|
|
70
161
|
.then(data => {
|
71
162
|
// guard against race: ensure the results we're trying to apply
|
72
163
|
// match the current search terms
|
73
|
-
if (compare(data.filter, this.
|
164
|
+
if (compare(data.filter, this.filter) != 0) {
|
74
165
|
return;
|
75
166
|
}
|
76
|
-
if (compare(data.search, this.
|
167
|
+
if (compare(data.search, this.search) != 0) {
|
77
168
|
return;
|
78
169
|
}
|
79
170
|
|
80
171
|
if (data.messages.length > 0) {
|
81
|
-
const newRows = this.
|
82
|
-
const
|
172
|
+
const newRows = this.toObjects(data.messages);
|
173
|
+
const rows = this.rows;
|
83
174
|
if (opts.before) {
|
84
|
-
|
175
|
+
rows.unshiftObjects(newRows);
|
85
176
|
} else {
|
86
|
-
newRows.forEach(
|
87
|
-
|
88
|
-
if (
|
89
|
-
|
90
|
-
if (this.
|
177
|
+
newRows.forEach(nrow => {
|
178
|
+
rows.forEach(erow => {
|
179
|
+
if (erow.key === nrow.key) {
|
180
|
+
rows.removeObject(erow);
|
181
|
+
if (this.currentRow === erow) {
|
91
182
|
// TODO would updateFromJson() work here?
|
92
|
-
this.
|
93
|
-
|
183
|
+
const messageIndex = this.findEquivalentMessageIndex(nrow);
|
184
|
+
this.selectRow(nrow, { messageIndex });
|
94
185
|
}
|
95
186
|
}
|
96
187
|
});
|
97
188
|
});
|
98
|
-
|
189
|
+
rows.addObjects(newRows);
|
99
190
|
if (newRows.length > 0) {
|
100
191
|
increaseTitleCount(newRows.length);
|
101
192
|
}
|
@@ -109,7 +200,7 @@ export default Em.Object.extend({
|
|
109
200
|
|
110
201
|
reload() {
|
111
202
|
this.set("total", 0);
|
112
|
-
this.
|
203
|
+
this.rows.clear();
|
113
204
|
|
114
205
|
return this.load().then(data => this.updateCanLoadMore(data));
|
115
206
|
},
|
@@ -126,43 +217,48 @@ export default Em.Object.extend({
|
|
126
217
|
},
|
127
218
|
|
128
219
|
loadMore() {
|
129
|
-
const
|
130
|
-
if (
|
220
|
+
const rows = this.rows;
|
221
|
+
if (rows.length === 0) {
|
131
222
|
this.load({});
|
132
223
|
return;
|
133
224
|
}
|
134
225
|
|
135
|
-
const
|
226
|
+
const lastLog = rows[rows.length - 1];
|
227
|
+
const lastKey = lastLog.group ? lastLog.row_id : lastLog.key;
|
136
228
|
this.load({
|
137
229
|
after: lastKey
|
138
230
|
});
|
139
231
|
},
|
140
232
|
|
141
233
|
hideCountInLoadMore: computed("search", "filter", function() {
|
142
|
-
const
|
143
|
-
|
144
|
-
|
234
|
+
const filter = this.filter;
|
235
|
+
return (
|
236
|
+
(this.search && this.search.length > 0) || (filter && filter.length < 6)
|
237
|
+
);
|
145
238
|
}),
|
146
239
|
|
147
|
-
moreBefore: computed("
|
148
|
-
return this.get("
|
240
|
+
moreBefore: computed("rows.length", "canLoadMore", function() {
|
241
|
+
return this.get("rows.length") >= BATCH_SIZE && this.canLoadMore;
|
149
242
|
}),
|
150
243
|
|
151
|
-
totalBefore: computed("total", "
|
152
|
-
return this.
|
244
|
+
totalBefore: computed("total", "rows.length", function() {
|
245
|
+
return this.total - this.rows.length;
|
153
246
|
}),
|
154
247
|
|
155
248
|
showMoreBefore: function() {
|
156
|
-
const
|
157
|
-
const
|
249
|
+
const rows = this.rows;
|
250
|
+
const firstLog = rows[0];
|
251
|
+
const firstKey = firstLog.group ? firstLog.row_id : firstLog.key;
|
252
|
+
const knownGroups = rows.filterBy("group").mapBy("regex");
|
158
253
|
|
159
254
|
this.load({
|
160
|
-
before: firstKey
|
255
|
+
before: firstKey,
|
256
|
+
knownGroups
|
161
257
|
}).then(data => this.updateCanLoadMore(data));
|
162
258
|
},
|
163
259
|
|
164
260
|
regexSearch: computed("search", function() {
|
165
|
-
const search = this.
|
261
|
+
const search = this.search;
|
166
262
|
if (search && search.length > 2 && search[0] === "/") {
|
167
263
|
const match = search.match(/\/(.*)\/(.*)/);
|
168
264
|
if (match && match.length === 3) {
|
@@ -175,7 +271,13 @@ export default Em.Object.extend({
|
|
175
271
|
}
|
176
272
|
}),
|
177
273
|
|
178
|
-
|
179
|
-
return
|
274
|
+
toObjects(rows) {
|
275
|
+
return rows.map(m => {
|
276
|
+
if (m.group) {
|
277
|
+
return Group.create(m);
|
278
|
+
} else {
|
279
|
+
return Message.create(m);
|
280
|
+
}
|
281
|
+
});
|
180
282
|
}
|
181
283
|
});
|