Skip to content

Commit 461a627

Browse files
authored
Rename Runtime to Environment (#1570)
1 parent e0206ae commit 461a627

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+533
-501
lines changed

.rubocop_todo.yml

-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ Lint/MissingCopEnableDirective:
7979
- 'spec/ddtrace/contrib/rails/support/database.rb'
8080
- 'spec/ddtrace/contrib/rails/support/middleware.rb'
8181
- 'spec/ddtrace/diagnostics/health_spec.rb'
82-
- 'spec/ddtrace/runtime/cgroup_spec.rb'
8382
- 'spec/support/container_helpers.rb'
8483
- 'spec/support/tracer_helpers.rb'
8584
- 'test/contrib/rails/controller_test.rb'

integration/images/include/datadog/demo_env.rb

+15-14
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
module Datadog
2+
# Helpers to read the application environment
23
module DemoEnv
34
module_function
45

56
def gem_spec(gem_name, defaults = {})
6-
args = if local_gem(gem_name)
7-
[local_gem(gem_name)]
8-
elsif git_gem(gem_name)
9-
[git_gem(gem_name)]
10-
else
11-
[]
12-
end
7+
args = if local_gem(gem_name)
8+
[local_gem(gem_name)]
9+
elsif git_gem(gem_name)
10+
[git_gem(gem_name)]
11+
else
12+
[]
13+
end
1314

1415
yield(args) if block_given?
1516

1617
args
1718
end
1819

1920
def gem_env_name(gem_name)
20-
gem_name.upcase.gsub('-', '_')
21+
gem_name.upcase.tr('-', '_')
2122
end
2223

2324
def local_gem(gem_name)
@@ -55,11 +56,11 @@ def print_env(header = 'Datadog test environment')
5556
puts "Features: #{features}"
5657
puts "Rails env: #{ENV['RAILS_ENV']}" if ENV['RAILS_ENV']
5758
puts "PID: #{Process.pid}"
58-
if ddtrace = Gem.loaded_specs['ddtrace']
59-
puts "Runtime ID: #{Datadog::Runtime::Identity.id}" if defined?(Datadog::Runtime::Identity)
59+
if (ddtrace = Gem.loaded_specs['ddtrace'])
60+
puts "Runtime ID: #{Datadog::Core::Environment::Identity.id}" if defined?(Datadog::Core::Environment::Identity)
6061
puts "ddtrace version: #{ddtrace.version}"
6162
puts "ddtrace path: #{ddtrace.full_gem_path}"
62-
if git_spec = git_gem('ddtrace')
63+
if (git_spec = git_gem('ddtrace'))
6364
puts "ddtrace git: #{git_spec[:git]}"
6465
puts "ddtrace ref: #{git_spec[:ref]}"
6566
end
@@ -69,10 +70,10 @@ def print_env(header = 'Datadog test environment')
6970

7071
def profiler_file_transport(dump_path = "/data/profile-pid-#{Process.pid}.pprof")
7172
Datadog::Profiling::Transport::IO.default(
72-
write: ->(out, data) do
73+
write: lambda do |_out, data|
7374
result = nil
7475
puts "Writing pprof #{dump_path}..."
75-
File.open(dump_path, "w") { |f| result = f.write(data) }
76+
File.open(dump_path, 'w') { |f| result = f.write(data) }
7677
puts "Pprof #{dump_path} written!"
7778
result
7879
end
@@ -86,7 +87,7 @@ def start_mem_dump!
8687

8788
def finish_mem_dump!(dump_path = "/data/mem-pid-#{Process.pid}.dump")
8889
File.delete(dump_path) if File.exist?(dump_path)
89-
File.open(dump_path, "w") do |io|
90+
File.open(dump_path, 'w') do |io|
9091
ObjectSpace.dump_all(output: io)
9192
end
9293
end
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
require 'datadog/core/environment/ext'
2+
3+
module Datadog
4+
module Core
5+
module Environment
6+
# Reads information from Linux cgroups.
7+
# This information is used to extract information
8+
# about the current Linux container identity.
9+
# @see https://man7.org/linux/man-pages/man7/cgroups.7.html
10+
module Cgroup
11+
LINE_REGEX = /^(\d+):([^:]*):(.+)$/.freeze
12+
13+
Descriptor = Struct.new(
14+
:id,
15+
:groups,
16+
:path,
17+
:controllers
18+
)
19+
20+
module_function
21+
22+
def descriptors(process = 'self')
23+
[].tap do |descriptors|
24+
begin
25+
filepath = "/proc/#{process}/cgroup"
26+
27+
if File.exist?(filepath)
28+
File.foreach("/proc/#{process}/cgroup") do |line|
29+
line = line.strip
30+
descriptors << parse(line) unless line.empty?
31+
end
32+
end
33+
rescue StandardError => e
34+
Datadog.logger.error("Error while parsing cgroup. Cause: #{e.message} Location: #{e.backtrace.first}")
35+
end
36+
end
37+
end
38+
39+
def parse(line)
40+
id, groups, path = line.scan(LINE_REGEX).first
41+
42+
Descriptor.new(id, groups, path).tap do |descriptor|
43+
descriptor.controllers = groups.split(',') unless groups.nil?
44+
end
45+
end
46+
end
47+
end
48+
end
49+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module Datadog
2+
module Core
3+
module Environment
4+
# Retrieves number of classes from runtime
5+
module ClassCount
6+
module_function
7+
8+
def value
9+
::ObjectSpace.count_objects[:T_CLASS]
10+
end
11+
12+
def available?
13+
::ObjectSpace.respond_to?(:count_objects) \
14+
&& ::ObjectSpace.count_objects.key?(:T_CLASS)
15+
end
16+
end
17+
end
18+
end
19+
end
+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
require 'datadog/core/environment/cgroup'
2+
3+
module Datadog
4+
module Core
5+
module Environment
6+
# For container environments
7+
module Container
8+
UUID_PATTERN = '[0-9a-f]{8}[-_]?[0-9a-f]{4}[-_]?[0-9a-f]{4}[-_]?[0-9a-f]{4}[-_]?[0-9a-f]{12}'.freeze
9+
CONTAINER_PATTERN = '[0-9a-f]{64}'.freeze
10+
11+
PLATFORM_REGEX = /(?<platform>.*?)(?:.slice)?$/.freeze
12+
POD_REGEX = /(?<pod>(pod)?#{UUID_PATTERN})(?:.slice)?$/.freeze
13+
CONTAINER_REGEX = /(?<container>#{UUID_PATTERN}|#{CONTAINER_PATTERN})(?:.scope)?$/.freeze
14+
FARGATE_14_CONTAINER_REGEX = /(?<container>[0-9a-f]{32}-[0-9]{10})/.freeze
15+
16+
Descriptor = Struct.new(
17+
:platform,
18+
:container_id,
19+
:task_uid
20+
)
21+
22+
module_function
23+
24+
def platform
25+
descriptor.platform
26+
end
27+
28+
def container_id
29+
descriptor.container_id
30+
end
31+
32+
def task_uid
33+
descriptor.task_uid
34+
end
35+
36+
def descriptor
37+
@descriptor ||= Descriptor.new.tap do |descriptor|
38+
begin
39+
Cgroup.descriptors.each do |cgroup_descriptor|
40+
# Parse container data from cgroup descriptor
41+
path = cgroup_descriptor.path
42+
next if path.nil?
43+
44+
# Split path into parts
45+
parts = path.split('/')
46+
parts.shift # Remove leading empty part
47+
48+
# Read info from path
49+
next if parts.empty?
50+
51+
platform = parts[0][PLATFORM_REGEX, :platform]
52+
container_id, task_uid = nil
53+
54+
case parts.length
55+
when 0..1
56+
next
57+
when 2
58+
container_id = parts[-1][CONTAINER_REGEX, :container] \
59+
|| parts[-1][FARGATE_14_CONTAINER_REGEX, :container]
60+
else
61+
if (container_id = parts[-1][CONTAINER_REGEX, :container])
62+
task_uid = parts[-2][POD_REGEX, :pod]
63+
else
64+
container_id = parts[-1][FARGATE_14_CONTAINER_REGEX, :container]
65+
end
66+
end
67+
68+
# If container ID wasn't found, ignore.
69+
# Path might describe a non-container environment.
70+
next if container_id.nil?
71+
72+
descriptor.platform = platform
73+
descriptor.container_id = container_id
74+
descriptor.task_uid = task_uid
75+
76+
break
77+
end
78+
rescue StandardError => e
79+
Datadog.logger.error(
80+
"Error while parsing container info. Cause: #{e.message} Location: #{e.backtrace.first}"
81+
)
82+
end
83+
end
84+
end
85+
end
86+
end
87+
end
88+
end

lib/datadog/core/environment/ext.rb

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
require 'ddtrace/version'
2+
3+
module Datadog
4+
module Core
5+
module Environment
6+
module Ext
7+
# Identity
8+
LANG = 'ruby'.freeze
9+
LANG_ENGINE = RUBY_ENGINE
10+
LANG_INTERPRETER = "#{RUBY_ENGINE}-#{RUBY_PLATFORM}".freeze
11+
LANG_PLATFORM = RUBY_PLATFORM
12+
LANG_VERSION = RUBY_VERSION
13+
RUBY_ENGINE = ::RUBY_ENGINE # e.g. 'ruby', 'jruby', 'truffleruby'
14+
TRACER_VERSION = Datadog::VERSION::STRING
15+
end
16+
end
17+
end
18+
end

lib/datadog/core/environment/gc.rb

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module Datadog
2+
module Core
3+
module Environment
4+
# Retrieves garbage collection statistics
5+
module GC
6+
module_function
7+
8+
def stat
9+
::GC.stat
10+
end
11+
12+
def available?
13+
defined?(::GC) && ::GC.respond_to?(:stat)
14+
end
15+
end
16+
end
17+
end
18+
end
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
require 'securerandom'
2+
require 'datadog/core/environment/ext'
3+
require 'ddtrace/utils/forking'
4+
5+
module Datadog
6+
module Core
7+
module Environment
8+
# For runtime identity
9+
module Identity
10+
extend Datadog::Utils::Forking
11+
12+
module_function
13+
14+
# Retrieves number of classes from runtime
15+
def id
16+
@id ||= SecureRandom.uuid
17+
18+
# Check if runtime has changed, e.g. forked.
19+
after_fork! { @id = SecureRandom.uuid }
20+
21+
@id
22+
end
23+
24+
def lang
25+
Core::Environment::Ext::LANG
26+
end
27+
28+
def lang_engine
29+
Core::Environment::Ext::LANG_ENGINE
30+
end
31+
32+
def lang_interpreter
33+
Core::Environment::Ext::LANG_INTERPRETER
34+
end
35+
36+
def lang_platform
37+
Core::Environment::Ext::LANG_PLATFORM
38+
end
39+
40+
def lang_version
41+
Core::Environment::Ext::LANG_VERSION
42+
end
43+
44+
def tracer_version
45+
Core::Environment::Ext::TRACER_VERSION
46+
end
47+
end
48+
end
49+
end
50+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
require 'objspace'
2+
3+
module Datadog
4+
module Core
5+
module Environment
6+
# Retrieves garbage collection statistics
7+
# DEV: Currently only used for testing.
8+
module ObjectSpace
9+
module_function
10+
11+
def estimate_bytesize(object)
12+
return 0 unless ::ObjectSpace.respond_to?(:memsize_of)
13+
14+
# Rough calculation of bytesize; not very accurate.
15+
object.instance_variables.inject(::ObjectSpace.memsize_of(object)) do |sum, var|
16+
sum + ::ObjectSpace.memsize_of(object.instance_variable_get(var))
17+
end
18+
end
19+
end
20+
end
21+
end
22+
end
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
require 'socket'
2+
3+
module Datadog
4+
module Core
5+
module Environment
6+
# For runtime identity
7+
module Socket
8+
module_function
9+
10+
def hostname
11+
::Socket.gethostname
12+
end
13+
end
14+
end
15+
end
16+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module Datadog
2+
module Core
3+
module Environment
4+
# Retrieves number of threads from runtime
5+
module ThreadCount
6+
module_function
7+
8+
def value
9+
Thread.list.count
10+
end
11+
12+
def available?
13+
Thread.respond_to?(:list)
14+
end
15+
end
16+
end
17+
end
18+
end

0 commit comments

Comments
 (0)