skylight 0.3.7 → 0.3.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 727271788a0fddacdf3b7e53451c413023d74a0d
4
- data.tar.gz: 0b911dd320834be2608b7cd294e5aacf395188b7
3
+ metadata.gz: 21e17f0c6b492a15fe9be1823c16121ffa55ffbb
4
+ data.tar.gz: 000df33e16f6d5cd9c8e007e96f20d0a7fac89cb
5
5
  SHA512:
6
- metadata.gz: 425fe8a9ece2086b79e08cadcd7687c1d808ce65e2772c6b3d457c7f5b79c57fe9284d78f9964a7a161e95f67d0e87d2cf4dc89370488d6d7ad7906abec53357
7
- data.tar.gz: bbbe029afd5bfaa9c203ad7103ac818bdebbc95a78b94435ed43344b5a00feb74e7992d75bc8fdca27e1fe63dadb784fcd64ef63abbb41130092c4511988f5ea
6
+ metadata.gz: 5bc55e53b477093f2239a954aa2892a14b34cf7a49d85d48c83c77a04348b09be58f6529fd6ce0e58a09dc9662f801ba890388390498ddf7045dfd83cb8250aa
7
+ data.tar.gz: 8635a462ded00edf9e8cdf8c05919a64201a7f9d7e5b39a4cb107b89454635602cd1ef2a655fe3b2a989c403f90d782423d01cbbed6af202c2c84e72dbfe241a
@@ -1,3 +1,16 @@
1
+ ## 0.3.8 (April 3, 2014)
2
+
3
+ * Update vendored highline to 1.6.21
4
+ * Send more information with exceptions for easier debugging
5
+ * Instrument and report internal agent metrics for easier debugging
6
+ * Fix bug with tracking request counts per endpoint
7
+
8
+ ## 0.3.7 (March 31, 2014)
9
+
10
+ * Use a default event category if none passed to Skylight.instrument
11
+ * Fix bugs around disabling the agent
12
+ * Fix native extension compilation bugs
13
+
1
14
  ## 0.3.6 (March 27, 2014)
2
15
 
3
16
  * Shorter token validation timeout
@@ -1,6 +1,6 @@
1
1
  ---
2
- version: "74fb9b3"
2
+ version: "f2a0e15"
3
3
  checksums:
4
- linux-x86_64: "98b04f7d73c1894cc79621a135b4598a679c421f5ff3eecc652f84ba07258d9c"
5
- linux-x86: "1d4bbd58e319237b18752607d087ce0c895fe99c58482e994abe62a9f07d41dd"
4
+ linux-x86_64: "a99d5542893418b0a5b6b53a599b2c2a07dc8186491181f6dbe0ccfab03dbed4"
5
+ linux-x86: "a4db4dfbaaa1181e74e6756f4d56ba00fdf4b88e54476294086e7e27bf0c3cdc"
6
6
 
@@ -428,46 +428,6 @@ static VALUE trace_serialize(VALUE self) {
428
428
  return rb_string;
429
429
  }
430
430
 
431
- static VALUE trace_span_add_annotation(VALUE self, VALUE rb_span_id, VALUE parent, VALUE rb_key, VALUE value) {
432
- uint32_t *parent_id = NULL;
433
- RustSlice rs_key;
434
- RustSlice *key = NULL;
435
- uint32_t new_id, parent_int;
436
-
437
- My_Struct(trace, RustTrace, freedTrace);
438
-
439
- CHECK_TYPE(rb_span_id, T_FIXNUM);
440
- uint32_t span_id = FIX2UINT(rb_span_id);
441
-
442
- if (parent != Qnil) {
443
- CHECK_TYPE(parent, T_FIXNUM);
444
- parent_int = FIX2UINT(parent);
445
- parent_id = &parent_int;
446
- }
447
-
448
- if (rb_key != Qnil) {
449
- CHECK_TYPE(rb_key, T_STRING);
450
-
451
- rs_key = STR2SLICE(rb_key);
452
- key = &rs_key;
453
- }
454
-
455
- if (TYPE(value) == T_FIXNUM) {
456
- CHECK_FFI(skylight_trace_add_annotation_int(trace, span_id, parent_id, key, NUM2LL(value)), "Could not add int annotation");
457
- } else if (TYPE(value) == T_FLOAT) {
458
- CHECK_FFI(skylight_trace_add_annotation_double(trace, span_id, parent_id, key, NUM2DBL(value)), "Could not add double annotation");
459
- } else if (TYPE(value) == T_STRING) {
460
- CHECK_FFI(skylight_trace_add_annotation_string(trace, span_id, parent_id, key, STR2SLICE(value)), "Could not add string annotation");
461
- } else if (TYPE(value) == T_SYMBOL && value == ID2SYM(rb_intern("nested"))) {
462
- CHECK_FFI(skylight_trace_add_annotation_nested(trace, span_id, parent_id, key, &new_id), "Could not add nested annotation");
463
- return ULL2NUM(new_id);
464
- } else {
465
- rb_raise(rb_eArgError, "You must pass an integer, string or :nested to native_span_add_annotation");
466
- }
467
-
468
- return Qnil;
469
- }
470
-
471
431
  /**
472
432
  * class Skylight::Batch
473
433
  */
@@ -564,7 +524,6 @@ void Init_skylight_native() {
564
524
  rb_define_method(rb_cTrace, "native_stop_span", trace_stop_span, 2);
565
525
  rb_define_method(rb_cTrace, "native_span_set_title", trace_span_set_title, 2);
566
526
  rb_define_method(rb_cTrace, "native_span_set_description", trace_span_set_description, 2);
567
- rb_define_method(rb_cTrace, "native_span_add_annotation", trace_span_add_annotation, 4);
568
527
 
569
528
  rb_cBatch = rb_define_class_under(rb_mSkylight, "Batch", rb_cObject);
570
529
  rb_define_singleton_method(rb_cBatch, "native_new", batch_new, 2);
@@ -81,9 +81,17 @@ module Skylight
81
81
  autoload :Subscriber, 'skylight/subscriber'
82
82
  autoload :Worker, 'skylight/worker'
83
83
 
84
+ module Metrics
85
+ autoload :Meter, 'skylight/metrics/meter'
86
+ autoload :EWMA, 'skylight/metrics/ewma'
87
+ autoload :ProcessMemGauge, 'skylight/metrics/process_mem_gauge'
88
+ autoload :ProcessCpuGauge, 'skylight/metrics/process_cpu_gauge'
89
+ end
90
+
84
91
  module Util
85
92
  require 'skylight/util/clock'
86
93
 
94
+ autoload :Conversions, 'skylight/util/conversions'
87
95
  autoload :Gzip, 'skylight/util/gzip'
88
96
  autoload :HTTP, 'skylight/util/http'
89
97
  autoload :Inflector, 'skylight/util/inflector'
@@ -19,50 +19,53 @@ module Skylight
19
19
 
20
20
  # Map environment variable keys with Skylight configuration keys
21
21
  ENV_TO_KEY = {
22
- 'ROOT' => :'root',
23
- 'LOG_FILE' => :'log_file',
24
- 'LOG_LEVEL' => :'log_level',
25
- 'APPLICATION' => :'application',
26
- 'AUTHENTICATION' => :'authentication',
27
- 'HOSTNAME' => :'hostname',
28
- 'SKIP_VALIDATION' => :'skip_validation',
29
- 'AGENT_INTERVAL' => :'agent.interval',
30
- 'AGENT_KEEPALIVE' => :'agent.keepalive',
31
- 'AGENT_SAMPLE_SIZE' => :'agent.sample',
32
- 'AGENT_SOCKFILE_PATH' => :'agent.sockfile_path',
33
- 'AGENT_STRATEGY' => :'agent.strategy',
34
- 'AGENT_MAX_MEMORY' => :'agent.max_memory',
35
- 'REPORT_HOST' => :'report.host',
36
- 'REPORT_PORT' => :'report.port',
37
- 'REPORT_SSL' => :'report.ssl',
38
- 'REPORT_DEFLATE' => :'report.deflate',
39
- 'ACCOUNTS_HOST' => :'accounts.host',
40
- 'ACCOUNTS_PORT' => :'accounts.port',
41
- 'ACCOUNTS_SSL' => :'accounts.ssl',
42
- 'ACCOUNTS_DEFLATE' => :'accounts.deflate',
43
- 'ME_AUTHENTICATION' => :'me.authentication',
44
- 'ME_CREDENTIALS_PATH' => :'me.credentials_path',
45
- 'TEST_CONSTANT_FLUSH' => :'test.constant_flush',
46
- 'TEST_IGNORE_TOKEN' => :'test.ignore_token' }
22
+ 'ROOT' => :'root',
23
+ 'LOG_FILE' => :'log_file',
24
+ 'LOG_LEVEL' => :'log_level',
25
+ 'APPLICATION' => :'application',
26
+ 'AUTHENTICATION' => :'authentication',
27
+ 'HOSTNAME' => :'hostname',
28
+ 'SKIP_VALIDATION' => :'skip_validation',
29
+ 'AGENT_INTERVAL' => :'agent.interval',
30
+ 'AGENT_KEEPALIVE' => :'agent.keepalive',
31
+ 'AGENT_SAMPLE_SIZE' => :'agent.sample',
32
+ 'AGENT_SOCKFILE_PATH' => :'agent.sockfile_path',
33
+ 'AGENT_STRATEGY' => :'agent.strategy',
34
+ 'AGENT_MAX_MEMORY' => :'agent.max_memory',
35
+ 'REPORT_HOST' => :'report.host',
36
+ 'REPORT_PORT' => :'report.port',
37
+ 'REPORT_SSL' => :'report.ssl',
38
+ 'REPORT_DEFLATE' => :'report.deflate',
39
+ 'ACCOUNTS_HOST' => :'accounts.host',
40
+ 'ACCOUNTS_PORT' => :'accounts.port',
41
+ 'ACCOUNTS_SSL' => :'accounts.ssl',
42
+ 'ACCOUNTS_DEFLATE' => :'accounts.deflate',
43
+ 'ME_AUTHENTICATION' => :'me.authentication',
44
+ 'ME_CREDENTIALS_PATH' => :'me.credentials_path',
45
+ 'METRICS_REPORT_INTERVAL' => :'metrics.report_interval',
46
+ 'TEST_CONSTANT_FLUSH' => :'test.constant_flush',
47
+ 'TEST_IGNORE_TOKEN' => :'test.ignore_token' }
47
48
 
48
49
  # Default values for Skylight configuration keys
49
50
  DEFAULTS = {
50
- :'log_file' => '-'.freeze,
51
- :'log_level' => 'INFO'.freeze,
52
- :'hostname' => default_hostname,
53
- :'agent.keepalive' => 60,
54
- :'agent.interval' => 5,
55
- :'agent.sample' => 200,
56
- :'agent.max_memory' => 256, # MB
57
- :'report.host' => 'agent.skylight.io'.freeze,
58
- :'report.port' => 443,
59
- :'report.ssl' => true,
60
- :'report.deflate' => true,
61
- :'accounts.host' => 'www.skylight.io'.freeze,
62
- :'accounts.port' => 443,
63
- :'accounts.ssl' => true,
64
- :'accounts.deflate' => false,
65
- :'me.credentials_path' => '~/.skylight' }.freeze
51
+ :'log_file' => '-'.freeze,
52
+ :'log_level' => 'INFO'.freeze,
53
+ :'hostname' => default_hostname,
54
+ :'agent.keepalive' => 60,
55
+ :'agent.interval' => 5,
56
+ :'agent.sample' => 200,
57
+ :'agent.max_memory' => 256, # MB
58
+ :'report.host' => 'agent.skylight.io'.freeze,
59
+ :'report.port' => 443,
60
+ :'report.ssl' => true,
61
+ :'report.deflate' => true,
62
+ :'accounts.host' => 'www.skylight.io'.freeze,
63
+ :'accounts.port' => 443,
64
+ :'accounts.ssl' => true,
65
+ :'accounts.deflate' => false,
66
+ :'me.credentials_path' => '~/.skylight',
67
+ :'metrics.report_interval' => 60
68
+ }.freeze
66
69
 
67
70
  REQUIRED = {
68
71
  :'authentication' => "authentication token",
@@ -0,0 +1,69 @@
1
+ module Skylight
2
+ module Metrics
3
+
4
+ # An exponentially-weighted moving average. Not thread-safe
5
+ class EWMA
6
+ include Util::Conversions
7
+
8
+ INTERVAL = 5
9
+
10
+ # Some common EWMA
11
+ attr_reader :interval
12
+
13
+ def initialize(alpha, interval)
14
+ @rate = 0.0
15
+ @alpha = alpha
16
+ @interval = secs_to_nanos(interval).to_f
17
+ @uncounted = 0
18
+ @initialized = false
19
+ end
20
+
21
+ def self.alpha(minutes, interval = INTERVAL)
22
+ 1 - Math.exp(-interval / 60.0 / minutes)
23
+ end
24
+
25
+ # Some common EWMA
26
+
27
+ M1 = alpha(1)
28
+ M5 = alpha(5)
29
+ M15 = alpha(15)
30
+
31
+ def self.one_minute_ewma
32
+ EWMA.new M1, INTERVAL
33
+ end
34
+
35
+ def self.five_minute_ewma
36
+ EWMA.new M5, INTERVAL
37
+ end
38
+
39
+ def self.fifteen_minute_ewma
40
+ EWMA.new M15, INTERVAL
41
+ end
42
+
43
+ def update(count)
44
+ @uncounted += count
45
+ end
46
+
47
+ def tick
48
+ # Compute the rate this interval (aka the num of occurences this tick)
49
+ instant_rate = @uncounted / @interval
50
+
51
+ # Reset the count
52
+ @uncounted = 0
53
+
54
+ if @initialized
55
+ @rate += (@alpha * (instant_rate - @rate))
56
+ else
57
+ @rate = instant_rate
58
+ @initialized = true
59
+ end
60
+ end
61
+
62
+ # Get the rate in the requested interval (where the interval is specified
63
+ # in number of seconds
64
+ def rate(interval = 1)
65
+ @rate * secs_to_nanos(interval)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,58 @@
1
+ require 'thread'
2
+
3
+ module Skylight
4
+ module Metrics
5
+ class Meter
6
+ def initialize(ewma = EWMA.one_minute_ewma, clock = Util::Clock.default)
7
+ @ewma = ewma
8
+ @lock = Mutex.new
9
+ @clock = clock
10
+ @start_time = @clock.tick
11
+ @last_tick = @start_time
12
+ end
13
+
14
+ def mark(n = 1)
15
+ @lock.synchronize do
16
+ tick_if_necessary
17
+ @ewma.update(n)
18
+ end
19
+ end
20
+
21
+ def rate
22
+ @lock.synchronize do
23
+ tick_if_necessary
24
+ @ewma.rate(1)
25
+ end
26
+ end
27
+
28
+ def call
29
+ rate
30
+ end
31
+
32
+ private
33
+
34
+ def tick_if_necessary
35
+ old_tick = @last_tick
36
+ new_tick = @clock.tick
37
+
38
+ # How far behind are we
39
+ age = new_tick - old_tick
40
+
41
+ if age >= @ewma.interval
42
+ new_tick = new_tick - age % @ewma.interval
43
+
44
+ # Update the last seen tick
45
+ @last_tick = new_tick
46
+
47
+ # Number of missing ticks
48
+ required_ticks = age / @ewma.interval
49
+
50
+ while required_ticks > 0
51
+ @ewma.tick
52
+ required_ticks -= 1
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,65 @@
1
+ module Skylight
2
+ module Metrics
3
+ class ProcessCpuGauge
4
+
5
+ def initialize(cache_for = 5, clock = Util::Clock.default)
6
+ @value = nil
7
+ @cache_for = cache_for
8
+ @last_check_at = 0
9
+ @clock = clock
10
+
11
+ @last_totaltime = nil
12
+ @last_usagetime = nil
13
+ @last_utime = nil
14
+ @last_stime = nil
15
+ end
16
+
17
+ def call(now = @clock.absolute_secs)
18
+ if !@value || should_check?(now)
19
+ @value = check
20
+ @last_check_at = now
21
+ end
22
+
23
+ @value
24
+ end
25
+
26
+ private
27
+
28
+ def check
29
+ ret = nil
30
+
31
+ statfile = "/proc/stat"
32
+ pidstatfile = "/proc/#{Process.pid}/stat"
33
+
34
+ if File.exist?(statfile) && File.exist?(pidstatfile)
35
+ cpustats = File.readlines(statfile).grep(/^cpu /).first.split(' ')
36
+ usagetime = cpustats[1..3].reduce(0){|sum, i| sum + i.to_i }
37
+ totaltime = usagetime + cpustats[4].to_i
38
+
39
+ pidstats = File.read(pidstatfile).split(' ')
40
+ utime, stime = pidstats[13].to_i, pidstats[14].to_i
41
+
42
+ if @last_totaltime && @last_usagetime && @last_utime && @last_stime
43
+ elapsed = totaltime - @last_totaltime
44
+ ret = [(usagetime - @last_usagetime).to_f / elapsed,
45
+ (utime - @last_utime).to_f / elapsed,
46
+ (stime - @last_stime).to_f / elapsed]
47
+ end
48
+
49
+ @last_totaltime = totaltime
50
+ @last_usagetime = usagetime
51
+ @last_utime = utime
52
+ @last_stime = stime
53
+ end
54
+
55
+ ret
56
+ rescue Errno::ENOENT
57
+ nil
58
+ end
59
+
60
+ def should_check?(now)
61
+ now >= @last_check_at + @cache_for
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,34 @@
1
+ module Skylight
2
+ module Metrics
3
+ class ProcessMemGauge
4
+
5
+ def initialize(cache_for = 30, clock = Util::Clock.default)
6
+ @value = nil
7
+ @cache_for = cache_for
8
+ @last_check_at = 0
9
+ @clock = clock
10
+ end
11
+
12
+ def call(now = @clock.absolute_secs)
13
+ if !@value || should_check?(now)
14
+ @value = check
15
+ @last_check_at = now
16
+ end
17
+
18
+ @value
19
+ end
20
+
21
+ private
22
+
23
+ def check
24
+ `ps -o rss= -p #{Process.pid}`.to_i / 1024
25
+ rescue Errno::ENOENT, Errno::EINTR
26
+ 0
27
+ end
28
+
29
+ def should_check?(now)
30
+ now >= @last_check_at + @cache_for
31
+ end
32
+ end
33
+ end
34
+ end
@@ -2,22 +2,28 @@ module Skylight
2
2
  module Util
3
3
  class Clock
4
4
 
5
- def absolute_secs
6
- Time.now.to_i
7
- end
8
-
9
5
  if Skylight.native?
10
- def nanos
6
+ def tick
11
7
  native_hrtime
12
8
  end
13
9
  else
14
- # Implement nanos to work when native extension is not present
15
- def nanos
10
+ def tick
16
11
  now = Time.now
17
12
  now.to_i * 1_000_000_000 + now.usec * 1_000
18
13
  end
19
14
  end
20
15
 
16
+ # TODO: rename to secs
17
+ def absolute_secs
18
+ Time.now.to_i
19
+ end
20
+
21
+ # TODO: remove
22
+ def nanos
23
+ tick
24
+ end
25
+
26
+ # TODO: remove
21
27
  def secs
22
28
  nanos / 1_000_000_000
23
29
  end