logster 2.4.0 → 2.4.1
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/README.md +2 -0
- data/assets/javascript/client-app.js +40 -38
- data/client-app/app/components/message-info.js +6 -0
- data/client-app/app/components/tabbed-section.js +1 -0
- data/client-app/app/controllers/index.js +40 -4
- data/client-app/app/models/message-collection.js +35 -32
- data/client-app/app/routes/index.js +3 -0
- data/client-app/app/templates/components/message-info.hbs +9 -5
- data/client-app/app/templates/index.hbs +2 -0
- data/lib/logster/base_store.rb +2 -3
- data/lib/logster/configuration.rb +3 -1
- data/lib/logster/message.rb +24 -2
- data/lib/logster/middleware/viewer.rb +10 -0
- data/lib/logster/redis_store.rb +30 -10
- data/lib/logster/version.rb +1 -1
- data/test/logster/middleware/test_viewer.rb +40 -0
- data/test/logster/test_message.rb +24 -0
- data/test/logster/test_redis_store.rb +15 -0
- 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: 32d46ec6061a8b58d50146ab27c3185f3964680207f0a6ad783ad3122aa44d2a
|
4
|
+
data.tar.gz: abf94ecdefb382f60606e0d94cffa9dae77a64eda8f124f7a1c6c9295be688bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0a40b769c195f36fa14bc856efe6490653113b57f65b0b07875a648d1ffaa98f26343cbed2f6d688402ef83c63b2ad142e8d81624f25f043f4d0f84be0d8f30
|
7
|
+
data.tar.gz: 428f7b1e3577f16c65752ddeca5f8004858f204e97fdba496816df532308201fdd415e8edf2b081bcb3090dd3bc0f2cd59f6778561af3b5a16f6f4d6163320d1
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
- 2019-10-17: 2.4.1
|
4
|
+
|
5
|
+
- PERF: Debounce search field so it doesn't fire a search query at every keystroke.
|
6
|
+
- PERF: Disallow search terms that are fewer than 2 characters long.
|
7
|
+
- PERF: Bypass refresh cycle if previous cycle hasn't finished.
|
8
|
+
- PERF: Defer sending message envs to client until the user requests them.
|
9
|
+
- PERF: Cap message size to 60,000 bytes by default.
|
10
|
+
|
3
11
|
- 2019-10-10: 2.4.0
|
4
12
|
|
5
13
|
- FEATURE: Allow having retroactive affect when adding suppression patterns
|
data/README.md
CHANGED
@@ -43,6 +43,8 @@ Logster can be configured using `Logster.config`:
|
|
43
43
|
- `Logster.config.enable_js_error_reporting` : enable js error reporting from clients
|
44
44
|
- `Logster.config.rate_limit_error_reporting` : controls automatic 1 minute rate limiting for JS error reporting.
|
45
45
|
- `Logster.config.web_title` : `<title>` tag for logster error page.
|
46
|
+
- `Logster.config.enable_custom_patterns_via_ui` : enables a setting page that allows adding suppression patterns via the UI.
|
47
|
+
- `Logster.config.maximum_message_size_bytes` : specifiy a size in bytes that a message cannot exceed. Note this isn't 100% accurate, meaning a message may still grow above the limit, but it shouldn't grow by more tha, say, 2000 bytes.
|
46
48
|
|
47
49
|
### Tracking Error Rate
|
48
50
|
Logster allows you to register a callback when the rate of errors has exceeded
|
@@ -1,8 +1,8 @@
|
|
1
1
|
"use strict"
|
2
2
|
define("client-app/app",["exports","client-app/resolver","ember-load-initializers","client-app/config/environment"],function(e,t,n,a){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
3
3
|
var s=Ember.Application.extend({modulePrefix:a.default.modulePrefix,podModulePrefix:a.default.podModulePrefix,Resolver:t.default});(0,n.default)(s,a.default.modulePrefix)
|
4
|
-
var
|
5
|
-
e.default=
|
4
|
+
var i=s
|
5
|
+
e.default=i}),define("client-app/components/actions-menu",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
6
6
|
var t=Ember.Component.extend({showMenu:!1,tagName:"span",init:function(){this._super.apply(this,arguments),this.bindingFunction=this.bindingFunction.bind(this)},bindingFunction:function(e){var t=this.$()[0]
|
7
7
|
Em.$.contains(t,e.target)||t===e.target||this.set("showMenu",!1)},bindDocument:Ember.observer("showMenu",function(){var e=Em.$(document)
|
8
8
|
this.get("showMenu")?e.on("click",this.get("bindingFunction")):e.off("click",this.get("bindingFunction"))}),willDestroyElement:function(){this._super.apply(this,arguments),Em.$(document).off("click",this.get("bindingFunction"))},actions:{expandMenu:function(){this.toggleProperty("showMenu")},share:function(){this.share()}}})
|
@@ -15,20 +15,20 @@ this.set("current",this.get("current")+t)},bigJump:function(e){var t="back"===e?
|
|
15
15
|
this.set("current",t)}}})
|
16
16
|
e.default=a}),define("client-app/components/message-info",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
17
17
|
var t=Ember.Component.extend({buttons:Ember.computed("currentMessage.{canSolve,protected}",function(){var e=this.get("currentMessage.canSolve"),t=this.get("currentMessage.protected"),n=[]
|
18
|
-
return!t&&e&&n.push({klass:"solve",action:"solve",icon:"check-square-o",label:"Solve",danger:!0}),t?n.push({klass:"unprotect",action:"unprotect",icon:"unlock",label:"Unprotect"}):n.push({klass:"remove",action:"remove",icon:"trash-o",label:"Remove",danger:!0},{klass:"protect",action:"protect",icon:"lock",label:"Protect"}),n}),actions:{protect:function(){this.get("currentMessage").protect()},unprotect:function(){this.get("currentMessage").unprotect()},remove:function(){this.removeMessage(this.get("currentMessage"))},solve:function(){this.solveMessage(this.get("currentMessage"))},share:function(){window.location.pathname=this.get("currentMessage.shareUrl")}}})
|
18
|
+
return!t&&e&&n.push({klass:"solve",action:"solve",icon:"check-square-o",label:"Solve",danger:!0}),t?n.push({klass:"unprotect",action:"unprotect",icon:"unlock",label:"Unprotect"}):n.push({klass:"remove",action:"remove",icon:"trash-o",label:"Remove",danger:!0},{klass:"protect",action:"protect",icon:"lock",label:"Protect"}),n}),actions:{tabChanged:function(e){this.onTabChange&&this.onTabChange(e)},protect:function(){this.get("currentMessage").protect()},unprotect:function(){this.get("currentMessage").unprotect()},remove:function(){this.removeMessage(this.get("currentMessage"))},solve:function(){this.solveMessage(this.get("currentMessage"))},share:function(){window.location.pathname=this.get("currentMessage.shareUrl")}}})
|
19
19
|
e.default=t}),define("client-app/components/message-row",["exports"],function(e){var t,n
|
20
20
|
Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
21
|
-
var a=Ember.Component.extend({tagName:"div",classNameBindings:["model.rowClass",":message-row","model.selected:selected"],click:function(){this.selectedMessage(this.get("model"))},willInsertElement:function(){if(!t){var e=Em.$("#top-panel"),a=e.scrollTop(),s=e.height(),
|
22
|
-
n=
|
21
|
+
var a=Ember.Component.extend({tagName:"div",classNameBindings:["model.rowClass",":message-row","model.selected:selected"],click:function(){this.selectedMessage(this.get("model"))},willInsertElement:function(){if(!t){var e=Em.$("#top-panel"),a=e.scrollTop(),s=e.height(),i=e[0].scrollHeight
|
22
|
+
n=i-20<s+a,t=!0}},didInsertElement:function(){var e=Em.$("#top-panel")
|
23
23
|
Em.run.next(function(){t=!1,n&&(n=!1,e.scrollTop(e[0].scrollHeight-e.height()))})}})
|
24
24
|
e.default=a}),define("client-app/components/panel-resizer",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
25
25
|
var t=["touchmove","mousemove"],n=["touchend","mouseup"],a=["touchstart","mousedown"],s=Ember.Component.extend({classNames:["divider"],divideView:function(e,t){var n=t||Em.$(window),a=n.height(),s=n.height()-e
|
26
26
|
e<100||e+170>a||(this.divider.css("bottom",s-5),this.events.trigger("panelResized",s))},didInsertElement:function(){var e=this
|
27
27
|
this.divider=Em.$(".divider")
|
28
|
-
var s=Em.$(window),
|
28
|
+
var s=Em.$(window),i=!1,r=function(t){i&&e.divideView(t.clientY||t.touches&&t.touches[0]&&t.touches[0].clientY,s)},o=function a(){Em.$("#overlay").remove(),i=!1,localStorage&&(localStorage.logster_divider_bottom=parseInt(e.divider.css("bottom"),10))
|
29
29
|
var s=Em.$(document)
|
30
|
-
t.forEach(function(e){return s.unbind(e,
|
31
|
-
this.divider.on(a.join(" "),function(e){e.preventDefault(),Em.$("<div id='overlay'></div>").appendTo(Em.$("body")),
|
30
|
+
t.forEach(function(e){return s.unbind(e,r)}),n.forEach(function(e){return s.unbind(e,a)})}
|
31
|
+
this.divider.on(a.join(" "),function(e){e.preventDefault(),Em.$("<div id='overlay'></div>").appendTo(Em.$("body")),i=!0,Em.$(document).on(t.join(" "),_.throttle(r,25)).on(n.join(" "),o)}),Em.run.next(function(){var t=localStorage&&localStorage.logster_divider_bottom||300,n=s.height()-parseInt(t,10)
|
32
32
|
e.divideView(n,s)})},willDestroyElement:function(){Em.$(".divider").off(a.join(" "))}})
|
33
33
|
e.default=s}),define("client-app/components/patterns-list",["exports","@babel/runtime/helpers/esm/toConsumableArray","client-app/models/pattern-item","client-app/lib/utilities"],function(e,t,n,a){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
34
34
|
var s=Ember.Component.extend({immutable:Ember.computed.not("mutable"),init:function(){this._super.apply(this,arguments),this.get("patterns.length")<1&&this.get("mutable")&&this.send("create")},allPatterns:Ember.computed("patterns.[]","newPatterns.[]",function(){var e=this.get("patterns"),n=this.get("newPatterns")||[]
|
@@ -43,25 +43,27 @@ t&&t[e](this)},didInsertElement:function(){this.invokeParent("addTab"),this.get(
|
|
43
43
|
e.default=t}),define("client-app/components/tabbed-section",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
44
44
|
var t=Ember.Component.extend({tabs:Em.A(),selectTab:function(e){if(e.get("isLink"))this.triggerAction(e.get("action"))
|
45
45
|
else{var t=this.get("selected")
|
46
|
-
t&&t.set("active",!1),this.set("selected",e),e.set("active",!0)}},addTab:function(e){this.get("tabs").addObject(e),this.get("selected")||e.get("isLink")||this.selectTab(e)},removeTab:function(e){this.get("selected")===e&&this.set("selected",null),this.get("tabs").removeObject(e)}})
|
46
|
+
t&&t.set("active",!1),this.set("selected",e),e.set("active",!0),this.onTabChange(e.name)}},addTab:function(e){this.get("tabs").addObject(e),this.get("selected")||e.get("isLink")||this.selectTab(e)},removeTab:function(e){this.get("selected")===e&&this.set("selected",null),this.get("tabs").removeObject(e)}})
|
47
47
|
e.default=t}),define("client-app/components/time-formatter",["exports","client-app/lib/utilities"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
48
48
|
var n=Ember.Component.extend({tagName:"span",classNames:"auto-update-time",attributeBindings:["dataTimestamp:data-timestamp","title"],title:Ember.computed(function(){return this.get("moment").format()}),dataTimestamp:Ember.computed(function(){return this.get("timestamp")}),moment:Ember.computed(function(){return moment(this.get("timestamp"))}),time:Ember.computed("timestamp",function(){return(0,t.formatTime)(this.get("timestamp"))})})
|
49
49
|
e.default=n}),define("client-app/components/update-time",["exports","client-app/lib/utilities"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
50
50
|
var n=Ember.Component.extend({didInsertElement:function(){Em.run.later(function e(){Em.$(".auto-update-time").each(function(){var e=parseInt(this.getAttribute("data-timestamp"),10),n=(0,t.formatTime)(e)
|
51
51
|
n!==this.innerText&&(this.innerText=n)}),Em.run.later(e,6e4)},6e4)}})
|
52
52
|
e.default=n}),define("client-app/controllers/index",["exports","client-app/lib/utilities","client-app/lib/preload"],function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
53
|
-
var a=Ember.Controller.extend({showDebug:!0,showInfo:!0,showWarn:!0,showErr:!0,showFatal:!0,search:"",currentMessage:Em.computed.alias("model.currentMessage"),showSettings:Ember.computed(function(){return n.default.get("patterns_enabled")}),resizePanels:function(e){Em.$("#bottom-panel").css("height",e-13),Em.$("#top-panel").css("bottom",e+12)},actionsInMenu:Ember.computed(function(){return this.site.isMobile}),
|
54
|
-
|
53
|
+
var a=Ember.Controller.extend({showDebug:!0,showInfo:!0,showWarn:!0,showErr:!0,showFatal:!0,search:"",currentMessage:Em.computed.alias("model.currentMessage"),currentTab:null,showSettings:Ember.computed(function(){return n.default.get("patterns_enabled")}),resizePanels:function(e){Em.$("#bottom-panel").css("height",e-13),Em.$("#top-panel").css("bottom",e+12)},actionsInMenu:Ember.computed(function(){return this.site.isMobile}),fetchEnv:function(){var e=this,n=this.get("currentMessage")
|
54
|
+
if(n)return this.set("loadingEnv",!0),(0,t.ajax)("/fetch-env/".concat(n.key,".json")).then(function(e){return n.set("env",e)}).always(function(){return e.set("loadingEnv",!1)})},actions:{expandMessage:function(e){e.expand()},selectMessage:function(e){var t=this.get("currentMessage")
|
55
|
+
t&&t.set("selected",!1),e.set("selected",!0),this.setProperties({currentMessage:e,loadingEnv:!1}),e.env||"env"!==this.currentTab||this.fetchEnv()},tabChanged:function(e){this.setProperties({currentTab:e,loadingEnv:!1}),"env"!==e||this.get("currentMessage.env")||this.fetchEnv()},showMoreBefore:function(){this.get("model").showMoreBefore()},loadMore:function(){return this.get("model").loadMore()},clear:function(){var e=this
|
55
56
|
confirm("Clear the logs?\n\nCancel = No, OK = Clear")&&(0,t.ajax)("/clear",{type:"POST"}).then(function(){e.get("model").reload()})},removeMessage:function(e){this.get("model").destroy(e)},solveMessage:function(e){this.get("model").solve(e)}},updateSelectedMessage:function(){var e=this.get("currentMessage.key"),t=this.get("model.messages")
|
56
57
|
if(e&&t){var n=t.find(function(t){return t.key===e})
|
57
58
|
n?n.set("selected",!0):this.set("currentMessage",null)}},filter:Ember.computed("showDebug","showInfo","showWarn","showErr","showFatal",function(){var e=this,t=[]
|
58
59
|
return["Debug","Info","Warn","Err","Fatal"].forEach(function(n,a){e.get("show".concat(n))&&t.push(a)}),t.push(5),t}),filterChanged:Ember.observer("filter.length",function(){var e=this,t=this.get("filter"),n=this.get("model")
|
59
|
-
n.set("filter",t),t&&this.get("initialized")&&n.reload().then(function(){return e.updateSelectedMessage()})}),
|
60
|
-
n.set("search",
|
60
|
+
n.set("filter",t),t&&this.get("initialized")&&n.reload().then(function(){return e.updateSelectedMessage()})}),doSearch:function(e){var t=this,n=this.get("model")
|
61
|
+
n.set("search",e),this.get("initialized")&&n.reload().then(function(){return t.updateSelectedMessage()})},searchChanged:Ember.observer("search",function(){var e=this.search,t=e&&e.length
|
62
|
+
t&&1===t||Ember.run.debounce(this,this.doSearch,e,250)})})
|
61
63
|
e.default=a}),define("client-app/controllers/show",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
62
64
|
var t=Ember.Controller.extend({actions:{protect:function(){this.get("model").protect()},unprotect:function(){this.get("model").unprotect()}}})
|
63
|
-
e.default=t}),define("client-app/helpers/app-version",["exports","client-app/config/environment","ember-cli-app-version/utils/regexp"],function(e,t,n){function a(e){var a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},s=t.default.APP.version,
|
64
|
-
return
|
65
|
+
e.default=t}),define("client-app/helpers/app-version",["exports","client-app/config/environment","ember-cli-app-version/utils/regexp"],function(e,t,n){function a(e){var a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},s=t.default.APP.version,i=a.versionOnly||a.hideSha,r=a.shaOnly||a.hideVersion,o=null
|
66
|
+
return i&&(a.showExtended&&(o=s.match(n.versionExtendedRegExp)),o||(o=s.match(n.versionRegExp))),r&&(o=s.match(n.shaRegExp)),o?o[0]:s}Object.defineProperty(e,"__esModule",{value:!0}),e.appVersion=a,e.default=void 0
|
65
67
|
var s=Ember.Helper.helper(a)
|
66
68
|
e.default=s}),define("client-app/helpers/logster-url",["exports","client-app/lib/preload"],function(e,t){function n(e){var n=e[0]
|
67
69
|
return"/"!==n[0]&&(n="/".concat(n)),t.default.get("rootPath")+n}Object.defineProperty(e,"__esModule",{value:!0}),e.logsterUrl=n,e.default=void 0
|
@@ -77,12 +79,12 @@ var n=["component","route"]
|
|
77
79
|
function a(e){var a,s
|
78
80
|
moment.updateLocale("en",{relativeTime:{future:"in %s",past:"%s ago",s:"secs",m:"a min",mm:"%d mins",h:"an hr",hh:"%d hrs",d:"a day",dd:"%d days",M:"a mth",MM:"%d mths",y:"a yr",yy:"%d yrs"}}),["","webkit","ms","moz","ms"].forEach(function(e){var t=e+(""===e?"hidden":"Hidden")
|
79
81
|
void 0===document[t]||a||(a=t,s=e+"visibilitychange")}),(0,t.updateHiddenProperty)(a),document.addEventListener(s,function(){(0,t.resetTitleCount)()},!1),e.register("events:main",Ember.Object.extend(Ember.Evented).create(),{instantiate:!1}),n.forEach(function(t){return e.inject(t,"events","events:main")})
|
80
|
-
var
|
81
|
-
|
82
|
+
var i=/mobile/i.test(navigator.userAgent)&&!/iPad/.test(navigator.userAgent)
|
83
|
+
i&&Em.$("body").addClass("mobile"),e.register("site:main",{isMobile:i},{instantiate:!1}),e.inject("controller","site","site:main")}var s={initialize:a}
|
82
84
|
e.default=s}),define("client-app/initializers/app-version",["exports","ember-cli-app-version/initializer-factory","client-app/config/environment"],function(e,t,n){var a,s
|
83
85
|
Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0,n.default.APP&&(a=n.default.APP.name,s=n.default.APP.version)
|
84
|
-
var
|
85
|
-
e.default=
|
86
|
+
var i={name:"App Version",initialize:(0,t.default)(a,s)}
|
87
|
+
e.default=i}),define("client-app/initializers/container-debug-adapter",["exports","ember-resolver/resolvers/classic/container-debug-adapter"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
86
88
|
var n={name:"container-debug-adapter",initialize:function(){var e=arguments[1]||arguments[0]
|
87
89
|
e.register("container-debug-adapter:main",t.default),e.inject("container-debug-adapter:main","namespace","application:main")}}
|
88
90
|
e.default=n}),define("client-app/initializers/ember-data",["exports","ember-data/setup-container","ember-data"],function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
@@ -104,22 +106,22 @@ function a(){var e=document.getElementById("preloaded-data").dataset
|
|
104
106
|
t=Em.$.extend(JSON.parse(e.preloaded),{rootPath:e.rootPath}),n=!0}var s={get:function(e){return n||a(),Em.get(t,e)}}
|
105
107
|
e.default=s}),define("client-app/lib/utilities",["exports","@babel/runtime/helpers/esm/typeof","client-app/lib/preload"],function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.escapeHtml=o,e.ajax=l,e.preloadOrAjax=function(e,t){var a=n.default.get(e.replace(".json",""))
|
106
108
|
return a?Em.RSVP.resolve(a):l(e,t)},e.updateHiddenProperty=function(e){a=e},e.isHidden=c,e.increaseTitleCount=function(e){if(!c())return
|
107
|
-
s=s||document.title,
|
109
|
+
s=s||document.title,i=i||0,i+=e,document.title="".concat(s," (").concat(i,")")},e.resetTitleCount=function(){i=0,document.title=s||document.title},e.formatTime=u,e.buildArrayString=d,e.buildHashString=function e(a,s){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[]
|
108
110
|
if(!a)return""
|
109
|
-
var
|
111
|
+
var r=[]
|
110
112
|
var l=[]
|
111
113
|
var c=n.default.get("env_expandable_keys")||[]
|
112
|
-
_.each(a,function(e,n){if(null===e)
|
114
|
+
_.each(a,function(e,n){if(null===e)r.push("null")
|
113
115
|
else if("[object Array]"===Object.prototype.toString.call(e)){var a=""
|
114
|
-
a=-1!==c.indexOf(n)&&!s&&-1===
|
116
|
+
a=-1!==c.indexOf(n)&&!s&&-1===i.indexOf(n)&&e.length>3?"".concat(o(e[0]),', <a class="expand-list" data-key=').concat(n,">").concat(e.length-1," more</a>"):d(e),r.push("<tr><td>"+o(n)+"</td><td>"+a+"</td></tr>")}else if("object"===(0,t.default)(e))l.push(n)
|
115
117
|
else if("time"===n&&"number"==typeof e){var p=moment(e).format(),f=u(e)
|
116
|
-
|
118
|
+
r.push('<tr title="'.concat(p,'"><td>').concat(n,"</td><td>").concat(f,"</td></tr>"))}else r.push("<tr><td>".concat(o(n),"</td><td>").concat(o(e),"</td></tr>"))})
|
117
119
|
_.size(l)>0&&_.each(l,function(t){var n=a[t]
|
118
|
-
|
120
|
+
r.push("<tr><td></td><td><table>"),r.push("<td>"+o(t)+"</td><td>"+e(n,!0)+"</td>"),r.push("</table></td></tr>")})
|
119
121
|
var p=s?"":"env-table"
|
120
|
-
return"<table class='"+p+"'>"+
|
121
|
-
var a,s,r
|
122
|
-
function o(e){return String(e).replace(/[&<>"'\/]/g,function(e){return
|
122
|
+
return"<table class='"+p+"'>"+r.join("\n")+"</table>"}
|
123
|
+
var a,s,i,r={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}
|
124
|
+
function o(e){return String(e).replace(/[&<>"'\/]/g,function(e){return r[e]})}function l(e,t){return(t=t||{}).headers=t.headers||{},t.headers["X-SILENCE-LOGGER"]=!0,Em.$.ajax(n.default.get("rootPath")+e,t)}function c(){return void 0!==a?document[a]:!document.hasFocus}function u(e){var t=moment(e),n=moment()
|
123
125
|
return t.diff(n.startOf("day"))>0?t.format("h:mm a"):t.diff(n.startOf("week"))>0?t.format("dd h:mm a"):t.diff(n.startOf("year"))>0?t.format("D MMM h:mm a"):t.format("D MMM YY")}function d(e){var t=[]
|
124
126
|
return e.forEach(function(e){null===e?t.push("null"):"[object Array]"===Object.prototype.toString.call(e)?t.push(d(e)):t.push(o(e.toString()))}),"["+t.join(", ")+"]"}}),define("client-app/models/message-collection",["exports","client-app/lib/utilities","client-app/models/message"],function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
125
127
|
var a=Em.Object.extend({messages:Em.A(),currentMessage:null,total:0,solve:function(e){var t=this
|
@@ -128,8 +130,8 @@ e.destroy(),e.set("selected",!1),this.set("total",this.get("total")-1),this.get(
|
|
128
130
|
e=e||{}
|
129
131
|
var a={filter:this.get("filter").join("_")},s=this.get("search")
|
130
132
|
_.isEmpty(s)||(a.search=s,this.get("regexSearch")&&(a.regex_search="true"))
|
131
|
-
return e.before&&(a.before=e.before),e.after&&(a.after=e.after),(0,t.ajax)("/messages.json",{data:a}).then(function(a){if(0==Ember.compare(a.filter,n.get("filter"))&&0==Ember.compare(a.search,n.get("search"))){if(a.messages.length>0){var s=n.toMessages(a.messages),
|
132
|
-
e.before?
|
133
|
+
return e.before&&(a.before=e.before),e.after&&(a.after=e.after),this.set("loading",!0),(0,t.ajax)("/messages.json",{data:a}).then(function(a){if(0==Ember.compare(a.filter,n.get("filter"))&&0==Ember.compare(a.search,n.get("search"))){if(a.messages.length>0){var s=n.toMessages(a.messages),i=n.get("messages")
|
134
|
+
e.before?i.unshiftObjects(s):(s.forEach(function(e){i.forEach(function(t){t.key==e.key&&(i.removeObject(t),n.get("currentMessage")===t&&(n.set("currentMessage",e),e.set("selected",t.get("selected"))))})}),i.addObjects(s),s.length>0&&(0,t.increaseTitleCount)(s.length))}return n.set("total",a.total),a}}).always(function(){return n.set("loading",!1)})},reload:function(){var e=this
|
133
135
|
return this.set("total",0),this.get("messages").clear(),this.load().then(function(t){return e.updateCanLoadMore(t)})},updateCanLoadMore:function(e){e&&(e.messages.length<50?this.set("canLoadMore",!1):this.set("canLoadMore",!0))},loadMore:function(){var e=this.get("messages")
|
134
136
|
if(0!==e.length){var t=e[e.length-1].get("key")
|
135
137
|
this.load({after:t})}else this.load({})},hideCountInLoadMore:Ember.computed("search","filter",function(){var e=this.get("search"),t=this.get("filter")
|
@@ -161,13 +163,13 @@ var a=n
|
|
161
163
|
e.default=a}),define("client-app/routes/index",["exports","client-app/models/message-collection","client-app/lib/utilities"],function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
162
164
|
var a=Ember.Route.extend({model:function(){return t.default.create()},setupController:function(e,t){this._super(e,t),t.setProperties(e.getProperties("filter","search")),t.reload(),e.set("initialized",!0)
|
163
165
|
var a=0,s=1
|
164
|
-
this.refreshInterval=setInterval(function(){a+=1
|
165
|
-
var e=(0,n.isHidden)(),
|
166
|
-
e&&a%s==0&&(
|
166
|
+
this.refreshInterval=setInterval(function(){if(!t.loading){a+=1
|
167
|
+
var e=(0,n.isHidden)(),i=!e
|
168
|
+
e&&a%s==0&&(i=!0,s<20&&s++),i&&(t.loadMore(),e||(s=1))}},3e3),this.events.on("panelResized",function(t){e.resizePanels(t)})},deactivate:function(){clearInterval(this.refreshInterval)}})
|
167
169
|
e.default=a}),define("client-app/routes/settings",["exports","client-app/lib/utilities","client-app/models/pattern-item"],function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
168
170
|
var a=Ember.Route.extend({model:function(){return(0,t.ajax)("/settings.json")},setupController:function(e,t){this._super.apply(this,arguments)
|
169
|
-
var a=t.suppression,s=a.filter(function(e){return e.hard}).map(function(e){return n.default.create(e)}),
|
170
|
-
e.setProperties({showCodedSuppression:
|
171
|
+
var a=t.suppression,s=a.filter(function(e){return e.hard}).map(function(e){return n.default.create(e)}),i=a.reject(function(e){return e.hard}).map(function(e){return n.default.create(e)}),r=s.length>0
|
172
|
+
e.setProperties({showCodedSuppression:r,codedSuppression:s,customSuppression:i})}})
|
171
173
|
e.default=a}),define("client-app/routes/show",["exports","client-app/models/message","client-app/lib/utilities"],function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
172
174
|
var a=Ember.Route.extend({model:function(e){return(0,n.preloadOrAjax)("/show/"+e.id+".json")},setupController:function(e,n){this._super.apply(this,arguments),e.set("model",t.default.create(n))}})
|
173
175
|
e.default=a}),define("client-app/services/ajax",["exports","ember-ajax/services/ajax"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})}),define("client-app/templates/application",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
@@ -177,7 +179,7 @@ var t=Ember.HTMLBars.template({id:"iO5WYaED",block:'{"symbols":["&default"],"sta
|
|
177
179
|
e.default=t}),define("client-app/templates/components/env-tab",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
178
180
|
var t=Ember.HTMLBars.template({id:"X1VwEK8H",block:'{"symbols":[],"statements":[[4,"if",[[23,["isEnvArray"]]],null,{"statements":[[0," "],[7,"div"],[11,"class","nav-controls"],[9],[0,"\\n "],[7,"button"],[12,"disabled",[21,"disableBackButtons"]],[11,"class","btn nav-btn no-text"],[9],[7,"i"],[11,"class","fa fa-fast-backward"],[9],[10],[3,"action",[[22,0,[]],"bigJump","back"]],[10],[0,"\\n "],[7,"button"],[12,"disabled",[21,"disableBackButtons"]],[11,"class","btn nav-btn no-text"],[9],[7,"i"],[11,"class","fa fa-backward"],[9],[10],[3,"action",[[22,0,[]],"takeStep","back"]],[10],[0,"\\n "],[7,"span"],[11,"class","env-number"],[9],[1,[21,"current"],false],[0,"/"],[1,[23,["message","env","length"]],false],[10],[0,"\\n "],[7,"button"],[12,"disabled",[21,"disableForwardButtons"]],[11,"class","btn nav-btn no-text"],[9],[7,"i"],[11,"class","fa fa-forward"],[9],[10],[3,"action",[[22,0,[]],"takeStep","front"]],[10],[0,"\\n "],[7,"button"],[12,"disabled",[21,"disableForwardButtons"]],[11,"class","btn nav-btn no-text"],[9],[7,"i"],[11,"class","fa fa-fast-forward"],[9],[10],[3,"action",[[22,0,[]],"bigJump","front"]],[10],[0,"\\n "],[10],[0,"\\n"]],"parameters":[]},null],[1,[21,"html"],true],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"client-app/templates/components/env-tab.hbs"}})
|
179
181
|
e.default=t}),define("client-app/templates/components/message-info",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
180
|
-
var t=Ember.HTMLBars.template({id:"
|
182
|
+
var t=Ember.HTMLBars.template({id:"gPjmElUI",block:'{"symbols":["btn"],"statements":[[7,"div"],[11,"class","message-info"],[9],[0,"\\n"],[4,"tabbed-section",null,[["onTabChange"],[[27,"action",[[22,0,[]],"tabChanged"],null]]],{"statements":[[4,"tab-contents",null,[["name","hint","currentMessage"],["info","show info",[23,["currentMessage"]]]],{"statements":[[4,"if",[[23,["showTitle"]]],null,{"statements":[[0," "],[7,"h3"],[9],[0,"Message\\n"],[4,"if",[[23,["currentMessage","showCount"]]],null,{"statements":[[0," ("],[1,[23,["currentMessage","count"]],false],[0," copies reported)\\n"]],"parameters":[]},null],[0," "],[10],[0,"\\n"]],"parameters":[]},null],[0," "],[7,"pre"],[9],[1,[23,["currentMessage","message"]],false],[10],[0,""]],"parameters":[]},null],[4,"tab-contents",null,[["name","defaultTab","hint","currentMessage"],["backtrace","true","show backtrace",[23,["currentMessage"]]]],{"statements":[[4,"if",[[23,["showTitle"]]],null,{"statements":[[0," "],[7,"h3"],[9],[0,"Backtrace"],[10],[0,"\\n"]],"parameters":[]},null],[0," "],[7,"pre"],[9],[1,[23,["currentMessage","backtrace"]],false],[10],[0,""]],"parameters":[]},null],[4,"tab-contents",null,[["className","name","hint","currentMessage"],["env","env","show environment",[23,["currentMessage"]]]],{"statements":[[4,"if",[[23,["currentMessage","env"]]],null,{"statements":[[4,"if",[[23,["showTitle"]]],null,{"statements":[[0," "],[7,"h3"],[9],[0,"Env"],[10],[0,"\\n"]],"parameters":[]},null],[0," "],[1,[27,"env-tab",null,[["message"],[[23,["currentMessage"]]]]],false],[0,"\\n"]],"parameters":[]},{"statements":[[4,"if",[[23,["loadingEnv"]]],null,{"statements":[[0," Loading env...\\n"]],"parameters":[]},{"statements":[[0," No env for this message.\\n "]],"parameters":[]}]],"parameters":[]}]],"parameters":[]},null]],"parameters":[]},null],[0,"\\n"],[4,"if",[[23,["currentMessage"]]],null,{"statements":[[0," "],[7,"div"],[11,"class","message-actions"],[9],[0,"\\n"],[4,"actions-menu",null,[["actionsInMenu","share"],[[23,["actionsInMenu"]],[27,"action",[[22,0,[]],"share"],null]]],{"statements":[[4,"each",[[23,["buttons"]]],null,{"statements":[[0," "],[7,"button"],[12,"class",[28,[[22,1,["klass"]]," btn ",[27,"if",[[22,1,["danger"]],"danger",""],null]]]],[9],[0,"\\n "],[7,"i"],[12,"class",[28,["fa fa-",[22,1,["icon"]]]]],[9],[10],[0,"\\n "],[7,"span"],[9],[1,[22,1,["label"]],false],[10],[0,"\\n "],[3,"action",[[22,0,[]],[22,1,["action"]]]],[10],[0,"\\n"]],"parameters":[1]},null]],"parameters":[]},null],[0," "],[10],[0,"\\n"]],"parameters":[]},null],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"client-app/templates/components/message-info.hbs"}})
|
181
183
|
e.default=t}),define("client-app/templates/components/message-row",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
182
184
|
var t=Ember.HTMLBars.template({id:"pF0hQ9a+",block:'{"symbols":[],"statements":[[7,"div"],[11,"class","count"],[9],[0,"\\n"],[4,"if",[[23,["model","showCount"]]],null,{"statements":[[0," "],[1,[23,["model","count"]],false],[0,"\\n"]],"parameters":[]},null],[10],[0,"\\n"],[7,"div"],[11,"class","severity"],[9],[1,[23,["model","glyph"]],true],[10],[0,"\\n"],[7,"div"],[11,"class","message-body"],[9],[0,"\\n "],[1,[23,["model","displayMessage"]],false],[0,"\\n"],[10],[0,"\\n"],[7,"div"],[11,"class","protected"],[9],[0,"\\n"],[4,"if",[[23,["model","protected"]]],null,{"statements":[[0," "],[7,"i"],[11,"title","message is protected, clearing will not remove it"],[11,"class","fa fa-lock"],[9],[10],[0,"\\n"]],"parameters":[]},null],[10],[0,"\\n"],[7,"div"],[11,"class","time"],[9],[1,[27,"time-formatter",null,[["timestamp"],[[23,["model","timestamp"]]]]],false],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"client-app/templates/components/message-row.hbs"}})
|
183
185
|
e.default=t}),define("client-app/templates/components/panel-resizer",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
@@ -189,10 +191,10 @@ var t=Ember.HTMLBars.template({id:"zCP0V00P",block:'{"symbols":["tab","&default"
|
|
189
191
|
e.default=t}),define("client-app/templates/components/time-formatter",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
190
192
|
var t=Ember.HTMLBars.template({id:"sp53cTcH",block:'{"symbols":[],"statements":[[1,[21,"time"],false],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"client-app/templates/components/time-formatter.hbs"}})
|
191
193
|
e.default=t}),define("client-app/templates/index",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
192
|
-
var t=Ember.HTMLBars.template({id:"
|
194
|
+
var t=Ember.HTMLBars.template({id:"2nOvOGVv",block:'{"symbols":["message"],"statements":[[7,"div"],[11,"id","top-panel"],[9],[0,"\\n "],[7,"div"],[11,"id","log-table"],[9],[0,"\\n"],[4,"if",[[23,["model","moreBefore"]]],null,{"statements":[[0," "],[7,"div"],[11,"class","show-more"],[9],[0,"\\n"],[4,"if",[[23,["model","hideCountInLoadMore"]]],null,{"statements":[[0," Load more\\n"]],"parameters":[]},{"statements":[[0," Select to see "],[1,[23,["model","totalBefore"]],false],[0," more\\n"]],"parameters":[]}],[0," "],[3,"action",[[22,0,[]],"showMoreBefore"]],[10],[0,"\\n"]],"parameters":[]},null],[4,"each",[[23,["model","messages"]]],null,{"statements":[[0," "],[1,[27,"message-row",null,[["model","selectedMessage"],[[22,1,[]],[27,"action",[[22,0,[]],"selectMessage"],null]]]],false],[0,"\\n"]],"parameters":[1]},null],[0," "],[10],[0,"\\n"],[10],[0,"\\n"],[7,"div"],[11,"id","bottom-panel"],[9],[0,"\\n "],[1,[27,"message-info",null,[["currentMessage","loadingEnv","removeMessage","solveMessage","onTabChange","actionsInMenu"],[[23,["currentMessage"]],[23,["loadingEnv"]],[27,"action",[[22,0,[]],"removeMessage"],null],[27,"action",[[22,0,[]],"solveMessage"],null],[27,"action",[[22,0,[]],"tabChanged"],null],[23,["actionsInMenu"]]]]],false],[0,"\\n\\n "],[7,"div"],[11,"class","action-panel"],[9],[0,"\\n "],[7,"div"],[11,"class","severity-filters"],[9],[0,"\\n "],[7,"div"],[11,"class","more-wrapping"],[9],[0,"\\n "],[7,"label"],[11,"class","debug"],[9],[0,"\\n "],[1,[27,"input",null,[["type","checked"],["checkbox",[23,["showDebug"]]]]],false],[0,"\\n "],[7,"span"],[9],[0,"Debug"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"label"],[11,"class","info"],[9],[0,"\\n "],[1,[27,"input",null,[["type","checked"],["checkbox",[23,["showInfo"]]]]],false],[0,"\\n "],[7,"span"],[9],[0,"Info"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"label"],[11,"class","warn"],[9],[0,"\\n "],[1,[27,"input",null,[["type","checked"],["checkbox",[23,["showWarn"]]]]],false],[0,"\\n "],[7,"i"],[11,"class","fa fa-exclamation-circle warning"],[9],[10],[0,"\\n "],[7,"span"],[9],[0,"Warning"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"label"],[11,"class","error"],[9],[0,"\\n "],[1,[27,"input",null,[["type","checked"],["checkbox",[23,["showErr"]]]]],false],[0,"\\n "],[7,"i"],[11,"class","fa fa-times-circle error"],[9],[10],[0,"\\n "],[7,"span"],[9],[0,"Error"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"label"],[11,"class","fatal"],[9],[0,"\\n "],[1,[27,"input",null,[["type","checked"],["checkbox",[23,["showFatal"]]]]],false],[0,"\\n "],[7,"i"],[11,"class","fa fa-times-circle fatal"],[9],[10],[0,"\\n "],[7,"span"],[9],[0,"Fatal"],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[7,"div"],[11,"class","search-clear-all"],[9],[0,"\\n "],[1,[27,"input",null,[["type","class","placeholder","value"],["textfield","search","Search",[23,["search"]]]]],false],[0,"\\n "],[7,"div"],[11,"class","footer-btns"],[9],[0,"\\n"],[4,"if",[[23,["showSettings"]]],null,{"statements":[[4,"link-to",["settings"],[["class"],["settings btn no-text"]],{"statements":[[0," "],[7,"i"],[11,"class","fa fa-cog"],[9],[10],[0,"\\n"]],"parameters":[]},null]],"parameters":[]},null],[0," "],[7,"button"],[11,"class","clear btn danger"],[9],[7,"i"],[11,"class","fa fa-trash-o"],[9],[10],[7,"span"],[9],[0,"Clear logs"],[10],[3,"action",[[22,0,[]],"clear"]],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n"],[10],[0,"\\n"],[1,[21,"panel-resizer"],false],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"client-app/templates/index.hbs"}})
|
193
195
|
e.default=t}),define("client-app/templates/settings",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
194
196
|
var t=Ember.HTMLBars.template({id:"ZVQ4fCm0",block:'{"symbols":[],"statements":[[7,"div"],[11,"class","settings-page"],[9],[0,"\\n "],[4,"link-to",["index"],null,{"statements":[[0,"Home"]],"parameters":[]},null],[0,"\\n "],[7,"div"],[11,"class","settings-header"],[9],[0,"\\n "],[7,"h1"],[11,"class","header-title"],[9],[0,"Settings"],[10],[0,"\\n "],[7,"img"],[11,"class","header-logo"],[12,"src",[27,"logster-url",["images/icon_144x144.png"],null]],[9],[10],[0,"\\n "],[10],[0,"\\n\\n "],[7,"div"],[11,"class","settings-section suppression-patterns"],[9],[0,"\\n "],[7,"h2"],[11,"class","section-title"],[9],[0,"Suppression Patterns"],[10],[0,"\\n "],[7,"div"],[9],[0,"New messages that match these Regular Expression patterns will be suppressed."],[10],[0,"\\n\\n"],[4,"if",[[23,["showCodedSuppression"]]],null,{"statements":[[0," "],[7,"h3"],[11,"class","subsection-title"],[9],[0,"Hard-coded patterns:"],[10],[0,"\\n "],[7,"div"],[11,"class","tip"],[9],[0,"These patterns can\'t be removed via the UI because they are commited to the source code of your app."],[10],[0,"\\n "],[1,[27,"patterns-list",null,[["patterns","mutable"],[[23,["codedSuppression"]],false]]],false],[0,"\\n"]],"parameters":[]},null],[0,"\\n "],[7,"h3"],[11,"class","subsection-title"],[9],[0,"Custom patterns:"],[10],[0,"\\n "],[1,[27,"patterns-list",null,[["patterns","key","applyRetroactivelyCheckbox","mutable"],[[23,["customSuppression"]],"suppression",true,true]]],false],[0,"\\n "],[10],[0,"\\n"],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"client-app/templates/settings.hbs"}})
|
195
197
|
e.default=t}),define("client-app/templates/show",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
196
198
|
var t=Ember.HTMLBars.template({id:"V916vpg9",block:'{"symbols":[],"statements":[[4,"link-to",["index"],null,{"statements":[[0,"Recent"]],"parameters":[]},null],[0,"\\n"],[7,"div"],[11,"id","bottom-panel"],[11,"class","full"],[9],[0,"\\n "],[1,[27,"message-info",null,[["currentMessage","showTitle","actionsInMenu"],[[23,["model"]],"true",false]]],false],[0,"\\n"],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"client-app/templates/show.hbs"}})
|
197
199
|
e.default=t}),define("client-app/config/environment",[],function(){try{var e="client-app/config/environment",t=document.querySelector('meta[name="'+e+'"]').getAttribute("content"),n={default:JSON.parse(decodeURIComponent(t))}
|
198
|
-
return Object.defineProperty(n,"__esModule",{value:!0}),n}catch(a){throw new Error('Could not read config from meta tag with name "'+e+'".')}}),runningTests||require("client-app/app").default.create({name:"client-app",version:"0.0.0+
|
200
|
+
return Object.defineProperty(n,"__esModule",{value:!0}),n}catch(a){throw new Error('Could not read config from meta tag with name "'+e+'".')}}),runningTests||require("client-app/app").default.create({name:"client-app",version:"0.0.0+9798c0bc"})
|
@@ -2,6 +2,7 @@ import Controller from "@ember/controller";
|
|
2
2
|
import { ajax } from "client-app/lib/utilities";
|
3
3
|
import { observer, computed } from "@ember/object";
|
4
4
|
import Preload from "client-app/lib/preload";
|
5
|
+
import { debounce } from "@ember/runloop";
|
5
6
|
|
6
7
|
export default Controller.extend({
|
7
8
|
showDebug: true,
|
@@ -11,6 +12,7 @@ export default Controller.extend({
|
|
11
12
|
showFatal: true,
|
12
13
|
search: "",
|
13
14
|
currentMessage: Em.computed.alias("model.currentMessage"),
|
15
|
+
currentTab: null,
|
14
16
|
|
15
17
|
showSettings: computed(function() {
|
16
18
|
return Preload.get("patterns_enabled");
|
@@ -25,6 +27,16 @@ export default Controller.extend({
|
|
25
27
|
return this.site.isMobile;
|
26
28
|
}),
|
27
29
|
|
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
|
+
|
28
40
|
actions: {
|
29
41
|
expandMessage(message) {
|
30
42
|
message.expand();
|
@@ -37,7 +49,23 @@ export default Controller.extend({
|
|
37
49
|
}
|
38
50
|
|
39
51
|
message.set("selected", true);
|
40
|
-
this.
|
52
|
+
this.setProperties({
|
53
|
+
currentMessage: message,
|
54
|
+
loadingEnv: false
|
55
|
+
});
|
56
|
+
if (!message.env && this.currentTab === "env") {
|
57
|
+
this.fetchEnv();
|
58
|
+
}
|
59
|
+
},
|
60
|
+
|
61
|
+
tabChanged(newTab) {
|
62
|
+
this.setProperties({
|
63
|
+
currentTab: newTab,
|
64
|
+
loadingEnv: false
|
65
|
+
});
|
66
|
+
if (newTab === "env" && !this.get("currentMessage.env")) {
|
67
|
+
this.fetchEnv();
|
68
|
+
}
|
41
69
|
},
|
42
70
|
|
43
71
|
showMoreBefore() {
|
@@ -109,13 +137,21 @@ export default Controller.extend({
|
|
109
137
|
}
|
110
138
|
}),
|
111
139
|
|
112
|
-
|
113
|
-
const search = this.get("search");
|
140
|
+
doSearch(term) {
|
114
141
|
const model = this.get("model");
|
115
|
-
model.set("search",
|
142
|
+
model.set("search", term);
|
116
143
|
|
117
144
|
if (this.get("initialized")) {
|
118
145
|
model.reload().then(() => this.updateSelectedMessage());
|
119
146
|
}
|
147
|
+
},
|
148
|
+
|
149
|
+
searchChanged: observer("search", function() {
|
150
|
+
const term = this.search;
|
151
|
+
const termSize = term && term.length;
|
152
|
+
if (termSize && termSize === 1) {
|
153
|
+
return;
|
154
|
+
}
|
155
|
+
debounce(this, this.doSearch, term, 250);
|
120
156
|
})
|
121
157
|
});
|
@@ -63,45 +63,48 @@ export default Em.Object.extend({
|
|
63
63
|
data.after = opts.after;
|
64
64
|
}
|
65
65
|
|
66
|
+
this.set("loading", true);
|
66
67
|
return ajax("/messages.json", {
|
67
68
|
data: data
|
68
|
-
})
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
69
|
+
})
|
70
|
+
.then(data => {
|
71
|
+
// guard against race: ensure the results we're trying to apply
|
72
|
+
// match the current search terms
|
73
|
+
if (compare(data.filter, this.get("filter")) != 0) {
|
74
|
+
return;
|
75
|
+
}
|
76
|
+
if (compare(data.search, this.get("search")) != 0) {
|
77
|
+
return;
|
78
|
+
}
|
77
79
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
80
|
+
if (data.messages.length > 0) {
|
81
|
+
const newRows = this.toMessages(data.messages);
|
82
|
+
const messages = this.get("messages");
|
83
|
+
if (opts.before) {
|
84
|
+
messages.unshiftObjects(newRows);
|
85
|
+
} else {
|
86
|
+
newRows.forEach(nmsg => {
|
87
|
+
messages.forEach(emsg => {
|
88
|
+
if (emsg.key == nmsg.key) {
|
89
|
+
messages.removeObject(emsg);
|
90
|
+
if (this.get("currentMessage") === emsg) {
|
91
|
+
// TODO would updateFromJson() work here?
|
92
|
+
this.set("currentMessage", nmsg);
|
93
|
+
nmsg.set("selected", emsg.get("selected"));
|
94
|
+
}
|
92
95
|
}
|
93
|
-
}
|
96
|
+
});
|
94
97
|
});
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
98
|
+
messages.addObjects(newRows);
|
99
|
+
if (newRows.length > 0) {
|
100
|
+
increaseTitleCount(newRows.length);
|
101
|
+
}
|
99
102
|
}
|
100
103
|
}
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
104
|
+
this.set("total", data.total);
|
105
|
+
return data;
|
106
|
+
})
|
107
|
+
.always(() => this.set("loading", false));
|
105
108
|
},
|
106
109
|
|
107
110
|
reload() {
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<div class="message-info">
|
2
|
-
{{#tabbed-section}}
|
2
|
+
{{#tabbed-section onTabChange=(action "tabChanged")}}
|
3
3
|
{{#tab-contents name="info" hint="show info" currentMessage=currentMessage}}
|
4
4
|
{{#if showTitle}}
|
5
5
|
<h3>Message
|
@@ -16,14 +16,18 @@
|
|
16
16
|
{{/if}}
|
17
17
|
<pre>{{currentMessage.backtrace}}</pre>
|
18
18
|
{{/tab-contents}}
|
19
|
-
{{#
|
20
|
-
{{#
|
19
|
+
{{#tab-contents className="env" name="env" hint="show environment" currentMessage=currentMessage }}
|
20
|
+
{{#if currentMessage.env}}
|
21
21
|
{{#if showTitle}}
|
22
22
|
<h3>Env</h3>
|
23
23
|
{{/if}}
|
24
24
|
{{env-tab message=currentMessage}}
|
25
|
-
{{
|
26
|
-
|
25
|
+
{{else if loadingEnv}}
|
26
|
+
Loading env...
|
27
|
+
{{else}}
|
28
|
+
No env for this message.
|
29
|
+
{{/if}}
|
30
|
+
{{/tab-contents}}
|
27
31
|
{{/tabbed-section}}
|
28
32
|
|
29
33
|
{{#if currentMessage}}
|
@@ -17,8 +17,10 @@
|
|
17
17
|
<div id="bottom-panel">
|
18
18
|
{{message-info
|
19
19
|
currentMessage=currentMessage
|
20
|
+
loadingEnv=loadingEnv
|
20
21
|
removeMessage=(action "removeMessage")
|
21
22
|
solveMessage=(action "solveMessage")
|
23
|
+
onTabChange=(action "tabChanged")
|
22
24
|
actionsInMenu=actionsInMenu}}
|
23
25
|
|
24
26
|
<div class="action-panel">
|
data/lib/logster/base_store.rb
CHANGED
@@ -183,13 +183,12 @@ module Logster
|
|
183
183
|
end
|
184
184
|
|
185
185
|
if similar
|
186
|
-
|
187
|
-
if similar.count < Logster::MAX_GROUPING_LENGTH && !has_env
|
186
|
+
if similar.count < Logster::MAX_GROUPING_LENGTH
|
188
187
|
similar.env = get_env(similar.key) || {}
|
189
188
|
end
|
190
189
|
save_env = similar.merge_similar_message(message)
|
191
190
|
|
192
|
-
replace_and_bump(similar, save_env: save_env
|
191
|
+
replace_and_bump(similar, save_env: save_env)
|
193
192
|
similar
|
194
193
|
else
|
195
194
|
save message
|
@@ -11,7 +11,8 @@ module Logster
|
|
11
11
|
:enable_js_error_reporting,
|
12
12
|
:environments,
|
13
13
|
:rate_limit_error_reporting,
|
14
|
-
:web_title
|
14
|
+
:web_title,
|
15
|
+
:maximum_message_size_bytes
|
15
16
|
)
|
16
17
|
|
17
18
|
attr_writer :subdirectory
|
@@ -25,6 +26,7 @@ module Logster
|
|
25
26
|
@enable_custom_patterns_via_ui = false
|
26
27
|
@rate_limit_error_reporting = true
|
27
28
|
@enable_js_error_reporting = true
|
29
|
+
@maximum_message_size_bytes = 60_000
|
28
30
|
|
29
31
|
@allow_grouping = false
|
30
32
|
|
data/lib/logster/message.rb
CHANGED
@@ -4,6 +4,7 @@ require 'securerandom'
|
|
4
4
|
module Logster
|
5
5
|
|
6
6
|
MAX_GROUPING_LENGTH = 50
|
7
|
+
MAX_MESSAGE_LENGTH = 600
|
7
8
|
|
8
9
|
class Message
|
9
10
|
LOGSTER_ENV = "_logster_env".freeze
|
@@ -21,13 +22,14 @@ module Logster
|
|
21
22
|
application_version
|
22
23
|
}
|
23
24
|
|
24
|
-
attr_accessor :timestamp, :severity, :progname, :
|
25
|
+
attr_accessor :timestamp, :severity, :progname, :key, :backtrace, :count, :protected, :first_timestamp
|
26
|
+
attr_reader :message, :env
|
25
27
|
|
26
28
|
def initialize(severity, progname, message, timestamp = nil, key = nil, count: 1)
|
27
29
|
@timestamp = timestamp || get_timestamp
|
28
30
|
@severity = severity
|
29
31
|
@progname = progname
|
30
|
-
@message = message
|
32
|
+
@message = truncate_message(message)
|
31
33
|
@key = key || SecureRandom.hex
|
32
34
|
@backtrace = nil
|
33
35
|
@count = count || 1
|
@@ -53,6 +55,10 @@ module Logster
|
|
53
55
|
h
|
54
56
|
end
|
55
57
|
|
58
|
+
def message=(m)
|
59
|
+
@message = truncate_message(m)
|
60
|
+
end
|
61
|
+
|
56
62
|
def to_json(opts = nil)
|
57
63
|
exclude_env = Hash === opts && opts.delete(:exclude_env)
|
58
64
|
JSON.fast_generate(to_h(exclude_env: exclude_env), opts)
|
@@ -74,6 +80,7 @@ module Logster
|
|
74
80
|
end
|
75
81
|
|
76
82
|
def env=(env)
|
83
|
+
@env_json = nil
|
77
84
|
@env = self.class.scrub_params(env)
|
78
85
|
end
|
79
86
|
|
@@ -90,6 +97,7 @@ module Logster
|
|
90
97
|
else
|
91
98
|
env = self.class.default_env.merge(env)
|
92
99
|
end
|
100
|
+
@env_json = nil
|
93
101
|
@env = Message.populate_from_env(env)
|
94
102
|
end
|
95
103
|
|
@@ -140,6 +148,10 @@ module Logster
|
|
140
148
|
self.count += other.count || 1
|
141
149
|
return false if self.count > Logster::MAX_GROUPING_LENGTH
|
142
150
|
|
151
|
+
size = self.to_json(exclude_env: true).bytesize + self.env_json.bytesize
|
152
|
+
extra_env_size = other.env_json.bytesize
|
153
|
+
return false if size + extra_env_size > Logster.config.maximum_message_size_bytes
|
154
|
+
|
143
155
|
other_env = JSON.load JSON.fast_generate other.env
|
144
156
|
if Hash === other_env && !other_env.key?("time")
|
145
157
|
other_env["time"] = other.timestamp
|
@@ -153,6 +165,7 @@ module Logster
|
|
153
165
|
else
|
154
166
|
Array === other_env ? self.env = [self.env, *other_env] : self.env = [self.env, other_env]
|
155
167
|
end
|
168
|
+
@env_json = nil
|
156
169
|
true
|
157
170
|
end
|
158
171
|
|
@@ -214,6 +227,10 @@ module Logster
|
|
214
227
|
end
|
215
228
|
end
|
216
229
|
|
230
|
+
def env_json
|
231
|
+
@env_json ||= (self.env || {}).to_json
|
232
|
+
end
|
233
|
+
|
217
234
|
def self.scrub_params(params)
|
218
235
|
if Array === params
|
219
236
|
params.map! { |p| scrub_params(p) }
|
@@ -233,6 +250,11 @@ module Logster
|
|
233
250
|
|
234
251
|
protected
|
235
252
|
|
253
|
+
def truncate_message(msg)
|
254
|
+
return msg unless msg
|
255
|
+
msg.size <= MAX_MESSAGE_LENGTH ? msg : msg[0...MAX_MESSAGE_LENGTH] + "..."
|
256
|
+
end
|
257
|
+
|
236
258
|
def get_timestamp
|
237
259
|
(Time.new.to_f * 1000).to_i
|
238
260
|
end
|
@@ -156,6 +156,14 @@ module Logster
|
|
156
156
|
[200, {}, ["OK"]]
|
157
157
|
elsif resource == "/"
|
158
158
|
[200, { "Content-Type" => "text/html; charset=utf-8" }, [body(preload_json)]]
|
159
|
+
elsif resource =~ /\/fetch-env\/([0-9a-f]+)\.json$/
|
160
|
+
key = $1
|
161
|
+
env = Logster.store.get_env(key)
|
162
|
+
if env
|
163
|
+
[200, { "Content-Type" => "application/json; charset=utf-8" }, [JSON.generate(env)]]
|
164
|
+
else
|
165
|
+
not_found
|
166
|
+
end
|
159
167
|
else
|
160
168
|
not_found
|
161
169
|
end
|
@@ -190,6 +198,8 @@ module Logster
|
|
190
198
|
search = (parse_regex(search) || search) if params["regex_search"] == "true"
|
191
199
|
opts[:search] = search
|
192
200
|
end
|
201
|
+
search = opts[:search]
|
202
|
+
opts[:with_env] = (String === search && search.size > 0) || Regexp === search
|
193
203
|
|
194
204
|
payload = {
|
195
205
|
messages: @store.latest(opts),
|
data/lib/logster/redis_store.rb
CHANGED
@@ -24,6 +24,7 @@ module Logster
|
|
24
24
|
return true if @redis.hget(solved_key, solved)
|
25
25
|
end
|
26
26
|
end
|
27
|
+
apply_max_size_limit(message)
|
27
28
|
|
28
29
|
@redis.multi do
|
29
30
|
@redis.hset(grouping_key, message.grouping_key, message.key)
|
@@ -64,7 +65,7 @@ module Logster
|
|
64
65
|
|
65
66
|
@redis.multi do
|
66
67
|
@redis.hset(hash_key, message.key, message.to_json(exclude_env: true))
|
67
|
-
@redis.hset(env_key, message.key,
|
68
|
+
@redis.hset(env_key, message.key, message.env_json) if save_env
|
68
69
|
@redis.lrem(list_key, -1, message.key)
|
69
70
|
@redis.rpush(list_key, message.key)
|
70
71
|
end
|
@@ -98,6 +99,7 @@ module Logster
|
|
98
99
|
before = opts[:before]
|
99
100
|
after = opts[:after]
|
100
101
|
search = opts[:search]
|
102
|
+
with_env = opts.key?(:with_env) ? opts[:with_env] : true
|
101
103
|
|
102
104
|
start, finish = find_location(before, after, limit)
|
103
105
|
|
@@ -110,7 +112,7 @@ module Logster
|
|
110
112
|
begin
|
111
113
|
keys = @redis.lrange(list_key, start, finish) || []
|
112
114
|
break unless keys && (keys.count > 0)
|
113
|
-
rows = bulk_get(keys)
|
115
|
+
rows = bulk_get(keys, with_env: with_env)
|
114
116
|
|
115
117
|
temp = []
|
116
118
|
|
@@ -204,14 +206,16 @@ module Logster
|
|
204
206
|
bulk_get(@redis.lrange(list_key, 0, -1))
|
205
207
|
end
|
206
208
|
|
207
|
-
def bulk_get(message_keys)
|
208
|
-
envs = @redis.
|
209
|
-
@redis.hmget(hash_key, message_keys).map
|
209
|
+
def bulk_get(message_keys, with_env: true)
|
210
|
+
envs = @redis.mapped_hmget(env_key, *message_keys) if with_env
|
211
|
+
@redis.hmget(hash_key, message_keys).map! do |json|
|
210
212
|
message = Message.from_json(json)
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
213
|
+
if with_env
|
214
|
+
env = envs[message.key]
|
215
|
+
if !message.env || message.env.size == 0
|
216
|
+
env = env && env.size > 0 ? ::JSON.parse(env) : {}
|
217
|
+
message.env = env
|
218
|
+
end
|
215
219
|
end
|
216
220
|
message
|
217
221
|
end
|
@@ -337,7 +341,7 @@ module Logster
|
|
337
341
|
|
338
342
|
def update_message(message)
|
339
343
|
@redis.hset(hash_key, message.key, message.to_json(exclude_env: true))
|
340
|
-
@redis.hset(env_key, message.key,
|
344
|
+
@redis.hset(env_key, message.key, message.env_json)
|
341
345
|
if message.protected
|
342
346
|
@redis.sadd(protected_key, message.key)
|
343
347
|
else
|
@@ -513,6 +517,22 @@ module Logster
|
|
513
517
|
|
514
518
|
private
|
515
519
|
|
520
|
+
def apply_max_size_limit(message)
|
521
|
+
size = message.to_json(exclude_env: true).bytesize
|
522
|
+
env_size = message.env_json.bytesize
|
523
|
+
max_size = Logster.config.maximum_message_size_bytes
|
524
|
+
if size + env_size > max_size
|
525
|
+
# env is most likely the reason for the large size
|
526
|
+
# truncate it so the overall size is < the limit
|
527
|
+
if Array === message.env
|
528
|
+
# the - 1 at the end ensures the size goes a little bit below the limit
|
529
|
+
truncate_at = (message.env.size.to_f * max_size.to_f / (env_size + size)).to_i - 1
|
530
|
+
truncate_at = 1 if truncate_at < 1
|
531
|
+
message.env = message.env[0...truncate_at]
|
532
|
+
end
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
516
536
|
def register_rate_limit(severities, limit, duration, callback)
|
517
537
|
severities = [severities] unless severities.is_a?(Array)
|
518
538
|
redis = (@redis_raw_connection && @redis_prefix) ? @redis_raw_connection : @redis
|
data/lib/logster/version.rb
CHANGED
@@ -328,4 +328,44 @@ class TestViewer < Minitest::Test
|
|
328
328
|
assert_equal(404, response.status, "#{path} should have 404'ed")
|
329
329
|
end
|
330
330
|
end
|
331
|
+
|
332
|
+
def test_messages_endpoint_doesnt_include_envs_when_search_term_absent
|
333
|
+
Logster.store.clear_all
|
334
|
+
env = { "b" => 1, "c" => 2 }
|
335
|
+
msg = Logster.store.report(Logger::INFO, "test", "something hello", env: env)
|
336
|
+
response = request.get("/logsie/messages.json")
|
337
|
+
assert_equal(200, response.status)
|
338
|
+
messages = JSON.parse(response.body)["messages"]
|
339
|
+
assert_equal(1, messages.size)
|
340
|
+
msg = messages.first
|
341
|
+
assert_equal("something hello", msg["message"])
|
342
|
+
assert_nil(msg["env"])
|
343
|
+
end
|
344
|
+
|
345
|
+
def test_messages_endpoint_includes_env_when_there_is_search_term
|
346
|
+
Logster.store.clear_all
|
347
|
+
env = { "b" => 1, "c" => 2 }
|
348
|
+
msg = Logster.store.report(Logger::INFO, "test", "something hello", env: env)
|
349
|
+
response = request.get("/logsie/messages.json?search=something")
|
350
|
+
assert_equal(200, response.status)
|
351
|
+
messages = JSON.parse(response.body)["messages"]
|
352
|
+
assert_equal(1, messages.size)
|
353
|
+
msg = messages.first
|
354
|
+
assert_equal("something hello", msg["message"])
|
355
|
+
assert_includes(msg["env"].values, 1, 2)
|
356
|
+
end
|
357
|
+
|
358
|
+
def test_fetch_env_returns_env_associated_with_message
|
359
|
+
env = { "b" => 1, "c" => 2 }
|
360
|
+
msg = Logster.store.report(Logger::INFO, "test", "something whatever store", env: env)
|
361
|
+
response = request.get("/logsie/fetch-env/#{msg.key}.json")
|
362
|
+
assert_equal(200, response.status)
|
363
|
+
res = JSON.parse(response.body)
|
364
|
+
assert_includes(res.values, 1, 2)
|
365
|
+
end
|
366
|
+
|
367
|
+
def test_fetch_env_returns_404_when_invalid_key
|
368
|
+
response = request.get("/logsie/fetch-env/123456abc.json")
|
369
|
+
assert_equal(404, response.status)
|
370
|
+
end
|
331
371
|
end
|
@@ -148,4 +148,28 @@ class TestMessage < MiniTest::Test
|
|
148
148
|
assert_includes(msg.to_json, test_hash.to_json)
|
149
149
|
refute_includes(msg.to_json(exclude_env: true), test_hash.to_json)
|
150
150
|
end
|
151
|
+
|
152
|
+
def test_title_is_truncated_when_too_large
|
153
|
+
msg = Logster::Message.new(0, "", "a" * 1000)
|
154
|
+
# 3 is the ... at the end to indicate truncated message
|
155
|
+
assert_equal(600 + 3, msg.message.size)
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_env_is_not_merged_into_similar_message_if_size_will_be_too_large
|
159
|
+
default = Logster.config.maximum_message_size_bytes
|
160
|
+
Logster.config.maximum_message_size_bytes = 1000
|
161
|
+
message = Logster::Message.new(Logger::INFO, "test", "message", count: 13)
|
162
|
+
env = [{ key1: "this is my first key", key2: "this is my second key" }] * 13
|
163
|
+
message.env = env
|
164
|
+
|
165
|
+
message2 = Logster::Message.new(Logger::INFO, "test", "message")
|
166
|
+
message2.env = env.first
|
167
|
+
message.merge_similar_message(message2)
|
168
|
+
|
169
|
+
# env isn't merged, but count is incremented
|
170
|
+
assert_equal(13, message.env.size)
|
171
|
+
assert_equal(14, message.count)
|
172
|
+
ensure
|
173
|
+
Logster.config.maximum_message_size_bytes = default
|
174
|
+
end
|
151
175
|
end
|
@@ -705,6 +705,21 @@ class TestRedisStore < Minitest::Test
|
|
705
705
|
end
|
706
706
|
end
|
707
707
|
|
708
|
+
def test_store_trims_too_big_envs
|
709
|
+
default = Logster.config.maximum_message_size_bytes
|
710
|
+
Logster.config.maximum_message_size_bytes = 1000
|
711
|
+
message = Logster::Message.new(Logger::INFO, "test", "message")
|
712
|
+
env = [{ key1: "this is my first key", key2: "this is my second key" }] * 40
|
713
|
+
message.env = env
|
714
|
+
@store.save(message)
|
715
|
+
trimmed_message = @store.latest.first
|
716
|
+
assert_equal(13, trimmed_message.env.size)
|
717
|
+
size = message.to_json(exclude_env: true).bytesize + message.env_json.bytesize
|
718
|
+
assert_operator(1000, :>, size)
|
719
|
+
ensure
|
720
|
+
Logster.config.maximum_message_size_bytes = default
|
721
|
+
end
|
722
|
+
|
708
723
|
private
|
709
724
|
|
710
725
|
def reset_redis
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.4.
|
4
|
+
version: 2.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- UI for viewing logs in Rack
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-10-
|
11
|
+
date: 2019-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|