Skip to content

Commit 10bfec2

Browse files
simonrozsivalgyfis
andauthored
Add runtime context to log events (#3)
* ✨ Add file, line, and frame label to runtime context * 💚 Fix existing tests * ✅ Add test for runtime context * 💄 * 🚧 * 👀 * 👀 * 👀 * 👀 * 👀 * 💚 * 💚 * 🚧 Improve gem installation path detection * 🚧 Account for older ruby versions * 🚧 Detect all logtail gems * 🚧 Change the regex * ✅ Update tests * Update lib/logtail/log_entry.rb Co-authored-by: Tomáš Hromada <[email protected]> * Revert "Update lib/logtail/log_entry.rb" This reverts commit 636f93c. Co-authored-by: Tomáš Hromada <[email protected]>
1 parent 7188401 commit 10bfec2

File tree

3 files changed

+52
-3
lines changed

3 files changed

+52
-3
lines changed

lib/logtail/log_entry.rb

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
require "socket"
22
require "time"
3+
require "pathname"
34

45
require "logtail/contexts"
56
require "logtail/events"
@@ -11,6 +12,7 @@ class LogEntry #:nodoc:
1112
BINARY_LIMIT_THRESHOLD = 1_000.freeze
1213
DT_PRECISION = 6.freeze
1314
MESSAGE_MAX_BYTES = 8192.freeze
15+
LOGTAIL_GEM_REGEX = /\/logtail(?:-ruby|-rails|-rack)?(?:-\d+(?:\.\d+)*)?\/lib$/.freeze
1416

1517
attr_reader :context_snapshot, :event, :level, :message, :progname, :tags, :time
1618

@@ -45,7 +47,7 @@ def to_hash(options = {})
4547
hash = {
4648
:level => level,
4749
:dt => formatted_dt,
48-
:message => message
50+
:message => message,
4951
}
5052

5153
if !tags.nil? && tags.length > 0
@@ -60,6 +62,10 @@ def to_hash(options = {})
6062
hash[:context] = context_snapshot
6163
end
6264

65+
hash[:context] ||= {}
66+
hash[:context][:runtime] ||= {}
67+
hash[:context][:runtime].merge!(current_runtime_context || {})
68+
6369
if options[:only]
6470
hash.select do |key, _value|
6571
options[:only].include?(key)
@@ -106,5 +112,34 @@ def encode_string(string)
106112
rescue Exception
107113
nil
108114
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
109144
end
110145
end

spec/logtail/log_devices/http_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
request_queue = http.instance_variable_get(:@request_queue)
103103
request_attempt = request_queue.deq
104104
expect(request_attempt.request).to be_kind_of(Net::HTTP::Post)
105-
expect(request_attempt.request.body).to start_with("\x92\x83\xA5level\xA4INFO\xA2dt\xBB2016-09-01T12:00:00.000000Z\xA7message\xB2test log message 1".force_encoding("ASCII-8BIT"))
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"))
106106

107107
message_queue = http.instance_variable_get(:@msg_queue)
108108
expect(message_queue.size).to eq(0)
@@ -127,7 +127,7 @@
127127
it "should deliver requests on an interval" do
128128
stub = stub_request(:post, "https://in.logtail.com/").
129129
with(
130-
:body => start_with("\x92\x83\xA5level\xA4INFO\xA2dt\xBB2016-09-01T12:00:00.000000Z\xA7message\xB2test log message 1".force_encoding("ASCII-8BIT")),
130+
:body => start_with("\x92\x84\xA5level\xA4INFO\xA2dt\xBB2016-09-01T12:00:00.000000Z\xA7message\xB2test log message 1".force_encoding("ASCII-8BIT")),
131131
:headers => {
132132
'Authorization' => 'Bearer MYKEY',
133133
'Content-Type' => 'application/msgpack',

spec/logtail/log_entry_spec.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,18 @@
1919
expect(msgpack).to start_with("\x85\xA5level\xA4INFO\xA2dt\xBB2016-09-01T12:00:00.000000Z".force_encoding("ASCII-8BIT"))
2020
end
2121
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
2236
end

0 commit comments

Comments
 (0)