Mercurial > lbo > hg > analyrics
changeset 44:e7e91f288868
Add origin country chart
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Tue, 19 Jul 2022 20:18:25 -0700 |
parents | 2ecb25f3adfe |
children | 90a4e4589d5e |
files | assets/index.html.hbs src/logsdb.rs src/main.rs |
diffstat | 3 files changed, 74 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/assets/index.html.hbs Tue Jul 19 19:56:14 2022 -0700 +++ b/assets/index.html.hbs Tue Jul 19 20:18:25 2022 -0700 @@ -86,11 +86,16 @@ <div class="plotframe halfwidth">Top paths<canvas id="topPaths"></canvas> </div> <div class="plotframe halfwidth">Requests per Session<canvas id="requestsBySession"></canvas> </div> </div> + <div class="plotrow row3"> + <div class="plotframe halfwidth">Sessions by country<canvas id="sessionsByCountry" height="30"></canvas> </div> + <div class="plotframe halfwidth">Requests per Session<canvas id="BLAH"></canvas> </div> + </div> <script> let plots = {"visitsAndSessions": {{{ chartconfig.visitsAndSessions }}}, "topPaths": {{{ chartconfig.topPaths }}}, - "requestsBySession": {{{ chartconfig.requestsBySession }}} }; + "requestsBySession": {{{ chartconfig.requestsBySession }}}, + "sessionsByCountry": {{{ chartconfig.sessionsByCountry }}} }; Object.keys(plots).forEach((cv) => { if (plots[cv] == undefined) {
--- a/src/logsdb.rs Tue Jul 19 19:56:14 2022 -0700 +++ b/src/logsdb.rs Tue Jul 19 20:18:25 2022 -0700 @@ -157,6 +157,32 @@ Ok((dates, visits, sessions)) } + pub async fn query_top_countries( + &mut self, + from: OffsetDateTime, + to: OffsetDateTime, + tz_offset: Option<i64>, + domain: Option<&str>, + ) -> Result<Vec<(String, i64)>, Error> { + let tz_offset = tz_offset.unwrap_or(0); + let result = sqlx::query( + r#" +SELECT origin_country, COUNT(*) AS count +FROM sessions +WHERE start+? > ? AND start+? < ? AND domain LIKE ? +GROUP BY origin_country +ORDER BY count DESC;"#, + ) + .bind(tz_offset) + .bind(from.unix_timestamp()) + .bind(tz_offset) + .bind(to.unix_timestamp()) + .bind(domain.unwrap_or("%")) + .fetch_all(&mut *self.0).await?; + + Ok(result.into_iter().map(|row| (row.get(0), row.get(1))).collect()) + } + pub async fn query_top_paths( &mut self, from: OffsetDateTime,
--- a/src/main.rs Tue Jul 19 19:56:14 2022 -0700 +++ b/src/main.rs Tue Jul 19 20:18:25 2022 -0700 @@ -144,13 +144,12 @@ } let datasets: Vec<Value> = values .iter() - .zip(colors) - .map(|((name, val), col)| { + .map(|((name, val))| { json!({ "label": name, "data": val, - "borderColor": col, - "backgroundColor": col, + "borderColor": colors, + "backgroundColor": colors, }) }) .collect(); @@ -237,10 +236,6 @@ .await { Ok((dates, visits, sessions)) => { - info!( - "Successfully queried visits/sessions: {:?}, {:?}", - visits, sessions - ); create_chart( dates, vec![("Visits".into(), visits), ("Sessions".into(), sessions)], @@ -251,7 +246,10 @@ ) .to_string() } - Err(e) => "undefined".to_string(), //return Template::render("index", context![loggedin: true, domain: domain, username: lig.0, flash: f, chartconfig: context![], error: format!("{:?}", e)],), + Err(e) => { + error!("Couldn't build chart: {}", e); + "undefined".to_string() + } }; let toppaths = match LogsDBSession(&mut conn) .query_top_paths(begin, end, Some(tz_offset), domain, 10) @@ -267,7 +265,10 @@ }, ) .to_string(), - Err(e) => "undefined".to_string(), + Err(e) => { + error!("Couldn't build chart: {}", e); + "undefined".to_string() + } }; let reqbyses = match LogsDBSession(&mut conn) .query_requests_per_session(begin, end, Some(tz_offset), domain) @@ -285,7 +286,31 @@ }, ) .to_string(), - Err(e) => "undefined".to_string(), + Err(e) => { + error!("Couldn't build chart: {}", e); + "undefined".to_string() + } + }; + let sesbycountry = match LogsDBSession(&mut conn) + .query_top_countries(begin, end, Some(tz_offset), domain) + .await + { + Ok(rs) => create_chart( + rs.iter().map(|(c, n)| c).collect(), + vec![( + "Sessions by Country".into(), + rs.iter().map(|(c, n)| n).collect(), + )], + &ChartOptions { + typ: "pie".into(), + ..ChartOptions::default() + }, + ) + .to_string(), + Err(e) => { + error!("Couldn't build chart: {}", e); + "undefined".to_string() + } }; let ymd_format = time::format_description::parse("[year]-[month]-[day]").unwrap(); @@ -303,7 +328,7 @@ ("today", tmpl_today.as_str()), ("duration", tmpl_duration.as_str())].into_iter()), beginnav: vec![HashMap::<&str, &str>::from_iter([("link", "/abc"), ("title", "3d")].into_iter())], - chartconfig: context![ visitsAndSessions: vissess, topPaths: toppaths, requestsBySession: reqbyses ]], + chartconfig: context![ visitsAndSessions: vissess, topPaths: toppaths, requestsBySession: reqbyses, sessionsByCountry: sesbycountry ]], ) } @@ -359,7 +384,11 @@ let orig = geoipdb.as_ref().and_then(|g| g.lookup(numip)); let is_bot = ua.to_lowercase().contains("bot"); match conn - .start_session(host.as_ref().map(String::as_str).unwrap_or(""), orig, is_bot) + .start_session( + host.as_ref().map(String::as_str).unwrap_or(""), + orig, + is_bot, + ) .await { Ok(id) => {