linr 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bcef053de65df1f4d261265f2bda9580f189d1a4
4
+ data.tar.gz: 266287b7ecdf66623a5eb8604b504778a776ea98
5
+ SHA512:
6
+ metadata.gz: d8f00681cb50cad889a4d2e72f176ab91ca951672f175432d75de041d54cbddd7ef8d2c1c70f5577f351a8e3d696ed6d9d9c652437aab4d6195161776d29250a
7
+ data.tar.gz: b23d48e01425fadb19117929e12ca9e0c71a3a6804634e3d800bf687f83a1e451bb66ce62776a8057d95232fe0705be671d0305e6928442170f929dbffeec687
@@ -0,0 +1,38 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /vendor/bundle
26
+ /lib/bundler/man/
27
+
28
+ # for a library or gem, you might want to ignore these files since the code is
29
+ # intended to run in multiple environments; otherwise, check them in:
30
+ # Gemfile.lock
31
+ # .ruby-version
32
+ # .ruby-gemset
33
+
34
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
35
+ .rvmrc
36
+
37
+ # Allow fresh games
38
+ Gemfile.lock
@@ -0,0 +1,9 @@
1
+ Style/StringLiterals:
2
+ EnforcedStyle: double_quotes
3
+
4
+ Style/Documentation:
5
+ Enabled: false
6
+
7
+ Metrics/MethodLength:
8
+ Exclude:
9
+ - "test/**/*"
@@ -0,0 +1 @@
1
+ linr
@@ -0,0 +1 @@
1
+ 2.2.3
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+ sudo: false
3
+ before_install: gem install bundler -v 1.10.6
4
+ rvm:
5
+ - "2.2"
6
+ - "2.1"
7
+ - "2.0"
8
+ - "1.9.3"
9
+ - ruby-head
10
+ - rbx-2
11
+ - jruby-19mode
12
+ - jruby-head
13
+ matrix:
14
+ allow_failures:
15
+ - rvm: ruby-head
16
+ - rvm: jruby-head
17
+ fast_finish: true
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Jonas Thiel
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,58 @@
1
+ # linr
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/linr.svg)](https://rubygems.org/gems/linr)
4
+ [![Build Status](https://travis-ci.org/jnbt/linr.svg?branch=master)](https://travis-ci.org/jnbt/linr)
5
+ [![Coverage Status](https://coveralls.io/repos/jnbt/linr/badge.svg?branch=master)](https://coveralls.io/r/jnbt/linr?branch=master)
6
+ [![Code Climate](https://codeclimate.com/github/jnbt/linr/badges/gpa.svg)](https://codeclimate.com/github/jnbt/linr)
7
+ [![Gemnasium](https://img.shields.io/gemnasium/jnbt/linr.svg?style=flat)](https://gemnasium.com/jnbt/linr)
8
+ [![Inline docs](http://inch-ci.org/github/jnbt/linr.svg?branch=master)](http://inch-ci.org/github/jnbt/linr)
9
+ [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg?style=flat)](http://www.rubydoc.info/github/jnbt/linr/master)
10
+
11
+ A simple UDP client for [InfluxDB](https://influxdb.com)
12
+
13
+ :construction: :warning:
14
+ **This project is in very stage. Things will change!**
15
+
16
+ ## Install
17
+
18
+ $ [sudo] gem install linr
19
+
20
+ Or add it to your Gemfile, etc.
21
+
22
+ ## Usage
23
+
24
+ Connect to a InfluxDB host via
25
+ [UDP](https://influxdb.com/docs/v0.9/write_protocols/udp.html)
26
+ and send a series:
27
+
28
+ ```ruby
29
+ require "linr"
30
+
31
+ client = Linr::Client.new(host: "127.0.0.1", port: 8836)
32
+ client.write(
33
+ measurement: "cpu_load_short",
34
+ tags: { host: "server01", region: "us-west" },
35
+ fields: { value: 0.64 },
36
+ timestamp: 1434055562
37
+ )
38
+ ```
39
+
40
+ ## References
41
+
42
+ * [Line Protocol Syntax](https://influxdb.com/docs/v0.9/write_protocols/write_syntax.html)
43
+ * [InfluxDB UDP](https://influxdb.com/docs/v0.9/write_protocols/udp.html)
44
+
45
+ ## Testing
46
+
47
+ Just run
48
+
49
+ $ rake
50
+
51
+
52
+ ## Contributing
53
+
54
+ 1. Fork it ( https://github.com/jnbt/linr/fork )
55
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
56
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
57
+ 4. Push to the branch (`git push origin my-new-feature`)
58
+ 5. Create a new Pull Request
@@ -0,0 +1,13 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+ require "rubocop/rake_task"
4
+
5
+ Rake::TestTask.new(:test) do |t|
6
+ t.libs << "spec"
7
+ t.libs << "lib"
8
+ t.test_files = FileList["spec/**/*_spec.rb"]
9
+ end
10
+
11
+ RuboCop::RakeTask.new
12
+
13
+ task default: [:test, :rubocop]
@@ -0,0 +1,11 @@
1
+ require "linr/version"
2
+ require "linr/config"
3
+ require "linr/client"
4
+ require "linr/data"
5
+ require "linr/encoder"
6
+ require "linr/connection"
7
+ require "linr/logger"
8
+
9
+ # A simple UDP client for InfluxDB
10
+ module Linr
11
+ end
@@ -0,0 +1,60 @@
1
+ module Linr
2
+ # Simple UDP-based InfluxDB client
3
+ # @example
4
+ # client = Client.new(host: "127.0.0.1", port: 8063)
5
+ # client.write(
6
+ # measurement: "cpu_load_short",
7
+ # tags: { host: "server01", region: "us-west" },
8
+ # fields: { value: 0.64 },
9
+ # timestamp: 1434055562
10
+ # )
11
+ class Client
12
+ attr_reader :config
13
+
14
+ # Initialize a new client.
15
+ # @param opts [Hash] See {Config} for opts
16
+ # @see Config
17
+ def initialize(opts = {})
18
+ @config = Config.new(opts)
19
+ connect!
20
+ end
21
+
22
+ # Write one or more series to the InfluxDB connection
23
+ # @param series [Array<Hash>] see {Data} for values
24
+ def write(*series)
25
+ payload = build_payload(series)
26
+ send(payload)
27
+ end
28
+
29
+ private
30
+
31
+ def connect!
32
+ @connection = Connection::UDP.new(config.host, config.port)
33
+ info("Connected to #{config.host}:#{config.port}")
34
+ end
35
+
36
+ def build_payload(series)
37
+ series.map do |serie|
38
+ data = Data.new(serie)
39
+ encode(data)
40
+ end.join("\n")
41
+ end
42
+
43
+ def send(payload)
44
+ debug(payload)
45
+ @connection.send(payload)
46
+ end
47
+
48
+ def encode(data)
49
+ config.encoder.dump(data)
50
+ end
51
+
52
+ def info(matter)
53
+ config.logger.info("Linr") { matter }
54
+ end
55
+
56
+ def debug(matter)
57
+ config.logger.debug("Linr") { matter }
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,24 @@
1
+ module Linr
2
+ # Holds the config of a {Client}
3
+ # @example
4
+ # Config.new(host: "db.domain.com", logger: Logger.new($stdout))
5
+ class Config
6
+ attr_reader :host
7
+ attr_reader :port
8
+ attr_reader :logger
9
+ attr_reader :encoder
10
+
11
+ # Build a config based on opts
12
+ # @param opts [Hash] the options to create the config
13
+ # @option opts [String] :host
14
+ # @option opts [Fixnum] :port
15
+ # @option opts [::Logger] :logger
16
+ # @option opts [Object] :encoder
17
+ def initialize(opts = {})
18
+ @host = opts.fetch(:host, "127.0.0.1")
19
+ @port = opts.fetch(:port, 8089)
20
+ @logger = opts.fetch(:logger, Logger::Null.new)
21
+ @encoder = opts.fetch(:encoder, Encoder::Line.new)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1 @@
1
+ require "linr/connection/udp"
@@ -0,0 +1,30 @@
1
+ require "socket"
2
+
3
+ module Linr
4
+ module Connection
5
+ # Connects to a InfluxDB UDP port
6
+ # @see https://influxdb.com/docs/v0.9/write_protocols/udp.html
7
+ # @example
8
+ # UDP.new("localhost", 8089).send("series a=0.51")
9
+ class UDP
10
+ # Use non-custom flags
11
+ SEND_FLAGS = 0
12
+
13
+ # Establishes a connection
14
+ # @param host [String]
15
+ # @param port [Fixnum]
16
+ def initialize(host, port)
17
+ @socket = UDPSocket.new
18
+ @socket.connect(host, port)
19
+ end
20
+
21
+ # Send data over the UDP connection. Should be encoded using the Line
22
+ # Protocol.
23
+ # @see Encoder::Line
24
+ # @param data [String]
25
+ def send(data)
26
+ @socket.send(data, SEND_FLAGS)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,24 @@
1
+ module Linr
2
+ # Describes series send to InfluxDB
3
+ # @see https://influxdb.com/docs/v0.9/guides/writing_data.html
4
+ # @example
5
+ # Data.new(
6
+ # measurement: cpu_load_short,
7
+ # tags: { host: "server01", region: "us-west" },
8
+ # fields: { value: 0.64 },
9
+ # timestamp: 1434055562
10
+ # )
11
+ class Data
12
+ attr_reader :measurement
13
+ attr_reader :fields
14
+ attr_reader :tags
15
+ attr_reader :timestamp
16
+
17
+ def initialize(source)
18
+ @measurement = source.fetch(:measurement)
19
+ @fields = source.fetch(:fields)
20
+ @tags = source[:tags]
21
+ @timestamp = source[:timestamp]
22
+ end
23
+ end
24
+ end
@@ -0,0 +1 @@
1
+ require "linr/encoder/line"
@@ -0,0 +1,81 @@
1
+ module Linr
2
+ module Encoder
3
+ # Encodes data entry into the InfluxDB line format.
4
+ # @see https://influxdb.com/docs/v0.9/write_protocols/write_syntax.html
5
+ # @example Encode a data series
6
+ # Line.new.dump(Data.new(measurement: "series", fields: { a: 0.5 }))
7
+ class Line
8
+ # Encodes data into the line syntax
9
+ # @param data [Data]
10
+ # @return [String]
11
+ def dump(data)
12
+ [
13
+ dump_measurement(data.measurement),
14
+ dump_tags(data.tags),
15
+ dump_fields(data.fields),
16
+ dump_timestamp(data.timestamp)
17
+ ].compact.join
18
+ end
19
+
20
+ private
21
+
22
+ def dump_measurement(measurement)
23
+ escape_key(measurement)
24
+ end
25
+
26
+ def dump_tags(tags)
27
+ dump_collection(tags, ",") do |key, value|
28
+ "#{escape_key(key)}=#{escape_value(value)}"
29
+ end
30
+ end
31
+
32
+ def dump_fields(fields)
33
+ dump_collection(fields) do |key, value|
34
+ "#{escape_key(key)}=#{encode_field_value(value)}"
35
+ end
36
+ end
37
+
38
+ def dump_timestamp(timestamp)
39
+ " #{timestamp}" if timestamp
40
+ end
41
+
42
+ def dump_collection(data, prefix = " ", &block)
43
+ return unless data && !data.empty?
44
+ prefix + data.map(&block).join(",")
45
+ end
46
+
47
+ def encode_field_value(value)
48
+ case value
49
+ when Numeric
50
+ encode_numberic(value)
51
+ when TrueClass, FalseClass
52
+ value.to_s
53
+ else
54
+ escape_qoute(escape_value(value))
55
+ end
56
+ end
57
+
58
+ def encode_numberic(value)
59
+ "#{value}i" if value.is_a?(Fixnum)
60
+ value
61
+ end
62
+
63
+ def escape_value(input)
64
+ input.to_s
65
+ .gsub(/\s/, '\ ')
66
+ .gsub(",", '\,')
67
+ .gsub('"', '\"')
68
+ end
69
+
70
+ def escape_qoute(input)
71
+ %("#{input}")
72
+ end
73
+
74
+ def escape_key(input)
75
+ input.to_s
76
+ .gsub(/\s/, '\ ')
77
+ .gsub(",", '\,')
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1 @@
1
+ require "linr/logger/null"
@@ -0,0 +1,15 @@
1
+ require "logger"
2
+
3
+ module Linr
4
+ module Logger
5
+ # A simple null logger without any output
6
+ # @api private
7
+ class Null < ::Logger
8
+ def initialize(*_args)
9
+ end
10
+
11
+ def add(*_args, &_block)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module Linr
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,30 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "linr/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "linr"
7
+ spec.version = Linr::VERSION
8
+ spec.authors = ["Jonas Thiel"]
9
+ spec.email = ["jonas@thiel.io"]
10
+
11
+ spec.summary = "A simple UDP client for InfluxDB"
12
+ spec.description = "A simple UDP client for InfluxDB"
13
+ spec.homepage = "https://github.com/jnbt/linr"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+
20
+ spec.executables = spec.files.grep(%r{^bin\/}) { |f| File.basename(f) }
21
+
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "rake", "~> 10.4"
25
+ spec.add_development_dependency "minitest", "~> 5.8"
26
+ spec.add_development_dependency "bundler", "~> 1.10"
27
+ spec.add_development_dependency "coveralls", "~> 0.8"
28
+ spec.add_development_dependency "inch", "~> 0.7"
29
+ spec.add_development_dependency "rubocop", "~> 0.35"
30
+ end
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: linr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jonas Thiel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-11-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '10.4'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '10.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.8'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.10'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.10'
55
+ - !ruby/object:Gem::Dependency
56
+ name: coveralls
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.8'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.8'
69
+ - !ruby/object:Gem::Dependency
70
+ name: inch
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.7'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.7'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.35'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.35'
97
+ description: A simple UDP client for InfluxDB
98
+ email:
99
+ - jonas@thiel.io
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".rubocop.yml"
106
+ - ".ruby-gemset"
107
+ - ".ruby-version"
108
+ - ".travis.yml"
109
+ - Gemfile
110
+ - LICENSE
111
+ - README.md
112
+ - Rakefile
113
+ - lib/linr.rb
114
+ - lib/linr/client.rb
115
+ - lib/linr/config.rb
116
+ - lib/linr/connection.rb
117
+ - lib/linr/connection/udp.rb
118
+ - lib/linr/data.rb
119
+ - lib/linr/encoder.rb
120
+ - lib/linr/encoder/line.rb
121
+ - lib/linr/logger.rb
122
+ - lib/linr/logger/null.rb
123
+ - lib/linr/version.rb
124
+ - linr.gemspec
125
+ homepage: https://github.com/jnbt/linr
126
+ licenses:
127
+ - MIT
128
+ metadata: {}
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubyforge_project:
145
+ rubygems_version: 2.4.5.1
146
+ signing_key:
147
+ specification_version: 4
148
+ summary: A simple UDP client for InfluxDB
149
+ test_files: []
150
+ has_rdoc: