logster 0.1.0 → 0.1.1

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: 2cfda323f9ee2749181b885b462d4e6b6398f03b
4
- data.tar.gz: d9cf1b6ce77e9c7d74745c253047d39c992a1855
3
+ metadata.gz: 817153c3885fd064575528496f299e302802edff
4
+ data.tar.gz: 2adf2a219859d1d5a1b7163fa98714a3e0d353fc
5
5
  SHA512:
6
- metadata.gz: bef73cfac1f6232793744b1fcb1807da74088a271bba04b0ad7ad6bca95de46a9d39ed73e23371970afd0c7e045a93c8d538c056b4434fddbed44946fb37064f
7
- data.tar.gz: 8bcab70e33821609e020ad951e2453394eafbe2fb11607d3cdb63563898656e0b48aa8227b1edb97e0eef471ef09f4f93a6c802db745676bffd714d7ca6eb2ac
6
+ metadata.gz: 40a5c76579e0f5145e3cdb490daab9550dd30e12d3e6be4609774aa045f46d33f3465ba20bcd0a1fe350de3000f92a9bff54c94cdb7032cbc1eccabb88765ea4
7
+ data.tar.gz: 33401bae4031a18e2d0e40f22679acfc1ebf0cb8515df2ea9084ca06e0eccb82a781ee34abeadf5dc4a5592c3327c77f246623b7724a40959ea330a6f4768df8
@@ -45,7 +45,7 @@ App.preloadOrAjax = function(url, settings) {
45
45
  }
46
46
  };
47
47
 
48
- App.Router.map(function(){
48
+ App.Router.map(function() {
49
49
  this.route("index", { path: "/" });
50
50
  this.route("show", { path: "/show/:id" });
51
51
  });
@@ -67,7 +67,7 @@ App.Message = Ember.Object.extend({
67
67
  return App.ajax("/unprotect/" + this.get('key'), { type: "DELETE" });
68
68
  },
69
69
 
70
- hasMore: function(){
70
+ hasMore: function() {
71
71
  var message = this.get("message");
72
72
  var expanded = this.get("expanded");
73
73
 
@@ -82,32 +82,37 @@ App.Message = Ember.Object.extend({
82
82
  return Logger.rootPath + (this.get('protected') ? '/unprotect/' : '/protect/') + this.get('key');
83
83
  }.property("key"),
84
84
 
85
- displayMessage: function(){
85
+ displayMessage: function() {
86
86
  var message = this.get("message");
87
87
  var expanded = this.get("expanded");
88
88
 
89
- if(!expanded && message.length > this.MAX_LEN){
90
- message = message.substr(0,this.MAX_LEN);
89
+ if (!expanded && message.length > this.MAX_LEN) {
90
+ message = message.substr(0, this.MAX_LEN);
91
91
  }
92
92
  return message;
93
- }.property("message","expanded"),
93
+ }.property("message", "expanded"),
94
94
 
95
- envDebug: function(){
95
+ envDebug: function() {
96
96
  var env = this.get("env");
97
- if(env){
98
- var buffer = [];
99
- _.each(env, function(v,k){
100
- if(k !== "params"){
97
+ if (env) {
98
+ var buffer = [],
99
+ hashes = [];
100
+ _.each(env, function(v, k) {
101
+ if (typeof v === "object") {
102
+ hashes.push(k);
103
+ } else {
101
104
  buffer.push(k + ": " + v);
102
105
  }
103
106
  });
104
107
 
105
- buffer.push("");
106
- if(_.size(env.params) > 0){
107
- buffer.push("Params:");
108
- buffer.push("");
109
- _.each(env.params, function(v,k){
110
- buffer.push(" " + k + ": " + v);
108
+ if (_.size(hashes) > 0) {
109
+ _.each(hashes, function(k1) {
110
+ v1 = env[k1];
111
+ buffer.push("");
112
+ buffer.push(k1 + ":");
113
+ _.each(v1, function(v2, k2) {
114
+ buffer.push(" " + k2 + ": " + v2);
115
+ })
111
116
  });
112
117
  }
113
118
  return buffer.join("\n");
@@ -116,7 +121,7 @@ App.Message = Ember.Object.extend({
116
121
  }.property("env"),
117
122
 
118
123
  rowClass: function() {
119
- switch(this.get("severity")){
124
+ switch (this.get("severity")) {
120
125
  case 0:
121
126
  return "debug";
122
127
  case 1:
@@ -130,8 +135,8 @@ App.Message = Ember.Object.extend({
130
135
  }
131
136
  }.property("severity"),
132
137
 
133
- glyph: function(){
134
- switch(this.get("severity")){
138
+ glyph: function() {
139
+ switch (this.get("severity")) {
135
140
  case 0:
136
141
  return "";
137
142
  case 1:
@@ -151,7 +156,7 @@ App.MessageCollection = Em.Object.extend({
151
156
  messages: Em.A(),
152
157
  total: 0,
153
158
 
154
- load: function(opts){
159
+ load: function(opts) {
155
160
  var self = this;
156
161
  opts = opts || {};
157
162
 
@@ -0,0 +1,80 @@
1
+
2
+ module Logster
3
+ class BaseStore
4
+
5
+ attr_accessor :level, :max_retention, :skip_empty, :ignore
6
+
7
+ def initialize
8
+ @dedup = false
9
+ @max_retention = 60 * 60 * 24 * 7
10
+ @skip_empty = true
11
+ end
12
+
13
+ def save(message)
14
+ not_implemented
15
+ end
16
+
17
+ def count
18
+ not_implemented
19
+ end
20
+
21
+ def clear
22
+ not_implemented
23
+ end
24
+
25
+ def clear_all
26
+ not_implemented
27
+ end
28
+
29
+ def get(message_key)
30
+ not_implemented
31
+ end
32
+
33
+ def protect(message_key)
34
+ not_implemented
35
+ end
36
+
37
+ def unprotect(message_key)
38
+ not_implemented
39
+ end
40
+
41
+ def report(severity, progname, message, opts = {})
42
+ return if (!message || (String === message && message.empty?)) && skip_empty
43
+ return if level && severity < level
44
+ return if ignore && ignore.any? { |pattern| message =~ pattern}
45
+
46
+ message = Logster::Message.new(severity, progname, message, opts[:timestamp])
47
+
48
+ env = opts[:env]
49
+ backtrace = opts[:backtrace]
50
+
51
+ if env
52
+ if env[:backtrace]
53
+ # Special - passing backtrace through env
54
+ backtrace = env.delete(:backtrace)
55
+ end
56
+
57
+ message.populate_from_env(env)
58
+ end
59
+
60
+ if backtrace
61
+ if backtrace.respond_to? :join
62
+ backtrace = backtrace.join("\n")
63
+ end
64
+ message.backtrace = backtrace
65
+ else
66
+ message.backtrace = caller.join("\n")
67
+ end
68
+
69
+ save message
70
+
71
+ message
72
+ end
73
+
74
+ private
75
+
76
+ def not_implemented
77
+ raise "Not Implemented"
78
+ end
79
+ end
80
+ end
@@ -1,38 +1,18 @@
1
1
  require 'json'
2
+ require 'logster/base_store'
2
3
 
3
4
  module Logster
4
- class RedisStore
5
+ class RedisStore < BaseStore
5
6
 
6
- attr_accessor :level, :redis, :max_backlog,
7
- :dedup, :max_retention, :skip_empty,
8
- :ignore
7
+ attr_accessor :redis, :max_backlog
9
8
 
10
9
  def initialize(redis = nil)
10
+ super()
11
11
  @redis = redis || Redis.new
12
12
  @max_backlog = 1000
13
- @dedup = false
14
- @max_retention = 60 * 60 * 24 * 7
15
- @skip_empty = true
16
13
  end
17
14
 
18
-
19
- def report(severity, progname, message, opts = nil)
20
- return if (!message || (String === message && message.empty?)) && skip_empty
21
- return if level && severity < level
22
- return if @ignore && @ignore.any?{|pattern| message =~ pattern}
23
-
24
- message = Logster::Message.new(severity, progname, message, (opts && opts[:timestamp]))
25
-
26
- if opts && backtrace = opts[:backtrace]
27
- message.backtrace = backtrace
28
- else
29
- message.backtrace = caller.join("\n")
30
- end
31
-
32
- if opts && env = opts[:env]
33
- message.populate_from_env(env)
34
- end
35
-
15
+ def save(message)
36
16
  # multi for integrity
37
17
  @redis.multi do
38
18
  @redis.hset(hash_key, message.key, message.to_json)
@@ -40,14 +20,12 @@ module Logster
40
20
  end
41
21
 
42
22
  # TODO make it atomic
43
- if @redis.llen(list_key) > @max_backlog
23
+ if @redis.llen(list_key) > max_backlog
44
24
  removed_key = @redis.lpop(list_key)
45
25
  if removed_key && !@redis.sismember(protected_key, removed_key)
46
26
  @redis.hdel(hash_key, removed_key)
47
27
  end
48
28
  end
49
-
50
- message
51
29
  end
52
30
 
53
31
  def count
@@ -1,3 +1,3 @@
1
1
  module Logster
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -1,13 +1,19 @@
1
1
  require_relative '../test_helper'
2
2
  require 'logster/logger'
3
+ require 'logster/redis_store'
3
4
  require 'logger'
4
5
  require 'examples/sidekiq_logster_reporter'
5
6
 
6
7
  class TestSidekiqReporter < MiniTest::Test
7
8
 
8
9
  def setup
9
- Logster.store = @store = Logster::TestStore.new
10
+ Logster.store = @store = Logster::RedisStore.new(Redis.new)
10
11
  Logster.logger = @logger = Logster::Logger.new(Logster.store)
12
+ @store.clear_all
13
+ end
14
+
15
+ def teardown
16
+ @store.clear_all
11
17
  end
12
18
 
13
19
  def test_sidekiq_handler_example
@@ -18,14 +24,23 @@ class TestSidekiqReporter < MiniTest::Test
18
24
  rescue => e
19
25
  error = e
20
26
  end
27
+ trace = error.backtrace
21
28
 
22
29
  handler.call(error, code: "Test", something_important: "Foo", params: { article_id: 20 })
23
30
 
24
- error = Logster.store.reported[0]
31
+ report = @store.latest[0]
32
+
33
+ # Message is right format
34
+ assert_equal("Job exception: TypeError\n", report.message)
35
+
36
+ # A backtrace is joined()
37
+ assert_equal(trace.join("\n"), report.backtrace)
38
+ # The backtrace is deleted from the env
39
+ assert_nil(report.env['backtrace'])
40
+ assert_nil(report.env[:backtrace])
25
41
 
26
- assert(error.backtrace != nil)
27
- assert_equal("Job exception: TypeError\n", error.message)
28
- assert_equal("Test", error.env[:code])
29
- assert_equal(20, error.env[:params][:article_id])
42
+ # The env is in the report
43
+ assert_equal("Test", report.env['code'])
44
+ assert_equal(20, report.env['params']['article_id'])
30
45
  end
31
46
  end
@@ -14,7 +14,7 @@ class TestReporter < Minitest::Test
14
14
  status, = reporter.call(env)
15
15
 
16
16
  assert_equal(200, status)
17
- assert_equal(1, Logster.store.reported.length)
17
+ assert_equal(1, Logster.store.count)
18
18
  end
19
19
 
20
20
  end
@@ -0,0 +1,94 @@
1
+ require_relative '../test_helper'
2
+ require 'logster/base_store'
3
+
4
+ class TestBaseStore < Minitest::Test
5
+
6
+ def setup
7
+ @store = Logster::TestStore.new
8
+ @store.clear_all
9
+ end
10
+
11
+ def teardown
12
+ @store.clear_all
13
+ end
14
+
15
+ def test_report_skip_empty
16
+ @store.skip_empty = true
17
+ @store.report(Logger::WARN, "test", nil)
18
+ @store.report(Logger::WARN, "test", '')
19
+ @store.report(Logger::WARN, "test", "foo") #
20
+ @store.skip_empty = false
21
+ @store.report(Logger::WARN, "test", nil) #
22
+
23
+ assert_equal(2, @store.count)
24
+ end
25
+
26
+ def test_report_skip_level
27
+ @store.level = nil
28
+ @store.report(Logger::DEBUG, "test", "A") #
29
+ @store.level = Logger::WARN
30
+ @store.report(Logger::DEBUG, "test", "A")
31
+ @store.report(Logger::INFO, "test", "B")
32
+ @store.report(Logger::WARN, "test", "C") #
33
+ @store.report(Logger::ERROR, "test", "D") #
34
+ assert_equal(3, @store.count)
35
+ end
36
+
37
+ def test_report_skip_ignore
38
+ @store.report(Logger::WARN, "test", "Can't verify CSRF token authenticity")
39
+ @store.report(Logger::FATAL, "test", "ActiveRecord::RecordNotFound (Couldn't find Upload with 'id'=9947)")
40
+ @store.report(Logger::WARN, "test", "B")
41
+ @store.ignore = [
42
+ /^ActiveRecord::RecordNotFound \(Couldn't find Upload/,
43
+ /^Can't verify CSRF token authenticity/
44
+ ]
45
+ @store.report(Logger::WARN, "test", "Can't verify CSRF token authenticity")
46
+ @store.report(Logger::FATAL, "test", "ActiveRecord::RecordNotFound (Couldn't find Upload with 'id'=9947)")
47
+ @store.report(Logger::FATAL, "test", "ActiveRecord::RecordNotFound (Couldn't find Upload with 'id'=9489+78946947)")
48
+ @store.report(Logger::WARN, "test", "B")
49
+
50
+ assert_equal(4, @store.count)
51
+ end
52
+
53
+ def test_timestamp
54
+ time = Time.now - 24*60*60
55
+ message = @store.report(Logger::WARN, "test", "B", timestamp: time)
56
+
57
+ assert_equal(time, message.timestamp)
58
+ end
59
+
60
+ def test_backtrace
61
+ # Create an error with a backtrace
62
+ error = TypeError.new
63
+ begin
64
+ raise error
65
+ rescue => e
66
+ error = e
67
+ end
68
+
69
+ # Backtrace can be passed via backtrace param or env
70
+ message = @store.report(Logger::WARN, "test", "A", backtrace: error.backtrace)
71
+ assert_equal(error.backtrace.join("\n"), message.backtrace)
72
+ message = @store.report(Logger::WARN, "test", "B", env: {backtrace: error.backtrace})
73
+ assert_equal(error.backtrace.join("\n"), message.backtrace)
74
+
75
+ # Via env takes priority
76
+ message = @store.report(Logger::WARN, "test", "C", backtrace: "Garbage", env: {backtrace: error.backtrace})
77
+ assert_equal(error.backtrace.join("\n"), message.backtrace)
78
+
79
+ # Backtrace is always a string
80
+ # Cannot do an equal assert here, because it uses `caller` when not provided
81
+ message = @store.report(Logger::WARN, "test", "D", backtrace: nil)
82
+ assert_kind_of(String, message.backtrace)
83
+ message = @store.report(Logger::WARN, "test", "E", env: {backtrace: nil})
84
+ assert_kind_of(String, message.backtrace)
85
+ message = @store.report(Logger::WARN, "test", "F", backtrace: nil, env: {backtrace: nil})
86
+ assert_kind_of(String, message.backtrace)
87
+ message = @store.report(Logger::WARN, "test", "G")
88
+ assert_kind_of(String, message.backtrace)
89
+
90
+ # Arrays are turned into strings via join \n
91
+ message = @store.report(Logger::WARN, "test", "H", backtrace: ["Foo", "Bar"])
92
+ assert_equal("Foo\nBar", message.backtrace)
93
+ end
94
+ end
@@ -6,7 +6,7 @@ class TestRedisStore < Minitest::Test
6
6
 
7
7
  def setup
8
8
  @store = Logster::RedisStore.new(Redis.new)
9
- @store.clear
9
+ @store.clear_all
10
10
  end
11
11
 
12
12
  def teardown
data/test/test_helper.rb CHANGED
@@ -4,36 +4,29 @@ require 'minitest/autorun'
4
4
  require 'minitest/pride'
5
5
  require 'logster'
6
6
  require 'redis'
7
+ require 'logster/base_store'
7
8
 
8
-
9
- class Logster::TestStore
9
+ class Logster::TestStore < Logster::BaseStore
10
10
  attr_accessor :reported
11
11
  def initialize
12
12
  @reported = []
13
13
  end
14
14
 
15
- def report(severity, progname, message, opts = nil)
16
- opts ||= {}
17
- env = opts[:env]
18
- backtrace = opts[:backtrace]
19
- if env && !backtrace
20
- backtrace = env[:backtrace]
21
- end
22
-
23
- message = Logster::Message.new(severity, progname, message)
24
-
25
- if backtrace
26
- message.backtrace = backtrace
27
- else
28
- message.backtrace = caller.join("\n")
29
- end
15
+ def save(message)
16
+ @reported << message
17
+ end
30
18
 
31
- if env
32
- message.populate_from_env(env)
33
- end
19
+ def count
20
+ @reported.count
21
+ end
34
22
 
35
- @reported << message
23
+ def clear
24
+ @reported = []
25
+ end
36
26
 
37
- message
27
+ def clear_all
28
+ @reported = []
38
29
  end
30
+
31
+ # get, protect, unprotect: unimplemented
39
32
  end
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.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - UI for viewing logs in Rack
@@ -126,6 +126,7 @@ files:
126
126
  - bower.json
127
127
  - lib/examples/sidekiq_logster_reporter.rb
128
128
  - lib/logster.rb
129
+ - lib/logster/base_store.rb
129
130
  - lib/logster/configuration.rb
130
131
  - lib/logster/logger.rb
131
132
  - lib/logster/message.rb
@@ -140,6 +141,7 @@ files:
140
141
  - test/examples/test_sidekiq_reporter_example.rb
141
142
  - test/logster/middleware/test_reporter.rb
142
143
  - test/logster/middleware/test_viewer.rb
144
+ - test/logster/test_base_store.rb
143
145
  - test/logster/test_logger.rb
144
146
  - test/logster/test_redis_store.rb
145
147
  - test/test_helper.rb
@@ -172,6 +174,7 @@ test_files:
172
174
  - test/examples/test_sidekiq_reporter_example.rb
173
175
  - test/logster/middleware/test_reporter.rb
174
176
  - test/logster/middleware/test_viewer.rb
177
+ - test/logster/test_base_store.rb
175
178
  - test/logster/test_logger.rb
176
179
  - test/logster/test_redis_store.rb
177
180
  - test/test_helper.rb