Analytics for Ruby
Maintenance libraries send data as intended but receive no new feature support and only critical maintenance updates from Segment. When possible, Segment recommends using a Flagship version of these libraries.
Segment’s Ruby library lets you record analytics data from your ruby code. The requests hit Segment servers, and then Segment routes your data to any analytics service you enable on your destinations page.
This library is open-source, so you can check it out on GitHub.
All of Segment’s server-side libraries are built for high-performance, so you can use them in your web server controller code. This library uses an internal queue to make Identify and Track calls non-blocking and fast. It also batches messages and flushes asynchronously to Segment’s servers.
Want to stay updated on releases? Subscribe to the release feed.
Getting Started
If you’re using Bundler, add the following line to your project’s Gemfile
:
gem 'analytics-ruby', '~> 2.4.0', :require => 'segment/analytics'
Or, if you’re using the gem directly from your application, you’ll need to:
gem install analytics-ruby
Then initialize the gem with your Segment source’s Write Key and an optional error handler, like so:
require 'segment/analytics'
Analytics = Segment::Analytics.new({
write_key: 'YOUR_WRITE_KEY',
on_error: Proc.new { |status, msg| print msg }
})
That will create an instance of Analytics
that you can use to send data to Segment for your source.
If you’re using Rails, you can stick that initialization logic in config/initializers/analytics_ruby.rb
and omit the require
call.
The analytics-ruby gem makes requests asynchronously, which can sometimes be suboptimal and difficult to debug if you’re pairing it with a queuing system like Sidekiq/delayed job/sucker punch/resqueue. If you prefer to use a gem that makes requests synchronously, you can use simple_segment
, an API-compatible drop-in replacement for the standard gem that does its work synchronously inline. If you choose to use simple_segment
, please note that because the simple_segment
package isn’t owned and maintained directly by Segment, Segment wont’ be able to provide support for it.
Regional configuration
For Business plans with access to Regional Segment, you can use the host
configuration parameter to send data to the desired region:
- Oregon (Default) —
api.segment.io/
- Dublin —
events.eu1.segmentapis.com/
Identify
Good to know: For any of the different methods described on this page, you can replace the properties and traits in the code samples with variables that represent the data collected.
The Identify method is how you associate your users and their actions to a recognizable userId
and traits
. You can find details on the identify method payload in the Spec.
The Identify call has the following fields:
Field | Type | Description |
user_id |
String | ID for this user in your database. Optional if anonymous_id is provided. |
anonymous_id |
String | The ID associated with the user when you don’t know who they are. Optional if user_id is provided. |
traits |
Hash | A Hash of traits you know about the user. Things like: email , name or friends . |
context , optional |
Hash | A Hash that can include things like user_agent or ip . |
integrations , optional |
Hash | Specifies which destinations this should be sent to. |
timestamp , optional |
Time | Represents the time when the action took place. This is most useful if you’re importing historical data. If the identify just happened, leave it blank and we’ll use the server’s time. |
message_id , optional |
String | Unique identifier for each message that lets you find an individual message across the API. |
Example Identify:
Analytics.identify(
user_id: '019mr8mf4r',
traits: { email: "#{ user.email }", friends: 872 },
context: {ip: '8.8.8.8'})
This example call identifies your user by their unique User ID (the one you know him by in your database) and labels them with email
and friends
traits.
Track
The Track method lets you record any actions your users perform. You can find details on the Track method payload.
The Track call has the following fields:
Field | Type | Description |
user_id |
String | ID for this user in your database. Optional if anonymous_id is provided. |
anonymous_id |
String | The ID associated with the user when you don’t know who they are. Optional if user_id is provided. |
event |
String | The name of the event you’re tracking. Segment recommends human-readable names like Song Played or Status Updated. |
properties , optional |
Hash | A Hash of properties for the event. If the event was Product Added to their cart, it might have properties like price or product . |
context , optional |
Hash | A Hash that can include things like user_agent or ip . |
integrations , optional |
Hash | Specifies which destinations this should be sent to. |
timestamp , optional |
Time | Represents the time when the action took place. This is most useful if you’re importing historical data. If the identify just happened, leave it blank and we’ll use the server’s time. |
message_id , optional |
String | Unique identifier for each message that lets you find an individual message across the API. |
You should track events that are indicators of success for your site, like Signed Up, Item Purchased or Article Bookmarked.
To get started, Segment recommends tracking just a few important events. You can always add more later.
Example Track call:
Analytics.track(
user_id: '019mr8mf4r',
event: 'Item Purchased',
properties: { revenue: 39.95, shipping: '2-day' })
This example Track call tells you that your user just triggered the Item Purchased event with a revenue of $39.95 and chose your hypothetical ‘2-day’ shipping.
Track event properties can be anything you want to record, for example:
Analytics.track(
user_id: 'f4ca124298',
event: 'Article Bookmarked',
properties: {
title: 'Snow Fall',
subtitle: 'The Avalance at Tunnel Creek',
author: 'John Branch'
})
For more information about choosing which events to track, event naming and more, check out Analytics Academy.
Page
The Page method lets you record page views on your website, along with optional extra information about the page being viewed.
If you’re using Segment’s client-side set up in combination with the Ruby library, page calls are already tracked for you by default. However, if you want to record your own page views manually and aren’t using the client-side library, read on.
The Page call has the following fields:
Field | Type | Description |
user_id |
String | ID for this user in your database. Optional if anonymous_id is provided. |
anonymous_id |
String | The ID associated with the user when you don’t know who they are. Optional if user_id is provided. |
name |
String | The name of the page, for example Signup or Home. |
category optional |
String | The category of the page. Useful for industries, like ecommerce, where many pages might live under a larger category. Note: if you only pass one string to Page, Segment assumes it’s a name , not a category . You must include a name if you want to send a category . |
properties , optional |
Hash | A Hash of properties for the page. |
context , optional |
Hash | A Hash that can include things like user_agent or ip . |
integrations , optional |
Hash | Specifies which destinations this should be sent to. |
timestamp , optional |
Time | Represents the time when the action took place. This is most useful if you’re importing historical data. If the identify just happened, leave it blank and we’ll use the server’s time. |
message_id , optional |
String | Unique identifier for each message that lets you find an individual message across the API. |
Example Page call:
Analytics.page(
user_id: user_id,
category: 'Docs',
name: 'Ruby library',
properties: { url: 'https://segment.com/libraries/ruby/' })
Find details on the Page payload in the Segment Spec.
Group
The Group method associates an identified user with a company, organization, project, workspace, team, tribe, platoon, assemblage, cluster, troop, gang, party, society or any other name you came up with for the same concept.
This is useful for tools like Intercom, Preact and Totango, as it ties the user to a group of other users.
The Group call has the following fields:
user_id |
String | ID for this user in your database. Optional if anonymous_id is provided. |
anonymous_id |
String | The ID associated with the user when you don’t know who they are. Optional if user_id is provided. |
group_id |
String | The ID of the group. |
traits optional |
Hash | A hash of traits you know about the group. For a company, they might be things like name , address , or phone . |
context , optional |
Hash | A Hash that can include things like user_agent or ip . |
integrations , optional |
Hash | Specifies which destinations this should be sent to. |
timestamp , optional |
Time | Represents the time when the action took place. This is most useful if you’re importing historical data. If the identify just happened, leave it blank and we’ll use the server’s time. |
message_id , optional |
String | Unique identifier for each message that lets you find an individual message across the API. |
Example Group call:
Analytics.group(
user_id: '019mr8mf4r',
group_id: '56',
traits: { name: 'Initech', description: 'Accounting Software'})
Find more details about Group including the Group payload in the Segment Spec.
Alias
Alias is how you associate one identity with another. This is an advanced method, but it is required to manage user identities successfully in some destinations.
In Mixpanel it’s used to associate an anonymous user with an identified user once they sign up. For Kissmetrics, if your user switches IDs, you can use Alias to rename the ‘userId’.
Alias method definition:
Analytics.alias(previous_id: 'previous id', user_id: 'new id')
The Alias call has the following fields:
userId |
String | The ID for this user in your database. |
previousId |
String | The previous ID to alias from. |
Here’s a full example of how you might use the Alias call:
# the anonymous user does actions ...
Analytics.track(user_id: 'anonymous_user', event: 'Anonymous Event')
# the anonymous user signs up and is aliased
Analytics.alias(previous_id: 'anonymous id', user_id: 'user id')
# the identified user is identified
Analytics.identify(user_id: 'user id', traits: { plan: 'Free' })
# the identified user does actions ...
Analytics.track(user_id: 'user id', event: 'Identified Action')
For more details about Alias, including the Alias call payload, check out the Segment Spec.
Historical Import
You can import historical data by adding the timestamp
argument to any of your method calls. This can be helpful if you’ve just switched to Segment.
Historical imports can only be done into destinations that can accept historical timestamped data. Most analytics tools like Mixpanel, Amplitude, Kissmetrics, etc. can handle that type of data just fine. One common destination that does not accept historical data is Google Analytics since their API cannot accept historical data.
Note: If you’re tracking things that are happening right now, leave out the timestamp
and Segment’s servers will timestamp the requests for you.
Selecting Destinations
The Alias, Group, Identify, Page, and Track calls can all be passed an object of integrations
that lets you turn certain destinations on or off. By default all destinations are enabled.
Here’s an example Track call with the integrations
object shown.
Analytics.track({
user_id: '83489',
event: 'Song Paused',
integrations: { All: false, Kissmetrics: true }
})
In this case, you’re specifying that you want this identify to only go to Kissmetrics. All: false
says that no destination should be enabled unless otherwise specified, and Kissmetrics: true
turns on Kissmetrics.
Destination flags are case sensitive and match the destination’s name in the docs (for example, “AdLearn Open Platform”, “awe.sm”, or “MailChimp”).
Note:
-
Business Tier users can filter Track calls right from the Segment UI on your source schema page. Segment recommends using the UI if possible since it’s a much simpler way of managing your filters and can be updated with no code changes on your side.
-
If you are on a grandfathered plan, events sent server-side that are filtered through the Segment dashboard still count towards your API usage.
Performance
Segment’s libraries are built to support high performance environments. That means it is safe to use analytics-ruby on a web server that’s serving hundreds of requests per second.
Every method you call does not result in an HTTP request, but is queued in memory instead. Messages are flushed in batch in the background, which allows for much faster operation.
By default, Segment’s library will flush:
- the very first time it gets a message
- whenever messages are queued and there is no outstanding request
There is a maximum of 500KB
per batch request and 32KB
per call.
HTTP Tracking API limits
Segment's HTTP Tracking API accepts batch requests up to 500KB. To avoid errors in event creation, ensure that individual event payload sizes remain below 32KB.
The queue consumer makes only a single outbound request at a time to avoid saturating your server’s resources. If multiple messages are in the queue, they are sent together in a batch call.
You can specify the following additional options to determine how the queue operates and to help debug possible errors. None of them are required for normal operation.
# Error handler to log statements
Segment::Analytics.new({
write_key: 'YOUR_WRITE_KEY',
on_error: Proc.new { |status, msg| print msg },
max_queue_size: 10000,
batch_size: 100,
stub: true
})
on_error optional |
Proc | A handler which is called whenever errors are returned from the API. Useful for debugging and first time destinations. |
max_queue_size optional |
FixNum | The max number of messages to put in the queue before refusing to queue more (defaults to 10,000 ). |
batch_size optional |
FixNum | The max number of events/identifies to send in a single batch (defaults to 100 ). The API servers will not respond to messages over a certain size, so 100 is a safe default. |
stub optional |
TrueClass|FalseClass | If true, the requests don’t hit the server and are stubbed to be successful (defaults to false ). |
Flush
If you’re running a script or internal queue system to upload data, you should call Analytics.flush
at the end of execution to ensure that all of your messages are sent to our servers. Segment also recommendeds that you call flush
on shutdown, so that all queued messages are sent to Segment instead of waiting for the next launch.
AppAnalytics = Segment::Analytics.new({
write_key: 'ONE_WRITE_KEY'
})
AppAnalytics.flush
success “” Tip: When you call
flush
, the call blocks execution on the thread until it finishes processing all the messages in the queue. If you want to callflush
during the normal operation of your application, you can spawn a local worker thread and call flush on the worker. This prevents the call from blocking the main thread.
Turbolinks
If you’re using Ruby on Rails with the Turbolinks setting enabled, and you’re adding Analytics.js on your website, you’ll need to tweak the default configuration.
Instead of having the entire snippet in the <head>
of your site, you need to move the analytics.page()
call that is included in the snippet by default into the <body>
so that it will get triggered on every new page load. But you must have the first part of the snippet in the <head>
or the library will fail to load properly.
Serialization
The Ruby library will automatically handle serializating your data into JSON for Segment’s servers. It uses JSON.generate
under the hood. Note that BigDecimal
values are intentionally sent as Strings rather than floats so that our Node servers don’t lose precision. If you’d prefer to use a float, you can coerce values to a float before sending the data to Segment.
Multiple Clients
Different parts of your application may require different types of batching, or even sending to multiple Segment sources. In that case, you can initialize multiple instances of Analytics
with different settings:
AppAnalytics = Segment::Analytics.new({
write_key: 'ONE_WRITE_KEY'
})
MarketingAnalytics = Segment::Analytics.new({
write_key: 'ANOTHER_WRITE_KEY'
})
Troubleshooting
The following tips often help resolve common issues.
No events in my debugger
-
Double check that you’ve followed all the steps in the Quickstart.
-
Make sure that you’re calling a Segment API method once the library is successfully installed—
identify
,track
, etc. -
Make sure your application isn’t shutting down before the
Analytics.Client
local queue events are pushed to Segment. You can manually callAnalytics.Client.Flush()
to ensure the queue is fully processed before shutdown.
Other common errors
If you are experiencing data loss from your Ruby source, you may be experiencing one or more of the following common errors:
-
Payload is too large: If you attempt to send events larger than 32KB per normal API request or batches of events larger than 500KB per request, Segment’s tracking API responds with
400 Bad Request
. Try sending smaller events (or smaller batches) to correct this error. -
Identifier is not present: Segment’s tracking API requires that each payload has a
userId
and/oranonymousId
. If you send events without either theuserId
oranonymousId
, Segment’s tracking API responds with anno_user_anon_id
error. Check the event payload and client instrumentation for more details. -
Track event is missing name: All Track events to Segment must have a name in string format.
-
Event dropped during deduplication: Segment automatically adds a
messageId
field to all payloads and uses this value to deduplicate events. If you’re manually setting amessageId
value, ensure that each event has a unique value. -
Incorrect credentials: Double check your credentials for your downstream destination(s).
-
Destination incompatibility: Make sure that the destination you are troubleshooting can accept server-side API calls. You can see compatibility information on the Destination comparison by category page and in the documentation for your specific destination.
-
Destination-specific requirements: Check out the destination’s documentation to see if there are other requirements for using the method and destination that you’re trying to get working.
This page was last modified: 30 May 2024
Need support?
Questions? Problems? Need more info? Contact Segment Support for assistance!