daemon-kit 0.1.7.4 → 0.1.7.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -29,6 +29,7 @@ DaemonKit includes a couple of its own arguments that can be used:
29
29
 
30
30
  -e ENV (or --env ENV) to set the daemon environment
31
31
  --pid /path/to/pidfile to set the path to a pidfile
32
+ -l path (or --log path) to set the path for the log file
32
33
  -v shows the DaemonKit version
33
34
  -h shows a useful help message
34
35
 
@@ -0,0 +1,113 @@
1
+ = Deploying your daemons
2
+
3
+ daemon-kit provides built-in support for
4
+ Capistrano[http://www.capify.org] deployments, using a customized
5
+ version of the standard 'deploy' recipe for Ruby on Rails
6
+ applications.
7
+
8
+ User of Vlad[http://hitsquad.rubyforge.org/vlad/]? Get in touch so we
9
+ can discuss your contribution to daemon-kit ;)
10
+
11
+ == Generating capistrano configurations
12
+
13
+ When generating a new daemon, you can pass the <em>-d capistrano</em>
14
+ argument to the <em>daemon_kit</em> command. In case you already have
15
+ a generated daemon, run the following command inside your project:
16
+
17
+ $ ruby script/generate deploy_capistrano
18
+
19
+ == Overview of generated configurations
20
+
21
+ The generator creates the following files worth noticing:
22
+
23
+ config/deploy.rb
24
+ config/deploy/*.rb
25
+
26
+ The generator also creates a new environment for you, a
27
+ <em>staging</em> environment. Useful for testing your deployments
28
+ before taking anything into production.
29
+
30
+ == Configuring capistrano
31
+
32
+ For each environment (staging & production) you only need to specify
33
+ the target hosts in <em>config/deploy/(staging|production).rb</em>.
34
+
35
+ Each of the stub files have example configuration values you can just
36
+ edit.
37
+
38
+ The rest of your configuration generally occurs in
39
+ <em>config/deploy.rb</em>.
40
+
41
+ Everything works exactly like standard capistrano, with the exception
42
+ of the following directives:
43
+
44
+ * :config_files
45
+ * :shared_children
46
+
47
+ === :config_files
48
+
49
+ Since the daemon configuration files will almost always differ between
50
+ your development environment and your staging/production environment,
51
+ the deployment recipe makes adequate provision for this.
52
+
53
+ Use the :config_files directive to set an array of file names from the
54
+ <em>config</em> directory that you want replaced with production
55
+ configuration files found on the server:
56
+
57
+ set :config_files, %w{ amqp.yaml }
58
+
59
+ On your target server, in the <em>:deploy_to</em> folder, create a
60
+ <em>config</em> directory and place your configuration files in
61
+ there. One each deploy, capistrano will rename the files in your
62
+ deployed configuration directory with a <em>.orig</em> extension, and copy
63
+ the files from <em>:deploy_to/config</em> into the newly deployed
64
+ release.
65
+
66
+ This makes it easy to keep production configurations out of your
67
+ working directories or version control systems.
68
+
69
+ === :shared_children
70
+
71
+ The original capistrano recipe that daemon-kit's recipe is built from
72
+ provided support for tracking shared directories between
73
+ deployments. This works by removing the deployed directory, and
74
+ creating a symlink from <em>:deploy_to/shared/</em> into the correct
75
+ location within the deployed release.
76
+
77
+ You specify your list of directories with the
78
+ <em>:shared_children</em>, each being relative to the DAEMON_ROOT.
79
+
80
+ set :shared_children, %w{ log }
81
+
82
+ The daemon-kit deployment recipe makes no assumptions on shared
83
+ directories, and gives you full control. The default only includes the
84
+ log directory, which you can remove if you want separate log
85
+ directories for each deployed release.
86
+
87
+ == Remote dependencies
88
+
89
+ By default, the deployment configuration file is configured to check
90
+ the remote dependencies before updating the code on the target
91
+ host. You can disable this behaviour by commenting out the following
92
+ line:
93
+
94
+ before "deploy:update_code", "deploy:check"
95
+
96
+ The only default remote dependency is the daemon-kit gem, and it will
97
+ check for the same version you currently have installed (or a later
98
+ one).
99
+
100
+ == More capistrano resources
101
+
102
+ To see a list of available commands, please run the following command
103
+ in the root of your project:
104
+
105
+ $ cap -vT
106
+
107
+ For more information on capistrano, please refer to the following list
108
+ of online resources:
109
+
110
+ * Capistrano Website[http://www.capify.org]
111
+ * Capistrano Wiki[http://wiki.capify.org]
112
+ * Capistrano Group[http://groups.google.com/group/capistrano]
113
+ * #capistrano on Freenode
@@ -1,5 +1,13 @@
1
- == 0.1.7.4 (Not released)
1
+ == 0.1.7.5 2009-06-08
2
2
 
3
+ * New AbstractLogger
4
+ ** Default Logger backend
5
+ ** SysLogLogger support
6
+ * More documentation
7
+
8
+ == 0.1.7.4 2009-06-05
9
+
10
+ * Fixed bug with control script generator (thanks Sho Fukamachi)
3
11
  * Enhanced deploy.rb template to check for current dk gem verion,
4
12
  unless vendored
5
13
  * Fix bug in capistrano recipe for restarting daemons
@@ -0,0 +1,92 @@
1
+ = Logging from inside your daemon
2
+
3
+ Proper logging inside your daemon process is critical, and daemon-kit
4
+ provides you with a great logging facility to (ab)use.
5
+
6
+ == Logging examples
7
+
8
+ From anywhere in your code you can access the
9
+ <em>DaemonKit.logger</em> instance, which is a configured
10
+ DaemonKit::AbstractLogger. It is compatible with Ruby's Logger class
11
+ but is much more verbose to help you gain some insight into your
12
+ running process.
13
+
14
+ DaemonKit.logger.info( "Hello world" )
15
+
16
+ This logs a 'Hello world' line to the log file, complete with the
17
+ calling file name and line number. Log lines look something like this:
18
+
19
+ 2009-06-07 23:21:30.248575 capd(32513) [INFO] initializer.rb:91: DaemonKit (0.1.7.4) booted, now running capd
20
+
21
+ Log as much as you can, but be careful not to abuse the <em>info</em>
22
+ level since your log files can become huge. For general processing
23
+ hints, use the <em>debug</em> level.
24
+
25
+ To log exceptions, use the special <em>exception</em> helper:
26
+
27
+ begin
28
+ # dangerous operation
29
+ rescue => e
30
+ DaemonKit.logger.exception( e )
31
+ end
32
+
33
+ == Controlling logging in a running process
34
+
35
+ Logging can be controlled in a running process, either via code or by
36
+ sending UNIX signals to the running process.
37
+
38
+ === Changing log levels in your code
39
+
40
+ Log levels can be toggled with the <em>level=</em> method:
41
+
42
+ DaemonKit.logger.level = :info
43
+
44
+ Alternatively you can silence all the logging activity for a while
45
+ using the silence helper:
46
+
47
+ DaemonKit.logger.silence do |logger|
48
+ # logger will only report :error or higher levels
49
+ end
50
+
51
+ === Changing log levels via UNIX signals
52
+
53
+ Send your process the +USR1+ signal to toggle between <em>:debug</em>
54
+ and <em>:info</em> log levels. Sending a +USR2+ signal will force the
55
+ logger into <em>:debug</em> mode (+USR1+ will revert).
56
+
57
+ == Support for log rotation
58
+
59
+ Support for logrotate is baked right into daemon-kit. By sending your
60
+ daemon a +HUP+ signal all the log files file be closed and re-opened
61
+ again on first use. Here is an example logrotate configuration:
62
+
63
+ /path/to/daemon.log {
64
+ rotate 5
65
+ weekly
66
+ postrotate
67
+ kill -HUP `cat /path/to/daemon.pid`
68
+ endscript
69
+ }
70
+
71
+ == Support for syslog logging
72
+
73
+ If you have the
74
+ SyslogLogger[http://seattlerb.rubyforge.org/SyslogLogger/] gem
75
+ installed, you can have your process log to a UNIX syslog server. You
76
+ can change the logging to syslog by either updating your
77
+ <em>environment.rb</em> file like this:
78
+
79
+ config.log_path = :syslog
80
+
81
+ Or by passing 'syslog' as the logfile argument when starting a daemon
82
+
83
+ $ ruby ./bin/daemon start -l syslog
84
+
85
+ The SyslogLogger rdoc's provide configuration examples for configuring
86
+ various UNIX syslog servers.
87
+
88
+ == More logging information
89
+
90
+ If you're running your daemon in the foreground (with the <em>run</em>
91
+ command, you'll get copies of all the log messages on STDOUT, and thus
92
+ voiding the need to tail log files the whole time.
@@ -1,5 +1,7 @@
1
1
  Configuration.txt
2
+ Deployment.txt
2
3
  History.txt
4
+ Logging.txt
3
5
  Manifest.txt
4
6
  PostInstall.txt
5
7
  README.rdoc
@@ -52,6 +54,7 @@ daemon_generators/nanite_agent/templates/config/nanite.yml
52
54
  daemon_generators/nanite_agent/templates/lib/actors/sample.rb
53
55
  daemon_generators/nanite_agent/templates/libexec/daemon.rb
54
56
  lib/daemon_kit.rb
57
+ lib/daemon_kit/abstract_logger.rb
55
58
  lib/daemon_kit/amqp.rb
56
59
  lib/daemon_kit/application.rb
57
60
  lib/daemon_kit/arguments.rb
@@ -87,6 +90,7 @@ script/console
87
90
  script/destroy
88
91
  script/generate
89
92
  script/txt2html
93
+ spec/abstract_logger_spec.rb
90
94
  spec/argument_spec.rb
91
95
  spec/config_spec.rb
92
96
  spec/daemon_kit_spec.rb
@@ -21,7 +21,6 @@ Supported generators:
21
21
 
22
22
  * Build it
23
23
  * Review TODO.txt
24
- * Review Configuration.txt
25
24
 
26
25
  == Synopsis
27
26
 
@@ -80,6 +79,11 @@ Stable versions, when released are available directly from Rubyforge:
80
79
 
81
80
  $ gem install daemon-kit
82
81
 
82
+ == Further reading
83
+
84
+ * Configuration.txt
85
+ * Deployment.txt
86
+
83
87
  == License
84
88
 
85
89
  (The MIT License)
@@ -7,19 +7,20 @@ $:.unshift( File.dirname(__FILE__).to_absolute_path ) unless
7
7
  $:.include?( File.dirname(__FILE__).to_absolute_path )
8
8
 
9
9
  module DaemonKit
10
- VERSION = '0.1.7.4'
11
-
12
- autoload :Initializer, 'daemon_kit/initializer'
13
- autoload :Application, 'daemon_kit/application'
14
- autoload :Arguments, 'daemon_kit/arguments'
15
- autoload :Config, 'daemon_kit/config'
16
- autoload :Safety, 'daemon_kit/safety'
17
- autoload :PidFile, 'daemon_kit/pid_file'
18
-
19
- autoload :Cron, 'daemon_kit/cron'
20
- autoload :Jabber, 'daemon_kit/jabber'
21
- autoload :AMQP, 'daemon_kit/amqp'
22
- autoload :Nanite, 'daemon_kit/nanite'
10
+ VERSION = '0.1.7.5'
11
+
12
+ autoload :Initializer, 'daemon_kit/initializer'
13
+ autoload :Application, 'daemon_kit/application'
14
+ autoload :Arguments, 'daemon_kit/arguments'
15
+ autoload :Config, 'daemon_kit/config'
16
+ autoload :Safety, 'daemon_kit/safety'
17
+ autoload :PidFile, 'daemon_kit/pid_file'
18
+ autoload :AbstractLogger, 'daemon_kit/abstract_logger'
19
+
20
+ autoload :Cron, 'daemon_kit/cron'
21
+ autoload :Jabber, 'daemon_kit/jabber'
22
+ autoload :AMQP, 'daemon_kit/amqp'
23
+ autoload :Nanite, 'daemon_kit/nanite'
23
24
 
24
25
  class << self
25
26
  def logger
@@ -0,0 +1,235 @@
1
+ require 'logger'
2
+
3
+ module DaemonKit
4
+ # One of the key parts of succesful background processes is adequate
5
+ # logging. The AbstractLogger aims to simplify logging from inside
6
+ # daemon processes by providing additional useful information with
7
+ # each log line, including calling file name and line number and
8
+ # support for cleanly logging exceptions.
9
+ #
10
+ # The logger can be accessed through #DaemonKit.logger.
11
+ #
12
+ # AbstractLogger provides an interface that is fully compatible with
13
+ # the Logger class provided by Ruby's Standard Library, and is
14
+ # extended with some additional conveniences.
15
+ #
16
+ # The AbstractLogger supports different backends, by default it uses
17
+ # a Logger instance, but can by swapped out for a SysLogLogger
18
+ # logger as well.
19
+ class AbstractLogger
20
+
21
+ attr_accessor :copy_to_stdout
22
+
23
+ @severities = {
24
+ :debug => Logger::DEBUG,
25
+ :info => Logger::INFO,
26
+ :warn => Logger::WARN,
27
+ :error => Logger::ERROR,
28
+ :fatal => Logger::FATAL,
29
+ :unknown => Logger::UNKNOWN
30
+ }
31
+
32
+ @silencer = true
33
+
34
+ class << self
35
+ attr_reader :severities
36
+ attr_accessor :silencer
37
+ end
38
+
39
+ # Optional log path, defaults to
40
+ # <em>DAEMON_ROOT/log/DAEMON_ENV.log</em>
41
+ def initialize( log_path = nil )
42
+ if log_path.to_s == "syslog"
43
+ @backend = :syslog
44
+ else
45
+ @logger_file = log_path || "#{DAEMON_ROOT}/log/#{DAEMON_ENV}.log"
46
+ @backend = :logger
47
+ end
48
+
49
+ @copy_to_stdout = false
50
+ end
51
+
52
+ # Silence the logger for the duration of the block.
53
+ def silence( temporary_level = :error )
54
+ if self.class.silencer
55
+ begin
56
+ old_level, self.level = self.level, temporary_level
57
+ yield self
58
+ ensure
59
+ self.level = old_level
60
+ end
61
+ else
62
+ yield self
63
+ end
64
+ end
65
+
66
+ def debug( msg )
67
+ add( :debug, msg )
68
+ end
69
+
70
+ def debug?
71
+ self.level == :debug
72
+ end
73
+
74
+ def info( msg )
75
+ add( :info, msg )
76
+ end
77
+
78
+ def info?
79
+ self.level == :info
80
+ end
81
+
82
+ def warn( msg )
83
+ add( :warn, msg )
84
+ end
85
+
86
+ def warn?
87
+ self.level == :warn
88
+ end
89
+
90
+ def error( msg )
91
+ add( :error, msg )
92
+ end
93
+
94
+ def error?
95
+ self.level == :error
96
+ end
97
+
98
+ def fatal( msg )
99
+ add( :fatal, msg )
100
+ end
101
+
102
+ def fatal?
103
+ self.level == :fatal
104
+ end
105
+
106
+ def unknown( msg )
107
+ add( :unknown, msg )
108
+ end
109
+
110
+ def unknown?
111
+ self.level == :unknown
112
+ end
113
+
114
+ def exception( e )
115
+ message = "EXCEPTION: #{e.message}: #{clean_trace( e.backtrace )}"
116
+ self.add( :error, message, true )
117
+ end
118
+
119
+ def add( severity, message, skip_caller = false )
120
+ message = "#{called(caller)}: #{message}" unless skip_caller
121
+
122
+ self.logger.add( self.class.severities[ severity ] ) { message }
123
+
124
+ STDOUT.puts( message ) if self.copy_to_stdout
125
+ end
126
+
127
+ def level
128
+ self.class.severities.invert[ @logger.level ]
129
+ end
130
+
131
+ def level=( level )
132
+ level = ( Symbol === level ? self.class.severities[ level ] : level )
133
+ self.logger.level = level
134
+ end
135
+
136
+ def logger
137
+ @logger ||= create_logger
138
+ end
139
+
140
+ def logger=( logger )
141
+ if logger.is_a?( Symbol )
142
+ @backend = logger
143
+ @logger.close rescue nil
144
+ @logger = create_logger
145
+ else
146
+ @logger.close rescue nil
147
+ @logger = logger
148
+ end
149
+ end
150
+
151
+ def clean_trace( trace )
152
+ trace = trace.map { |l| l.gsub(DAEMON_ROOT, '') }
153
+ trace = trace.reject { |l| l =~ /gems\/daemon[\-_]kit/ }
154
+ trace = trace.reject { |l| l =~ /vendor\/daemon[\-_]kit/ }
155
+ trace
156
+ end
157
+
158
+ def close
159
+ case @backend
160
+ when :logger
161
+ self.logger.close
162
+ @logger = nil
163
+ end
164
+ end
165
+
166
+ private
167
+
168
+ def called( trace )
169
+ l = trace.detect('unknown:0') { |l| l.index('abstract_logger.rb').nil? }
170
+ file, num, _ = l.split(':')
171
+
172
+ [ File.basename(file), num ].join(':')
173
+ end
174
+
175
+ def create_logger
176
+ case @backend
177
+ when :logger
178
+ create_standard_logger
179
+ when :syslog
180
+ create_syslog_logger
181
+ end
182
+ end
183
+
184
+ def create_standard_logger
185
+ log_path = File.dirname( @logger_file )
186
+ unless File.directory?( log_path )
187
+ begin
188
+ FileUtils.mkdir_p( log_path )
189
+ rescue
190
+ STDERR.puts "#{log_path} not writable, using STDERR for logging"
191
+ @logger_file = STDERR
192
+ end
193
+ end
194
+
195
+ l = Logger.new( @logger_file )
196
+ l.formatter = Formatter.new
197
+ l.progname = if DaemonKit.configuration
198
+ DaemonKit.configuration.daemon_name
199
+ else
200
+ File.basename($0)
201
+ end
202
+ l
203
+ end
204
+
205
+ def create_syslog_logger
206
+ begin
207
+ require 'syslog_logger'
208
+ SyslogLogger.new( DaemonKit.configuration ? DaemonKit.configuration.daemon_name : File.basename($0) )
209
+ rescue LoadError
210
+ self.logger = :logger
211
+ self.error( "Couldn't load syslog_logger gem, reverting to standard logger" )
212
+ end
213
+ end
214
+
215
+ class Formatter
216
+
217
+ # YYYY:MM:DD HH:MM:SS.MS daemon_name(pid) level: message
218
+ @format = "%s %s(%d) [%s] %s\n"
219
+
220
+ class << self
221
+ attr_accessor :format
222
+ end
223
+
224
+ def call(severity, time, progname, msg)
225
+ self.class.format % [ format_time( time ), progname, $$, severity, msg.to_s ]
226
+ end
227
+
228
+ private
229
+
230
+ def format_time( time )
231
+ time.strftime( "%Y-%m-%d %H:%M:%S." ) + time.usec.to_s
232
+ end
233
+ end
234
+ end
235
+ end
@@ -33,6 +33,8 @@ module DaemonKit
33
33
  self.clean_fd
34
34
  self.redirect_io( true )
35
35
 
36
+ DaemonKit.configuration.log_stdout = true
37
+
36
38
  require file
37
39
  end
38
40
 
@@ -58,6 +58,7 @@ module DaemonKit
58
58
  #
59
59
  # -e value or --env value => environment
60
60
  # --pid pidfile => pid_file
61
+ # -l path or --log path => /path/to/log/file
61
62
  #
62
63
  def configuration( argv )
63
64
  configs = []
@@ -74,6 +75,11 @@ module DaemonKit
74
75
  configs << "environment=#{argv.delete_at(i)}"
75
76
  end
76
77
 
78
+ if argv[i] == "-l" || argv[i] == "--log"
79
+ argv.delete_at( i )
80
+ configs << "log_path=#{argv.delete_at(i)}"
81
+ end
82
+
77
83
  if argv[i] == "--pid"
78
84
  argv.delete_at( i )
79
85
  configs << "pid_file=#{argv.delete_at(i)}"
@@ -92,7 +98,7 @@ module DaemonKit
92
98
  end
93
99
 
94
100
  attr_reader :options
95
-
101
+
96
102
  def initialize
97
103
  @options = {}
98
104
 
@@ -121,6 +127,10 @@ module DaemonKit
121
127
  # Nothing, just here for show
122
128
  end
123
129
 
130
+ opts.on("-l", "--log /path/to/logfile", "Path to the log file", "Defaults to log/[environment].log") do
131
+ # Nothing, just here for show
132
+ end
133
+
124
134
  opts.separator ""
125
135
  opts.separator "Advanced configurations:"
126
136
  opts.on("--config ATTRIBUTE=VALUE",
@@ -1,4 +1,3 @@
1
- require 'logger'
2
1
  require 'pathname'
3
2
 
4
3
  DAEMON_ENV = (ENV['DAEMON_ENV'] || 'development').dup unless defined?(DAEMON_ENV)
@@ -135,8 +134,9 @@ module DaemonKit
135
134
  return if DaemonKit.logger
136
135
 
137
136
  unless logger = configuration.logger
138
- logger = Logger.new( configuration.log_path )
137
+ logger = AbstractLogger.new( configuration.log_path )
139
138
  logger.level = configuration.log_level
139
+ logger.copy_to_stdout = configuration.log_stdout
140
140
  end
141
141
 
142
142
  DaemonKit.logger = logger
@@ -144,13 +144,16 @@ module DaemonKit
144
144
  DaemonKit.logger.info "DaemonKit (#{DaemonKit::VERSION}) booting in #{DAEMON_ENV} mode"
145
145
 
146
146
  configuration.trap("USR1") {
147
- DaemonKit.logger.level = DaemonKit.logger.debug? ? Logger::INFO : Logger::DEBUG
147
+ DaemonKit.logger.level = DaemonKit.logger.debug? ? :info : :debug
148
148
  DaemonKit.logger.info "Log level changed to #{DaemonKit.logger.debug? ? 'DEBUG' : 'INFO' }"
149
149
  }
150
150
  configuration.trap("USR2") {
151
- DaemonKit.logger.level = Logger::DEBUG
151
+ DaemonKit.logger.level = :debug
152
152
  DaemonKit.logger.info "Log level changed to DEBUG"
153
153
  }
154
+ configuration.trap("HUP") {
155
+ DaemonKit.logger.close
156
+ }
154
157
  end
155
158
 
156
159
  def initialize_signal_traps
@@ -178,14 +181,17 @@ module DaemonKit
178
181
  # List of load paths
179
182
  attr_accessor :load_paths
180
183
 
184
+ # Custom logger instance to use
185
+ attr_accessor :logger
186
+
181
187
  # The log level to use, defaults to DEBUG
182
188
  attr_accessor :log_level
183
189
 
184
190
  # Path to the log file, defaults to 'log/<environment>.log'
185
191
  attr_accessor :log_path
186
192
 
187
- # Provide a custom logger to use
188
- attr_accessor :logger
193
+ # Duplicate log data to stdout
194
+ attr_accessor :log_stdout
189
195
 
190
196
  # Path to the pid file, defaults to 'log/<daemon_name>.pid'
191
197
  attr_accessor :pid_file
@@ -209,8 +215,8 @@ module DaemonKit
209
215
  set_daemon_defaults!
210
216
 
211
217
  self.load_paths = default_load_paths
212
- self.log_level = default_log_level
213
- self.log_path = default_log_path
218
+ self.log_level ||= default_log_level
219
+ self.log_path ||= default_log_path
214
220
 
215
221
  self.force_kill_wait = false
216
222
 
@@ -299,21 +305,13 @@ module DaemonKit
299
305
  raise "DAEMON_ROOT is not a directory" unless File.directory?(::DAEMON_ROOT)
300
306
 
301
307
  @root_path = ::DAEMON_ROOT.to_absolute_path
302
- # Pathname is incompatible with Windows, but Windows doesn't have
303
- # real symlinks so File.expand_path is safe.
304
- #if RUBY_PLATFORM =~ /(:?mswin|mingw)/
305
- # File.expand_path(::DAEMON_ROOT)
306
-
307
- # Otherwise use Pathname#realpath which respects symlinks.
308
- #else
309
- # File.expand_path( Pathname.new(::DAEMON_ROOT).realpath.to_s )
310
- #end
311
308
 
312
309
  Object.const_set(:RELATIVE_DAEMON_ROOT, ::DAEMON_ROOT.dup) unless defined?(::RELATIVE_DAEMON_ROOT)
313
310
  ::DAEMON_ROOT.replace @root_path
314
311
  end
315
312
 
316
313
  def set_daemon_defaults!
314
+ self.log_stdout = false
317
315
  end
318
316
 
319
317
  def default_load_paths
@@ -325,7 +323,7 @@ module DaemonKit
325
323
  end
326
324
 
327
325
  def default_log_level
328
- environment == 'production' ? Logger::INFO : Logger::DEBUG
326
+ environment == 'production' ? :info : :debug
329
327
  end
330
328
 
331
329
  def error( msg )
@@ -0,0 +1,126 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe DaemonKit::AbstractLogger do
4
+
5
+ before(:each) do
6
+ @log_file = "#{DAEMON_ROOT}/log/spec.log"
7
+ @logger = DaemonKit::AbstractLogger.new( @log_file )
8
+ @logger.level = :debug
9
+ end
10
+
11
+ it "should have a log level" do
12
+ @logger.level.should == :debug
13
+ end
14
+
15
+ it "should have a backend logger" do
16
+ @logger.logger.should_not be_nil
17
+ end
18
+
19
+ it "should accept a different backend" do
20
+ l = Logger.new('/dev/null')
21
+ @logger.logger = l
22
+ @logger.logger.should == l
23
+ end
24
+
25
+ it "should be able to log to STDOUT as well" do
26
+ @logger.copy_to_stdout = true
27
+
28
+ STDOUT.expects(:puts).with(regexp_matches(/test/))
29
+
30
+ @logger.debug "test"
31
+ IO.readlines( @log_file ).last.should match(/test/)
32
+ end
33
+
34
+ it "should log debug level messages" do
35
+ @logger.debug( "Debug test" )
36
+
37
+ IO.readlines( @log_file ).last.should match(/\[DEBUG\].*Debug test/)
38
+ end
39
+
40
+ it "should log info level messages" do
41
+ @logger.info( "Info test" )
42
+
43
+ IO.readlines( @log_file ).last.should match(/\[INFO\].*Info test/)
44
+ end
45
+
46
+ it "should log warn level messages" do
47
+ @logger.warn( "Warn test" )
48
+
49
+ IO.readlines( @log_file ).last.should match(/\[WARN\].*Warn test/)
50
+ end
51
+
52
+ it "should log error level messages" do
53
+ @logger.error( "Err test" )
54
+
55
+ IO.readlines( @log_file ).last.should match(/\[ERROR\].*Err test/)
56
+ end
57
+
58
+ it "should log fatal level messages" do
59
+ @logger.fatal( "Fatal test" )
60
+
61
+ IO.readlines( @log_file ).last.should match(/\[FATAL\].*Fatal test/)
62
+ end
63
+
64
+ it "should log unknown level messages" do
65
+ @logger.unknown( "Unknown test" )
66
+
67
+ IO.readlines( @log_file ).last.should match(/\[ANY\].*Unknown test/)
68
+ end
69
+
70
+ it "should log the caller file and line number" do
71
+ f = File.basename(__FILE__)
72
+ l = __LINE__ + 2
73
+
74
+ @logger.info( "Caller test" )
75
+
76
+ IO.readlines( @log_file ).last.should match(/#{f}:#{l}:/)
77
+ end
78
+
79
+ it "should log exceptions with daemon traces" do
80
+ fake_trace = [
81
+ "/home/kenneth/daemon/libexec/daemon-daemon.rb:1:in `foo'",
82
+ "/usr/lib/ruby/gems/1.8/gems/daemon-kit-0.0.1/lib/daemon_kit/abstract_logger.rb:49: in `info'"
83
+ ]
84
+
85
+ e = RuntimeError.new( 'Test error' )
86
+ e.set_backtrace( fake_trace )
87
+
88
+ @logger.exception( e )
89
+
90
+ IO.readlines( @log_file ).last.should match(/EXCEPTION: Test error/)
91
+ end
92
+
93
+ it "should log exceptions without framework traces" do
94
+ fake_trace = [
95
+ "/home/kenneth/daemon/libexec/daemon-daemon.rb:1:in `foo'",
96
+ "/usr/lib/ruby/gems/1.8/gems/daemon-kit-0.0.1/lib/daemon_kit/abstract_logger.rb:49: in `info'"
97
+ ]
98
+
99
+ clean_trace = @logger.clean_trace( fake_trace )
100
+
101
+ clean_trace.should include("/home/kenneth/daemon/libexec/daemon-daemon.rb:1:in `foo'")
102
+ clean_trace.should_not include("/usr/lib/ruby/gems/1.8/gems/daemon-kit-0.0.1/lib/daemon_kit/abstract_logger.rb:49: in `info'")
103
+ end
104
+
105
+ it "should support reopening log files" do
106
+ @logger.close
107
+
108
+ FileUtils.rm( @log_file )
109
+
110
+ @logger.info( 'Reopen')
111
+ IO.readlines( @log_file ).last.should match(/Reopen/)
112
+ end
113
+
114
+ it "should support silencing" do
115
+ @logger.silence do |logger|
116
+ logger.info "This should never be logged"
117
+ end
118
+
119
+ @logger.info "This should be logged"
120
+
121
+ log = IO.readlines( @log_file )
122
+
123
+ log.detect { |l| l =~ /This should never be logged/ }.should be_nil
124
+ log.detect { |l| l =~ /This should be logged/ }.should_not be_nil
125
+ end
126
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: daemon-kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7.4
4
+ version: 0.1.7.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenneth Kalmer
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-05 00:00:00 +02:00
12
+ date: 2009-06-08 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -51,14 +51,18 @@ extensions: []
51
51
 
52
52
  extra_rdoc_files:
53
53
  - Configuration.txt
54
+ - Deployment.txt
54
55
  - History.txt
56
+ - Logging.txt
55
57
  - Manifest.txt
56
58
  - PostInstall.txt
57
59
  - README.rdoc
58
60
  - TODO.txt
59
61
  files:
60
62
  - Configuration.txt
63
+ - Deployment.txt
61
64
  - History.txt
65
+ - Logging.txt
62
66
  - Manifest.txt
63
67
  - PostInstall.txt
64
68
  - README.rdoc
@@ -111,6 +115,7 @@ files:
111
115
  - daemon_generators/nanite_agent/templates/lib/actors/sample.rb
112
116
  - daemon_generators/nanite_agent/templates/libexec/daemon.rb
113
117
  - lib/daemon_kit.rb
118
+ - lib/daemon_kit/abstract_logger.rb
114
119
  - lib/daemon_kit/amqp.rb
115
120
  - lib/daemon_kit/application.rb
116
121
  - lib/daemon_kit/arguments.rb
@@ -146,6 +151,7 @@ files:
146
151
  - script/destroy
147
152
  - script/generate
148
153
  - script/txt2html
154
+ - spec/abstract_logger_spec.rb
149
155
  - spec/argument_spec.rb
150
156
  - spec/config_spec.rb
151
157
  - spec/daemon_kit_spec.rb