Coder Social home page Coder Social logo

analytics-ruby's Introduction

analytics-ruby

analytics-ruby is a ruby client for Segment

⚠️ Maintenance ⚠️

This library is in maintenance mode. It will send data as intended, but receive no new feature support and only critical maintenance updates from Segment.

You can't fix what you can't measure

Analytics helps you measure your users, product, and business. It unlocks insights into your app's funnel, core business metrics, and whether you have product-market fit.

How to get started

  1. Collect analytics data from your app(s).
    • The top 200 Segment companies collect data from 5+ source types (web, mobile, server, CRM, etc.).
  2. Send the data to analytics tools (for example, Google Analytics, Amplitude, Mixpanel).
    • Over 250+ Segment companies send data to eight categories of destinations such as analytics tools, warehouses, email marketing and remarketing systems, session recording, and more.
  3. Explore your data by creating metrics (for example, new signups, retention cohorts, and revenue generation).
    • The best Segment companies use retention cohorts to measure product market fit. Netflix has 70% paid retention after 12 months, 30% after 7 years.

Segment collects analytics data and allows you to send it to more than 250 apps (such as Google Analytics, Mixpanel, Optimizely, Facebook Ads, Slack, Sentry) just by flipping a switch. You only need one Segment code snippet, and you can turn integrations on and off at will, with no additional code. Sign up with Segment today.

Why?

  1. Power all your analytics apps with the same data. Instead of writing code to integrate all of your tools individually, send data to Segment, once.

  2. Install tracking for the last time. We're the last integration you'll ever need to write. You only need to instrument Segment once. Reduce all of your tracking code and advertising tags into a single set of API calls.

  3. Send data from anywhere. Send Segment data from any device, and we'll transform and send it on to any tool.

  4. Query your data in SQL. Slice, dice, and analyze your data in detail with Segment SQL. We'll transform and load your customer behavioral data directly from your apps into Amazon Redshift, Google BigQuery, or Postgres. Save weeks of engineering time by not having to invent your own data warehouse and ETL pipeline.

    For example, you can capture data on any app:

    analytics.track('Order Completed', { price: 99.84 })

    Then, query the resulting data in SQL:

    select * from app.order_completed
    order by price desc

🚀 Startup Program

If you are part of a new startup (<$5M raised, <2 years since founding), we just launched a new startup program for you. You can get a Segment Team plan (up to $25,000 value in Segment credits) for free up to 2 years — apply here!

Install

Into Gemfile from rubygems.org:

gem 'analytics-ruby'

Into environment gems from rubygems.org:

gem install 'analytics-ruby'

Usage

Create an instance of the Analytics object:

analytics = Segment::Analytics.new(write_key: 'YOUR_WRITE_KEY')

Identify the user for the people section, see more here.

analytics.identify(user_id: 42,
                   traits: {
                     email: '[email protected]',
                     first_name: 'Foo',
                     last_name: 'Bar'
                   })

Alias an user, see more here.

analytics.alias(user_id: 41)

Track a user event, see more here.

analytics.track(user_id: 42, event: 'Created Account')

There are a few calls available, please check the documentation section.

Documentation

Documentation is available at segment.com/docs/sources/server/ruby

Test Queue

You can use the test: true option to Segment::Analytics.new to cause all requests to be saved to a test queue until manually reset. All events will process as specified by the configuration, and they will also be stored in a separate queue for inspection during testing.

A test queue can be used as follows:

client = Segment::Analytics.new(write_key: 'YOUR_WRITE_KEY', test: true)

client.test_queue # => #<Segment::Analytics::TestQueue:0x00007f88d454e9a8 @messages={}>

client.track(user_id: 'foo', event: 'bar')

client.test_queue.all
# [
#     {
#            :context => {
#             :library => {
#                    :name => "analytics-ruby",
#                 :version => "2.2.8.pre"
#             }
#         },
#          :messageId => "e9754cc0-1c5e-47e4-832a-203589d279e4",
#          :timestamp => "2021-02-19T13:32:39.547+01:00",
#             :userId => "foo",
#               :type => "track",
#              :event => "bar",
#         :properties => {}
#     }
# ]

client.test_queue.track
# [
#     {
#            :context => {
#             :library => {
#                    :name => "analytics-ruby",
#                 :version => "2.2.8.pre"
#             }
#         },
#          :messageId => "e9754cc0-1c5e-47e4-832a-203589d279e4",
#          :timestamp => "2021-02-19T13:32:39.547+01:00",
#             :userId => "foo",
#               :type => "track",
#              :event => "bar",
#         :properties => {}
#     }
# ]

# Other available methods
client.test_queue.alias # => []
client.test_queue.group # => []
client.test_queue.identify # => []
client.test_queue.page # => []
client.test_queue.screen # => []

client.test_queue.reset!

client.test_queue.all # => []

Note: It is recommended to call reset! before each test to ensure your test queue is empty. For example, in rspec you may have the following:

RSpec.configure do |config|
  config.before do
    Analytics.test_queue.reset!
  end
end

And also to stub actions use stub: true along with test: true so that it doesn't send any real calls during specs.

License

WWWWWW||WWWWWW
 W W W||W W W
      ||
    ( OO )__________
     /  |           \
    /o o|    MIT     \
    \___/||_||__||_|| *
         || ||  || ||
        _||_|| _||_||
       (__|__|(__|__|

(The MIT License)

Copyright (c) 2013 Segment Inc. [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

analytics-ruby's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

analytics-ruby's Issues

issue with identify/track being called in a loop

e.g.

require 'logger'
require 'segment/analytics'
require 'rake'

Analytics = Segment::Analytics.new :write_key => "YOUR_WRITE_KEY"
log = Logger.new STDOUT

(1..10).each do |i| 
  log.info "identify"
  Analytics.identify(
    user_id: "travis",
    traits: {
      email: "[email protected]",
    }
  )

  log.info "track"
  Analytics.track(
    user_id: "travis",
    event: 'Activated'
  )
end

log.info "About to flush analytics calls"
Analytics.flush
log.info "Done flushing"

Idiomatic Ruby

https://github.com/segmentio/analytics-ruby/blob/master/lib/analytics-ruby/client.rb#L118-L124

Generally in ruby most developers don't do much explicit type checking. It's not a big deal but I had to crack open the source to see that it required a String. The error message wasn't even clear about that.
A better approach might be to call the method .to_s on the user_id and coerce it into a string inside that method.

The use case is a simple rails example.

u = User.find 53
Analytics.identify(user_id: u.id, traits:{email: u.email,twitter: u.twitter_name, username: u.username})
# => ArgumentError: Must supply a non-empty user_id

The id in that case is a number so it failed.

So it forces me to call the method like this with to_s on the u.id.

...
Analytics.identify(user_id: u.id.to_s,   ...)
# => true

Ongoing changes for API v2

https://github.com/segmentio/spec

  • Use HTTP Basic Auth with the project's Write Key.
  • Rename to anonymousId from sessionId for clarity.
  • Separate integrations (was providers) object from context, for cleaner logs.
  • Add requestId for easily tracing calls through to the raw logs.
  • Change library to be a object with name and version for consistency.

Memory leak on JRuby

JRuby application servers that can do hot redeploys will shut down the old JRuby runtime without exiting the process. In the consumer processor, analytics-ruby creates a thread that won't shut down until the process dies. This thread will cause a stopped JRuby runtime to sit around in memory much longer than necessary (they appear to be weakrefs and as such, should eventually be GC'd).

The simple fix is to flag the thread in an at_exit handler. I did this for another project:

https://github.com/wr0ngway/lumber/blob/a35520abace41a87b455b15398be630e7ef5b2da/lib/lumber/level_util.rb#L83

The additional trick here will be to stop the consumer queue from blocking.

add debug logging

so that the user can monitor when requests/flushes happen and check out the requestIds

Development/Test Mode

Would be awesome to have a 'dev mode' when instead of actually sending requests it would do some action (log for example).

This could be implemented as simple dependency injection on Client and Consumer.
Consumer would instead of doing Request.new do @requester.new
Like:

Analytics.init(secret: nil)
Analytics.client.consumer.requester = MyClass

class MyClass
  def post(*)
  end
end
``

This would allow *testing* and *logging* in developer mode.

There is a race condition with the group method.

I've noticed that occasionally group seems to execute before the identify call for a given user. This happens despite the fact group was called after identify. This causes two users with the same id to be created in Intercom. One of the users has all the right user traits but isn't associated to a company where as the other user is associated to the company but only has the right id set.

Unable to add analytics-ruby Gem

I can't seem to get the 'analytics-ruby' gem working.

After adding it to my gemfile, I either get

uninitialized constant AnalyticsRuby

or when I add require 'analytics-ruby' I get

cannot load such file -- analytics-ruby

Any ideas?

Track should allow hash arguments to be strings

I'm enqueuing a tracking job in Redis that consists of a simple hash. When the hash is deserialized, it's no longer a Hash#with_indifferent_access, so the keys come in as strings.

I'm manually calling Hash#with_indifferent_access, but it seems fairly rigid to require the keys to be symbols.

I can submit a pull request if it makes sense.

Heroku thread errors

I'm having problems with the gem causing ThreadError exceptions on heroku.

My application is Rails 3.2.14 and I'm running a Unicorn 4.6.3 web server.

Here is how I'm invoking the gem in my unicorn.rb in the after_fork:

defined?(Analytics) and Analytics.init(secret: ENV['segment_secret_key']) if ENV['segment_secret_key'].present?

and here are the methods in my application controller where I'm invoking the gem:

def analytics_client
    client = nil

    if Settings.segment_secret_key.present?
      client_options = { secret: Settings.segment_secret_key }
      client = AnalyticsRuby::Client.new(client_options)

      identify_options = nil

      if user_signed_in?
        client.alias(from: cookies[:user_uuid], to: current_user.channel_token)

        identify_options = { user_id: current_user.channel_token, created: current_user.created_at.iso8601, name: current_user.name, type: 'user', email: current_user.email }
      elsif salon_signed_in?
        client.alias(from: cookies[:user_uuid], to: current_salon.channel_token)

        identify_options = { user_id: current_salon.channel_token, created: current_salon.created_at.iso8601, name: current_salon.name, type: 'salon', email: current_salon.email }
      else
        identify_options = { user_id: cookies[:user_uuid] }
      end

      client.identify(identify_options)
    end

    client
  end

  def track_event(event_string, properties={})
    analytics ||= analytics_client

    if analytics.present?
      user_id = nil

      if user_signed_in?
        user_id = current_user.channel_token
      elsif salon_signed_in?
        user_id = current_salon.channel_token
      else
        user_id = cookies[:user_uuid]
      end

      options = {
        user_id: user_id,
        event: event_string,
        properties: properties
      }

      analytics.track(options)
    end
  end

Several times a week now I get a ThreadError: can't create thread
when it tries to create a new instance of the Analytics client. This is effectively causing my application to fail as the track_event method is called on most application pages.

I'd love to hear any thoughts on why this may be happening. I realize it could be other parts of my application, but this client is the main things that's creating new threads. The problem has gotten worse as I've added more analytics events.

Alternatively, I'd like to hear your thoughts on the best way to rescue from the ThreadError in my code.

Any help appreciated.

Thanks,
Mark

Clean up / spec

  • namespace under segment::analytics
  • add shortcut for namespace
  • update to spec

segmentio error class

Suggested by the treble.io guys: adding a special error class for segment.io errors. We should only be throwing on initialization, but it's probably still a good idea to have.

Synchronous mode

Currently if analytics-ruby is notconfigured at all, misconfigured or for a variety of reasons like #14, calls made to it fail silently. This is problematic because 1) we don't know that things are not working as they should and 2) once we are aware that something is wrong (typically we see no data) we have no diagnostics for why the problem exists, or how to fix it.

Please add a way to have analytics-ruby do all of its work inline, synchronously, and raise exceptions for all errors.

Improve release notes for 0.5.0 release

The release notes for the 0.5.0 release has a single entry:

Removing global Analytics alias in favor of adding it to our config

It should probably be elaborated that this change will break your config and you won't be logging any analytics until you switch the name of your constant. Fortunately we caught the problem before we went days without analytics.

SSL_connect error when using identify

Everything works in the javascript on my rails app. But when I call AnalyticsRuby.identify for a user on signup, I get this error:
err: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed retries: 4
It then retries a few times with a few seconds in between and fails with the same error each time.

I've tried setting AnalyticsRuby::Defaults::Request::SSL to false, but then it fails with: err: An established connection was aborted by the software in your host machine. retries: 4
Which then retries the same way.

I do not have SSL set up on my project. I'm not getting any build errors or dependency errors.

How to set integrations?

Sorry this is a question, but I don't seem to be able to define integrations on .identify calls using analytics-ruby. It works fine using analytics.js.

Below is what I've tried and the resulting output in the debugger raw tab for the call. In both cases data is still being sent to Intercom I'm totally stumped. I'm not very well versed in Ruby and doing my best to add this in to our existing code. Also please note, I'm using v1.1.0 because the later versions don't seem to work for me, not sure if they're incompatible with something.

    Analytics.identify(
      user_id: current_user.id,
      traits: { email: current_user.email_address, username: current_user.username },
      integrations: { Intercom: false }
  ) 

Results in the following in the debugger (raw):

{
  "userId": "...",
  "traits": {
    "email": "...",
    "username": "..."
  },
  "timestamp": "2014-06-29T14:30:52.000Z",
  "requestId": "...",
  "writeKey": "...",
  "receivedAt": "2014-06-29T14:34:53.774Z",
  "type": "identify",
  "integrations": {},
    "library": {
      "name": "analytics-ruby",
      "version": "unknown"
    }
  }
}

And

    Analytics.identify(
      user_id: current_user.id,
      traits: { email: current_user.email_address, username: current_user.username },
      context: { integrations: { Intercom: false } }
  ) 

results in:

{
  "userId": "...",
  "traits": {
    "email": "...",
    "username": "..."
  },
  "timestamp": "2014-06-29T14:30:52.000Z",
  "requestId": "...",
  "writeKey": "...",
  "receivedAt": "2014-06-29T14:34:53.774Z",
  "type": "identify",
  "integrations": {},
  "options": {
    "integrations": {
      "Intercom": false
    },
    "library": {
      "name": "analytics-ruby",
      "version": "unknown"
    }
  }
}

Util module should be namespaced

Util is a very generic name.
My application was erroring since I had a class with the same name and Util module from the gem conflicted.
I am not sure, what the guidelines are with the project. Would be happy to send a PR fixing this.

why convert user_id to string?

Hi,

Could you explain why do you convert user_id to string ?

This has caused us a lot of trouble implementing segment.io into our apps because we usr integer for the user_id and since the javascript library doesn't convert it to a string, it created weird behaviour in Kissmetrics & Intercom.io for us (example)...

I think you should let us, the user, define what type of value we want to pass so we can easily keep some kind of consistency across the tool, since after this is what segment.io is for.

Cheers,
S

undefined method `is_requesting?' for nil:NilClass when calling flush

I'm making some identify and track calls in a rake task before then calling flush at the end of the task and sometimes the rake task gets aborted due to the following error:

undefined method `is_requesting?' for nil:NilClass
/Users/hamiltonchapman/.rvm/gems/ruby-2.0.0-p451/gems/analytics-ruby-2.0.1/lib/segment/analytics/client.rb:37:in `flush'
/Users/hamiltonchapman/.rvm/gems/ruby-2.0.0-p451/gems/analytics-ruby-2.0.1/lib/segment/analytics.rb:19:in `method_missing'

Client not properly initializing in Rails app

I am attempting to use this library in a Rails app, and I can't seem to figure out exactly what is going on.

I followed the instructions provided in the documentation, but when I call Analytics.track, the event never shows up on the segment.io dashboard.

Everything works fine when I manually init in the console, but not when the code is in an initializer.

When I log out the client when I manually call init in the console:

=> #<AnalyticsRuby::Client:0x007fa79e128cc8
 @consumer=
  #<AnalyticsRuby::Consumer:0x007fa79e128a98
   @batch_size=100,
   @current_batch=[],
   @mutex=#<Mutex:0x007fa79e128908>,
   @on_error=
    #<Proc:0x007fa79e128958@/Users/Shane/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/analytics-ruby-0.5.0/lib/analytics-ruby/consumer.rb:27>,
   @queue=
    #<Queue:0x007fa79e128bd8
     @cond=
      #<ConditionVariable:0x007fa79e128b60
       @waiters={#<Thread:0x007fa79e1288e0 sleep>=>true},
       @waiters_mutex=#<Mutex:0x007fa79e128ac0>>,
     @mutex=#<Mutex:0x007fa79e128b88>,
     @num_waiting=1,
     @que=[]>,
   @secret="omitted">,
 @max_queue_size=10000,
 @queue=
  #<Queue:0x007fa79e128bd8
   @cond=
    #<ConditionVariable:0x007fa79e128b60
     @waiters={#<Thread:0x007fa79e1288e0 sleep>=>true},
     @waiters_mutex=#<Mutex:0x007fa79e128ac0>>,
   @mutex=#<Mutex:0x007fa79e128b88>,
   @num_waiting=1,
   @que=[]>,
 @secret="omitted",
 @thread=#<Thread:0x007fa79e1288e0 sleep>>

When I log out the client when created in the initializer:

=> #<AnalyticsRuby::Client:0x007ff730811828
 @consumer=
  #<AnalyticsRuby::Consumer:0x007ff730810888
   @batch_size=100,
   @current_batch=[],
   @mutex=#<Mutex:0x007ff730810220>,
   @on_error=
    #<Proc:0x007ff730811d50@/Users/Shane/Dropbox/Development/tilt/tilt365/config/initializers/analytics_ruby.rb:3>,
   @queue=
    #<Queue:0x007ff730810dd8
     @cond=
      #<ConditionVariable:0x007ff730810978
       @waiters={},
       @waiters_mutex=#<Mutex:0x007ff7308108d8>>,
     @mutex=#<Mutex:0x007ff730810a68>,
     @num_waiting=1,
     @que=
      [{:event=>"This is weird.",
        :userId=>"11422",
        :context=>{:library=>"analytics-ruby"},
        :properties=>{},
        :timestamp=>"2013-11-12T12:44:37-05:00",
        :action=>"track"}]>,
   @secret="omitted">,
 @max_queue_size=10000,
 @queue=
  #<Queue:0x007ff730810dd8
   @cond=
    #<ConditionVariable:0x007ff730810978
     @waiters={},
     @waiters_mutex=#<Mutex:0x007ff7308108d8>>,
   @mutex=#<Mutex:0x007ff730810a68>,
   @num_waiting=1,
   @que=
    [{:event=>"This is weird.",
      :userId=>"11422",
      :context=>{:library=>"analytics-ruby"},
      :properties=>{},
      :timestamp=>"2013-11-12T12:44:37-05:00",
      :action=>"track"}]>,
 @secret="omitted",
 @thread=#<Thread:0x007ff7308101d0 dead>>

I am not at all experienced with threaded programming, but dead sounds like the issue. The event is still sitting in the queue.

I am using Unicorn in production (unicorn-rails in development), and have followed the documentation and included the necessary code in my unicorn.rb.

I am not doing anything differently than it is described in the documentation. Any ideas? Thanks in advance!

Add support for ruby 1.8

There are a few new language features which we made use of for 1.9 which aren't found in 1.8.

We aren't the most in touch with the ruby community, but if enough people are still running 1.8 we can think about adding it in.

profile + perf

double check ssl renegotiation because i think with the most recent net:http change we might not be taking advantage of it.

Changing thread creation point

A lot of people have problems or get confused by where to place Analytics.init call since it spawns a new thread. If they are using passenger or unicorn in production, they need to make sure to put the init in the post-fork section.

It's not really a good "drop-in anywhere" system. Depending on how you use the library, you need to have some idea of how it works underneath. We should change it to threads on the first track or identify.

License missing from gemspec

RubyGems.org doesn't report a license for your gem. This is because it is not specified in the gemspec of your last release.

via e.g.

spec.license = 'MIT'
# or
spec.licenses = ['MIT', 'GPL-2']

Including a license in your gemspec is an easy way for rubygems.org and other tools to check how your gem is licensed. As you can imagine, scanning your repository for a LICENSE file or parsing the README, and then attempting to identify the license or licenses is much more difficult and more error prone. So, even for projects that already specify a license, including a license in your gemspec is a good practice. See, for example, how rubygems.org uses the gemspec to display the rails gem license.

There is even a License Finder gem to help companies/individuals ensure all gems they use meet their licensing needs. This tool depends on license information being available in the gemspec. This is an important enough issue that even Bundler now generates gems with a default 'MIT' license.

I hope you'll consider specifying a license in your gemspec. If not, please just close the issue with a nice message. In either case, I'll follow up. Thanks for your time!

Appendix:

If you need help choosing a license (sorry, I haven't checked your readme or looked for a license file), GitHub has created a license picker tool. Code without a license specified defaults to 'All rights reserved'-- denying others all rights to use of the code.
Here's a list of the license names I've found and their frequencies

p.s. In case you're wondering how I found you and why I made this issue, it's because I'm collecting stats on gems (I was originally looking for download data) and decided to collect license metadata,too, and make issues for gemspecs not specifying a license as a public service :). See the previous link or my blog post about this project for more information.

Puma

How to correctly implement this with a multi instances puma envirnoment?

:write_key should not be required when :stub is true

When I call Segment::Analytics.new with stub: true, :write_key option is still required in check_write_key!.

I guess this requirement should be released because:

  • it is probably not really needed
  • it may be frightening to have to give a key when you just want stubbed requests.

If :write_key was not required, we could use this kind of code in our initializer (config/initializers/analytics_ruby.rb), which seems convenient and reassuring:

options = {}
if Rails.env.test?
  options[:stub] = true  
else
  options[:write_key] = MY_WRITE_KEY
end
Analytics = Segment::Analytics.new(options)

Faraday dependency issues

When trying to use analytics-ruby 0.6.0, bundler is blowing up because of Farday:

Bundler could not find compatible versions for gem "faraday":
  In Gemfile:
    analytics-ruby (~> 0.6.0) ruby depends on
      faraday (< 0.9, >= 0.7.4) ruby

    analytics-ruby (~> 0.6.0) ruby depends on
      faraday (0.9.0)

I believe faraday_middleware 0.9.0 depends on faraday < 0.9.0...

analytics-ruby-0.6.0/lib/analytics-ruby/client.rb:303:in `check_secret': Secret must be initialized (RuntimeError)

I'm getting this error in dev after trying to start my rails server:

/Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/analytics-ruby-0.6.0/lib/analytics-ruby/client.rb:303:in check_secret': Secret must be initialized (RuntimeError) from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/analytics-ruby-0.6.0/lib/analytics-ruby/client.rb:31:ininitialize'
from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/analytics-ruby-0.6.0/lib/analytics-ruby.rb:8:in new' from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/analytics-ruby-0.6.0/lib/analytics-ruby.rb:8:ininit'
from /Users/angelasmith/repos/Homebase1/config/initializers/analytics_ruby.rb:18:in <top (required)>' from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/activesupport-3.2.18/lib/active_support/dependencies.rb:245:inload'
from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/activesupport-3.2.18/lib/active_support/dependencies.rb:245:in block in load' from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/activesupport-3.2.18/lib/active_support/dependencies.rb:236:inload_dependency'
from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/activesupport-3.2.18/lib/active_support/dependencies.rb:245:in load' from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/railties-3.2.18/lib/rails/engine.rb:593:inblock (2 levels) in class:Engine'
from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/railties-3.2.18/lib/rails/engine.rb:592:in each' from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/railties-3.2.18/lib/rails/engine.rb:592:inblock in class:Engine'
from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/railties-3.2.18/lib/rails/initializable.rb:30:in instance_exec' from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/railties-3.2.18/lib/rails/initializable.rb:30:inrun'
from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/railties-3.2.18/lib/rails/initializable.rb:55:in block in run_initializers' from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/railties-3.2.18/lib/rails/initializable.rb:54:ineach'
from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/railties-3.2.18/lib/rails/initializable.rb:54:in run_initializers' from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/railties-3.2.18/lib/rails/application.rb:136:ininitialize!'
from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/railties-3.2.18/lib/rails/railtie/configurable.rb:30:in method_missing' from /Users/angelasmith/repos/Homebase1/config/environment.rb:5:in<top (required)>'
from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/activesupport-3.2.18/lib/active_support/dependencies.rb:251:in require' from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/activesupport-3.2.18/lib/active_support/dependencies.rb:251:inblock in require'
from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/activesupport-3.2.18/lib/active_support/dependencies.rb:236:in load_dependency' from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/activesupport-3.2.18/lib/active_support/dependencies.rb:251:inrequire'
from /Users/angelasmith/repos/Homebase1/config.ru:3:in block in <main>' from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/rack-1.4.5/lib/rack/builder.rb:51:ininstance_eval'
from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/rack-1.4.5/lib/rack/builder.rb:51:in initialize' from /Users/angelasmith/repos/Homebase1/config.ru:innew'
from /Users/angelasmith/repos/Homebase1/config.ru:in <main>' from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/rack-1.4.5/lib/rack/builder.rb:40:ineval'
from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/rack-1.4.5/lib/rack/builder.rb:40:in parse_file' from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/rack-1.4.5/lib/rack/server.rb:200:inapp'
from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/railties-3.2.18/lib/rails/commands/server.rb:46:in app' from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/rack-1.4.5/lib/rack/server.rb:304:inwrapped_app'
from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/rack-1.4.5/lib/rack/server.rb:254:in start' from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/railties-3.2.18/lib/rails/commands/server.rb:70:instart'
from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/railties-3.2.18/lib/rails/commands.rb:55:in block in <top (required)>' from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/railties-3.2.18/lib/rails/commands.rb:50:intap'
from /Users/angelasmith/.rvm/gems/ruby-1.9.3-p484/gems/railties-3.2.18/lib/rails/commands.rb:50:in <top (required)>' from script/rails:6:inrequire'
from script/rails:6:in `

'

I have removed the gem, reinstalled & updated via bundler several times with no luck.

server side analytics not working from Heroku

Server side Analytics.identify and .track are not reaching segment.io from heroku.

I've tried this from my local machine as well as AWS - it works fine...but no calls reach from heroku...

Namespacing "Analytics" Constant

Would there by any consideration of namespacing the top-level "Analytics" constant or perhaps the AnalyticsRuby module?

I've found issues of it clashing with internal classes named "Analytics" since its defined as top-level namespace (https://github.com/segmentio/analytics-ruby/blob/master/lib/analytics-ruby.rb#L35)

I can work on a PR and submit it if you're interested, however just wanted to throw out the idea as an improvement. "Analytics" is such a general name so I imagine it would cause some conflicts down the road..

In any case, great work guys. Looking forward to the service growing. 👍

Faraday dependency causing issues

Hi,

the dependency on Faraday is declared in such a way that it is causing problems:

spec.add_dependency 'faraday', ['>= 0.8', '< 0.10']

Faraday is now on 0.9 but users of analytics-ruby cannot update as it conflicts with this requirement. IMO unless there is a specific known incompatibility with 0.10 (impossible, since it is not released yet), it's inappropriate to exclude it in this way. '>= 0.8' should be sufficient.

Generic name "Analytics" creates conflicts

I'm working with a rails app which has the name "Analytics" and it conflicts with your gem's name. I'm looking at changing the app name really quick, but I figured I'd surface it... 'analytics' is a really generic word to use for the "segment IO tracking gem".

But maybe that's just me! If it's not a problem for others, I say ignore me.

Dates are all screwed up

You are currently converting dates into a format that Mixpanel and Intercom can't handle.

I feel like this is actually probably a server side issue but seems like Segment is just passing the converted Time straight through to Mixpanel and Intercom instead of reformatting into something the services can understand.

This seems to be happing with all dates but lets look at created_at just to simplify things.

The field created_at gets converted to $created in Mixpanel and SIGNED UP in Intercom. They expect dates to be sent in YYYY-MM-DDTHH:MM:SS and unix timestamp respectively. However Segment is converting the date to "#{time.strftime("%Y-%m-%dT%H:%M:%S")}#{fraction}#{formatted_offset(time, true, 'Z')}".

So for example if you have an ActiveSupport::TimeWithZone that is set to Thu, 05 Jun 2014 15:16:51 CDT -05:00 it'll get converted to 2014-06-05T15:19:30-18000:00 by analytics-ruby. This results in $created getting set to 1970-01-01T00:33:34 on Mixpanel and SIGNED UP being set to 44 years ago on Intercom as of today which is 1970-01-01T00:33:34Z.

If I explicitly format created_at to %Y-%m-%dT%H:%M:%S the analytics-ruby gem will ignore it and it'll be passed through correctly to Mixpanel.

So for example if created_at is sent as 2014-06-05T15:19:30 it'll be set $created in Mixpanel as 2014-06-05T15:19:30. The odd thing I don't understand is that it also seems to work in Intercom even though they explicitly only support unix timestamps. My only guess is you are converting it server side however that doesn't make any sense since your own date format doesn't seem to get set correctly.

Additionally it seems like custom date traits are not always sent to Intercom for some reason. I have a deleted_at trait that does get set when I send it in the format 2014-06-09 but not in the format 2014-06-09T17:11:18. I'm not exactly sure why the parsing works at all since Intercom is supposed to want a unix timestamp however i'd expect to at least see the field being set as a string for 2014-06-09T17:11:18.

Anyway I think this is actually the issue, it's fairly confusing with out knowing exactly what happens server side so it's just my best guess.

Events tracked via Resque never appear

I have a tracking job that I'm enqueueing via Resque. It's a fairly simple passthrough to Analytics.track:

# in an after_filter
def track_event
  Resque.enqueue MyAnalytics::Event,
    user_id: current_user.id,
    event: 'Created a thing',
    properties: { company_id: current_user.company_id }
end

module MyAnalytics
  class Event
    @queue = 'my_analytics'

    def self.perform(opts)
      Analytics.track opts.with_indifferent_access
    end
  end
end

However, I'm never seeing these statistics show up in Segment.io or any of the connected accounts.

Per the documentation, I also tried with

def self.after_perform(opts)
  Analytics.flush
end

but that just sits there for about a minute, then appears to timeout.

If I call Analytics.track directly in a console or in that after_filter, it works as expected.

Any thoughts? Am I doing something horribly wrong?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.