Skip to content

Commit 5f62a26

Browse files
committed
Prevent telemetry crash from leaking exception
If an exception happens after telemetry has been sent but before returning from `main`'s `begin`..`end` block, two telemetry events may be emitted, which contradicts the "one start" => "one conclusion" design. Therefore: - tighten exception catching around injection in `main` - prevent telemetry from bubbling an exception up (we can't do anything in this case anyway)
1 parent ffc2287 commit 5f62a26

File tree

2 files changed

+30
-26
lines changed

2 files changed

+30
-26
lines changed

src/mod/main.rb

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,24 +47,24 @@
4747
begin
4848
# TODO: pass args, e.g context, location, etc...
4949
injected, err = injector.call
50-
51-
if err
52-
telemetry.emit([
53-
{ :name => 'library_entrypoint.error', :tags => ["reason:#{err}"] },
54-
])
55-
else
56-
log.info { 'inject:complete' }
57-
58-
telemetry.emit([
59-
{ :name => 'library_entrypoint.complete' },
60-
])
61-
end
6250
rescue StandardError => _e
6351
log.info { 'inject:error' }
6452

6553
telemetry.emit([
6654
{ :name => 'library_entrypoint.error', :tags => ["reason:exc.fatal"] },
6755
])
6856
end
57+
58+
if err
59+
telemetry.emit([
60+
{ :name => 'library_entrypoint.error', :tags => ["reason:#{err}"] },
61+
])
62+
else
63+
log.info { 'inject:complete' }
64+
65+
telemetry.emit([
66+
{ :name => 'library_entrypoint.complete' },
67+
])
68+
end
6969
end
7070
end

src/mod/telemetry.rb

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,33 @@ def payload(pid, version, points)
2424
private :payload
2525

2626
def emit(*args)
27-
opts = args.last.is_a?(Hash) ? args.pop : {}
28-
points = args.shift
27+
begin
28+
opts = args.last.is_a?(Hash) ? args.pop : {}
29+
points = args.shift
2930

30-
LOG.info { "telemetry:emit points:#{points.inspect}" }
31+
LOG.info { "telemetry:emit points:#{points.inspect}" }
3132

32-
pid = opts[:pid] || PROCESS.pid # TODO: emit from isolate
33-
version = opts[:version] || package_version
33+
pid = opts[:pid] || PROCESS.pid # TODO: emit from isolate
34+
version = opts[:version] || package_version
3435

35-
forwarder = ENV['DD_TELEMETRY_FORWARDER_PATH']
36+
forwarder = ENV['DD_TELEMETRY_FORWARDER_PATH']
3637

37-
return unless forwarder && !forwarder.empty?
38+
return unless forwarder && !forwarder.empty?
3839

39-
rd, wr = IO.pipe
40+
rd, wr = IO.pipe
4041

41-
pid = PROCESS.spawn(forwarder, 'library_entrypoint', { :in => rd, [:out, :err] => '/dev/null' })
42+
pid = PROCESS.spawn(forwarder, 'library_entrypoint', { :in => rd, [:out, :err] => '/dev/null' })
4243

43-
wr.write(payload(pid, version, points))
44-
wr.flush
45-
wr.close
44+
wr.write(payload(pid, version, points))
45+
wr.flush
46+
wr.close
4647

47-
cpid, status = Process.waitpid2(pid)
48+
cpid, status = Process.waitpid2(pid)
4849

49-
LOG.info { "telemetry:forwarder cpid:#{cpid} status:#{status}" }
50+
LOG.info { "telemetry:forwarder cpid:#{cpid} status:#{status}" }
51+
rescue StandardError => exc
52+
LOG.info { "telemetry:error exc:#{exc}" }
53+
end
5054
end
5155

5256
# TODO: extract to a package module

0 commit comments

Comments
 (0)