metrux 1.0.0

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.
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