timber 2.0.24 → 2.1.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/CHANGELOG +3 -0
- data/README.md +314 -59
- data/bin/timber +11 -2
- data/lib/timber.rb +2 -7
- data/lib/timber/cli.rb +16 -28
- data/lib/timber/cli/api.rb +80 -14
- data/lib/timber/cli/api/application.rb +30 -0
- data/lib/timber/cli/config_file.rb +66 -0
- data/lib/timber/cli/file_helper.rb +43 -0
- data/lib/timber/cli/installer.rb +58 -0
- data/lib/timber/cli/installers.rb +37 -0
- data/lib/timber/cli/installers/other.rb +47 -0
- data/lib/timber/cli/installers/rails.rb +255 -0
- data/lib/timber/cli/installers/root.rb +189 -0
- data/lib/timber/cli/io.rb +97 -0
- data/lib/timber/cli/io/ansi.rb +22 -0
- data/lib/timber/cli/io/messages.rb +213 -0
- data/lib/timber/cli/os_helper.rb +53 -0
- data/lib/timber/config.rb +97 -43
- data/lib/timber/config/integrations.rb +63 -0
- data/lib/timber/config/integrations/rack.rb +74 -0
- data/lib/timber/context.rb +13 -10
- data/lib/timber/contexts.rb +1 -0
- data/lib/timber/contexts/custom.rb +16 -3
- data/lib/timber/contexts/http.rb +10 -3
- data/lib/timber/contexts/organization.rb +4 -0
- data/lib/timber/contexts/release.rb +46 -0
- data/lib/timber/contexts/runtime.rb +7 -1
- data/lib/timber/contexts/session.rb +8 -1
- data/lib/timber/contexts/system.rb +5 -1
- data/lib/timber/contexts/user.rb +9 -2
- data/lib/timber/current_context.rb +43 -11
- data/lib/timber/events/controller_call.rb +4 -0
- data/lib/timber/events/custom.rb +13 -5
- data/lib/timber/events/exception.rb +4 -0
- data/lib/timber/events/http_client_request.rb +4 -0
- data/lib/timber/events/http_client_response.rb +4 -0
- data/lib/timber/events/http_server_request.rb +5 -0
- data/lib/timber/events/http_server_response.rb +15 -3
- data/lib/timber/events/sql_query.rb +3 -0
- data/lib/timber/events/template_render.rb +3 -0
- data/lib/timber/integration.rb +40 -0
- data/lib/timber/integrations.rb +21 -14
- data/lib/timber/integrations/action_controller.rb +18 -0
- data/lib/timber/integrations/action_controller/log_subscriber.rb +2 -0
- data/lib/timber/integrations/action_controller/log_subscriber/timber_log_subscriber.rb +6 -0
- data/lib/timber/integrations/action_dispatch.rb +23 -0
- data/lib/timber/integrations/action_dispatch/debug_exceptions.rb +2 -0
- data/lib/timber/integrations/action_view.rb +18 -0
- data/lib/timber/integrations/action_view/log_subscriber.rb +2 -0
- data/lib/timber/integrations/action_view/log_subscriber/timber_log_subscriber.rb +10 -0
- data/lib/timber/integrations/active_record.rb +18 -0
- data/lib/timber/integrations/active_record/log_subscriber.rb +2 -0
- data/lib/timber/integrations/active_record/log_subscriber/timber_log_subscriber.rb +8 -0
- data/lib/timber/integrations/rack.rb +12 -2
- data/lib/timber/integrations/rack/exception_event.rb +38 -5
- data/lib/timber/integrations/rack/http_context.rb +4 -6
- data/lib/timber/integrations/rack/http_events.rb +177 -27
- data/lib/timber/integrations/rack/middleware.rb +28 -0
- data/lib/timber/integrations/rack/session_context.rb +5 -6
- data/lib/timber/integrations/rack/user_context.rb +90 -43
- data/lib/timber/integrations/rails.rb +22 -0
- data/lib/timber/integrations/rails/rack_logger.rb +2 -0
- data/lib/timber/integrator.rb +18 -3
- data/lib/timber/log_devices/http.rb +107 -99
- data/lib/timber/log_devices/http/dropping_sized_queue.rb +26 -0
- data/lib/timber/log_devices/http/flushable_sized_queue.rb +42 -0
- data/lib/timber/log_entry.rb +14 -2
- data/lib/timber/logger.rb +51 -36
- data/lib/timber/overrides.rb +2 -0
- data/lib/timber/overrides/active_support_3_tagged_logging.rb +103 -0
- data/lib/timber/overrides/active_support_tagged_logging.rb +53 -90
- data/lib/timber/timer.rb +21 -0
- data/lib/timber/util/hash.rb +1 -1
- data/lib/timber/util/http_event.rb +16 -3
- data/lib/timber/version.rb +1 -1
- data/spec/support/timber.rb +2 -3
- data/spec/timber/cli/installers/rails_spec.rb +160 -0
- data/spec/timber/cli/installers/root_spec.rb +100 -0
- data/spec/timber/config_spec.rb +28 -0
- data/spec/timber/current_context_spec.rb +61 -12
- data/spec/timber/events/custom_spec.rb +13 -2
- data/spec/timber/events/exception_spec.rb +15 -0
- data/spec/timber/events/http_server_request_spec.rb +3 -3
- data/spec/timber/integrations/rack/http_events_spec.rb +101 -0
- data/spec/timber/log_devices/http_spec.rb +20 -4
- data/spec/timber/log_entry_spec.rb +2 -1
- data/spec/timber/logger_spec.rb +8 -8
- metadata +40 -9
- data/benchmarks/rails.rb +0 -122
- data/lib/timber/cli/application.rb +0 -28
- data/lib/timber/cli/install.rb +0 -196
- data/lib/timber/cli/io_helper.rb +0 -65
- data/lib/timber/cli/messages.rb +0 -180
- data/lib/timber/integrations/active_support/tagged_logging.rb +0 -71
@@ -0,0 +1,63 @@
|
|
1
|
+
require "timber/config/integrations/rack"
|
2
|
+
require "timber/integrations/action_controller"
|
3
|
+
require "timber/integrations/action_view"
|
4
|
+
require "timber/integrations/active_record"
|
5
|
+
require "timber/integrations/rack"
|
6
|
+
|
7
|
+
module Timber
|
8
|
+
class Config
|
9
|
+
# Convenience module for accessing the various `Timber::Integrations::*` classes
|
10
|
+
# through the {Timber::Config} object. Timber couples configuration with the class
|
11
|
+
# responsibls for implementing it. This provides for a tighter design, but also
|
12
|
+
# requires the user to understand and access the various classes. This module aims
|
13
|
+
# to provide a simple ruby-like configuration interface for internal Timber classes.
|
14
|
+
#
|
15
|
+
# For example:
|
16
|
+
#
|
17
|
+
# config = Timber::Config.instance
|
18
|
+
# config.integrations.active_record.silence = true
|
19
|
+
module Integrations
|
20
|
+
extend self
|
21
|
+
|
22
|
+
# Convenience method for accessing the {Timber::Integrations::ActionController} class
|
23
|
+
# specific configuration.
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# config = Timber::Config.instance
|
27
|
+
# config.integrations.action_controller.silence = true
|
28
|
+
def action_controller
|
29
|
+
Timber::Integrations::ActionController
|
30
|
+
end
|
31
|
+
|
32
|
+
# Convenience method for accessing the {Timber::IIntegrations::ActionView} class
|
33
|
+
# specific configuration.
|
34
|
+
#
|
35
|
+
# @example
|
36
|
+
# config = Timber::Config.instance
|
37
|
+
# config.integrations.action_view.silence = true
|
38
|
+
def action_view
|
39
|
+
Timber::Integrations::ActionView
|
40
|
+
end
|
41
|
+
|
42
|
+
# Convenience method for accessing the {Timber::IIntegrations::ActiveRecord} class
|
43
|
+
# specific configuration.
|
44
|
+
#
|
45
|
+
# @example
|
46
|
+
# config = Timber::Config.instance
|
47
|
+
# config.integrations.active_record.silence = true
|
48
|
+
def active_record
|
49
|
+
Timber::Integrations::ActiveRecord
|
50
|
+
end
|
51
|
+
|
52
|
+
# Convenience method for accessing the various `Timber::IIntegrations::Rack::*`
|
53
|
+
# classes. See {Rack} for a list of methods available.
|
54
|
+
#
|
55
|
+
# @example
|
56
|
+
# config = Timber::Config.instance
|
57
|
+
# config.integrations.rack.http_events.enabled = true
|
58
|
+
def rack
|
59
|
+
Rack
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Timber
|
2
|
+
class Config
|
3
|
+
module Integrations
|
4
|
+
# Convenience module for accessing the various `Timber::Integrations::Rack::*` classes
|
5
|
+
# through the {Timber::Config} object. Timber couples configuration with the class
|
6
|
+
# responsibls for implementing it. This provides for a tighter design, but also
|
7
|
+
# requires the user to understand and access the various classes. This module aims
|
8
|
+
# to provide a simple ruby-like configuration interface for internal Timber classes.
|
9
|
+
#
|
10
|
+
# For example:
|
11
|
+
#
|
12
|
+
# config = Timber::Config.instance
|
13
|
+
# config.integrations.rack.http_events.enabled = false
|
14
|
+
module Rack
|
15
|
+
extend self
|
16
|
+
|
17
|
+
# Convenience method for accessing the {Timber::Integrations::Rack::ExceptionEvent}
|
18
|
+
# middleware class specific configuration. See {Timber::Integrations::Rack::ExceptionEvent}
|
19
|
+
# for a list of methods available.
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# config = Timber::Config.instance
|
23
|
+
# config.integrations.rack.exception_event.enabled = false
|
24
|
+
def exception_event
|
25
|
+
Timber::Integrations::Rack::ExceptionEvent
|
26
|
+
end
|
27
|
+
|
28
|
+
# Convenience method for accessing the {Timber::Integrations::Rack::HTTPContext}
|
29
|
+
# middleware class specific configuration. See {Timber::Integrations::Rack::HTTPContext}
|
30
|
+
# for a list of methods available.
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
# config = Timber::Config.instance
|
34
|
+
# config.integrations.rack.http_context.enabled = false
|
35
|
+
def http_context
|
36
|
+
Timber::Integrations::Rack::HTTPContext
|
37
|
+
end
|
38
|
+
|
39
|
+
# Convenience method for accessing the {Timber::Integrations::Rack::HTTPEvents}
|
40
|
+
# middleware class specific configuration. See {Timber::Integrations::Rack::HTTPEvents}
|
41
|
+
# for a list of methods available.
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
# config = Timber::Config.instance
|
45
|
+
# config.integrations.rack.http_events.enabled = false
|
46
|
+
def http_events
|
47
|
+
Timber::Integrations::Rack::HTTPEvents
|
48
|
+
end
|
49
|
+
|
50
|
+
# Convenience method for accessing the {Timber::Integrations::Rack::SessionContext}
|
51
|
+
# middleware class specific configuration. See {Timber::Integrations::Rack::SessionContext}
|
52
|
+
# for a list of methods available.
|
53
|
+
#
|
54
|
+
# @example
|
55
|
+
# config = Timber::Config.instance
|
56
|
+
# config.integrations.rack.session_context.enabled = false
|
57
|
+
def session_context
|
58
|
+
Timber::Integrations::Rack::SessionContext
|
59
|
+
end
|
60
|
+
|
61
|
+
# Convenience method for accessing the {Timber::Integrations::Rack::UserContext}
|
62
|
+
# middleware class specific configuration. See {Timber::Integrations::Rack::UserContext}
|
63
|
+
# for a list of methods available.
|
64
|
+
#
|
65
|
+
# @example
|
66
|
+
# config = Timber::Config.instance
|
67
|
+
# config.integrations.rack.user_context.enabled = false
|
68
|
+
def user_context
|
69
|
+
Timber::Integrations::Rack::UserContext
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/timber/context.rb
CHANGED
@@ -3,25 +3,28 @@ module Timber
|
|
3
3
|
# @private
|
4
4
|
class Context
|
5
5
|
class << self
|
6
|
+
# The keyspace is the key used when storing the context.
|
7
|
+
# For example:
|
8
|
+
#
|
9
|
+
# {:build => {:version => "1.0.0"}}
|
10
|
+
#
|
11
|
+
# The keyspace in the above context is `:build`. This is required
|
12
|
+
# because it prevents key name conflicts. Without the keyspace
|
13
|
+
# it very possible another context type might also have a `:version`
|
14
|
+
# attribute.
|
6
15
|
def keyspace
|
7
16
|
@keyspace || raise(NotImplementedError.new)
|
8
17
|
end
|
9
18
|
end
|
10
19
|
|
11
|
-
|
12
|
-
|
13
|
-
end
|
14
|
-
|
20
|
+
# Returns a simple structure sufficient for encoding. We use
|
21
|
+
# `as_json` as the name since this is a ruby pattern.
|
15
22
|
def as_json(options = {})
|
16
23
|
raise NotImplementedError.new
|
17
24
|
end
|
18
25
|
|
19
|
-
def
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
def to_msgpack(*args)
|
24
|
-
as_json.to_msgpack(*args)
|
26
|
+
def keyspace
|
27
|
+
self.class.keyspace
|
25
28
|
end
|
26
29
|
end
|
27
30
|
end
|
data/lib/timber/contexts.rb
CHANGED
@@ -1,10 +1,22 @@
|
|
1
|
+
require "timber/context"
|
2
|
+
require "timber/util"
|
3
|
+
|
1
4
|
module Timber
|
2
5
|
module Contexts
|
3
6
|
# Custom contexts allow you to add application specific context not covered elsewhere.
|
7
|
+
# Any data added this way will be included in your logs. A good example is worker job
|
8
|
+
# IDs. When processing a job you might add the job ID to the context, allowing you to
|
9
|
+
# view *all* logs generated while processing that job, not just the logs that contain
|
10
|
+
# the ID.
|
11
|
+
#
|
12
|
+
# Note in the example below all custom contexts must contain a root key. This is to
|
13
|
+
# ensure attribute names and types never clash across your contexts. It gives you
|
14
|
+
# much cleaner pallete to organize your data on.
|
4
15
|
#
|
5
|
-
# @example Adding a context
|
16
|
+
# @example Adding a custom context
|
6
17
|
# logger.with_context(build: {version: "1.0.0"}) do
|
7
|
-
# #
|
18
|
+
# # anything logged here will have the custom context above
|
19
|
+
# # when this block exits the context will no longer be included
|
8
20
|
# end
|
9
21
|
class Custom < Context
|
10
22
|
@keyspace = :custom
|
@@ -16,7 +28,8 @@ module Timber
|
|
16
28
|
@data = attributes[:data] || raise(ArgumentError.new(":data is required"))
|
17
29
|
end
|
18
30
|
|
19
|
-
|
31
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
32
|
+
def as_json(options = {})
|
20
33
|
{Timber::Util::Object.try(type, :to_sym) => data}
|
21
34
|
end
|
22
35
|
end
|
data/lib/timber/contexts/http.rb
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
+
require "timber/context"
|
2
|
+
|
1
3
|
module Timber
|
2
4
|
module Contexts
|
3
|
-
# The HTTP
|
4
|
-
#
|
5
|
-
#
|
5
|
+
# The HTTP context adds data about the current HTTP request being processed to your logs.
|
6
|
+
# This allows your to tail and filter by this data. A very useful piece of data this
|
7
|
+
# captures is the request ID. This gives you the ability to trace requests and view logs
|
8
|
+
# for a specific request only. For example, say you've searched your logs and found the
|
9
|
+
# specific line you are looking for, but it lacks context. With Timber you can simply
|
10
|
+
# click the request ID and "zoom out" to view all logs for that request. This gives you
|
11
|
+
# complete picture of how the log line in questio was generated.
|
6
12
|
#
|
7
13
|
# @note This context should be installed automatically through integrations,
|
8
14
|
# such as the {Intregrations::Rack::HTTPContext} rack middleware.
|
@@ -18,6 +24,7 @@ module Timber
|
|
18
24
|
@request_id = attributes[:request_id]
|
19
25
|
end
|
20
26
|
|
27
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
21
28
|
def as_json(_options = {})
|
22
29
|
{:method => method, :path => path, :remote_addr => remote_addr, :request_id => request_id}
|
23
30
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require "timber/context"
|
2
|
+
require "timber/util"
|
3
|
+
|
1
4
|
module Timber
|
2
5
|
module Contexts
|
3
6
|
# The organization context tracks the organization of the currently
|
@@ -25,6 +28,7 @@ module Timber
|
|
25
28
|
@name = attributes[:name]
|
26
29
|
end
|
27
30
|
|
31
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
28
32
|
def as_json(_options = {})
|
29
33
|
{id: Timber::Util::Object.try(id, :to_s), name: name}
|
30
34
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "timber/context"
|
2
|
+
require "timber/util"
|
3
|
+
|
4
|
+
module Timber
|
5
|
+
module Contexts
|
6
|
+
# The release context tracks application releases / versions / deploys.
|
7
|
+
# To automatically set this context, see {.from_env}.
|
8
|
+
class Release < Context
|
9
|
+
@keyspace = :release
|
10
|
+
|
11
|
+
class << self
|
12
|
+
# Builds a release context based on environment variables. Simply add the
|
13
|
+
# `RELEASE_COMMIT`, `RELEASE_CREATED_AT`, or the `RELEASE_VERSION` env vars
|
14
|
+
# to get this context automatially. All are optional, but at least one
|
15
|
+
# must be present.
|
16
|
+
#
|
17
|
+
# If you're on Heroku, simply enable dyno metadata to get this automatically:
|
18
|
+
# https://devcenter.heroku.com/articles/dyno-metadata
|
19
|
+
def from_env
|
20
|
+
commit_hash = ENV['RELEASE_COMMIT'] || ENV['HEROKU_SLUG_COMMIT']
|
21
|
+
created_at = ENV['RELEASE_CREATED_AT'] || ENV['HEROKU_RELEASE_CREATED_AT']
|
22
|
+
version = ENV['RELEASE_VERSION'] || ENV['HEROKU_RELEASE_VERSION']
|
23
|
+
|
24
|
+
if commit_hash || created_at || version
|
25
|
+
new(commit_hash: commit_hash, created_at: created_at, version: version)
|
26
|
+
else
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :commit_hash, :created_at, :version
|
33
|
+
|
34
|
+
def initialize(attributes)
|
35
|
+
@commit_hash = attributes[:commit_hash]
|
36
|
+
@created_at = attributes[:created_at]
|
37
|
+
@version = attributes[:version]
|
38
|
+
end
|
39
|
+
|
40
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
41
|
+
def as_json(_options = {})
|
42
|
+
{commit_hash: commit_hash, created_at: created_at, version: version}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -1,6 +1,11 @@
|
|
1
|
+
require "timber/context"
|
2
|
+
|
1
3
|
module Timber
|
2
4
|
module Contexts
|
3
|
-
#
|
5
|
+
# The runtime context adds current runtime data to your logs, such as the file, line number,
|
6
|
+
# class or module name, etc. This makes it easy to tail and search your logs by their
|
7
|
+
# origin in your code. For example, if you are debugging a specific class, you can narrow
|
8
|
+
# by that class and see only it's logs.
|
4
9
|
class Runtime < Context
|
5
10
|
@keyspace = :runtime
|
6
11
|
|
@@ -15,6 +20,7 @@ module Timber
|
|
15
20
|
@module_name = attributes[:module_name]
|
16
21
|
end
|
17
22
|
|
23
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
18
24
|
def as_json(_options = {})
|
19
25
|
{application: application, class_name: class_name, file: file, function: function,
|
20
26
|
line: line, module_name: module_name}
|
@@ -1,6 +1,12 @@
|
|
1
|
+
require "timber/context"
|
2
|
+
require "timber/util"
|
3
|
+
|
1
4
|
module Timber
|
2
5
|
module Contexts
|
3
|
-
# The session context
|
6
|
+
# The session context adds the current session ID to your logs. This allows your
|
7
|
+
# to tail and filter logs by specific session IDs. Moreover, it gives you a unique
|
8
|
+
# identifier to report on user activity by session. This way your logs can tell the
|
9
|
+
# story of how many time a user has engaged your site.
|
4
10
|
#
|
5
11
|
# @note This is tracked automatically with the {Integrations::Rack::SessionContext} rack
|
6
12
|
# middleware.
|
@@ -13,6 +19,7 @@ module Timber
|
|
13
19
|
@id = attributes[:id] || raise(ArgumentError.new(":id is required"))
|
14
20
|
end
|
15
21
|
|
22
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
16
23
|
def as_json(_options = {})
|
17
24
|
{id: Timber::Util::Object.try(id, :to_s)}
|
18
25
|
end
|
@@ -1,6 +1,9 @@
|
|
1
|
+
require "timber/context"
|
2
|
+
require "timber/util"
|
3
|
+
|
1
4
|
module Timber
|
2
5
|
module Contexts
|
3
|
-
#
|
6
|
+
# The system context tracks OS level process information, such as the process ID.
|
4
7
|
class System < Context
|
5
8
|
@keyspace = :system
|
6
9
|
|
@@ -12,6 +15,7 @@ module Timber
|
|
12
15
|
@pid = @pid.to_s
|
13
16
|
end
|
14
17
|
|
18
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
15
19
|
def as_json(_options = {})
|
16
20
|
{hostname: hostname, pid: Timber::Util::Object.try(pid, :to_s)}
|
17
21
|
end
|
data/lib/timber/contexts/user.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
+
require "timber/context"
|
2
|
+
require "timber/util"
|
3
|
+
|
1
4
|
module Timber
|
2
5
|
module Contexts
|
3
|
-
# The user context
|
6
|
+
# The user context adds data about the currently authenticated user to your logs.
|
7
|
+
# By adding this context all of your logs will contain user information. This allows
|
8
|
+
# filter and tail logs by specific users.
|
4
9
|
#
|
5
10
|
# @note This is tracked automatically with the {Integrations::Rack::UserContext} rack
|
6
|
-
# middleware.
|
11
|
+
# middleware for supported authentication frameworks. See {Integrations::Rack::UserContext}
|
12
|
+
# for more details.
|
7
13
|
class User < Context
|
8
14
|
@keyspace = :user
|
9
15
|
|
@@ -15,6 +21,7 @@ module Timber
|
|
15
21
|
@email = attributes[:email]
|
16
22
|
end
|
17
23
|
|
24
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
18
25
|
def as_json(_options = {})
|
19
26
|
{id: Timber::Util::Object.try(id, :to_s), name: name, email: email}
|
20
27
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require "singleton"
|
2
2
|
|
3
|
+
require "timber/contexts/release"
|
4
|
+
|
3
5
|
module Timber
|
4
6
|
# Holds the current context in a thread safe memory storage. This context is
|
5
7
|
# appended to every log line. Think of context as join data between your log lines,
|
@@ -13,30 +15,43 @@ module Timber
|
|
13
15
|
THREAD_NAMESPACE = :_timber_current_context.freeze
|
14
16
|
|
15
17
|
class << self
|
16
|
-
# Convenience method for {#with}. See {#with} for
|
18
|
+
# Convenience method for {CurrentContext#with}. See {CurrentContext#with} for more info.
|
17
19
|
def with(*args, &block)
|
18
20
|
instance.with(*args, &block)
|
19
21
|
end
|
20
22
|
|
21
|
-
# Convenience method for {#add}. See {#add} for
|
23
|
+
# Convenience method for {CurrentContext#add}. See {CurrentContext#add} for more info.
|
22
24
|
def add(*args)
|
23
25
|
instance.add(*args)
|
24
26
|
end
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
+
# Convenience method for {CurrentContext#fetch}. See {CurrentContext#fetch} for more info.
|
29
|
+
def fetch(*args)
|
30
|
+
instance.fetch(*args)
|
28
31
|
end
|
29
32
|
|
30
|
-
# Convenience method for {#remove}. See {#remove} for
|
33
|
+
# Convenience method for {CurrentContext#remove}. See {CurrentContext#remove} for more info.
|
31
34
|
def remove(*args)
|
32
35
|
instance.remove(*args)
|
33
36
|
end
|
34
37
|
|
38
|
+
# Convenience method for {CurrentContext#reset}. See {CurrentContext#reset} for more info.
|
35
39
|
def reset(*args)
|
36
40
|
instance.reset(*args)
|
37
41
|
end
|
38
42
|
end
|
39
43
|
|
44
|
+
# Instantiates a new object, automatically adding context based on env variables (if present).
|
45
|
+
# For example, the {Contexts::ReleaseContext} is automatically added if the proper environment
|
46
|
+
# variables are present. Please see that class for more details.
|
47
|
+
def initialize
|
48
|
+
super
|
49
|
+
release_context = Contexts::Release.from_env
|
50
|
+
if release_context
|
51
|
+
add(release_context)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
40
55
|
# Adds a context and then removes it when the block is finished executing.
|
41
56
|
#
|
42
57
|
# @note Because context is included with every log line, it is recommended that you limit this
|
@@ -85,12 +100,13 @@ module Timber
|
|
85
100
|
hash[key] = json
|
86
101
|
end
|
87
102
|
end
|
103
|
+
expire_cache!
|
104
|
+
self
|
88
105
|
end
|
89
106
|
|
90
|
-
#
|
91
|
-
|
92
|
-
|
93
|
-
Thread.current[THREAD_NAMESPACE] ||= {}
|
107
|
+
# Fetch a specific context by key.
|
108
|
+
def fetch(*args)
|
109
|
+
hash.fetch(*args)
|
94
110
|
end
|
95
111
|
|
96
112
|
# Removes a context. If you wish to remove by key, or some other way, use {#hash} and
|
@@ -113,18 +129,34 @@ module Timber
|
|
113
129
|
end
|
114
130
|
end
|
115
131
|
end
|
132
|
+
expire_cache!
|
133
|
+
self
|
116
134
|
end
|
117
135
|
|
118
136
|
# Resets the context to be blank. Use this carefully! This will remove *any* context,
|
119
137
|
# include context that is automatically included with Timber.
|
120
138
|
def reset
|
121
139
|
hash.clear
|
140
|
+
expire_cache!
|
141
|
+
self
|
122
142
|
end
|
123
143
|
|
124
144
|
# Snapshots the current context so that you get a moment in time representation of the context,
|
125
|
-
# since the context can change as execution proceeds.
|
145
|
+
# since the context can change as execution proceeds. Note that individual contexts
|
146
|
+
# should be immutable, and we implement snapshot caching as a result of this assumption.
|
126
147
|
def snapshot
|
127
|
-
hash.clone
|
148
|
+
@snapshot ||= hash.clone
|
128
149
|
end
|
150
|
+
|
151
|
+
private
|
152
|
+
# The internal hash that is maintained. Use {#with} and {#add} for hash maintenance.
|
153
|
+
def hash
|
154
|
+
Thread.current[THREAD_NAMESPACE] ||= {}
|
155
|
+
end
|
156
|
+
|
157
|
+
# Hook to clear any caching implement in this class
|
158
|
+
def expire_cache!
|
159
|
+
@snapshot = nil
|
160
|
+
end
|
129
161
|
end
|
130
162
|
end
|