daemon-kit 0.1.7.4 → 0.1.7.5

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.
@@ -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