teelogger 0.3.0 → 0.4.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d9c8a99263a3785628fce130b7a1557eb0cc89dd
4
- data.tar.gz: 8816398916355794b10a4c5a0bb47a0c710bd5cf
3
+ metadata.gz: 895f6e899d661222b23023e1ad0ebc7a57578b6a
4
+ data.tar.gz: 7ebdb6eeb7aee0fa333638951b6b8cff677b8f37
5
5
  SHA512:
6
- metadata.gz: 78d098f5fb1393b842b5356f2eb4629ccaaf6d332e0c5976200f410e385a6498116e217e2f36aebc289977be130202295365d5aa271d781177766e2481933ce6
7
- data.tar.gz: 57f4f91f1a68473af37473c968e2b4f221db3b5a901566e6f2ee0f184606af332ba52e3d5480df8aee277ab38ac138352b87e3eb5c1c0dc2a52e71077896f626
6
+ metadata.gz: 4da6b7652981ab639c5a3e728c3dce879a2db89ec4b81c4a5d8be960132cb047eee34d3c9765b4e55f6e847321f333d8690c222ddefbb03dd1dd9f2dae774aa2
7
+ data.tar.gz: befc09d315e3e342b7af707c10ec72f8b52a5b8ed8fced762b4ac905b2ae4578dc78f694b0c971d30794394f68b5e8a8e443a9b1ab4e77ea5d94497ebabeabb0
data/.travis.yml CHANGED
@@ -5,6 +5,11 @@ script:
5
5
  os:
6
6
  - linux
7
7
  - osx
8
+ language: ruby
8
9
  rvm:
9
10
  - 1.9.3
10
11
  - 2.0.0
12
+ notifications:
13
+ email:
14
+ recipients:
15
+ - foss@spritecloud.com
data/README.md CHANGED
@@ -56,3 +56,8 @@ end
56
56
  3. Commit your changes (`git commit -am 'Add some feature'`)
57
57
  4. Push to the branch (`git push origin my-new-feature`)
58
58
  5. Create a new Pull Request
59
+
60
+
61
+ ## Shameless Plug
62
+
63
+ Need software testing services? Contact [spriteCloud](http://www.spritecloud.com)
@@ -56,3 +56,20 @@ Feature: Logger
56
56
  | ERROR | have |
57
57
  | FATAL | have |
58
58
 
59
+ @logger_05
60
+ Scenario Outline: Flushing after each invocation
61
+ Given I create a TeeLogger with default parameters
62
+ And I set the flush_interval to "1"
63
+ And I set the log level to "<level>"
64
+ And I write a log message at log level "<level>"
65
+ Then I expect the log level "<level>" to have taken hold
66
+ And I expect the log message to appear on the screen
67
+
68
+ Examples:
69
+ | level |
70
+ | DEBUG |
71
+ | INFO |
72
+ | WARN |
73
+ | ERROR |
74
+ | FATAL |
75
+
@@ -10,8 +10,16 @@ logger = nil
10
10
 
11
11
  Given(/^I create a TeeLogger with default parameters$/) do
12
12
  logger = TeeLogger::TeeLogger.new
13
+ assert [TeeLogger::DEFAULT_FLUSH_INTERVAL] == logger.flush_interval, "Flush interval is not default: #{logger.flush_interval}"
13
14
  end
14
15
 
16
+ Given(/^I set the flush_interval to "([^"]*)"$/) do |interval|
17
+ i = interval.to_i
18
+ logger.flush_interval = i
19
+ assert [i] == logger.flush_interval, "Setting flush interval did not take: #{logger.flush_interval}"
20
+ end
21
+
22
+
15
23
  Given(/^I set the log level to "(.*?)"$/) do |level|
16
24
  logger.level = level
17
25
  end
@@ -28,6 +36,7 @@ end
28
36
  Then(/^I expect the log level "(.*?)" to (.*?) taken hold$/) do |level, condition|
29
37
  meth = "#{level.downcase}?".to_sym
30
38
  res = logger.send(meth)
39
+ logger.flush
31
40
 
32
41
  assert res, "Bad results!"
33
42
  if 'have' === condition
data/lib/teelogger.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  # TeeLogger
3
3
  # https://github.com/spriteCloud/teelogger
4
4
  #
5
- # Copyright (c) 2014 spriteCloud B.V. and other TeeLogger contributors.
5
+ # Copyright (c) 2014-2015 spriteCloud B.V. and other TeeLogger contributors.
6
6
  # All rights reserved.
7
7
  #
8
8
  require "teelogger/version"
@@ -10,6 +10,49 @@ require "teelogger/version"
10
10
  require "logger"
11
11
 
12
12
  module TeeLogger
13
+ DEFAULT_FLUSH_INTERVAL = 2000
14
+
15
+ ##
16
+ # Extensions for the ruby logger
17
+ module LoggerExtensions
18
+ attr_accessor :teelogger_io
19
+ attr_accessor :flush_interval
20
+
21
+ ##
22
+ # Flush ruby and OS buffers for this logger
23
+ def flush
24
+ if @teelogger_io.nil?
25
+ raise "TeeLogger logger without IO object, can't do anything"
26
+ end
27
+
28
+ @teelogger_io.flush
29
+ begin
30
+ @teelogger_io.fsync
31
+ rescue NotImplementedError, Errno::EINVAL
32
+ # pass
33
+ end
34
+ end
35
+
36
+
37
+ ##
38
+ # This function invokes flush if it's been invoked more often than
39
+ # flush_interval.
40
+ def auto_flush
41
+ if @written.nil?
42
+ @written = 0
43
+ end
44
+
45
+ @written += 1
46
+
47
+ if @written >= self.flush_interval
48
+ self.flush
49
+ @written = 0
50
+ end
51
+ end
52
+ end # module LoggerExtensions
53
+
54
+
55
+
13
56
  ##
14
57
  # Logger that writes to multiple outputs. Behaves just like Ruby's Logger,
15
58
  # and like a hash of String => Logger.
@@ -32,6 +75,7 @@ module TeeLogger
32
75
  class TeeLogger
33
76
  @default_level
34
77
  @loggers
78
+ @ios
35
79
 
36
80
  ##
37
81
  # Convert a log level to its string name
@@ -63,38 +107,51 @@ module TeeLogger
63
107
  return val
64
108
  end
65
109
 
110
+ private
111
+ ##
112
+ # Define log functions as strings, for internal re-use
113
+ LOG_FUNCTIONS = Logger::Severity.constants.map { |level| TeeLogger.string_level(level.to_s).downcase }
66
114
 
115
+ public
67
116
 
68
117
  ##
69
118
  # Add a logger to the current loggers.
70
119
  def add_logger(arg)
71
120
  key = nil
72
121
  logger = nil
122
+ io = nil
73
123
  if arg.is_a? String
74
124
  # We have a filename
75
125
  key = File.basename(arg)
76
126
 
77
127
  # Try to create the logger.
78
- file = File.new(arg, File::WRONLY | File::APPEND | File::CREAT)
79
- logger = Logger.new(file)
128
+ io = File.new(arg, File::WRONLY | File::APPEND | File::CREAT)
129
+ logger = Logger.new(io)
80
130
 
81
131
  # Initialize logger
82
- logger.unknown "Logging to '#{arg}' initialized with level #{TeeLogger.string_level(@default_level)}."
132
+ io.write "Logging to '#{arg}' initialized with level #{TeeLogger.string_level(@default_level)}.\n"
83
133
  logger.level = TeeLogger.convert_level(@default_level)
84
134
  else
85
135
  # We have some other object - let's hope it's an IO object
86
136
  key = arg.to_s
87
137
 
88
138
  # Try to create the logger.
89
- logger = Logger.new(arg)
139
+ io = arg
140
+ logger = Logger.new(io)
90
141
 
91
142
  # Initialize logger
92
- logger.unknown "Logging to #{key} initialized with level #{TeeLogger.string_level(@default_level)}."
143
+ io.write "Logging to #{key} initialized with level #{TeeLogger.string_level(@default_level)}.\n"
93
144
  logger.level = TeeLogger.convert_level(@default_level)
94
145
  end
95
146
 
96
- if not key.nil? and not logger.nil?
147
+ # Extend logger instances with extra functionality
148
+ logger.extend(LoggerExtensions)
149
+ logger.teelogger_io = io
150
+ logger.flush_interval = DEFAULT_FLUSH_INTERVAL
151
+
152
+ if not key.nil? and not logger.nil? and not io.nil?
97
153
  @loggers[key] = logger
154
+ @ios[key] = io
98
155
  end
99
156
  end
100
157
 
@@ -110,6 +167,7 @@ module TeeLogger
110
167
  # Initialization
111
168
  @default_level = Logger::Severity::INFO
112
169
  @loggers = {}
170
+ @ios = {}
113
171
 
114
172
  # Create logs for all arguments
115
173
  args.each do |arg|
@@ -117,6 +175,7 @@ module TeeLogger
117
175
  end
118
176
  end
119
177
 
178
+
120
179
  ##
121
180
  # Set log level; override this to also accept strings
122
181
  def level=(val)
@@ -142,13 +201,16 @@ module TeeLogger
142
201
 
143
202
  ##
144
203
  # For each log level, define an appropriate logging function
145
- Logger::Severity.constants.each do |const|
146
- meth = TeeLogger.string_level(const.to_s).downcase
147
-
204
+ ["add"] + LOG_FUNCTIONS.each do |meth|
205
+ # Methods corresponding to severity levels will be auto_flushed
148
206
  define_method(meth) { |*args, &block|
149
- dispatch(meth, *args, &block)
207
+ x = dispatch(meth, *args, &block)
208
+ dispatch("auto_flush")
209
+ x
150
210
  }
151
- if "unknown" != meth
211
+
212
+ # Query methods for severity levels are defined
213
+ if not ["unknown", "add"].include? meth
152
214
  query = "#{meth}?"
153
215
  define_method(query) { |*args, &block|
154
216
  dispatch(query, *args, &block)
@@ -157,6 +219,18 @@ module TeeLogger
157
219
  end
158
220
 
159
221
 
222
+ ##
223
+ # Add flush related functions from LoggerExtensions
224
+ LoggerExtensions.instance_methods(false).each do |method|
225
+ name = method.to_s
226
+ if name.start_with?("flush")
227
+ define_method(name) { |*args, &block|
228
+ dispatch(name, *args, &block)
229
+ }
230
+ end
231
+ end
232
+
233
+
160
234
  ##
161
235
  # Every function this class doesn't have should be mapped to the original
162
236
  # logger
@@ -207,12 +281,12 @@ module TeeLogger
207
281
  ret = []
208
282
  @loggers.each do |key, logger|
209
283
  if logger.respond_to? meth_name
210
- if args.length > 0
284
+ if LOG_FUNCTIONS.include? meth_name
211
285
  ret << logger.send(meth_name, key) do
212
286
  message
213
287
  end
214
288
  else
215
- ret << logger.send(meth_name, &block)
289
+ ret << logger.send(meth_name, *args, &block)
216
290
  end
217
291
  end
218
292
  end
@@ -228,4 +302,5 @@ module TeeLogger
228
302
  end
229
303
 
230
304
  end
305
+
231
306
  end
@@ -2,9 +2,9 @@
2
2
  # TeeLogger
3
3
  # https://github.com/spriteCloud/teelogger
4
4
  #
5
- # Copyright (c) 2014 spriteCloud B.V. and other TeeLogger contributors.
5
+ # Copyright (c) 2014,2015 spriteCloud B.V. and other TeeLogger contributors.
6
6
  # All rights reserved.
7
7
  #
8
8
  module TeeLogger
9
- VERSION = "0.3.0"
9
+ VERSION = "0.4.0"
10
10
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: teelogger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jens Finkhaeuser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-09 00:00:00.000000000 Z
11
+ date: 2015-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler