teelogger 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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