I want to track multiple events using GA _trackEvent method across multiple domains.
Because of the nature of the report I want to generate, I must do something like this:
for (var i=0; var < books.length; i++)
{
//showing values for current books[i]
_gaq.push(['_trackEvent', 'Books Displayed', 'Fantasy', 'Lord of The Rings']);
}
So, when my books list is populated I want to send appropriate GA event. It is important that I send each item separately so I can drill-down on Event Dashboard to preview all items in 'Fantasy' category and so on.
Note, books list is never longer than about 10 items.
The problem I'm experiencing at the moment is that for no good reason Google code is ignoring some of my requests. The way how Google event tracking works, is that with every call to _trackEvent, Google is dropping gif on the page:
http://www.google-analytics.com/__utm.gif
that has loads of parameters, and one of them - utme contains my data:
__utm.gif?utmt=event&utme=5(Books%20Displayed*Fantasy*Lord%20of%20The%20Rings)
Using Fiddler (or Firebug Net tab) I can check if this request is really coming out from the browser.
Unfortunately, it seems like every time about half of my requests are completely ignored by google and _trackEvent is not translated to __utm.gif call.
I have a feeling it has something to do with the frequency of the _trackEvent call. Because I am using them inside a for loop, all events are spawned with minimal interval between. It seems like Google doesn't like it, and ignores my calls.
I did test it, adding 2 seconds interval between each call and it worked. But this solution is unacceptable - I can't make user wait for 20 seconds to send all events.
Unfortunately this flaw makes GA Event Tracking completely useless - I can't just "hope" GA code will correctly record my event because the report won't be precise. The worst thing about it is that there is no proper documentation on Google saying what is the maximum allowed number of requests per second (they only state that max request per session is 500 what is a lot more than what I generate anyway).
My question is - did you experience similar problems with Google Event tracking before and how did you manage to fix it? Or does it mean I must completely abandon GA Tracking because it will never be precise enough?
First off, I want to point out that the 500 limit per session is for all requests to Google, not just for events. So that includes any other custom tracking you are doing, and that also includes normal page view hits.
This to me sounds more like a general js issue than a GA issue. Something along the lines of you pushing code for GA to process faster than it can process so some are falling through the cracks. I don't think there really is anything you can do about that except for delay each push as you have done...though I think you could probably lower that interval from 2s to maybe as low as 500ms...but still, that would at best drop you down to a 5 second wait, which IMO is a lot better than 20s but still too long.
One solution that might work would be for you to skip using _gaq.push() and output an image tag with the URL and params directly for each one. This is sort of the same principle as the "traditional" GA code that came before the async version, and is what most other analytics tools still do today.
If you want my honest opinion though...in my experience with web analytics, I think the most likely thing here is that you need to re-evaluate what you are tracking in the first place.
Judging by the context of your values, (and this is just a guess) it looks to me like you have for instance a page where a user can see a list of books, like a search results page or maybe a general "featured books" page or something similar, and you are wanting to track all the books a user sees on that page.
Based on my experience with web analytics, you are being way too granular about the data you collect. My advice to you is to sit down and ask yourself "How actionable is this data?" That is, after all, the point of web analytics - to help make actionable decisions.
All day long I see clients fall into the trap of wanting to know absolutely every minute detail about stuff because they think it will help them answer something or make some kind of decision, and 99% of the time, it doesn't. It is one thing to track as an event individual books a user views, like an individual product details page, where you'd be tracking a single event.
Or for search results page...track it as a "search" event, popping stuff like what the term searched was, how many results given, etc.. but not details about what was actually returned.
I guess if I knew more details about your site and what this tracking is for, I could maybe give you more solid advice :/
This is probably due to the 1 event per second limit
"Events Per Session Limit
In addition to general collection limits and quotas, the following limit applies to event tracking in ga.js:
The first 10 event hits sent to Google Analytics are tracked immediately, thereafter tracking is rate limited to one event hit per second.
As the number of events in a session approaches the collection limit, additional events might not be tracked. For this reason, you should:
avoid scripting a video to send an event for every second played and other highly repetitive event triggers
avoid excessive mouse movement tracking
avoid time-lapse mechanisms that generate high event counts
(from https://developers.google.com/analytics/devguides/collection/gajs/eventTrackerGuide)
That is why your 2 seconds delay works. You can theoretically cut that in half, though a factor of safety would probably reduce that cut.
Related
Is there a way of checking the number of currently subscribed clients to a certain publish function? Problem is that I have different groups where every group has its own unique ghash.
When a user chooses to leave a group and enters a new one, this ghash changes and THE SAME publish function is subscribed, although with a different ghash of course.
So I am looking for a way to check how many clients are subscribed to each group/ghash at a time (at the server side). I've been fiddeling around all day with stuff like this but it does not work that well to be honest. I am also listening for the "unsub" event of sockets and all that but still ... this is all buggy as hell.
If some one's interested in my whole code, you can find it here! (I found it too long to paste it here into my post.)
I really hope someone can help! :-)
cheers, P
EDIT: Or in other words: Is there a way to count the number of clients currently connected to a sockjs websocket where all these websockets were called with the same params?
=========================================================================
EDIT 2:
New version: LINK
For some reason this is not working at all ... No inserts are made because the ghash provided to the subscription is NEVER equal to any of the actual socket subscriptions (--> see lin 20: ghash is never equal to ghash2). I just don't understand how this is possible? the whole subscription function is called each time the Session ghash changes. How can this var never be equal to the param submitted to the actual socket (submission)? (it's always also a ghash, but always a ghash of another group).
I am really lost here! :-(
I now see you are doing straight old node style socket.io programming. I've done similar things in node projects. This is maybe the real question. On the docs for Meteor they don't even use the word socket. Maybe someone else would get into that new question with you, but this question about tracking subscribers is answered by this answer.
I think meteor is a new world, and will handle such stuff for you, if you adapt to its way of thinking. For example, make a collection of messages, with a field for chatroom. Each client picks their chatroom, finds those messages.find({chatroom:'box5'}), and displays them. A new message automatically goes to every client that is listening to that chatroom. Let Meteor use sockets for you.
Answer to counting clients subscribed to something:
Pseudo code:
Make an object to hold the counts of each subscription signature
counts = {}
on signup, Make a string that represents the subscription uniquely, add it to your counting object.
counts['params as string'] += 1;
on signout
counts['params as string'] -= 1;
The logic to know when no one is still subscribed is this:
done = (0 == counts['params as string'] )
Apparently as I know as of now it is not possible to do this.
I did some research and tried many things but for some reason sometimes multiple websockets are opened for trasnfering the same data to the same client. --> counting the number of clients connected is impossible via this approach.
Just triggering an event when my ghash changes is also not good enough as a close of the browser window would not trigger it.
I think having a functionality to count the number of clients "viewing the same data changes" (can't think of a better way to put it) would be awesome. Maybe some meteor core dev can just put his/her 2 cents in here so we know if this is even possible at all.
I hope someone can come up with a solution at some point .. I can't! :(
My user-status package tracks the number of clients connected to a Meteor app by tracking the number of subscriptions to a global publish function. You may be able to draw some inspiration from it. It's not granular at the per-publication level, but you can certainly do the same thing for publications that you are interested in.
https://github.com/mizzao/meteor-user-status
The main points to note are
each open session will call the subscription (users may have more than one tab open)
each time a user logs in our out, the subscription will update
you can read the per-session id in the publish function
you can listen to the close event for the SockJS socket for browser tabs being closed, etc.
I don't think it would be too hard to do this for groups; I am doing the same thing for another project.
I want to implement a 'live search' or 'search suggestions' feature in a web application that uses the Dojo Framework. It would be similar to the way Google and Bing searches display matches as you type: when you type in the search box, a list of potential matches appears below. Searches would be performed server side, with the results sent back to the browser using AJAX.
Does anyone know of a good way to implement this using Dojo?
Here are some potential options:
The built-in widget dijit.form.ComboBox
This has very similar functionality, but I've only seen it used with limited data sets. The examples always use small lists (such as the 50 states in USA) and preload the entire data set for client-side filtering. However I presume I could hook it up to a dojox.data.JsonQueryRestStore for server-side search — can anyone confirm whether that works?
QueryBox http://marumushi.com/code/querybox/
This implementation mainly does the job, but it has some minor bugs and doesn't look like it's being maintained. I'd have to do some bugfixes on the code before using it.
Medryx http://blog.medryx.org/2008/09/10/dijitsearch-part-2/
This also looks like it does the job, but it is described as 'alpha-level' code and the link to the code seems to be broken...
I could probably make one of the above work, but I'd like to know if there are any better alternatives out there.
I implemented it 5 years ago when Dojo was at 0.2:
http://www.lazutkin.com/blog/2005/12/23/live-filtering/
While the code is ancient, it is trivial, and hopefully it'll give you ideas on how to attack it. The rough sketch:
Attach an event handler to your input box, which is triggered on changes — use "onkeyup" to detect a change in the input box.
Wait until user stopped typing by setting a timer in your event handler, if it is not set yet. 200-500ms are good waiting times.
The timeout plays a dual role:
It throttles our requests to a server to prevent overloading.
It plays on our perception of time and our typing habits.
If our timeout is up, and we don't wait for a server ⇒ send server a string we have so far.
If we are still waiting for a server, cancel the request and ask again.
This part is app-specific: we don't want to overload a server, and sometimes a server cannot handle broken connections well.
In the example I don't cancel the XHR call, but wait it to finish first before submitting new request.
Server responds with relevant results, which are promptly shown.
In the blog post I implemented it as a widget. Obviously the exact packaging is up to you.
I'm trying to find the best approach for analyics on 3rd party JavaScript widgets - i.e. tools and content that is distributed to any number of arbitrary users, who include the widgets as HTML snippets with tags.
On the same domain
Note that the widgets do not load into an iframe element that has a document loaded from the external site. Instead, they load content into the DOM of the host page - i.e. they are treated as being on the same domain as the host.
Analytics for a fragment of the host page
So, essentially, I want to track stats (such as widget views, user clicks and custom interactions within the widget), but I only want to track stats for the fragment of the host page that is the widget. I don't want to track clicks on the host page that are outside the widget.
I want the stats to be collated together, so that stats for the widget on site A will be aggregated with those of the widget on site B and site C, etc.
Questions
Is it possible to use Google Analaytics in a custom way that satisfies these requirements? Or is it not possible to separate GA from the rest of the data collected on the host page?
If it is possible to use Google Analytics, then will there be a problem if the host page already uses GA (with a different GA profile ID), or is it possible to keep them safely apart?
Are there any other analytics packages out there that are properly suited to widget stats tracking, to meet these requirements?
Or, how else would you approach the problem of obtaining stats for these widgets?
GA can be used for this, though since it is a free tool, it is a bit limited compared to the other tools out there. Example of other tools out there are Yahoo Web Analytics (YWA), Omniture SiteCatalyst, and Webtrends.
Most of the tracking tools out there have the ability to do custom link and "event" tracking. Basically what you would do is lookup the necessary snippet of code for custom link tracking and put it into a wrapper function to be executed in an onclick event (or add an event listener, etc..).
The first thing you want to do is decide what "events" you want to have for the widget(s). You mentioned counting "widget views". That's easy enough to do: just put a snippet of custom code on the page the widget is embedded on.
But beyond that...does clicking any button count as a single event? Does each button signify a different event? etc... Also, are there any custom values you want to associate with the buttons, like a product ID or description or whatever.
Another important thing to ask yourself when deciding on what you want to track is "How actionable is this data?" There is very little you can't track, but there are a lot of things that aren't very useful for making real business decisions.
For example, it sounds like overall you are wanting to try to measure user interaction with widgets. I'm sure the idea is to figure out how useful, engaging, etc... they are to people, so you can figure out whether it's worth further developing them or throwing money at them or dropping them. Fair enough. But just remember to make the events goal-oriented. Knowing how many times a user clicked a button isn't very useful because all by itself it isn't very actionable. Knowing how many times people completed a process or step, etc.. is more actionable.
Once you have made a list of what all you want to track and when, then you can start building your custom code.
With GA, there are 2 main ways to track events and metrics: through steps/goals, and through custom variables. The way you setup steps/goals with GA is to have GA match what the URL of the page is. For example, if you have a newsletter signup form, the form page might be signup.html and the confirmation page might be signup_confirmation.html. You would then setup a goal in the GA interface. The goal would match for signup_confirmation.html and you could have a step be to look for signup.html. Then you can see how many people viewed your form and completed it vs. abandoned it.
You can use this same tracking method with events, by pushing a virtual page view to GA.
Here is an article detailing how to push a virtual page view:
http://www.google.com/support/analytics/bin/answer.py?hl=en&answer=55521
But basically, whenever the event happens (like a view of the widget, click of a button, etc.. you would execute the following javascript:
pageTracker._trackPageview(’virtual url here’);
Main thing to note about this method is that you can organize/categorize/provide hierarchy to your data by passing delimited values. This will help you rollup data for different widgets/sites.
The 2nd way to record events is with custom variables. Making use of custom variables during events provides a lot of reporting possibilities and flexibility. Here is a link to how to use them:
http://code.google.com/apis/analytics/docs/tracking/gaTrackingCustomVariables.html
I had to develop a newsletter manager with JS + PHP + MYSQL and I would like to know a few things on browser timing out the JS functions. If I'm running a recursive function that delays a call to itself (while PHP returns a list of email), how can I be sure that the browser won't timeout this JS function ?
I'm asking this, because I remember using a similar newsletter manager, that while doing the ajax requests, after a few calls, it stopped without any apparent reason. I know JS is not meant for this, and I should use Crontab on server, but, I can't assume the users server handles cron, so I had to stick with JS + php.
PS - This didn't happened on this app yet, I'm just trying to prevent the worse of the scenarios (since I've tested a newsletter manager, that worked the same as this one I'm developing). Since my dummy email list is small and the delays between calls are also small, this works just fine, but let's imagine a 1,000 contact list, with a delay between sends of 120 seconds: Sending 30 emails for each 2 minutes.
By the way, why this ? Well, many hosting servers has a limit on emails sent per day or hour and this helps preventing violating that policy.
from the mootools standpoint, there are several possible solutions here.
request.periodical - http://mootools.net/docs/more/Request/Request.Periodical
has plenty of options that allow for handling batches of jobs, look at it like a more complex .periodical (setInterval) that understands async nature of the result and can compensate for lag etc. I think it can literally do what you set in your requirements out of the box, all you need is an oncomplete callback that clears up the done from your pending array (for eg).
request.queue - http://mootools.net/docs/more/Request/Request.Queue
basically, setup all your requests to handle the chunks of data and pass them on to Request.Queue to handle sequentially. Probably less sophisticated from the point of view of sending rate control.
How about a meta refresh. That will not cause a timeout in your javascript function. You Just reload your page after a specific time and then send the next emails out. Adding a parameter to the URL you can find out which "round" you are on.
Can this do the job for you?
You need to use setTimeOut. The code needs to yield control to the UI thread and let the browser become responsive to avoid the script from being stopped.
Read this post by Nick Z.
http://www.nczonline.net/blog/2009/01/13/speed-up-your-javascript-part-1/
There is also something the W3C Spec about this called "Efficient Script Yielding" I'm not sure how far along it is or if any browsers support it.
https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/setImmediate/Overview.html
You could also try HTML5 Web Workers.
I'm getting in to a situation where I have several interacting widgets (on a web UI), all of whom can be in multiple different states, and whose behavior depends on others the others. I'm running in to situations where, for example, a set of data gets sorted twice, or the data gets displayed before it's sorted, rather than the other way around. It's a little bit of a wack-a-mole problem, where I think I've simplified things and gotten it working, only to find out I've broken things somewhere else.
I have functions that do things like:
widgetAFunction
load data into widget B
tell widget B to sort the data
tell widget B to display the data
My love of code reuse makes me want to do something like write a loadData function in widget A that goes something like this:
widgetBLoadDataFunction
update data
sort the data
refresh the view
So that all widgetA has to do is call one function on widgetB. But then there are cases where I just want to sort the data, without updating the data, so I write:
widgetBSortFunction
sort the data
refresh the view
And then maybe I want a filter function
widgetBFilterFunction
filter the data
refresh the view
And maybe I want to be update the data but not sort it, so I have
widgetBNoSortLoadDataFunction
update data
refresh the view
It doesn't seem that complex, but I wind up with these really long, very brittle chains of function calls, or a bunch of very similar calls. As Martin Fowler would say, the code is getting a little smelly.
So, what other alternatives do I have? I did something on a recent project where I did a state machine kind of thing, where I registered a bunch of functions with a set of conditions, or states which would trigger their execution. That worked somewhat well, and I'm thinking that approach might be good to use again.
Does anyone know what I'm talking about here, and even better, can anyone point me toward some patterns that will help me get my head around this better?
What you need is a finite state machine implementation. Basically every finite state machine needs:
Events that the program responds to
States where the program waits between events
Transitions between states in response to events
Actions taken during transitions
Variables that hold values needed by actions between events
A good article from IBM teachs you a way of implementing it by means of Javascript.
Edit: Here is a FSM builder, so you don't have to build your own.
Fernando already mentioned FSMs, and gave good info and links. :)
In addition, I'll add that your classes should already incorporate enough state so that you're not worried about sorting twice, etc. I.e., widgetB.sort() should check if it's been sorted since last update and just return if so. There's practically no downside to doing this, and it can improve performance (and also guard consistency).