Logging Events
Overview
The first step towards building better products is tracking events. As the saying goes, "If you can't measure something, you can't understand it. If you can't understand it, you can't control it. If you can't control it, you can't improve it." Regardless of if you plan to use Statsig for web or product analytics, or for experimentation, defining the key events and metrics for your product is the best place to start. Event data is consumable in metrics explorer, can be turned into custom metrics, visualized in dashboards, and used in experiment results to show the impact of your experiments on the metrics you care about.
We try to make this easy in a few ways:
- Our web SDKs offer autocaptured web analytics to automatically log common events like pageviews, clicks, and more.
- We offer integrations to connect your existing event data in Segment, mParticle, and other sources
- All of our client and server SDKs provide a simple
logEvent
API to instrument your own events in your app or webserver.
For general guidance on event logging and core concepts, read on, or jump to the logging events via SDKs section.
Identifying Users and the "StatsigUser" object
Many analytics platforms have a concept of "identifying" a user. In Statsig, this is the StatsigUser object that is set a initialization time in client SDKs, or with each event in Server SDKs.
The StatsigUser
is a set of properties that describe the user. It roughly has the same json definition across all SDKs and integrations:
{
userID,
customIDs,
email,
ip,
userAgent,
country,
locale,
appVersion,
custom,
privateAttributes,
}
The userID
field is reserved for a unique identifier for the user. This should be the ID of the logged in user.
customIDs
are explained in "Group Analytics" below.
The other fields are fairly self explanatory, and power not just targeting and evaluation for feature flags, but can also be used for custom metrics and data queries in metrics explorer.
Group Analytics
Another core concept in analytics is the idea of different "groups". For example, a user could belong to a certain company, organization, page, subreddit, facebook group, etc.
In Statsig, groups are represented by the customIDs
field. This is a dictionary that can contain multiple IDs for a single user. For example, a user could have the following customIDs:
{
"userID": "123",
"customIDs": {
"companyID": "456",
"projectID": "abc",
}
}
Statsig computes all metrics at the user level, but also for each custom identifier. This means you can run experiments at a company level, where all users in a company will get the same experience, and compare the impact of company level metrics.
You can also use metrics explorer to slice and dice metrics at the company level, rather than the user level, if you set up a customID for it. For example, in the Statsig project, I can look at the console page views at a user or company level in metrics explorer:
To set up a new "group" or "customID":
- Go to your [project settings] (https://console.statsig.com/settings)
- Locate the "Custom IDs" section and hit "edit"
- Name the new customID and give it a description so other people in your project know what it means
- Start logging events with that customID in the
customIDs
field of the StatsigUser object
NOTE: you must provide the set of all IDs on each StatsigUser object. Statsig does not
Best practices
Set all known IDs on each StatsigUser object
In order to generate metrics for each user/group, Statsig needs to know the set of all IDs on each StatsigUser object. Whether this is at client sdk initialization time, or when calling logEvent
in a server SDK, you need to pass each identifier for the user for it to contribute to those metrics.
If you use a logged out identifier for anonymous users, you should continue to pass that identifier even after the user logs in and you populate the logged in userID. This will enable any gates or experiments on the logged out identifier to continue to bucket the user appropriately, and calculate metrics at both the logged out and logged in level.
Deduplicating custom events
At the moment, Statsig does not provide a way to deduplicate custom events that you log.
Naming conventions
The most important aspect is consistency - you should pick a convention and stick with it. Your events and metrics catalogue can quickly become messy and difficult to navigate when there are similar events with different conventions. Technically speaking, Statsig can accept any type of name convention - E.g.; "Page View", "PageView", "Page-view" and "page_view". Practically speaking, we recommend using "page_view" — that is, to avoid spacing, and to use all lowercase characters. One thing to note, special characters cannot be used in event names. Statsig drops events that match this regex/contain this character set: "\\[\]{}<>#=;&$%|\u0000\n\r"
. This will ensure there are no duplicate entries with different casing, and ensure other downstream systems connected via integration can accept and process the event properly given this is the most universally-compatible convention.
What to measure
In general, if you're doing normal experimentation/product analytics, you'll want events that correspond to user actions. How you classify them will depend on what you're trying to do. In general, keep the following in mind:
- Events should not have high cardinality if you don't have a lot of users. Otherwise, experimental/metrics data will be too sparse. E.g.; an eCommerce website should not log a separate event name for every single product page. But instead, should have a generic "product_page_view" event and include contextual page information within the
optional_event_metadata
object. - If you have a well-defined user funnel, you'll want each step to be a separate event.
- If you have a less defined user journey, you'll want to log generic events (eg. "page_view"), and add more details to either the value field (which should be the primary dimension of interest), or the
optional_event_metadata
object.
Logging events via SDKs
All our SDKs provide a very simple API to log events. They look like this:
statsig.logEvent(
event_name,
optional_event_value,
optional_event_metadata
);
Where event name describes a notable event in your product, like sign_up
, achievement_unlocked
, add_to_cart
, check_out
, etc.
These events can optionally take an event value. For instance, you can use this field to specify the type of achievement that was unlocked, or the name of the product that was added to cart, or the price of the item that was purchased. In experiments, the "value" will generate an automatic breakdown of the event if there are fewer than 8 distinct values.
And finally, the metadata field allows you to specify even more details about the event. Here's an couple examples of how a logEvent
call looks like:
statsig.logEvent(
'add_to_cart', // Name
19.99, // Price
{
item_id: 'BC22010',
cart_size: 2,
user_segment: 'first_time_purchaser',
}
);
An example in CSharp
StatsigClient.LogEvent(
"level_completed", // Event Name
11, // Level number
new Dictionary<string, string>()
{
{ "score", "452" }
}
);
Note that there are limits to how large each event field can be. Object fields have an overall limit of 4096 on its stringified length. String fields have a limit of 64 on its length.
See the SDK reference for more details on logging events in the language of your choice.