ledis 0.0.1
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/README.md +56 -0
- data/Rakefile +374 -0
- data/ledis.gemspec +29 -0
- data/lib/ledis.rb +259 -0
- metadata +48 -0
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
NAME
|
2
|
+
|
3
|
+
ledis
|
4
|
+
|
5
|
+
|
6
|
+
SYNOPSIS
|
7
|
+
|
8
|
+
a K.I.S.S auto-rotating redis logger for ruby/rails
|
9
|
+
|
10
|
+
Ruby
|
11
|
+
|
12
|
+
redis = Redis.new
|
13
|
+
|
14
|
+
logger = Ledis.logger redis
|
15
|
+
|
16
|
+
logger = Ledis.new
|
17
|
+
|
18
|
+
logger = Ledis.new do |config|
|
19
|
+
|
20
|
+
config.redis = Redis.new
|
21
|
+
|
22
|
+
config.list = 'teh_foo:log'
|
23
|
+
|
24
|
+
config.cap = 2 ** 16
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
Rails
|
29
|
+
|
30
|
+
### file: config/environments/development.rb
|
31
|
+
|
32
|
+
config.logger = Ledis.logger do |logger|
|
33
|
+
|
34
|
+
logger.list = "teh_rails_app:#{ Rails.env }:log"
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
DESCRIPTION
|
40
|
+
|
41
|
+
ledis logs yo shiznit to redis. it's got built in logic to auto-truncate
|
42
|
+
logs when they get to big
|
43
|
+
|
44
|
+
logger.truncate(2 **16)
|
45
|
+
|
46
|
+
and to grab the most recent ones
|
47
|
+
|
48
|
+
puts logger.tail(1024)
|
49
|
+
|
50
|
+
it's list/line oriented, just like a log file and makes no attempt to
|
51
|
+
annotated log lines or add fancy data structures to them
|
52
|
+
|
53
|
+
INSTALL
|
54
|
+
|
55
|
+
gem 'ledis'
|
56
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,374 @@
|
|
1
|
+
This.rubyforge_project = 'codeforpeople'
|
2
|
+
This.author = "Ara T. Howard"
|
3
|
+
This.email = "ara.t.howard@gmail.com"
|
4
|
+
This.homepage = "https://github.com/ahoward/#{ This.lib }"
|
5
|
+
|
6
|
+
task :license do
|
7
|
+
open('LICENSE', 'w'){|fd| fd.puts "same as ruby's"}
|
8
|
+
end
|
9
|
+
|
10
|
+
task :default do
|
11
|
+
puts((Rake::Task.tasks.map{|task| task.name.gsub(/::/,':')} - ['default']).sort)
|
12
|
+
end
|
13
|
+
|
14
|
+
task :test do
|
15
|
+
run_tests!
|
16
|
+
end
|
17
|
+
|
18
|
+
namespace :test do
|
19
|
+
task(:unit){ run_tests!(:unit) }
|
20
|
+
task(:functional){ run_tests!(:functional) }
|
21
|
+
task(:integration){ run_tests!(:integration) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def run_tests!(which = nil)
|
25
|
+
which ||= '**'
|
26
|
+
test_dir = File.join(This.dir, "test")
|
27
|
+
test_glob ||= File.join(test_dir, "#{ which }/**_test.rb")
|
28
|
+
test_rbs = Dir.glob(test_glob).sort
|
29
|
+
|
30
|
+
div = ('=' * 119)
|
31
|
+
line = ('-' * 119)
|
32
|
+
|
33
|
+
test_rbs.each_with_index do |test_rb, index|
|
34
|
+
testno = index + 1
|
35
|
+
command = "#{ This.ruby } -I ./lib -I ./test/lib #{ test_rb }"
|
36
|
+
|
37
|
+
puts
|
38
|
+
say(div, :color => :cyan, :bold => true)
|
39
|
+
say("@#{ testno } => ", :bold => true, :method => :print)
|
40
|
+
say(command, :color => :cyan, :bold => true)
|
41
|
+
say(line, :color => :cyan, :bold => true)
|
42
|
+
|
43
|
+
system(command)
|
44
|
+
|
45
|
+
say(line, :color => :cyan, :bold => true)
|
46
|
+
|
47
|
+
status = $?.exitstatus
|
48
|
+
|
49
|
+
if status.zero?
|
50
|
+
say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
|
51
|
+
say("SUCCESS", :color => :green, :bold => true)
|
52
|
+
else
|
53
|
+
say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
|
54
|
+
say("FAILURE", :color => :red, :bold => true)
|
55
|
+
end
|
56
|
+
say(line, :color => :cyan, :bold => true)
|
57
|
+
|
58
|
+
exit(status) unless status.zero?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
task :gemspec do
|
64
|
+
ignore_extensions = ['git', 'svn', 'tmp', /sw./, 'bak', 'gem']
|
65
|
+
ignore_directories = ['pkg']
|
66
|
+
ignore_files = ['test/log']
|
67
|
+
|
68
|
+
shiteless =
|
69
|
+
lambda do |list|
|
70
|
+
list.delete_if do |entry|
|
71
|
+
next unless test(?e, entry)
|
72
|
+
extension = File.basename(entry).split(%r/[.]/).last
|
73
|
+
ignore_extensions.any?{|ext| ext === extension}
|
74
|
+
end
|
75
|
+
list.delete_if do |entry|
|
76
|
+
next unless test(?d, entry)
|
77
|
+
dirname = File.expand_path(entry)
|
78
|
+
ignore_directories.any?{|dir| File.expand_path(dir) == dirname}
|
79
|
+
end
|
80
|
+
list.delete_if do |entry|
|
81
|
+
next unless test(?f, entry)
|
82
|
+
filename = File.expand_path(entry)
|
83
|
+
ignore_files.any?{|file| File.expand_path(file) == filename}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
lib = This.lib
|
88
|
+
object = This.object
|
89
|
+
version = This.version
|
90
|
+
files = shiteless[Dir::glob("**/**")]
|
91
|
+
executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
|
92
|
+
#has_rdoc = true #File.exist?('doc')
|
93
|
+
test_files = "test/#{ lib }.rb" if File.file?("test/#{ lib }.rb")
|
94
|
+
summary = object.respond_to?(:summary) ? object.summary : "summary: #{ lib } kicks the ass"
|
95
|
+
description = object.respond_to?(:description) ? object.description : "description: #{ lib } kicks the ass"
|
96
|
+
|
97
|
+
if This.extensions.nil?
|
98
|
+
This.extensions = []
|
99
|
+
extensions = This.extensions
|
100
|
+
%w( Makefile configure extconf.rb ).each do |ext|
|
101
|
+
extensions << ext if File.exists?(ext)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
extensions = [extensions].flatten.compact
|
105
|
+
|
106
|
+
template =
|
107
|
+
if test(?e, 'gemspec.erb')
|
108
|
+
Template{ IO.read('gemspec.erb') }
|
109
|
+
else
|
110
|
+
Template {
|
111
|
+
<<-__
|
112
|
+
## #{ lib }.gemspec
|
113
|
+
#
|
114
|
+
|
115
|
+
Gem::Specification::new do |spec|
|
116
|
+
spec.name = #{ lib.inspect }
|
117
|
+
spec.version = #{ version.inspect }
|
118
|
+
spec.platform = Gem::Platform::RUBY
|
119
|
+
spec.summary = #{ lib.inspect }
|
120
|
+
spec.description = #{ description.inspect }
|
121
|
+
|
122
|
+
spec.files =\n#{ files.sort.pretty_inspect }
|
123
|
+
spec.executables = #{ executables.inspect }
|
124
|
+
|
125
|
+
spec.require_path = "lib"
|
126
|
+
|
127
|
+
spec.test_files = #{ test_files.inspect }
|
128
|
+
|
129
|
+
### spec.add_dependency 'lib', '>= version'
|
130
|
+
#### spec.add_dependency 'map'
|
131
|
+
|
132
|
+
spec.extensions.push(*#{ extensions.inspect })
|
133
|
+
|
134
|
+
spec.rubyforge_project = #{ This.rubyforge_project.inspect }
|
135
|
+
spec.author = #{ This.author.inspect }
|
136
|
+
spec.email = #{ This.email.inspect }
|
137
|
+
spec.homepage = #{ This.homepage.inspect }
|
138
|
+
end
|
139
|
+
__
|
140
|
+
}
|
141
|
+
end
|
142
|
+
|
143
|
+
Fu.mkdir_p(This.pkgdir)
|
144
|
+
gemspec = "#{ lib }.gemspec"
|
145
|
+
open(gemspec, "w"){|fd| fd.puts(template)}
|
146
|
+
This.gemspec = gemspec
|
147
|
+
end
|
148
|
+
|
149
|
+
task :gem => [:clean, :gemspec] do
|
150
|
+
Fu.mkdir_p(This.pkgdir)
|
151
|
+
before = Dir['*.gem']
|
152
|
+
cmd = "gem build #{ This.gemspec }"
|
153
|
+
`#{ cmd }`
|
154
|
+
after = Dir['*.gem']
|
155
|
+
gem = ((after - before).first || after.first) or abort('no gem!')
|
156
|
+
Fu.mv(gem, This.pkgdir)
|
157
|
+
This.gem = File.join(This.pkgdir, File.basename(gem))
|
158
|
+
end
|
159
|
+
|
160
|
+
task :readme do
|
161
|
+
samples = ''
|
162
|
+
prompt = '~ > '
|
163
|
+
lib = This.lib
|
164
|
+
version = This.version
|
165
|
+
|
166
|
+
Dir['sample*/*'].sort.each do |sample|
|
167
|
+
samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
|
168
|
+
|
169
|
+
cmd = "cat #{ sample }"
|
170
|
+
samples << Util.indent(prompt + cmd, 2) << "\n\n"
|
171
|
+
samples << Util.indent(`#{ cmd }`, 4) << "\n"
|
172
|
+
|
173
|
+
cmd = "ruby #{ sample }"
|
174
|
+
samples << Util.indent(prompt + cmd, 2) << "\n\n"
|
175
|
+
|
176
|
+
cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -I ./lib #{ sample })'"
|
177
|
+
samples << Util.indent(`#{ cmd } 2>&1`, 4) << "\n"
|
178
|
+
end
|
179
|
+
|
180
|
+
template =
|
181
|
+
if test(?e, 'readme.erb')
|
182
|
+
Template{ IO.read('readme.erb') }
|
183
|
+
else
|
184
|
+
Template {
|
185
|
+
<<-__
|
186
|
+
NAME
|
187
|
+
#{ lib }
|
188
|
+
|
189
|
+
DESCRIPTION
|
190
|
+
|
191
|
+
INSTALL
|
192
|
+
gem install #{ lib }
|
193
|
+
|
194
|
+
SAMPLES
|
195
|
+
#{ samples }
|
196
|
+
__
|
197
|
+
}
|
198
|
+
end
|
199
|
+
|
200
|
+
open("README", "w"){|fd| fd.puts template}
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
task :clean do
|
205
|
+
Dir[File.join(This.pkgdir, '**/**')].each{|entry| Fu.rm_rf(entry)}
|
206
|
+
end
|
207
|
+
|
208
|
+
|
209
|
+
task :release => [:clean, :gemspec, :gem] do
|
210
|
+
gems = Dir[File.join(This.pkgdir, '*.gem')].flatten
|
211
|
+
raise "which one? : #{ gems.inspect }" if gems.size > 1
|
212
|
+
raise "no gems?" if gems.size < 1
|
213
|
+
|
214
|
+
cmd = "gem push #{ This.gem }"
|
215
|
+
puts cmd
|
216
|
+
puts
|
217
|
+
system(cmd)
|
218
|
+
abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
|
219
|
+
|
220
|
+
cmd = "rubyforge login && rubyforge add_release #{ This.rubyforge_project } #{ This.lib } #{ This.version } #{ This.gem }"
|
221
|
+
puts cmd
|
222
|
+
puts
|
223
|
+
system(cmd)
|
224
|
+
abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
|
225
|
+
end
|
226
|
+
|
227
|
+
|
228
|
+
|
229
|
+
|
230
|
+
|
231
|
+
BEGIN {
|
232
|
+
# support for this rakefile
|
233
|
+
#
|
234
|
+
$VERBOSE = nil
|
235
|
+
|
236
|
+
require 'ostruct'
|
237
|
+
require 'erb'
|
238
|
+
require 'fileutils'
|
239
|
+
require 'rbconfig'
|
240
|
+
require 'pp'
|
241
|
+
|
242
|
+
# fu shortcut
|
243
|
+
#
|
244
|
+
Fu = FileUtils
|
245
|
+
|
246
|
+
# cache a bunch of stuff about this rakefile/environment
|
247
|
+
#
|
248
|
+
This = OpenStruct.new
|
249
|
+
|
250
|
+
This.file = File.expand_path(__FILE__)
|
251
|
+
This.dir = File.dirname(This.file)
|
252
|
+
This.pkgdir = File.join(This.dir, 'pkg')
|
253
|
+
|
254
|
+
# grok lib
|
255
|
+
#
|
256
|
+
lib = ENV['LIB']
|
257
|
+
unless lib
|
258
|
+
lib = File.basename(Dir.pwd).sub(/[-].*$/, '')
|
259
|
+
end
|
260
|
+
This.lib = lib
|
261
|
+
|
262
|
+
# grok version
|
263
|
+
#
|
264
|
+
version = ENV['VERSION']
|
265
|
+
unless version
|
266
|
+
require "./lib/#{ This.lib }"
|
267
|
+
This.name = lib.capitalize
|
268
|
+
This.object = eval(This.name)
|
269
|
+
version = This.object.send(:version)
|
270
|
+
end
|
271
|
+
This.version = version
|
272
|
+
|
273
|
+
# we need to know the name of the lib an it's version
|
274
|
+
#
|
275
|
+
abort('no lib') unless This.lib
|
276
|
+
abort('no version') unless This.version
|
277
|
+
|
278
|
+
# discover full path to this ruby executable
|
279
|
+
#
|
280
|
+
c = Config::CONFIG
|
281
|
+
bindir = c["bindir"] || c['BINDIR']
|
282
|
+
ruby_install_name = c['ruby_install_name'] || c['RUBY_INSTALL_NAME'] || 'ruby'
|
283
|
+
ruby_ext = c['EXEEXT'] || ''
|
284
|
+
ruby = File.join(bindir, (ruby_install_name + ruby_ext))
|
285
|
+
This.ruby = ruby
|
286
|
+
|
287
|
+
# some utils
|
288
|
+
#
|
289
|
+
module Util
|
290
|
+
def indent(s, n = 2)
|
291
|
+
s = unindent(s)
|
292
|
+
ws = ' ' * n
|
293
|
+
s.gsub(%r/^/, ws)
|
294
|
+
end
|
295
|
+
|
296
|
+
def unindent(s)
|
297
|
+
indent = nil
|
298
|
+
s.each_line do |line|
|
299
|
+
next if line =~ %r/^\s*$/
|
300
|
+
indent = line[%r/^\s*/] and break
|
301
|
+
end
|
302
|
+
indent ? s.gsub(%r/^#{ indent }/, "") : s
|
303
|
+
end
|
304
|
+
extend self
|
305
|
+
end
|
306
|
+
|
307
|
+
# template support
|
308
|
+
#
|
309
|
+
class Template
|
310
|
+
def initialize(&block)
|
311
|
+
@block = block
|
312
|
+
@template = block.call.to_s
|
313
|
+
end
|
314
|
+
def expand(b=nil)
|
315
|
+
ERB.new(Util.unindent(@template)).result((b||@block).binding)
|
316
|
+
end
|
317
|
+
alias_method 'to_s', 'expand'
|
318
|
+
end
|
319
|
+
def Template(*args, &block) Template.new(*args, &block) end
|
320
|
+
|
321
|
+
# colored console output support
|
322
|
+
#
|
323
|
+
This.ansi = {
|
324
|
+
:clear => "\e[0m",
|
325
|
+
:reset => "\e[0m",
|
326
|
+
:erase_line => "\e[K",
|
327
|
+
:erase_char => "\e[P",
|
328
|
+
:bold => "\e[1m",
|
329
|
+
:dark => "\e[2m",
|
330
|
+
:underline => "\e[4m",
|
331
|
+
:underscore => "\e[4m",
|
332
|
+
:blink => "\e[5m",
|
333
|
+
:reverse => "\e[7m",
|
334
|
+
:concealed => "\e[8m",
|
335
|
+
:black => "\e[30m",
|
336
|
+
:red => "\e[31m",
|
337
|
+
:green => "\e[32m",
|
338
|
+
:yellow => "\e[33m",
|
339
|
+
:blue => "\e[34m",
|
340
|
+
:magenta => "\e[35m",
|
341
|
+
:cyan => "\e[36m",
|
342
|
+
:white => "\e[37m",
|
343
|
+
:on_black => "\e[40m",
|
344
|
+
:on_red => "\e[41m",
|
345
|
+
:on_green => "\e[42m",
|
346
|
+
:on_yellow => "\e[43m",
|
347
|
+
:on_blue => "\e[44m",
|
348
|
+
:on_magenta => "\e[45m",
|
349
|
+
:on_cyan => "\e[46m",
|
350
|
+
:on_white => "\e[47m"
|
351
|
+
}
|
352
|
+
def say(phrase, *args)
|
353
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
354
|
+
options[:color] = args.shift.to_s.to_sym unless args.empty?
|
355
|
+
keys = options.keys
|
356
|
+
keys.each{|key| options[key.to_s.to_sym] = options.delete(key)}
|
357
|
+
|
358
|
+
color = options[:color]
|
359
|
+
bold = options.has_key?(:bold)
|
360
|
+
|
361
|
+
parts = [phrase]
|
362
|
+
parts.unshift(This.ansi[color]) if color
|
363
|
+
parts.unshift(This.ansi[:bold]) if bold
|
364
|
+
parts.push(This.ansi[:clear]) if parts.size > 1
|
365
|
+
|
366
|
+
method = options[:method] || :puts
|
367
|
+
|
368
|
+
Kernel.send(method, parts.join)
|
369
|
+
end
|
370
|
+
|
371
|
+
# always run out of the project dir
|
372
|
+
#
|
373
|
+
Dir.chdir(This.dir)
|
374
|
+
}
|
data/ledis.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
## ledis.gemspec
|
2
|
+
#
|
3
|
+
|
4
|
+
Gem::Specification::new do |spec|
|
5
|
+
spec.name = "ledis"
|
6
|
+
spec.version = "0.0.1"
|
7
|
+
spec.platform = Gem::Platform::RUBY
|
8
|
+
spec.summary = "ledis"
|
9
|
+
spec.description = "description: ledis kicks the ass"
|
10
|
+
|
11
|
+
spec.files =
|
12
|
+
["README.md", "Rakefile", "ledis.gemspec", "lib", "lib/ledis.rb"]
|
13
|
+
|
14
|
+
spec.executables = []
|
15
|
+
|
16
|
+
spec.require_path = "lib"
|
17
|
+
|
18
|
+
spec.test_files = nil
|
19
|
+
|
20
|
+
### spec.add_dependency 'lib', '>= version'
|
21
|
+
#### spec.add_dependency 'map'
|
22
|
+
|
23
|
+
spec.extensions.push(*[])
|
24
|
+
|
25
|
+
spec.rubyforge_project = "codeforpeople"
|
26
|
+
spec.author = "Ara T. Howard"
|
27
|
+
spec.email = "ara.t.howard@gmail.com"
|
28
|
+
spec.homepage = "https://github.com/ahoward/ledis"
|
29
|
+
end
|
data/lib/ledis.rb
ADDED
@@ -0,0 +1,259 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
#
|
3
|
+
# NAME
|
4
|
+
#
|
5
|
+
# ledis
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# SYNOPSIS
|
9
|
+
#
|
10
|
+
# a K.I.S.S auto-rotating redis logger for ruby/rails
|
11
|
+
#
|
12
|
+
# Ruby
|
13
|
+
#
|
14
|
+
# redis = Redis.new
|
15
|
+
#
|
16
|
+
# logger = Ledis.logger redis
|
17
|
+
#
|
18
|
+
# logger = Ledis.new
|
19
|
+
#
|
20
|
+
# logger = Ledis.new do |config|
|
21
|
+
#
|
22
|
+
# config.redis = Redis.new
|
23
|
+
#
|
24
|
+
# config.list = 'teh_foo:log'
|
25
|
+
#
|
26
|
+
# config.cap = 2 ** 16
|
27
|
+
#
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# Rails
|
31
|
+
#
|
32
|
+
# ### file: config/environments/development.rb
|
33
|
+
#
|
34
|
+
# config.logger = Ledis.logger do |logger|
|
35
|
+
#
|
36
|
+
# logger.list = "teh_rails_app:#{ Rails.env }:log"
|
37
|
+
#
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
#
|
41
|
+
# DESCRIPTION
|
42
|
+
#
|
43
|
+
# ledis logs yo shiznit to redis. it's got built in logic to auto-truncate
|
44
|
+
# logs when they get to big
|
45
|
+
#
|
46
|
+
# logger.truncate(2 **16)
|
47
|
+
#
|
48
|
+
# and to grab the most recent ones
|
49
|
+
#
|
50
|
+
# puts logger.tail(1024)
|
51
|
+
#
|
52
|
+
# it's list/line oriented, just like a log file and makes no attempt to
|
53
|
+
# annotated log lines or add fancy data structures to them
|
54
|
+
#
|
55
|
+
# INSTALL
|
56
|
+
#
|
57
|
+
# gem 'ledis'
|
58
|
+
#
|
59
|
+
|
60
|
+
require 'logger'
|
61
|
+
|
62
|
+
module Ledis
|
63
|
+
##
|
64
|
+
#
|
65
|
+
class << Ledis
|
66
|
+
def version
|
67
|
+
'0.0.1'
|
68
|
+
end
|
69
|
+
|
70
|
+
def dependencies
|
71
|
+
{
|
72
|
+
'map' => [ 'map' , ' >= 6.0.1' ],
|
73
|
+
'redis' => [ 'redis' , ' >= 2.2.2' ]
|
74
|
+
}
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
begin
|
79
|
+
require 'rubygems'
|
80
|
+
rescue LoadError
|
81
|
+
nil
|
82
|
+
end
|
83
|
+
|
84
|
+
dependencies.each do |lib, dependency|
|
85
|
+
gem(*dependency) if defined?(gem)
|
86
|
+
require(lib)
|
87
|
+
end
|
88
|
+
|
89
|
+
##
|
90
|
+
#
|
91
|
+
class << Ledis
|
92
|
+
def logger(*args, &block)
|
93
|
+
return rails_logger(*args, &block) if defined?(::Rails.application)
|
94
|
+
|
95
|
+
Logger.new(*args, &block)
|
96
|
+
end
|
97
|
+
|
98
|
+
def rails_logger(*args, &block)
|
99
|
+
config = ::Rails.application.config
|
100
|
+
|
101
|
+
logger = Logger.new(*args, &block)
|
102
|
+
|
103
|
+
if defined?(::ActiveSupport::TaggedLogging)
|
104
|
+
logger = ::ActiveSupport::TaggedLogging.new(logger)
|
105
|
+
end
|
106
|
+
|
107
|
+
logger.level = config.log_level
|
108
|
+
|
109
|
+
logger
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
##
|
114
|
+
#
|
115
|
+
class Logger < ::Logger
|
116
|
+
#
|
117
|
+
attr_accessor :logdev
|
118
|
+
attr_accessor :formatter
|
119
|
+
|
120
|
+
def initialize(*args, &block)
|
121
|
+
super(STDERR)
|
122
|
+
@logdev = LogDevice.new(*args, &block)
|
123
|
+
@formatter = Formatter.new
|
124
|
+
end
|
125
|
+
|
126
|
+
class Formatter < ::Logger::Formatter
|
127
|
+
Format = "%s, [%s#%d] %5s : %s\n"
|
128
|
+
|
129
|
+
def call(severity, time, progname, msg)
|
130
|
+
Format %
|
131
|
+
[severity[0..0], format_datetime(time), $$, severity, msg2str(msg)]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def << (*args)
|
136
|
+
super
|
137
|
+
self
|
138
|
+
end
|
139
|
+
|
140
|
+
def level=(level)
|
141
|
+
@level = level_for(level)
|
142
|
+
end
|
143
|
+
|
144
|
+
Levels =
|
145
|
+
Hash[ Severity.constants.map{|c| [c.to_s.downcase, Severity.const_get(c)]} ]
|
146
|
+
|
147
|
+
def level_for(level)
|
148
|
+
case level
|
149
|
+
when Integer
|
150
|
+
Levels[ Levels.invert[level] || 4 ]
|
151
|
+
else
|
152
|
+
Levels[ level.to_s.downcase ]
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
%w(
|
157
|
+
redis redis=
|
158
|
+
list list=
|
159
|
+
cap cap=
|
160
|
+
step step=
|
161
|
+
cycle cycle=
|
162
|
+
tail
|
163
|
+
truncate
|
164
|
+
size
|
165
|
+
).each do |method|
|
166
|
+
case method
|
167
|
+
when /=/
|
168
|
+
class_eval <<-__, __FILE__, __LINE__
|
169
|
+
def #{ method }(arg)
|
170
|
+
@logdev.#{ method }(arg)
|
171
|
+
end
|
172
|
+
__
|
173
|
+
|
174
|
+
else
|
175
|
+
class_eval <<-__, __FILE__, __LINE__
|
176
|
+
def #{ method }(*args, &block)
|
177
|
+
@logdev.#{ method }(*args, &block)
|
178
|
+
end
|
179
|
+
__
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
##
|
184
|
+
#
|
185
|
+
class LogDevice
|
186
|
+
attr_accessor :config
|
187
|
+
attr_accessor :cap
|
188
|
+
attr_accessor :step
|
189
|
+
attr_accessor :cycle
|
190
|
+
attr_accessor :list
|
191
|
+
|
192
|
+
def initialize(*args, &block)
|
193
|
+
config = Map.options_for!(args)
|
194
|
+
config[:redis] ||= args.shift
|
195
|
+
configure(config, &block)
|
196
|
+
end
|
197
|
+
|
198
|
+
def configure(config = {}, &block)
|
199
|
+
@config = Map.for(config)
|
200
|
+
|
201
|
+
block.call(@config) if block
|
202
|
+
|
203
|
+
@redis = @config[:redis] || @redis
|
204
|
+
@cap = @config[:cap] || (2 ** 16)
|
205
|
+
@step = @config[:step] || 0
|
206
|
+
@cycle = @config[:cycle] || (2 ** 8)
|
207
|
+
@list = @config[:list] || 'ledis:log'
|
208
|
+
end
|
209
|
+
|
210
|
+
def redis
|
211
|
+
@redis ||= Redis.new
|
212
|
+
end
|
213
|
+
|
214
|
+
def redis=(redis)
|
215
|
+
@redis = redis
|
216
|
+
end
|
217
|
+
|
218
|
+
def write(message)
|
219
|
+
begin
|
220
|
+
redis.lpush(list, message)
|
221
|
+
rescue Object => e
|
222
|
+
error = "#{ e.message } (#{ e.class })\n#{ Array(e.backtrace).join(10.chr) }"
|
223
|
+
STDERR.puts(error)
|
224
|
+
STDERR.puts(message)
|
225
|
+
end
|
226
|
+
ensure
|
227
|
+
if (@step % @cycle).zero?
|
228
|
+
truncate(@cap) rescue nil
|
229
|
+
end
|
230
|
+
@step = (@step + 1) % @cycle
|
231
|
+
end
|
232
|
+
|
233
|
+
if defined?(Rails::Server) and STDOUT.tty? and not defined?(ActiveSupport::Logger.broadcast)
|
234
|
+
alias_method('__write__', 'write')
|
235
|
+
|
236
|
+
def write(message, &block)
|
237
|
+
STDOUT.puts(message)
|
238
|
+
__write__(message, &block)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def close
|
243
|
+
redis.quit rescue nil
|
244
|
+
end
|
245
|
+
|
246
|
+
def tail(n = 1024)
|
247
|
+
redis.lrange(list, 0, n - 1).reverse
|
248
|
+
end
|
249
|
+
|
250
|
+
def truncate(size)
|
251
|
+
redis.ltrim(list, 0, size - 1)
|
252
|
+
end
|
253
|
+
|
254
|
+
def size
|
255
|
+
redis.llen(list)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ledis
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ara T. Howard
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-06-15 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: ! 'description: ledis kicks the ass'
|
15
|
+
email: ara.t.howard@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- README.md
|
21
|
+
- Rakefile
|
22
|
+
- ledis.gemspec
|
23
|
+
- lib/ledis.rb
|
24
|
+
homepage: https://github.com/ahoward/ledis
|
25
|
+
licenses: []
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ! '>='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubyforge_project: codeforpeople
|
44
|
+
rubygems_version: 1.8.23
|
45
|
+
signing_key:
|
46
|
+
specification_version: 3
|
47
|
+
summary: ledis
|
48
|
+
test_files: []
|