ostrich-jruby 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a5501e591147820c321e0b7e44c807f431664f66
4
+ data.tar.gz: 76fabcc57352345790b7e6b5ac9a265ac08f85fa
5
+ SHA512:
6
+ metadata.gz: 5365b0eb50c41dd1e13063191f919a8c2774ad7719ca63a99a82e5dfdd9fadd5e8ecd25ad54d1548cea8d82a8b618c6b7653d543fdcaefee72191fe9b4ec450b
7
+ data.tar.gz: 3db43bca39f2197d98dd1d3669f56a7b01fcf9c3b644626e5c04e2b3744b6698f57e17619621a15b9189acf90bbd674d566cf78f661d29eeb1ee5b6d4f900f3c
data/Gemfile ADDED
@@ -0,0 +1,23 @@
1
+ source "http://gems.local.twitter.com"
2
+
3
+ group :development, :test do
4
+ gem "rake"
5
+ gem "jbundler"
6
+
7
+ # necessary for development because jbundler
8
+ # doesn't bootstrap our environment properly
9
+ load 'ostrich-jruby.gemspec'
10
+
11
+ require 'jbundler/classpath_file'
12
+ JBundler::ClasspathFile.new.require_classpath
13
+
14
+ require 'ostrich-jruby'
15
+ end
16
+
17
+ group :test do
18
+ gem 'rspec', '~> 2.11.0'
19
+ gem 'rr', '~> 1.0.4'
20
+ gem 'grape', '~> 0.11.0'
21
+ gem 'json'
22
+ gem 'rack-test'
23
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
4
+
5
+ require 'bundler'
6
+ require 'digest'
7
+
8
+ require 'rubygems/package_task'
9
+ require 'rspec/core/rake_task'
10
+
11
+ Bundler::GemHelper.install_tasks
12
+
13
+ task :default => :spec
14
+
15
+ desc 'Run specs'
16
+ RSpec::Core::RakeTask.new do |t|
17
+ t.pattern = './spec/**/*_spec.rb'
18
+ end
@@ -0,0 +1,12 @@
1
+ module Ostrich
2
+ autoload :Stats, "ostrich-jruby/stats"
3
+ autoload :CommandHandler, "ostrich-jruby/command_handler"
4
+ autoload :GrapeEndpoint, "ostrich-jruby/grape_endpoint"
5
+ end
6
+
7
+ require "java"
8
+ require "ostrich-jruby/util"
9
+
10
+ require "ostrich-jruby/ext/hash"
11
+ require "ostrich-jruby/scala/functions"
12
+ require "ostrich-jruby/scala/kernel"
@@ -0,0 +1,41 @@
1
+ # https://github.com/twitter/ostrich/blob/master/src/main/scala/com/twitter/ostrich/admin/CommandHandler.scala
2
+ module Ostrich
3
+ class CommandHandler
4
+
5
+ attr_reader :handler
6
+
7
+ DEFAULT_MIN_DURATION = Util::Duration.from_seconds(60)
8
+
9
+ def initialize(stats_collection, min_period = DEFAULT_MIN_DURATION)
10
+ @handler = handler_class.new(nil, stats_collection, min_period)
11
+ end
12
+
13
+ %w(ping stats).each do |command|
14
+ define_method(command.to_sym) do |parameters = {}, format = :json|
15
+ execute(command.to_s, parameters, format)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def execute(command, parameters, format)
22
+ handler.apply(command, parameters.to_scala, format_obj_for(format))
23
+ end
24
+
25
+ def handler_class
26
+ com.twitter.ostrich.admin.CommandHandler
27
+ end
28
+
29
+ def format_obj_for(symbol)
30
+ java_sym = case symbol
31
+ when :txt then :PlainText
32
+ when :json then :Json
33
+ else
34
+ raise "Invalid format"
35
+ end
36
+
37
+ companion(com.twitter.ostrich.admin, :Format, java_sym)
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,9 @@
1
+ class Hash
2
+ def to_scala
3
+ Java::Scala.collection.mutable::HashMap.new.tap do |map|
4
+ each_pair do |key, val|
5
+ map.put(key, val)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,22 @@
1
+ require 'grape'
2
+
3
+ module Ostrich
4
+ class GrapeEndpoint < Grape::API
5
+
6
+ # let Ostrich handle the formatting for json (just return the string)
7
+ content_type :json, "application/json"
8
+ formatter :json, lambda { |object, env| object }
9
+
10
+ default_format :json
11
+
12
+ desc "Get stats from ostrich." do
13
+ named: 'stats'
14
+ end
15
+
16
+ get :stats do
17
+ handler = Ostrich::CommandHandler.new(Ostrich::Stats.collection)
18
+ handler.stats(params, params[:format].to_sym)
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ module Scala
2
+ class Function
3
+ attr_reader :proc
4
+
5
+ def initialize(proc)
6
+ @proc = proc
7
+ end
8
+
9
+ def method_missing(method, *args, &block)
10
+ # This is necessary for Scala's "specialization" feature,
11
+ # which will call `apply$mcD$sp` if it wants a double, for example.
12
+ if method.to_s =~ /\Aapply/
13
+ proc.call(*args, &block)
14
+ end
15
+ end
16
+ end
17
+
18
+ class Function0 < Function
19
+ include Java::Scala.Function0
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ module Kernel
2
+ def companion(klass, *names)
3
+ singleton = klass.const_get(:"#{names.join("$")}$")
4
+ field = singleton.java_class.field(:"MODULE$")
5
+ field.value(singleton)
6
+ end
7
+ end
@@ -0,0 +1,43 @@
1
+ # https://github.com/twitter/ostrich/blob/master/src/main/scala/com/twitter/ostrich/stats/Stats.scala
2
+ # https://github.com/twitter/ostrich/blob/master/src/main/scala/com/twitter/ostrich/stats/StatsCollection.scala
3
+ # https://github.com/twitter/ostrich/blob/master/src/main/scala/com/twitter/ostrich/stats/StatsProvider.scala
4
+ module Ostrich
5
+ class Stats
6
+ class << self
7
+
8
+ def incr(name, amount = 1)
9
+ collection.incr(name, amount)
10
+ end
11
+
12
+ def get_counter(name)
13
+ collection.getCounter(name)
14
+ end
15
+
16
+ def add_gauge(name, &block)
17
+ proc = Scala::Function0.new(block)
18
+ collection.addGauge(name, proc)
19
+ end
20
+
21
+ def get_gauge(name)
22
+ collection.getGauge(name)
23
+ end
24
+
25
+ def add_metric(name, value)
26
+ collection.addMetric(name, value)
27
+ end
28
+
29
+ def get_metric(name)
30
+ collection.getMetric(name)
31
+ end
32
+
33
+ def clear_all
34
+ collection.clearAll
35
+ end
36
+
37
+ def collection
38
+ companion(com.twitter.ostrich.stats, :Stats)
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,3 @@
1
+ module Util
2
+ autoload :Duration, "ostrich-jruby/util/duration"
3
+ end
@@ -0,0 +1,18 @@
1
+ # https://github.com/twitter/util/blob/master/util-core/src/main/scala/com/twitter/util/Duration.scala
2
+ module Util
3
+ class Duration
4
+ class << self
5
+
6
+ def from_seconds(seconds)
7
+ duration.fromSeconds(seconds)
8
+ end
9
+
10
+ private
11
+
12
+ def duration
13
+ companion(com.twitter.util, :Duration)
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module Ostrich
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: UTF-8
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), 'lib')
4
+ require 'ostrich-jruby/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "ostrich-jruby"
8
+ s.version = '2.0.1'
9
+ s.authors = ["Cameron Dutro"]
10
+ s.email = ["cdutro@twitter.com"]
11
+ s.homepage = ""
12
+
13
+ s.description = s.summary = "Ruby wrapper around the stats collector & reporter for Scala servers"
14
+
15
+ s.platform = Gem::Platform::RUBY
16
+ s.has_rdoc = true
17
+
18
+ s.requirements << "jar 'com.twitter:ostrich', '9.2.0'"
19
+ s.require_path = 'lib'
20
+
21
+ s.files = Dir["{lib,spec}/**/*", "Gemfile", "History.txt", "LICENSE", "README.md", "Rakefile", "ostrich-jruby.gemspec"]
22
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Ostrich::CommandHandler do
6
+ let(:handler) { Ostrich::CommandHandler.new(Ostrich::Stats.collection) }
7
+
8
+ describe "#ping" do
9
+ it "should return 'pong'" do
10
+ JSON.parse(handler.ping).should == { "response" => "pong" }
11
+ end
12
+ end
13
+
14
+ describe "#stats" do
15
+ def get_stats(params)
16
+ handler.stats({}, params[:format])
17
+ end
18
+
19
+ it_behaves_like "a stats reporter"
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Hash do
6
+ describe "#to_scala" do
7
+ let(:hash) do
8
+ { "a" => "b", "c" => "d" }
9
+ end
10
+
11
+ it "should convert the ruby hash into a mutable scala hashmap" do
12
+ hash.to_scala.tap do |hash_map|
13
+ hash_map.should be_a(Java::Scala.collection.mutable::HashMap)
14
+ hash_map.get("a").get.should == "b"
15
+ hash_map.get("c").get.should == "d"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Ostrich::GrapeEndpoint do
6
+ include Rack::Test::Methods
7
+
8
+ def app
9
+ Ostrich::GrapeEndpoint
10
+ end
11
+
12
+ describe "#stats" do
13
+ def get_stats(params)
14
+ get "stats.#{params[:format]}"
15
+ last_response.body
16
+ end
17
+
18
+ it_behaves_like "a stats reporter"
19
+ end
20
+ end
@@ -0,0 +1,49 @@
1
+ # encoding: UTF-8
2
+
3
+ require "rspec"
4
+ require "ostrich-jruby"
5
+ require 'rack/test'
6
+ require 'json'
7
+ require 'yaml'
8
+
9
+ RSpec.configure do |config|
10
+ config.mock_with(:rr)
11
+
12
+ config.before(:each) do
13
+ Ostrich::Stats.clear_all
14
+ end
15
+
16
+ shared_examples "a stats reporter" do
17
+ it "should report basic JVM stats in json format" do
18
+ results = JSON.parse(get_stats(format: :json))
19
+ results["gauges"].should include("jvm_heap_committed")
20
+ results["counters"].should include("jvm_gc_msec")
21
+ end
22
+
23
+ # NOTE: the txt format just so happens to be yaml
24
+ it "should report basic JVM stats in txt format" do
25
+ results = YAML.load(get_stats(format: :txt))
26
+ results["gauges"].should include("jvm_heap_committed")
27
+ results["counters"].should include("jvm_gc_msec")
28
+ end
29
+
30
+ context "with some statsy things" do
31
+ before(:each) do
32
+ Ostrich::Stats.incr("foo", 2)
33
+ Ostrich::Stats.add_gauge("bar") { 4 + 1 }
34
+ end
35
+
36
+ it "should report custom counters and gauges in json format" do
37
+ results = JSON.parse(get_stats(format: :json))
38
+ results["counters"]["foo"].should == 2
39
+ results["gauges"]["bar"].should == 5
40
+ end
41
+
42
+ it "should report custom counters and gauges in txt format" do
43
+ results = YAML.load(get_stats(format: :txt))
44
+ results["counters"]["foo"].should == 2
45
+ results["gauges"]["bar"].should == 5
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Ostrich::Stats do
6
+ let(:stats) { Ostrich::Stats }
7
+
8
+ describe "#incr" do
9
+ it "should increment the stat" do
10
+ stats.incr("blarg").should == 1
11
+ stats.incr("blarg", 2).should == 3
12
+ stats.get_counter("blarg").apply.should == 3
13
+ end
14
+ end
15
+
16
+ describe "#add_gauge" do
17
+ it "should add a gauge with a block" do
18
+ stats.add_gauge("foobar") { 10.2 }
19
+ stats.get_gauge("foobar").get.should == 10.2
20
+ end
21
+ end
22
+
23
+ describe "#add_metric" do
24
+ it "should add a metric" do
25
+ stats.add_metric("teapot", 14.1)
26
+ stats.get_metric("teapot").should be_a(com.twitter.ostrich.stats.Metric)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Util::Duration do
6
+ describe "#from_seconds" do
7
+ it "should return a Duration object with the correct length of time" do
8
+ Util::Duration.from_seconds(60).tap do |duration|
9
+ duration.should be_a(com.twitter.util.Duration)
10
+ duration.inNanoseconds.should == 60_000_000_000
11
+ end
12
+ end
13
+ end
14
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ostrich-jruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Cameron Dutro
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-14 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Ruby wrapper around the stats collector & reporter for Scala servers
14
+ email:
15
+ - cdutro@twitter.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - Gemfile
21
+ - Rakefile
22
+ - lib/ostrich-jruby.rb
23
+ - lib/ostrich-jruby/command_handler.rb
24
+ - lib/ostrich-jruby/ext/hash.rb
25
+ - lib/ostrich-jruby/grape_endpoint.rb
26
+ - lib/ostrich-jruby/scala/functions.rb
27
+ - lib/ostrich-jruby/scala/kernel.rb
28
+ - lib/ostrich-jruby/stats.rb
29
+ - lib/ostrich-jruby/util.rb
30
+ - lib/ostrich-jruby/util/duration.rb
31
+ - lib/ostrich-jruby/version.rb
32
+ - ostrich-jruby.gemspec
33
+ - spec/command_handler_spec.rb
34
+ - spec/ext/hash_spec.rb
35
+ - spec/grape_endpoint_spec.rb
36
+ - spec/spec_helper.rb
37
+ - spec/stats_spec.rb
38
+ - spec/util/duration_spec.rb
39
+ homepage: ''
40
+ licenses: []
41
+ metadata: {}
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements:
57
+ - jar 'com.twitter:ostrich', '9.2.0'
58
+ rubyforge_project:
59
+ rubygems_version: 2.4.3
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Ruby wrapper around the stats collector & reporter for Scala servers
63
+ test_files: []
64
+ has_rdoc: true