generate unique visitor key from date + ip + user agent

This commit is contained in:
Danny van Kooten 2017-01-13 16:45:17 +01:00
parent f6cab7c297
commit 626de69c95
3 changed files with 26 additions and 14 deletions

View File

@ -1,7 +1,9 @@
package api package api
import ( import (
"database/sql"
"encoding/base64" "encoding/base64"
"log"
"net/http" "net/http"
"strings" "strings"
"time" "time"
@ -42,13 +44,18 @@ func CollectHandler(w http.ResponseWriter, r *http.Request) {
defer stmt.Close() defer stmt.Close()
err := stmt.QueryRow(page.Hostname, page.Path).Scan(&page.ID) err := stmt.QueryRow(page.Hostname, page.Path).Scan(&page.ID)
if err != nil { if err != nil {
page.Save(db.Conn) if err == sql.ErrNoRows {
page.Save(db.Conn)
} else {
log.Fatal(err)
}
} }
// find or insert visitor. // find or insert visitor.
// TODO: Mask IP Address now := time.Now()
ip := getRequestIp(r)
visitor := models.Visitor{ visitor := models.Visitor{
IpAddress: getRequestIp(r), IpAddress: ip,
BrowserLanguage: q.Get("l"), BrowserLanguage: q.Get("l"),
ScreenResolution: q.Get("sr"), ScreenResolution: q.Get("sr"),
DeviceOS: ua.OS(), DeviceOS: ua.OS(),
@ -60,21 +67,26 @@ func CollectHandler(w http.ResponseWriter, r *http.Request) {
visitor.BrowserName = parseMajorMinor(visitor.BrowserName) visitor.BrowserName = parseMajorMinor(visitor.BrowserName)
// query by unique visitor key // query by unique visitor key
visitor.GenerateKey() visitor.Key = visitor.GenerateKey(now.Format("2006-01-02"), visitor.IpAddress, r.UserAgent())
stmt, _ = db.Conn.Prepare("SELECT v.id FROM visitors v WHERE v.visitor_key = ? LIMIT 1") stmt, _ = db.Conn.Prepare("SELECT v.id FROM visitors v WHERE v.visitor_key = ? LIMIT 1")
defer stmt.Close() defer stmt.Close()
err = stmt.QueryRow(visitor.Key).Scan(&visitor.ID) err = stmt.QueryRow(visitor.Key).Scan(&visitor.ID)
if err != nil { if err != nil {
visitor.Save(db.Conn) if err == sql.ErrNoRows {
err = visitor.Save(db.Conn)
checkError(err)
} else {
log.Fatal(err)
}
} }
now := time.Now().Format("2006-01-02 15:04:05")
pageview := models.Pageview{ pageview := models.Pageview{
PageID: page.ID, PageID: page.ID,
VisitorID: visitor.ID, VisitorID: visitor.ID,
ReferrerUrl: q.Get("ru"), ReferrerUrl: q.Get("ru"),
ReferrerKeyword: q.Get("rk"), ReferrerKeyword: q.Get("rk"),
Timestamp: now, Timestamp: now.Format("2006-01-02 15:04:05"),
} }
// only store referrer URL if not coming from own site // only store referrer URL if not coming from own site

View File

@ -99,6 +99,7 @@ func Seed(n int) {
// print a dot as progress indicator // print a dot as progress indicator
fmt.Print(".") fmt.Print(".")
date := randomDateBeforeNow()
// create or find visitor // create or find visitor
visitor := models.Visitor{ visitor := models.Visitor{
@ -110,7 +111,8 @@ func Seed(n int) {
ScreenResolution: randSliceElement(screenResolutions), ScreenResolution: randSliceElement(screenResolutions),
Country: randomdata.Country(randomdata.TwoCharCountry), Country: randomdata.Country(randomdata.TwoCharCountry),
} }
visitor.Key = visitor.GenerateKey() dummyUserAgent := visitor.BrowserName + visitor.BrowserVersion + visitor.DeviceOS
visitor.Key = visitor.GenerateKey(date.Format("2006-01-02"), visitor.IpAddress, dummyUserAgent)
err := stmtVisitor.QueryRow(visitor.Key).Scan(&visitor.ID) err := stmtVisitor.QueryRow(visitor.Key).Scan(&visitor.ID)
if err != nil { if err != nil {
@ -118,7 +120,6 @@ func Seed(n int) {
} }
// generate random timestamp // generate random timestamp
date := randomDateBeforeNow()
timestamp := fmt.Sprintf("%s %d:%d:%d", date.Format("2006-01-02"), randInt(10, 24), randInt(10, 60), randInt(10, 60)) timestamp := fmt.Sprintf("%s %d:%d:%d", date.Format("2006-01-02"), randInt(10, 24), randInt(10, 60), randInt(10, 60))
pv := models.Pageview{ pv := models.Pageview{
@ -144,7 +145,7 @@ func Seed(n int) {
func randomDate() time.Time { func randomDate() time.Time {
now := time.Now() now := time.Now()
month := months[randInt(0, len(months))] month := months[randInt(0, len(months))]
t := time.Date(now.Year(), month, randInt(1, 31), randInt(0, 23), randInt(0, 59), randInt(0, 59), 0, time.UTC) t := time.Date(randInt(now.Year()-1, now.Year()), month, randInt(1, 31), randInt(0, 23), randInt(0, 59), randInt(0, 59), 0, time.UTC)
return t return t
} }

View File

@ -34,7 +34,6 @@ func (v *Visitor) Save(conn *sql.DB) error {
return err return err
} }
defer stmt.Close() defer stmt.Close()
result, err := stmt.Exec( result, err := stmt.Exec(
v.Key, v.Key,
v.IpAddress, v.IpAddress,
@ -53,8 +52,8 @@ func (v *Visitor) Save(conn *sql.DB) error {
return err return err
} }
// GenerateKey generates the "unique" visitor key // GenerateKey generates the "unique" visitor key from date, user agent + screen resolution
func (v *Visitor) GenerateKey() string { func (v *Visitor) GenerateKey(date string, ipAddress string, userAgent string) string {
byteKey := md5.Sum([]byte(v.IpAddress + v.DeviceOS + v.BrowserName + v.ScreenResolution)) byteKey := md5.Sum([]byte(date + ipAddress + userAgent))
return hex.EncodeToString(byteKey[:]) return hex.EncodeToString(byteKey[:])
} }