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 ADDED
@@ -0,0 +1,7 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ .idea
5
+
6
+ # bundler
7
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in yell.gemspec
4
+ gemspec
5
+
6
+
7
+ group :development do
8
+ gem "rake"
9
+
10
+ gem "rspec", "~> 2"
11
+ gem "timecop"
12
+ end
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
@@ -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
@@ -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
@@ -0,0 +1,4 @@
1
+ module Yell
2
+ VERSION = "0.0.1"
3
+
4
+ end
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: []