camayoc 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,33 +1,33 @@
1
1
  class MemoryTest < Test::Unit::TestCase
2
-
2
+
3
3
  def setup
4
4
  @handler = Camayoc::Handlers::Memory.new
5
5
  end
6
-
6
+
7
7
  def test_count_initializes_to_0_and_increments_value
8
- @handler.count(Camayoc::StatEvent.new("foo:bar","count",100))
8
+ @handler.event(Camayoc::StatEvent.new(:count,"foo:bar","count",100))
9
9
  assert_equal(100,@handler["foo:bar:count"])
10
10
  end
11
11
 
12
12
  def test_multiple_counts_increments_value
13
- @handler.count(Camayoc::StatEvent.new("foo:bar","count",100))
14
- @handler.count(Camayoc::StatEvent.new("foo:bar","count",500))
15
- @handler.count(Camayoc::StatEvent.new("foo:bar","count",400))
13
+ @handler.event(Camayoc::StatEvent.new(:count,"foo:bar","count",100))
14
+ @handler.event(Camayoc::StatEvent.new(:count,"foo:bar","count",500))
15
+ @handler.event(Camayoc::StatEvent.new(:count,"foo:bar","count",400))
16
16
  assert_equal(1000,@handler["foo:bar:count"])
17
17
  end
18
18
 
19
19
  def test_timing_initializes_timing_object_and_adds_data
20
- @handler.timing(Camayoc::StatEvent.new("foo:bar","time",500))
20
+ @handler.event(Camayoc::StatEvent.new(:timing,"foo:bar","time",500))
21
21
  timing = @handler["foo:bar:time"]
22
22
  assert_not_nil(timing)
23
23
  assert_equal(1,timing.count)
24
24
  end
25
25
 
26
26
  def test_timing_increments_timing_object
27
- @handler.timing(Camayoc::StatEvent.new("foo:bar","time",100))
28
- @handler.timing(Camayoc::StatEvent.new("foo:bar","time",600))
29
- @handler.timing(Camayoc::StatEvent.new("foo:bar","time",1000))
30
- @handler.timing(Camayoc::StatEvent.new("foo:bar","time",500))
27
+ @handler.event(Camayoc::StatEvent.new(:timing,"foo:bar","time",100))
28
+ @handler.event(Camayoc::StatEvent.new(:timing,"foo:bar","time",600))
29
+ @handler.event(Camayoc::StatEvent.new(:timing,"foo:bar","time",1000))
30
+ @handler.event(Camayoc::StatEvent.new(:timing,"foo:bar","time",500))
31
31
  timing = @handler["foo:bar:time"]
32
32
  assert_equal(4,timing.count)
33
33
  assert_equal(100,timing.min)
@@ -35,4 +35,55 @@ class MemoryTest < Test::Unit::TestCase
35
35
  assert_equal(2200,timing.total)
36
36
  assert_equal(550,timing.average)
37
37
  end
38
- end
38
+
39
+ def test_ignore_unknown_event_type
40
+ @handler.expects(:count).never
41
+ @handler.expects(:timing).never
42
+ @handler.event(Camayoc::StatEvent.new(:throwaway,"foo:bar","time",500))
43
+ end
44
+
45
+ def test_add_generic_event
46
+ @handler.expects(:generic).once
47
+ @handler.event(Camayoc::StatEvent.new(:generic,"foo:bar","time",50))
48
+ end
49
+
50
+ def test_safe_defaults_for_max_events_falls_back
51
+ @handler = Camayoc::Handlers::Memory.new
52
+ assert_equal(Camayoc::Handlers::Memory::DEFAULT_MAX_EVENTS,
53
+ @handler.max_events)
54
+
55
+ @handler = Camayoc::Handlers::Memory.new(:max_events=>"apple pie")
56
+ assert_equal(Camayoc::Handlers::Memory::DEFAULT_MAX_EVENTS,
57
+ @handler.max_events)
58
+
59
+ @handler = Camayoc::Handlers::Memory.new(:max_events=>"0")
60
+ assert_equal(Camayoc::Handlers::Memory::DEFAULT_MAX_EVENTS,
61
+ @handler.max_events)
62
+
63
+ @handler = Camayoc::Handlers::Memory.new(:max_events=>"-1")
64
+ assert_equal(Camayoc::Handlers::Memory::DEFAULT_MAX_EVENTS,
65
+ @handler.max_events)
66
+
67
+ # valid value for good measure
68
+ @handler = Camayoc::Handlers::Memory.new(:max_events=>"1")
69
+ assert_equal(1,@handler.max_events)
70
+ end
71
+
72
+ def test_capped_fifo_generic_events
73
+ max_events = 10
74
+ @handler = Camayoc::Handlers::Memory.new(:max_events=>max_events)
75
+
76
+ overflow = 3
77
+ num_events = max_events + overflow
78
+
79
+ num_events.times do |idx|
80
+ @handler.event(Camayoc::StatEvent.new(:generic,
81
+ "foo:bar","beep",{:idx=>idx}))
82
+ end
83
+ beeps = @handler['foo:bar:beep']
84
+ assert_equal(max_events,beeps.size)
85
+ assert_equal({:idx=>overflow+max_events-1},beeps[0])
86
+ assert_equal({:idx=>overflow},beeps[-1])
87
+ end
88
+
89
+ end
@@ -7,7 +7,7 @@ if (begin; require 'camayoc/handlers/redis'; true; rescue LoadError; false end)
7
7
 
8
8
  def test_count_increments_correct_key_in_redis
9
9
  @redis.expects(:incrby).with("foo:bar:baz",500)
10
- @handler.count(Camayoc::StatEvent.new("foo:bar","baz",500))
10
+ @handler.event(Camayoc::StatEvent.new(:count,"foo:bar","baz",500))
11
11
  end
12
12
 
13
13
  def test_timing_updates_redis_keys_with_timing_info
@@ -17,12 +17,17 @@ if (begin; require 'camayoc/handlers/redis'; true; rescue LoadError; false end)
17
17
  @redis.expects(:incrby).with("foo:bar:time:_total",500).in_sequence(seq)
18
18
  @redis.expects(:incrby).with("foo:bar:time:_total",400).in_sequence(seq)
19
19
  @redis.expects(:incrby).with("foo:bar:time:_total",200).in_sequence(seq)
20
- @handler.timing(Camayoc::StatEvent.new("foo:bar","time",500))
21
- @handler.timing(Camayoc::StatEvent.new("foo:bar","time",400))
22
- @handler.timing(Camayoc::StatEvent.new("foo:bar","time",200))
20
+ @handler.event(Camayoc::StatEvent.new(:timing,"foo:bar","time",500))
21
+ @handler.event(Camayoc::StatEvent.new(:timing,"foo:bar","time",400))
22
+ @handler.event(Camayoc::StatEvent.new(:timing,"foo:bar","time",200))
23
+ end
24
+
25
+ def test_ignore_unknown_event_type
26
+ @redis.expects(:set).never
27
+ @handler.event(Camayoc::StatEvent.new(:throwaway,"foo:bar","time",500))
23
28
  end
24
29
 
25
30
  end
26
31
  else
27
32
  puts "Warn: Skipping Redis test because redis gem is not installed"
28
- end
33
+ end
@@ -1,17 +1,37 @@
1
1
  class StatsdTest < Test::Unit::TestCase
2
-
2
+
3
3
  def setup
4
4
  @statsd = Camayoc::Handlers::Statsd.new(:host=>"localhost",:port=>1234)
5
5
  end
6
-
6
+
7
7
  def test_count_sends_correct_statsd_message
8
8
  expect_message("foo.bar.baz:500|c")
9
- @statsd.count(Camayoc::StatEvent.new("foo:bar","baz",500,{}))
9
+ @statsd.event(Camayoc::StatEvent.new(:count,"foo:bar","baz",500,{}))
10
10
  end
11
11
 
12
12
  def test_timing_sends_correct_statsd_message
13
13
  expect_message("foo.bar.time:100|ms")
14
- @statsd.timing(Camayoc::StatEvent.new("foo:bar","time",100,{}))
14
+ @statsd.event(Camayoc::StatEvent.new(:timing,"foo:bar","time",100,{}))
15
+ end
16
+
17
+ def test_generic_sends_count_statsd_message
18
+ expect_message("foo.bar.beep:1|c")
19
+ @statsd.event(Camayoc::StatEvent.new(:count,"foo:bar","beep",1,{}))
20
+ end
21
+
22
+ def test_any_other_event_type_is_treated_as_a_count_with_value_if_value_is_integer
23
+ expect_message("foo.bar.beep:25|c")
24
+ @statsd.event(Camayoc::StatEvent.new(:foo,"foo:bar","beep",25,{}))
25
+ end
26
+
27
+ def test_any_other_event_type_is_treated_as_a_count_with_value_if_value_is_string_integer_representation
28
+ expect_message("foo.bar.beep:31|c")
29
+ @statsd.event(Camayoc::StatEvent.new(:foo,"foo:bar","beep","31",{}))
30
+ end
31
+
32
+ def test_any_other_event_type_is_treated_as_a_count_of_1_if_value_is_not_convertable_to_integer
33
+ expect_message("foo.bar.beep:1|c")
34
+ @statsd.event(Camayoc::StatEvent.new(:foo,"foo:bar","beep",{:a=>50},{}))
15
35
  end
16
36
 
17
37
  private
@@ -19,4 +39,8 @@ class StatsdTest < Test::Unit::TestCase
19
39
  @statsd.instance_variable_get("@socket").expects(:send).with(message,0,"localhost",1234)
20
40
  end
21
41
 
22
- end
42
+ def never_expect_message
43
+ @statsd.__send__(:socket).expects(:send).never
44
+ end
45
+
46
+ end
@@ -51,6 +51,18 @@ class RegistrationTest < Test::Unit::TestCase
51
51
  assert_equal([root,middle,child1,child2],all)
52
52
  end
53
53
 
54
+ def test_brackets_on_stats_gets_namespaced_descendant
55
+ parent = Camayoc["foo:bar"]
56
+ desc = parent["a:b:c"]
57
+ assert_equal(Camayoc.join(parent.name,"a:b:c"),desc.name)
58
+ assert_equal(parent,desc.parent)
59
+ end
60
+
61
+ def test_join_builds_name_with_delimiter
62
+ assert_equal("a:b:c",Camayoc.join("a","b","c"))
63
+ assert_equal("foo:bar:baz",Camayoc.join(%w(foo bar:baz)))
64
+ end
65
+
54
66
  def teardown
55
67
  Camayoc.instance_variable_get("@registry").clear
56
68
  end
@@ -1,8 +1,8 @@
1
1
  class StatsTest < Test::Unit::TestCase
2
2
 
3
3
  def test_ns_stat_uses_source_for_namespace
4
- event = Camayoc::StatEvent.new("foo:bar:baz","stat",10000,{})
4
+ event = Camayoc::StatEvent.new(:ignored,"foo:bar:baz","stat",10000,{})
5
5
  assert_equal("foo:bar:baz:stat",event.ns_stat)
6
6
  end
7
7
 
8
- end
8
+ end
@@ -1,35 +1,37 @@
1
1
  class StatsTest < Test::Unit::TestCase
2
2
 
3
+ include EventTestHelper
4
+
3
5
  def setup
4
6
  @stats = Camayoc::Stats.new("foo:bar")
5
7
  @handler = mock("handler1")
6
8
  @stats.add(@handler)
7
9
  end
8
10
 
9
- def test_count_fires_to_all_handlers
11
+ with_event_types("test_event_fires_to_all_handlers") do
10
12
  h2 = mock("handler2")
11
13
  @stats.add(h2)
12
-
13
- @handler.expects(:count).with(kind_of(Camayoc::StatEvent))
14
- h2.expects(:count).with(kind_of(Camayoc::StatEvent))
15
- @stats.count("count",500)
14
+
15
+ @handler.expects(:event).with(kind_of(Camayoc::StatEvent))
16
+ h2.expects(:event).with(kind_of(Camayoc::StatEvent))
17
+ @stats.send(@event_method,"beep",500)
16
18
  end
17
-
18
- def test_count_generates_correct_stat_event
19
- @handler.expects(:count).with(
20
- &stat_event_match("foo:bar","count",500,{:pass_through=>true}))
21
- @stats.count("count",500,:pass_through=>true)
19
+
20
+ with_event_types("test_generates_correct_stat_event") do
21
+ @handler.expects(:event).with(
22
+ &stat_event_match(@event_type,"foo:bar","beep",500,{:pass_through=>true}))
23
+ @stats.send(@event_method,"beep",500,:pass_through=>true)
22
24
  end
23
25
 
24
- def test_count_propagates_event_to_parent_after_firing_to_handlers
26
+ with_event_types("test_propagates_event_to_parent_after_firing_to_handlers") do
25
27
  @stats.parent = Camayoc::Stats.new("foo")
26
28
 
27
29
  seq = sequence("firing")
28
- evt = stat_event_match("foo:bar","count",100,{:pass_through=>true})
29
- @handler.expects(:count).with(&evt).in_sequence(seq)
30
- @stats.parent.expects(:count_event).with(&evt).in_sequence(seq)
31
-
32
- @stats.count("count",100,:pass_through=>true)
30
+ evt = stat_event_match(@event_type,"foo:bar","beep",100,{:pass_through=>true})
31
+ @handler.expects(:event).with(&evt).in_sequence(seq)
32
+ @stats.parent.expects(:propagate_event).with(&evt).in_sequence(seq)
33
+
34
+ @stats.send(@event_method,"beep",100,:pass_through=>true)
33
35
  end
34
36
 
35
37
  def test_increment_delegates_to_count
@@ -42,53 +44,46 @@ class StatsTest < Test::Unit::TestCase
42
44
  @stats.decrement("count")
43
45
  end
44
46
 
45
- def test_timing_fires_to_all_handlers
46
- h2 = mock("handler2")
47
- @stats.add(h2)
48
-
49
- @handler.expects(:timing).with(kind_of(Camayoc::StatEvent))
50
- h2.expects(:timing).with(kind_of(Camayoc::StatEvent))
51
- @stats.timing("time",500)
52
- end
47
+ def test_realtime_calculates_time_for_block_fires_timing_event_and_returns_time
48
+ start_time = Time.now
49
+ end_time = (Time.now + 10.5)
50
+ duration = end_time.to_f - start_time.to_f
51
+ duration_ms = (duration*1000).round
52
+
53
+ seq = sequence("duration")
54
+ Time.expects(:now).returns(start_time).in_sequence(seq)
55
+ Time.expects(:now).returns(end_time).in_sequence(seq)
53
56
 
54
- def test_timing_generates_correct_stat_event
55
- @handler.expects(:timing).with(
56
- &stat_event_match("foo:bar","time",1,{:pass_through=>true}))
57
- @stats.timing("time",1,:pass_through=>true)
57
+ @handler.expects(:event).with(
58
+ &stat_event_match(:timing,"foo:bar","baz",duration_ms,{:pass_through=>true}))
59
+
60
+ actual_duration = @stats.realtime("baz",:pass_through=>true) { "no-op" }
61
+ assert_equal(duration,actual_duration)
58
62
  end
59
63
 
60
- def test_timing_propagates_event_to_parent_after_firing_to_handlers
61
- @stats.parent = Camayoc::Stats.new("foo")
64
+ def test_benchmark_calls_realtime_and_returns_value_of_block
65
+ @stats.expects(:realtime).with("baz",:pass_through=>true).yields
62
66
 
63
- seq = sequence("firing")
64
- evt = stat_event_match("foo:bar","time",100,{:pass_through=>true})
65
- @handler.expects(:timing).with(&evt).in_sequence(seq)
66
- @stats.parent.expects(:timing_event).with(&evt).in_sequence(seq)
67
-
68
- @stats.timing("time",100,:pass_through=>true)
67
+ block_value = rand(10000)
68
+ result = @stats.benchmark("baz",:pass_through=>true) do
69
+ block_value
70
+ end
71
+
72
+ assert_equal(block_value,result)
69
73
  end
70
74
 
75
+
71
76
  def test_handler_errors_are_swallowed_and_firing_continues
72
77
  h2 = mock("handler2")
73
78
  @stats.add(h2)
74
79
 
75
80
  seq = sequence("firing")
76
- @handler.expects(:count).raises("FAIL").in_sequence(seq)
77
- h2.expects(:count).in_sequence(seq)
81
+ @handler.expects(:event).raises("FAIL").in_sequence(seq)
82
+ h2.expects(:event).in_sequence(seq)
78
83
 
79
84
  assert_nothing_raised do
80
85
  @stats.count("baz",100)
81
86
  end
82
87
  end
83
88
 
84
- private
85
- def stat_event_match(*args)
86
- template = Camayoc::StatEvent.new(*args)
87
- Proc.new do |event|
88
- event.source == template.source &&
89
- event.stat == template.stat &&
90
- event.value == template.value &&
91
- event.options == template.options
92
- end
93
- end
94
- end
89
+ end
@@ -3,4 +3,42 @@ require 'test/unit'
3
3
  require 'mocha'
4
4
 
5
5
  $: << File.join(File.dirname(__FILE__),"..","lib")
6
- require 'camayoc'
6
+ require 'camayoc'
7
+
8
+ module EventTestHelper
9
+
10
+ def self.included(test)
11
+ test.extend(ClassMethods)
12
+ end
13
+
14
+ module ClassMethods
15
+ # Generates methods and populates:
16
+ # * +@event_type+ :: +:count+, +:timing+ or +:generic+
17
+ # * +@event_method+ :: method for Stats:
18
+ # +:count+, +:timing+, or +:event+
19
+ def with_event_types(name,event_types=[:count,:timing,:generic],&block)
20
+ Array(event_types).each do |event_type|
21
+ define_method("#{name}_with_#{event_type}") do
22
+ @event_type = event_type
23
+ @event_method = case event_type
24
+ when :count, :timing then event_type
25
+ else :event
26
+ end
27
+ instance_eval(&block)
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ def stat_event_match(*args)
34
+ template = Camayoc::StatEvent.new(*args)
35
+ Proc.new do |event|
36
+ event.type == template.type &&
37
+ event.source == template.source &&
38
+ event.stat == template.stat &&
39
+ event.value == template.value &&
40
+ event.options == template.options
41
+ end
42
+ end
43
+
44
+ end
metadata CHANGED
@@ -1,21 +1,22 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: camayoc
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 0.1.0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Hayes Davis
14
+ - Jerry Chen
14
15
  autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2011-06-02 00:00:00 -07:00
19
+ date: 2011-11-19 00:00:00 -08:00
19
20
  default_executable:
20
21
  dependencies:
21
22
  - !ruby/object:Gem::Dependency
@@ -32,7 +33,7 @@ dependencies:
32
33
  version: "0"
33
34
  type: :development
34
35
  version_requirements: *id001
35
- description: " Inspired by logging frameworks, Camayoc makes it easy send stats and metrics \n from your application to collectors like Graphite (via statsd) or Redis. \n Extensible handlers mean you can use whatever storage system you like \n with the same interface.\n"
36
+ description: " Inspired by logging frameworks, Camayoc makes it easy to track events and \n send stats from your application to collectors like Graphite (via statsd). \n It has an extensible handler system that allows you to use whatever storage \n system you like with the same interface.\n"
36
37
  email: hayes@appozite.com
37
38
  executables: []
38
39
 
@@ -41,6 +42,7 @@ extensions: []
41
42
  extra_rdoc_files:
42
43
  - LICENSE
43
44
  - README.md
45
+ - HISTORY.md
44
46
  files:
45
47
  - README.md
46
48
  - LICENSE
@@ -54,6 +56,7 @@ files:
54
56
  - lib/camayoc/stat_event.rb
55
57
  - lib/camayoc/stats.rb
56
58
  - lib/camayoc/thread_safety.rb
59
+ - lib/camayoc/timer.rb
57
60
  - lib/camayoc/version.rb
58
61
  - lib/camayoc.rb
59
62
  - test/handlers/filter_test.rb
@@ -67,6 +70,7 @@ files:
67
70
  - test/stats_test.rb
68
71
  - test/test_helper.rb
69
72
  - test/thread_safety_test.rb
73
+ - HISTORY.md
70
74
  has_rdoc: true
71
75
  homepage: http://github.com/appozite/camayoc
72
76
  licenses: []