logster 0.8.4.3.pre → 0.8.4.4.pre

Sign up to get free protection for your applications and to get access to all the features.
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