Skip to content

Commit 43d5a1b

Browse files
update metrics
1 parent 2c4adde commit 43d5a1b

20 files changed

+256
-114
lines changed

Gemfile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,8 @@ source 'https://rubygems.org'
1717

1818
gemspec name: 'skywalking'
1919

20-
ruby ">= 3.0.0"
20+
ruby ">= 3.0.0"
21+
22+
# Optional dependencies for enhanced performance
23+
# Uncomment the following line to enable FFI for better system call performance
24+
# gem 'ffi', '~> 1.17'

docs/en/agent/meter-log-reporter.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,30 @@ The agent automatically collects Ruby runtime metrics when `meter_reporter_activ
1010

1111
**CPU Metrics:**
1212

13-
- `instance_ruby_cpu_usage_percent` - Ruby process CPU usage percentage (based on load average)
13+
- `instance_ruby_cpu_usage_percent` - Ruby process CPU usage percentage
1414

1515
**Memory Metrics:**
1616

1717
- `instance_ruby_memory_rss_mb` - Ruby process RSS memory usage in MB
18+
- `instance_ruby_memory_usage_percent` - Ruby process memory usage percentage
1819

1920
**Garbage Collection Metrics:**
2021

2122
- `instance_ruby_gc_count_total` - Total GC execution count
2223
- `instance_ruby_gc_minor_count_total` - Minor GC count (if available)
2324
- `instance_ruby_gc_major_count_total` - Major GC count (if available)
25+
- `instance_ruby_gc_time_total` - Total GC time in milliseconds (cumulative)
2426
- `instance_ruby_heap_usage_percent` - Heap memory usage percentage
2527
- `instance_ruby_heap_live_slots_count` - Number of live heap slots
26-
- `instance_ruby_heap_allocated_slots_count` - Number of allocated heap slots
2728

2829
**Object System Metrics:**
2930

3031
- `instance_ruby_total_allocated_objects` - Total allocated objects count
3132

3233
**Thread Metrics:**
3334

34-
- `instance_ruby_thread_count_active` - Number of active threads
35+
- `instance_ruby_thread_count_active` - Number of active threads (all alive threads)
36+
- `instance_ruby_thread_count_running` - Number of threads in running state
3537

3638
### Log Integration
3739

docs/en/setup/quick-start.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ The following lists all the configuration options:
140140
| properties_report_period_factor | SW_AGENT_PROPERTIES_REPORT_PERIOD_FACTOR | 10 | The agent will report service instance properties every `collector_heartbeat_period * properties_report_period_factor` seconds. |
141141
| max_queue_size | SW_AGENT_MAX_QUEUE_SIZE | 10000 | The maximum queue size for reporting data. |
142142
| meter_reporter_active | SW_AGENT_METER_REPORTER_ACTIVE | true | Enable/disable meter reporter for runtime metrics collection. |
143-
| meter_report_period | SW_AGENT_METER_REPORT_PERIOD | 20 | Meter report period in seconds. |
143+
| meter_report_period | SW_AGENT_METER_REPORT_PERIOD | 60 | Meter report period in seconds. |
144144
| max_meter_queue_size | SW_AGENT_MAX_METER_QUEUE_SIZE | 1000 | Maximum meter queue size for buffering metrics data. |
145145
| log_reporter_active | SW_AGENT_LOG_REPORTER_ACTIVE | true | Enable/disable log reporter for log collection. |
146146
| log_reporter_level | SW_AGENT_LOG_REPORTER_LEVEL | 1 (INFO) | Minimum log level to report (Logger::DEBUG=0, INFO=1, WARN=2, ERROR=3, FATAL=4). |

lib/skywalking/agent.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def started?
6363
end
6464

6565
attr_reader :logger, :agent_config
66-
66+
6767
# Get the singleton instance
6868
# @return [Agent, nil] the agent instance or nil if not started
6969
def instance
@@ -120,7 +120,7 @@ def start_log_reporting_thread
120120
Thread.new do
121121
loop do
122122
break unless log_reporter_active?
123-
123+
124124
process_log_queue
125125
sleep @config[:log_report_period]
126126
end
@@ -132,13 +132,13 @@ def process_log_queue
132132
log_count = 0
133133
enumerator = Enumerator.new do |yielder|
134134
while (log_data = log_buffer.stream_data)
135-
log_data.each do |data|
135+
log_data.each do |data|
136136
log_count += 1
137-
yielder << data
137+
yielder << data
138138
end
139139
end
140140
end
141-
141+
142142
enumerator.each_slice(10) do |batch|
143143
begin
144144
reporter.report_log(batch)

lib/skywalking/configuration.rb

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class Configuration
112112
},
113113
:meter_report_period => {
114114
type: :int,
115-
default: 20,
115+
default: 60,
116116
desc: 'Meter report period in seconds'
117117
},
118118
:max_meter_queue_size => {
@@ -213,18 +213,18 @@ def override_config_by_env
213213
next if env_value.nil?
214214

215215
type = env_schema[:type]
216-
case type
217-
when :string
218-
new_config[env_key] = env_value.to_s
219-
when :bool
220-
# rubocop:disable Performance/CollectionLiteralInLoop
221-
new_config[env_key] = !%w[0 false].include?(env_value.strip.downcase)
222-
# rubocop:enable Performance/CollectionLiteralInLoop
223-
when :int
224-
new_config[env_key] = env_value.to_i
225-
else
226-
env_value
227-
end
216+
new_config[env_key] = case type
217+
when :string
218+
env_value.to_s
219+
when :bool
220+
# rubocop:disable Performance/CollectionLiteralInLoop
221+
!%w[0 false].include?(env_value.strip.downcase)
222+
# rubocop:enable Performance/CollectionLiteralInLoop
223+
when :int
224+
env_value.to_i
225+
else
226+
env_value
227+
end
228228
end
229229

230230
new_config

lib/skywalking/environment.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def app_name
3737
rescue
3838
nil
3939
end
40-
40+
4141
def env
4242
::Rails.env
4343
end
@@ -63,7 +63,7 @@ def app_name
6363
rescue
6464
"Sinatra"
6565
end
66-
66+
6767
def env
6868
ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
6969
end
@@ -81,7 +81,7 @@ def present?
8181
def app_name
8282
"Ruby"
8383
end
84-
84+
8585
def env
8686
ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
8787
end
@@ -111,7 +111,7 @@ def framework_root
111111
"."
112112
end
113113
end
114-
114+
115115
def framework_env
116116
@framework_env ||= framework_info.env
117117
end

lib/skywalking/meter/meter_service.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ def stop
6161
private
6262

6363
def run_collection_loop
64-
period = @config[:meter_report_period] || 20
65-
64+
period = @config[:meter_report_period]
65+
6666
while @running
6767
begin
6868
collect_and_queue_metrics

lib/skywalking/meter/runtime/cpu_data_source.rb

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,43 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
require 'sys/cpu'
1716
require_relative '../base'
1817

1918
module Skywalking
2019
module Meter
2120
module Runtime
22-
# DataSource for collecting CPU usage metrics
21+
# DataSource for collecting Ruby process CPU usage metrics
2322
class CpuDataSource < DataSource
2423
def initialize
25-
@cpu_count = Sys::CPU.num_cpu || 1
24+
@last_cpu_time = Process.clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID)
25+
@last_wall_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
2626
end
27-
28-
# Return current process CPU utilization percentage
27+
28+
# Ruby process CPU usage percentage
2929
def cpu_usage_percent_generator
30-
# Use Sys::CPU load average as a simple metric
31-
# This is similar to how Python's psutil works
32-
load_avg = Sys::CPU.load_avg[0] # 1-minute load average
33-
load_avg * 100.0 / @cpu_count
34-
35-
rescue
36-
0.0
30+
begin
31+
current_cpu_time = Process.clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID)
32+
current_wall_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
33+
34+
cpu_time_diff = current_cpu_time - @last_cpu_time
35+
wall_time_diff = current_wall_time - @last_wall_time
36+
37+
# Calculate CPU usage as percentage of wall time
38+
if wall_time_diff > 0
39+
cpu_usage = (cpu_time_diff / wall_time_diff) * 100.0
40+
cpu_usage = [cpu_usage, 0.0].max
41+
else
42+
cpu_usage = 0.0
43+
end
44+
45+
# Update last values for next calculation
46+
@last_cpu_time = current_cpu_time
47+
@last_wall_time = current_wall_time
48+
49+
cpu_usage
50+
rescue
51+
0.0
52+
end
3753
end
3854
end
3955
end

lib/skywalking/meter/runtime/gc_data_source.rb

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,48 @@ module Meter
2020
module Runtime
2121
# DataSource for collecting GC metrics
2222
class GcDataSource < DataSource
23+
def initialize
24+
@cached_stats = nil
25+
@cached_count = nil
26+
@cache_time = 0
27+
@cache_duration = 60
28+
end
29+
2330
# Total GC count
2431
def gc_count_total_generator
25-
GC.count
32+
get_gc_data
33+
@cached_count || 0
2634
rescue
2735
0
2836
end
29-
37+
3038
# Minor GC count (if available)
3139
def gc_minor_count_total_generator
32-
GC.stat[:minor_gc_count] || 0
40+
stats = get_gc_stats
41+
stats[:minor_gc_count] || 0
3342
rescue
3443
0
3544
end
36-
45+
3746
# Major GC count (if available)
3847
def gc_major_count_total_generator
39-
GC.stat[:major_gc_count] || 0
48+
stats = get_gc_stats
49+
stats[:major_gc_count] || 0
50+
rescue
51+
0
52+
end
53+
54+
# GC total time
55+
def gc_time_total_generator
56+
stats = get_gc_stats
57+
stats[:time] || 0
4058
rescue
4159
0
4260
end
4361

4462
# Heap usage percentage
4563
def heap_usage_percent_generator
46-
stats = GC.stat
64+
stats = get_gc_stats
4765
if stats[:heap_available_slots] && stats[:heap_available_slots] > 0
4866
(stats[:heap_live_slots].to_f / stats[:heap_available_slots] * 100)
4967
else
@@ -52,6 +70,29 @@ def heap_usage_percent_generator
5270
rescue
5371
0.0
5472
end
73+
74+
private
75+
76+
# Get cached GC statistics, refresh if cache is expired
77+
def get_gc_stats
78+
current_time = Time.now.to_i
79+
if @cached_stats.nil? || (current_time - @cache_time) > @cache_duration
80+
@cached_stats = GC.stat
81+
@cache_time = current_time
82+
end
83+
@cached_stats
84+
end
85+
86+
# Get both GC.count and GC.stat data, refresh if cache is expired
87+
def get_gc_data
88+
current_time = Time.now.to_i
89+
if @cached_stats.nil? || (current_time - @cache_time) > @cache_duration
90+
@cached_stats = GC.stat
91+
@cached_count = GC.count
92+
@cache_time = current_time
93+
end
94+
@cached_stats
95+
end
5596
end
5697
end
5798
end

0 commit comments

Comments
 (0)