Skip to content
This repository was archived by the owner on Jan 2, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
source 'https://rubygems.org/'

gemspec
gemspec name: 'multimeter'
gemspec name: 'multimeter-http'

group :examples do
gem 'rack'
Expand Down
6 changes: 6 additions & 0 deletions ext/java/multimeter/Counter.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.javasupport.JavaUtil;

import static org.jruby.runtime.Visibility.PRIVATE;

Expand All @@ -30,6 +31,11 @@ public Counter(Ruby runtime, com.codahale.metrics.Counter counter) {
this.counter = counter;
}

@JRubyMethod(name="to_java")
public IRubyObject toJava(ThreadContext ctx) {
return JavaUtil.convertJavaToUsableRubyObject(ctx.runtime, counter);
}

@JRubyMethod
public IRubyObject count(ThreadContext ctx) {
return ctx.runtime.newFixnum(counter.getCount());
Expand Down
5 changes: 5 additions & 0 deletions ext/java/multimeter/Gauge.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ public Gauge(Ruby runtime, com.codahale.metrics.Gauge<? extends Object> gauge) {
this.gauge = gauge;
}

@JRubyMethod(name="to_java")
public IRubyObject toJava(ThreadContext ctx) {
return JavaUtil.convertJavaToUsableRubyObject(ctx.runtime, gauge);
}

@JRubyMethod
public IRubyObject value(ThreadContext ctx) {
Object value = gauge.getValue();
Expand Down
6 changes: 6 additions & 0 deletions ext/java/multimeter/Histogram.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.javasupport.JavaUtil;

import static org.jruby.runtime.Visibility.PRIVATE;

Expand All @@ -30,6 +31,11 @@ public Histogram(Ruby runtime, com.codahale.metrics.Histogram histogram) {
this.histogram = histogram;
}

@JRubyMethod(name="to_java")
public IRubyObject toJava(ThreadContext ctx) {
return JavaUtil.convertJavaToUsableRubyObject(ctx.runtime, histogram);
}

@JRubyMethod
public IRubyObject count(ThreadContext ctx) {
return ctx.runtime.newFixnum(histogram.getCount());
Expand Down
6 changes: 6 additions & 0 deletions ext/java/multimeter/Meter.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.javasupport.JavaUtil;

import static org.jruby.runtime.Visibility.PRIVATE;

Expand All @@ -30,6 +31,11 @@ public Meter(Ruby runtime, com.codahale.metrics.Meter meter) {
this.meter = meter;
}

@JRubyMethod(name="to_java")
public IRubyObject toJava(ThreadContext ctx) {
return JavaUtil.convertJavaToUsableRubyObject(ctx.runtime, meter);
}

@JRubyMethod
public IRubyObject count(ThreadContext ctx) {
return ctx.runtime.newFixnum(meter.getCount());
Expand Down
6 changes: 6 additions & 0 deletions ext/java/multimeter/Timer.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.javasupport.JavaUtil;

import static org.jruby.runtime.Visibility.PRIVATE;

Expand All @@ -35,6 +36,11 @@ public Timer(Ruby runtime, com.codahale.metrics.Timer timer) {
this.timer = timer;
}

@JRubyMethod(name="to_java")
public IRubyObject toJava(ThreadContext ctx) {
return JavaUtil.convertJavaToUsableRubyObject(ctx.runtime, timer);
}

@JRubyMethod
public IRubyObject count(ThreadContext ctx) {
return ctx.runtime.newFixnum(timer.getCount());
Expand Down
119 changes: 18 additions & 101 deletions lib/multimeter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,91 +3,55 @@
require 'metrics-core-jars'
require 'multimeter_metrics'
require 'json'
require 'multimeter/rack'
require 'multimeter/json'

module Metrics
include_package 'com.codahale.metrics'
end

module Multimeter
extend Rack

class MetricRegistry
def to_h
h = {}
metrics.each do |metric_name, metric|
h[metric_name] = metric.to_h
end
h
def to_json
Json.dump(self)
end
end

class Meter
def to_h
{
:type => :meter,
:count => count,
:mean_rate => mean_rate,
:one_minute_rate => one_minute_rate,
:five_minute_rate => five_minute_rate,
:fifteen_minute_rate => fifteen_minute_rate
}
def to_json
Json.dump(self)
end
end

class Counter
def to_h
{
:type => :counter,
:count => count
}
def to_json
Json.dump(self)
end
end

class Histogram
def to_h
{
:type => :histogram,
:count => count,
}.merge(snapshot.to_h(NANO_TO_MILLI_SCALE))
def to_json
Json.dump(self)
end
end

class Timer
def to_h
{
:type => :timer,
:count => count,
:mean_rate => mean_rate,
:one_minute_rate => one_minute_rate,
:five_minute_rate => five_minute_rate,
:fifteen_minute_rate => fifteen_minute_rate,
}.merge(snapshot.to_h(NANO_TO_MILLI_SCALE))
def to_json
Json.dump(self)
end
end

class Snapshot
def to_h(scale=1)
{
:max => max * scale,
:min => min * scale,
:mean => mean * scale,
:std_dev => std_dev * scale,
:median => median * scale,
:percentiles => {
'75' => p75 * scale,
'95' => p95 * scale,
'98' => p98 * scale,
'99' => p99 * scale,
'99.9' => p999 * scale,
}
}
def to_json
Json.dump(self)
end
end

class Gauge
def to_h
{
:type => :gauge,
:value => value,
}
def to_json
Json.dump(self)
end
end

Expand All @@ -98,51 +62,4 @@ def self.create_registry
def self.jmx(registry, options = {})
Metrics::JmxReporter.forRegistry(registry.to_java).inDomain(options[:domain] || 'multimeter').build.tap(&:start)
end

def self.http(registry, rack_handler, options={})
server_thread = Java::JavaLang::Thread.new do
rack_handler.run(Http.create_app(registry), options)
end
server_thread.daemon = true
server_thread.name = 'multimeter-http-server'
server_thread.start
server_thread
end

private

NANO_TO_MILLI_SCALE = 1.0/1_000_000

module Http
class BadRequest < StandardError; end

COMMON_HEADERS = {'Connection' => 'close'}.freeze
JSON_HEADERS = COMMON_HEADERS.merge('Content-Type' => 'application/json').freeze
JSONP_HEADERS = COMMON_HEADERS.merge('Content-Type' => 'application/javascript').freeze
ERROR_HEADERS = COMMON_HEADERS.merge('Content-Type' => 'text/plain').freeze

def self.create_app(registry)
proc do |env|
begin
body = registry.to_h.to_json
headers = JSON_HEADERS
if (callback_name = env['QUERY_STRING'][/callback=([^$&]+)/, 1])
if callback_name =~ /^[\w\d.]+$/
body = "#{callback_name}(#{body});"
headers = JSONP_HEADERS
else
raise BadRequest
end
else
headers = headers.merge('Access-Control-Allow-Origin' => '*')
end
[200, headers, [body]]
rescue BadRequest => e
[400, ERROR_HEADERS, ['Bad Request']]
rescue => e
[500, ERROR_HEADERS, ["Internal Server Error\n\n", e.message, "\n\t", *e.backtrace.join("\n\t")]]
end
end
end
end
end
58 changes: 58 additions & 0 deletions lib/multimeter/http.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# encoding: utf-8

require 'multimeter'
require 'metrics-servlets-jars'
require 'rjack-jetty'

module Metrics
module Servlets
include_package 'com.codahale.metrics.servlets'
end
end

module Jetty
include_package 'org.eclipse.jetty.server'
include_package 'org.eclipse.jetty.servlet'
end

module Multimeter
module Http
def http(registry, options={})
server = Jetty::Server.new(options[:port] || 5747)
server.handler = create_servlet_context(registry)
Server.new(server)
end

private

def create_servlet_context(registry)
context = Jetty::ServletContextHandler.new(Jetty::ServletContextHandler::SESSIONS)
context.context_path = '/'
context.set_attribute(Metrics::Servlets::MetricsServlet::METRICS_REGISTRY, registry.to_java);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stray ;

context.add_servlet(Metrics::Servlets::MetricsServlet.java_class, '/*')
context
end

class Server
def initialize(server)
@server = server
end

def start
@server.start
self
end

def stop
@server.stop
self
end

def join
@server.join
end
end
end

extend Http
end
39 changes: 39 additions & 0 deletions lib/multimeter/json.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# encoding: utf-8

require 'metrics-json-jars'

module Metrics
module Json
include_package 'com.codahale.metrics.json'
end
end

module Jackson
module Databind
include_package 'com.fasterxml.jackson.databind'
end
end

module Multimeter
class Json
def initialize
@object_mapper = Jackson::Databind::ObjectMapper.new
end

def setup
metrics_module = Metrics::Json::MetricsModule.new(rate_unit = Java::JavaUtilConcurrent::TimeUnit::SECONDS, duration_unit = Java::JavaUtilConcurrent::TimeUnit::MILLISECONDS, show_samples = false)
@object_mapper.register_module(metrics_module)
self
end

def dump(metric)
stream = Java::JavaIo::ByteArrayOutputStream.new
@object_mapper.write_value(stream, metric.to_java)
String.from_java_bytes(stream.to_byte_array)
end

def self.dump(metric)
new.setup.dump(metric)
end
end
end
Loading