logtail 0.1.0 → 0.1.1
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 +4 -4
- data/Rakefile +2 -2
- data/lib/logtail/log_devices/http.rb +7 -7
- data/lib/logtail/log_entry.rb +36 -1
- data/lib/logtail/logger.rb +2 -2
- data/lib/logtail/version.rb +1 -1
- data/spec/logtail/log_devices/http_spec.rb +2 -2
- data/spec/logtail/log_entry_spec.rb +14 -0
- data/spec/logtail/logger_spec.rb +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5a701070a19f4a33ac78a22d48f7eb3f9c2a6f794bf1e1abcc95a535d29fc9c0
|
|
4
|
+
data.tar.gz: fc2ed9e71f8d4b6c43ec5b18d2f28b55e4bc05163da236fda364081147b6fd8b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bc08401deaf074e084929ac7964a90680adc463077466ba95b170022f4b30438c339d5fb8ea47e468ffbb94b9be34e2da13270bc829d59148ae208be4d4f2092
|
|
7
|
+
data.tar.gz: a1d1518ce6c835031eb6c01b945df19d7fec6626905aa4c49c830d73619bd617f1452d6fe3596ae28a90ac0bc46b8f33bad4d7437f1f912323a0997495d115d9
|
data/Rakefile
CHANGED
|
@@ -14,7 +14,7 @@ def puts_with_level(message, level = :info)
|
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
task :test_the_pipes, [:
|
|
17
|
+
task :test_the_pipes, [:source_token] do |t, args|
|
|
18
18
|
support_email = "support@logtail.com"
|
|
19
19
|
# Do not modify below this line. It's important to keep the `Logtail::Logger`
|
|
20
20
|
# because it provides an API for logging structured data and capturing context.
|
|
@@ -26,7 +26,7 @@ task :test_the_pipes, [:api_key] do |t, args|
|
|
|
26
26
|
|
|
27
27
|
current_context = Logtail::CurrentContext.instance.snapshot
|
|
28
28
|
entry = Logtail::LogEntry.new(:info, Time.now, nil, "Testing the pipes (click the inspect icon to view more details)", current_context, nil)
|
|
29
|
-
http_device = Logtail::LogDevices::HTTP.new(args.
|
|
29
|
+
http_device = Logtail::LogDevices::HTTP.new(args.source_token, flush_continuously: false)
|
|
30
30
|
response = http_device.deliver_one(entry)
|
|
31
31
|
if response.is_a?(Exception)
|
|
32
32
|
message = <<~HEREDOC
|
|
@@ -36,7 +36,7 @@ module Logtail
|
|
|
36
36
|
# you can drop the log messages instead by passing a {DroppingSizedQueue} via the
|
|
37
37
|
# `:request_queue` option.
|
|
38
38
|
#
|
|
39
|
-
# @param
|
|
39
|
+
# @param source_token [String] The API key provided to you after you add your application to
|
|
40
40
|
# [Logtail](https://logtail.com).
|
|
41
41
|
# @param [Hash] options the options to create a HTTP log device with.
|
|
42
42
|
# @option attributes [Symbol] :batch_size (1000) Determines the maximum of log lines in
|
|
@@ -64,13 +64,13 @@ module Logtail
|
|
|
64
64
|
# The default is set via {LOGTAIL_HOST}.
|
|
65
65
|
#
|
|
66
66
|
# @example Basic usage
|
|
67
|
-
# Logtail::Logger.new(Logtail::LogDevices::HTTP.new("
|
|
67
|
+
# Logtail::Logger.new(Logtail::LogDevices::HTTP.new("my_logtail_source_token"))
|
|
68
68
|
#
|
|
69
69
|
# @example Apply back pressure instead of dropping messages
|
|
70
|
-
# http_log_device = Logtail::LogDevices::HTTP.new("
|
|
70
|
+
# http_log_device = Logtail::LogDevices::HTTP.new("my_logtail_source_token", request_queue: SizedQueue.new(25))
|
|
71
71
|
# Logtail::Logger.new(http_log_device)
|
|
72
|
-
def initialize(
|
|
73
|
-
@
|
|
72
|
+
def initialize(source_token, options = {})
|
|
73
|
+
@source_token = source_token || raise(ArgumentError.new("The source_token parameter cannot be blank"))
|
|
74
74
|
@logtail_host = options[:logtail_host] || ENV['LOGTAIL_HOST'] || LOGTAIL_HOST
|
|
75
75
|
@logtail_port = options[:logtail_port] || ENV['LOGTAIL_PORT'] || LOGTAIL_PORT
|
|
76
76
|
@logtail_scheme = options[:logtail_scheme] || ENV['LOGTAIL_SCHEME'] || LOGTAIL_SCHEME
|
|
@@ -168,7 +168,7 @@ MESSAGE
|
|
|
168
168
|
end
|
|
169
169
|
|
|
170
170
|
raise <<-MESSAGE
|
|
171
|
-
|
|
171
|
+
|
|
172
172
|
Log delivery failed! No request was made.
|
|
173
173
|
|
|
174
174
|
You can enable internal debug logging with the following:
|
|
@@ -361,7 +361,7 @@ MESSAGE
|
|
|
361
361
|
|
|
362
362
|
# Builds the `Authorization` header value for HTTP delivery to the Logtail API.
|
|
363
363
|
def authorization_payload
|
|
364
|
-
"Bearer #{@
|
|
364
|
+
"Bearer #{@source_token}"
|
|
365
365
|
end
|
|
366
366
|
end
|
|
367
367
|
end
|
data/lib/logtail/log_entry.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require "socket"
|
|
2
2
|
require "time"
|
|
3
|
+
require "pathname"
|
|
3
4
|
|
|
4
5
|
require "logtail/contexts"
|
|
5
6
|
require "logtail/events"
|
|
@@ -11,6 +12,7 @@ module Logtail
|
|
|
11
12
|
BINARY_LIMIT_THRESHOLD = 1_000.freeze
|
|
12
13
|
DT_PRECISION = 6.freeze
|
|
13
14
|
MESSAGE_MAX_BYTES = 8192.freeze
|
|
15
|
+
LOGTAIL_GEM_REGEX = /\/logtail(?:-ruby|-rails|-rack)?(?:-\d+(?:\.\d+)*)?\/lib$/.freeze
|
|
14
16
|
|
|
15
17
|
attr_reader :context_snapshot, :event, :level, :message, :progname, :tags, :time
|
|
16
18
|
|
|
@@ -45,7 +47,7 @@ module Logtail
|
|
|
45
47
|
hash = {
|
|
46
48
|
:level => level,
|
|
47
49
|
:dt => formatted_dt,
|
|
48
|
-
:message => message
|
|
50
|
+
:message => message,
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
if !tags.nil? && tags.length > 0
|
|
@@ -60,6 +62,10 @@ module Logtail
|
|
|
60
62
|
hash[:context] = context_snapshot
|
|
61
63
|
end
|
|
62
64
|
|
|
65
|
+
hash[:context] ||= {}
|
|
66
|
+
hash[:context][:runtime] ||= {}
|
|
67
|
+
hash[:context][:runtime].merge!(current_runtime_context || {})
|
|
68
|
+
|
|
63
69
|
if options[:only]
|
|
64
70
|
hash.select do |key, _value|
|
|
65
71
|
options[:only].include?(key)
|
|
@@ -106,5 +112,34 @@ module Logtail
|
|
|
106
112
|
rescue Exception
|
|
107
113
|
nil
|
|
108
114
|
end
|
|
115
|
+
|
|
116
|
+
def current_runtime_context
|
|
117
|
+
index = caller_locations.rindex { |x| logtail_frame?(x) }
|
|
118
|
+
frame = caller_locations[index + 1] unless index.nil?
|
|
119
|
+
return convert_to_runtime_context(frame) unless frame.nil?
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def convert_to_runtime_context(frame)
|
|
123
|
+
{
|
|
124
|
+
file: relative_to_main_module(frame.absolute_path),
|
|
125
|
+
line: frame.lineno,
|
|
126
|
+
frame_label: frame.label,
|
|
127
|
+
}
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def logtail_frame?(frame)
|
|
131
|
+
return false if frame.absolute_path.nil? || logtail_gem_paths.empty?
|
|
132
|
+
logtail_gem_paths.any? { |path| frame.absolute_path.start_with?(path) }
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def logtail_gem_paths
|
|
136
|
+
@logtail_gem_paths ||= $LOAD_PATH.select { |path| path.match(LOGTAIL_GEM_REGEX) }
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def relative_to_main_module(path)
|
|
140
|
+
base_file = caller_locations.last.absolute_path
|
|
141
|
+
base_path = Pathname.new(File.dirname(base_file || '/'))
|
|
142
|
+
Pathname.new(path).relative_path_from(base_path).to_s
|
|
143
|
+
end
|
|
109
144
|
end
|
|
110
145
|
end
|
data/lib/logtail/logger.rb
CHANGED
|
@@ -135,7 +135,7 @@ module Logtail
|
|
|
135
135
|
# logger = Logtail::Logger.new(STDOUT)
|
|
136
136
|
#
|
|
137
137
|
# @example Logging to the Logtail HTTP device
|
|
138
|
-
# http_device = Logtail::LogDevices::HTTP.new("my-logtail-
|
|
138
|
+
# http_device = Logtail::LogDevices::HTTP.new("my-logtail-source-token")
|
|
139
139
|
# logger = Logtail::Logger.new(http_device)
|
|
140
140
|
#
|
|
141
141
|
# @example Logging to a file (with rotation)
|
|
@@ -143,7 +143,7 @@ module Logtail
|
|
|
143
143
|
# logger = Logtail::Logger.new(file_device)
|
|
144
144
|
#
|
|
145
145
|
# @example Logging to a file and the Logtail HTTP device (multiple log devices)
|
|
146
|
-
# http_device = Logtail::LogDevices::HTTP.new("my-logtail-
|
|
146
|
+
# http_device = Logtail::LogDevices::HTTP.new("my-logtail-source-token")
|
|
147
147
|
# file_logger = ::Logger.new("path/to/file.log")
|
|
148
148
|
# logger = Logtail::Logger.new(http_device, file_logger)
|
|
149
149
|
def initialize(*io_devices_and_loggers)
|
data/lib/logtail/version.rb
CHANGED
|
@@ -102,7 +102,7 @@ describe Logtail::LogDevices::HTTP do
|
|
|
102
102
|
request_queue = http.instance_variable_get(:@request_queue)
|
|
103
103
|
request_attempt = request_queue.deq
|
|
104
104
|
expect(request_attempt.request).to be_kind_of(Net::HTTP::Post)
|
|
105
|
-
expect(request_attempt.request.body).to start_with("\x92\
|
|
105
|
+
expect(request_attempt.request.body).to start_with("\x92\x84\xA5level\xA4INFO\xA2dt\xBB2016-09-01T12:00:00.000000Z\xA7message\xB2test log message 1".force_encoding("ASCII-8BIT"))
|
|
106
106
|
|
|
107
107
|
message_queue = http.instance_variable_get(:@msg_queue)
|
|
108
108
|
expect(message_queue.size).to eq(0)
|
|
@@ -127,7 +127,7 @@ describe Logtail::LogDevices::HTTP do
|
|
|
127
127
|
it "should deliver requests on an interval" do
|
|
128
128
|
stub = stub_request(:post, "https://in.logtail.com/").
|
|
129
129
|
with(
|
|
130
|
-
:body => start_with("\x92\
|
|
130
|
+
:body => start_with("\x92\x84\xA5level\xA4INFO\xA2dt\xBB2016-09-01T12:00:00.000000Z\xA7message\xB2test log message 1".force_encoding("ASCII-8BIT")),
|
|
131
131
|
:headers => {
|
|
132
132
|
'Authorization' => 'Bearer MYKEY',
|
|
133
133
|
'Content-Type' => 'application/msgpack',
|
|
@@ -19,4 +19,18 @@ describe Logtail::LogEntry do
|
|
|
19
19
|
expect(msgpack).to start_with("\x85\xA5level\xA4INFO\xA2dt\xBB2016-09-01T12:00:00.000000Z".force_encoding("ASCII-8BIT"))
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
|
+
|
|
23
|
+
describe "#to_hash" do
|
|
24
|
+
it "should include runtime context information" do
|
|
25
|
+
$:.unshift(File.expand_path(__dir__ + '/../../lib'))
|
|
26
|
+
|
|
27
|
+
log_entry = described_class.new("INFO", time, nil, "log message", {}, {})
|
|
28
|
+
hash = log_entry.to_hash
|
|
29
|
+
expect(hash[:context]).to_not be_nil
|
|
30
|
+
expect(hash[:context][:runtime]).to_not be_nil
|
|
31
|
+
expect(hash[:context][:runtime][:file]).to_not be_nil
|
|
32
|
+
expect(hash[:context][:runtime][:line]).to_not be_nil
|
|
33
|
+
expect(hash[:context][:runtime][:frame_label]).to_not be_nil
|
|
34
|
+
end
|
|
35
|
+
end
|
|
22
36
|
end
|
data/spec/logtail/logger_spec.rb
CHANGED
|
@@ -161,7 +161,7 @@ describe Logtail::Logger do
|
|
|
161
161
|
end
|
|
162
162
|
|
|
163
163
|
context "with the HTTP log device" do
|
|
164
|
-
let(:io) { Logtail::LogDevices::HTTP.new("
|
|
164
|
+
let(:io) { Logtail::LogDevices::HTTP.new("my_source_token") }
|
|
165
165
|
|
|
166
166
|
it "should use the PassThroughFormatter" do
|
|
167
167
|
expect(logger.formatter).to be_kind_of(Logtail::Logger::PassThroughFormatter)
|
|
@@ -189,7 +189,7 @@ describe Logtail::Logger do
|
|
|
189
189
|
|
|
190
190
|
describe "#formatter=" do
|
|
191
191
|
it "should not allow changing the formatter when the device is HTTP" do
|
|
192
|
-
http_device = Logtail::LogDevices::HTTP.new("
|
|
192
|
+
http_device = Logtail::LogDevices::HTTP.new("source_token")
|
|
193
193
|
logger = Logtail::Logger.new(http_device)
|
|
194
194
|
expect { logger.formatter = ::Logger::Formatter.new }.to raise_error(ArgumentError)
|
|
195
195
|
end
|