{"id":16056345,"url":"https://github.com/ksylvest/analytic","last_synced_at":"2025-04-19T12:07:57.888Z","repository":{"id":251636980,"uuid":"837979070","full_name":"ksylvest/analytic","owner":"ksylvest","description":null,"archived":false,"fork":false,"pushed_at":"2024-12-11T21:06:46.000Z","size":409,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-10T23:51:05.997Z","etag":null,"topics":["analytics","ruby"],"latest_commit_sha":null,"homepage":"https://analytic.ksylvest.com/","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/ksylvest.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2024-08-04T15:49:16.000Z","updated_at":"2024-12-11T21:06:50.000Z","dependencies_parsed_at":"2024-08-08T01:36:59.656Z","dependency_job_id":"cc57ed02-6298-475f-bf1c-2429724f67a3","html_url":"https://github.com/ksylvest/analytic","commit_stats":null,"previous_names":["ksylvest/analytic"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ksylvest%2Fanalytic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ksylvest%2Fanalytic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ksylvest%2Fanalytic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ksylvest%2Fanalytic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ksylvest","download_url":"https://codeload.github.com/ksylvest/analytic/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235233261,"owners_count":18957066,"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":["analytics","ruby"],"created_at":"2024-10-09T02:41:22.540Z","updated_at":"2025-01-23T06:13:45.491Z","avatar_url":"https://github.com/ksylvest.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Analytic\n\n[![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ksylvest/analytic/blob/main/LICENSE)\n[![RubyGems](https://img.shields.io/gem/v/analytic)](https://rubygems.org/gems/analytic)\n[![GitHub](https://img.shields.io/badge/github-repo-blue.svg)](https://github.com/ksylvest/analytic)\n[![Yard](https://img.shields.io/badge/docs-site-blue.svg)](https://analytic.ksylvest.com)\n[![CircleCI](https://img.shields.io/circleci/build/github/ksylvest/analytic)](https://circleci.com/gh/ksylvest/analytic)\n[![CodeClimate Maintainability](https://api.codeclimate.com/v1/badges/005074b4a948038893a9/maintainability)](https://codeclimate.com/github/ksylvest/analytic/maintainability)\n[![CodeClimate Test Coverage](https://api.codeclimate.com/v1/badges/005074b4a948038893a9/test_coverage)](https://codeclimate.com/github/ksylvest/analytic/test_coverage)\n\n![Demo](https://raw.githubusercontent.com/ksylvest/analytic/refs/heads/main/demo.png)\n\nAnalytic provides visitor / session / view tracking without the need for any third-party service.\n\n## Installation\n\n```bash\n$ bundle add analytic\n$ bin/rails analytic:install:migrations\n$ bin/rails db:migrate\n```\n\n```ruby\n# config/routes.rb\nRails.application.routes.draw do\n  mount Analytic::Engine, at: '/analytic'\nend\n```\n\n## Usage\n\nDefault inline tracking is configured with:\n\n```ruby\nclass ApplicationController\n  include Analytic::Trackable\n\n  before_action :analytic_track!, if: -\u003e { request.format.html? }\nend\n```\n\nAlternative job tracking is configured with:\n\n```ruby\nclass ApplicationController\n  include Analytic::Trackable\n\n  before_action :analytic_enqueue_track_job!, if: -\u003e { request.format.html? }\nend\n```\n\n_note: a queue such as sidekiq, rescue, etc must be running to see tracking_\n\n## Configuration\n\n### Authentication the Dashboard\n\nBy default **Analytic** is not authenticated. To authenticate using `Rack::Auth` generate a random username and password:\n\n```ruby\n$ bin/rails secret # generate a secret\n$ bin/rails credentials:edit\n```\n\n```yaml\nanalytic:\n  username: abc...\n  password: def...\n```\n\n```ruby\n# config/initializers/analytic.rb\n\ndef same?(src, dst)\n  # https://api.rubyonrails.org/classes/ActiveSupport/SecurityUtils.html\n  ActiveSupport::SecurityUtils.secure_compare(src, dst)\nend\n\nAnalytic.configure do |config|\n  unless Rails.env.local?\n    config.use Rack::Auth::Basic do |username, password|\n      credentials = Rails.application.credentials.analytic\n      same?(username, credentials.username) \u0026\u0026 same?(password, credentials.password)\n    end\n  end\nend\n```\n\n### Capturing Extra Parameters\n\nBy default **Analytic** tracks `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, `utm_term`, `ref` and `source` parameters for each request. This list can be customized using:\n\n```ruby\n# config/initializer/analytic.rb\nAnalytic.configure do |config|\n  config.params \u003c\u003c :gclid # e.g. Google\n  config.params \u003c\u003c :msclkid # e.g. Bing\nend\n```\n\n### Changing the Time Zone\n\nBy default **Analytic** uses `Time.zone`. The time zone can be changed using:\n\n```ruby\n# config/application.rb\nclass Application \u003c Rails::Application\n  config.time_zone = 'Canada/Pacific'\nend\n```\n\nThe time zone may also be specified for **Analytic** using any `ActiveSupport::TimeZone`:\n\n```ruby\n# config/initializer/analytic.rb\nAnalytic.configure do |config|\n  config.time_zone = Time.find_zone('Canada/Pacific')\nend\n```\n\n### Changing the Database\n\nBy default **Analytic** uses your apps main database. The database can be changed using:\n\n```ruby\n# config/initializer/analytic.rb\nAnalytic.configure do |config|\n  config.connects_to = { database: { writing: :primary, reading: :replica } }\nend\n```\n\n### Overriding IP Masking Rules\n\nBy default IP addresses are masked as follows:\n\n- IPv4: limit to leading 24-bits (e.g. '255.255.255.255' becomes '255.255.255.0')\n- IPv6: limit to leading 48-bits (e.g. 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' becomes 'ffff:ffff:ffff:0000:0000:0000:0000:0000')\n\nTo override both an `ip_v4_mask` and `ip_v6_mask` are assignable:\n\n```ruby\nAnalytic.configure do |config|\n  config.ip_v4_mask = 24 # nil skips masking\n  config.ip_v6_mask = 48 # nil skips masking\n```\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fksylvest%2Fanalytic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fksylvest%2Fanalytic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fksylvest%2Fanalytic/lists"}