Implemented pirsch 1.5.

This commit is contained in:
Marvin Blum
2020-09-11 15:02:42 +02:00
committed by Marvin Blum
parent 47e6ecfadd
commit 36acf6eb3a
6 changed files with 110 additions and 142 deletions

2
go.mod
View File

@@ -7,7 +7,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emvi/api-go v0.2.2 github.com/emvi/api-go v0.2.2
github.com/emvi/logbuch v1.1.1 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/go-sql-driver/mysql v1.5.0 // indirect
github.com/golang-migrate/migrate v3.5.4+incompatible github.com/golang-migrate/migrate v3.5.4+incompatible
github.com/golang-migrate/migrate/v4 v4.12.2 github.com/golang-migrate/migrate/v4 v4.12.2

2
go.sum
View File

@@ -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.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 h1:3813YrIqN1W5q8v+NrzEHAqKrks3jike3xUmEPsG/8E=
github.com/emvi/pirsch v1.5.0/go.mod h1:GDijqLHM331iWtmDmc7th19RxDrZadRkKoNvd9/kDX8= 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.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.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=

47
main.go
View File

@@ -122,47 +122,44 @@ func serveTracking() http.HandlerFunc {
endDate = time.Now().UTC() endDate = time.Now().UTC()
} }
//totalVisitorsLabels, totalVisitorsDps := tracking.GetTotalVisitors(startDate, endDate) activeVisitorPages, activeVisitors := tracking.GetActiveVisitors()
//hourlyVisitorsLabels, hourlyVisitorsDps := tracking.GetHourlyVisitors(startDate, endDate) totalVisitorsLabels, totalVisitorsDps := tracking.GetTotalVisitors(startDate, endDate)
//hourlyVisitorsTodayLabels, hourlyVisitorsTodayDps := tracking.GetHourlyVisitorsToday() hourlyVisitorsTodayLabels, hourlyVisitorsTodayDps := tracking.GetHourlyVisitorsToday()
pageVisitors, pageRank := tracking.GetPageVisits(startDate, endDate)
tplCache.RenderWithoutCache(w, "tracking.html", struct { tplCache.RenderWithoutCache(w, "tracking.html", struct {
Start int Start int
StartDate time.Time StartDate time.Time
EndDate time.Time EndDate time.Time
//TotalVisitorsLabels template.JS TotalVisitorsLabels template.JS
//TotalVisitorsDps template.JS TotalVisitorsDps template.JS
//PageVisits []tracking.PageVisits PageVisitors []tracking.PageVisitors
//Pages []pirsch.Stats PageRank []tracking.PageVisitors
//Languages []pirsch.Stats Languages []pirsch.LanguageStats
//Referrer []pirsch.Stats Referrer []pirsch.ReferrerStats
//Browser []pirsch.Stats Browser []pirsch.BrowserStats
//OS []pirsch.Stats OS []pirsch.OSStats
//Platform *pirsch.Stats Platform *pirsch.VisitorStats
//HourlyVisitorsLabels template.JS HourlyVisitorsTodayLabels template.JS
//HourlyVisitorsDps template.JS HourlyVisitorsTodayDps template.JS
//HourlyVisitorsTodayLabels template.JS ActiveVisitors int
//HourlyVisitorsTodayDps template.JS ActiveVisitorPages []pirsch.Stats
//ActiveVisitors int
//ActiveVisitorPages []pirsch.Stats
}{ }{
start, start,
startDate, startDate,
endDate, endDate,
/*totalVisitorsLabels, totalVisitorsLabels,
totalVisitorsDps, totalVisitorsDps,
tracking.GetPageVisits(startDate, endDate), pageVisitors,
tracking.GetPages(startDate, endDate), pageRank,
tracking.GetLanguages(startDate, endDate), tracking.GetLanguages(startDate, endDate),
tracking.GetReferrer(startDate, endDate), tracking.GetReferrer(startDate, endDate),
tracking.GetBrowser(startDate, endDate), tracking.GetBrowser(startDate, endDate),
tracking.GetOS(startDate, endDate), tracking.GetOS(startDate, endDate),
tracking.GetPlatform(startDate, endDate), tracking.GetPlatform(startDate, endDate),
hourlyVisitorsLabels,
hourlyVisitorsDps,
hourlyVisitorsTodayLabels, hourlyVisitorsTodayLabels,
hourlyVisitorsTodayDps, hourlyVisitorsTodayDps,
tracking.GetActiveVisitors(), activeVisitors,
tracking.GetActiveVisitorPages(),*/ activeVisitorPages,
}) })
} }
} }

View File

@@ -19,10 +19,10 @@
<input type="submit" value="Update" /> <input type="submit" value="Update" />
</form> </form>
</section> </section>
{{/*<section> <section>
<h2>Active Visitors</h2> <h2>Active Visitors</h2>
<p> <p>
Active visitors within the last five minutes: {{.ActiveVisitors}} Active visitors within the last ten minutes: {{.ActiveVisitors}}
</p> </p>
<p> <p>
The next diagram shows active visitors for each hour of today. The next diagram shows active visitors for each hour of today.
@@ -42,7 +42,7 @@
{{range $data := .ActiveVisitorPages}} {{range $data := .ActiveVisitorPages}}
<tr> <tr>
<td class="break-line-anywhere"> <td class="break-line-anywhere">
<a href="{{$data.Path.String}}" target="_blank">{{$data.Path.String}}</a> <a href="{{$data.Path}}" target="_blank">{{$data.Path}}</a>
</td> </td>
<td>{{$data.Visitors}}</td> <td>{{$data.Visitors}}</td>
</tr> </tr>
@@ -54,13 +54,6 @@
<h2>Total Visitors</h2> <h2>Total Visitors</h2>
<canvas id="totalVisitors" class="tracking"></canvas> <canvas id="totalVisitors" class="tracking"></canvas>
</section> </section>
<section>
<h2>Visitors Per Hour</h2>
<p>
This is the cumulated visitor count per hour on each day of the selected time frame.
</p>
<canvas id="hourlyVisitors" class="tracking"></canvas>
</section>
<section> <section>
<h2>Pages</h2> <h2>Pages</h2>
<p> <p>
@@ -74,10 +67,10 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{{range $data := .Pages}} {{range $data := .PageRank}}
<tr> <tr>
<td class="break-line-anywhere"> <td class="break-line-anywhere">
<a href="{{$data.Path.String}}" target="_blank">{{$data.Path.String}}</a> <a href="{{$data.Path}}" target="_blank">{{$data.Path}}</a>
</td> </td>
<td>{{$data.Visitors}}</td> <td>{{$data.Visitors}}</td>
</tr> </tr>
@@ -195,18 +188,18 @@
<tbody> <tbody>
<tr> <tr>
<td>Desktop</td> <td>Desktop</td>
<td>{{.Platform.PlatformDesktopVisitors}}</td> <td>{{.Platform.PlatformDesktop}}</td>
<td>{{round (multiply .Platform.PlatformDesktopRelative 100)}} %</td> <td>{{round (multiply .Platform.RelativePlatformDesktop 100)}} %</td>
</tr> </tr>
<tr> <tr>
<td>Mobile</td> <td>Mobile</td>
<td>{{.Platform.PlatformMobileVisitors}}</td> <td>{{.Platform.PlatformMobile}}</td>
<td>{{round (multiply .Platform.PlatformMobileRelative 100)}} %</td> <td>{{round (multiply .Platform.RelativePlatformMobile 100)}} %</td>
</tr> </tr>
<tr> <tr>
<td>(unknown)</td> <td>(unknown)</td>
<td>{{.Platform.PlatformUnknownVisitors}}</td> <td>{{.Platform.PlatformUnknown}}</td>
<td>{{round (multiply .Platform.PlatformUnknownRelative 100)}} %</td> <td>{{round (multiply .Platform.RelativePlatformUnknown 100)}} %</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@@ -215,7 +208,7 @@
<h2>Page Visits</h2> <h2>Page Visits</h2>
</section> </section>
{{range $i, $data := .PageVisits}} {{range $i, $data := .PageVisitors}}
<section> <section>
<h3>{{$data.Path}}</h3> <h3>{{$data.Path}}</h3>
<canvas id="pageVisits{{$i}}" class="tracking"></canvas> <canvas id="pageVisits{{$i}}" class="tracking"></canvas>
@@ -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'), { new Chart(document.getElementById('platform').getContext('2d'), {
type: "doughnut", type: "doughnut",
data: { data: {
@@ -271,14 +251,14 @@
backgroundColor: ["#515151", "#7f7f7f", "#dbdbdb"], backgroundColor: ["#515151", "#7f7f7f", "#dbdbdb"],
borderColor: ["#515151", "#7f7f7f", "#dbdbdb"], borderColor: ["#515151", "#7f7f7f", "#dbdbdb"],
data: [ data: [
{{round (multiply .Platform.PlatformDesktopRelative 100)}}, {{round (multiply .Platform.RelativePlatformDesktop 100)}},
{{round (multiply .Platform.PlatformMobileRelative 100)}}, {{round (multiply .Platform.RelativePlatformMobile 100)}},
{{round (multiply .Platform.PlatformUnknownRelative 100)}}] {{round (multiply .Platform.RelativePlatformUnknown 100)}}]
}] }]
} }
}); });
{{range $i, $data := .PageVisits}} {{range $i, $data := .PageVisitors}}
new Chart(document.getElementById('pageVisits{{$i}}').getContext('2d'), { new Chart(document.getElementById('pageVisits{{$i}}').getContext('2d'), {
type: "line", type: "line",
data: { data: {
@@ -292,6 +272,6 @@
} }
}); });
{{end}} {{end}}
</script>*/}} </script>
{{template "end.html"}} {{template "end.html"}}

View File

@@ -1,7 +1,12 @@
package tracking package tracking
import ( import (
"fmt"
"github.com/emvi/logbuch"
"github.com/emvi/pirsch"
"html/template" "html/template"
"sort"
"strings"
"time" "time"
) )
@@ -9,13 +14,36 @@ const (
statisticsDateFormat = "2006-01-02" statisticsDateFormat = "2006-01-02"
) )
type PageVisits struct { type PageVisitors struct {
Path string Path string
Visitors int
Labels template.JS Labels template.JS
Data 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}) visitors, err := analyzer.Visitors(&pirsch.Filter{From: startDate, To: endDate})
if err != nil { if err != nil {
@@ -26,41 +54,36 @@ type PageVisits struct {
return getLabelsAndData(visitors) 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}) visits, err := analyzer.PageVisitors(&pirsch.Filter{From: startDate, To: endDate})
if err != nil { if err != nil {
logbuch.Error("Error reading page statistics", logbuch.Fields{"err": err}) 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 { for i, visit := range visits {
labels, data := getLabelsAndData(visit.VisitorsPerDay) labels, data := getLabelsAndData(visit.Stats)
pageVisits[i] = PageVisits{visit.Path.String, labels, data} 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 { func GetLanguages(startDate, endDate time.Time) []pirsch.LanguageStats {
pages, err := analyzer.Pages(&pirsch.Filter{From: startDate, To: endDate}) languages, err := analyzer.Languages(&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})
if err != nil { if err != nil {
logbuch.Error("Error reading language statistics", logbuch.Fields{"err": err}) logbuch.Error("Error reading language statistics", logbuch.Fields{"err": err})
@@ -74,7 +97,7 @@ func GetLanguages(startDate, endDate time.Time) []pirsch.Stats {
return languages 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}) referrer, err := analyzer.Referrer(&pirsch.Filter{From: startDate, To: endDate})
if err != nil { if err != nil {
@@ -89,7 +112,7 @@ func GetReferrer(startDate, endDate time.Time) []pirsch.Stats {
return referrer 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}) os, err := analyzer.OS(&pirsch.Filter{From: startDate, To: endDate})
if err != nil { if err != nil {
@@ -100,7 +123,7 @@ func GetOS(startDate, endDate time.Time) []pirsch.Stats {
return os 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}) browser, err := analyzer.Browser(&pirsch.Filter{From: startDate, To: endDate})
if err != nil { if err != nil {
@@ -111,51 +134,21 @@ func GetBrowser(startDate, endDate time.Time) []pirsch.Stats {
return browser return browser
} }
func GetPlatform(startDate, endDate time.Time) *pirsch.Stats { func GetPlatform(startDate, endDate time.Time) *pirsch.VisitorStats {
platform, err := analyzer.Platform(&pirsch.Filter{From: startDate, To: endDate}) return 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 sumVisitors(stats []pirsch.Stats) int {
sum := 0
for _, s := range stats {
sum += s.Visitors
} }
func GetHourlyVisitorsToday() (template.JS, template.JS) { return sum
visitors, err := analyzer.HourlyVisitors(&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 getLabelsAndData(visitors []pirsch.Stats) (template.JS, template.JS) {
}
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) {
var labels strings.Builder var labels strings.Builder
var dp 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]) 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 labels strings.Builder
var dp strings.Builder var dp strings.Builder
@@ -181,7 +174,7 @@ func getLabelsAndDataHourly(visitors []pirsch.Stats) (template.JS, template.JS)
labelsStr := labels.String() labelsStr := labels.String()
dataStr := dp.String() dataStr := dp.String()
return template.JS(labelsStr[:len(labelsStr)-1]), template.JS(dataStr[:len(dataStr)-1]) return template.JS(labelsStr[:len(labelsStr)-1]), template.JS(dataStr[:len(dataStr)-1])
}*/ }
func today() time.Time { func today() time.Time {
now := time.Now() now := time.Now()

View File

@@ -9,10 +9,6 @@ import (
"os" "os"
) )
const (
domain = "marvinblum.de"
)
var ( var (
store pirsch.Store store pirsch.Store
analyzer *pirsch.Analyzer analyzer *pirsch.Analyzer
@@ -35,7 +31,7 @@ func NewTracker() (*pirsch.Tracker, context.CancelFunc) {
store = pirsch.NewPostgresStore(conn, nil) store = pirsch.NewPostgresStore(conn, nil)
tracker := pirsch.NewTracker(store, os.Getenv("MB_TRACKING_SALT"), &pirsch.TrackerConfig{ tracker := pirsch.NewTracker(store, os.Getenv("MB_TRACKING_SALT"), &pirsch.TrackerConfig{
// I don't care about traffic from my own website // I don't care about traffic from my own website
ReferrerDomainBlacklist: []string{domain}, ReferrerDomainBlacklist: []string{"marvinblum.de"},
ReferrerDomainBlacklistIncludesSubdomains: true, ReferrerDomainBlacklistIncludesSubdomains: true,
}) })
analyzer = pirsch.NewAnalyzer(store) analyzer = pirsch.NewAnalyzer(store)