Skip to content

Commit be4bc20

Browse files
committed
feature: generate duration in favor of session_length aggregation
1 parent b75248b commit be4bc20

File tree

2 files changed

+62
-9
lines changed

2 files changed

+62
-9
lines changed

chat/analytics-server/src/events.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use axum::http::request::Parts;
66
use chat_core::User;
77
use clickhouse::Row;
88
use serde::{Deserialize, Serialize};
9-
use tracing::info;
9+
use tracing::{info, warn};
1010
use uuid::Uuid;
1111

1212
const SESSION_TIMEOUT: i64 = 10 * 60 * 1000; // 10 minutes
@@ -16,6 +16,7 @@ pub struct AnalyticsEventRow {
1616
// EventContext fields
1717
pub client_id: String,
1818
pub session_id: String,
19+
pub duration: u32,
1920
pub app_version: String,
2021
pub system_os: String,
2122
pub system_arch: String,
@@ -87,12 +88,19 @@ impl AnalyticsEventRow {
8788
pub fn set_session_id(&mut self, state: &AppState) {
8889
if let Some(mut v) = state.sessions.get_mut(&self.client_id) {
8990
let (session_id, last_server_ts) = v.value_mut();
90-
if self.server_ts - *last_server_ts < SESSION_TIMEOUT {
91+
let mut duration = self.server_ts - *last_server_ts;
92+
if duration < 0 {
93+
warn!("Session {} duration is negative, reset to 0", session_id);
94+
duration = 0;
95+
}
96+
if duration < SESSION_TIMEOUT {
9197
self.session_id = session_id.clone();
98+
self.duration = duration as u32;
9299
*last_server_ts = self.server_ts;
93100
} else {
94101
let new_session_id = Uuid::now_v7().to_string();
95102
self.session_id = new_session_id.clone();
103+
self.duration = 0;
96104
info!(
97105
"Session {} expired, start a new session: {}",
98106
session_id, new_session_id
@@ -103,6 +111,7 @@ impl AnalyticsEventRow {
103111
} else {
104112
let session_id = Uuid::now_v7().to_string();
105113
self.session_id = session_id.clone();
114+
self.duration = 0;
106115
info!("No client id found, start a new session: {}", session_id);
107116
state
108117
.sessions

protos/clickhouse.sql

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ CREATE TABLE analytics.analytics_events(
22
-- EventContext fields
33
client_id String,
44
session_id String,
5+
duration UInt32,
56
app_version String,
67
system_os String,
78
system_arch String,
@@ -53,8 +54,20 @@ CREATE TABLE analytics.sessions(
5354
date date,
5455
client_id String,
5556
session_id String,
57+
app_version String,
58+
system_os String,
59+
system_arch String,
60+
system_locale String,
61+
system_timezone String,
62+
user_id Nullable(String),
63+
ip Nullable(String),
64+
user_agent Nullable(String),
65+
geo_country Nullable(String),
66+
geo_region Nullable(String),
67+
geo_city Nullable(String),
5668
session_start SimpleAggregateFunction(min, DateTime64(3)),
5769
session_end SimpleAggregateFunction(max, DateTime64(3)),
70+
session_length SimpleAggregateFunction(sum, UInt64),
5871
total_events UInt32) ENGINE = SummingMergeTree()
5972
ORDER BY
6073
(
@@ -69,8 +82,20 @@ SELECT
6982
toDate(server_ts) AS date,
7083
client_id,
7184
session_id,
72-
minSimpleState(server_ts) AS session_start,
73-
maxSimpleState(server_ts) AS session_end,
85+
any(app_version) AS app_version,
86+
any(system_os) AS system_os,
87+
any(system_arch) AS system_arch,
88+
any(system_locale) AS system_locale,
89+
any(system_timezone) AS system_timezone,
90+
any(user_id) AS user_id,
91+
any(ip) AS ip,
92+
any(user_agent) AS user_agent,
93+
any(geo_country) AS geo_country,
94+
any(geo_region) AS geo_region,
95+
any(geo_city) AS geo_city,
96+
min(server_ts) AS session_start,
97+
max(server_ts) AS session_end,
98+
sum(duration) / 1000 AS session_length,
7499
count(1) AS total_events
75100
FROM
76101
analytics.analytics_events
@@ -83,16 +108,22 @@ GROUP BY
83108
-- INSERT INTO analytics.sessions...;
84109
-- query sessions table
85110
SELECT
86-
*,
87-
dateDiff('second', session_start, session_end) AS session_length
111+
date,
112+
client_id,
113+
session_id,
114+
session_start,
115+
session_end,
116+
session_length,
117+
total_events
88118
FROM
89119
analytics.sessions FINAL;
90120

91121
CREATE TABLE analytics.daily_sessions(
92122
date date,
93123
client_id String,
94124
total_session_length SimpleAggregateFunction(sum, UInt64),
95-
total_events SimpleAggregateFunction(sum, UInt64)) ENGINE = SummingMergeTree()
125+
total_session_events SimpleAggregateFunction(sum, UInt64),
126+
unique_users AggregateFunction(uniq, Nullable(String))) ENGINE = SummingMergeTree()
96127
ORDER BY
97128
(
98129
date,
@@ -103,14 +134,27 @@ CREATE MATERIALIZED VIEW analytics.daily_sessions_mv TO analytics.daily_sessions
103134
SELECT
104135
date,
105136
client_id,
106-
sumSimpleState(dateDiff('second', session_start, session_end)) AS total_session_length,
107-
sumSimpleState(total_events) AS total_events
137+
sum(session_length) AS total_session_length,
138+
sum(total_events) AS total_session_events,
139+
uniqState(user_id) AS unique_users
108140
FROM
109141
analytics.sessions
110142
GROUP BY
111143
date,
112144
client_id;
113145

146+
SELECT
147+
date,
148+
client_id,
149+
sum(total_session_length) AS total_session_length,
150+
sum(total_session_events) AS total_session_events,
151+
uniqMerge(unique_users) AS unique_users
152+
FROM
153+
analytics.daily_sessions
154+
GROUP BY
155+
date,
156+
client_id;
157+
114158
-- Insert sample data for AppStartEvent
115159
INSERT INTO analytics.analytics_events(client_id, session_id, app_version, system_os, system_arch, system_locale, system_timezone, client_ts, server_ts, event_type)
116160
VALUES ('client_001', 'session_001', '1.0.0', 'macOS', 'x86_64', 'en-US', 'America/New_York', now(), now(), 'AppStart');

0 commit comments

Comments
 (0)