{"id":13411913,"url":"https://github.com/influxdata/influxdb-rails","last_synced_at":"2025-05-16T05:06:47.990Z","repository":{"id":12478488,"uuid":"15147022","full_name":"influxdata/influxdb-rails","owner":"influxdata","description":"Ruby on Rails bindings to automatically write metrics into InfluxDB","archived":false,"fork":false,"pushed_at":"2024-08-02T03:34:22.000Z","size":523,"stargazers_count":212,"open_issues_count":25,"forks_count":64,"subscribers_count":39,"default_branch":"master","last_synced_at":"2024-09-17T03:06:54.579Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/influxdata.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-12-12T20:47:14.000Z","updated_at":"2024-09-06T15:01:55.000Z","dependencies_parsed_at":"2024-01-02T23:41:42.402Z","dependency_job_id":"c2f532a9-faad-4b23-b0b2-f268542fba79","html_url":"https://github.com/influxdata/influxdb-rails","commit_stats":{"total_commits":280,"total_committers":29,"mean_commits":9.655172413793103,"dds":0.7678571428571428,"last_synced_commit":"0d7aee240144d0a5ef742f8a11599846592e7f31"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/influxdata%2Finfluxdb-rails","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/influxdata%2Finfluxdb-rails/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/influxdata%2Finfluxdb-rails/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/influxdata%2Finfluxdb-rails/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/influxdata","download_url":"https://codeload.github.com/influxdata/influxdb-rails/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247867361,"owners_count":21009240,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T20:01:18.389Z","updated_at":"2025-04-08T15:07:08.241Z","avatar_url":"https://github.com/influxdata.png","language":"Ruby","funding_links":[],"categories":["Ruby","Client libraries"],"sub_categories":["Official"],"readme":"\u003e :warning: You are looking at the README a development branch of this gem.\n\u003e If you are using this gem you should have a look at the\n\u003e latest [released version (1.0.3)](https://github.com/influxdata/influxdb-rails/tree/v1.0.3#readme)\n\u003e instead.\n\n# influxdb-rails\n\n[![Gem Version](https://badge.fury.io/rb/influxdb-rails.svg)](https://badge.fury.io/rb/influxdb-rails)\n[![Build Status](https://github.com/influxdata/influxdb-rails/actions/workflows/spec.yml/badge.svg)](https://github.com/influxdata/influxdb-rails/actions)\n\nAutomatically instrument your Ruby on Rails applications and write the metrics directly into\n[InfluxDB](https://www.influxdata.com/).\n\n## Table of contents\n\n- [Installation](#installation)\n- [Usage](#installation)\n- [Configuration](#configuration)\n- [Demo](#demo)\n- [FAQ](#frequently-asked-questions)\n- [Contributing](#contributing)\n\n## Installation\n\nAdd the gem to your `Gemfile`:\n\n```console\necho 'gem \"influxdb-rails\"' \u003e\u003e Gemfile\nbundle install\n```\n\nTo get things set up, create an initializer:\n\n```console\nbundle exec rails generate influxdb\n```\n\nThis creates a file `config/initializers/influxdb_rails.rb`, which allows\nconfiguration of this gem.\n\n## Usage\n\nOut of the box, you'll automatically get reporting for the Ruby on Rails components mentioned\nbelow.\n\n### Action Controller\n\nReported ActiveSupport instrumentation hooks:\n\n- [start\\_processing.action\\_controller](https://guides.rubyonrails.org/active_support_instrumentation.html#start-processing-action-controller)\n- [process\\_action.action\\_controller](https://guides.rubyonrails.org/active_support_instrumentation.html#process-action-action-controller)\n\nReported fields:\n\n```ruby\n  controller: 48.467,\n  view: 46.848,\n  db: 0.157,\n  started: 1465839830100400200,\n  request_id: \"d5bf620b-3494-425b-b7e1-4953597ea744\"\n```\n\nReported tags:\n\n```ruby\n{\n  hook:        \"process_action\",\n  server:      Socket.gethostname,\n  app_name:    configuration.application_name,\n  method:      \"PostsController#index\",\n  http_method: \"GET\",\n  format:      \"html\",\n  status:      [\"500\"],\n  exception:   \"ArgumentError\"\n}\n```\n\n### Action View\n\nReported ActiveSupport instrumentation hooks:\n\n- [render\\_template.action\\_view](https://guides.rubyonrails.org/active_support_instrumentation.html#render-template-action-view)\n- [render\\_partial.action\\_view](https://guides.rubyonrails.org/active_support_instrumentation.html#render-partial-action-view)\n- [render\\_collection.action\\_view](https://guides.rubyonrails.org/active_support_instrumentation.html#render-collection-action-view)\n\nReported fields:\n\n```ruby\n  value: 48.467,\n  count: 3,\n  cache_hits: 0,\n  request_id: \"d5bf620b-3494-425b-b7e1-4953597ea744\"\n```\n\nReported tags:\n\n```ruby\n  hook:       [\"render_template\", \"render_partial\", \"render_collection\"],\n  server:     Socket.gethostname,\n  app_name:   configuration.application_name,\n  location:   \"PostsController#index\",\n  filename:   \"/some/file/action.html\"\n```\n\n### Active Record\n\nReported ActiveSupport instrumentation hooks:\n\n- [sql.active\\_record](https://guides.rubyonrails.org/active_support_instrumentation.html#sql-active-record)\n- [instantiation.active\\_record](https://guides.rubyonrails.org/active_support_instrumentation.html#instantiation-active-record)\n\nReported fields:\n\n```ruby\n  sql: \"SELECT \\\"posts\\\".* FROM \\\"posts\\\"\",\n  request_id: \"d5bf620b-3494-425b-b7e1-4953597ea744\"\n```\n\nReported SQL tags:\n\n```ruby\n  hook:       \"sql\",\n  server:     Socket.gethostname,\n  app_name:   configuration.application_name,\n  location:   \"PostsController#index\",\n  operation:  \"SELECT\",\n  class_name: \"POST\",\n  name:       \"Post Load\"\n```\n\nReported instantiation values:\n\n```ruby\n  record_count: 1,\n  request_id:   \"d5bf620b-3494-425b-b7e1-4953597ea744\"\n  value:        7.689\n```\n\nReported instantiation tags:\n\n```ruby\n  hook:       \"instantiation\",\n  server:     Socket.gethostname,\n  app_name:   configuration.application_name,\n  location:   \"PostsController#index\",\n  class_name: \"POST\"\n```\n\n### Active Job\n\nReported ActiveSupport instrumentation hooks:\n\n- [enqueue.active\\_job](https://guides.rubyonrails.org/active_support_instrumentation.html#enqueue-active-job)\n- [perform.active\\_job](https://guides.rubyonrails.org/active_support_instrumentation.html#perform-active-job)\n\nReported fields:\n\n```ruby\n  value: 89.467\n```\n\nReported tags:\n\n```ruby\n  hook:       [\"enqueue\", \"perform\"],\n  state:      [\"queued\", \"succeeded\", \"failed\"],\n  job:        \"SomeJobClassName\",\n  queue:      \"queue_name\"\n```\n\n*Note*: Only the measurements with the hook `perform` report a duration in the value.\nThe enqueue hook is a counter and always reports a value of `1`.\n\n### Action Mailer\n\nReported ActiveSupport instrumentation hooks:\n\n- [deliver.action\\_mailer](https://guides.rubyonrails.org/active_support_instrumentation.html#deliver-action-mailer)\n\nReported fields:\n\n```ruby\n  value: 1\n```\n\nReported tags:\n\n```ruby\n  hook:               \"deliver\",\n  mailer:             \"SomeMailerClassName\"\n```\n\n*Note*: The hook is just a counter and always report a value of `1`.\n\n## Configuration\n\nThe only settings you actually need to configure are the organization, bucket and access token.\n\n```ruby\nInfluxDB::Rails.configure do |config|\n  config.client.org = \"org\"\n  config.client.bucket = \"bucket\"\n  config.client.token = \"token\"\nend\n```\n\nYou'll find all of the configuration settings in the initializer file.\n\n### Custom Tags\n\nYou can modify the tags sent to InfluxDB by defining a middleware, which\nreceives the current tag set as argument and returns a hash in the same\nform. The middleware can be any object, as long it responds to `#call`\n(like a `Proc`):\n\n```ruby\nInfluxDB::Rails.configure do |config|\n  config.tags_middleware = lambda do |tags|\n    tags.merge(env: Rails.env)\n  end\nend\n```\n\nThe `tags` argument is a Hash (mapping Symbol keys to String values). The\nactual keys and values depend on the series name (`tags[:series]`, see\nnext section).\n\nIf you want to add dynamically tags or fields *per request*, you can access\n`InfluxDB::Rails.current` to do so. For instance, you could add the current\nuser as tag or redis query time to every data point:\n\n```ruby\nclass ApplicationController\n  before_action :set_influx_data\n\n  def set_influx_data\n    InfluxDB::Rails.current.tags = { user: current_user.id }\n    InfluxDB::Rails.current.fields = { redis_value: redis_value }\n  end\nend\n```\n\n### Block Instrumentation\nIf you want to add custom instrumentation, you can wrap any code into a block instrumentation\n\n```ruby\nInfluxDB::Rails.instrument \"expensive_operation\", tags: { }, fields: { } do\n  expensive_operation\nend\n```\n\nReported tags:\n\n```ruby\n  hook:       \"block_instrumentation\",\n  server:     Socket.gethostname,\n  app_name:   configuration.application_name,\n  location:   \"PostsController#index\",\n  name:       \"expensive_operation\"\n```\n\nReported fields:\n```ruby\n  value: 100 # execution time of the block in ms\n```\n\nYou can also overwrite the `value`\n\n```ruby\nInfluxDB::Rails.instrument \"user_count\", fields: { value: 1 } do\n  User.create(name: 'mickey', surname: 'mouse')\nend\n```\n\nor call it even without a block\n\n```ruby\nInfluxDB::Rails.instrument \"temperature\", fields: { value: 25 }\n```\n\n### Custom client configuration\n\nThe settings named `config.client.*` are used to construct an `InfluxDB::Client`\ninstance, which is used internally to transmit the reporting data points\nto your InfluxDB server. You can access this client as well, and perform\narbitrary operations on your data:\n\n```ruby\nInfluxDB::Rails.write_api.write(\n  name: \"events\",\n  tags:   { url: \"/foo\", user_id: current_user.id, location: InfluxDB::Rails.current.location },\n  fields: { value: 0 }\n)\n```\n\nIf you do that, it might be useful to add the current context to these custom\ndata points which can get accessed with `InfluxDB::Rails.current.location`.\n\nSee [influxdb-client](https://github.com/influxdata/influxdb-client-ruby) for a\nfull list of configuration options and detailed usage.\n\n### Disabling hooks\n\nIf you are not interested in certain reports you can disable them in the configuration.\n\n```ruby\nInfluxDB::Rails.configure do |config|\n  config.ignored_hooks = ['sql.active_record', 'render_template.action_view']\nend\n```\n\n## Demo\nWant to see this in action? Check out our [sample dashboard](https://github.com/influxdata/influxdb-rails/tree/master/sample-dashboard).\n\n## Frequently Asked Questions\n\n### I'm seeing far less requests recorded in InfluxDB than my logs suggest.\n\nBy default, this gem writes data points with *millisecond time precision*\nto the InfluxDB server. If you have more than 1000 requests/second (and/or\nmultiple parallel requests), **only the last** data point (within the\nsame tag set) is stored. See [InfluxDB server docs][duplicate-points] for\nfurther details.\n\nTo work around this limitation, set the `config.client.time_precision`\nto one of `\"us\"` (microseconds, 1·10\u003csup\u003e-6\u003c/sup\u003es) or `\"ns\"` (nanoseconds,\n1·10\u003csup\u003e-9\u003c/sup\u003es).\n\nPlease note: This will only ever reduce the likelihood of data points\noverwriting each other, but not eliminate it completely.\n\n[duplicate-points]: https://docs.influxdata.com/influxdb/v1.4/troubleshooting/frequently-asked-questions/#how-does-influxdb-handle-duplicate-points\n\n\n### How does the measurement influence the response time?\n\nThis gem subscribes to various `ActiveSupport::Notifications` hooks.\n(cf. [guide][arn-guide] · [docs][arn-docs] · [impl][arn-impl]). The\ncontroller notifications are run *after* a controller action has finished,\nand should not impact the response time.\n\nOther notification hooks (rendering and SQL queries) run *inline* in the\nrequest processing. The amount of overhead introduced should be negligible,\nthough. However reporting of SQL queries relies on Ruby string parsing which\nmight cause performance issues on traffic intensive applications. Disable it in\nthe configuration if you are not willing to tolerate this.\n\nBy default, this gem performs writes to InfluxDB asynchronously. A single\nhook usually only performs some time delta calculations, and then enqueues\nthe data point into a worker queue (which is processed by a background\nthread).\n\nIf you, however, use a synchronous client (`config.client.async = false`),\nthe data points are immediately sent to the InfluxDB server. Depending on\nthe network link, this might cause the HTTP thread to block a lot longer.\n\n[arn-guide]: http://guides.rubyonrails.org/v5.1/active_support_instrumentation.html#process-action-action-controller\n[arn-docs]: http://api.rubyonrails.org/v5.1/classes/ActiveSupport/Notifications.html\n[arn-impl]: https://github.com/rails/rails/blob/5-1-stable/actionpack/lib/action_controller/metal/instrumentation.rb#L30-L38\n\n### How does this gem handle an unreachable InfluxDB server?\n\nBy default, the InfluxDB client will retry indefinitely, until a write\nsucceeds (see [client docs][] for details). This has two important\nimplications, depending on the value of `config.client.async`:\n\n- if the client runs asynchronously (i.e. in a separate thread), the queue\n  might fill up with hundreds of megabytes of data points\n- if the client runs synchronously (i.e. inline in the request/response\n  cycle), it might block all available request threads\n\nIn both cases, your application server might become unresponsive and needs\nto be restarted.\n\nIf you setup a maximum retry value (`Integer === config.client.retry`),\nthe client will try up to that amount of times to send the data to the server\nand (on final error) log an error and discard the values.\n\n[client docs]: https://github.com/influxdata/influxdb-ruby#retry\n\n### What happens, when the InfluxDB client or this gem throws an exception? Will the user see 500 errors?\n\nNo. The controller instrumentation is wrapped in a `rescue StandardError`\nclause, i.e. this gem will only write the error to the `client.logger`\n(`Rails.logger` by default) and not disturb the user experience.\n\n### What happens with unwritten points, when the application restarts?\n\nThe data points are simply discarded.\n\n## Contributing\n\n- Fork this repository on GitHub\n- Make your changes\n  - Add tests.\n  - Add an entry in the `CHANGELOG.md` in the \"unreleased\" section on top.\n- Run the tests:\n  - Either run them manually:\n\n    ```console\n    rake test:all\n    ```\n\n  - or wait for [our CI](https://github.com/influxdata/influxdb-rails/actions) to pick up your changes, *after*\n    you made a pull request.\n- Send a pull request.\n- If your changes are looking good, we'll merge them.\n\n### Testing Tasks\n\n```console\nrake            # unit tests + Rubocop linting\nrake spec       # only unit tests\nrake rubocop    # only Rubocop linter\nrake test:all   # integration tests with various Rails version\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfluxdata%2Finfluxdb-rails","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finfluxdata%2Finfluxdb-rails","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfluxdata%2Finfluxdb-rails/lists"}