timber 2.1.4 → 2.1.5

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: 8abcf84c32b728be216520c831ea391b2d8d4aff
4
- data.tar.gz: bd66dceece6b234a4de867656eeaeebeb5c9a7a5
3
+ metadata.gz: 73567629c6afb913426d711c96cb394d9e2bf741
4
+ data.tar.gz: 952d3e7d73d9de740abdaf536d3eb3fe985024e4
5
5
  SHA512:
6
- metadata.gz: 71850c881fe047e8e80f850010f99989b0206be96087cbf15ff84adb09b6d9780b062ba492e65c2fffd659bd2d013c12f6e2b829c60847d0e750ae56f9d6268d
7
- data.tar.gz: 27c4421fcfa563a47d6d92911effde2472a3e48b4ba5da9b7def6ee3fa031f1bcc2d3a9cd54da88a3aa13db1f0a19e5556eb6d5c84fba4394aa62f28ab353c54
6
+ metadata.gz: 5ddc053cd804b4121e27fd91128b9f950270a85fc10a316a57f9a618000c46e5fbe07627a492af9574d7c77096004da07b21343263155cf40dc534f1301174d5
7
+ data.tar.gz: 2f063f0a6ec629265f4fbd1f2d7de23392d81faaef3a671fc02129bdfa984ddbda873391ca118040cda3a27fe61ad599a4920ce9014b05e2da757bbb1375ca61
data/README.md CHANGED
@@ -4,17 +4,17 @@
4
4
  [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://www.rubydoc.info/github/timberio/timber-ruby)
5
5
  [![Build Status](https://travis-ci.org/timberio/timber-ruby.svg?branch=master)](https://travis-ci.org/timberio/timber-ruby)
6
6
 
7
+ [Timber.io](https://timber.io) is a simple cloud-based logging platform built for developers.
8
+ This is our official Ruby library.
9
+
7
10
  ## Overview
8
11
 
9
- Timber for Ruby is a drop-in upgrade for your Ruby logs that unobtrusively
10
- [structures your logs through augmentation](https://timber.io/docs/concepts/structuring-through-augmentation).
11
- It's clean structured logging without the effort. When paired with the
12
- [Timber console](#the-timber-console), Timber will
13
- [fundamentally change the way you use your logs](#do-amazing-things-with-your-logs).
12
+ Ruby logs are broken. They're noisy, unparesable, and in the context of multiple servers and processes, unreadable. Current logging systems built for ops engineers haven't helped. This is why we built Timber. It's a different approach to Ruby logging. Instead of prefixing your logs with noisy tags, Timber integrates directly with your application, capturing rich context and metadata without altering your logs. This makes your logs easy to [search, use, and _read_](#do-amazing-things-with-your-logs), giving you _complete_ insight into your Ruby app.
14
13
 
15
14
  1. [**Easy setup** - `bundle exec timber install`](#installation)
16
- 2. [**Seamlessly integrates with popular libraries and frameworks**](#integrations)
17
- 3. [**Do amazing things with your Ruby logs**](#do-amazing-things-with-your-logs)
15
+ 2. [**Powerful logging**](#usage)
16
+ 3. [**Seamlessly integrates with popular libraries and frameworks**](#integrations)
17
+ 4. [**Do amazing things with your Ruby logs**](#do-amazing-things-with-your-logs)
18
18
 
19
19
 
20
20
  ## Installation
@@ -52,12 +52,13 @@ metadata, you don't have to worry about making every log structured!
52
52
 
53
53
  </p></details>
54
54
 
55
- <details><summary><strong>Custom events</strong></summary><p>
55
+ <details><summary><strong>Logging events (structured data)</strong></summary><p>
56
56
 
57
- Custom events allow you to extend beyond events already defined in the
58
- [`Timber::Events`](http://www.rubydoc.info/github/timberio/timber-ruby/Timber/Events) namespace.
59
- If you aren't sure what an event is, please read the
60
- ["Metdata, Context, and Events" doc](https://timber.io/docs/concepts/metadata-context-and-events).
57
+ Logging events allows you to log structured data without sacrificing readability or worrying about
58
+ structured data name or type conflicts. Keep in mind, Timber defines common events in the
59
+ [`Timber::Events`](http://www.rubydoc.info/github/timberio/timber-ruby/Timber/Events) namespace,
60
+ which are automatically logged for you through our [integrations](#integrations). You should not
61
+ have to maually log events defined there except in special circumstances.
61
62
 
62
63
  ### How to use it
63
64
 
@@ -75,22 +76,29 @@ logger.warn "Payment rejected", payment_rejected: {customer_id: "abcd1234", amou
75
76
 
76
77
  </p></details>
77
78
 
78
- <details><summary><strong>Custom contexts</strong></summary><p>
79
+ <details><summary><strong>Setting context</strong></summary><p>
79
80
 
80
- Custom contexts allow you to extend beyond contexts already defined in
81
- the [`Timber::Contexts`](http://www.rubydoc.info/github/timberio/timber-ruby/Timber/Contexts)
82
- namespace. If you aren't sure what context is, please read the
83
- ["Metdata, Context, and Events" doc](https://timber.io/docs/concepts/metadata-context-and-events).
81
+ Context is amazingly powerful, think of it like join data for your logs. It represents the
82
+ environment when the log was written, allowing you to relate logs so you can easily segment them.
83
+ It's how Timber is able to accomplish features like
84
+ [tailing users](https://timber.io/docs/app/console/tail-a-user) and
85
+ [tracing HTTP requests](https://timber.io/docs/app/console/trace-http-requests).
86
+ Keep in mind, Timber defines common contexts in the
87
+ [`Timber::Contexts`](http://www.rubydoc.info/github/timberio/timber-ruby/Timber/Contexts) namespace,
88
+ which are automatically set for you through our [integrations](#integrations). You should not
89
+ have to maually set these contexts except in special circumstances.
84
90
 
85
91
  ### How to use it
86
92
 
87
93
  ```ruby
88
- logger.with_context(build: {version: "1.0.0"}) do
89
- logger.info("My log message")
94
+ logger.with_context(job: {id: 123}) do
95
+ logger.info("Background job execution started")
96
+ # ... code here
97
+ logger.info("Background job execution completed")
90
98
  end
91
99
  ```
92
100
 
93
- 1. [Search it](https://timber.io/docs/app/console/searching) with queries like: `build.version:1.0.0`
101
+ 1. [Search it](https://timber.io/docs/app/console/searching) with queries like: `job.id:123`
94
102
  2. [View this context when viewing a log's metadata](https://timber.io/docs/app/console/view-metdata-and-context)
95
103
  3. ...read more in our [docs](https://timber.io/docs/languages/ruby/usage/custom-context)
96
104
 
@@ -158,7 +166,7 @@ config = Timber::Config.instance
158
166
  config.logrageify!()
159
167
  ```
160
168
 
161
- ## How it works
169
+ ### How it works
162
170
 
163
171
  It turns this:
164
172
 
@@ -301,10 +309,10 @@ All variables are optional, but at least one must be present.
301
309
 
302
310
  ## Integrations
303
311
 
304
- [Timber for Ruby](https://github.com/timberio/timber-ruby) extends beyond your basic logging
305
- functionality and integrates with popular libraries and frameworks. This makes structured quality
306
- logging effortless. Below is a list of integrations we offer and the various events and contexts
307
- they create.
312
+ Timber integrates with popular frameworks and libraries to capture context and metadata you
313
+ couldn't otherwise. This automatically upgrades logs produced by these libraries, making them
314
+ [easier to search and use](#do-amazing-things-with-your-logs). Below is a list of libraries we
315
+ support:
308
316
 
309
317
  1. [**Rails**](https://timber.io/docs/languages/ruby/integrations/rails)
310
318
  2. [**Rack**](https://timber.io/docs/languages/ruby/integrations/rack)
@@ -318,14 +326,13 @@ they create.
318
326
 
319
327
  ## Do amazing things with your logs
320
328
 
321
- What does all of this mean? Doing amazing things with your logs! Being more productive, solving
322
- problems faster, and _actually_ enjoying using your logs for application insight:
329
+ Unlock the potential of your logs:
323
330
 
324
- 1. [**Live tail users on your app**](https://timber.io/docs/app/console/tail-a-user)
325
- 2. [**Trace HTTP requests**](https://timber.io/docs/app/console/trace-http-requests)
326
- 3. [**Inspect HTTP request parameters**](https://timber.io/docs/app/console/inspect-http-requests)
327
- 4. [**Powerful searching**](https://timber.io/docs/app/console/searching)
328
- 5. [**Threshold based alerting**](https://timber.io/docs/app/alerts)
331
+ 1. [**Powerful searching.** - Find what you need faster.](https://timber.io/docs/app/console/searching)
332
+ 2. [**Live tail users.** - Easily solve customer issues.](https://timber.io/docs/app/console/tail-a-user)
333
+ 3. [**Viw logs per HTTP request.** - See the full story without the noise.](https://timber.io/docs/app/console/trace-http-requests)
334
+ 4. [**Inspect HTTP request parameters.** - Quickly reproduce issues.](https://timber.io/docs/app/console/inspect-http-requests)
335
+ 5. [**Threshold based alerting.** - Know when things break.](https://timber.io/docs/app/alerts)
329
336
  6. ...and more! Checkout our [the Timber application docs](https://timber.io/docs/app)
330
337
 
331
338
 
@@ -22,6 +22,10 @@ module Timber
22
22
  append!("config.logrageify!")
23
23
  end
24
24
 
25
+ def silence_template_renders!
26
+ append!("config.integrations.action_view.silence = true")
27
+ end
28
+
25
29
  private
26
30
  def append!(code)
27
31
  if !content.include?(code)
@@ -19,6 +19,33 @@ module Timber
19
19
  io.puts IO::Messages.separator, :green
20
20
  io.puts ""
21
21
 
22
+ # if OSHelper.has_git?
23
+ # if OSHelper.git_master? || !OSHelper.git_clean_working_tree?
24
+ # io.puts "Before we begin, this installer will make a few simple code changes."
25
+ # io.puts ""
26
+
27
+ # case io.ask_yes_no("Would you like to exit and start over on a clean git branch?")
28
+ # when :yes
29
+ # command = "git checkout -b install-timber"
30
+ # copied = OSHelper.copy_to_clipboard(command)
31
+
32
+ # io.puts ""
33
+ # io.puts "Good idea. Here's a simple git command to make things easier:"
34
+ # io.puts ""
35
+ # io.puts " #{IO::ANSI.colorize(command, :blue)}"
36
+
37
+ # if copied
38
+ # io.puts " #{IO::Messages.copied_to_clipboard}"
39
+ # end
40
+
41
+ # io.puts ""
42
+ # io.puts "Once you've switched branches, run the installer command again."
43
+ # io.puts ""
44
+ # return
45
+ # end
46
+ # end
47
+ # end
48
+
22
49
  if !api_key
23
50
  api.event(:no_api_key)
24
51
 
@@ -33,7 +60,7 @@ module Timber
33
60
  if OSHelper.can_open?
34
61
  case io.ask_yes_no("Open #{app_url}?")
35
62
  when :yes
36
- puts ""
63
+ io.puts ""
37
64
  io.task("Opening #{app_url}") do
38
65
  OSHelper.open(app_url)
39
66
  end
@@ -22,6 +22,8 @@ module Timber
22
22
 
23
23
  if logrageify?
24
24
  config_file.logrageify!
25
+ elsif silence_template_renders?
26
+ config_file.silence_template_renders!
25
27
  end
26
28
 
27
29
  io.puts ""
@@ -31,7 +33,7 @@ module Timber
31
33
 
32
34
  private
33
35
  def logrageify?
34
- if defined?(::Lograge)
36
+ if lograge?
35
37
  io.puts ""
36
38
  io.puts IO::Messages.separator
37
39
  io.puts ""
@@ -54,6 +56,44 @@ module Timber
54
56
  false
55
57
  end
56
58
  end
59
+
60
+ def lograge?
61
+ require "lograge"
62
+ true
63
+ rescue Exception
64
+ false
65
+ end
66
+
67
+ def silence_template_renders?
68
+ if action_view?
69
+ io.puts ""
70
+ io.puts IO::Messages.separator
71
+ io.puts ""
72
+ io.puts "Would you like to silence template render logs?"
73
+ io.puts "(We've founds this to be of low value in production environments."
74
+ io.puts "You can always adjust this later in config/initialzers/timber.rb)"
75
+ io.puts ""
76
+ io.puts "y) Yes, silence template renders", :blue
77
+ io.puts "n) No, use the Rails logging defaults", :blue
78
+ io.puts ""
79
+
80
+ case io.ask_yes_no("Enter your choice:", event_prompt: "Silence template renders?")
81
+ when :yes
82
+ true
83
+ when :no
84
+ false
85
+ end
86
+ else
87
+ false
88
+ end
89
+ end
90
+
91
+ def action_view?
92
+ require("action_view")
93
+ true
94
+ rescue Exception
95
+ false
96
+ end
57
97
  end
58
98
  end
59
99
  end
@@ -111,11 +111,11 @@ module Timber
111
111
  io.puts ""
112
112
  io.puts IO::Messages.separator
113
113
  io.puts ""
114
- io.puts "All done! Simply run your application locally and you'll see logs"
115
- io.puts "show up in Timber. Enjoy!"
114
+ io.puts "All done! To start using Timber:"
116
115
  io.puts ""
117
- io.puts "When you're ready to move to production/staging, create a"
118
- io.puts "production/staging app in Timber and follow the instructions shown."
116
+ io.puts IO::ANSI.colorize("1. Run your application locally to see logs show up in Timber", :blue)
117
+ io.puts IO::ANSI.colorize("2. When you're ready to move to production/staging, create a", :blue)
118
+ io.puts IO::ANSI.colorize(" production/staging app in Timber and follow the instructions shown.", :blue)
119
119
  io.puts ""
120
120
  io.ask_to_proceed
121
121
  end
@@ -91,7 +91,7 @@ MESSAGE
91
91
 
92
92
  def free_data
93
93
  message = <<-MESSAGE
94
- Because you're awesome, we've credited your account with ✨ 100mb✨.
94
+ Get free data:
95
95
 
96
96
  * Get ✨ 250mb✨ for starring our repo: #{IO::ANSI.colorize(REPO_URL, :blue)}
97
97
  * Get ✨ 250mb✨ for tweeting your experience to #{IO::ANSI.colorize(TWITTER_HANDLE, :blue)}
@@ -101,7 +101,7 @@ MESSAGE
101
101
 
102
102
  def header
103
103
  message = <<-MESSAGE
104
- 🌲 Timber.io Ruby Installer
104
+ 🌲 Timber.io Ruby Installer - Sane logging for Ruby developers.
105
105
 
106
106
  ^ ^ ^ ^ ___I_ ^ ^ ^ ^ ^ ^ ^
107
107
  /|\\/|\\/|\\ /|\\ /\\-_--\\ /|\\/|\\ /|\\/|\\/|\\ /|\\/|\\
@@ -14,6 +14,10 @@ module Timber
14
14
  false
15
15
  end
16
16
 
17
+ def self.git_clean_working_tree?
18
+ `git diff-index --quiet HEAD -- || echo "untracked";` == ""
19
+ end
20
+
17
21
  def self.git_commit_changes
18
22
  begin
19
23
  `git add config/initializers/timber.rb`
@@ -26,6 +30,10 @@ module Timber
26
30
  false
27
31
  end
28
32
 
33
+ def self.git_master?
34
+ `git rev-parse --abbrev-ref HEAD` == "master"
35
+ end
36
+
29
37
  def self.has_git?
30
38
  begin
31
39
  `which git` != ""
@@ -52,22 +52,11 @@ module Timber
52
52
  # @note Because context is included with every log line, it is recommended that you limit this
53
53
  # to only neccessary data.
54
54
  #
55
- # @example Adding a custom context with a map
55
+ # @example Adding a custom context
56
56
  # Timber::CurrentContext.with({build: {version: "1.0.0"}}) do
57
57
  # # ... anything logged here will include the context ...
58
58
  # end
59
59
  #
60
- # @example Adding a custom context with a struct
61
- # BuildContext = Struct.new(:version) do
62
- # def type; :build; end
63
- # end
64
- # build_context = BuildContext.new("1.0.0")
65
- # Timber::CurrentContext.with(build_context) do
66
- # # ... anything logged here will include the context ...
67
- # end
68
- # # Be sure to checkout Timber::Contexts! These are officially supported and many of these
69
- # # will be automatically included via Timber::Integrations
70
- #
71
60
  # @example Adding multiple contexts
72
61
  # Timber::CurrentContext.with(context1, context2) { ... }
73
62
  def with(*objects)
@@ -1,5 +1,4 @@
1
1
  require "timber/log_devices/http"
2
- require "timber/log_devices/multi"
3
2
 
4
3
  module Timber
5
4
  # Namespace for all log devices.
@@ -8,63 +8,14 @@ require "timber/log_devices"
8
8
  require "timber/log_entry"
9
9
 
10
10
  module Timber
11
- # The Timber Logger behaves exactly like `::Logger`, except that it supports a transparent API
12
- # for logging structured messages. It ensures your log messages are communicated properly
13
- # with the Timber.io API.
11
+ # The Timber Logger behaves exactly like the standard Ruby `::Logger`, except that it supports a
12
+ # transparent API for logging structured data and events.
14
13
  #
15
- # To adhere to our no code debt / no lock-in promise, the Timber Logger will *never* deviate
16
- # from the `::Logger` interface. That is, it will *never* add methods, or alter any
17
- # method signatures. This ensures Timber can be removed without consequence.
18
- #
19
- # @example Basic example (the original ::Logger interface remains untouched):
14
+ # @example Basic logging
20
15
  # logger.info "Payment rejected for customer #{customer_id}"
21
16
  #
22
- # @example Using a Hash
23
- # # The :message key is required, the other additional key is your event type and data
24
- # # :type is the namespace used in timber for the :data
17
+ # @example Logging an event
25
18
  # logger.info "Payment rejected", payment_rejected: {customer_id: customer_id, amount: 100}
26
- #
27
- # @example Using a Struct (a simple, more structured way, to define events)
28
- # PaymentRejectedEvent = Struct.new(:customer_id, :amount, :reason) do
29
- # # `#message` and `#type` are required, otherwise they will not be logged properly.
30
- # # `#type` is the namespace used in timber for the struct data
31
- # def message; "Payment rejected for #{customer_id}"; end
32
- # def type; :payment_rejected; end
33
- # end
34
- # Logger.info PaymentRejectedEvent.new("abcd1234", 100, "Card expired")
35
- #
36
- # @example Using typed Event classes
37
- # # Event implementation is left to you. Events should be simple classes.
38
- # # The only requirement is that it responds to #to_timber_event and return the
39
- # # appropriate Timber::Events::* type.
40
- # class Event
41
- # def to_hash
42
- # hash = {}
43
- # instance_variables.each { |var| hash[var.to_s.delete("@")] = instance_variable_get(var) }
44
- # hash
45
- # end
46
- # alias to_h to_hash
47
- #
48
- # def to_timber_event
49
- # Timber::Events::Custom.new(type: type, message: message, data: to_hash)
50
- # end
51
- #
52
- # def message; raise NotImplementedError.new; end
53
- # def type; raise NotImplementedError.new; end
54
- # end
55
- #
56
- # class PaymentRejectedEvent < Event
57
- # attr_accessor :customer_id, :amount
58
- # def initialize(customer_id, amount)
59
- # @customer_id = customer_id
60
- # @amount = amount
61
- # end
62
- # def message; "Payment rejected for customer #{customer_id}"; end
63
- # def type; :payment_rejected_event; end
64
- # end
65
- #
66
- # Logger.info PymentRejectedEvent.new("abcd1234", 100)
67
- #
68
19
  class Logger < ::Logger
69
20
 
70
21
  # @private
@@ -209,15 +160,13 @@ module Timber
209
160
  # file_device = Logger::LogDevice.new("path/to/file.log")
210
161
  # logger = Timber::Logger.new(http_device, file_device)
211
162
  def initialize(*io_devices)
212
- io_device = \
213
- if io_devices.size == 0
214
- raise ArgumentError.new("At least one IO device must be provided when instantiating " +
215
- "a Timber::Logger. Ex: Timber::Logger.new(STDOUT).")
216
- elsif io_devices.size > 1
217
- LogDevices::Multi.new(io_devices)
218
- else
219
- io_devices.first
220
- end
163
+ if io_devices.size == 0
164
+ raise ArgumentError.new("At least one IO device must be provided when instantiating " +
165
+ "a Timber::Logger. Ex: Timber::Logger.new(STDOUT).")
166
+ end
167
+
168
+ @extra_loggers = io_devices[1..-1].collect { |io_device| self.class.new(io_device) }
169
+ io_device = io_devices[0]
221
170
 
222
171
  super(io_device)
223
172
 
@@ -275,6 +224,11 @@ module Timber
275
224
  # This is required because of Rails' monkey patching on Logger via `::LoggerSilence`.
276
225
  def add(severity, message = nil, progname = nil, &block)
277
226
  return true if @logdev.nil? || (severity || UNKNOWN) < level
227
+
228
+ @extra_loggers.each do |logger|
229
+ logger.add(severity, message, progname, &block)
230
+ end
231
+
278
232
  super
279
233
  end
280
234
 
@@ -1,3 +1,3 @@
1
1
  module Timber
2
- VERSION = "2.1.4"
2
+ VERSION = "2.1.5"
3
3
  end
@@ -16,7 +16,8 @@ describe Timber::CLI::ConfigFile, :rails_23 => true do
16
16
  end
17
17
 
18
18
  describe ".logrageify!" do
19
- it "should set the option in the config file" do
19
+ it "should not set the option in the config file" do
20
+ allow(config_file).to receive(:log_rage?).and_return(true)
20
21
  config_file.logrageify!
21
22
  new_contents = initial_contents.gsub(contents_hook, "config.logrageify!\n\n#{contents_hook}")
22
23
  expect(config_file.send(:content)).to eq(new_contents)
@@ -40,18 +40,11 @@ describe Timber::CLI::Installers::ConfigFile, :rails_23 => true do
40
40
  expect(output.string).to eq("")
41
41
  end
42
42
 
43
- context "with a Lograge constant" do
44
- around(:each) do |example|
45
- Lograge = 1
46
- example.run
47
- Object.send(:remove_const, :Lograge)
48
- end
49
-
50
- it "should prompt for Lograge configuration and return true for y" do
51
- input.string = "y\n"
52
- expect(installer.send(:logrageify?)).to eq(true)
53
- expect(output.string).to eq("\n--------------------------------------------------------------------------------\n\nWe noticed you have lograge installed. Would you like to configure \nTimber to function similarly?\n(This silences template renders, sql queries, and controller calls.\nYou can always do this later in config/initialzers/timber.rb)\n\n\e[34my) Yes, configure Timber like lograge\e[0m\n\e[34mn) No, use the Rails logging defaults\e[0m\n\nEnter your choice: (y/n) ")
54
- end
43
+ it "should prompt for Lograge configuration and return true for y" do
44
+ allow(installer).to receive(:lograge?).and_return(true)
45
+ input.string = "y\n"
46
+ expect(installer.send(:logrageify?)).to eq(true)
47
+ expect(output.string).to eq("\n--------------------------------------------------------------------------------\n\nWe noticed you have lograge installed. Would you like to configure \nTimber to function similarly?\n(This silences template renders, sql queries, and controller calls.\nYou can always do this later in config/initialzers/timber.rb)\n\n\e[34my) Yes, configure Timber like lograge\e[0m\n\e[34mn) No, use the Rails logging defaults\e[0m\n\nEnter your choice: (y/n) ")
55
48
  end
56
49
  end
57
50
  end
@@ -21,7 +21,7 @@ describe Timber::Logger, :rails_23 => true do
21
21
  end
22
22
  end
23
23
 
24
- it "should use the Multi log device" do
24
+ it "should allow multiple loggers" do
25
25
  io1 = StringIO.new
26
26
  io2 = StringIO.new
27
27
  logger = Timber::Logger.new(STDOUT, io1, io2)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timber
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.4
4
+ version: 2.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Timber Technologies, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-16 00:00:00.000000000 Z
11
+ date: 2017-08-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -217,7 +217,6 @@ files:
217
217
  - lib/timber/log_devices/http.rb
218
218
  - lib/timber/log_devices/http/dropping_sized_queue.rb
219
219
  - lib/timber/log_devices/http/flushable_sized_queue.rb
220
- - lib/timber/log_devices/multi.rb
221
220
  - lib/timber/log_entry.rb
222
221
  - lib/timber/logger.rb
223
222
  - lib/timber/overrides.rb
@@ -1,34 +0,0 @@
1
- module Timber
2
- module LogDevices
3
- # @private
4
- #
5
- # A log device that writes to multiple IO devices.
6
- #
7
- # Note, you should not have to instantiate this class directly. Simply pass multiple
8
- # arguments to the `Timber::Logger#new` method.
9
- #
10
- # See the {Timber::Logger#new} for examples.
11
- class Multi
12
- def initialize(targets)
13
- @targets = targets
14
- end
15
-
16
- def write(*args)
17
- @targets.each { |t| t.write(*args) }
18
- @targets.first
19
- end
20
-
21
- def sync=(value)
22
- @targets.each do |t|
23
- if t.respond_to?(:sync=)
24
- t.sync = value
25
- end
26
- end
27
- end
28
-
29
- def close
30
- @targets.each(&:close)
31
- end
32
- end
33
- end
34
- end