diff --git a/go.mod b/go.mod index a57956a..0f4934d 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/emvi/api-go v0.2.2 github.com/emvi/logbuch v1.1.1 - github.com/emvi/pirsch v1.5.0 + github.com/emvi/pirsch v1.5.1-0.20200911122906-93d727c607a9 github.com/go-sql-driver/mysql v1.5.0 // indirect github.com/golang-migrate/migrate v3.5.4+incompatible github.com/golang-migrate/migrate/v4 v4.12.2 diff --git a/go.sum b/go.sum index 16341cd..4e17d6b 100644 --- a/go.sum +++ b/go.sum @@ -96,6 +96,8 @@ github.com/emvi/pirsch v1.4.3 h1:Km7Jph8tATJIQIjMTF2iYyGYjgCqt5D9AD2sBoYQJIU= github.com/emvi/pirsch v1.4.3/go.mod h1:GDijqLHM331iWtmDmc7th19RxDrZadRkKoNvd9/kDX8= github.com/emvi/pirsch v1.5.0 h1:3813YrIqN1W5q8v+NrzEHAqKrks3jike3xUmEPsG/8E= github.com/emvi/pirsch v1.5.0/go.mod h1:GDijqLHM331iWtmDmc7th19RxDrZadRkKoNvd9/kDX8= +github.com/emvi/pirsch v1.5.1-0.20200911122906-93d727c607a9 h1:H1+nLRJsBy1ZuhBP4xUZTK3PUJdaPqjIxCs4B8bG6xo= +github.com/emvi/pirsch v1.5.1-0.20200911122906-93d727c607a9/go.mod h1:GDijqLHM331iWtmDmc7th19RxDrZadRkKoNvd9/kDX8= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= diff --git a/main.go b/main.go index c841f7d..7a36620 100644 --- a/main.go +++ b/main.go @@ -122,47 +122,44 @@ func serveTracking() http.HandlerFunc { endDate = time.Now().UTC() } - //totalVisitorsLabels, totalVisitorsDps := tracking.GetTotalVisitors(startDate, endDate) - //hourlyVisitorsLabels, hourlyVisitorsDps := tracking.GetHourlyVisitors(startDate, endDate) - //hourlyVisitorsTodayLabels, hourlyVisitorsTodayDps := tracking.GetHourlyVisitorsToday() + activeVisitorPages, activeVisitors := tracking.GetActiveVisitors() + totalVisitorsLabels, totalVisitorsDps := tracking.GetTotalVisitors(startDate, endDate) + hourlyVisitorsTodayLabels, hourlyVisitorsTodayDps := tracking.GetHourlyVisitorsToday() + pageVisitors, pageRank := tracking.GetPageVisits(startDate, endDate) tplCache.RenderWithoutCache(w, "tracking.html", struct { - Start int - StartDate time.Time - EndDate time.Time - //TotalVisitorsLabels template.JS - //TotalVisitorsDps template.JS - //PageVisits []tracking.PageVisits - //Pages []pirsch.Stats - //Languages []pirsch.Stats - //Referrer []pirsch.Stats - //Browser []pirsch.Stats - //OS []pirsch.Stats - //Platform *pirsch.Stats - //HourlyVisitorsLabels template.JS - //HourlyVisitorsDps template.JS - //HourlyVisitorsTodayLabels template.JS - //HourlyVisitorsTodayDps template.JS - //ActiveVisitors int - //ActiveVisitorPages []pirsch.Stats + Start int + StartDate time.Time + EndDate time.Time + TotalVisitorsLabels template.JS + TotalVisitorsDps template.JS + PageVisitors []tracking.PageVisitors + PageRank []tracking.PageVisitors + Languages []pirsch.LanguageStats + Referrer []pirsch.ReferrerStats + Browser []pirsch.BrowserStats + OS []pirsch.OSStats + Platform *pirsch.VisitorStats + HourlyVisitorsTodayLabels template.JS + HourlyVisitorsTodayDps template.JS + ActiveVisitors int + ActiveVisitorPages []pirsch.Stats }{ start, startDate, endDate, - /*totalVisitorsLabels, + totalVisitorsLabels, totalVisitorsDps, - tracking.GetPageVisits(startDate, endDate), - tracking.GetPages(startDate, endDate), + pageVisitors, + pageRank, tracking.GetLanguages(startDate, endDate), tracking.GetReferrer(startDate, endDate), tracking.GetBrowser(startDate, endDate), tracking.GetOS(startDate, endDate), tracking.GetPlatform(startDate, endDate), - hourlyVisitorsLabels, - hourlyVisitorsDps, hourlyVisitorsTodayLabels, hourlyVisitorsTodayDps, - tracking.GetActiveVisitors(), - tracking.GetActiveVisitorPages(),*/ + activeVisitors, + activeVisitorPages, }) } } diff --git a/template/tracking.html b/template/tracking.html index c887389..f296f86 100644 --- a/template/tracking.html +++ b/template/tracking.html @@ -19,10 +19,10 @@ -{{/*
+

Active Visitors

- Active visitors within the last five minutes: {{.ActiveVisitors}} + Active visitors within the last ten minutes: {{.ActiveVisitors}}

The next diagram shows active visitors for each hour of today. @@ -42,7 +42,7 @@ {{range $data := .ActiveVisitorPages}} - {{$data.Path.String}} + {{$data.Path}} {{$data.Visitors}} @@ -54,13 +54,6 @@

Total Visitors

-
-

Visitors Per Hour

-

- This is the cumulated visitor count per hour on each day of the selected time frame. -

- -

Pages

@@ -74,10 +67,10 @@ - {{range $data := .Pages}} + {{range $data := .PageRank}} - {{$data.Path.String}} + {{$data.Path}} {{$data.Visitors}} @@ -195,18 +188,18 @@ Desktop - {{.Platform.PlatformDesktopVisitors}} - {{round (multiply .Platform.PlatformDesktopRelative 100)}} % + {{.Platform.PlatformDesktop}} + {{round (multiply .Platform.RelativePlatformDesktop 100)}} % Mobile - {{.Platform.PlatformMobileVisitors}} - {{round (multiply .Platform.PlatformMobileRelative 100)}} % + {{.Platform.PlatformMobile}} + {{round (multiply .Platform.RelativePlatformMobile 100)}} % (unknown) - {{.Platform.PlatformUnknownVisitors}} - {{round (multiply .Platform.PlatformUnknownRelative 100)}} % + {{.Platform.PlatformUnknown}} + {{round (multiply .Platform.RelativePlatformUnknown 100)}} % @@ -215,7 +208,7 @@

Page Visits

-{{range $i, $data := .PageVisits}} +{{range $i, $data := .PageVisitors}}

{{$data.Path}}

@@ -250,19 +243,6 @@ } }); - new Chart(document.getElementById('hourlyVisitors').getContext('2d'), { - type: "bar", - data: { - labels: [{{.HourlyVisitorsLabels}}], - datasets: [{ - backgroundColor: "#7f7f7f", - borderColor: "#7f7f7f", - label: "Hourly Visitors", - data: [{{.HourlyVisitorsDps}}] - }] - } - }); - new Chart(document.getElementById('platform').getContext('2d'), { type: "doughnut", data: { @@ -271,14 +251,14 @@ backgroundColor: ["#515151", "#7f7f7f", "#dbdbdb"], borderColor: ["#515151", "#7f7f7f", "#dbdbdb"], data: [ - {{round (multiply .Platform.PlatformDesktopRelative 100)}}, - {{round (multiply .Platform.PlatformMobileRelative 100)}}, - {{round (multiply .Platform.PlatformUnknownRelative 100)}}] + {{round (multiply .Platform.RelativePlatformDesktop 100)}}, + {{round (multiply .Platform.RelativePlatformMobile 100)}}, + {{round (multiply .Platform.RelativePlatformUnknown 100)}}] }] } }); - {{range $i, $data := .PageVisits}} + {{range $i, $data := .PageVisitors}} new Chart(document.getElementById('pageVisits{{$i}}').getContext('2d'), { type: "line", data: { @@ -292,6 +272,6 @@ } }); {{end}} -*/}} + {{template "end.html"}} diff --git a/tracking/statistics.go b/tracking/statistics.go index 1dffb3c..a10fb52 100644 --- a/tracking/statistics.go +++ b/tracking/statistics.go @@ -1,7 +1,12 @@ package tracking import ( + "fmt" + "github.com/emvi/logbuch" + "github.com/emvi/pirsch" "html/template" + "sort" + "strings" "time" ) @@ -9,13 +14,36 @@ const ( statisticsDateFormat = "2006-01-02" ) -type PageVisits struct { - Path string - Labels template.JS - Data template.JS +type PageVisitors struct { + Path string + Visitors int + Labels template.JS + Data template.JS } -/*func GetTotalVisitors(startDate, endDate time.Time) (template.JS, template.JS) { +func GetActiveVisitors() ([]pirsch.Stats, int) { + visitors, total, err := analyzer.ActiveVisitors(nil, time.Minute*10) + + if err != nil { + logbuch.Error("Error reading active visitors", logbuch.Fields{"err": err}) + return nil, 0 + } + + return visitors, total +} + +func GetHourlyVisitorsToday() (template.JS, template.JS) { + visitors, err := analyzer.VisitorHours(&pirsch.Filter{From: today(), To: today()}) + + if err != nil { + logbuch.Error("Error reading hourly visitors for today", logbuch.Fields{"err": err}) + return "", "" + } + + return getLabelsAndDataHourly(visitors) +} + +func GetTotalVisitors(startDate, endDate time.Time) (template.JS, template.JS) { visitors, err := analyzer.Visitors(&pirsch.Filter{From: startDate, To: endDate}) if err != nil { @@ -26,41 +54,36 @@ type PageVisits struct { return getLabelsAndData(visitors) } -func GetPageVisits(startDate, endDate time.Time) []PageVisits { +func GetPageVisits(startDate, endDate time.Time) ([]PageVisitors, []PageVisitors) { visits, err := analyzer.PageVisitors(&pirsch.Filter{From: startDate, To: endDate}) if err != nil { logbuch.Error("Error reading page statistics", logbuch.Fields{"err": err}) - return nil + return nil, nil } - pageVisits := make([]PageVisits, len(visits)) + pageVisitors := make([]PageVisitors, len(visits)) for i, visit := range visits { - labels, data := getLabelsAndData(visit.VisitorsPerDay) - pageVisits[i] = PageVisits{visit.Path.String, labels, data} + labels, data := getLabelsAndData(visit.Stats) + pageVisitors[i] = PageVisitors{ + Path: visit.Path, + Visitors: sumVisitors(visit.Stats), + Labels: labels, + Data: data, + } } - return pageVisits + pageRank := make([]PageVisitors, len(pageVisitors)) + copy(pageRank, pageVisitors) + sort.Slice(pageRank, func(i, j int) bool { + return pageRank[i].Visitors > pageRank[j].Visitors + }) + return pageVisitors, pageRank } -func GetPages(startDate, endDate time.Time) []pirsch.Stats { - pages, err := analyzer.Pages(&pirsch.Filter{From: startDate, To: endDate}) - - if err != nil { - logbuch.Error("Error reading page statistics", logbuch.Fields{"err": err}) - return nil - } - - if len(pages) > 10 { - return pages[:10] - } - - return pages -} - -func GetLanguages(startDate, endDate time.Time) []pirsch.Stats { - languages, _, err := analyzer.Languages(&pirsch.Filter{From: startDate, To: endDate}) +func GetLanguages(startDate, endDate time.Time) []pirsch.LanguageStats { + languages, err := analyzer.Languages(&pirsch.Filter{From: startDate, To: endDate}) if err != nil { logbuch.Error("Error reading language statistics", logbuch.Fields{"err": err}) @@ -74,7 +97,7 @@ func GetLanguages(startDate, endDate time.Time) []pirsch.Stats { return languages } -func GetReferrer(startDate, endDate time.Time) []pirsch.Stats { +func GetReferrer(startDate, endDate time.Time) []pirsch.ReferrerStats { referrer, err := analyzer.Referrer(&pirsch.Filter{From: startDate, To: endDate}) if err != nil { @@ -89,7 +112,7 @@ func GetReferrer(startDate, endDate time.Time) []pirsch.Stats { return referrer } -func GetOS(startDate, endDate time.Time) []pirsch.Stats { +func GetOS(startDate, endDate time.Time) []pirsch.OSStats { os, err := analyzer.OS(&pirsch.Filter{From: startDate, To: endDate}) if err != nil { @@ -100,7 +123,7 @@ func GetOS(startDate, endDate time.Time) []pirsch.Stats { return os } -func GetBrowser(startDate, endDate time.Time) []pirsch.Stats { +func GetBrowser(startDate, endDate time.Time) []pirsch.BrowserStats { browser, err := analyzer.Browser(&pirsch.Filter{From: startDate, To: endDate}) if err != nil { @@ -111,51 +134,21 @@ func GetBrowser(startDate, endDate time.Time) []pirsch.Stats { return browser } -func GetPlatform(startDate, endDate time.Time) *pirsch.Stats { - platform, err := analyzer.Platform(&pirsch.Filter{From: startDate, To: endDate}) - - if err != nil { - logbuch.Error("Error reading platform statistics", logbuch.Fields{"err": err}) - return nil - } - - return platform +func GetPlatform(startDate, endDate time.Time) *pirsch.VisitorStats { + return analyzer.Platform(&pirsch.Filter{From: startDate, To: endDate}) } -func GetHourlyVisitorsToday() (template.JS, template.JS) { - visitors, err := analyzer.HourlyVisitors(&pirsch.Filter{From: today(), To: today()}) +func sumVisitors(stats []pirsch.Stats) int { + sum := 0 - if err != nil { - logbuch.Error("Error reading hourly visitors for today", logbuch.Fields{"err": err}) - return "", "" + for _, s := range stats { + sum += s.Visitors } - return getLabelsAndDataHourly(visitors) + return sum } -func GetActiveVisitors() int { - visitors, err := analyzer.ActiveVisitors(pirsch.NullTenant, time.Minute*5) - - if err != nil { - logbuch.Error("Error reading active visitors", logbuch.Fields{"err": err}) - return 0 - } - - return visitors -} - -func GetActiveVisitorPages() []pirsch.Stats { - pages, err := analyzer.ActiveVisitorsPages(pirsch.NullTenant, time.Second*30) - - if err != nil { - logbuch.Error("Error reading active visitor pages", logbuch.Fields{"err": err}) - return nil - } - - return pages -} - -func getLabelsAndData(visitors []pirsch.VisitorsPerDay) (template.JS, template.JS) { +func getLabelsAndData(visitors []pirsch.Stats) (template.JS, template.JS) { var labels strings.Builder var dp strings.Builder @@ -169,7 +162,7 @@ func getLabelsAndData(visitors []pirsch.VisitorsPerDay) (template.JS, template.J return template.JS(labelsStr[:len(labelsStr)-1]), template.JS(dataStr[:len(dataStr)-1]) } -func getLabelsAndDataHourly(visitors []pirsch.Stats) (template.JS, template.JS) { +func getLabelsAndDataHourly(visitors []pirsch.VisitorTimeStats) (template.JS, template.JS) { var labels strings.Builder var dp strings.Builder @@ -181,7 +174,7 @@ func getLabelsAndDataHourly(visitors []pirsch.Stats) (template.JS, template.JS) labelsStr := labels.String() dataStr := dp.String() return template.JS(labelsStr[:len(labelsStr)-1]), template.JS(dataStr[:len(dataStr)-1]) -}*/ +} func today() time.Time { now := time.Now() diff --git a/tracking/tracking.go b/tracking/tracking.go index ab373af..4b8ad0f 100644 --- a/tracking/tracking.go +++ b/tracking/tracking.go @@ -9,10 +9,6 @@ import ( "os" ) -const ( - domain = "marvinblum.de" -) - var ( store pirsch.Store analyzer *pirsch.Analyzer @@ -35,7 +31,7 @@ func NewTracker() (*pirsch.Tracker, context.CancelFunc) { store = pirsch.NewPostgresStore(conn, nil) tracker := pirsch.NewTracker(store, os.Getenv("MB_TRACKING_SALT"), &pirsch.TrackerConfig{ // I don't care about traffic from my own website - ReferrerDomainBlacklist: []string{domain}, + ReferrerDomainBlacklist: []string{"marvinblum.de"}, ReferrerDomainBlacklistIncludesSubdomains: true, }) analyzer = pirsch.NewAnalyzer(store)