my_stuff-logger 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/COPYING +13 -0
- data/lib/my_stuff/logger/levels.rb +14 -0
- data/lib/my_stuff/logger/reader.rb +46 -0
- data/lib/my_stuff/logger/reader_filter.rb +13 -0
- data/lib/my_stuff/logger/reader_filters/multidb_unmangle.rb +30 -0
- data/lib/my_stuff/logger/reader_filters/priority_colors.rb +31 -0
- data/lib/my_stuff/logger/reader_filters/tail_follow_highlight.rb +14 -0
- data/lib/my_stuff/logger/reader_filters.rb +26 -0
- data/lib/my_stuff/logger/writer.rb +85 -0
- data/lib/my_stuff/logger.rb +31 -0
- metadata +56 -0
data/COPYING
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright (c) 2011-present, Fred Emmott <copyright@fredemmott.co.uk>
|
2
|
+
|
3
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
4
|
+
purpose with or without fee is hereby granted, provided that the above
|
5
|
+
copyright notice and this permission notice appear in all copies.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
8
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
9
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
10
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
11
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
12
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
13
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Copyright 2011-present Fred Emmott. See COPYING file.
|
2
|
+
|
3
|
+
require 'my_stuff/logger/levels'
|
4
|
+
require 'my_stuff/logger/reader_filters'
|
5
|
+
|
6
|
+
module MyStuff::Logger
|
7
|
+
class Reader
|
8
|
+
attr_accessor :filters
|
9
|
+
attr_reader :output
|
10
|
+
def colorize?; @colorize; end
|
11
|
+
|
12
|
+
def initialize options = {}
|
13
|
+
@output = options[:device] || STDOUT
|
14
|
+
if options.include? :colorize
|
15
|
+
@colorize = options[:colorize]
|
16
|
+
else
|
17
|
+
@colorize = @output.tty?
|
18
|
+
end
|
19
|
+
|
20
|
+
@filters = (options[:filters] || [
|
21
|
+
:PriorityColors,
|
22
|
+
]).map{ |filter| ReaderFilters.get(filter) }
|
23
|
+
end
|
24
|
+
|
25
|
+
# Read lines from IO, and pretty-print them.
|
26
|
+
def format_io input
|
27
|
+
input.each_line do |line|
|
28
|
+
output.write format_log_line(line)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def format_log_line x
|
33
|
+
filters.each do |filter|
|
34
|
+
x.replace(filter.call(x, :colorize => colorize?))
|
35
|
+
end
|
36
|
+
x
|
37
|
+
end
|
38
|
+
|
39
|
+
# Do a *really* poor job of emulating an IO device :p
|
40
|
+
def write x
|
41
|
+
x.each_line do |line|
|
42
|
+
output.write format_log_line(line)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# Copyright 2011-present Fred Emmott. See COPYING file.
|
2
|
+
|
3
|
+
module MyStuff::Logger
|
4
|
+
class ReaderFilter
|
5
|
+
def filter_line line, options = {}
|
6
|
+
raise NotImplementedError.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.to_proc
|
10
|
+
lambda { |*args| self.new.filter_line *args }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Copyright 2011-present Fred Emmott. See COPYING file.
|
2
|
+
|
3
|
+
require 'my_stuff/multidb'
|
4
|
+
|
5
|
+
module MyStuff::Logger::ReaderFilters
|
6
|
+
# For use with MyStuff::MultiDB.
|
7
|
+
#
|
8
|
+
# Your backtrace will include something like:
|
9
|
+
# Foo::MYSTUFF_MULTIDB_DB_load_of_hex::Bar
|
10
|
+
# And give you:
|
11
|
+
# Foo::<host:port/database>::Bar
|
12
|
+
class MultiDBUnmangle < MyStuff::Logger::ReaderFilter
|
13
|
+
def filter_line line, options = {}
|
14
|
+
line.gsub(/MYSTUFF_MULTIDB_DB_[a-z0-9]+/) do |mangled|
|
15
|
+
data = MyStuff::MultiDB.unmangle(mangled)
|
16
|
+
unmangled = "<%s:%d/%s>" % [
|
17
|
+
data[:host],
|
18
|
+
data[:port],
|
19
|
+
data[:database],
|
20
|
+
]
|
21
|
+
if options[:colorize]
|
22
|
+
# Make it cyan
|
23
|
+
"\e[36m%s\e[0m" % unmangled
|
24
|
+
else
|
25
|
+
unmangled
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Copyright 2011-present Fred Emmott. See COPYING file.
|
2
|
+
|
3
|
+
module MyStuff::Logger::ReaderFilters
|
4
|
+
# Highlight info/warning/error/fatal in different colors.
|
5
|
+
class PriorityColors < MyStuff::Logger::ReaderFilter
|
6
|
+
def filter_line line, options = {}
|
7
|
+
return line unless options[:colorize]
|
8
|
+
|
9
|
+
line = line.dup
|
10
|
+
|
11
|
+
# Colorize, based on priority
|
12
|
+
line.sub! /^([IWEF]) ([0-9]+ \[[^>]+>)/ do |prefix|
|
13
|
+
# Set the color
|
14
|
+
colors = {
|
15
|
+
# debug => meh
|
16
|
+
'I' => '32', # info => green
|
17
|
+
'W' => '33', # warn => yellow
|
18
|
+
'E' => '31', # errror => red
|
19
|
+
'F' => '1;31', # fatal => bold + red
|
20
|
+
}
|
21
|
+
# Reset it once the standard info is done
|
22
|
+
prefix.sub! /^[IWEF]/ do |pri|
|
23
|
+
"\e[%sm%s" % [colors[pri], pri]
|
24
|
+
end
|
25
|
+
prefix.sub! '>', ">\e[0m"
|
26
|
+
prefix
|
27
|
+
end
|
28
|
+
line
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Copyright 2011-present Fred Emmott. See COPYING file.
|
2
|
+
|
3
|
+
module MyStuff::Logger::ReaderFilters
|
4
|
+
# If you actually pipe tail -F through this...
|
5
|
+
class TailFollowHighlight < MyStuff::Logger::ReaderFilter
|
6
|
+
def filter_line line, options = {}
|
7
|
+
if options[:colorize]
|
8
|
+
line.sub(/^(tail: .+ new file$)/, "\e[1m\\1\e[0m")
|
9
|
+
else
|
10
|
+
line
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Copyright 2011-present Fred Emmott. See COPYING file.
|
2
|
+
|
3
|
+
require 'my_stuff/logger/reader_filter'
|
4
|
+
|
5
|
+
module MyStuff::Logger
|
6
|
+
module ReaderFilters
|
7
|
+
SYMBOL_MAP = {
|
8
|
+
:PriorityColors => 'priority_colors',
|
9
|
+
:TailFollowHighlight => 'tail_follow_highlight',
|
10
|
+
:MultiDBUnmangle => 'multidb_unmangle',
|
11
|
+
}
|
12
|
+
|
13
|
+
SYMBOL_MAP.each do |sym, file|
|
14
|
+
autoload sym, "my_stuff/logger/reader_filters/#{file}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.get filter
|
18
|
+
case filter
|
19
|
+
when Symbol
|
20
|
+
self.get MyStuff::Logger::ReaderFilters.const_get(filter)
|
21
|
+
when Class
|
22
|
+
filter.to_proc
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# Copyright 2011-present Fred Emmott. See COPYING file.
|
2
|
+
|
3
|
+
require 'my_stuff/logger/levels'
|
4
|
+
|
5
|
+
module MyStuff
|
6
|
+
module Logger
|
7
|
+
class Writer
|
8
|
+
# Configure the logger.
|
9
|
+
#
|
10
|
+
# These can be set:
|
11
|
+
# - globally, via Writer.option = foo
|
12
|
+
# - per-class, via Writer.new(:option => foo)
|
13
|
+
# - per class, via Writer.new.option = foo
|
14
|
+
OVERRIDABLE_OPTIONS = [
|
15
|
+
:backtrace_level,
|
16
|
+
:device,
|
17
|
+
:level,
|
18
|
+
:root_path,
|
19
|
+
]
|
20
|
+
attr_writer *OVERRIDABLE_OPTIONS
|
21
|
+
|
22
|
+
def initialize options = {}
|
23
|
+
OVERRIDABLE_OPTIONS.each do |opt|
|
24
|
+
if options.include? opt
|
25
|
+
instance_variable_set "@#{opt}", options[opt]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def raw_log outer_caller, level, args
|
31
|
+
|
32
|
+
unless LEVELS.include? level
|
33
|
+
raw_log outer_caller, :fatal, "%s (unknown level '%s')" % [log_text(*args), level.inspect]
|
34
|
+
end
|
35
|
+
|
36
|
+
return if LEVELS[level] < LEVELS[self.level]
|
37
|
+
|
38
|
+
message = "%s %s @%s> %s\n" % [
|
39
|
+
level.to_s[0].upcase, # D|I|W|E|F
|
40
|
+
Time.new.strftime("%s [%Y-%m-%d %H:%M:%S %z]"),
|
41
|
+
pretty_caller(outer_caller.first),
|
42
|
+
log_text(*args)
|
43
|
+
]
|
44
|
+
|
45
|
+
if LEVELS[level] >= LEVELS[self.backtrace_level]
|
46
|
+
# Full backtrace
|
47
|
+
outer_caller.each do |x|
|
48
|
+
message += " from %s\n" % pretty_caller(x)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
device.write message
|
53
|
+
end
|
54
|
+
|
55
|
+
LEVELS.each do |level,i|
|
56
|
+
define_method level do |*args|
|
57
|
+
raw_log caller, level, args
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
OVERRIDABLE_OPTIONS.each do |opt|
|
62
|
+
define_method opt do
|
63
|
+
instance_variable_get("@#{opt}") || MyStuff::Logger.send(opt)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def log_text *args
|
70
|
+
args.map do |arg|
|
71
|
+
case arg
|
72
|
+
when String
|
73
|
+
arg
|
74
|
+
else
|
75
|
+
arg.inspect
|
76
|
+
end
|
77
|
+
end.join('')
|
78
|
+
end
|
79
|
+
|
80
|
+
def pretty_caller x
|
81
|
+
x.sub(root_path + '/', '').sub(/^.\//, '')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Copyright 2011-present Fred Emmott. See COPYING file.
|
2
|
+
|
3
|
+
require 'my_stuff/logger/writer'
|
4
|
+
|
5
|
+
module MyStuff
|
6
|
+
module Logger
|
7
|
+
class <<self
|
8
|
+
def new *args
|
9
|
+
MyStuff::Logger::Writer.new *args
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_writer :device, :level, :backtrace_level, :root_path
|
13
|
+
|
14
|
+
def device
|
15
|
+
@device ||= STDOUT
|
16
|
+
end
|
17
|
+
|
18
|
+
def level
|
19
|
+
@level ||= :info
|
20
|
+
end
|
21
|
+
|
22
|
+
def backtrace_level
|
23
|
+
@backtrace_level ||= :error
|
24
|
+
end
|
25
|
+
|
26
|
+
def root_path
|
27
|
+
@root_path ||= File.dirname(File.expand_path($0))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: my_stuff-logger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Fred Emmott
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-08-30 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
14
|
+
description: ''
|
15
|
+
email:
|
16
|
+
- mail@fredemmott.co.uk
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- COPYING
|
22
|
+
- lib/my_stuff/logger/levels.rb
|
23
|
+
- lib/my_stuff/logger/reader.rb
|
24
|
+
- lib/my_stuff/logger/reader_filter.rb
|
25
|
+
- lib/my_stuff/logger/reader_filters/multidb_unmangle.rb
|
26
|
+
- lib/my_stuff/logger/reader_filters/priority_colors.rb
|
27
|
+
- lib/my_stuff/logger/reader_filters/tail_follow_highlight.rb
|
28
|
+
- lib/my_stuff/logger/reader_filters.rb
|
29
|
+
- lib/my_stuff/logger/writer.rb
|
30
|
+
- lib/my_stuff/logger.rb
|
31
|
+
homepage: https://github.com/fredemmott/my_stuff-logger
|
32
|
+
licenses:
|
33
|
+
- ISC
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
requirements: []
|
51
|
+
rubyforge_project:
|
52
|
+
rubygems_version: 1.8.6
|
53
|
+
signing_key:
|
54
|
+
specification_version: 3
|
55
|
+
summary: Logging class
|
56
|
+
test_files: []
|