Skip to content

Commit

Permalink
Remove visits/sessions entirely
Browse files Browse the repository at this point in the history
  • Loading branch information
benvinegar committed Dec 11, 2024
1 parent d7817a2 commit 3d648e2
Show file tree
Hide file tree
Showing 7 changed files with 20 additions and 63 deletions.
17 changes: 8 additions & 9 deletions app/analytics/__tests__/collect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ describe("collectRequestHandler", () => {
],
doubles: [
1, // new visitor
1, // new session
0, // DEAD COLUMN (was session)
1, // new visit, so bounce
],
indexes: [
Expand All @@ -95,7 +95,7 @@ describe("collectRequestHandler", () => {
"doubles",
[
1, // new visitor
1, // new session
0, // DEAD COLUMN (was session)
1, // new visit, so bounce
],
);
Expand Down Expand Up @@ -124,7 +124,7 @@ describe("collectRequestHandler", () => {
"doubles",
[
0, // NOT a new visitor
0, // NOT a new session
0, // DEAD COLUMN (was session)
0, // NOT first or second visit
],
);
Expand Down Expand Up @@ -158,8 +158,7 @@ describe("collectRequestHandler", () => {
"doubles",
[
1, // new visitor because a new day began
0, // NOT a new session because continuation of earlier session (< 30 mins)
// (session logic doesn't care if a new day began or not)
0, // DEAD COLUMN (was session)
1, // new visitor so bounce counted
],
);
Expand Down Expand Up @@ -188,7 +187,7 @@ describe("collectRequestHandler", () => {
"doubles",
[
1, // new visitor because > 30 days passed
1, // new session because > 30 minutes passed
0, // DEAD COLUMN (was session)
1, // new visitor so bounce
],
);
Expand Down Expand Up @@ -217,7 +216,7 @@ describe("collectRequestHandler", () => {
"doubles",
[
1, // new visitor because > 24 hours passed
1, // new session because > 30 minutes passed
0, // DEAD COLUMN (was session)
1, // new visitor so bounce
],
);
Expand Down Expand Up @@ -254,7 +253,7 @@ describe("collectRequestHandler", () => {
"doubles",
[
0, // NOT a new visitor
0, // NOT a new session
0, // DEAD COLUMN (was session)
-1, // First visit after the initial visit so decrement bounce
],
);
Expand Down Expand Up @@ -293,7 +292,7 @@ describe("collectRequestHandler", () => {
"doubles",
[
0, // NOT a new visitor
0, // NOT a new session
0, // DEAD COLUMN (was session)
0, // After the second visit so no bounce
],
);
Expand Down
10 changes: 2 additions & 8 deletions app/analytics/__tests__/query.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,25 +187,22 @@ describe("AnalyticsEngineAPI", () => {
});

describe("getCounts", () => {
test("should return an object with view, visit, and visitor counts", async () => {
test("should return an object with view, visitor, and bounce counts", async () => {
fetch.mockResolvedValue(
createFetchResponse({
data: [
{
count: 3,
isVisit: 1,
isVisitor: 0,
isBounce: 1,
},
{
count: 2,
isVisit: 0,
isVisitor: 0,
isBounce: 0,
},
{
count: 1,
isVisit: 0,
isVisitor: 1,
isBounce: -1,
},
Expand All @@ -219,7 +216,6 @@ describe("AnalyticsEngineAPI", () => {
expect(fetch).toHaveBeenCalled();
expect(await result).toEqual({
views: 6,
visits: 3,
visitors: 1,
bounces: 2,
});
Expand Down Expand Up @@ -328,18 +324,16 @@ describe("AnalyticsEngineAPI", () => {
).toEqual(
"SELECT blob4, " +
"double1 as isVisitor, " +
"double2 as isVisit, " +
"double3 as isBounce, " +
"SUM(_sample_interval) as count " +
"FROM metricsDataset WHERE timestamp >= NOW() - INTERVAL '7' DAY AND timestamp < NOW() AND blob8 = 'example.com' AND blob4 = 'CA' " +
"GROUP BY blob4, double1, double2, double3 " +
"GROUP BY blob4, double1, double3 " +
"ORDER BY count DESC LIMIT 10",
);
expect(await result).toEqual({
CA: {
views: 3,
visitors: 0,
visits: 0,
bounces: 0,
},
});
Expand Down
18 changes: 3 additions & 15 deletions app/analytics/collect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,9 @@ function getBounce(current: Date | null): number {

function checkVisitorSession(ifModifiedSince: string | null): {
newVisitor: boolean;
newSession: boolean;
} {
let newVisitor = true;
let newSession = true;

const minutesUntilSessionResets = 30;
if (ifModifiedSince) {
// check today is a new day vs ifModifiedSince
const today = new Date();
Expand All @@ -66,18 +63,9 @@ function checkVisitorSession(ifModifiedSince: string | null): {
// if ifModifiedSince is today, this is not a new visitor
newVisitor = false;
}

// check ifModifiedSince is less than 30 mins ago
if (
Date.now() - new Date(ifModifiedSince).getTime() <
minutesUntilSessionResets * 60 * 1000
) {
// this is a continuation of the same session
newSession = false;
}
}

return { newVisitor, newSession };
return { newVisitor };
}

function extractParamsFromQueryString(requestUrl: string): {
Expand All @@ -104,7 +92,7 @@ export function collectRequestHandler(request: Request, env: Env) {
parsedUserAgent.getBrowser().name;

const ifModifiedSince = request.headers.get("if-modified-since");
const { newVisitor, newSession } = checkVisitorSession(ifModifiedSince);
const { newVisitor } = checkVisitorSession(ifModifiedSince);
const modifiedDate = getNextModifiedDate(
ifModifiedSince ? new Date(ifModifiedSince) : null,
);
Expand All @@ -115,7 +103,7 @@ export function collectRequestHandler(request: Request, env: Env) {
path: params.p,
referrer: params.r,
newVisitor: newVisitor ? 1 : 0,
newSession: newSession ? 1 : 0,
newSession: 0, // dead column
bounce: newVisitor ? 1 : getBounce(modifiedDate),
// user agent stuff
userAgent: userAgent,
Expand Down
24 changes: 6 additions & 18 deletions app/analytics/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,22 @@ interface AnalyticsQueryResult<

interface AnalyticsCountResult {
views: number;
visits: number;
visitors: number;
bounces: number;
}

/** Given an AnalyticsCountResult object, and an object representing a row returned from
* CF Analytics Engine w/ counts grouped by isVisitor and isVisit, accumulate view,
* CF Analytics Engine w/ counts grouped by isVisitor, accumulate view,
* visit, and visitor counts.
*/
function accumulateCountsFromRowResult(
counts: AnalyticsCountResult,
row: {
count: number;
isVisitor: number;
isVisit: number;
isBounce: number;
},
) {
if (row.isVisit == 1) {
counts.visits += Number(row.count);
}
if (row.isVisitor == 1) {
counts.visitors += Number(row.count);
}
Expand Down Expand Up @@ -214,9 +209,8 @@ export class AnalyticsEngineAPI {

const filterStr = filtersToSql(filters);

// NOTE: when using toStartOfInterval, cannot group by other columns
// like double1 (isVisitor) or double2 (isSession/isVisit). This
// is just a limitation of Cloudflare Analytics Engine.
// NOTE: when using toStartOfInterval, cannot group by other columns like double1 (isVisitor).
// This is just a limitation of Cloudflare Analytics Engine.
// -- but you can filter on them (using WHERE)

// NOTE 2: Since CF AE doesn't support COALESCE, this query will not return
Expand Down Expand Up @@ -309,19 +303,17 @@ export class AnalyticsEngineAPI {
const query = `
SELECT SUM(_sample_interval) as count,
${ColumnMappings.newVisitor} as isVisitor,
${ColumnMappings.newSession} as isVisit,
${ColumnMappings.bounce} as isBounce
FROM metricsDataset
WHERE timestamp >= ${startIntervalSql} AND timestamp < ${endIntervalSql}
${filterStr}
AND ${siteIdColumn} = '${siteId}'
GROUP BY isVisitor, isVisit, isBounce
ORDER BY isVisitor, isVisit, isBounce ASC`;
GROUP BY isVisitor, isBounce
ORDER BY isVisitor, isBounce ASC`;

type SelectionSet = {
count: number;
isVisitor: number;
isVisit: number;
isBounce: number;
};

Expand All @@ -342,7 +334,6 @@ export class AnalyticsEngineAPI {
const counts: AnalyticsCountResult = {
views: 0,
visitors: 0,
visits: 0,
bounces: 0,
};

Expand Down Expand Up @@ -445,21 +436,19 @@ export class AnalyticsEngineAPI {
const query = `
SELECT ${_column},
${ColumnMappings.newVisitor} as isVisitor,
${ColumnMappings.newSession} as isVisit,
${ColumnMappings.bounce} as isBounce,
SUM(_sample_interval) as count
FROM metricsDataset
WHERE timestamp >= ${startIntervalSql} AND timestamp < ${endIntervalSql}
AND ${ColumnMappings.siteId} = '${siteId}'
${filterStr}
GROUP BY ${_column}, ${ColumnMappings.newVisitor}, ${ColumnMappings.newSession}, ${ColumnMappings.bounce}
GROUP BY ${_column}, ${ColumnMappings.newVisitor}, ${ColumnMappings.bounce}
ORDER BY count DESC
LIMIT ${limit * page}`;

type SelectionSet = {
readonly count: number;
readonly isVisitor: number;
readonly isVisit: number;
readonly isBounce: number;
} & Record<
(typeof ColumnMappings)[T],
Expand Down Expand Up @@ -493,7 +482,6 @@ export class AnalyticsEngineAPI {
acc[key] = {
views: 0,
visitors: 0,
visits: 0,
bounces: 0,
} as AnalyticsCountResult;
}
Expand Down
3 changes: 0 additions & 3 deletions app/routes/__tests__/dashboard.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,6 @@ describe("Dashboard route", () => {
loader: () => {
return json({
views: 0,
visits: 0,
visitors: 0,
});
},
Expand Down Expand Up @@ -270,7 +269,6 @@ describe("Dashboard route", () => {
siteId: "example",
sites: ["example"],
views: 2133,
visits: 80,
visitors: 33,
viewsGroupedByInterval: [
["2024-01-11 05:00:00", 0],
Expand Down Expand Up @@ -304,7 +302,6 @@ describe("Dashboard route", () => {
loader: () => {
return json({
views: 2133,
visits: 80,
visitors: 33,
});
},
Expand Down
2 changes: 0 additions & 2 deletions app/routes/__tests__/resources.stats.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ describe("resources.stats loader", () => {
test("returns formatted stats from analytics engine", async () => {
const mockGetCounts = vi.fn().mockResolvedValue({
views: 1000,
visits: 500,
visitors: 250,
});

Expand All @@ -31,7 +30,6 @@ describe("resources.stats loader", () => {

expect(data).toEqual({
views: 1000,
visits: 500,
visitors: 250,
});
});
Expand Down
9 changes: 1 addition & 8 deletions app/routes/resources.stats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export async function loader({ context, request }: LoaderFunctionArgs) {

return json({
views: counts.views,
visits: counts.visits,
visitors: counts.visitors,
bounces: counts.bounces,
});
Expand All @@ -36,7 +35,7 @@ export const StatsCard = ({
}) => {
const dataFetcher = useFetcher<typeof loader>();

const { views, visits, visitors, bounces } = dataFetcher.data || {};
const { views, visitors, bounces } = dataFetcher.data || {};
const countFormatter = Intl.NumberFormat("en", { notation: "compact" });

useEffect(() => {
Expand Down Expand Up @@ -65,12 +64,6 @@ export const StatsCard = ({
{views ? countFormatter.format(views) : "-"}
</div>
</div>
<div>
<div className="text-md sm:text-lg">Visits</div>
<div className="text-4xl">
{visits ? countFormatter.format(visits) : "-"}
</div>
</div>
<div>
<div className="text-md sm:text-lg">Visitors</div>
<div className="text-4xl">
Expand Down

0 comments on commit 3d648e2

Please sign in to comment.