cleaned up tracking
This commit is contained in:
1
go.mod
1
go.mod
@@ -18,6 +18,7 @@ require (
|
|||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/mileusna/useragent v1.3.5 // indirect
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||||
github.com/prometheus/client_model v0.6.2 // indirect
|
github.com/prometheus/client_model v0.6.2 // indirect
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -26,6 +26,8 @@ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHP
|
|||||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
github.com/mileusna/useragent v1.3.5 h1:SJM5NzBmh/hO+4LGeATKpaEX9+b4vcGg2qXGLiNGDws=
|
||||||
|
github.com/mileusna/useragent v1.3.5/go.mod h1:3d8TOmwL/5I8pJjyVDteHtgDGcefrFUX4ccGOMKNYYc=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||||
|
|||||||
@@ -102,7 +102,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MY supper tracking
|
// MY supper tracking
|
||||||
e.Use(tracking.Echo)
|
e.Use(tracking.EchoWithConfig(tracking.TrackingConfig{
|
||||||
|
IgnorePaths: []string{"/tracking", "/metrics", "/css/*", "/js/*"},
|
||||||
|
IgnoreUserAgents: []string{"Prometheus", "UptimeRobot"},
|
||||||
|
}))
|
||||||
trackingGroup := e.Group("/tracking")
|
trackingGroup := e.Group("/tracking")
|
||||||
trackingGroup.GET("", tracking.BasicTrackingHandler)
|
trackingGroup.GET("", tracking.BasicTrackingHandler)
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
package tracking
|
package tracking
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"knet.sk/src/util"
|
"knet.sk/src/util"
|
||||||
)
|
)
|
||||||
@@ -35,33 +32,36 @@ type PageStat struct {
|
|||||||
|
|
||||||
var ts *TrackingService
|
var ts *TrackingService
|
||||||
|
|
||||||
var ignorePaths = []string{
|
type TrackingConfig struct {
|
||||||
"/tracking",
|
IgnorePaths []string
|
||||||
"/metrics",
|
IgnoreUserAgents []string
|
||||||
}
|
}
|
||||||
|
|
||||||
var ignoreUserAgents = []string{
|
type TrackingMiddleware struct {
|
||||||
"Prometheus",
|
Config TrackingConfig
|
||||||
"UptimeRobot",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Echo(next echo.HandlerFunc) echo.HandlerFunc {
|
var middleware *TrackingMiddleware
|
||||||
|
|
||||||
|
func EchoWithConfig(config TrackingConfig) func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
|
middleware = &TrackingMiddleware{
|
||||||
|
Config: config,
|
||||||
|
}
|
||||||
|
return middleware.Echo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mw TrackingMiddleware) Echo(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
ts = StartTrackingService()
|
ts = StartTrackingService()
|
||||||
return func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
fmt.Printf("Tracking visit: %s %s\n", c.RealIP(), c.Request().URL.Path)
|
ignorePathsRegex := getRegexFromWildcard(mw.Config.IgnorePaths)
|
||||||
// Check if the path is in the ignore list
|
if ignorePathsRegex.Match([]byte(c.Request().URL.Path)) {
|
||||||
for _, path := range ignorePaths {
|
|
||||||
if c.Request().URL.Path == path {
|
|
||||||
return next(c) // Skip tracking for ignored paths
|
return next(c) // Skip tracking for ignored paths
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the user agent is in the ignore list
|
ignoreUserAgentsRegex := getRegexFromWildcard(mw.Config.IgnoreUserAgents)
|
||||||
for _, ua := range ignoreUserAgents {
|
if ignoreUserAgentsRegex.Match([]byte(c.Request().UserAgent())) {
|
||||||
if strings.Contains(c.Request().UserAgent(), ua) {
|
|
||||||
return next(c) // Skip tracking for ignored user agents
|
return next(c) // Skip tracking for ignored user agents
|
||||||
}
|
}
|
||||||
}
|
|
||||||
go ts.AddVisit(c)
|
go ts.AddVisit(c)
|
||||||
return next(c)
|
return next(c)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package tracking
|
|||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
_ "modernc.org/sqlite"
|
_ "modernc.org/sqlite"
|
||||||
@@ -175,10 +176,21 @@ func (ts *TrackingService) GetRecentVisits(limit int) []VisitDisplay {
|
|||||||
var visits []VisitDisplay
|
var visits []VisitDisplay
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var visit VisitDisplay
|
var visit VisitDisplay
|
||||||
if err := rows.Scan(&visit.Timestamp, &visit.IPAddress, &visit.Path, &visit.UserAgent, &visit.Referrer); err != nil {
|
var rawTimestamp string
|
||||||
|
if err := rows.Scan(&rawTimestamp, &visit.IPAddress, &visit.Path, &visit.UserAgent, &visit.Referrer); err != nil {
|
||||||
println("Error scanning visit:", err.Error())
|
println("Error scanning visit:", err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse and format the timestamp
|
||||||
|
if t, err := time.Parse("2006-01-02 15:04:05", rawTimestamp); err == nil {
|
||||||
|
visit.Timestamp = t.Format("Jan 2, 2006 at 3:04 PM")
|
||||||
|
} else {
|
||||||
|
// Fallback to original timestamp if parsing fails
|
||||||
|
visit.Timestamp = rawTimestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
visit.UserAgent = parseUserAgent(visit.UserAgent)
|
||||||
visits = append(visits, visit)
|
visits = append(visits, visit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
src/tracking/useragent.go
Normal file
12
src/tracking/useragent.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package tracking
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mileusna/useragent"
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseUserAgent(ua string) string {
|
||||||
|
|
||||||
|
parsedUA := useragent.Parse(ua)
|
||||||
|
|
||||||
|
return parsedUA.Name + " " + parsedUA.OS + " " + parsedUA.Version
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
package tracking
|
package tracking
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -13,3 +16,16 @@ func getFingerprint(c echo.Context) string {
|
|||||||
// Combine them into a fingerprint string
|
// Combine them into a fingerprint string
|
||||||
return ip + userAgent + acceptLanguage
|
return ip + userAgent + acceptLanguage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getRegexFromWildcard(wildcards []string) *regexp.Regexp {
|
||||||
|
escapedWildcards := make([]string, len(wildcards))
|
||||||
|
for i, wildcard := range wildcards {
|
||||||
|
escapedWildcards[i] = regexp.QuoteMeta(wildcard)
|
||||||
|
escapedWildcards[i] = strings.ReplaceAll(escapedWildcards[i], `\*`, ".*") // Replace escaped wildcard with regex equivalent
|
||||||
|
}
|
||||||
|
pattern := "^(" + strings.Join(escapedWildcards, "|") + ")$"
|
||||||
|
|
||||||
|
// Compile the regex
|
||||||
|
regex := regexp.MustCompile(pattern)
|
||||||
|
return regex
|
||||||
|
}
|
||||||
|
|||||||
@@ -154,8 +154,6 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="/js/global.d.ts?v={{.BuildNumber}}" integrity="{{index .Integrity.JS "global.d.ts" }}" crossorigin="anonymous"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
Reference in New Issue
Block a user