logsaber 0.0.1 → 1.0.0
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.
- 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
|
+
[](https://travis-ci.org/acook/logsaber)
|
10
|
+
[](https://codeclimate.com/github/acook/logsaber)
|
11
|
+
[](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:
|