mirror of
https://github.com/Kugelschieber/marvinblum.git
synced 2026-01-18 14:50:27 +00:00
Added hourly visitors and active visitors to tracking page.
This commit is contained in:
2
go.mod
2
go.mod
@@ -8,7 +8,7 @@ require (
|
|||||||
github.com/cenkalti/backoff/v4 v4.0.2 // indirect
|
github.com/cenkalti/backoff/v4 v4.0.2 // indirect
|
||||||
github.com/emvi/api-go v0.0.0-20191210194347-0a945446f6a8
|
github.com/emvi/api-go v0.0.0-20191210194347-0a945446f6a8
|
||||||
github.com/emvi/logbuch v1.1.1
|
github.com/emvi/logbuch v1.1.1
|
||||||
github.com/emvi/pirsch v0.0.0-20200625182355-75f0aba03718
|
github.com/emvi/pirsch v0.0.0-20200625233854-9bc410bf1483
|
||||||
github.com/gorilla/mux v1.7.4
|
github.com/gorilla/mux v1.7.4
|
||||||
github.com/gosimple/slug v1.9.0
|
github.com/gosimple/slug v1.9.0
|
||||||
github.com/jmoiron/sqlx v1.2.0
|
github.com/jmoiron/sqlx v1.2.0
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -97,6 +97,8 @@ github.com/emvi/pirsch v0.0.0-20200625145826-bf2196e7b9f8 h1:m/3rKmlG0s6nlW+yvND
|
|||||||
github.com/emvi/pirsch v0.0.0-20200625145826-bf2196e7b9f8/go.mod h1:+YmBbltJ3feZz9L/QQyqwywltYvQKBfzrGD51TPKl5g=
|
github.com/emvi/pirsch v0.0.0-20200625145826-bf2196e7b9f8/go.mod h1:+YmBbltJ3feZz9L/QQyqwywltYvQKBfzrGD51TPKl5g=
|
||||||
github.com/emvi/pirsch v0.0.0-20200625182355-75f0aba03718 h1:FOaeJg2A9rGb5WMZsnW/2SorGesIoVn9doW1Okgt1BU=
|
github.com/emvi/pirsch v0.0.0-20200625182355-75f0aba03718 h1:FOaeJg2A9rGb5WMZsnW/2SorGesIoVn9doW1Okgt1BU=
|
||||||
github.com/emvi/pirsch v0.0.0-20200625182355-75f0aba03718/go.mod h1:+YmBbltJ3feZz9L/QQyqwywltYvQKBfzrGD51TPKl5g=
|
github.com/emvi/pirsch v0.0.0-20200625182355-75f0aba03718/go.mod h1:+YmBbltJ3feZz9L/QQyqwywltYvQKBfzrGD51TPKl5g=
|
||||||
|
github.com/emvi/pirsch v0.0.0-20200625233854-9bc410bf1483 h1:hTW+M/0XaAEn1+bpXL/z2DZAFU1xgvKk56OgL1lodSU=
|
||||||
|
github.com/emvi/pirsch v0.0.0-20200625233854-9bc410bf1483/go.mod h1:+YmBbltJ3feZz9L/QQyqwywltYvQKBfzrGD51TPKl5g=
|
||||||
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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/exoscale/egoscale v0.18.1/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE=
|
github.com/exoscale/egoscale v0.18.1/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE=
|
||||||
|
|||||||
23
main.go
23
main.go
@@ -119,6 +119,7 @@ func serveBlogArticle() http.HandlerFunc {
|
|||||||
|
|
||||||
func serveTracking() http.HandlerFunc {
|
func serveTracking() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
tracker.Hit(r)
|
||||||
start, _ := strconv.Atoi(r.URL.Query().Get("start"))
|
start, _ := strconv.Atoi(r.URL.Query().Get("start"))
|
||||||
|
|
||||||
if start > 365 {
|
if start > 365 {
|
||||||
@@ -128,18 +129,30 @@ func serveTracking() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
totalVisitorsLabels, totalVisitorsDps := tracking.GetTotalVisitors(start)
|
totalVisitorsLabels, totalVisitorsDps := tracking.GetTotalVisitors(start)
|
||||||
|
hourlyVisitorsLabels, hourlyVisitorsDps := tracking.GetHourlyVisitors(start)
|
||||||
|
hourlyVisitorsTodayLabels, hourlyVisitorsTodayDps := tracking.GetHourlyVisitorsToday()
|
||||||
tplCache.RenderWithoutCache(w, "tracking.html", struct {
|
tplCache.RenderWithoutCache(w, "tracking.html", struct {
|
||||||
Start int
|
Start int
|
||||||
TotalVisitorsLabels template.JS
|
TotalVisitorsLabels template.JS
|
||||||
TotalVisitorsDps template.JS
|
TotalVisitorsDps template.JS
|
||||||
PageVisits []tracking.PageVisits
|
PageVisits []tracking.PageVisits
|
||||||
Languages []pirsch.VisitorLanguage
|
Languages []pirsch.VisitorLanguage
|
||||||
|
HourlyVisitorsLabels template.JS
|
||||||
|
HourlyVisitorsDps template.JS
|
||||||
|
HourlyVisitorsTodayLabels template.JS
|
||||||
|
HourlyVisitorsTodayDps template.JS
|
||||||
|
ActiveVisitors int
|
||||||
}{
|
}{
|
||||||
start,
|
start,
|
||||||
totalVisitorsLabels,
|
totalVisitorsLabels,
|
||||||
totalVisitorsDps,
|
totalVisitorsDps,
|
||||||
tracking.GetPageVisits(start),
|
tracking.GetPageVisits(start),
|
||||||
tracking.GetLanguages(start),
|
tracking.GetLanguages(start),
|
||||||
|
hourlyVisitorsLabels,
|
||||||
|
hourlyVisitorsDps,
|
||||||
|
hourlyVisitorsTodayLabels,
|
||||||
|
hourlyVisitorsTodayDps,
|
||||||
|
tracking.GetActiveVisitors(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,13 +14,21 @@
|
|||||||
<a href="/tracking?start=365" class="button {{if eq .Start 365}}filled{{end}}">Year</a>
|
<a href="/tracking?start=365" class="button {{if eq .Start 365}}filled{{end}}">Year</a>
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
<section>
|
||||||
<!-- TODO real time -->
|
<h2>Active Visitors</h2>
|
||||||
|
<p>
|
||||||
|
Active within the last five minutes: {{.ActiveVisitors}}
|
||||||
|
</p>
|
||||||
|
<canvas id="hourlyVisitorsToday" class="tracking"></canvas>
|
||||||
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<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>
|
||||||
|
<canvas id="hourlyVisitors" class="tracking"></canvas>
|
||||||
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<h2>Pages Visits</h2>
|
<h2>Pages Visits</h2>
|
||||||
</section>
|
</section>
|
||||||
@@ -57,13 +65,21 @@
|
|||||||
</table>
|
</table>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- TODO -->
|
|
||||||
<!--<section>
|
|
||||||
<h2>Visitors Per Hour</h2>
|
|
||||||
</section>-->
|
|
||||||
|
|
||||||
<script type="text/javascript" src="/static/js/Chart-v2.9.3.bundle.min.js"></script>
|
<script type="text/javascript" src="/static/js/Chart-v2.9.3.bundle.min.js"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
new Chart(document.getElementById('hourlyVisitorsToday').getContext('2d'), {
|
||||||
|
type: "line",
|
||||||
|
data: {
|
||||||
|
labels: [{{.HourlyVisitorsTodayLabels}}],
|
||||||
|
datasets: [{
|
||||||
|
backgroundColor: "rgba(127, 127, 127, 0.05)",
|
||||||
|
borderColor: "#7f7f7f",
|
||||||
|
label: "Hourly Visitors for Today",
|
||||||
|
data: [{{.HourlyVisitorsTodayDps}}]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
new Chart(document.getElementById('totalVisitors').getContext('2d'), {
|
new Chart(document.getElementById('totalVisitors').getContext('2d'), {
|
||||||
type: "line",
|
type: "line",
|
||||||
data: {
|
data: {
|
||||||
@@ -77,6 +93,19 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
new Chart(document.getElementById('hourlyVisitors').getContext('2d'), {
|
||||||
|
type: "line",
|
||||||
|
data: {
|
||||||
|
labels: [{{.HourlyVisitorsLabels}}],
|
||||||
|
datasets: [{
|
||||||
|
backgroundColor: "rgba(127, 127, 127, 0.05)",
|
||||||
|
borderColor: "#7f7f7f",
|
||||||
|
label: "Hourly Visitors",
|
||||||
|
data: [{{.HourlyVisitorsDps}}]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
{{range $i, $data := .PageVisits}}
|
{{range $i, $data := .PageVisits}}
|
||||||
new Chart(document.getElementById('pageVisits{{$i}}').getContext('2d'), {
|
new Chart(document.getElementById('pageVisits{{$i}}').getContext('2d'), {
|
||||||
type: "line",
|
type: "line",
|
||||||
|
|||||||
@@ -63,6 +63,39 @@ func GetLanguages(start int) []pirsch.VisitorLanguage {
|
|||||||
return languages
|
return languages
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetHourlyVisitors(start int) (template.JS, template.JS) {
|
||||||
|
visitors, err := analyzer.HourlyVisitors(&pirsch.Filter{From: getStartTime(start), To: today()})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logbuch.Error("Error reading hourly visitors", logbuch.Fields{"err": err})
|
||||||
|
return "", ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return getLabelsAndDataHourly(visitors)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetHourlyVisitorsToday() (template.JS, template.JS) {
|
||||||
|
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 GetActiveVisitors() int {
|
||||||
|
visitors, err := analyzer.ActiveVisitors(time.Minute * 5)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logbuch.Error("Error reading active visitors", logbuch.Fields{"err": err})
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return visitors
|
||||||
|
}
|
||||||
|
|
||||||
func getStartTime(start int) time.Time {
|
func getStartTime(start int) time.Time {
|
||||||
startTime := today()
|
startTime := today()
|
||||||
return startTime.Add(-time.Hour * 24 * time.Duration(start-1))
|
return startTime.Add(-time.Hour * 24 * time.Duration(start-1))
|
||||||
@@ -82,6 +115,20 @@ 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.HourlyVisitors) (template.JS, template.JS) {
|
||||||
|
var labels strings.Builder
|
||||||
|
var dp strings.Builder
|
||||||
|
|
||||||
|
for _, point := range visitors {
|
||||||
|
labels.WriteString(fmt.Sprintf("'%d',", point.Hour))
|
||||||
|
dp.WriteString(fmt.Sprintf("%d,", point.Visitors))
|
||||||
|
}
|
||||||
|
|
||||||
|
labelsStr := labels.String()
|
||||||
|
dataStr := dp.String()
|
||||||
|
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()
|
||||||
return time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC)
|
return time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC)
|
||||||
|
|||||||
Reference in New Issue
Block a user