Coder Social home page Coder Social logo

riemann-ruby-client's Introduction

Riemann Ruby Client

CI

Installing

gem install riemann-client

Use

require 'riemann/client'

# Create a client. Host, port and timeout are optional.
c = Riemann::Client.new host: 'localhost', port: 5555, timeout: 5

# Send a simple event
c << {service: 'testing', metric: 2.5}

# Or a more complex one
c << {
  host: 'web3',
  service: 'api latency',
  state: 'warn',
  metric: 63.5,
  description: "63.5 milliseconds per request",
  time: Time.now.to_i - 10
}

# :host defaults to gethostname(). :time defaults to current unix time. You
# can explicitly override host...

c << {host: nil, service: 'the cloud', state: 'nebulous'}

# Get all the states from the server
c['true']

# Or specific states matching a query
c['host =~ "%.dc1" and (state = "critical" or state = "warning")']

Transports

Riemann::Client sends small events over UDP by default, and uses TCP for queries and large events. UDP sends are essentially "shouting into the void". They will not block your application and are roughly an order of magnitude faster than TCP, but you will not know if the server is down or encountered an error. You can specify what transport to use by selecting a subclient:

c.udp << { :state => "ok" } # => nil
c.tcp << { :state => "ok" } # => #<Message ...>
c.tcp["true"]            # => [#<Event ... >, ...]
c.udp["true"]            # => raise Riemann::Client::Unsupported

Client state management

Riemann::Client provides some classes to make managing state updates easier.

Riemann::MetricThread starts a thread to poll a metric periodically, which can be used to flush an accumulated value to ustate at regular intervals.

Riemann::AutoState bundles a state and a client together. Any changes to the AutoState automatically send the new state to the client.

License

The MIT License

Copyright (c) 2011-2024 Kyle Kingsbury

riemann-ruby-client's People

Contributors

agile avatar aphyr avatar b avatar dch avatar dependabot[bot] avatar eric avatar jamtur01 avatar jegt avatar lafka avatar nukemberg avatar rkelln avatar smortex avatar squarism avatar vadv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

riemann-ruby-client's Issues

How to format emails?

Currently, my emails are formated like this:
#riemann.codec.Event{:host "foo", :service "bar", :state "critical", :description "{\"exception\":\"some error\",\"datetime\":\"20210104061928\"...", :tags ["tag-1"]}

You can notice that the description is a JSON object, am unable to beautify its contents from the email. Is there a way I can format the emails in a better way so that it's easily readable?

Possibly flakey test

https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true

[69](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:70)
  - should raise Riemann::Client::Unsupported exception on query
[70](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:71)
[71](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:72)
RuntimeError: wait_for condition never realized
[72](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:73)
	spec/client.rb:35:in `wait_for': Riemann::Client (UDP transport) - should send a state without time nor time_micros
[73](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:74)
	spec/client.rb:155:in `block (2 levels) in <top (required)>'
[74](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:75)
	spec/client.rb:149:in `block in <top (required)>'
[75](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:76)
	spec/client.rb:334:in `block in <top (required)>'
[76](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:77)
	spec/client.rb:328:in `<top (required)>'
[77](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:78)
	/opt/hostedtoolcache/Ruby/3.1.2/x64/lib/ruby/gems/3.1.0/gems/bundler-2.3.16/lib/bundler/cli/exec.rb:58:in `load'
[78](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:79)
	/opt/hostedtoolcache/Ruby/3.1.2/x64/lib/ruby/gems/3.1.0/gems/bundler-2.3.16/lib/bundler/cli/exec.rb:58:in `kernel_load'
[79](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:80)
	/opt/hostedtoolcache/Ruby/3.1.2/x64/lib/ruby/gems/3.1.0/gems/bundler-2.3.16/lib/bundler/cli/exec.rb:23:in `run'
[80](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:81)
	/opt/hostedtoolcache/Ruby/3.1.2/x64/lib/ruby/gems/3.1.0/gems/bundler-2.3.16/lib/bundler/cli.rb:479:in `exec'
[81](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:82)
	/opt/hostedtoolcache/Ruby/3.1.2/x64/lib/ruby/gems/3.1.0/gems/bundler-2.3.16/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
[82](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:83)
	/opt/hostedtoolcache/Ruby/3.1.2/x64/lib/ruby/gems/3.1.0/gems/bundler-2.3.16/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
[83](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:84)
	/opt/hostedtoolcache/Ruby/3.1.2/x64/lib/ruby/gems/3.1.0/gems/bundler-2.3.16/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
[84](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:85)
	/opt/hostedtoolcache/Ruby/3.1.2/x64/lib/ruby/gems/3.1.0/gems/bundler-2.3.16/lib/bundler/cli.rb:31:in `dispatch'
[85](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:86)
	/opt/hostedtoolcache/Ruby/3.1.2/x64/lib/ruby/gems/3.1.0/gems/bundler-2.3.16/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
[86](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:87)
	/opt/hostedtoolcache/Ruby/3.1.2/x64/lib/ruby/gems/3.1.0/gems/bundler-2.3.16/lib/bundler/cli.rb:25:in `start'
[87](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:88)
	/opt/hostedtoolcache/Ruby/3.1.2/x64/lib/ruby/gems/3.1.0/gems/bundler-2.3.16/exe/bundle:48:in `block in <top (required)>'
[88](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:89)
	/opt/hostedtoolcache/Ruby/3.1.2/x64/lib/ruby/gems/3.1.0/gems/bundler-2.3.16/lib/bundler/friendly_errors.rb:117:in `with_friendly_errors'
[89](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:90)
	/opt/hostedtoolcache/Ruby/3.1.2/x64/lib/ruby/gems/3.1.0/gems/bundler-2.3.16/exe/bundle:36:in `<top (required)>'
[90](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:91)
	/opt/hostedtoolcache/Ruby/3.1.2/x64/bin/bundle:25:in `load'
[91](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:92)
	/opt/hostedtoolcache/Ruby/3.1.2/x64/bin/bundle:25:in `<main>'
[92](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:93)
[93](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:94)
49 specifications (107 requirements), 0 failures, 1 errors
[94](https://github.com/riemann/riemann-ruby-client/runs/7054304294?check_suite_focus=true#step:5:95)
Error: Process completed with exit code 1.

ip6 support

The current client explicitly uses AF_INET and therefor riemann-tools and similar would not accept raw ip6 addresses or hostnames with no ip4 addresses.

I'v made a preliminary patch at lafka@7903811, but as I have no knowledge of Ruby or the reason why AF_INET was set explicitly some feedback would be great before i make a pull request!

Support micro-seconds resolution

Riemann has supported microsecond resolution since 0.2.13

Added support of time in microsecond resolution in the Riemann
protocol (See time_micros in the Riemann client. If you maintain a Riemann client should update them to support microseconds.

I'm not sure how complicated adding this is, but I think it's a prerequisite for adding support for ms resolution in the logstash output plugin. logstash-plugins/logstash-output-riemann#19

Error in the HOWTO

Reading the readme, the suggested usage is:

# Or a more complex one
c << {
  host: 'web3',
  service: 'api latency',
  state: 'warn',
  metric: 63.5
  description: "63.5 milliseconds per request"
  time: Time.now.to_i - 10
}

But this produces a syntax error for me in ruby 1.8.7:

x.rb:21: odd number list for Hash
  host: 'web3',

Using the code from this modules test suite works as expected:

c << {
  :service     => 'testing',
  :metric      => 42,
  :state       => 'foo',
  :tags        => ['tag', 'another_tag'],
  :description => 'service event description',
}

Rubinius error or UDP issue

I was getting an odd error using rubinius 2.2.5 and riemann-ruby-client when I started digging into it there may be an error in the UDP code.

At first the error was:

    NoMethodError: undefined method `bytesize' on an instance of Beefcake::Buffer.
    kernel/delta/kernel.rb:78:in `bytesize (method_missing)'
    /home/user/.rvm/rubies/rbx-2.2.5/gems/gems/rubysl-socket-2.0.1/lib/rubysl/socket.rb:1330:in `send'

but looking at the UDP code and how Beefcake works it looks like it is sending the Beefcake Buffer to send rather than the encoded string. From the Beefcake docs:

# For example, you can encode into a String:
s = ""
x.encode(s)
s # => "\b\x01\x10\x02)\0"

# If you don't encode into anything, a new Beefcake::Buffer will be returned:
x.encode # => #<Beefcake::Buffer:0x007fbfe1867ab0 @buf="\b\x01\x10\x02)\0">

# And that buffer can be converted to a String:
x.encode.to_s # => "\b\x01\x10\x02)\0"

Leading me to believe that what we actually want is this:

require 'riemann/client'

module Riemann
  class Client
    class UDP < Client

      def send_maybe_recv(message)
        with_connection do |s|
          encoded_string = ''
          message.encode encoded_string
          unless encoded_string.length < @max_size
            raise TooBig
          end

          s.send(encoded_string, 0, @host, @port)
          nil
        end
      end
    end
  end
end

r = Riemann::Client.new
# require 'rubinius/debugger'
# Rubinius::Debugger.start
# b Riemann::Client::UDP#send_maybe_recv:1
# b UDPSocket#send:1
r << { service: 'testing', metric: 1.0, tags: ['test', 'the', 'client'] }

Which versions of Ruby?

The Riemann Quickstart refers to Ruby 1.9.3.

I've got 2.3.1 installed on my Mac, and the Quickstart example for using riemann-client is doing this:

> irb -r riemann/client
irb(main):001:0>  r = Riemann::Client.new
=> #<Riemann::Client:0x007fab4387bdb0 @options={:host=>"127.0.0.1", :port=>5555, :timeout=>5}, @udp=#<Riemann::Client::UDP:0x007fab4387bd10 @host="127.0.0.1", @port=5555, @max_size=16384>, @tcp=#<Riemann::Client::TCP:0x007fab4387bcc0 @options={:host=>"127.0.0.1", :port=>5555, :timeout=>5}, @locket=#<Monitor:0x007fab4387bc98 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Thread::Mutex:0x007fab4387bbf8>>>>
irb(main):002:0> r << {
irb(main):003:1* host: "www1",
irb(main):004:1* service: "http req",
irb(main):005:1* metric: 2.53,
irb(main):006:1* state: "critical",
irb(main):007:1* description: "Request took 2.53 seconds.",
irb(main):008:1* tags: ["http"]
irb(main):009:1> }
=> nil
irb(main):010:0>  r['service =~ "http%"']
=> []

Protobuf serialization in Ruby very expensive

Hey Kyle,

@justinsteffy and I have been hitting performance snags doing 50-100 serializations during the request response cycle. We've identified that most of the time is spent in the beefcake library doing protobuf serialization. Have you had any issues with this?

r = Riemann::Client.new
# => #<Riemann::Client:0x00000001fc3040 @host="127.0.0.1", @port=5555, @timeout=5, @udp=#<Riemann::Client::UDP:0x00000001fc2fc8 @host="127.0.0.1", @port=5555, @max_size=16384, @locket=#<Mutex:0x00000001fcafc0>>, @tcp=#<Riemann::Client::TCP:0x00000001fcaf98 @host="127.0.0.1", @port=5555, @timeout=5, @locket=#<Mutex:0x00000001fcaf70>>>
r << { service: 'testing', metric: 1.0, tags: ['test', 'the', 'client'] }
# => nil
require 'benchmark'
# => true
Benchmark.measure do
  1000.times do
    r << { service: 'testing', metric: 1.0, tags: ['test', 'the', 'client'] }
  end
end
=>   0.120000   0.060000   0.180000 (  0.185700)

SSL/TLS support

Initial implementation here - not very happy about it because some openssl specific constants are in lib/riemann/client/tcp_socket.rb here and here
Another issue is that the current interface of the client uses the same port for UDP and TCP which is inconvenient for TLS (most people bind on port 5554). I'm guessing people who use TLS probably don't want non-encrypted connections and will avoid UDP entirely.

Usage example:

c = Riemann::Client.new(ssl: true, key_file: "riemann_server.key", cert_file: "riemann_server.crt", port: 5554) 
c.query("true")
c.tcp << {host: "hlkhlkj", service: "test service", state: "ok", description: "test", metric: 1.222}

cc @jamtur01

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.