metrux 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +14 -0
  5. data/.ruby-version.sample +1 -0
  6. data/CHANGELOG.md +110 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +429 -0
  10. data/Rakefile +2 -0
  11. data/bin/console +9 -0
  12. data/bin/playground +38 -0
  13. data/bin/rake +17 -0
  14. data/bin/rspec +17 -0
  15. data/bin/rubocop +17 -0
  16. data/bin/setup +15 -0
  17. data/config/metrux.sample.yml +46 -0
  18. data/lib/metrux.rb +60 -0
  19. data/lib/metrux/client.rb +40 -0
  20. data/lib/metrux/commands.rb +12 -0
  21. data/lib/metrux/commands/base.rb +62 -0
  22. data/lib/metrux/commands/gauge.rb +21 -0
  23. data/lib/metrux/commands/meter.rb +15 -0
  24. data/lib/metrux/commands/notice_error.rb +38 -0
  25. data/lib/metrux/commands/periodic_gauge.rb +25 -0
  26. data/lib/metrux/commands/periodic_gauge/agent.rb +68 -0
  27. data/lib/metrux/commands/periodic_gauge/registry.rb +39 -0
  28. data/lib/metrux/commands/periodic_gauge/reporter.rb +33 -0
  29. data/lib/metrux/commands/periodic_gauge/supervisor.rb +53 -0
  30. data/lib/metrux/commands/timer.rb +30 -0
  31. data/lib/metrux/commands/write.rb +9 -0
  32. data/lib/metrux/config_builders.rb +11 -0
  33. data/lib/metrux/config_builders/common.rb +53 -0
  34. data/lib/metrux/config_builders/influx.rb +71 -0
  35. data/lib/metrux/config_builders/logger.rb +48 -0
  36. data/lib/metrux/config_builders/periodic_gauge.rb +21 -0
  37. data/lib/metrux/config_builders/yaml.rb +64 -0
  38. data/lib/metrux/configuration.rb +52 -0
  39. data/lib/metrux/connections.rb +7 -0
  40. data/lib/metrux/connections/influx_db.rb +17 -0
  41. data/lib/metrux/connections/null.rb +19 -0
  42. data/lib/metrux/constants.rb +19 -0
  43. data/lib/metrux/loggable.rb +24 -0
  44. data/lib/metrux/plugin_register.rb +57 -0
  45. data/lib/metrux/plugins.rb +10 -0
  46. data/lib/metrux/plugins/gc.rb +52 -0
  47. data/lib/metrux/plugins/periodic_gauge.rb +32 -0
  48. data/lib/metrux/plugins/process.rb +71 -0
  49. data/lib/metrux/plugins/thread.rb +13 -0
  50. data/lib/metrux/plugins/yarv.rb +26 -0
  51. data/lib/metrux/sleeper.rb +8 -0
  52. data/lib/metrux/version.rb +3 -0
  53. data/metrux.gemspec +40 -0
  54. metadata +250 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 49292a8d88d4fe6a2e1a4e4c511662fcb67c4d36
4
+ data.tar.gz: 85ca030fd6ffac6140836471c3658838b5211bdf
5
+ SHA512:
6
+ metadata.gz: f7e277a6d683600266519423c75fbb9ef86660d64df4f9189c54785b788435174b4c12e552b4503604b3c84699bd89254c718a8cbb300a938cbd1b7debd11ff3
7
+ data.tar.gz: 2fe239f826e5298d845a20a01a5827e67044782562fa0d7aab2283f995292a52fb6feb3f29f3a2810bc2537491d8c1fda67834e7e2727f9eb34c689dde472be1
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /log/
11
+ .ruby-version
12
+ /config/metrux.yml
13
+ *.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,14 @@
1
+ Documentation:
2
+ Enabled: false
3
+
4
+ Style/MultilineOperationIndentation:
5
+ EnforcedStyle: indented
6
+
7
+ AllCops:
8
+ # Include gemspec and Rakefile
9
+ Include:
10
+ - '**/*.gemspec'
11
+ - '**/Rakefile'
12
+ Exclude:
13
+ - 'spec/**/*'
14
+ - 'bin/**/*'
@@ -0,0 +1 @@
1
+ 2.3.0
@@ -0,0 +1,110 @@
1
+ # 1.0.0 (open source release \o/)
2
+
3
+ - NO CHANGES
4
+
5
+ # 0.11.0
6
+
7
+ - Allow writing a point with a custom timestamp
8
+
9
+ # 0.10.3
10
+
11
+ - Cast boolean values for influx configs
12
+
13
+ # 0.10.2
14
+
15
+ - Cast numeric values for influx configs
16
+
17
+ # 0.10.1
18
+
19
+ - Fix periodic gauge base plugin
20
+
21
+ # 0.10.0
22
+
23
+ - Create a periodic gauge base plugin
24
+ - Switch built-in plugins inheritance from Base to PeriodicGauge
25
+ - Now it's easier to test the plugins
26
+ - Remove `Metrux::Plugins::Base`
27
+ - Change notice error command to save error message as a field to avoid big
28
+ indexes
29
+
30
+ # 0.9.0
31
+
32
+ - Remove the need of having a config file, it can be configured only with env
33
+ vars
34
+ - Add fallback of non existant config file to return an empty hash
35
+ - Change `Configuration` setup
36
+ - Change influx db configuration defaults
37
+ - Allow to force setting STDOUT through env var or config file
38
+ - Remove the need of having `config/metrux.yml` to run the test suite
39
+
40
+ # 0.8.0
41
+
42
+ - Change built-in plugins
43
+ - Each plugin will register only one gauge with all info
44
+ - Change its measurement key
45
+
46
+ # 0.7.0
47
+
48
+ **We encourage that you use this version or higher to avoid big database indexes
49
+ issues**
50
+
51
+ - Remove `uniq` tag on writing
52
+ - To ensure that we can write "duplicate" points, we are switching the tag
53
+ `uniq` with the timestamp in nanoseconds because it was increasing the
54
+ indexes of all databases, letting them very slow.
55
+
56
+ # 0.6.3
57
+
58
+ - Remove i18n issues due to `String#parameterize`
59
+
60
+ # 0.6.2
61
+
62
+ - Setup metrux's configuration lazily
63
+ - Fix async specs
64
+
65
+ # 0.6.1
66
+
67
+ - Fix test issues
68
+
69
+ # 0.6.0
70
+
71
+ - Remove spaces and non-ascii chars from prefix
72
+
73
+ # 0.5.0
74
+
75
+ - Fix prefix fetching on base command
76
+ - Add puma worker number on program name
77
+
78
+ # 0.4.1
79
+
80
+ - Add logging on plugin registering
81
+
82
+ # 0.4.0
83
+
84
+ - Add `env` tag on writing
85
+ - Add `app_name` prefix on measurement key
86
+ - Remove prefix option from plugins
87
+
88
+ # 0.3.0
89
+
90
+ - Add `program_name` tag on writing
91
+ - Create built-in plugins
92
+ - `Metrux::Plugins::Trhead`
93
+ - `Metrux::Plugins::Gc`
94
+ - `Metrux::Plugins::Process`
95
+ - `Metrux::Plugins::Yarv`
96
+ - Create a plugin register
97
+
98
+ # 0.2.0
99
+
100
+ - Load and parse configuration file with ERB templating
101
+
102
+ # 0.1.0
103
+
104
+ - First release
105
+ - Write command
106
+ - Gauge command
107
+ - Timer command
108
+ - Meter command
109
+ - Notice error command
110
+ - Periodic gauge command
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in metrux.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Locaweb
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
13
+ all 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
21
+ THE SOFTWARE.
@@ -0,0 +1,429 @@
1
+ # Metrux
2
+
3
+ An instrumentation library which persists the metrics on InfluxDB.
4
+
5
+ ## Summary
6
+
7
+ 1. [Installation](#installation)
8
+ 2. [Configuration](#configuration)
9
+ 1. [Configuration Keys](#configuration-keys)
10
+ 3. [Usage](#usage)
11
+ 1. [Write](#write)
12
+ 2. [Meter](#meter)
13
+ 3. [Gauge](#gauge)
14
+ 4. [Periodic Gauge](#periodic-gauge)
15
+ 5. [Timer](#timer)
16
+ 6. [Notice Error](#notice-error)
17
+ 7. [Plugins](#plugins)
18
+ 1. [Registering](#registering)
19
+
20
+ ## Installation
21
+
22
+ Add this line to your application's Gemfile:
23
+
24
+ ```ruby
25
+ gem 'metrux'
26
+ ```
27
+
28
+ And then execute:
29
+
30
+ $ bundle
31
+
32
+ Or install it yourself as:
33
+
34
+ $ gem install metrux
35
+
36
+ ## Configuration
37
+
38
+ You will need to create a config file on `config/metrux.yml`. See a
39
+ [sample](config/metrux.sample.yml) here.
40
+
41
+ Its configuration is based on ENV VARS and/or YAML, pretty similar to
42
+ `appsignal` or `newrelic` gems. ENV VARS will always override yaml configs.
43
+
44
+ **If you want to configure only via ENV VARS you won't need to have the config
45
+ file.**
46
+
47
+ ### Configuration keys
48
+
49
+ | ENV VAR | yaml | Default | Description |
50
+ | ------- | ---- | ------- | ----------- |
51
+ | `METRUX_ACTIVE` | `active` | `false` | Whether it is active. Can be true or false |
52
+ | `METRUX_APP_NAME` | `app_name` | | Your application's name (All metrics will be marked with this tag) |
53
+ | `METRUX_PERIODIC_GAUGE_INTERVAL` | `periodic_gauge_interval` | `60` | Interval that agent will execute all registered periodic gauges (in seconds) |
54
+ | `METRUX_LOG_FILE` | `log_file` | `STDOUT` | Log file path |
55
+ | `METRUX_LOG_LEVEL` | `log_level` | `info` | Log level |
56
+ | `METRUX_INFLUX_HOST` | `influx_host` | localhost | InfluxDB host - See: https://github.com/influxdata/influxdb-ruby#creating-a-client |
57
+ | `METRUX_INFLUX_PORT` | `influx_port` | 8083 | InfluxDB port |
58
+ | `METRUX_INFLUX_DATABASE` | `influx_database` | | InfluxDB database |
59
+ | `METRUX_INFLUX_USERNAME` | `influx_username` | root | InfluxDB username |
60
+ | `METRUX_INFLUX_PASSWORD` | `influx_password` | root | InfluxDB password |
61
+ | `METRUX_INFLUX_ASYNC` | `influx_async` | true | InfluxDB async options - See: https://github.com/influxdata/influxdb-ruby#writing-data |
62
+
63
+ ## Usage
64
+
65
+ Before you start sending your metrics to InfluxDB, is very important that you
66
+ read [InfluxDB Schema Design](https://docs.influxdata.com/influxdb/v0.13/concepts/schema_and_data_layout/#encouraged-schema-design)
67
+ for a better understanding of how to use `tags` and `fields`.
68
+
69
+ All writes will automatically include the tags `app_name`, `hostname`, `env` and
70
+ `program_name` unless you pass another value.
71
+
72
+ All measurement keys will have the prefix of the app name
73
+ (`app_name.underscore`).
74
+
75
+ ### Write
76
+
77
+ Writes a point.
78
+
79
+ #### Single value/field
80
+
81
+ ```ruby
82
+ key = 'my_awesome_key'
83
+ data = 1
84
+
85
+ # Options are not required
86
+ options = { tags: { something: 'a-string-value' }, precision: 's' }
87
+
88
+ # options[:timestamp] = Time.now.to_i # you can also provide a custom timestamp
89
+
90
+ Metrux.write(key, data, options)
91
+ ```
92
+
93
+ Result:
94
+ ```
95
+ name: app_name/my_awesome_key
96
+ --------------------
97
+ time app_name hostname something value
98
+ 1466604892000000000 Your appname YOURHOSTNAME a-string-value 1
99
+ ```
100
+
101
+ #### Multi value/field
102
+
103
+ ```ruby
104
+ key = 'my_awesome_key'
105
+ data = { another_field: 1, value: 2 }
106
+
107
+ # Options are not required
108
+ options = { tags: { something: 'a-string-value' }, precision: 's' }
109
+
110
+ # options[:timestamp] = Time.now.to_i # you can also provide a custom timestamp
111
+
112
+ Metrux.write(key, data, options)
113
+ ```
114
+
115
+ Result:
116
+ ```
117
+ name: app_name/my_awesome_key
118
+ --------------------
119
+ time app_name hostname another_field something value
120
+ 1466604892000000000 Your appname YOURHOSTNAME 1 a-string-value 2
121
+ ```
122
+
123
+ ### Meter
124
+
125
+ Writes a meter (aka counter). All meters' key will have the prefix `meters/`.
126
+
127
+ #### Simple increment (value: 1)
128
+
129
+ ```ruby
130
+ key = 'my_meter'
131
+
132
+ # Options are not required
133
+ options = { tags: { something: 'a-string-value' }, precision: 's' }
134
+
135
+ # options[:timestamp] = Time.now.to_i # you can also provide a custom timestamp
136
+
137
+ Metrux.meter(key, options)
138
+ ```
139
+
140
+ Result:
141
+ ```
142
+ name: app_name/meters/my_meter
143
+ ---------------------
144
+ time app_name hostname something value
145
+ 1466604892000000000 Your appname YOURHOSTNAME a-string-value 1
146
+ ```
147
+
148
+
149
+ #### Different increment (value <> 1)
150
+
151
+ ```ruby
152
+ key = 'my_meter'
153
+
154
+ value = 5
155
+
156
+ # Options are not required
157
+ options = {
158
+ value: value, tags: { something: 'a-string-value' }, precision: 's'
159
+ }
160
+
161
+ # options[:timestamp] = Time.now.to_i # you can also provide a custom timestamp
162
+
163
+ Metrux.meter(key, options)
164
+ ```
165
+
166
+ Result:
167
+ ```
168
+ name: app_name/meters/my_meter
169
+ ---------------------
170
+ time app_name hostname something value
171
+ 1466604892000000000 Your appname YOURHOSTNAME a-string-value 5
172
+ ```
173
+
174
+ ### Gauge
175
+
176
+ Writes a gauge (result of something). All gauges' key will have the prefix
177
+ `gauges/`.
178
+
179
+ #### Execute a block and save its result
180
+
181
+ ```ruby
182
+ key = 'my_gauge'
183
+
184
+ # Options are not required
185
+ options = { tags: { something: 'a-string-value' }, precision: 's' }
186
+
187
+ # options[:timestamp] = Time.now.to_i # you can also provide a custom timestamp
188
+
189
+ Metrux.gauge(key, options) { 40 }
190
+ # => 40
191
+ ```
192
+
193
+ Result:
194
+ ```
195
+ name: app_name/gauges/my_gauge
196
+ ---------------------
197
+ time app_name hostname something value
198
+ 1466604892000000000 Your appname YOURHOSTNAME a-string-value 40
199
+ ```
200
+
201
+ The rule for multi value/field is the same of [write](#write).
202
+
203
+
204
+ #### Just save the result of a previously executed block
205
+
206
+ ```ruby
207
+ key = 'my_gauge'
208
+
209
+ result = 42
210
+
211
+ # Options are not required
212
+ options = {
213
+ result: result, tags: { something: 'a-string-value' }, precision: 's'
214
+ }
215
+
216
+ # options[:timestamp] = Time.now.to_i # you can also provide a custom timestamp
217
+
218
+ Metrux.gauge(key, options)
219
+ # => 42
220
+ ```
221
+
222
+ Result:
223
+ ```
224
+ name: app_name/gauges/my_gauge
225
+ ---------------------
226
+ time app_name hostname something value
227
+ 1466604892000000000 Your appname YOURHOSTNAME a-string-value 42
228
+ ```
229
+
230
+ The rule for multi value/field is the same of [write](#write).
231
+
232
+ ### Periodic gauge
233
+
234
+ Executes periodically a gauge (result of something) and writes it. All periodic
235
+ gauges' key will have the prefix `gauges/`.
236
+
237
+ The interval of each execution will depend on the configuration. See
238
+ [Configuration](#configuration).
239
+
240
+ **Remember that gauges must be lightweight and very fast to execute.**
241
+
242
+ ```ruby
243
+ key = 'my_periodic_gauge'
244
+
245
+ # Options are not required
246
+ options = { tags: { something: 'a-string-value' }, precision: 's' }
247
+
248
+ # options[:timestamp] = Time.now.to_i # you can also provide a custom timestamp
249
+
250
+ Metrux.periodic_gauge(key, options) { Thread.list.count }
251
+ ```
252
+
253
+ Result after having passed (interval * 1) seconds:
254
+ ```
255
+ name: app_name/gauges/my_gauge
256
+ ---------------------
257
+ time app_name hostname something value
258
+ 1466609741000000000 Your appname YOURHOSTNAME a-string-value 6
259
+ ```
260
+
261
+ Result after having passed (interval * 2) seconds:
262
+ ```
263
+ name: app_name/gauges/my_gauge
264
+ ---------------------
265
+ time app_name hostname something value
266
+ 1466609741000000000 Your appname YOURHOSTNAME a-string-value 6
267
+ 1466609746000000000 Your appname YOURHOSTNAME a-string-value 6
268
+ ```
269
+
270
+ The rule for multi value/field is the same of [write](#write).
271
+
272
+ ### Timer
273
+
274
+ Calculates and writes the time elapsed of something. All timers' key will have
275
+ the prefix `timers/`.
276
+
277
+ #### Execute a block and save its execution time
278
+
279
+ ```ruby
280
+ key = 'my_timer'
281
+
282
+ # Options are not required
283
+ options = { tags: { something: 'a-string-value' }, precision: 's' }
284
+
285
+ # options[:timestamp] = Time.now.to_i # you can also provide a custom timestamp
286
+
287
+ Metrux.timer(key, options) { sleep(0.45); 40 }
288
+ # => 40
289
+ ```
290
+
291
+ Result:
292
+ ```
293
+ name: app_name/timers/my_timer
294
+ ---------------------
295
+ time app_name hostname something value
296
+ 1466604892000000000 Your appname YOURHOSTNAME a-string-value 455
297
+ ```
298
+
299
+ #### Just save the duration of a previously calculated block
300
+
301
+ ```ruby
302
+ key = 'my_timer'
303
+
304
+ duration = 1342 # milliseconds
305
+
306
+ # Options are not required
307
+ options = {
308
+ duration: duration, tags: { something: 'a-string-value' }, precision: 's'
309
+ }
310
+
311
+ # options[:timestamp] = Time.now.to_i # you can also provide a custom timestamp
312
+
313
+ Metrux.timer(key, options)
314
+ # => nil
315
+ ```
316
+
317
+ Result:
318
+ ```
319
+ name: app_name/timers/my_timer
320
+ ---------------------
321
+ time app_name hostname something value
322
+ 1466604892000000000 Your appname YOURHOSTNAME a-string-value 1342
323
+ ```
324
+
325
+ ### Notice error
326
+
327
+ Meters errors.
328
+
329
+ ```ruby
330
+ def do_something(a, b)
331
+ raise(ArgumentError, 'Some message') if b = 0
332
+ rescue => e
333
+ # Args are not required
334
+ args = { a: a, b: b, uri: 'http://domain.tld/path' }
335
+
336
+ # args[:timestamp] = Time.now.to_i # you can also provide a custom timestamp
337
+
338
+ Metrux.notice_error(e, args)
339
+
340
+ raise
341
+ end
342
+
343
+ do_something(1, 0)
344
+ ```
345
+
346
+ Result:
347
+ ```
348
+ name: app_name/meters/errors
349
+ ---------------------
350
+ time a app_name b error hostname message uri value
351
+ 1466608927000000000 1 Your appname 0 ArgumentError YOURHOSTNAME Some message "http://domain.tld/path" 1
352
+ ```
353
+
354
+ ### Plugins
355
+
356
+ * `Metrux::Plugins::Thread` - Register a periodic gauge to count the amount of
357
+ running threads. See [Metrux::Plugins::Thread](lib/metrux/plugins/thread.rb)
358
+ * `Metrux::Plugins::Gc` - Register a periodic gauge to fetch info from
359
+ Ruby's GC. See [Metrux::Plugins::Gc](lib/metrux/plugins/gc.rb)
360
+ * `Metrux::Plugins::Process` - Register a periodic gauge to fetch the memory
361
+ consumption (rss) of the current process. See
362
+ [Metrux::Plugins::Process](lib/metrux/plugins/process.rb)
363
+ * `Metrux::Plugins::Yarv` - Register a periodic gauges to fetch info from
364
+ Ruby's VM. See [Metrux::Plugins::Yarv](lib/metrux/plugins/yarv.rb)
365
+
366
+ #### Registering
367
+
368
+ You need to register the plugins to have them working. It's also possible to
369
+ register your own plugins on `Metrux`:
370
+
371
+ ```ruby
372
+ module Metrux
373
+ module Plugins
374
+ class MyAwesomePlugin
375
+ def initialize(config, options); @config, @options = config, options; end
376
+
377
+ def call
378
+ Metrux.periodic_gauge('threads_count', @options) { Thread.list.count }
379
+ end
380
+ end
381
+ end
382
+ end
383
+
384
+ plugin = Metrux::Plugins::MyAwesomePlugin
385
+ options = { my: { plugin: :options } }
386
+
387
+ Metrux.register(plugin, options) # => true
388
+ ```
389
+
390
+ Or you can use a `Proc` instead of a class:
391
+
392
+ ```ruby
393
+ options = { my: { plugin: :options } }
394
+
395
+ Metrux.register(options) do |config, options|
396
+ Metrux.periodic_gauge('threads_count', options) { Thread.list.count }
397
+ end # => true
398
+ ```
399
+
400
+ ## Development
401
+
402
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
403
+
404
+ To install this gem onto your local machine, run `bin/rake install`. To release a new version, update the version number in `version.rb`, and then run `bin/rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
405
+
406
+ ## License
407
+
408
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
409
+
410
+ ## Git tags
411
+
412
+ Don't forget to tag your work! After a merge request being accepted, run:
413
+
414
+ 1. (git tag -a "x.x.x" -m "") to create the new tag.
415
+ 2. (git push origin "x.x.x") to push the new tag to remote.
416
+
417
+ Follow the RubyGems conventions at http://docs.rubygems.org/read/chapter/7 to know how to increment the version number. Covered in more detail in http://semver.org/
418
+
419
+ ## Pull requests acceptance
420
+
421
+ Don't forget to write tests for your changes. It's very important to maintain the codebase's sanity. Any pull request that doesn't have enough test coverage will be asked a revision.
422
+
423
+ ## Contributing
424
+
425
+ 1. Fork it
426
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
427
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
428
+ 4. Push to the branch (`git push origin my-new-feature`)
429
+ 5. Create new Pull Request