logsaber 0.0.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +1 -0
- data/.travis.yml +11 -0
- data/README.markdown +70 -30
- data/lib/logsaber.rb +8 -97
- data/lib/logsaber/entry.rb +66 -0
- data/lib/logsaber/formatter.rb +63 -0
- data/lib/logsaber/log.rb +75 -0
- data/lib/logsaber/options.rb +15 -0
- data/lib/logsaber/simple_color.rb +21 -0
- data/lib/logsaber/version.rb +2 -2
- data/spec/{logsaber_spec.rb → log_spec.rb} +47 -3
- metadata +11 -5
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm --create ruby-1.9.3-p385@logsaber
|
data/.travis.yml
ADDED
data/README.markdown
CHANGED
@@ -3,10 +3,17 @@ Logsaber
|
|
3
3
|
|
4
4
|
A logger for a more civilized age.
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
- Edge Logsaber README: https://github.com/acook/logsaber#readme
|
7
|
+
- Release version README: http://rubydoc.info/gems/logsaber/file/README.markdown
|
8
8
|
|
9
|
-
|
9
|
+
[![Build Status](https://travis-ci.org/acook/logsaber.png?branch=master)](https://travis-ci.org/acook/logsaber)
|
10
|
+
[![Code Climate](https://codeclimate.com/github/acook/logsaber.png)](https://codeclimate.com/github/acook/logsaber)
|
11
|
+
[![Dependency Status](https://gemnasium.com/acook/logsaber.png)](https://gemnasium.com/acook/logsaber)
|
12
|
+
|
13
|
+
Philosophy / Why Logsaber?
|
14
|
+
--------------------------
|
15
|
+
|
16
|
+
Logsaber is a lot like Ruby's built in [Logger](http://www.ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html) class,
|
10
17
|
but it is based on the real world experience of how I actually use loggers.
|
11
18
|
|
12
19
|
The biggest difference is Logsaber's intelligent output.
|
@@ -51,40 +58,59 @@ end
|
|
51
58
|
...Logsaber will intelligently evaluate it and format your output sanely:
|
52
59
|
|
53
60
|
```
|
54
|
-
2013-03-02 21:20:04.715 [ INFO] 32981 | heavy :
|
61
|
+
2013-03-02 21:20:04.715 [ INFO] 32981 | heavy : "this could be resource intensive" | 9999
|
55
62
|
```
|
56
63
|
|
57
|
-
Also, since blocks are lazy loaded, they won't be evaluated at all if the severity is below the log level threshold,
|
64
|
+
Also, since blocks are lazy loaded, they won't be evaluated at all if the severity is below the log level threshold,
|
65
|
+
this is really important if your debug output is resource intensive.
|
58
66
|
|
59
67
|
### Ruby Logger Limitations Surpassed
|
60
68
|
|
61
69
|
There's also some complaints about the native Logger than I address:
|
62
70
|
|
63
|
-
1. You can't specify the log level on instantiation
|
64
|
-
- Logsaber lets you set the log level when you create it:
|
65
|
-
`$log = Logsaber.create file, :warn`
|
66
|
-
- But you can still change the default later:
|
67
|
-
`$log.level = :info`
|
68
|
-
2. You must specify the "progname" for every event
|
69
|
-
- Logsaber lets you set the app name when you create it:
|
70
|
-
`$log = Logsaber.create file, :warn, 'MyApp'`
|
71
|
-
- Or change it to something else at any time:
|
72
|
-
`$log.appname = 'SomethingElse'`
|
71
|
+
1. You can't specify the log level on instantiation.
|
73
72
|
|
74
|
-
|
75
|
-
|
73
|
+
Logsaber lets you set the log level when you create it:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
$log = Logsaber.create level: :warn
|
77
|
+
```
|
78
|
+
|
79
|
+
But you can still change the default later:
|
76
80
|
|
77
|
-
|
81
|
+
```ruby
|
82
|
+
$log.level = :info
|
83
|
+
```
|
78
84
|
|
79
|
-
|
85
|
+
2. You must specify the "progname" for every event.
|
80
86
|
|
81
|
-
|
87
|
+
Logsaber lets you set your app's name when you create it:
|
82
88
|
|
83
|
-
|
89
|
+
```ruby
|
90
|
+
$log = Logsaber.create appname: 'MyApp'
|
91
|
+
```
|
92
|
+
|
93
|
+
Or change it to something else at any time:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
$log.appname = 'SomethingElse'
|
97
|
+
```
|
98
|
+
|
99
|
+
...and the output will look like this:
|
100
|
+
|
101
|
+
```
|
102
|
+
2013-03-03 16:50:43.595 [ INFO] SomethingElse:8881 | MSG : ohai
|
103
|
+
```
|
104
|
+
|
105
|
+
Installation
|
106
|
+
------------
|
84
107
|
|
85
|
-
|
108
|
+
Use [Bundler](http://gembundler.com):
|
86
109
|
|
87
|
-
|
110
|
+
```ruby
|
111
|
+
# in your Gemfile
|
112
|
+
gem 'logsaber'
|
113
|
+
```
|
88
114
|
|
89
115
|
Setup
|
90
116
|
-----
|
@@ -95,13 +121,13 @@ Give it a filename and it will log to a file:
|
|
95
121
|
$log = Logsaber.create './log/my_app.log'
|
96
122
|
```
|
97
123
|
|
98
|
-
|
124
|
+
Or you log to an IO (`$stdout` is the default, good for debugging):
|
99
125
|
|
100
126
|
```ruby
|
101
127
|
$log = Logsaber.create $stdout
|
102
128
|
```
|
103
129
|
|
104
|
-
|
130
|
+
It can even log to a StringIO (good for test environments):
|
105
131
|
|
106
132
|
```ruby
|
107
133
|
require 'stringio'
|
@@ -110,16 +136,22 @@ stringio = StringIO.create
|
|
110
136
|
$log = Logsaber.create stringio
|
111
137
|
```
|
112
138
|
|
113
|
-
You can also set the log level on initialization (it's
|
139
|
+
You can also set the log level on initialization (it's `:info` by default):
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
$log = Logsaber.create level: :debug
|
143
|
+
```
|
144
|
+
|
145
|
+
And you can optionally specify the name of your app (which is `nil` by default, it's displayed next to the pid in the output):
|
114
146
|
|
115
147
|
```ruby
|
116
|
-
$log = Logsaber.create
|
148
|
+
$log = Logsaber.create appname: 'MyApp'
|
117
149
|
```
|
118
150
|
|
119
|
-
|
151
|
+
Example with all options:
|
120
152
|
|
121
153
|
```ruby
|
122
|
-
|
154
|
+
Logsaber.create 'my_app.log', level: :debug, appname: 'MyApp'
|
123
155
|
```
|
124
156
|
|
125
157
|
Usage
|
@@ -135,12 +167,20 @@ like this:
|
|
135
167
|
$log.warn 'Something might be amiss here'
|
136
168
|
```
|
137
169
|
|
138
|
-
or this:
|
170
|
+
or like this:
|
139
171
|
|
140
172
|
```ruby
|
141
173
|
$log.error 'PEBKAC', @user
|
142
174
|
```
|
143
175
|
|
176
|
+
or maybe:
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
@log.debug "What is this I don't even." do
|
180
|
+
big_data.inspect
|
181
|
+
end
|
182
|
+
```
|
183
|
+
|
144
184
|
Contributing
|
145
185
|
------------
|
146
186
|
|
data/lib/logsaber.rb
CHANGED
@@ -1,100 +1,11 @@
|
|
1
1
|
require 'logsaber/version'
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
else
|
11
|
-
new_output
|
12
|
-
end
|
13
|
-
|
14
|
-
log.level = new_level
|
15
|
-
log.appname = new_appname
|
16
|
-
|
17
|
-
log
|
18
|
-
end
|
19
|
-
attr_accessor :output, :level, :appname, :time_format
|
20
|
-
|
21
|
-
DEFAULT_TIME_FORMAT ||= '%Y-%m-%d %H:%M:%S.%L'
|
22
|
-
SEVERITY_LEVELS ||= [:debug, :info, :warn, :error, :fatal]
|
23
|
-
|
24
|
-
SEVERITY_LEVELS.each do |method_name|
|
25
|
-
eval <<-END_OF_METHOD
|
26
|
-
def #{method_name} *args, &block
|
27
|
-
log :#{method_name}, *args, &block
|
28
|
-
end
|
29
|
-
END_OF_METHOD
|
30
|
-
end
|
31
|
-
|
32
|
-
def level= new_level
|
33
|
-
@level = new_level if SEVERITY_LEVELS.include? new_level
|
34
|
-
end
|
35
|
-
|
36
|
-
def time_format
|
37
|
-
@time_format ||= DEFAULT_TIME_FORMAT
|
38
|
-
end
|
39
|
-
|
40
|
-
protected
|
41
|
-
|
42
|
-
def log severity, *details
|
43
|
-
return unless loggable? severity
|
44
|
-
label, info, object = extract_details details, block_given?
|
45
|
-
|
46
|
-
if block_given? then
|
47
|
-
result = yield
|
48
|
-
|
49
|
-
info << ' | ' unless info.empty?
|
50
|
-
info << result.to_s
|
51
|
-
|
52
|
-
object = result
|
53
|
-
end
|
54
|
-
|
55
|
-
message = format severity, "#{label} : #{info}"
|
56
|
-
output.puts message
|
57
|
-
output.flush
|
58
|
-
|
59
|
-
object
|
60
|
-
end
|
61
|
-
|
62
|
-
def extract_details details, given_block
|
63
|
-
primary, secondary, object = details
|
64
|
-
|
65
|
-
if details.length == 2 then
|
66
|
-
[primary.to_s, secondary.inspect, object || secondary]
|
67
|
-
elsif given_block then
|
68
|
-
[primary, secondary.to_s, object]
|
69
|
-
elsif [String, Numeric].any?{|klass| primary.is_a? klass} then
|
70
|
-
['MSG', primary, object || primary]
|
71
|
-
else
|
72
|
-
['OBJ', primary.to_s, object || primary]
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def loggable? severity
|
77
|
-
SEVERITY_LEVELS.index(severity) >= SEVERITY_LEVELS.index(level)
|
78
|
-
end
|
79
|
-
|
80
|
-
def format severity, contents
|
81
|
-
%Q{#{timestamp} [#{severity_info severity}] #{process_info} | #{contents}}
|
82
|
-
end
|
83
|
-
|
84
|
-
def process_info
|
85
|
-
pid = Process.pid.to_s
|
86
|
-
appname? ? "#{appname}:#{pid}" : pid
|
87
|
-
end
|
88
|
-
|
89
|
-
def severity_info severity
|
90
|
-
severity.to_s.upcase.rjust 5
|
91
|
-
end
|
92
|
-
|
93
|
-
def timestamp
|
94
|
-
Time.now.strftime time_format
|
95
|
-
end
|
96
|
-
|
97
|
-
def appname?
|
98
|
-
!!@appname
|
2
|
+
require 'logsaber/formatter'
|
3
|
+
require 'logsaber/log'
|
4
|
+
require 'logsaber/options'
|
5
|
+
require 'logsaber/entry'
|
6
|
+
|
7
|
+
module Logsaber
|
8
|
+
def self.create *args, &block
|
9
|
+
Log.create *args, &block
|
99
10
|
end
|
100
11
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Logsaber
|
2
|
+
class Entry
|
3
|
+
def self.create all_details, &block
|
4
|
+
all_details << block.call if block
|
5
|
+
new all_details.length, all_details.shift, Array(all_details)
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize length, primary, secondary
|
9
|
+
@length, @primary, @secondary = length, primary, secondary
|
10
|
+
end
|
11
|
+
attr :length, :primary, :secondary
|
12
|
+
|
13
|
+
def parse
|
14
|
+
[text, value]
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def value
|
20
|
+
secondary.last || primary
|
21
|
+
end
|
22
|
+
|
23
|
+
def text
|
24
|
+
"#{label} : #{info}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def label
|
28
|
+
if !secondary.empty? then
|
29
|
+
view primary
|
30
|
+
elsif primary.is_a? String then
|
31
|
+
'MSG'
|
32
|
+
else
|
33
|
+
'OBJ'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def info
|
38
|
+
if secondary.empty? then
|
39
|
+
view primary
|
40
|
+
else
|
41
|
+
details
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def details
|
46
|
+
secondary.map{|item| analyze item }.join ' | '
|
47
|
+
end
|
48
|
+
|
49
|
+
def view object
|
50
|
+
viewable?(object) ? object.to_s : object.inspect
|
51
|
+
end
|
52
|
+
|
53
|
+
def analyze object
|
54
|
+
analyzeable?(object) ? object : object.inspect
|
55
|
+
end
|
56
|
+
|
57
|
+
def viewable? object
|
58
|
+
object && (analyzeable?(object) || object.is_a?(Symbol))
|
59
|
+
end
|
60
|
+
|
61
|
+
def analyzeable? object
|
62
|
+
object.is_a?(String) && !object.empty?
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Logsaber
|
2
|
+
class Formatter
|
3
|
+
DEFAULT_TIME_FORMAT ||= '%Y-%m-%d %H:%M:%S.%L'
|
4
|
+
|
5
|
+
def initialize color = nil
|
6
|
+
@color = color
|
7
|
+
end
|
8
|
+
attr_accessor :time_format, :log, :color
|
9
|
+
|
10
|
+
def set_log new_log
|
11
|
+
self.log = new_log
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
def time_format
|
16
|
+
@time_format ||= DEFAULT_TIME_FORMAT
|
17
|
+
end
|
18
|
+
|
19
|
+
def color!
|
20
|
+
@color = SimpleColor.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def color?
|
24
|
+
!!@color
|
25
|
+
end
|
26
|
+
|
27
|
+
def format severity, contents
|
28
|
+
index = log.class::SEVERITY_LEVELS.index(severity)
|
29
|
+
text = layout severity, contents
|
30
|
+
|
31
|
+
if color? then
|
32
|
+
color.colorize index, text
|
33
|
+
else
|
34
|
+
text
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def layout severity, contents
|
39
|
+
%(#{timestamp} [#{severity_info severity}] #{process_info} | #{contents})
|
40
|
+
end
|
41
|
+
|
42
|
+
def timestamp
|
43
|
+
Time.now.strftime time_format
|
44
|
+
end
|
45
|
+
|
46
|
+
def severity_info severity
|
47
|
+
severity.to_s.upcase.rjust 5
|
48
|
+
end
|
49
|
+
|
50
|
+
def process_info
|
51
|
+
pid = Process.pid.to_s
|
52
|
+
appname? ? "#{appname}:#{pid}" : pid
|
53
|
+
end
|
54
|
+
|
55
|
+
def appname?
|
56
|
+
!!appname
|
57
|
+
end
|
58
|
+
|
59
|
+
def appname
|
60
|
+
log.appname
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/logsaber/log.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
module Logsaber
|
2
|
+
class Log
|
3
|
+
class << self
|
4
|
+
def create *args
|
5
|
+
default_options = {
|
6
|
+
output: $stdout,
|
7
|
+
level: :info,
|
8
|
+
appname: nil,
|
9
|
+
formatter: Logsaber::Formatter.new
|
10
|
+
}
|
11
|
+
options = Options.extract_from args, default_options, :output
|
12
|
+
|
13
|
+
self.new *options
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
SEVERITY_LEVELS ||= [:debug, :info, :warn, :error, :fatal, :off]
|
18
|
+
|
19
|
+
def initialize output, level, appname, formatter
|
20
|
+
@output = outputize output
|
21
|
+
@level = level.to_sym
|
22
|
+
@appname = appname
|
23
|
+
@formatter = formatter.set_log self
|
24
|
+
|
25
|
+
unless SEVERITY_LEVELS.include? @level then
|
26
|
+
raise "Invalid level: #{level.inspect}.\nUse one of: #{SEVERITY_LEVELS}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_accessor :output, :level, :appname, :formatter
|
31
|
+
|
32
|
+
SEVERITY_LEVELS.each do |method_name|
|
33
|
+
next if method_name == :off
|
34
|
+
|
35
|
+
eval <<-END_OF_METHOD
|
36
|
+
def #{method_name} *args, &block
|
37
|
+
log :#{method_name}, *args, &block
|
38
|
+
end
|
39
|
+
END_OF_METHOD
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
def log severity, *details, &block
|
45
|
+
return unless loggable? severity
|
46
|
+
message, object = Entry.create(details, &block).parse
|
47
|
+
|
48
|
+
out format(severity, message)
|
49
|
+
object
|
50
|
+
end
|
51
|
+
|
52
|
+
def out text
|
53
|
+
output.puts text
|
54
|
+
output.flush
|
55
|
+
end
|
56
|
+
|
57
|
+
def format *args
|
58
|
+
formatter.format *args
|
59
|
+
end
|
60
|
+
|
61
|
+
def loggable? severity
|
62
|
+
SEVERITY_LEVELS.index(severity) >= SEVERITY_LEVELS.index(level)
|
63
|
+
end
|
64
|
+
|
65
|
+
def outputize new_output
|
66
|
+
if new_output.is_a? String then
|
67
|
+
File.new new_output, 'a'
|
68
|
+
elsif new_output.respond_to? :puts then
|
69
|
+
new_output
|
70
|
+
else
|
71
|
+
raise "invalid output object: #{new_output.inspect}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Logsaber
|
2
|
+
class Options < OpenStruct
|
3
|
+
def self.extract_from args, defaults = {}, primary = nil
|
4
|
+
options = args.last.is_a?(Hash) ? args.pop : Hash.new
|
5
|
+
options[primary] = args.shift if primary && args.first
|
6
|
+
|
7
|
+
new defaults.merge(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_a
|
11
|
+
@table.values
|
12
|
+
end
|
13
|
+
alias_method :to_ary, :to_a
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Logsaber
|
2
|
+
class SimpleColor
|
3
|
+
attr_accessor colors
|
4
|
+
|
5
|
+
def colorize index, text = nil, &block
|
6
|
+
"#{color index}#{text || yield}#{esc 0}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def color index
|
10
|
+
esc colors[index]
|
11
|
+
end
|
12
|
+
|
13
|
+
def colors
|
14
|
+
@colors = [31, 0, 33, 31, '31;1']
|
15
|
+
end
|
16
|
+
|
17
|
+
def esc seq
|
18
|
+
"\e[#{seq}m"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/logsaber/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "0.0
|
1
|
+
module Logsaber
|
2
|
+
VERSION = "1.0.0"
|
3
3
|
end
|
@@ -72,11 +72,11 @@ spec 'basic usage' do
|
|
72
72
|
@output.string.include? format('MSG', test_string)
|
73
73
|
end
|
74
74
|
|
75
|
-
spec '
|
75
|
+
spec 'with details usage' do
|
76
76
|
clear_log
|
77
77
|
|
78
78
|
@log.info :test_string, test_string
|
79
|
-
@output.string.include? format(:test_string, test_string
|
79
|
+
@output.string.include? format(:test_string, test_string)
|
80
80
|
end
|
81
81
|
|
82
82
|
spec 'object usage' do
|
@@ -102,6 +102,50 @@ spec 'block with details usage' do
|
|
102
102
|
@log.info 'label', 'details' do
|
103
103
|
'block'
|
104
104
|
end
|
105
|
-
@output.string.include?(format('label', '
|
105
|
+
@output.string.include?(format('label', 'details | block')) || @output.string
|
106
106
|
end
|
107
107
|
|
108
|
+
spec 'accepts appname during creation' do
|
109
|
+
clear_log
|
110
|
+
|
111
|
+
log = Logsaber.create output: @output, appname: 'MyAwesomeApp'
|
112
|
+
|
113
|
+
log.info 'ohai'
|
114
|
+
@output.string.include?("[ INFO] MyAwesomeApp:#{Process.pid} | MSG : ohai") || @output.string
|
115
|
+
end
|
116
|
+
|
117
|
+
spec 'setting level to :off will prevent any logging' do
|
118
|
+
output = capture do
|
119
|
+
log = Logsaber.create level: :off
|
120
|
+
|
121
|
+
log.debug 'debug'
|
122
|
+
log.info 'info'
|
123
|
+
log.warn 'warn'
|
124
|
+
log.error 'error'
|
125
|
+
log.fatal 'fatal'
|
126
|
+
end
|
127
|
+
|
128
|
+
output.empty? || output
|
129
|
+
end
|
130
|
+
|
131
|
+
spec 'there is no "off" method' do
|
132
|
+
!@log.respond_to? :off
|
133
|
+
end
|
134
|
+
|
135
|
+
spec 'timestamp format is mutable' do
|
136
|
+
clear_log
|
137
|
+
|
138
|
+
@log.formatter.time_format = 'xxx%Yxxx'
|
139
|
+
@log.info test_string
|
140
|
+
@log.formatter.time_format = Logsaber::Formatter::DEFAULT_TIME_FORMAT
|
141
|
+
|
142
|
+
match = @output.string.match /(xxx\d\d\d\dxxx) (#{Regexp.escape format('MSG', test_string)})/
|
143
|
+
!match[0].nil? && !match[1].nil? || match rescue @output.string
|
144
|
+
end
|
145
|
+
|
146
|
+
spec 'Log#log allows many items' do
|
147
|
+
clear_log
|
148
|
+
|
149
|
+
@log.info :foo, '1', '2', '3'
|
150
|
+
@output.string.include? format('foo', '1 | 2 | 3')
|
151
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logsaber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: uspec
|
@@ -35,14 +35,21 @@ extensions: []
|
|
35
35
|
extra_rdoc_files: []
|
36
36
|
files:
|
37
37
|
- .gitignore
|
38
|
+
- .rvmrc
|
39
|
+
- .travis.yml
|
38
40
|
- Gemfile
|
39
41
|
- LICENSE.txt
|
40
42
|
- README.markdown
|
41
43
|
- Rakefile
|
42
44
|
- lib/logsaber.rb
|
45
|
+
- lib/logsaber/entry.rb
|
46
|
+
- lib/logsaber/formatter.rb
|
47
|
+
- lib/logsaber/log.rb
|
48
|
+
- lib/logsaber/options.rb
|
49
|
+
- lib/logsaber/simple_color.rb
|
43
50
|
- lib/logsaber/version.rb
|
44
51
|
- logsaber.gemspec
|
45
|
-
- spec/
|
52
|
+
- spec/log_spec.rb
|
46
53
|
- spec/spec_helper.rb
|
47
54
|
homepage: http://github.com/acook/logsaber
|
48
55
|
licenses: []
|
@@ -69,6 +76,5 @@ signing_key:
|
|
69
76
|
specification_version: 3
|
70
77
|
summary: A logger for a more civilized age.
|
71
78
|
test_files:
|
72
|
-
- spec/
|
79
|
+
- spec/log_spec.rb
|
73
80
|
- spec/spec_helper.rb
|
74
|
-
has_rdoc:
|