logger_facade 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- data/.rspec +1 -1
- data/Gemfile.lock +31 -25
- data/README.md +127 -25
- data/lib/logger_facade/log.rb +14 -12
- data/lib/logger_facade/middleware/rack.rb +43 -0
- data/lib/logger_facade/plugins.rb +2 -0
- data/lib/logger_facade/plugins/base.rb +59 -0
- data/lib/logger_facade/plugins/console.rb +19 -55
- data/lib/logger_facade/plugins/logstash.rb +64 -0
- data/lib/logger_facade/version.rb +1 -1
- data/logger_facade.gemspec +3 -0
- data/spec/spec_helper.rb +28 -0
- data/spec/unit/log_spec.rb +45 -1
- data/spec/unit/middleware/rack_spec.rb +107 -0
- data/spec/unit/plugins/console_spec.rb +2 -13
- data/spec/unit/plugins/logstash_spec.rb +207 -0
- metadata +37 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a44006ba93de9dceaa753368eb3b452fe733e416
|
4
|
+
data.tar.gz: 654b4861ab41420d47ed09e825af6672c7a8683b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57d9fa7a05c8819f5976d0b38296d8efa1a5a4e55a2989339ecb03ec0af7166ebb72ab3d6638350d27dbb57db693167f8b20cb7509a9ea7195bde31256aaea1c
|
7
|
+
data.tar.gz: da2c70344b93d61fc57d6d84804a959f56aa6977032ab149e8edc2aa003daa13b815fa5078c79fc66a9344194fe0477c8c6269649158fec4a89b20d66d079942
|
data/.rspec
CHANGED
@@ -1 +1 @@
|
|
1
|
-
-f doc --color
|
1
|
+
-f doc --color --require spec_helper
|
data/Gemfile.lock
CHANGED
@@ -1,55 +1,60 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
logger_facade (0.
|
4
|
+
logger_facade (0.3.0)
|
5
5
|
airbrake (~> 4.0)
|
6
6
|
hashie (~> 3.2)
|
7
7
|
sucker_punch (~> 1.1)
|
8
|
+
yajl-ruby (~> 1.2)
|
8
9
|
|
9
10
|
GEM
|
10
11
|
remote: https://rubygems.org/
|
11
12
|
specs:
|
12
|
-
airbrake (4.
|
13
|
+
airbrake (4.1.0)
|
13
14
|
builder
|
14
15
|
multi_json
|
15
16
|
builder (3.2.2)
|
16
|
-
bump (0.5.
|
17
|
-
celluloid (0.
|
18
|
-
timers (~>
|
19
|
-
codeclimate-test-reporter (0.
|
17
|
+
bump (0.5.1)
|
18
|
+
celluloid (0.16.0)
|
19
|
+
timers (~> 4.0.0)
|
20
|
+
codeclimate-test-reporter (0.4.4)
|
20
21
|
simplecov (>= 0.7.1, < 1.0.0)
|
21
22
|
coderay (1.1.0)
|
22
23
|
diff-lcs (1.2.5)
|
23
24
|
docile (1.1.5)
|
24
|
-
hashie (3.2
|
25
|
+
hashie (3.3.2)
|
26
|
+
hitimes (1.2.2)
|
25
27
|
method_source (0.8.2)
|
26
28
|
multi_json (1.10.1)
|
27
|
-
pry (0.10.
|
29
|
+
pry (0.10.1)
|
28
30
|
coderay (~> 1.1.0)
|
29
31
|
method_source (~> 0.8.1)
|
30
32
|
slop (~> 3.4)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
rspec-
|
35
|
-
rspec-
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
rack (1.6.0)
|
34
|
+
rake (10.4.2)
|
35
|
+
rspec (3.1.0)
|
36
|
+
rspec-core (~> 3.1.0)
|
37
|
+
rspec-expectations (~> 3.1.0)
|
38
|
+
rspec-mocks (~> 3.1.0)
|
39
|
+
rspec-core (3.1.7)
|
40
|
+
rspec-support (~> 3.1.0)
|
41
|
+
rspec-expectations (3.1.2)
|
39
42
|
diff-lcs (>= 1.2.0, < 2.0)
|
40
|
-
rspec-support (~> 3.
|
41
|
-
rspec-mocks (3.
|
42
|
-
rspec-support (~> 3.
|
43
|
-
rspec-support (3.
|
44
|
-
simplecov (0.9.
|
43
|
+
rspec-support (~> 3.1.0)
|
44
|
+
rspec-mocks (3.1.3)
|
45
|
+
rspec-support (~> 3.1.0)
|
46
|
+
rspec-support (3.1.2)
|
47
|
+
simplecov (0.9.1)
|
45
48
|
docile (~> 1.1.0)
|
46
|
-
multi_json
|
49
|
+
multi_json (~> 1.0)
|
47
50
|
simplecov-html (~> 0.8.0)
|
48
51
|
simplecov-html (0.8.0)
|
49
52
|
slop (3.6.0)
|
50
|
-
sucker_punch (1.
|
51
|
-
celluloid (~> 0.
|
52
|
-
timers (
|
53
|
+
sucker_punch (1.3.2)
|
54
|
+
celluloid (~> 0.16.0)
|
55
|
+
timers (4.0.1)
|
56
|
+
hitimes
|
57
|
+
yajl-ruby (1.2.1)
|
53
58
|
|
54
59
|
PLATFORMS
|
55
60
|
ruby
|
@@ -60,6 +65,7 @@ DEPENDENCIES
|
|
60
65
|
codeclimate-test-reporter (~> 0.3)
|
61
66
|
logger_facade!
|
62
67
|
pry (~> 0.10)
|
68
|
+
rack (~> 1.6)
|
63
69
|
rake (~> 10.3)
|
64
70
|
rspec (~> 3.0)
|
65
71
|
simplecov (~> 0.9)
|
data/README.md
CHANGED
@@ -39,13 +39,6 @@ Set up plugins
|
|
39
39
|
```ruby
|
40
40
|
require 'logger_facade'
|
41
41
|
|
42
|
-
# this is default config for Console plugin
|
43
|
-
config = {
|
44
|
-
level: :info,
|
45
|
-
time_format: '%y-%M-%d %H:%M:%S',
|
46
|
-
message_format: '%time | %level | %logger - %msg'
|
47
|
-
}
|
48
|
-
|
49
42
|
# configuration is optional in console plugin
|
50
43
|
plugin = LoggerFacade::Plugins::Console.new(config);
|
51
44
|
|
@@ -65,10 +58,52 @@ log.error(Exception.new("some caught exception"))
|
|
65
58
|
|
66
59
|
**NOTE**: Console plugin uses check [strftime](http://www.ruby-doc.org/core-2.1.2/Time.html#method-i-strftime) formats.
|
67
60
|
|
61
|
+
### With Sinatra
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
require 'logger_facade'
|
65
|
+
require 'logger_facade/middleware/rack'
|
66
|
+
|
67
|
+
plugin = LoggerFacade::Plugins::Console.new({ level: Settings.logging.console.level })
|
68
|
+
LoggerFacade::Manager.use(plugin)
|
69
|
+
|
70
|
+
set :logging, nil
|
71
|
+
use LoggerFacade::Middleware::Rack
|
72
|
+
```
|
73
|
+
|
74
|
+
### Injecting log with LoggerFacade::Loggable module
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
class AwesomeLog
|
78
|
+
include LoggerFacade::Loggable
|
79
|
+
|
80
|
+
def action
|
81
|
+
log.debug("This will allow you to log into Logger with class name, here is 'AwesomeLog'")
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
# equivalent to
|
87
|
+
|
88
|
+
class AwesomeLog
|
89
|
+
|
90
|
+
def action
|
91
|
+
log.debug("This will allow you to log into Logger with class name, here is 'AwesomeLog'")
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def log
|
97
|
+
@log ||= LoggerFacade::Manager.get_logger("AwesomeLog")
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
```
|
102
|
+
|
68
103
|
## Available plugins
|
69
|
-
* Console
|
70
|
-
* Airbrake
|
71
|
-
*
|
104
|
+
* [Console](#loggerfacadepluginsconsole)
|
105
|
+
* [Airbrake](#loggerfacadepluginsairbrake)
|
106
|
+
* [Logstash](loggerfacadepluginslogstash)
|
72
107
|
|
73
108
|
** Do you need some other plugin?**
|
74
109
|
|
@@ -91,30 +126,96 @@ log = LoggerFacade::Manager.getLogger("Log Name")
|
|
91
126
|
|
92
127
|
```ruby
|
93
128
|
log.isDebug() # return if in debug or trace level
|
129
|
+
metadata = { metadata: "some more context" }
|
130
|
+
# log.trace(message, metadata = {})
|
94
131
|
log.trace("trace something")
|
132
|
+
# log.debug(message, metadata = {})
|
95
133
|
log.debug("debug something")
|
134
|
+
# log.info(message, metadata = {})
|
96
135
|
log.info("info something")
|
136
|
+
# log.warn(message, metadata = {})
|
97
137
|
log.warn("warn something")
|
98
|
-
log.error(
|
138
|
+
# log.error(message, metadata = {})
|
139
|
+
log.error("error something", metadata)
|
99
140
|
log.error(Exception.new('some caught exception'))
|
100
141
|
```
|
101
142
|
|
102
|
-
##
|
143
|
+
## Plugins available
|
144
|
+
|
145
|
+
### LoggerFacade::Plugins::Console
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
# this is default config for Console plugin
|
149
|
+
config = {
|
150
|
+
level: :info,
|
151
|
+
time_format: '%y-%M-%d %H:%M:%S',
|
152
|
+
message_format: '%time | %level | %logger - %msg'
|
153
|
+
}
|
154
|
+
|
155
|
+
# configuration is optional in console plugin
|
156
|
+
plugin = LoggerFacade::Plugins::Console.new(config);
|
157
|
+
LoggerFacade::Manager.use(plugin)
|
158
|
+
```
|
103
159
|
|
104
|
-
|
160
|
+
### LoggerFacade::Plugins::Airbrake
|
105
161
|
|
162
|
+
```ruby
|
163
|
+
env = 'production'
|
164
|
+
plugin = LoggerFacade::Plugins::Airbrake.new(env)
|
165
|
+
plugin.configure do |config|
|
166
|
+
config.api_key = "airbrake.api_key"
|
167
|
+
config.host = "airbrake.host"
|
168
|
+
config.port = "airbrake.port"
|
169
|
+
config.secure = config.port == 443
|
170
|
+
end
|
171
|
+
LoggerFacade::Manager.use(plugin)
|
106
172
|
```
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
#
|
112
|
-
|
113
|
-
|
114
|
-
#
|
115
|
-
|
173
|
+
|
174
|
+
### LoggerFacade::Plugins::Logstash
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
# this is default config for Console plugin
|
178
|
+
config = { level: :debug }
|
179
|
+
|
180
|
+
# configuration is optional in Logstash plugin
|
181
|
+
plugin = LoggerFacade::Plugins::Logstash.new(config);
|
182
|
+
LoggerFacade::Manager.use(plugin)
|
183
|
+
|
184
|
+
|
185
|
+
# by default logrotation is disabled and you should consider using a proper tool such logrotate.
|
186
|
+
# but you can use some Logger (from stdlib) options.
|
187
|
+
config = {
|
188
|
+
level: :debug
|
189
|
+
device: {
|
190
|
+
shift_age: 'daily', # (optional) daily/weekly/monthly
|
191
|
+
shift_size: 1024000 # (optional) bytes
|
192
|
+
}
|
193
|
+
}
|
194
|
+
|
116
195
|
```
|
117
196
|
|
197
|
+
## LoggerFacade::Plugins
|
198
|
+
|
199
|
+
If you wanna use a custom plugin you just need to use an object that responds to the following contract:
|
200
|
+
|
201
|
+
```ruby
|
202
|
+
# the plugin name
|
203
|
+
plugin.name
|
204
|
+
# the plugin configuration
|
205
|
+
plugin.config
|
206
|
+
# the plugin level
|
207
|
+
plugin.level
|
208
|
+
|
209
|
+
def isDebug() # return if in debug or trace level
|
210
|
+
def trace(logger, message, metadata: {})
|
211
|
+
def debug(logger, message, metadata: {})
|
212
|
+
def info(logger, message, metadata: {})
|
213
|
+
def warn(logger, message, metadata: {})
|
214
|
+
def error(logger, message, metadata: {})
|
215
|
+
def error(logger, exception, metadata: {})
|
216
|
+
```
|
217
|
+
|
218
|
+
|
118
219
|
## Contributing
|
119
220
|
|
120
221
|
1. Fork it
|
@@ -126,18 +227,19 @@ The plugins must follow this contract:
|
|
126
227
|
## Bump versioning
|
127
228
|
|
128
229
|
We use [bump gem](https://github.com/gregorym/bump) to control gem versioning.
|
230
|
+
Use --tag to generate commit and tag for each version.
|
129
231
|
|
130
232
|
Bump Patch version
|
131
233
|
|
132
|
-
$ bump patch
|
234
|
+
$ bump patch --tag
|
133
235
|
|
134
236
|
Bump Minor version
|
135
237
|
|
136
|
-
$ bump minor
|
238
|
+
$ bump minor --tag
|
137
239
|
|
138
240
|
Bump Major version
|
139
241
|
|
140
|
-
$ bump major
|
242
|
+
$ bump major --tag
|
141
243
|
|
142
244
|
## Running Specs
|
143
245
|
|
data/lib/logger_facade/log.rb
CHANGED
@@ -13,31 +13,33 @@ module LoggerFacade
|
|
13
13
|
plugins.select { |p| p.is_debug }.size > 0
|
14
14
|
end
|
15
15
|
|
16
|
-
def trace(message)
|
17
|
-
log(:trace, message)
|
16
|
+
def trace(message, metadata = {})
|
17
|
+
log(:trace, message, metadata)
|
18
18
|
end
|
19
19
|
|
20
|
-
def debug(message)
|
21
|
-
log(:debug, message)
|
20
|
+
def debug(message, metadata = {})
|
21
|
+
log(:debug, message, metadata)
|
22
22
|
end
|
23
23
|
|
24
|
-
def info(message)
|
25
|
-
log(:info, message)
|
24
|
+
def info(message, metadata = {})
|
25
|
+
log(:info, message, metadata)
|
26
26
|
end
|
27
27
|
|
28
|
-
def warn(message)
|
29
|
-
log(:warn, message)
|
28
|
+
def warn(message, metadata = {})
|
29
|
+
log(:warn, message, metadata)
|
30
30
|
end
|
31
31
|
|
32
|
-
def error(message)
|
33
|
-
log(:error, message)
|
32
|
+
def error(message, metadata = {})
|
33
|
+
log(:error, message, metadata)
|
34
34
|
end
|
35
35
|
|
36
36
|
private
|
37
37
|
|
38
|
-
def log(level, message)
|
38
|
+
def log(level, message, metadata)
|
39
|
+
metadata[:timestamp] = Time.now.utc
|
40
|
+
metadata[:pid] = Process.pid
|
39
41
|
plugins.each do |plugin|
|
40
|
-
plugin.send(level, name, message)
|
42
|
+
plugin.send(level, name, message, metadata: metadata)
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module LoggerFacade::Middleware
|
2
|
+
class Rack < Rack::CommonLogger
|
3
|
+
def initialize(app, logger=nil)
|
4
|
+
log = LoggerFacade::Manager.get_logger("RackLogger")
|
5
|
+
@format = '%s "%s %s" %d %s %0.4f'
|
6
|
+
super(app, log)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def log(env, status, header, began_at)
|
12
|
+
metadata = get_metadata(env, status, header, began_at)
|
13
|
+
|
14
|
+
msg = @format % [
|
15
|
+
metadata["clientip"] || "-",
|
16
|
+
metadata["verb"],
|
17
|
+
metadata["request"],
|
18
|
+
metadata["response"].to_s[0..3],
|
19
|
+
metadata["bytes"],
|
20
|
+
metadata["request_time"] ]
|
21
|
+
|
22
|
+
@logger.info(msg, metadata)
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_metadata(env, status, header, began_at)
|
26
|
+
length = extract_content_length(header)
|
27
|
+
qs = env["QUERY_STRING"].empty? ? "" : "?#{env["QUERY_STRING"]}"
|
28
|
+
{
|
29
|
+
'clientip' => env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"],
|
30
|
+
'verb' => env["REQUEST_METHOD"],
|
31
|
+
'request' => "#{env["PATH_INFO"]}#{qs}",
|
32
|
+
'http_version' => env["HTTP_VERSION"],
|
33
|
+
'response' => status.to_s,
|
34
|
+
'bytes' => (length || "").to_i,
|
35
|
+
'referrer' => env["HTTP_REFERER"],
|
36
|
+
'agent' => env['HTTP_USER_AGENT'],
|
37
|
+
'request_time' => Time.now - began_at,
|
38
|
+
'request_full_url' => env['REQUEST_URI']
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module LoggerFacade::Plugins
|
2
|
+
|
3
|
+
class Base
|
4
|
+
|
5
|
+
attr_reader :config, :level, :name
|
6
|
+
|
7
|
+
def initialize(name, config = nil)
|
8
|
+
@config = Hashie::Mash.new(config)
|
9
|
+
@level = (@config.level || :debug).to_sym
|
10
|
+
@name = name
|
11
|
+
end
|
12
|
+
|
13
|
+
def is_debug
|
14
|
+
is_level_active(:debug)
|
15
|
+
end
|
16
|
+
|
17
|
+
def trace(logger, message, metadata: {})
|
18
|
+
log(:trace, message, logger, metadata)
|
19
|
+
end
|
20
|
+
|
21
|
+
def debug(logger, message, metadata: {})
|
22
|
+
log(:debug, message, logger, metadata)
|
23
|
+
end
|
24
|
+
|
25
|
+
def info(logger, message, metadata: {})
|
26
|
+
log(:info, message, logger, metadata)
|
27
|
+
end
|
28
|
+
|
29
|
+
def warn(logger, message, metadata: {})
|
30
|
+
log(:warn, message, logger, metadata)
|
31
|
+
end
|
32
|
+
|
33
|
+
def error(logger, message, metadata: {})
|
34
|
+
log(:error, message, logger, metadata)
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
def log(severity, message, logger, metadata)
|
40
|
+
# do nothing by default
|
41
|
+
end
|
42
|
+
|
43
|
+
def levels
|
44
|
+
{
|
45
|
+
trace: 0,
|
46
|
+
debug: 1,
|
47
|
+
info: 2,
|
48
|
+
warn: 3,
|
49
|
+
error: 4
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def is_level_active(log_level)
|
54
|
+
levels[log_level] >= levels[level]
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -2,9 +2,7 @@ require 'hashie'
|
|
2
2
|
|
3
3
|
module LoggerFacade::Plugins
|
4
4
|
|
5
|
-
class Console
|
6
|
-
|
7
|
-
attr_reader :config, :level, :name
|
5
|
+
class Console < Base
|
8
6
|
|
9
7
|
def initialize(config = {})
|
10
8
|
defaults = {
|
@@ -13,73 +11,39 @@ module LoggerFacade::Plugins
|
|
13
11
|
message_format: '%time | %level | %logger - %msg'
|
14
12
|
}
|
15
13
|
config = defaults.merge(config)
|
16
|
-
|
17
|
-
@config = Hashie::Mash.new(config)
|
18
|
-
@level = @config.level.to_sym
|
19
|
-
@name = "LoggerFacade::Plugins::Console"
|
20
|
-
end
|
21
|
-
|
22
|
-
def is_debug
|
23
|
-
is_level_active(:debug)
|
24
|
-
end
|
25
|
-
|
26
|
-
def trace(logger, message)
|
27
|
-
log(:trace, message, logger)
|
14
|
+
super("LoggerFacade::Plugins::Console", config)
|
28
15
|
end
|
29
16
|
|
30
|
-
|
31
|
-
log(:debug, message, logger)
|
32
|
-
end
|
17
|
+
protected
|
33
18
|
|
34
|
-
def
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
def warn(logger, message)
|
39
|
-
log(:warn, message, logger)
|
40
|
-
end
|
19
|
+
def log(log_level, message, logger, metadata)
|
20
|
+
return unless is_level_active(log_level)
|
41
21
|
|
42
|
-
|
43
|
-
log(:error, message, logger)
|
22
|
+
write message(log_level, message, logger, metadata)
|
44
23
|
end
|
45
24
|
|
46
25
|
private
|
47
26
|
|
48
|
-
def
|
49
|
-
|
50
|
-
trace: 0,
|
51
|
-
debug: 1,
|
52
|
-
info: 2,
|
53
|
-
warn: 3,
|
54
|
-
error: 4
|
55
|
-
}
|
56
|
-
end
|
57
|
-
|
58
|
-
def is_level_active(log_level)
|
59
|
-
levels[log_level] >= levels[level]
|
60
|
-
end
|
27
|
+
def message(level, msg, logger, metadata)
|
28
|
+
msg = log_exception(msg) if msg.is_a? Exception
|
61
29
|
|
62
|
-
|
63
|
-
|
30
|
+
timestamp = metadata[:timestamp] || Time.now.utc
|
31
|
+
pid = metadata[:pid] || Process.pid
|
64
32
|
|
65
|
-
|
66
|
-
outputMsg = "#{msg.message}\n#{(msg.backtrace || []).join("\n")}"
|
67
|
-
end
|
68
|
-
|
69
|
-
formatedMessage = config.message_format
|
33
|
+
config.message_format
|
70
34
|
.gsub('%logger', logger.upcase)
|
71
|
-
.gsub('%time',
|
35
|
+
.gsub('%time', timestamp.strftime(config.time_format))
|
72
36
|
.gsub('%level', level.to_s.upcase)
|
73
|
-
.gsub('%pid',
|
74
|
-
.gsub('%msg',
|
75
|
-
|
76
|
-
return formatedMessage;
|
37
|
+
.gsub('%pid', pid.to_s)
|
38
|
+
.gsub('%msg', msg)
|
77
39
|
end
|
78
40
|
|
79
|
-
def
|
80
|
-
|
41
|
+
def log_exception(msg)
|
42
|
+
"#{msg.message}\n#{(msg.backtrace || []).join("\n")}"
|
43
|
+
end
|
81
44
|
|
82
|
-
|
45
|
+
def write(message)
|
46
|
+
Kernel.puts message
|
83
47
|
end
|
84
48
|
|
85
49
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'yajl'
|
3
|
+
|
4
|
+
module LoggerFacade::Plugins
|
5
|
+
class Logstash < Base
|
6
|
+
|
7
|
+
def initialize(configuration = {})
|
8
|
+
super("LoggerFacade::Plugins::Logstash", configuration)
|
9
|
+
|
10
|
+
fail "Invalid configuration filename: #{config.filename}" unless config.filename
|
11
|
+
|
12
|
+
@logdevice = if config["device"]
|
13
|
+
shift_age = config.device["shift_age"]
|
14
|
+
shift_size = config.device["shift_size"]
|
15
|
+
LogDeviceWithRotation.new(config.filename, shift_age, shift_size)
|
16
|
+
else
|
17
|
+
LogDeviceWithoutRotation.new(config.filename)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :logdevice
|
24
|
+
|
25
|
+
def log(severity, message, logger, metadata)
|
26
|
+
return unless is_level_active(severity)
|
27
|
+
return unless logdevice
|
28
|
+
|
29
|
+
ts = metadata.delete :timestamp
|
30
|
+
ts ||= Time.now.utc
|
31
|
+
metadata[:severity] = severity
|
32
|
+
metadata[:logger] = logger
|
33
|
+
metadata[:message] = message
|
34
|
+
metadata[:backtrace] = message.backtrace if message.is_a? Exception
|
35
|
+
|
36
|
+
json = {
|
37
|
+
'@timestamp' => ts.iso8601,
|
38
|
+
'@fields' => metadata
|
39
|
+
}
|
40
|
+
|
41
|
+
@logdevice.write("#{Yajl::Encoder.encode(json)}\n")
|
42
|
+
end
|
43
|
+
|
44
|
+
class LogDeviceWithRotation < ::Logger::LogDevice
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# overrides base.add_log_header to disable log header
|
49
|
+
def add_log_header(file)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class LogDeviceWithoutRotation < LogDeviceWithRotation
|
54
|
+
|
55
|
+
# overrides base.write to disable log shifting
|
56
|
+
def write(message)
|
57
|
+
@mutex.synchronize do
|
58
|
+
@dev.write(message)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
data/logger_facade.gemspec
CHANGED
@@ -29,9 +29,12 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.add_development_dependency 'simplecov', '~> 0.9'
|
30
30
|
spec.add_development_dependency 'codeclimate-test-reporter', '~> 0.3'
|
31
31
|
spec.add_development_dependency 'bump', '~> 0.5'
|
32
|
+
spec.add_development_dependency 'rack', '~> 1.6'
|
32
33
|
|
33
34
|
spec.add_dependency 'hashie', '~> 3.2'
|
34
35
|
spec.add_dependency 'airbrake', '~> 4.0'
|
35
36
|
# sucker punch is used to use airbrake async
|
36
37
|
spec.add_dependency 'sucker_punch', '~> 1.1'
|
38
|
+
# used by logstash plugin, for better performance
|
39
|
+
spec.add_dependency 'yajl-ruby', '~> 1.2'
|
37
40
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -23,3 +23,31 @@ RSpec.configure do |c|
|
|
23
23
|
}
|
24
24
|
end
|
25
25
|
end
|
26
|
+
|
27
|
+
module TimeTestHelper
|
28
|
+
def with_mock_time(t = 0)
|
29
|
+
mc = class <<Time; self; end
|
30
|
+
mc.send :alias_method, :old_now, :now
|
31
|
+
mc.send :define_method, :now do
|
32
|
+
at(t)
|
33
|
+
end
|
34
|
+
yield
|
35
|
+
ensure
|
36
|
+
mc.send :alias_method, :now, :old_now
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module LevelTestHelper
|
41
|
+
def next_level(lev)
|
42
|
+
levels = {
|
43
|
+
trace: 0,
|
44
|
+
debug: 1,
|
45
|
+
info: 2,
|
46
|
+
warn: 3,
|
47
|
+
error: 4
|
48
|
+
}
|
49
|
+
|
50
|
+
val = levels[lev.to_sym]
|
51
|
+
levels.select { |k,v| v > val }.keys.first
|
52
|
+
end
|
53
|
+
end
|
data/spec/unit/log_spec.rb
CHANGED
@@ -41,13 +41,57 @@ describe LoggerFacade::Log do
|
|
41
41
|
%w(trace debug info warn error).each do |level|
|
42
42
|
|
43
43
|
describe("##{level}") do
|
44
|
+
let(:time) { Time.new(1983, 01, 25, 13, 10, 01, '+00:00') }
|
45
|
+
let(:pid) { 0 }
|
44
46
|
|
45
47
|
it("calls the plugin in #{level} level") do
|
46
48
|
message = "call with message"
|
47
|
-
expect(plugin).to receive(level.to_sym).with(subject.name, message)
|
49
|
+
expect(plugin).to receive(level.to_sym).with(subject.name, message, anything)
|
48
50
|
subject.send(level.to_sym, message)
|
49
51
|
end
|
50
52
|
|
53
|
+
it("calls the plugin with metadata dictionary when not present") do
|
54
|
+
message = "call with message"
|
55
|
+
metadata = {}
|
56
|
+
expect(plugin).to receive(level.to_sym)
|
57
|
+
.with(subject.name, message,
|
58
|
+
hash_including(metadata: hash_including(:timestamp, :pid)))
|
59
|
+
subject.send(level.to_sym, message)
|
60
|
+
end
|
61
|
+
|
62
|
+
it("appends timestamp to metadata") do
|
63
|
+
allow(Time).to receive(:now) { time }
|
64
|
+
message = "call with message"
|
65
|
+
metadata = {}
|
66
|
+
expect(plugin).to receive(level.to_sym)
|
67
|
+
.with(subject.name, message,
|
68
|
+
hash_including(metadata: hash_including(timestamp: time))
|
69
|
+
)
|
70
|
+
subject.send(level.to_sym, message, metadata)
|
71
|
+
end
|
72
|
+
|
73
|
+
it("appends timestamp to metadata") do
|
74
|
+
allow(Time).to receive(:now) { time }
|
75
|
+
message = "call with message"
|
76
|
+
metadata = {}
|
77
|
+
expect(plugin).to receive(level.to_sym)
|
78
|
+
.with(subject.name, message,
|
79
|
+
hash_including(metadata: hash_including(timestamp: time))
|
80
|
+
)
|
81
|
+
subject.send(level.to_sym, message, metadata)
|
82
|
+
end
|
83
|
+
|
84
|
+
it("appends pid to metadata") do
|
85
|
+
allow(Process).to receive(:pid) { pid }
|
86
|
+
message = "call with message"
|
87
|
+
metadata = {}
|
88
|
+
expect(plugin).to receive(level.to_sym)
|
89
|
+
.with(subject.name, message,
|
90
|
+
hash_including(metadata: hash_including(pid: pid))
|
91
|
+
)
|
92
|
+
subject.send(level.to_sym, message, metadata)
|
93
|
+
end
|
94
|
+
|
51
95
|
end
|
52
96
|
|
53
97
|
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'rack/commonlogger'
|
2
|
+
require 'rack/lint'
|
3
|
+
require 'rack/mock'
|
4
|
+
require 'logger_facade'
|
5
|
+
require 'logger_facade/middleware/rack'
|
6
|
+
|
7
|
+
describe LoggerFacade::Middleware::Rack do
|
8
|
+
include TimeTestHelper
|
9
|
+
let(:regex) do
|
10
|
+
/(-) "(\w+) \/(\w+)\?(q=\w+)" (\d{3}) (\d+) ([\d\.]+)/
|
11
|
+
end
|
12
|
+
let(:logger) { double('logger') }
|
13
|
+
let(:obj) { "foobar" }
|
14
|
+
let(:length) { obj.size }
|
15
|
+
let(:app) do
|
16
|
+
Rack::Lint.new lambda { |env|
|
17
|
+
[200,
|
18
|
+
{"Content-Type" => "text/html", "Content-Length" => length.to_s},
|
19
|
+
[obj]]}
|
20
|
+
end
|
21
|
+
|
22
|
+
before do
|
23
|
+
expect(LoggerFacade::Manager).to receive(:get_logger){ logger }
|
24
|
+
end
|
25
|
+
|
26
|
+
it "logs to logger facade instance" do
|
27
|
+
expect(logger).to receive(:info)#.with('- "GET /" 200 6 0.0007')
|
28
|
+
res = Rack::MockRequest.new(described_class.new(app)).get("/")
|
29
|
+
end
|
30
|
+
|
31
|
+
it "log in the specified log format" do
|
32
|
+
expect(logger).to receive(:info) do |message|
|
33
|
+
md = regex.match(message)
|
34
|
+
expect(md).not_to be_nil
|
35
|
+
ip, method, path, qs, status, size, duration = *md.captures
|
36
|
+
expect(ip).to eq("-")
|
37
|
+
expect(method).to eq("GET")
|
38
|
+
expect(path).to eq("path")
|
39
|
+
expect(qs).to eq("q=true")
|
40
|
+
expect(status).to eq("200")
|
41
|
+
expect(size).to eq(length.to_s)
|
42
|
+
expect(duration.to_f).to eq(0)
|
43
|
+
end
|
44
|
+
with_mock_time do
|
45
|
+
Rack::MockRequest.new(described_class.new(app)).get("/path?q=true")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'with proper metadata' do
|
50
|
+
|
51
|
+
after do
|
52
|
+
with_mock_time do
|
53
|
+
Rack::MockRequest.new(described_class.new(app)).get("/path?q=true")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it "log clientip as metadata" do
|
58
|
+
expect(logger).to receive(:info)
|
59
|
+
.with(anything, hash_including("clientip"))
|
60
|
+
end
|
61
|
+
|
62
|
+
it "log verb as metadata" do
|
63
|
+
expect(logger).to receive(:info)
|
64
|
+
.with(anything, hash_including("verb" => "GET"))
|
65
|
+
end
|
66
|
+
|
67
|
+
it "log request as metadata" do
|
68
|
+
expect(logger).to receive(:info)
|
69
|
+
.with(anything, hash_including("request" => "/path?q=true"))
|
70
|
+
end
|
71
|
+
|
72
|
+
it "log http_version as metadata" do
|
73
|
+
expect(logger).to receive(:info)
|
74
|
+
.with(anything, hash_including("http_version" => nil))
|
75
|
+
end
|
76
|
+
|
77
|
+
it "log response as metadata" do
|
78
|
+
expect(logger).to receive(:info)
|
79
|
+
.with(anything, hash_including("response" => "200"))
|
80
|
+
end
|
81
|
+
|
82
|
+
it "log bytes as metadata" do
|
83
|
+
expect(logger).to receive(:info)
|
84
|
+
.with(anything, hash_including("bytes" => length))
|
85
|
+
end
|
86
|
+
|
87
|
+
it "log referrer as metadata" do
|
88
|
+
expect(logger).to receive(:info)
|
89
|
+
.with(anything, hash_including("referrer" => nil))
|
90
|
+
end
|
91
|
+
|
92
|
+
it "log agent as metadata" do
|
93
|
+
expect(logger).to receive(:info)
|
94
|
+
.with(anything, hash_including("agent" => nil))
|
95
|
+
end
|
96
|
+
|
97
|
+
it "log request_time as metadata" do
|
98
|
+
expect(logger).to receive(:info)
|
99
|
+
.with(anything, hash_including("request_time" => 0.0))
|
100
|
+
end
|
101
|
+
|
102
|
+
it "log request_full_url as metadata" do
|
103
|
+
expect(logger).to receive(:info)
|
104
|
+
.with(anything, hash_including("request_full_url" => nil))
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -1,10 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe LoggerFacade::Plugins::Console do
|
4
|
+
include LevelTestHelper
|
4
5
|
|
5
6
|
subject { described_class.new }
|
6
7
|
|
7
8
|
let(:time) { Time.new(1983, 01, 25, 13, 10, 01, '+00:00') }
|
9
|
+
let(:metadata){ { timestamp: time, pid: 100 } }
|
8
10
|
|
9
11
|
before :each do
|
10
12
|
allow(Time).to receive(:now) { time }
|
@@ -23,19 +25,6 @@ describe LoggerFacade::Plugins::Console do
|
|
23
25
|
|
24
26
|
end
|
25
27
|
|
26
|
-
def next_level(lev)
|
27
|
-
levels = {
|
28
|
-
trace: 0,
|
29
|
-
debug: 1,
|
30
|
-
info: 2,
|
31
|
-
warn: 3,
|
32
|
-
error: 4
|
33
|
-
}
|
34
|
-
|
35
|
-
val = levels[lev.to_sym]
|
36
|
-
levels.select { |k,v| v > val }.keys.first
|
37
|
-
end
|
38
|
-
|
39
28
|
%w(trace debug info warn error).each do |level|
|
40
29
|
|
41
30
|
context("logging in #{level} level") do
|
@@ -0,0 +1,207 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
describe LoggerFacade::Plugins::Logstash do
|
4
|
+
include LevelTestHelper
|
5
|
+
|
6
|
+
subject { described_class.new }
|
7
|
+
|
8
|
+
let(:filename) { './test.log' }
|
9
|
+
let(:config) { { filename: filename } }
|
10
|
+
let(:time) { Time.new(1983, 01, 25, 13, 10, 01, '+00:00') }
|
11
|
+
let(:metadata){ { timestamp: time, pid: 100 } }
|
12
|
+
let(:file) { double('file') }
|
13
|
+
|
14
|
+
before :each do
|
15
|
+
allow(Time).to receive(:now) { time }
|
16
|
+
allow_any_instance_of(Object).to receive(:open) { file }
|
17
|
+
allow_any_instance_of(Object).to receive(:sync=)
|
18
|
+
end
|
19
|
+
|
20
|
+
describe("initialize") do
|
21
|
+
it 'defaults to logdevice without rotation' do
|
22
|
+
expect(LoggerFacade::Plugins::Logstash::LogDeviceWithoutRotation)
|
23
|
+
.to receive(:new).with(filename)
|
24
|
+
described_class.new(config)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'uses ruby Logger config' do
|
28
|
+
age = 'age'
|
29
|
+
size = 1024
|
30
|
+
config[:device] = { shift_age: age, shift_size: size }
|
31
|
+
expect(LoggerFacade::Plugins::Logstash::LogDeviceWithRotation)
|
32
|
+
.to receive(:new).with(filename, age, size)
|
33
|
+
described_class.new(config)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'raises an error on invalid filename configuration' do
|
37
|
+
expect { described_class.new({}) }.to raise_exception(RuntimeError)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe('#is_debug') do
|
42
|
+
|
43
|
+
it('returns true when log level lower than info') do
|
44
|
+
subject = described_class.new(config)
|
45
|
+
expect(subject.is_debug).to be true
|
46
|
+
end
|
47
|
+
|
48
|
+
it('returns false when log level higher than debug') do
|
49
|
+
config[:level] = :info
|
50
|
+
subject = described_class.new(config)
|
51
|
+
expect(subject.is_debug).to be false
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
%w(trace debug info warn error).each do |level|
|
57
|
+
|
58
|
+
context("logging in #{level} level") do
|
59
|
+
subject do
|
60
|
+
config[:level] = level.to_sym
|
61
|
+
described_class.new(config)
|
62
|
+
end
|
63
|
+
|
64
|
+
let(:message) { "call with message" }
|
65
|
+
let(:logger) { "name" }
|
66
|
+
let(:severity) { level.to_sym }
|
67
|
+
|
68
|
+
context("when plugin log level lower or equal than #{level}") do
|
69
|
+
|
70
|
+
it("writes to file") do
|
71
|
+
expect(file).to receive(:write)
|
72
|
+
subject.send(severity, logger, message)
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'format' do
|
76
|
+
it("writes a valid json") do
|
77
|
+
expect(file).to receive(:write) do |msg|
|
78
|
+
data = nil
|
79
|
+
expect { data = JSON.parse(msg) }.not_to raise_exception
|
80
|
+
expect(data).to be
|
81
|
+
end
|
82
|
+
subject.send(severity, logger, message)
|
83
|
+
end
|
84
|
+
|
85
|
+
it("ends with line break") do
|
86
|
+
expect(file).to receive(:write) do |msg|
|
87
|
+
expect(msg[-1,1]).to eq("\n")
|
88
|
+
end
|
89
|
+
subject.send(severity, logger, message)
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'timestamp' do
|
93
|
+
# time + 1.month
|
94
|
+
let(:ts) { time + 2592000 }
|
95
|
+
let(:metadata) { { timestamp: ts } }
|
96
|
+
|
97
|
+
it("writes logstash timestamp format") do
|
98
|
+
expect(file).to receive(:write) do |msg|
|
99
|
+
data = JSON.parse(msg)
|
100
|
+
expect(data["@timestamp"]).to eq(time.iso8601)
|
101
|
+
end
|
102
|
+
subject.send(severity, logger, message)
|
103
|
+
end
|
104
|
+
|
105
|
+
it("uses metadata timestamp") do
|
106
|
+
expect(file).to receive(:write) do |msg|
|
107
|
+
data = JSON.parse(msg)
|
108
|
+
expect(data["@timestamp"]).to eq(ts.iso8601)
|
109
|
+
end
|
110
|
+
subject.send(severity, logger, message, metadata: metadata)
|
111
|
+
end
|
112
|
+
|
113
|
+
it("doesn't write field timestamp") do
|
114
|
+
expect(file).to receive(:write) do |msg|
|
115
|
+
data = JSON.parse(msg)["@fields"]
|
116
|
+
expect(data["timestamp"]).to be_nil
|
117
|
+
end
|
118
|
+
subject.send(severity, logger, message, metadata: metadata)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it("writes fields") do
|
123
|
+
expect(file).to receive(:write) do |msg|
|
124
|
+
data = JSON.parse(msg)
|
125
|
+
expect(data["@fields"]).to be
|
126
|
+
end
|
127
|
+
subject.send(severity, logger, message)
|
128
|
+
end
|
129
|
+
|
130
|
+
it("writes severity") do
|
131
|
+
expect(file).to receive(:write) do |msg|
|
132
|
+
data = JSON.parse(msg)["@fields"]
|
133
|
+
expect(data["severity"]).to eq(severity.to_s)
|
134
|
+
end
|
135
|
+
subject.send(severity, logger, message)
|
136
|
+
end
|
137
|
+
|
138
|
+
it("writes logger") do
|
139
|
+
expect(file).to receive(:write) do |msg|
|
140
|
+
data = JSON.parse(msg)["@fields"]
|
141
|
+
expect(data["logger"]).to eq(logger)
|
142
|
+
end
|
143
|
+
subject.send(severity, logger, message)
|
144
|
+
end
|
145
|
+
|
146
|
+
it("writes message") do
|
147
|
+
expect(file).to receive(:write) do |msg|
|
148
|
+
data = JSON.parse(msg)["@fields"]
|
149
|
+
expect(data["message"]).to eq(message)
|
150
|
+
end
|
151
|
+
subject.send(severity, logger, message)
|
152
|
+
end
|
153
|
+
|
154
|
+
it("writes other metadata fields") do
|
155
|
+
metadata = { context: true }
|
156
|
+
expect(file).to receive(:write) do |msg|
|
157
|
+
data = JSON.parse(msg)["@fields"]
|
158
|
+
expect(data["context"]).to eq(true)
|
159
|
+
end
|
160
|
+
subject.send(severity, logger, message, metadata: metadata)
|
161
|
+
end
|
162
|
+
|
163
|
+
context "on excepetion parameter" do
|
164
|
+
|
165
|
+
it('writes the exception message') do
|
166
|
+
error = Exception.new('test log')
|
167
|
+
expect(file).to receive(:write) do |msg|
|
168
|
+
data = JSON.parse(msg)["@fields"]
|
169
|
+
expect(data["message"]).to eq("test log")
|
170
|
+
end
|
171
|
+
subject.send(severity, logger, error)
|
172
|
+
end
|
173
|
+
|
174
|
+
it('writes the exception backtrace') do
|
175
|
+
error = Exception.new('test log')
|
176
|
+
error.set_backtrace "stacktrace"
|
177
|
+
expect(file).to receive(:write) do |msg|
|
178
|
+
data = JSON.parse(msg)["@fields"]
|
179
|
+
expect(data["backtrace"]).to eq(error.backtrace)
|
180
|
+
end
|
181
|
+
subject.send(severity, logger, error)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
|
188
|
+
unless level == 'error'
|
189
|
+
context("when plugin log level higher than #{level}") do
|
190
|
+
subject do
|
191
|
+
config[:level] = next_level(level)
|
192
|
+
described_class.new(config)
|
193
|
+
end
|
194
|
+
|
195
|
+
it("doesn't write to file") do
|
196
|
+
expect(file).not_to receive(:write)
|
197
|
+
subject.send(level.to_sym, "name", message)
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logger_facade
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pedro Januário
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0.5'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rack
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.6'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.6'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: hashie
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,6 +164,20 @@ dependencies:
|
|
150
164
|
- - "~>"
|
151
165
|
- !ruby/object:Gem::Version
|
152
166
|
version: '1.1'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: yajl-ruby
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '1.2'
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '1.2'
|
153
181
|
description: |-
|
154
182
|
Simple class library to work as logger facade.
|
155
183
|
This simple logger facade allows you to hook plugins to execute logging.
|
@@ -172,17 +200,22 @@ files:
|
|
172
200
|
- lib/logger_facade/log.rb
|
173
201
|
- lib/logger_facade/loggable.rb
|
174
202
|
- lib/logger_facade/manager.rb
|
203
|
+
- lib/logger_facade/middleware/rack.rb
|
175
204
|
- lib/logger_facade/plugins.rb
|
176
205
|
- lib/logger_facade/plugins/airbrake.rb
|
206
|
+
- lib/logger_facade/plugins/base.rb
|
177
207
|
- lib/logger_facade/plugins/console.rb
|
208
|
+
- lib/logger_facade/plugins/logstash.rb
|
178
209
|
- lib/logger_facade/version.rb
|
179
210
|
- logger_facade.gemspec
|
180
211
|
- spec/spec_helper.rb
|
181
212
|
- spec/unit/log_spec.rb
|
182
213
|
- spec/unit/loggable_spec.rb
|
183
214
|
- spec/unit/manager_spec.rb
|
215
|
+
- spec/unit/middleware/rack_spec.rb
|
184
216
|
- spec/unit/plugins/airbrake_spec.rb
|
185
217
|
- spec/unit/plugins/console_spec.rb
|
218
|
+
- spec/unit/plugins/logstash_spec.rb
|
186
219
|
homepage: https://github.com/pjanuario/logger-facade-ruby
|
187
220
|
licenses:
|
188
221
|
- MIT
|
@@ -214,5 +247,7 @@ test_files:
|
|
214
247
|
- spec/unit/log_spec.rb
|
215
248
|
- spec/unit/loggable_spec.rb
|
216
249
|
- spec/unit/manager_spec.rb
|
250
|
+
- spec/unit/middleware/rack_spec.rb
|
217
251
|
- spec/unit/plugins/airbrake_spec.rb
|
218
252
|
- spec/unit/plugins/console_spec.rb
|
253
|
+
- spec/unit/plugins/logstash_spec.rb
|