diff options
author | Oscar Najera <hi@oscarnajera.com> | 2025-02-09 20:05:48 +0100 |
---|---|---|
committer | Oscar Najera <hi@oscarnajera.com> | 2025-02-09 20:05:48 +0100 |
commit | 5db6afef2702a9ad0e175df8675dee4607d8476f (patch) | |
tree | 323aade86b52da60515df63c79078eb3e5e1de45 | |
parent | 87ef3a1635aae064bfcfac0be532b9904bdd927d (diff) | |
download | scratch-5db6afef2702a9ad0e175df8675dee4607d8476f.tar.gz scratch-5db6afef2702a9ad0e175df8675dee4607d8476f.tar.bz2 scratch-5db6afef2702a9ad0e175df8675dee4607d8476f.zip |
plot site visits
-rw-r--r-- | webstats/queries.sql | 11 | ||||
-rw-r--r-- | webstats/server.lisp | 32 | ||||
-rw-r--r-- | webstats/stats.paren | 18 |
3 files changed, 60 insertions, 1 deletions
diff --git a/webstats/queries.sql b/webstats/queries.sql index 2a3f762..5e16da0 100644 --- a/webstats/queries.sql +++ b/webstats/queries.sql @@ -19,3 +19,14 @@ DROP TABLE IF EXISTS STATS -- Insert a data point INSERT INTO STATS (click, page, referrer, ip, user_agent, title) VALUES (:click, :page, :referer, :ip, :user_agent, :title) + + +-- name: activity-stats +-- timeseries of activity +SELECT + (timestamp / 600) * 600 AS time, + count(*) +FROM + STATS +GROUP BY + 1; diff --git a/webstats/server.lisp b/webstats/server.lisp index 44dbe89..6c74b3e 100644 --- a/webstats/server.lisp +++ b/webstats/server.lisp @@ -1,4 +1,4 @@ -(ql:quickload '(hunchentoot spinneret cl-yesql cl-yesql/sqlite parenscript)) +(ql:quickload '(hunchentoot spinneret cl-yesql cl-yesql/sqlite parenscript cl-json)) (defpackage :webstats (:use :common-lisp :hunchentoot :spinneret)) @@ -96,3 +96,33 @@ (:input :type "text" :name "title") (:input :type "submit" :value "submit" :name "submit")))) )) + +(hunchentoot:define-easy-handler (metric :uri "/metric.json") (q) + (setf (hunchentoot:content-type*) "application/json") + (sqlite:with-open-database (db "test.db") + (let ((series (activity-stats db))) + (cl-json:encode-json-to-string + (apply #'mapcar #'list series))))) + +(hunchentoot:define-easy-handler (graphs :uri "/graphs") () + (with-html-string + (:doctype) + (:html + (:head (:title "hu yu ipi") + (:meta :charset "utf-8") + (:link :rel "stylesheet" :href "/webstats/static/uPlot.min.css") + (:script :async t :src "/webstats/static/uPlot.iife.min.js" :type "text/javascript") + (:script :async t :src "/stats/stats.js" :type "text/javascript") + (:script :async t :src "http://127.0.0.1:8095/skewer")) + (:body + (:h1 "great graph stats") + (:div :id "graph") + (:script + (:raw + (ps:ps + (add-event-listener + "load" + (lambda () + (ps:chain (fetch "/stats/metric.json") + (then #'response-to-json) + (then #'plot))))))))))) diff --git a/webstats/stats.paren b/webstats/stats.paren index b9d3974..4721272 100644 --- a/webstats/stats.paren +++ b/webstats/stats.paren @@ -38,6 +38,24 @@ ((@ r text)))) (then (@ console log))))) +(defun response-to-json (response) + (if (@ response ok) + (chain response (json)) + (throw (new (-error "not 2XX resp"))))) + +(defun plot (data) + (new + (u-plot + (create + :title "Site activity visits" + :width 450 + :height 400 + :cursor (create sync (create key "moo")) + :series (list (create label "Time") + (create label "visits" stroke "red"))) + data + (chain document (get-element-by-id "graph"))))) + (add-event-listener "load" (lambda () |