yell 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/.gitignore +7 -0
- data/Gemfile +12 -0
- data/Rakefile +26 -0
- data/init.rb +1 -0
- data/lib/yell/adapters/base.rb +72 -0
- data/lib/yell/adapters/datefile.rb +39 -0
- data/lib/yell/adapters/file.rb +95 -0
- data/lib/yell/adapters.rb +19 -0
- data/lib/yell/config.rb +53 -0
- data/lib/yell/formatter.rb +58 -0
- data/lib/yell/logger.rb +82 -0
- data/lib/yell/version.rb +4 -0
- data/lib/yell.rb +21 -0
- data/yell.gemspec +21 -0
- metadata +58 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
$LOAD_PATH.unshift( 'lib' )
|
2
|
+
|
3
|
+
require 'bundler'
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
# === RSpec
|
7
|
+
require 'rspec/core/rake_task'
|
8
|
+
|
9
|
+
desc "Run specs"
|
10
|
+
RSpec::Core::RakeTask.new do |t|
|
11
|
+
t.rspec_opts = %w(-fs --color)
|
12
|
+
end
|
13
|
+
|
14
|
+
task :default => :spec
|
15
|
+
|
16
|
+
|
17
|
+
# === Rdoc
|
18
|
+
require 'rake/rdoctask'
|
19
|
+
Rake::RDocTask.new do |rdoc|
|
20
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
21
|
+
|
22
|
+
rdoc.rdoc_dir = 'rdoc'
|
23
|
+
rdoc.title = "inventory #{version}"
|
24
|
+
rdoc.rdoc_files.include('README*')
|
25
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
26
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'yell'
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Yell::Adapters
|
2
|
+
class Base
|
3
|
+
|
4
|
+
attr_reader :name # name of the logger this adapter belongs to
|
5
|
+
|
6
|
+
# Initialize a new base adapter. Other adapters should inherit from it.
|
7
|
+
def initialize ( options = {}, &block )
|
8
|
+
@block = block
|
9
|
+
|
10
|
+
@name = options[:name] || Yell.config.env
|
11
|
+
@level, @data = '', '' # default
|
12
|
+
end
|
13
|
+
|
14
|
+
def call ( level, msg )
|
15
|
+
reset!(true) if reset? # connect / get a file handle or whatever
|
16
|
+
|
17
|
+
@level, @message = level, msg
|
18
|
+
|
19
|
+
# self.instance_eval &@block if @block
|
20
|
+
@block.call( self ) if @block
|
21
|
+
end
|
22
|
+
|
23
|
+
def message
|
24
|
+
return @message if @message.is_a?( String )
|
25
|
+
|
26
|
+
@message.inspect
|
27
|
+
end
|
28
|
+
|
29
|
+
# Convenience method for resetting the processor.
|
30
|
+
#
|
31
|
+
# @param [true, false] now Perform the reset immediately? (default false)
|
32
|
+
def reset!( now = false )
|
33
|
+
close
|
34
|
+
open if now
|
35
|
+
end
|
36
|
+
|
37
|
+
# Opens the logfile or connection (in case of a database adapter)
|
38
|
+
def open
|
39
|
+
open! unless opened?
|
40
|
+
end
|
41
|
+
|
42
|
+
# Closes the file handle or connection (in case of a database adapter)
|
43
|
+
def close
|
44
|
+
close! unless closed?
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def reset?; closed?; end
|
51
|
+
|
52
|
+
# stub
|
53
|
+
def open!
|
54
|
+
raise "Not implemented"
|
55
|
+
end
|
56
|
+
|
57
|
+
def opened?; false; end
|
58
|
+
|
59
|
+
# stub
|
60
|
+
def close!
|
61
|
+
raise "Not implemented"
|
62
|
+
end
|
63
|
+
|
64
|
+
def closed?; !opened?; end
|
65
|
+
|
66
|
+
# stub
|
67
|
+
def write
|
68
|
+
raise 'Not implemented'
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Yell::Adapters
|
2
|
+
class Datefile < Yell::Adapters::File
|
3
|
+
|
4
|
+
DefaultDatePattern = "%Y%m%d"
|
5
|
+
|
6
|
+
def initialize ( options = {}, &block )
|
7
|
+
@date_pattern = options[:date_pattern] || DefaultDatePattern
|
8
|
+
@date = nil # default; do not override --R
|
9
|
+
|
10
|
+
@file_basename = options[:filename] || default_filename
|
11
|
+
options[:filename] = @file_basename
|
12
|
+
|
13
|
+
super( options, &block )
|
14
|
+
end
|
15
|
+
|
16
|
+
def reset!( now )
|
17
|
+
@filename = new_filename
|
18
|
+
super( now )
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def reset?
|
25
|
+
_date = Time.now.strftime( @date_pattern )
|
26
|
+
unless opened? && _date == @date
|
27
|
+
@date = _date
|
28
|
+
return true
|
29
|
+
end
|
30
|
+
|
31
|
+
false
|
32
|
+
end
|
33
|
+
|
34
|
+
def new_filename
|
35
|
+
@file_basename.sub( /(\.\w+)?$/, ".#{@date}\\1" )
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Yell::Adapters
|
2
|
+
class File < Yell::Adapters::Base
|
3
|
+
|
4
|
+
Colors = {
|
5
|
+
'DEBUG' => "\e[32;1m", # green;bold
|
6
|
+
# 'INFO' => "\e[0m", # white
|
7
|
+
'WARN' => "\e[33;1m", # yello;bold
|
8
|
+
'ERROR' => "\e[31;1m", # red;bold
|
9
|
+
'FATAL' => "\e[35;1m", # magenta;bold
|
10
|
+
'UNKNOWN' => "\e[36m", # cyan
|
11
|
+
'DEFAULT' => "\e[0m" # NONE
|
12
|
+
}
|
13
|
+
|
14
|
+
def initialize ( options = {}, &block )
|
15
|
+
super
|
16
|
+
|
17
|
+
@formatter = formatter_from( options )
|
18
|
+
|
19
|
+
@colorize = options[:colorize]
|
20
|
+
@filename = options[:filename] || default_filename
|
21
|
+
|
22
|
+
@file_prefix, @file_suffix = options[:file_prefix], options[:file_suffix]
|
23
|
+
|
24
|
+
# validate the filename
|
25
|
+
unless @filename.is_a?( String )
|
26
|
+
raise( TypeError, "Argument :filename must be a string." )
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def call ( level, msg )
|
31
|
+
super # Base call
|
32
|
+
|
33
|
+
msg = @formatter.format( @level, message )
|
34
|
+
msg = colorize( @level, msg ) if @colorize
|
35
|
+
msg << "\n" unless msg[-1] == ?\n # add new line if there is none
|
36
|
+
|
37
|
+
write( msg )
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def write ( msg )
|
44
|
+
@file.print( msg )
|
45
|
+
@file.flush
|
46
|
+
rescue Exception => e
|
47
|
+
close # make sure the file gets closed
|
48
|
+
raise( e ) # re-raise the error
|
49
|
+
end
|
50
|
+
|
51
|
+
def close!
|
52
|
+
@file.close
|
53
|
+
@file = nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def open!
|
57
|
+
# create directory if not exists
|
58
|
+
dirname = ::File.dirname( @filename )
|
59
|
+
FileUtils.mkdir_p( dirname ) unless ::File.directory?( dirname )
|
60
|
+
|
61
|
+
# open file for appending if exists, or create a new
|
62
|
+
filename = [ dirname, "#{@file_prefix}#{::File.basename(@filename)}#{@file_suffix}" ].join( '/' )
|
63
|
+
@file = ::File.open( filename, ::File::WRONLY|::File::APPEND|::File::CREAT )
|
64
|
+
end
|
65
|
+
|
66
|
+
def opened?; !@file.nil?; end
|
67
|
+
|
68
|
+
# Returns the right formatter from the given options
|
69
|
+
def formatter_from( options )
|
70
|
+
if options.key?(:formatter)
|
71
|
+
# this is done, so we can set :formatter => false to just output the given message
|
72
|
+
options[:formatter] || Yell::Formatter.new( "%m" )
|
73
|
+
elsif options[:formatter]
|
74
|
+
# the options :formatter was given
|
75
|
+
Yell::Formatter.new(
|
76
|
+
options[:formatter][:pattern],
|
77
|
+
options[:formatter][:date_pattern]
|
78
|
+
)
|
79
|
+
else
|
80
|
+
# Standard formatter
|
81
|
+
Yell::Formatter.new
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def colorize( level, msg )
|
86
|
+
return msg unless color = Colors[level.upcase]
|
87
|
+
color + msg + Colors['DEFAULT']
|
88
|
+
end
|
89
|
+
|
90
|
+
def default_filename
|
91
|
+
"#{Yell.config.env}.log"
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Yell
|
2
|
+
module Adapters
|
3
|
+
|
4
|
+
Dir[ ::File.dirname(__FILE__) + '/adapters/*.rb' ].each do |file|
|
5
|
+
autoload ::File.basename(file, '.rb').capitalize, file
|
6
|
+
end
|
7
|
+
|
8
|
+
# returns an instance of the given processor type
|
9
|
+
def self.new( type, options = {}, &block )
|
10
|
+
klass = case type
|
11
|
+
when String, Symbol then const_get( type.to_s.capitalize )
|
12
|
+
else type
|
13
|
+
end
|
14
|
+
|
15
|
+
klass.new( options, &block )
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
data/lib/yell/config.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
module Yell
|
2
|
+
class Config
|
3
|
+
|
4
|
+
def initialize( yaml_file = nil )
|
5
|
+
@yaml_file = yaml_file
|
6
|
+
|
7
|
+
reload!
|
8
|
+
end
|
9
|
+
|
10
|
+
def reload!; @options = nil; end
|
11
|
+
|
12
|
+
def []( key ); options[key]; end
|
13
|
+
|
14
|
+
def options
|
15
|
+
@options ||= begin
|
16
|
+
if yaml_file_defined?
|
17
|
+
require 'yaml'
|
18
|
+
require 'erb'
|
19
|
+
|
20
|
+
(YAML.load( ERB.new( File.read( yaml_file ) ).result ) || {})[ env ] || {}
|
21
|
+
else
|
22
|
+
{} # default
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def env
|
28
|
+
ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'default'
|
29
|
+
end
|
30
|
+
|
31
|
+
def root
|
32
|
+
return ENV['RAILS_ROOT'] if ENV['RAILS_ROOT']
|
33
|
+
return RAILS_ROOT if defined?( RAILS_ROOT )
|
34
|
+
|
35
|
+
'.'
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def yaml_file_defined?
|
42
|
+
yaml_file && File.exist?( yaml_file )
|
43
|
+
end
|
44
|
+
|
45
|
+
# Locates the yell.yml file. The file can end in .yml or .yaml,
|
46
|
+
# and be located in the current directory (eg. project root) or
|
47
|
+
# in a .config/ or config/ subdirectory of the current directory.
|
48
|
+
def yaml_file
|
49
|
+
@yaml_file || Dir.glob( "#{root}/{,.config/,config/}yell{.yml,.yaml}" ).first
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Yell
|
2
|
+
class Formatter
|
3
|
+
|
4
|
+
PatternTable = {
|
5
|
+
"m" => "message",
|
6
|
+
"d" => "date",
|
7
|
+
"l" => "level.downcase",
|
8
|
+
"L" => "level.upcase",
|
9
|
+
"p" => "$$", # pid
|
10
|
+
"h" => "hostname"
|
11
|
+
}
|
12
|
+
PatternRegexp = /([^%]*)(%\d*)?([dlLphm])?(.*)/
|
13
|
+
|
14
|
+
DefaultPattern = "%d [%5L] %p %h: %m"
|
15
|
+
DefaultDatePattern = "%Y-%m-%d %H:%M:%S" # ISO8601
|
16
|
+
|
17
|
+
|
18
|
+
def initialize ( pattern = nil, date_pattern = nil )
|
19
|
+
@pattern = pattern || DefaultPattern
|
20
|
+
@date_pattern = date_pattern || DefaultDatePattern
|
21
|
+
|
22
|
+
define_format_method
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def define_format_method
|
29
|
+
buff, args, _pattern = "", [], @pattern.dup
|
30
|
+
|
31
|
+
while true
|
32
|
+
match = PatternRegexp.match( _pattern )
|
33
|
+
|
34
|
+
buff << match[1] unless match[1].empty?
|
35
|
+
break if match[2].nil?
|
36
|
+
|
37
|
+
buff << match[2] + 's' # '%s'
|
38
|
+
args << PatternTable[ match[3] ]
|
39
|
+
|
40
|
+
_pattern = match[4]
|
41
|
+
end
|
42
|
+
|
43
|
+
instance_eval %-
|
44
|
+
def format ( level, message )
|
45
|
+
sprintf( "#{buff}", #{args.join(',')} )
|
46
|
+
end
|
47
|
+
-
|
48
|
+
end
|
49
|
+
|
50
|
+
def date; Time.now.strftime( @date_pattern ); end
|
51
|
+
|
52
|
+
def hostname
|
53
|
+
return @hostname if defined?( @hostname )
|
54
|
+
@hostname = Socket.gethostname rescue nil
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
data/lib/yell/logger.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
module Yell
|
2
|
+
class Logger
|
3
|
+
Levels = [ 'debug', 'info', 'warn', 'error', 'fatal', 'unknown' ]
|
4
|
+
|
5
|
+
|
6
|
+
def initialize( *args, &block )
|
7
|
+
@adapters = []
|
8
|
+
|
9
|
+
# extract options
|
10
|
+
@options = args.last.is_a?(Hash) ? args.pop : {}
|
11
|
+
|
12
|
+
# check if filename was given as argument and put it into the @options
|
13
|
+
if args.last.is_a?( String )
|
14
|
+
@options[:filename] = args.pop unless @options[:filename]
|
15
|
+
end
|
16
|
+
|
17
|
+
@default_adapter = args.last.is_a?( Symbol ) ? args.pop : :file
|
18
|
+
|
19
|
+
# eval the given block if any
|
20
|
+
instance_eval( &block ) if block
|
21
|
+
|
22
|
+
build
|
23
|
+
end
|
24
|
+
|
25
|
+
# === the following methods are used for the logger setup
|
26
|
+
def adapter ( type, options = {}, &block )
|
27
|
+
@adapters << Yell::Adapters.new( type, @options.merge(options), &block )
|
28
|
+
rescue LoadError => e
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
def level ( val )
|
33
|
+
@level = case val
|
34
|
+
when Integer then val
|
35
|
+
when String, Symbol then Levels.index( val.to_s )
|
36
|
+
else nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Convenience method for resetting all adapters of the Logger.
|
41
|
+
#
|
42
|
+
# @param [true, false] now Perform the reset immediately? (default false)
|
43
|
+
def reset!( now = false )
|
44
|
+
close
|
45
|
+
open if now
|
46
|
+
end
|
47
|
+
|
48
|
+
def close; @adapters.each(&:close); end
|
49
|
+
def open; @adapters.each(&:open); end
|
50
|
+
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def build
|
55
|
+
adapter @default_adapter if @adapters.empty? # default adapter when none defined
|
56
|
+
|
57
|
+
define_log_methods
|
58
|
+
end
|
59
|
+
|
60
|
+
def define_log_methods
|
61
|
+
Levels.each_with_index do |name, index|
|
62
|
+
instance_eval %-
|
63
|
+
def #{name}?; #{@level.nil? || index >= @level}; end
|
64
|
+
|
65
|
+
def #{name} ( data = '' )
|
66
|
+
return unless #{name}?
|
67
|
+
|
68
|
+
data = yield if block_given?
|
69
|
+
process( "#{name}", data )
|
70
|
+
|
71
|
+
data
|
72
|
+
end
|
73
|
+
-
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def process ( level, data )
|
78
|
+
@adapters.each { |a| a.call( level, data ) }
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
data/lib/yell/version.rb
ADDED
data/lib/yell.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Yell
|
2
|
+
|
3
|
+
autoload :Config, File.dirname(__FILE__) + '/yell/config'
|
4
|
+
autoload :Formatter, File.dirname(__FILE__) + '/yell/formatter'
|
5
|
+
autoload :Logger, File.dirname(__FILE__) + '/yell/logger'
|
6
|
+
autoload :Adapters, File.dirname(__FILE__) + '/yell/adapters'
|
7
|
+
|
8
|
+
# custom errors
|
9
|
+
class NoAdaptersDefined < StandardError; end
|
10
|
+
class NoSuchAdapter < StandardError; end
|
11
|
+
|
12
|
+
|
13
|
+
def self.new( *args, &block )
|
14
|
+
Yell::Logger.new( *args, &block )
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.config
|
18
|
+
@@config ||= Yell::Config.new
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/yell.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "yell/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "yell"
|
7
|
+
s.version = Yell::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Rudolf Schmidt"]
|
10
|
+
|
11
|
+
s.homepage = "http://rubygems.org/gems/yell"
|
12
|
+
s.summary = %q{Logging library to log into files and databases}
|
13
|
+
s.description = %q{Logging library to log into files and databases}
|
14
|
+
|
15
|
+
s.rubyforge_project = "d_log"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: yell
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Rudolf Schmidt
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-10-23 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
14
|
+
description: Logging library to log into files and databases
|
15
|
+
email:
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- .gitignore
|
21
|
+
- Gemfile
|
22
|
+
- Rakefile
|
23
|
+
- init.rb
|
24
|
+
- lib/yell.rb
|
25
|
+
- lib/yell/adapters.rb
|
26
|
+
- lib/yell/adapters/base.rb
|
27
|
+
- lib/yell/adapters/datefile.rb
|
28
|
+
- lib/yell/adapters/file.rb
|
29
|
+
- lib/yell/config.rb
|
30
|
+
- lib/yell/formatter.rb
|
31
|
+
- lib/yell/logger.rb
|
32
|
+
- lib/yell/version.rb
|
33
|
+
- yell.gemspec
|
34
|
+
homepage: http://rubygems.org/gems/yell
|
35
|
+
licenses: []
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options: []
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ! '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubyforge_project: d_log
|
54
|
+
rubygems_version: 1.8.10
|
55
|
+
signing_key:
|
56
|
+
specification_version: 3
|
57
|
+
summary: Logging library to log into files and databases
|
58
|
+
test_files: []
|