logster 0.8.4.3.pre → 0.8.4.4.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e704a239b3cbe88f36a41e30888836d981451494
4
- data.tar.gz: ea74d3dfb8a7f2ffe9371194a4ab233c13133e0c
3
+ metadata.gz: 26758317e1dfa2cb38fd7932d7ffc2f9fd073c96
4
+ data.tar.gz: 58b3c563e7cb4232417b798bfcad902d3fe88621
5
5
  SHA512:
6
- metadata.gz: 45bbecf6dc989a24d796eb5059588dfee399bded667c775b3183d48d5158f782ef6aa796fd83df0faea0631b72a923b1a8e92e1aecce33f15affab8112d78bf5
7
- data.tar.gz: 715218740ee56fe89bc9b46174722a95d3f49b2545b894a608e2f92e56cb034227a117f6ba9b55826ecbdcb7f3385ca481766828ff6015711b68c2121abaacc3
6
+ metadata.gz: 47d950c4d8cf793f2d0999040c973bd5bf6d4a6c692135fe3ee549f79549e72c6a908f322ae2724eb4b55a99db2db797164d369371a9af917d20032952d275e0
7
+ data.tar.gz: dbbfee1e1e49871c6256def779f97f3675c74f0a0fccc0ff2f37ed930a8bc85274dd3a46ef3c7a240edec908f635c72a023ee996e965e8d26e39f52e29c8559f
@@ -101,6 +101,10 @@ App.Message = Ember.Object.extend({
101
101
  this.set("expanded", true);
102
102
  },
103
103
 
104
+ "delete": function() {
105
+ return App.ajax("/message/" + this.get('key'), { type: "DELETE" });
106
+ },
107
+
104
108
  protect: function() {
105
109
  this.set('protected', true);
106
110
  return App.ajax("/protect/" + this.get('key'), { type: "PUT" });
@@ -181,6 +185,13 @@ App.MessageCollection = Em.Object.extend({
181
185
  currentMessage: null,
182
186
  total: 0,
183
187
 
188
+ "delete": function(message){
189
+ message.delete();
190
+ this.get('messages').removeObject(message);
191
+ this.set('currentMessage', null);
192
+ this.set('total', this.get('total')-1);
193
+ },
194
+
184
195
  load: function(opts) {
185
196
  var self = this;
186
197
  opts = opts || {};
@@ -372,6 +383,11 @@ App.IndexController = Em.Controller.extend({
372
383
  });
373
384
  }
374
385
  },
386
+
387
+ removeMessage: function(msg) {
388
+ var messages = this.get('model');
389
+ messages.delete(msg);
390
+ }
375
391
  },
376
392
 
377
393
  filterChanged: function(){
@@ -650,12 +666,18 @@ App.TabContentsComponent = Ember.Component.extend({
650
666
  this.invokeParent("removeTab");
651
667
  },
652
668
 
669
+ });
670
+
671
+ App.MessageInfoComponent = Ember.Component.extend({
653
672
  actions: {
654
673
  protect: function(){
655
674
  this.get('currentMessage').protect();
656
675
  },
657
676
  unprotect: function(){
658
677
  this.get('currentMessage').unprotect();
678
+ },
679
+ "remove": function(){
680
+ this.sendAction("removeMessage", this.get('currentMessage'));
659
681
  }
660
682
  }
661
683
  });
@@ -25,4 +25,19 @@
25
25
  {{/tab-contents}}
26
26
  {{/if}}
27
27
  {{/tabbed-section}}
28
+
29
+ {{#if currentMessage}}
30
+ <div class='message-actions'>
31
+
32
+ {{#unless currentMessage.protected}}
33
+ <button {{action 'remove'}} class="delete btn"><i class='fa fa-trash-o'></i>Delete</button>
34
+
35
+ <button {{action 'protect'}} class="protect btn"><i class='fa fa-lock'></i>Protect</button>
36
+ {{else}}
37
+ <button {{action 'unprotect'}} class="unprotect btn"><i class='fa fa-unlock'></i>Unprotect</button>
38
+ {{/unless}}
39
+ <a href="{{currentMessage.shareUrl}}" class="share btn">Share</a>
40
+ </div>
41
+
42
+ {{/if}}
28
43
  </div>
@@ -1,15 +1 @@
1
1
  {{yield}}
2
- {{#if currentMessage}}
3
- <div class='message-actions'>
4
-
5
- {{#unless currentMessage.protected}}
6
- <i class='fa fa-lock'></i>
7
- <a href {{action 'protect'}} class="protect">Protect</a>
8
- {{else}}
9
- <i class='fa fa-unlock'></i>
10
- <a href {{action 'unprotect'}} class="protect">Unprotect</a>
11
- {{/unless}}
12
- <a href="{{currentMessage.shareUrl}}" class="share">Share</a>
13
- </div>
14
-
15
- {{/if}}
@@ -23,7 +23,7 @@
23
23
  </div>
24
24
  {{panel-resizer}}
25
25
  <div id="bottom-panel">
26
- {{message-info currentMessage=currentMessage}}
26
+ {{message-info currentMessage=currentMessage removeMessage="removeMessage"}}
27
27
 
28
28
  <div class="action-panel">
29
29
  <label class="debug">
@@ -52,6 +52,6 @@
52
52
  <label class="search">
53
53
  {{input type="textfield" placeholder="Search" value=search}}
54
54
  </label>
55
- <a class="clear" href {{action "clear"}}>Clear logs</a>
55
+ <a class="clear btn danger" href {{action "clear"}}><i class='fa fa-trash-o'></i> Clear logs</a>
56
56
  </div>
57
57
  </div>
@@ -145,15 +145,40 @@ tr.show-more {
145
145
  bottom: 10px;
146
146
  }
147
147
 
148
+ #bottom-panel.full button.delete {
149
+ display: none;
150
+ }
151
+
152
+ #bottom-panel.full .message-actions {
153
+ position: fixed;
154
+ height: 40px;
155
+ width: 100%;
156
+ left: 0;
157
+ bottom: 0;
158
+ background-color: #eee;
159
+ border-top: 1px solid #dfdfdf;
160
+ padding-left: 10px;
161
+ }
162
+
163
+ #bottom-panel.full .message-actions button {
164
+ margin-top: 10px;
165
+ }
166
+
167
+
168
+
148
169
  .message-actions {
149
- position: fixed;
150
- bottom: 45px;
151
- right: 10px;
170
+ position: absolute;
171
+ bottom: 3px;
172
+ right: 30px;
152
173
  }
153
174
 
154
- .message-actions a {
155
- z-index: 10000;
156
- padding-right: 7px;
175
+ .message-actions button {
176
+ margin-right: 7px;
177
+ }
178
+
179
+ .message-actions .share {
180
+ text-decoration: none;
181
+ color: #333;
157
182
  }
158
183
 
159
184
  .divider {
@@ -224,9 +249,8 @@ tr.show-more {
224
249
  }
225
250
 
226
251
  .action-panel .clear {
227
- position: relative;
228
- top: -1px;
229
- margin-left: 50px;
252
+ position: absolute;
253
+ right: 30px;
230
254
  vertical-align: middle;
231
255
  }
232
256
 
@@ -306,3 +330,39 @@ tr.show-more {
306
330
  border-top: 1px solid #f1f1f1;
307
331
  background-color: #f1f1f1;
308
332
  }
333
+
334
+
335
+ .btn {
336
+ display: inline-block;
337
+ margin: 0;
338
+ padding: 2px 12px;
339
+ font-weight: 500;
340
+ font-size: 1em;
341
+ line-height: 18px;
342
+ text-align: center;
343
+ cursor: pointer;
344
+ transition: all .25s;
345
+ background-color: #DDD;
346
+ text-decoration: none;
347
+ border: none;
348
+ color: #333;
349
+ font-weight: normal;
350
+ }
351
+
352
+ .btn:hover {
353
+ color: #000;
354
+ background-color: #ccc;
355
+ }
356
+
357
+ .btn .fa {
358
+ margin-right: 7px;
359
+ }
360
+
361
+ .btn:active {
362
+ text-shadow: none;
363
+ }
364
+
365
+ .btn.danger:hover {
366
+ background-color: #c63c1b;
367
+ color: #EEE;
368
+ }
@@ -50,6 +50,10 @@ module Logster
50
50
  not_implemented
51
51
  end
52
52
 
53
+ def delete(message_key)
54
+ not_implemented
55
+ end
56
+
53
57
  # Clear the protected mark for a message.
54
58
  def unprotect(message_key)
55
59
  not_implemented
@@ -19,7 +19,7 @@ module Logster
19
19
  process_id
20
20
  }
21
21
 
22
- attr_accessor :timestamp, :severity, :progname, :message, :key, :backtrace, :count, :env, :protected
22
+ attr_accessor :timestamp, :severity, :progname, :message, :key, :backtrace, :count, :env, :protected, :first_timestamp
23
23
 
24
24
  def initialize(severity, progname, message, timestamp = nil, key = nil)
25
25
  @timestamp = timestamp || get_timestamp
@@ -33,7 +33,7 @@ module Logster
33
33
  end
34
34
 
35
35
  def to_h
36
- {
36
+ h = {
37
37
  message: @message,
38
38
  progname: @progname,
39
39
  severity: @severity,
@@ -44,6 +44,12 @@ module Logster
44
44
  env: @env,
45
45
  protected: @protected
46
46
  }
47
+
48
+ if @first_timestamp
49
+ h[:first_timestamp] = @first_timestamp
50
+ end
51
+
52
+ h
47
53
  end
48
54
 
49
55
  def to_json(opts = nil)
@@ -61,6 +67,7 @@ module Logster
61
67
  msg.env = parsed["env"]
62
68
  msg.count = parsed["count"]
63
69
  msg.protected = parsed["protected"]
70
+ msg.first_timestamp = parsed["first_timestamp"]
64
71
  msg
65
72
  end
66
73
 
@@ -90,6 +97,8 @@ module Logster
90
97
  end
91
98
 
92
99
  def merge_similar_message(other)
100
+ self.first_timestamp ||= self.timestamp
101
+ self.timestamp = [self.timestamp,other.timestamp].max
93
102
  other_env = JSON.load JSON.fast_generate other.env
94
103
  other_env.keys.each do |env_key|
95
104
  self.env[env_key] = Message.env_merge_helper(self.env[env_key], other_env[env_key])
@@ -38,6 +38,20 @@ module Logster
38
38
  elsif resource.start_with?("/messages.json")
39
39
  serve_messages(Rack::Request.new(env))
40
40
 
41
+ elsif resource =~ /\/message\/([0-9a-f]+)$/
42
+ if env[REQUEST_METHOD] != "DELETE"
43
+ return [405, {}, ["GET not allowed for /clear"]]
44
+ end
45
+
46
+ key = $1
47
+ message = Logster.store.get(key)
48
+ unless message
49
+ return [404, {}, ["Message not found"]]
50
+ end
51
+
52
+ Logster.store.delete(message)
53
+ return [301, {"Location" => "#{@logs_path}/"}, []]
54
+
41
55
  elsif resource =~ /\/(un)?protect\/([0-9a-f]+)$/
42
56
  off = $1 == "un"
43
57
  key = $2
@@ -25,6 +25,14 @@ module Logster
25
25
  true
26
26
  end
27
27
 
28
+ def delete(msg)
29
+ @redis.multi do
30
+ @redis.hdel(hash_key, msg.key)
31
+ @redis.hdel(grouping_key, msg.grouping_key)
32
+ @redis.lrem(list_key, -1, msg.key)
33
+ end
34
+ end
35
+
28
36
  def replace_and_bump(message)
29
37
  # TODO make it atomic
30
38
  exists = @redis.hexists(hash_key, message.key)
@@ -130,9 +138,7 @@ module Logster
130
138
  json = @redis.hget(hash_key, message_key)
131
139
  return nil unless json
132
140
 
133
- message = Message.from_json(json)
134
- # message.protected = @redis.sismember(protected_key, message_key)
135
- message
141
+ Message.from_json(json)
136
142
  end
137
143
 
138
144
  def protect(message_key)
@@ -1,3 +1,3 @@
1
1
  module Logster
2
- VERSION = "0.8.4.3.pre"
2
+ VERSION = "0.8.4.4.pre"
3
3
  end
@@ -1,6 +1,24 @@
1
1
  require_relative '../test_helper'
2
- require 'logster/redis_store'
2
+ require 'logster/message'
3
3
 
4
4
  class TestMessage < MiniTest::Test
5
5
 
6
+ def test_merge_similar
7
+ msg1 = Logster::Message.new(0, '', 'test', 10)
8
+ msg1.populate_from_env(a: "1", b: "2")
9
+
10
+ msg2 = Logster::Message.new(0, '', 'test', 20)
11
+ msg2.populate_from_env(a: "2", c: "3")
12
+
13
+ assert_equal(msg2.grouping_key, msg1.grouping_key)
14
+
15
+ msg1.merge_similar_message(msg2)
16
+
17
+ msg1 = Logster::Message.from_json(msg1.to_json)
18
+
19
+ assert_equal(20, msg1.timestamp)
20
+ assert_equal(10, msg1.first_timestamp)
21
+
22
+ end
23
+
6
24
  end
@@ -13,6 +13,14 @@ class TestRedisStore < Minitest::Test
13
13
  @store.clear_all
14
14
  end
15
15
 
16
+ def test_delete
17
+ msg = @store.report(Logger::WARN, "test", "testing")
18
+ @store.delete(msg)
19
+ latest = @store.latest
20
+
21
+ assert_equal(0,latest.length)
22
+ end
23
+
16
24
  def test_latest
17
25
  @store.report(Logger::WARN, "test", "IGNORE")
18
26
  @store.report(Logger::WARN, "test", "This is a warning")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logster
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.4.3.pre
4
+ version: 0.8.4.4.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - UI for viewing logs in Rack