pirsch

package module
v3.10.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2022 License: AGPL-3.0 Imports: 35 Imported by: 0

README

Pirsch

Go Reference Go Report Card Chat on Discord

Pirsch is a server side, no-cookie, drop-in and privacy focused tracking solution for Go. Integrated into a Go application it enables you to track HTTP traffic without invading the privacy of your visitors. The visualization of the data (dashboard) is not part of this project.

If you're looking for a managed solution with an easy-to-use API and JavaScript integration, check out https://pirsch.io/.

How does it work?

Pirsch generates a unique fingerprint for each visitor. The fingerprint is a hash of the visitors IP, User-Agent, the date, and a salt.

Each time a visitor opens your page, Pirsch will store a hit. The hits are analyzed using the Analyzer to extract meaningful data.

The tracking works without invading the visitor's privacy as no cookies are used nor required. Pirsch can track visitors using ad blockers that block trackers like Google Analytics.

Features

  • unique visitor count per day, path, and hour
  • session count
  • bounce rate
  • view count
  • growth (unique visitors, sessions, bounces, views, average session duration)
  • average time on page
  • average session duration
  • languages
  • operating system and browser (including versions)
  • referrers
  • countries
  • cities
  • platform
  • screen size
  • UTM query parameters for campaign tracking
  • entry and exit pages
  • custom event tracking
  • conversion goals

All timestamps are stored as UTC. Starting with version 2.1, the results can be transformed to the desired timezone. All data points belongs to an (optional) client, which can be used to split data between multiple domains for example. If you just integrate Pirsch into your application, you don't need to care about that field. But if you do, you need to set a client ID for all columns!

Usage

To store hits and statistics, Pirsch uses ClickHouse. Database migrations can be run manually be executing the migrations steps in schema or by using the automatic migration.

Make sure you read the changelog before upgrading! There are sometimes manual steps required to migrate the data to the new version.

Server-side tracking

Here is a quick demo on how to use the library:

// Set the key for SipHash. This should be called on startup (before generating the first fingerprint) and is NOT concurrency save.
pirsch.SetFingerprintKeys(42, 123)

// Migrate the database.
pirsch.Migrate("tcp://127.0.0.1:9000/database")

// Create a new ClickHouse client to save hits.
store, _ := pirsch.NewClient("tcp://127.0.0.1:9000/database", nil)

// Set up a default tracker with a salt.
// This will buffer and store hits and generate sessions by default.
tracker := pirsch.NewTracker(store, "salt", nil)

// Create a handler to serve traffic.
// We prevent tracking resources by checking the path. So a file on /my-file.txt won't create a new hit
// but all page calls will be tracked.
http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path == "/" {
        go tracker.Hit(r, nil)
    }

    w.Write([]byte("<h1>Hello World!</h1>"))
}))

// And finally, start the server.
// We don't flush hits on shutdown but you should add that in a real application by calling Tracker.Flush().
log.Println("Starting server on port 8080...")
http.ListenAndServe(":8080", nil)

The secret salt passed to NewTracker should not be known outside your organization as it can be used to generate fingerprints equal to yours. Note that while you can generate the salt at random, the fingerprints will change too. To get reliable data configure a fixed salt and treat it like a password.

To analyze hits and processed data you can use the Analyzer, which provides convenience functions to extract useful information.

// This also needs access to the store.
analyzer := pirsch.NewAnalyzer(store)

// As an example, lets extract the total number of visitors.
// The filter is used to specify the time frame you're looking at (days) and is optional.
// If you pass nil, the Analyzer returns statistics for all hits (be careful about that!).
visitors, err := analyzer.Visitors(&pirsch.Filter{
    From: yesterday(),
    To: today()
})
Client-side tracking

You can also track visitors on the client side by adding pirsch.js/pirsch-events.js to your website. It will perform a GET request to the configured endpoint.

<!-- add the tracking script to the head area and configure it using attributes -->
<script type="text/javascript" src="js/pirsch.js" id="pirschjs"
        data-endpoint="/count"
        data-client-id="42"
        data-exclude="/path/to/exclude,/regex/.*"
        data-domain="foo.com,bar.com"
        data-dev
        data-param-optional-param="test"></script>

The parameters are configured through HTML attributes. All of them are optional, except for the id. Here is a list of the possible options.

Option Description Default
data-endpoint The endpoint to call. This can be a local path, like /tracking, or a complete URL, like http://mywebsite.com/tracking. It must not contain any parameters. /pirsch
data-client-id The client ID to use, in case you plan to track multiple websites using the same backend, or you want to split the data. Note that the client ID must be validated in the backend. 0 (no client)
data-exclude Specifies a list of regular expressions to test against. On a match, the page view or event will be ignored. (no paths)
data-domain Specifies a list of additional domains to send data to. (empty list)
data-dev Enable tracking hits on localhost. This is used for testing purposes only. false
data-param-* Additional parameters to send with the request. The name send is everything after data-param-. (no parameters)

The scripts can be disabled by setting the disable_pirsch variable in localStorage of your browser.

To track the hits you need to call Hit from the endpoint that you configured for pirsch.js. Here is a simple example.

// Create an endpoint to handle client tracking requests.
// HitOptionsFromRequest is a utility function to process the required parameters.
// You might want to additional checks, like for the client ID.
http.Handle("/count", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    tracker.Hit(r, pirsch.HitOptionsFromRequest(r))
}))

HitOptionsFromRequest will read the parameters send by pirsch.js and returns a new HitOptions object that can be passed to Hit. You might want to split these steps into two, to run additional checks for the parameters that were sent by the user.

Custom Event Tracking

Custom events are conceptually the same as hits, except that they have a name and hold additional metadata. To create an event, call the tracker and pass in the additional fields.

http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path == "/" {
    	// The name in the options is required!
		options := pirsch.EventOptions{
            Name: "my-event",
            Duration: 42, // optional field to save a duration, this will be used to calculate an average time when using the analyzer
            Meta: map[string]string{ // optional metadata, the results can be filtered by them
                "http_status": "200",
                "product_id": "123",
            },
        }
        go tracker.Event(r, options, nil)
    }

    w.Write([]byte("<h1>Hello World!</h1>"))
}))

There are two methods to read events using the Analyzer. Analyzer.Events returns a list containing all events and metadata keys. Analyzer.EventBreakdown breaks down a single event by grouping the metadata fields by value. You have to set the Filter.EventName and Filter.EventMetaKey when using this function. All other analyzer methods can be used with an event name to filter for an event.

Mapping IPs to countries and cities

Pirsch uses MaxMind's GeoLite2 database to map IPs to countries. The database is not included, so you need to download it yourself. IP mapping is optional, it must explicitly be enabled by setting the GeoDB attribute of the TrackerConfig or through the HitOptions when calling HitFromRequest.

  1. create an account at MaxMind
  2. generate a new license key
  3. call GetGeoLite2 with the path you would like to extract the tarball to and pass your license key
  4. create a new GeoDB by using NewGeoDB and the file you downloaded and extracted using the step before

The GeoDB should be updated on a regular basis. The Tracker has a method SetGeoDB to update the GeoDB at runtime (thread-safe).

Documentation

Read the full documentation for details, check out demos, or read the article at https://marvinblum.de/blog/server-side-tracking-without-cookies-in-go-OxdzmGZ1Bl.

Building pirsch.js and pirsch-events.js

To minify pirsch.js/pirsch-events.js to pirsch.min.js/pirsch-events.min.js you need to run npm i and npm run minify inside the js directory.

Things to maintain

The following things need regular maintenance/updates (using the scripts in the scripts directory when possible):

  • Go and JS dependencies
  • referrer blacklist
  • User-Agent blacklist
  • browser version mapping
  • os version mapping
  • referrer mapping (grouping)

GeoDB updates itself if used.

Changelog

See CHANGELOG.md.

Contribution

Contributions are welcome! Please open a pull requests for your changes and tickets in case you would like to discuss something or have a question.

To run the tests you'll need a ClickHouse database, and a schema called pirschtest. The user is set to default (no password).

Note that we only accept pull requests if you transfer the ownership of your contribution to us. As we also offer a managed commercial solution with this library at its core, we want to make sure we can keep control over the source code.

License

GNU AGPLv3

Documentation

Index

Constants

View Source
const (
	// PeriodDay groups the results by date.
	PeriodDay = Period(iota)

	// PeriodWeek groups the results by week.
	PeriodWeek

	// PeriodMonth groups the results by month.
	PeriodMonth

	// PeriodYear groups the result by year.
	PeriodYear

	// PlatformDesktop filters for everything on desktops.
	PlatformDesktop = "desktop"

	// PlatformMobile filters for everything on mobile devices.
	PlatformMobile = "mobile"

	// PlatformUnknown filters for everything where the platform is unspecified.
	PlatformUnknown = "unknown"

	// Unknown filters for an unknown (empty) value.
	// This is a synonym for "null".
	Unknown = "null"

	// DirectionASC sorts results in ascending order.
	DirectionASC = Direction("ASC")

	// DirectionDESC sorts results in descending order.
	DirectionDESC = Direction("DESC")
)
View Source
const (
	// BrowserChrome represents the Chrome and Chromium browser.
	BrowserChrome = "Chrome"

	// BrowserFirefox represents the Firefox browser.
	BrowserFirefox = "Firefox"

	// BrowserSafari  represents the Safari browser.
	BrowserSafari = "Safari"

	// BrowserOpera represents the Opera browser.
	BrowserOpera = "Opera"

	// BrowserEdge represents the Edge browser.
	BrowserEdge = "Edge"

	// BrowserIE represents the Internet Explorer browser.
	BrowserIE = "IE"

	// OSWindows represents the Windows operating system.
	OSWindows = "Windows"

	// OSMac represents the Mac operating system.
	OSMac = "Mac"

	// OSLinux represents a Linux distribution.
	OSLinux = "Linux"

	// OSAndroid represents the Android operating system.
	OSAndroid = "Android"

	// OSiOS represents the iOS operating system.
	OSiOS = "iOS"

	// OSWindowsMobile represents the Windows Mobile operating system.
	OSWindowsMobile = "Windows Mobile"
)
View Source
const (

	// GeoLite2Filename is the default filename of the GeoLite2 database.
	GeoLite2Filename = "GeoLite2-City.mmdb"
)

Variables

View Source
var (
	// FieldCount is a query result column.
	FieldCount = Field{

		Name: "count",
		// contains filtered or unexported fields
	}

	// FieldPath is a query result column.
	FieldPath = Field{

		Name: "path",
		// contains filtered or unexported fields
	}

	// FieldEntryPath is a query result column.
	FieldEntryPath = Field{

		Name: "entry_path",
		// contains filtered or unexported fields
	}

	// FieldEntries is a query result column.
	FieldEntries = Field{

		Name: "entries",
		// contains filtered or unexported fields
	}

	// FieldExitPath is a query result column.
	FieldExitPath = Field{

		Name: "exit_path",
		// contains filtered or unexported fields
	}

	// FieldExits is a query result column.
	FieldExits = Field{

		Name: "exits",
		// contains filtered or unexported fields
	}

	// FieldVisitors is a query result column.
	FieldVisitors = Field{

		Name: "visitors",
		// contains filtered or unexported fields
	}

	// FieldRelativeVisitors is a query result column.
	FieldRelativeVisitors = Field{

		Name: "relative_visitors",
		// contains filtered or unexported fields
	}

	// FieldCR is a query result column.
	FieldCR = Field{

		Name: "cr",
		// contains filtered or unexported fields
	}

	// FieldSessions is a query result column.
	FieldSessions = Field{

		Name: "sessions",
		// contains filtered or unexported fields
	}

	// FieldViews is a query result column.
	FieldViews = Field{

		Name: "views",
		// contains filtered or unexported fields
	}

	// FieldRelativeViews is a query result column.
	FieldRelativeViews = Field{

		Name: "relative_views",
		// contains filtered or unexported fields
	}

	// FieldBounces is a query result column.
	FieldBounces = Field{

		Name: "bounces",
		// contains filtered or unexported fields
	}

	// FieldBounceRate is a query result column.
	FieldBounceRate = Field{

		Name: "bounce_rate",
		// contains filtered or unexported fields
	}

	// FieldReferrer is a query result column.
	FieldReferrer = Field{

		Name: "referrer",
		// contains filtered or unexported fields
	}

	// FieldAnyReferrer is a query result column.
	FieldAnyReferrer = Field{

		Name: "referrer",
		// contains filtered or unexported fields
	}

	// FieldReferrerName is a query result column.
	FieldReferrerName = Field{

		Name: "referrer_name",
		// contains filtered or unexported fields
	}

	// FieldReferrerIcon is a query result column.
	FieldReferrerIcon = Field{

		Name: "referrer_icon",
		// contains filtered or unexported fields
	}

	// FieldLanguage is a query result column.
	FieldLanguage = Field{

		Name: "language",
		// contains filtered or unexported fields
	}

	// FieldCountryCity is a query result column.
	// This field can only be used in combination with the FieldCity.
	FieldCountryCity = Field{

		Name: "country_code",
		// contains filtered or unexported fields
	}

	// FieldCountry is a query result column.
	FieldCountry = Field{

		Name: "country_code",
		// contains filtered or unexported fields
	}

	// FieldCity is a query result column.
	FieldCity = Field{

		Name: "city",
		// contains filtered or unexported fields
	}

	// FieldBrowser is a query result column.
	FieldBrowser = Field{

		Name: "browser",
		// contains filtered or unexported fields
	}

	// FieldBrowserVersion is a query result column.
	FieldBrowserVersion = Field{

		Name: "browser_version",
		// contains filtered or unexported fields
	}

	// FieldOS is a query result column.
	FieldOS = Field{

		Name: "os",
		// contains filtered or unexported fields
	}

	// FieldOSVersion is a query result column.
	FieldOSVersion = Field{

		Name: "os_version",
		// contains filtered or unexported fields
	}

	// FieldScreenClass is a query result column.
	FieldScreenClass = Field{

		Name: "screen_class",
		// contains filtered or unexported fields
	}

	// FieldUTMSource is a query result column.
	FieldUTMSource = Field{

		Name: "utm_source",
		// contains filtered or unexported fields
	}

	// FieldUTMMedium is a query result column.
	FieldUTMMedium = Field{

		Name: "utm_medium",
		// contains filtered or unexported fields
	}

	// FieldUTMCampaign is a query result column.
	FieldUTMCampaign = Field{

		Name: "utm_campaign",
		// contains filtered or unexported fields
	}

	// FieldUTMContent is a query result column.
	FieldUTMContent = Field{

		Name: "utm_content",
		// contains filtered or unexported fields
	}

	// FieldUTMTerm is a query result column.
	FieldUTMTerm = Field{

		Name: "utm_term",
		// contains filtered or unexported fields
	}

	// FieldTitle is a query result column.
	FieldTitle = Field{

		Name: "title",
		// contains filtered or unexported fields
	}

	// FieldEntryTitle is a query result column.
	FieldEntryTitle = Field{

		Name: "title",
		// contains filtered or unexported fields
	}

	// FieldExitTitle is a query result column.
	FieldExitTitle = Field{

		Name: "title",
		// contains filtered or unexported fields
	}

	// FieldDay is a query result column.
	FieldDay = Field{

		Name: "day",
		// contains filtered or unexported fields
	}

	// FieldHour is a query result column.
	FieldHour = Field{

		Name: "hour",
		// contains filtered or unexported fields
	}

	// FieldEventName is a query result column.
	FieldEventName = Field{

		Name: "event_name",
		// contains filtered or unexported fields
	}

	// FieldEventMeta is a query result column.
	FieldEventMeta = Field{

		Name: "meta",
		// contains filtered or unexported fields
	}

	// FieldEventMetaKeys is a query result column.
	FieldEventMetaKeys = Field{

		Name: "meta_keys",
		// contains filtered or unexported fields
	}

	// FieldEventMetaValues is a query result column.
	FieldEventMetaValues = Field{

		Name: "meta_value",
		// contains filtered or unexported fields
	}

	// FieldEventTimeSpent is a query result column.
	FieldEventTimeSpent = Field{

		Name: "average_time_spent_seconds",
		// contains filtered or unexported fields
	}
)
View Source
var (
	// CFConnectingIP is an HeaderParser.
	// https://support.cloudflare.com/hc/en-us/articles/206776727-What-is-True-Client-IP-
	CFConnectingIP = HeaderParser{"CF-Connecting-IP", parseXForwardedForHeader}

	// TrueClientIP is an HeaderParser.
	TrueClientIP = HeaderParser{"True-Client-IP", parseXForwardedForHeader}

	// XForwardedFor is an HeaderParser.
	XForwardedFor = HeaderParser{"X-Forwarded-For", parseXForwardedForHeader}

	// Forwarded is an HeaderParser.
	Forwarded = HeaderParser{"Forwarded", parseForwardedHeader}

	// XRealIP is an HeaderParser.
	XRealIP = HeaderParser{"X-Real-IP", parseXRealIPHeader}

	// DefaultHeaderParser is a list of headers and corresponding parsers to look up the real client IP.
	// They will be check in order, the first non-empty one will be picked,
	// or else the remote address is selected.
	DefaultHeaderParser = []HeaderParser{
		CFConnectingIP,
		TrueClientIP,
		XForwardedFor,
		Forwarded,
		XRealIP,
	}
)
View Source
var (
	// ErrNoPeriodOrDay is returned in case no period or day was specified to calculate the growth rate.
	ErrNoPeriodOrDay = errors.New("no period or day specified")
)
View Source
var NullClient = int64(0)

NullClient is a placeholder for no client (0).

View Source
var ScreenClasses = []screenClass{
	{5120, "UHD 5K"},
	{3840, "UHD 4K"},
	{2560, "WQHD"},
	{1920, "Full HD"},
	{1280, "HD"},
	{1024, "XL"},
	{800, "L"},
	{600, "M"},
	{415, "S"},
}

ScreenClasses is a list of typical screen sizes used to group resolutions. Everything below is considered "XS" (tiny).

Functions

func ExtendSession added in v3.2.0

func ExtendSession(r *http.Request, salt string, options *HitOptions)

ExtendSession looks up and extends the session for given request. This function does not Store a hit or event in database.

func Fingerprint

func Fingerprint(r *http.Request, salt string, headerParser []HeaderParser, allowed []net.IPNet) uint64

Fingerprint returns a hash for given request and salt. The hash is unique for the visitor.

func GetGeoLite2

func GetGeoLite2(path, licenseKey string) error

GetGeoLite2 downloads and unpacks the MaxMind GeoLite2 database. The tarball is downloaded and unpacked at the provided path. The directories will created if required. The license key is used for the download and must be provided for a registered account. Please refer to MaxMinds website on how to do that: https://dev.maxmind.com/geoip/geoip2/geolite2/ The database should be updated on a regular basis.

func GetScreenClass

func GetScreenClass(width uint16) string

GetScreenClass returns the screen class for given width in pixels.

func HitFromRequest

func HitFromRequest(r *http.Request, salt string, options *HitOptions) (*PageView, SessionState, *UserAgent)

HitFromRequest returns a new PageView and Session for given request, salt and HitOptions. The salt must stay consistent to track visitors across multiple calls. The easiest way to track visitors is to use the Tracker.

func IgnoreHit

func IgnoreHit(r *http.Request) bool

IgnoreHit returns true, if a hit should be ignored for given request, or false otherwise. The easiest way to track visitors is to use the Tracker.

func Migrate

func Migrate(config *ClientConfig) error

Migrate runs the database migration for given connection string. This will use the embedded schema migration scripts.

func RunAtMidnight

func RunAtMidnight(f func()) context.CancelFunc

RunAtMidnight calls given function on each day of month on midnight (UTC), unless it is cancelled by calling the cancel function.

func SetFingerprintKeys added in v3.3.0

func SetFingerprintKeys(key0, key1 uint64)

SetFingerprintKeys used to set the SipHash keys for fingerprints. This function is NOT concurrency save and should be called once on startup (before generating the first fingerprint).

func Today

func Today() time.Time

Today returns the date for today without time at UTC.

Types

type ActiveVisitorStats

type ActiveVisitorStats struct {
	Path     string `json:"path"`
	Title    string `json:"title"`
	Visitors int    `json:"visitors"`
}

ActiveVisitorStats is the result type for active visitor statistics.

type Analyzer

type Analyzer struct {
	// contains filtered or unexported fields
}

Analyzer provides an interface to analyze statistics.

func NewAnalyzer

func NewAnalyzer(store Store, config *AnalyzerConfig) *Analyzer

NewAnalyzer returns a new Analyzer for given Store.

func (*Analyzer) ActiveVisitors

func (analyzer *Analyzer) ActiveVisitors(filter *Filter, duration time.Duration) ([]ActiveVisitorStats, int, error)

ActiveVisitors returns the active visitors per path and (optional) page title and the total number of active visitors for given duration. Use time.Minute*5 for example to get the active visitors for the past 5 minutes.

func (*Analyzer) AvgSessionDuration

func (analyzer *Analyzer) AvgSessionDuration(filter *Filter) ([]TimeSpentStats, error)

AvgSessionDuration returns the average session duration grouped by day, week, month, or year.

func (*Analyzer) AvgTimeOnPage

func (analyzer *Analyzer) AvgTimeOnPage(filter *Filter) ([]TimeSpentStats, error)

AvgTimeOnPage returns the average time on page grouped by day, week, month, or year.

func (*Analyzer) Browser

func (analyzer *Analyzer) Browser(filter *Filter) ([]BrowserStats, error)

Browser returns the visitor count grouped by browser.

func (*Analyzer) BrowserVersion

func (analyzer *Analyzer) BrowserVersion(filter *Filter) ([]BrowserVersionStats, error)

BrowserVersion returns the visitor count grouped by browser and version.

func (*Analyzer) Cities

func (analyzer *Analyzer) Cities(filter *Filter) ([]CityStats, error)

Cities returns the visitor count grouped by city.

func (*Analyzer) Countries

func (analyzer *Analyzer) Countries(filter *Filter) ([]CountryStats, error)

Countries returns the visitor count grouped by country.

func (*Analyzer) EntryPages

func (analyzer *Analyzer) EntryPages(filter *Filter) ([]EntryStats, error)

EntryPages returns the visitor count and time on page grouped by path and (optional) page title for the first page visited.

func (*Analyzer) EventBreakdown

func (analyzer *Analyzer) EventBreakdown(filter *Filter) ([]EventStats, error)

EventBreakdown returns the visitor count, views, and conversion rate for a custom event grouping them by a meta value for given key. The Filter.EventName and Filter.EventMetaKey must be set, or otherwise the result set will be empty.

func (*Analyzer) EventList added in v3.5.0

func (analyzer *Analyzer) EventList(filter *Filter) ([]EventListStats, error)

EventList returns events as a list. The metadata is grouped as key-value pairs.

func (*Analyzer) Events

func (analyzer *Analyzer) Events(filter *Filter) ([]EventStats, error)

Events returns the visitor count, views, and conversion rate for custom events.

func (*Analyzer) ExitPages

func (analyzer *Analyzer) ExitPages(filter *Filter) ([]ExitStats, error)

ExitPages returns the visitor count and time on page grouped by path and (optional) page title for the last page visited.

func (*Analyzer) Growth

func (analyzer *Analyzer) Growth(filter *Filter) (*Growth, error)

Growth returns the growth rate for visitor count, session count, bounces, views, and average session duration or average time on page (if path is set). The growth rate is relative to the previous time range or day. The period or day for the filter must be set, else an error is returned.

func (*Analyzer) Languages

func (analyzer *Analyzer) Languages(filter *Filter) ([]LanguageStats, error)

Languages returns the visitor count grouped by language.

func (*Analyzer) OS

func (analyzer *Analyzer) OS(filter *Filter) ([]OSStats, error)

OS returns the visitor count grouped by operating system.

func (*Analyzer) OSVersion

func (analyzer *Analyzer) OSVersion(filter *Filter) ([]OSVersionStats, error)

OSVersion returns the visitor count grouped by operating systems and version.

func (*Analyzer) PageConversions

func (analyzer *Analyzer) PageConversions(filter *Filter) (*PageConversionsStats, error)

PageConversions returns the visitor count, views, and conversion rate for conversion goals. This function is supposed to be used with the Filter.PathPattern, to list page conversions.

func (*Analyzer) Pages

func (analyzer *Analyzer) Pages(filter *Filter) ([]PageStats, error)

Pages returns the visitor count, session count, bounce rate, views, and average time on page grouped by path and (optional) page title.

func (*Analyzer) Platform

func (analyzer *Analyzer) Platform(filter *Filter) (*PlatformStats, error)

Platform returns the visitor count grouped by platform.

func (*Analyzer) Referrer

func (analyzer *Analyzer) Referrer(filter *Filter) ([]ReferrerStats, error)

Referrer returns the visitor count and bounce rate grouped by referrer.

func (*Analyzer) ScreenClass

func (analyzer *Analyzer) ScreenClass(filter *Filter) ([]ScreenClassStats, error)

ScreenClass returns the visitor count grouped by screen class.

func (*Analyzer) TotalVisitors added in v3.4.3

func (analyzer *Analyzer) TotalVisitors(filter *Filter) (*TotalVisitorStats, error)

TotalVisitors returns the total visitor count, session count, bounce rate, and views.

func (*Analyzer) UTMCampaign

func (analyzer *Analyzer) UTMCampaign(filter *Filter) ([]UTMCampaignStats, error)

UTMCampaign returns the visitor count grouped by utm source.

func (*Analyzer) UTMContent

func (analyzer *Analyzer) UTMContent(filter *Filter) ([]UTMContentStats, error)

UTMContent returns the visitor count grouped by utm source.

func (*Analyzer) UTMMedium

func (analyzer *Analyzer) UTMMedium(filter *Filter) ([]UTMMediumStats, error)

UTMMedium returns the visitor count grouped by utm medium.

func (*Analyzer) UTMSource

func (analyzer *Analyzer) UTMSource(filter *Filter) ([]UTMSourceStats, error)

UTMSource returns the visitor count grouped by utm source.

func (*Analyzer) UTMTerm

func (analyzer *Analyzer) UTMTerm(filter *Filter) ([]UTMTermStats, error)

UTMTerm returns the visitor count grouped by utm source.

func (*Analyzer) VisitorHours

func (analyzer *Analyzer) VisitorHours(filter *Filter) ([]VisitorHourStats, error)

VisitorHours returns the visitor count grouped by time of day.

func (*Analyzer) Visitors

func (analyzer *Analyzer) Visitors(filter *Filter) ([]VisitorStats, error)

Visitors returns the visitor count, session count, bounce rate, and views grouped by day, week, month, or year.

type AnalyzerConfig added in v3.7.0

type AnalyzerConfig struct {
	// IsBotThreshold see HitOptions.IsBotThreshold.
	IsBotThreshold uint8

	// DisableBotFilter disables IsBotThreshold (otherwise these would be set to the default value).
	DisableBotFilter bool
}

AnalyzerConfig is the optional configuration for the Analyzer.

type AvgTimeSpentStats added in v3.10.0

type AvgTimeSpentStats struct {
	Path                    string
	AverageTimeSpentSeconds int `db:"average_time_spent_seconds"`
}

AvgTimeSpentStats is the average time spent on a page.

type BrowserStats

type BrowserStats struct {
	MetaStats
	Browser string `json:"browser"`
}

BrowserStats is the result type for browser statistics.

type BrowserVersionStats

type BrowserVersionStats struct {
	MetaStats
	Browser        string `json:"browser"`
	BrowserVersion string `db:"browser_version" json:"browser_version"`
}

BrowserVersionStats is the result type for browser version statistics.

type CityStats

type CityStats struct {
	MetaStats
	CountryCode string `db:"country_code" json:"country_code"`
	City        string `json:"city"`
}

CityStats is the result type for city statistics.

type Client

type Client struct {
	*sql.DB
	// contains filtered or unexported fields
}

Client is a ClickHouse database client.

func NewClient

func NewClient(config *ClientConfig) (*Client, error)

NewClient returns a new client for given database connection string. Pass nil for the config to use the defaults.

func (*Client) Count

func (client *Client) Count(query string, args ...any) (int, error)

Count implements the Store interface.

func (*Client) GetGrowthStats added in v3.10.0

func (client *Client) GetGrowthStats(query string, args ...any) (*GrowthStats, error)

GetGrowthStats implements the Store interface.

func (*Client) GetPageConversionsStats added in v3.10.0

func (client *Client) GetPageConversionsStats(query string, args ...any) (*PageConversionsStats, error)

GetPageConversionsStats implements the Store interface.

func (*Client) GetPlatformStats added in v3.10.0

func (client *Client) GetPlatformStats(query string, args ...any) (*PlatformStats, error)

GetPlatformStats implements the Store interface.

func (*Client) GetTotalVisitorStats added in v3.10.0

func (client *Client) GetTotalVisitorStats(query string, args ...any) (*TotalVisitorStats, error)

GetTotalVisitorStats implements the Store interface.

func (*Client) SaveEvents

func (client *Client) SaveEvents(events []Event) error

SaveEvents implements the Store interface.

func (*Client) SavePageViews added in v3.4.0

func (client *Client) SavePageViews(pageViews []PageView) error

SavePageViews implements the Store interface.

func (*Client) SaveSessions added in v3.4.0

func (client *Client) SaveSessions(sessions []Session) error

SaveSessions implements the Store interface.

func (*Client) SaveUserAgents

func (client *Client) SaveUserAgents(userAgents []UserAgent) error

SaveUserAgents implements the Store interface.

func (*Client) SelectActiveVisitorStats added in v3.10.0

func (client *Client) SelectActiveVisitorStats(includeTitle bool, query string, args ...any) ([]ActiveVisitorStats, error)

SelectActiveVisitorStats implements the Store interface.

func (*Client) SelectAvgTimeSpentStats added in v3.10.0

func (client *Client) SelectAvgTimeSpentStats(query string, args ...any) ([]AvgTimeSpentStats, error)

SelectAvgTimeSpentStats implements the Store interface.

func (*Client) SelectBrowserStats added in v3.10.0

func (client *Client) SelectBrowserStats(query string, args ...any) ([]BrowserStats, error)

SelectBrowserStats implements the Store interface.

func (*Client) SelectBrowserVersionStats added in v3.10.0

func (client *Client) SelectBrowserVersionStats(query string, args ...any) ([]BrowserVersionStats, error)

SelectBrowserVersionStats implements the Store interface.

func (*Client) SelectCityStats added in v3.10.0

func (client *Client) SelectCityStats(query string, args ...any) ([]CityStats, error)

SelectCityStats implements the Store interface.

func (*Client) SelectCountryStats added in v3.10.0

func (client *Client) SelectCountryStats(query string, args ...any) ([]CountryStats, error)

SelectCountryStats implements the Store interface.

func (*Client) SelectEntryStats added in v3.10.0

func (client *Client) SelectEntryStats(includeTitle bool, query string, args ...any) ([]EntryStats, error)

SelectEntryStats implements the Store interface.

func (*Client) SelectEventListStats added in v3.10.0

func (client *Client) SelectEventListStats(query string, args ...any) ([]EventListStats, error)

SelectEventListStats implements the Store interface.

func (*Client) SelectEventStats added in v3.10.0

func (client *Client) SelectEventStats(breakdown bool, query string, args ...any) ([]EventStats, error)

SelectEventStats implements the Store interface.

func (*Client) SelectExitStats added in v3.10.0

func (client *Client) SelectExitStats(includeTitle bool, query string, args ...any) ([]ExitStats, error)

SelectExitStats implements the Store interface.

func (*Client) SelectLanguageStats added in v3.10.0

func (client *Client) SelectLanguageStats(query string, args ...any) ([]LanguageStats, error)

SelectLanguageStats implements the Store interface.

func (*Client) SelectOSStats added in v3.10.0

func (client *Client) SelectOSStats(query string, args ...any) ([]OSStats, error)

SelectOSStats implements the Store interface.

func (*Client) SelectOSVersionStats added in v3.10.0

func (client *Client) SelectOSVersionStats(query string, args ...any) ([]OSVersionStats, error)

SelectOSVersionStats implements the Store interface.

func (*Client) SelectPageStats added in v3.10.0

func (client *Client) SelectPageStats(includeTitle, includeEvent bool, query string, args ...any) ([]PageStats, error)

SelectPageStats implements the Store interface.

func (*Client) SelectReferrerStats added in v3.10.0

func (client *Client) SelectReferrerStats(query string, args ...any) ([]ReferrerStats, error)

SelectReferrerStats implements the Store interface.

func (*Client) SelectScreenClassStats added in v3.10.0

func (client *Client) SelectScreenClassStats(query string, args ...any) ([]ScreenClassStats, error)

SelectScreenClassStats implements the Store interface.

func (*Client) SelectTimeSpentStats added in v3.10.0

func (client *Client) SelectTimeSpentStats(period Period, query string, args ...any) ([]TimeSpentStats, error)

SelectTimeSpentStats implements the Store interface.

func (*Client) SelectTotalVisitorSessionStats added in v3.10.0

func (client *Client) SelectTotalVisitorSessionStats(query string, args ...any) ([]TotalVisitorSessionStats, error)

SelectTotalVisitorSessionStats implements the Store interface.

func (*Client) SelectUTMCampaignStats added in v3.10.0

func (client *Client) SelectUTMCampaignStats(query string, args ...any) ([]UTMCampaignStats, error)

SelectUTMCampaignStats implements the Store interface.

func (*Client) SelectUTMContentStats added in v3.10.0

func (client *Client) SelectUTMContentStats(query string, args ...any) ([]UTMContentStats, error)

SelectUTMContentStats implements the Store interface.

func (*Client) SelectUTMMediumStats added in v3.10.0

func (client *Client) SelectUTMMediumStats(query string, args ...any) ([]UTMMediumStats, error)

SelectUTMMediumStats implements the Store interface.

func (*Client) SelectUTMSourceStats added in v3.10.0

func (client *Client) SelectUTMSourceStats(query string, args ...any) ([]UTMSourceStats, error)

SelectUTMSourceStats implements the Store interface.

func (*Client) SelectUTMTermStats added in v3.10.0

func (client *Client) SelectUTMTermStats(query string, args ...any) ([]UTMTermStats, error)

SelectUTMTermStats implements the Store interface.

func (*Client) SelectVisitorHourStats added in v3.10.0

func (client *Client) SelectVisitorHourStats(query string, args ...any) ([]VisitorHourStats, error)

SelectVisitorHourStats implements the Store interface.

func (*Client) SelectVisitorStats added in v3.10.0

func (client *Client) SelectVisitorStats(period Period, query string, args ...any) ([]VisitorStats, error)

SelectVisitorStats implements the Store interface.

func (*Client) Session

func (client *Client) Session(clientID, fingerprint uint64, maxAge time.Time) (*Session, error)

Session implements the Store interface.

type ClientConfig added in v3.7.3

type ClientConfig struct {
	// Hostname is the database hostname.
	Hostname string

	// Port is the database port.
	Port int

	// Database is the database schema.
	Database string

	// Username is the database user.
	Username string

	// Password is the database password.
	Password string

	// Secure enables TLS encryption.
	Secure bool

	// SSLSkipVerify skips the SSL verification if set to true.
	SSLSkipVerify bool

	// MaxOpenConnections sets the number of maximum open connections.
	// If set to <= 0, the default value of 20 will be used.
	MaxOpenConnections int

	// MaxConnectionLifetimeSeconds sets the maximum amount of time a connection will be reused.
	// If set to <= 0, the default value of 1800 will be used.
	MaxConnectionLifetimeSeconds int

	// MaxIdleConnections sets the number of maximum idle connections.
	// If set to <= 0, the default value of 5 will be used.
	MaxIdleConnections int

	// MaxConnectionIdleTimeSeconds sets the maximum amount of time a connection can be idle.
	// If set to <= 0, the default value of 300 will be used.
	MaxConnectionIdleTimeSeconds int

	// Logger is the log.Logger used for logging.
	// The default log will be used printing to os.Stdout with "pirsch" in its prefix in case it is not set.
	Logger *log.Logger

	// Debug will enable verbose logging.
	Debug bool
}

ClientConfig is the optional configuration for the Client.

type ClientMock

type ClientMock struct {
	PageViews     []PageView
	Sessions      []Session
	Events        []Event
	UserAgents    []UserAgent
	ReturnSession *Session
	// contains filtered or unexported fields
}

ClientMock is a mock Store implementation.

func NewMockClient

func NewMockClient() *ClientMock

NewMockClient returns a new mock client.

func (*ClientMock) Count

func (client *ClientMock) Count(string, ...any) (int, error)

Count implements the Store interface.

func (*ClientMock) GetGrowthStats added in v3.10.0

func (client *ClientMock) GetGrowthStats(string, ...any) (*GrowthStats, error)

GetGrowthStats implements the Store interface.

func (*ClientMock) GetPageConversionsStats added in v3.10.0

func (client *ClientMock) GetPageConversionsStats(string, ...any) (*PageConversionsStats, error)

GetPageConversionsStats implements the Store interface.

func (*ClientMock) GetPlatformStats added in v3.10.0

func (client *ClientMock) GetPlatformStats(string, ...any) (*PlatformStats, error)

GetPlatformStats implements the Store interface.

func (*ClientMock) GetTotalVisitorStats added in v3.10.0

func (client *ClientMock) GetTotalVisitorStats(string, ...any) (*TotalVisitorStats, error)

GetTotalVisitorStats implements the Store interface.

func (*ClientMock) SaveEvents

func (client *ClientMock) SaveEvents(events []Event) error

SaveEvents implements the Store interface.

func (*ClientMock) SavePageViews added in v3.4.0

func (client *ClientMock) SavePageViews(pageViews []PageView) error

SavePageViews implements the Store interface.

func (*ClientMock) SaveSessions added in v3.4.0

func (client *ClientMock) SaveSessions(sessions []Session) error

SaveSessions implements the Store interface.

func (*ClientMock) SaveUserAgents

func (client *ClientMock) SaveUserAgents(userAgents []UserAgent) error

SaveUserAgents implements the Store interface.

func (*ClientMock) SelectActiveVisitorStats added in v3.10.0

func (client *ClientMock) SelectActiveVisitorStats(bool, string, ...any) ([]ActiveVisitorStats, error)

SelectActiveVisitorStats implements the Store interface.

func (*ClientMock) SelectAvgTimeSpentStats added in v3.10.0

func (client *ClientMock) SelectAvgTimeSpentStats(string, ...any) ([]AvgTimeSpentStats, error)

SelectAvgTimeSpentStats implements the Store interface.

func (*ClientMock) SelectBrowserStats added in v3.10.0

func (client *ClientMock) SelectBrowserStats(string, ...any) ([]BrowserStats, error)

SelectBrowserStats implements the Store interface.

func (*ClientMock) SelectBrowserVersionStats added in v3.10.0

func (client *ClientMock) SelectBrowserVersionStats(string, ...any) ([]BrowserVersionStats, error)

SelectBrowserVersionStats implements the Store interface.

func (*ClientMock) SelectCityStats added in v3.10.0

func (client *ClientMock) SelectCityStats(string, ...any) ([]CityStats, error)

SelectCityStats implements the Store interface.

func (*ClientMock) SelectCountryStats added in v3.10.0

func (client *ClientMock) SelectCountryStats(string, ...any) ([]CountryStats, error)

SelectCountryStats implements the Store interface.

func (*ClientMock) SelectEntryStats added in v3.10.0

func (client *ClientMock) SelectEntryStats(bool, string, ...any) ([]EntryStats, error)

SelectEntryStats implements the Store interface.

func (*ClientMock) SelectEventListStats added in v3.10.0

func (client *ClientMock) SelectEventListStats(string, ...any) ([]EventListStats, error)

SelectEventListStats implements the Store interface.

func (*ClientMock) SelectEventStats added in v3.10.0

func (client *ClientMock) SelectEventStats(bool, string, ...any) ([]EventStats, error)

SelectEventStats implements the Store interface.

func (*ClientMock) SelectExitStats added in v3.10.0

func (client *ClientMock) SelectExitStats(bool, string, ...any) ([]ExitStats, error)

SelectExitStats implements the Store interface.

func (*ClientMock) SelectLanguageStats added in v3.10.0

func (client *ClientMock) SelectLanguageStats(string, ...any) ([]LanguageStats, error)

SelectLanguageStats implements the Store interface.

func (*ClientMock) SelectOSStats added in v3.10.0

func (client *ClientMock) SelectOSStats(string, ...any) ([]OSStats, error)

SelectOSStats implements the Store interface.

func (*ClientMock) SelectOSVersionStats added in v3.10.0

func (client *ClientMock) SelectOSVersionStats(string, ...any) ([]OSVersionStats, error)

SelectOSVersionStats implements the Store interface.

func (*ClientMock) SelectPageStats added in v3.10.0

func (client *ClientMock) SelectPageStats(bool, bool, string, ...any) ([]PageStats, error)

SelectPageStats implements the Store interface.

func (*ClientMock) SelectReferrerStats added in v3.10.0

func (client *ClientMock) SelectReferrerStats(string, ...any) ([]ReferrerStats, error)

SelectReferrerStats implements the Store interface.

func (*ClientMock) SelectScreenClassStats added in v3.10.0

func (client *ClientMock) SelectScreenClassStats(string, ...any) ([]ScreenClassStats, error)

SelectScreenClassStats implements the Store interface.

func (*ClientMock) SelectTimeSpentStats added in v3.10.0

func (client *ClientMock) SelectTimeSpentStats(Period, string, ...any) ([]TimeSpentStats, error)

SelectTimeSpentStats implements the Store interface.

func (*ClientMock) SelectTotalVisitorSessionStats added in v3.10.0

func (client *ClientMock) SelectTotalVisitorSessionStats(string, ...any) ([]TotalVisitorSessionStats, error)

SelectTotalVisitorSessionStats implements the Store interface.

func (*ClientMock) SelectUTMCampaignStats added in v3.10.0

func (client *ClientMock) SelectUTMCampaignStats(string, ...any) ([]UTMCampaignStats, error)

SelectUTMCampaignStats implements the Store interface.

func (*ClientMock) SelectUTMContentStats added in v3.10.0

func (client *ClientMock) SelectUTMContentStats(string, ...any) ([]UTMContentStats, error)

SelectUTMContentStats implements the Store interface.

func (*ClientMock) SelectUTMMediumStats added in v3.10.0

func (client *ClientMock) SelectUTMMediumStats(string, ...any) ([]UTMMediumStats, error)

SelectUTMMediumStats implements the Store interface.

func (*ClientMock) SelectUTMSourceStats added in v3.10.0

func (client *ClientMock) SelectUTMSourceStats(string, ...any) ([]UTMSourceStats, error)

SelectUTMSourceStats implements the Store interface.

func (*ClientMock) SelectUTMTermStats added in v3.10.0

func (client *ClientMock) SelectUTMTermStats(string, ...any) ([]UTMTermStats, error)

SelectUTMTermStats implements the Store interface.

func (*ClientMock) SelectVisitorHourStats added in v3.10.0

func (client *ClientMock) SelectVisitorHourStats(string, ...any) ([]VisitorHourStats, error)

SelectVisitorHourStats implements the Store interface.

func (*ClientMock) SelectVisitorStats added in v3.10.0

func (client *ClientMock) SelectVisitorStats(Period, string, ...any) ([]VisitorStats, error)

SelectVisitorStats implements the Store interface.

func (*ClientMock) Session

func (client *ClientMock) Session(uint64, uint64, time.Time) (*Session, error)

Session implements the Store interface.

type CountryStats

type CountryStats struct {
	MetaStats
	CountryCode string `db:"country_code" json:"country_code"`
}

CountryStats is the result type for country statistics.

type Direction added in v3.8.0

type Direction string

Direction is used to sort results.

type EntryStats

type EntryStats struct {
	Path                    string  `db:"entry_path" json:"path"`
	Title                   string  `json:"title"`
	Visitors                int     `json:"visitors"`
	Sessions                int     `json:"sessions"`
	Entries                 int     `json:"entries"`
	EntryRate               float64 `db:"entry_rate" json:"entry_rate"`
	AverageTimeSpentSeconds int     `db:"average_time_spent_seconds" json:"average_time_spent_seconds"`
}

EntryStats is the result type for entry page statistics.

type Event

type Event struct {
	ClientID        uint64    `db:"client_id" json:"client_id"`
	VisitorID       uint64    `db:"visitor_id" json:"visitor_id"`
	Time            time.Time `json:"time"`
	SessionID       uint32    `db:"session_id" json:"session_id"`
	Name            string    `db:"event_name" json:"name"`
	MetaKeys        []string  `db:"event_meta_keys" json:"meta_keys"`
	MetaValues      []string  `db:"event_meta_values" json:"meta_values"`
	DurationSeconds uint32    `db:"duration_seconds" json:"duration_seconds"`
	Path            string    `json:"path"`
	Title           string    `json:"title"`
	Language        string    `json:"language"`
	CountryCode     string    `db:"country_code" json:"country_code"`
	City            string    `json:"city"`
	Referrer        string    `json:"referrer"`
	ReferrerName    string    `db:"referrer_name" json:"referrer_name"`
	ReferrerIcon    string    `db:"referrer_icon" json:"referrer_icon"`
	OS              string    `json:"os"`
	OSVersion       string    `db:"os_version" json:"os_version"`
	Browser         string    `json:"browser"`
	BrowserVersion  string    `db:"browser_version" json:"browser_version"`
	Desktop         bool      `json:"desktop"`
	Mobile          bool      `json:"mobile"`
	ScreenWidth     uint16    `db:"screen_width" json:"screen_width"`
	ScreenHeight    uint16    `db:"screen_height" json:"screen_height"`
	ScreenClass     string    `db:"screen_class" json:"screen_class"`
	UTMSource       string    `db:"utm_source" json:"utm_source"`
	UTMMedium       string    `db:"utm_medium" json:"utm_medium"`
	UTMCampaign     string    `db:"utm_campaign" json:"utm_campaign"`
	UTMContent      string    `db:"utm_content" json:"utm_content"`
	UTMTerm         string    `db:"utm_term" json:"utm_term"`
}

Event represents a single data point for custom events. It's basically the same as Session, but with some additional fields (event name, time, and meta fields).

func (Event) String

func (event Event) String() string

String implements the Stringer interface.

type EventListStats added in v3.5.0

type EventListStats struct {
	Name     string            `db:"event_name" json:"name"`
	Meta     map[string]string `json:"meta"`
	Visitors int               `json:"visitors"`
	Count    int               `json:"count"`
}

EventListStats is the result type for a custom event list.

type EventOptions

type EventOptions struct {
	// Name is the name of the event (required).
	Name string

	// Duration is an optional duration that is used to calculate an average time on the dashboard.
	Duration uint32

	// Meta are optional fields used to break down the events that were send for a name.
	Meta map[string]string
}

EventOptions are the options to save a new event. The name is required. All other fields are optional.

type EventStats

type EventStats struct {
	Name                   string   `db:"event_name" json:"name"`
	Visitors               int      `json:"visitors"`
	Views                  int      `json:"views"`
	CR                     float64  `json:"cr"`
	AverageDurationSeconds int      `db:"average_time_spent_seconds" json:"average_duration_seconds"`
	MetaKeys               []string `db:"meta_keys" json:"meta_keys"`
	MetaValue              string   `db:"meta_value" json:"meta_value"`
}

EventStats is the result type for custom events.

type ExitStats

type ExitStats struct {
	Path     string  `db:"exit_path" json:"path"`
	Title    string  `json:"title"`
	Visitors int     `json:"visitors"`
	Sessions int     `json:"sessions"`
	Exits    int     `json:"exits"`
	ExitRate float64 `db:"exit_rate" json:"exit_rate"`
}

ExitStats is the result type for exit page statistics.

type Field added in v3.8.0

type Field struct {
	Name string
	// contains filtered or unexported fields
}

Field is a column for a query.

type Filter

type Filter struct {
	// ClientID is the optional.
	ClientID int64

	// Timezone sets the timezone used to interpret dates and times.
	// It will be set to UTC by default.
	Timezone *time.Location

	// From is the start date of the selected period.
	From time.Time

	// To is the end date of the selected period.
	To time.Time

	// IncludeTime sets whether the selected period should contain the time (hour, minute, second).
	IncludeTime bool

	// Period sets the period to group results.
	// This is only used by Analyzer.Visitors, Analyzer.AvgSessionDuration, and Analyzer.AvgTimeOnPage.
	// Using it for other queries leads to wrong results and might return an error.
	// This can either be PeriodDay (default), PeriodWeek, or PeriodYear.
	Period Period

	// Path filters for the path.
	// Note that if this and PathPattern are both set, Path will be preferred.
	Path string

	// EntryPath filters for the entry page.
	EntryPath string

	// ExitPath filters for the exit page.
	ExitPath string

	// PathPattern filters for the path using a (ClickHouse supported) regex pattern.
	// Note that if this and Path are both set, Path will be preferred.
	// Examples for useful patterns (all case-insensitive, * is used for every character but slashes, ** is used for all characters including slashes):
	//  (?i)^/path/[^/]+$ // matches /path/*
	//  (?i)^/path/[^/]+/.* // matches /path/*/**
	//  (?i)^/path/[^/]+/slashes$ // matches /path/*/slashes
	//  (?i)^/path/.+/slashes$ // matches /path/**/slashes
	PathPattern string

	// Language filters for the ISO language code.
	Language string

	// Country filters for the ISO country code.
	Country string

	// City filters for the city name.
	City string

	// Referrer filters for the full referrer.
	Referrer string

	// ReferrerName filters for the referrer name.
	ReferrerName string

	// OS filters for the operating system.
	OS string

	// OSVersion filters for the operating system version.
	OSVersion string

	// Browser filters for the browser.
	Browser string

	// BrowserVersion filters for the browser version.
	BrowserVersion string

	// Platform filters for the platform (desktop, mobile, unknown).
	Platform string

	// ScreenClass filters for the screen class.
	ScreenClass string

	// ScreenWidth filters for the screen width.
	ScreenWidth string

	// ScreenHeight filters for the screen width.
	ScreenHeight string

	// UTMSource filters for the utm_source query parameter.
	UTMSource string

	// UTMMedium filters for the utm_medium query parameter.
	UTMMedium string

	// UTMCampaign filters for the utm_campaign query parameter.
	UTMCampaign string

	// UTMContent filters for the utm_content query parameter.
	UTMContent string

	// UTMTerm filters for the utm_term query parameter.
	UTMTerm string

	// EventName filters for an event by its name.
	EventName string

	// EventMetaKey filters for an event meta key.
	// This must be used together with an EventName.
	EventMetaKey string

	// EventMeta filters for event metadata.
	EventMeta map[string]string

	// Search searches the results for given fields and inputs.
	Search []Search

	// Sort sorts the results.
	// This will overwrite the default order provided by the Analyzer.
	Sort []Sort

	// Offset limits the number of results. Less or equal to zero means no offset.
	Offset int

	// Limit limits the number of results. Less or equal to zero means no limit.
	Limit int

	// IncludeTitle indicates that the Analyzer.Pages, Analyzer.EntryPages, and Analyzer.ExitPages should contain the page title.
	IncludeTitle bool

	// IncludeTimeOnPage indicates that the Analyzer.Pages and Analyzer.EntryPages should contain the average time on page.
	IncludeTimeOnPage bool

	// MaxTimeOnPageSeconds is an optional maximum for the time spent on page.
	// Visitors who are idle artificially increase the average time spent on a page, this option can be used to limit the effect.
	// Set to 0 to disable this option (default).
	MaxTimeOnPageSeconds int
	// contains filtered or unexported fields
}

Filter are all fields that can be used to filter the result sets. Fields can be inverted by adding a "!" in front of the string. To compare to none/unknown/empty, set the value to "null" (case-insensitive).

func NewFilter

func NewFilter(clientID int64) *Filter

NewFilter creates a new filter for given client ID.

type GeoDB

type GeoDB struct {
	// contains filtered or unexported fields
}

GeoDB maps IPs to their geo location based on MaxMinds GeoLite2 or GeoIP2 database.

func NewGeoDB

func NewGeoDB(config GeoDBConfig) (*GeoDB, error)

NewGeoDB creates a new GeoDB for given database file. The file is loaded into memory, therefore it's not necessary to close the reader (see oschwald/maxminddb-golang documentatio). The database should be updated on a regular basis.

func (*GeoDB) CountryCodeAndCity

func (db *GeoDB) CountryCodeAndCity(ip string) (string, string)

CountryCodeAndCity looks up the country code and city for given IP. If the IP is invalid it will return an empty string. The country code is returned in lowercase.

type GeoDBConfig

type GeoDBConfig struct {
	// File is the path (including the filename) to the GeoLite2 country database file.
	// See GeoLite2Filename for the required filename.
	File string

	// Logger is the log.Logger used for logging.
	// Note that this will log the IP address and should therefore only be used for debugging.
	// Set it to nil to disable logging for GeoDB.
	Logger *log.Logger
}

GeoDBConfig is the configuration for the GeoDB.

type Growth

type Growth struct {
	VisitorsGrowth  float64 `json:"visitors_growth"`
	ViewsGrowth     float64 `json:"views_growth"`
	SessionsGrowth  float64 `json:"sessions_growth"`
	BouncesGrowth   float64 `json:"bounces_growth"`
	TimeSpentGrowth float64 `json:"time_spent_growth"`
}

Growth represents the visitors, views, sessions, bounces, and average session duration growth between two time periods.

type GrowthStats added in v3.10.0

type GrowthStats struct {
	Visitors   int
	Views      int
	Sessions   int
	Bounces    int
	BounceRate float64 `db:"bounce_rate"`
}

GrowthStats is the sum to calculate the growth rate.

type HeaderParser added in v3.9.0

type HeaderParser struct {
	Header string
	Parser ParseHeaderFunc
}

HeaderParser parses a header to extract the real client IP address.

type HitOptions

type HitOptions struct {
	// Salt is used to generate a fingerprint (optional).
	// It can be different for every request.
	Salt string

	// SessionCache is the cache to look up sessions.
	SessionCache SessionCache

	// HeaderParser is an (optional) list of parsers to extract the real client IP from request headers.
	HeaderParser []HeaderParser

	// AllowedProxySubnets is an (optional) list of subnets to trust when extracting the real client IP from request headers.
	AllowedProxySubnets []net.IPNet

	// ClientID is optionally saved with a hit to split the data between multiple clients.
	ClientID uint64

	// SessionMaxAge defines the maximum time a session stays active.
	// A session is kept active if requests are made within the time frame.
	// Set to 15 minutes by default.
	SessionMaxAge time.Duration

	// MinDelay defines the minimum time in milliseconds between two page views before the session is flagged as a bot request.
	// This will update the Session.IsBot counter, which can later be used to filter upon.
	// Set it to 0 to disable flagging bots.
	MinDelay int64

	// IsBotThreshold sets the threshold before a request is ignored.
	// If Session.IsBot is larger or equal to the configured value, the request won't be accepted.
	// Set it to 0 to disable ignoring requests.
	IsBotThreshold uint8

	// URL can be set to manually overwrite the URL stored for this request.
	// This will also affect the Path, except it is set too.
	URL string

	// Path can be set to manually overwrite the path stored for the request.
	// This will also affect the URL.
	Path string

	// Title is the page title.
	Title string

	// Referrer can be set to manually overwrite the referrer from the request.
	Referrer string

	// ReferrerDomainBlacklist is used to filter out unwanted referrers from the Referrer header.
	// This can be used to filter out traffic from your own site or subdomains.
	// To filter your own domain and subdomains, add your domain to the list and set ReferrerDomainBlacklistIncludesSubdomains to true.
	// This way the referrer for blog.mypage.com -> mypage.com won't be saved.
	ReferrerDomainBlacklist []string

	// ReferrerDomainBlacklistIncludesSubdomains set to true to include all subdomains in the ReferrerDomainBlacklist,
	// or else subdomains must explicitly be included in the blacklist.
	// If the blacklist contains domain.com, sub.domain.com and domain.com will be treated as equals.
	ReferrerDomainBlacklistIncludesSubdomains bool

	// ScreenWidth sets the screen width to be stored with the hit.
	ScreenWidth uint16

	// ScreenHeight sets the screen height to be stored with the hit.
	ScreenHeight uint16
	// contains filtered or unexported fields
}

HitOptions is used to manipulate the data saved on a hit.

func HitOptionsFromRequest

func HitOptionsFromRequest(r *http.Request) *HitOptions

HitOptionsFromRequest returns the HitOptions for given client request. This function can be used to accept hits from pirsch.js. Invalid parameters are ignored and left empty. You might want to add additional checks before calling HitFromRequest afterwards (like for the HitOptions.ClientID).

type LanguageStats

type LanguageStats struct {
	MetaStats
	Language string `json:"language"`
}

LanguageStats is the result type for language statistics.

type MetaStats

type MetaStats struct {
	Visitors         int     `json:"visitors"`
	RelativeVisitors float64 `db:"relative_visitors" json:"relative_visitors"`
}

MetaStats is the base for meta result types (languages, countries, ...).

type OSStats

type OSStats struct {
	MetaStats
	OS string `json:"os"`
}

OSStats is the result type for operating system statistics.

type OSVersionStats

type OSVersionStats struct {
	MetaStats
	OS        string `json:"os"`
	OSVersion string `db:"os_version" json:"os_version"`
}

OSVersionStats is the result type for operating system version statistics.

type PageConversionsStats

type PageConversionsStats struct {
	Visitors int     `json:"visitors"`
	Views    int     `json:"views"`
	CR       float64 `json:"cr"`
}

PageConversionsStats is the result type for page conversions.

type PageStats

type PageStats struct {
	Path                    string  `json:"path"`
	Title                   string  `json:"title"`
	Visitors                int     `json:"visitors"`
	Views                   int     `json:"views"`
	Sessions                int     `json:"sessions"`
	Bounces                 int     `json:"bounces"`
	RelativeVisitors        float64 `db:"relative_visitors" json:"relative_visitors"`
	RelativeViews           float64 `db:"relative_views" json:"relative_views"`
	BounceRate              float64 `db:"bounce_rate" json:"bounce_rate"`
	AverageTimeSpentSeconds int     `db:"average_time_spent_seconds" json:"average_time_spent_seconds"`
}

PageStats is the result type for page statistics.

type PageView added in v3.4.0

type PageView struct {
	ClientID        uint64    `db:"client_id" json:"client_id"`
	VisitorID       uint64    `db:"visitor_id" json:"visitor_id"`
	SessionID       uint32    `db:"session_id" json:"session_id"`
	Time            time.Time `json:"time"`
	DurationSeconds uint32    `db:"duration_seconds" json:"duration_seconds"`
	Path            string    `json:"path"`
	Title           string    `json:"title"`
	Language        string    `json:"language"`
	CountryCode     string    `db:"country_code" json:"country_code"`
	City            string    `json:"city"`
	Referrer        string    `json:"referrer"`
	ReferrerName    string    `db:"referrer_name" json:"referrer_name"`
	ReferrerIcon    string    `db:"referrer_icon" json:"referrer_icon"`
	OS              string    `json:"os"`
	OSVersion       string    `db:"os_version" json:"os_version"`
	Browser         string    `json:"browser"`
	BrowserVersion  string    `db:"browser_version" json:"browser_version"`
	Desktop         bool      `json:"desktop"`
	Mobile          bool      `json:"mobile"`
	ScreenWidth     uint16    `db:"screen_width" json:"screen_width"`
	ScreenHeight    uint16    `db:"screen_height" json:"screen_height"`
	ScreenClass     string    `db:"screen_class" json:"screen_class"`
	UTMSource       string    `db:"utm_source" json:"utm_source"`
	UTMMedium       string    `db:"utm_medium" json:"utm_medium"`
	UTMCampaign     string    `db:"utm_campaign" json:"utm_campaign"`
	UTMContent      string    `db:"utm_content" json:"utm_content"`
	UTMTerm         string    `db:"utm_term" json:"utm_term"`
}

PageView represents a single page visit.

func (PageView) String added in v3.4.0

func (pageView PageView) String() string

String implements the Stringer interface.

type ParseHeaderFunc added in v3.9.0

type ParseHeaderFunc func(string) string

ParseHeaderFunc parses and validates an IP address from a header. It must return an empty string if the header or contained IP address is invalid.

type Period added in v3.7.0

type Period int

Period is used to group results.

type PlatformStats

type PlatformStats struct {
	PlatformDesktop         int     `db:"platform_desktop" json:"platform_desktop"`
	PlatformMobile          int     `db:"platform_mobile" json:"platform_mobile"`
	PlatformUnknown         int     `db:"platform_unknown" json:"platform_unknown"`
	RelativePlatformDesktop float64 `db:"relative_platform_desktop" json:"relative_platform_desktop"`
	RelativePlatformMobile  float64 `db:"relative_platform_mobile" json:"relative_platform_mobile"`
	RelativePlatformUnknown float64 `db:"relative_platform_unknown" json:"relative_platform_unknown"`
}

PlatformStats is the result type for platform statistics.

type RedisMutex added in v3.6.2

type RedisMutex struct {
	// contains filtered or unexported fields
}

RedisMutex wraps a redis mutex.

func (*RedisMutex) Lock added in v3.6.2

func (m *RedisMutex) Lock()

func (*RedisMutex) Unlock added in v3.6.2

func (m *RedisMutex) Unlock()

type ReferrerStats

type ReferrerStats struct {
	Referrer         string  `json:"referrer"`
	ReferrerName     string  `db:"referrer_name" json:"referrer_name"`
	ReferrerIcon     string  `db:"referrer_icon" json:"referrer_icon"`
	Visitors         int     `json:"visitors"`
	Sessions         int     `json:"sessions"`
	RelativeVisitors float64 `db:"relative_visitors" json:"relative_visitors"`
	Bounces          int     `json:"bounces"`
	BounceRate       float64 `db:"bounce_rate" json:"bounce_rate"`
}

ReferrerStats is the result type for referrer statistics.

type ScreenClassStats

type ScreenClassStats struct {
	MetaStats
	ScreenClass string `db:"screen_class" json:"screen_class"`
}

ScreenClassStats is the result type for screen class statistics.

type Search struct {
	Field Field
	Input string
}

Search filters results by searching for the given input for given field. The field needs to contain the search string and is performed case-insensitively.

type Session added in v3.4.0

type Session struct {
	Sign            int8      `json:"sign"`
	ClientID        uint64    `db:"client_id" json:"client_id"`
	VisitorID       uint64    `db:"visitor_id" json:"visitor_id"`
	SessionID       uint32    `db:"session_id" json:"session_id"`
	Time            time.Time `json:"time"`
	Start           time.Time `json:"start"`
	DurationSeconds uint32    `db:"duration_seconds" json:"duration_seconds"`
	EntryPath       string    `db:"entry_path" json:"entry_path"`
	ExitPath        string    `db:"exit_path" json:"exit_path"`
	PageViews       uint16    `db:"page_views" json:"page_views"`
	IsBounce        bool      `db:"is_bounce" json:"is_bounce"`
	EntryTitle      string    `db:"entry_title" json:"entry_title"`
	ExitTitle       string    `db:"exit_title" json:"exit_title"`
	Language        string    `json:"language"`
	CountryCode     string    `db:"country_code" json:"country_code"`
	City            string    `json:"city"`
	Referrer        string    `json:"referrer"`
	ReferrerName    string    `db:"referrer_name" json:"referrer_name"`
	ReferrerIcon    string    `db:"referrer_icon" json:"referrer_icon"`
	OS              string    `json:"os"`
	OSVersion       string    `db:"os_version" json:"os_version"`
	Browser         string    `json:"browser"`
	BrowserVersion  string    `db:"browser_version" json:"browser_version"`
	Desktop         bool      `json:"desktop"`
	Mobile          bool      `json:"mobile"`
	ScreenWidth     uint16    `db:"screen_width" json:"screen_width"`
	ScreenHeight    uint16    `db:"screen_height" json:"screen_height"`
	ScreenClass     string    `db:"screen_class" json:"screen_class"`
	UTMSource       string    `db:"utm_source" json:"utm_source"`
	UTMMedium       string    `db:"utm_medium" json:"utm_medium"`
	UTMCampaign     string    `db:"utm_campaign" json:"utm_campaign"`
	UTMContent      string    `db:"utm_content" json:"utm_content"`
	UTMTerm         string    `db:"utm_term" json:"utm_term"`
	IsBot           uint8     `db:"is_bot" json:"is_bot"`
}

Session represents a single visitor.

func (Session) String added in v3.4.0

func (session Session) String() string

String implements the Stringer interface.

type SessionCache

type SessionCache interface {
	// Get returns a session for given client ID, fingerprint, and maximum age.
	Get(uint64, uint64, time.Time) *Session

	// Put stores a session for given client ID, fingerprint, and Session.
	Put(uint64, uint64, *Session)

	// Clear clears the cache.
	Clear()

	// NewMutex creates a new mutex for given client ID and fingerprint.
	NewMutex(uint64, uint64) sync.Locker
}

SessionCache caches sessions.

type SessionCacheMem added in v3.1.0

type SessionCacheMem struct {
	// contains filtered or unexported fields
}

SessionCacheMem caches sessions in memory. This does only make sense for non-distributed systems (tracking on a single machine/app).

func NewSessionCacheMem added in v3.1.0

func NewSessionCacheMem(client Store, maxSessions int) *SessionCacheMem

NewSessionCacheMem creates a new cache for given client and maximum size.

func (*SessionCacheMem) Clear added in v3.1.0

func (cache *SessionCacheMem) Clear()

Clear implements the SessionCache interface.

func (*SessionCacheMem) Get added in v3.1.0

func (cache *SessionCacheMem) Get(clientID, fingerprint uint64, maxAge time.Time) *Session

Get implements the SessionCache interface.

func (*SessionCacheMem) NewMutex added in v3.6.2

func (cache *SessionCacheMem) NewMutex(uint64, uint64) sync.Locker

NewMutex implements the SessionCache interface.

func (*SessionCacheMem) Put added in v3.1.0

func (cache *SessionCacheMem) Put(clientID, fingerprint uint64, session *Session)

Put implements the SessionCache interface.

type SessionCacheRedis added in v3.1.0

type SessionCacheRedis struct {
	// contains filtered or unexported fields
}

SessionCacheRedis caches sessions in Redis.

func NewSessionCacheRedis added in v3.1.0

func NewSessionCacheRedis(maxAge time.Duration, log *log.Logger, redisOptions *redis.Options) *SessionCacheRedis

NewSessionCacheRedis creates a new cache for given maximum age and redis connection.

func (*SessionCacheRedis) Clear added in v3.1.0

func (cache *SessionCacheRedis) Clear()

Clear implements the SessionCache interface.

func (*SessionCacheRedis) Get added in v3.1.0

func (cache *SessionCacheRedis) Get(clientID, fingerprint uint64, _ time.Time) *Session

Get implements the SessionCache interface.

func (SessionCacheRedis) NewMutex added in v3.6.2

func (cache SessionCacheRedis) NewMutex(clientID, fingerprint uint64) sync.Locker

NewMutex implements the SessionCache interface.

func (*SessionCacheRedis) Put added in v3.1.0

func (cache *SessionCacheRedis) Put(clientID, fingerprint uint64, session *Session)

Put implements the SessionCache interface.

type SessionState added in v3.4.1

type SessionState struct {
	// State is the new state for the session.
	State Session

	// Cancel is the state to cancel.
	// On session creation, this field is nil.
	Cancel *Session
}

SessionState is the state and cancellation for a session. The sessions must be inserted together to ensure sessions collapse.

type Sort added in v3.8.0

type Sort struct {
	Field     Field
	Direction Direction
}

Sort sorts results by a field and direction.

type Store

type Store interface {
	// SavePageViews saves given hits.
	SavePageViews([]PageView) error

	// SaveSessions saves given sessions.
	SaveSessions([]Session) error

	// SaveEvents saves given events.
	SaveEvents([]Event) error

	// SaveUserAgents saves given UserAgent headers.
	SaveUserAgents([]UserAgent) error

	// Session returns the last hit for given client, fingerprint, and maximum age.
	Session(uint64, uint64, time.Time) (*Session, error)

	// Count returns the number of results for given query.
	Count(string, ...any) (int, error)

	// SelectActiveVisitorStats selects ActiveVisitorStats.
	SelectActiveVisitorStats(bool, string, ...any) ([]ActiveVisitorStats, error)

	// GetTotalVisitorStats returns the TotalVisitorStats.
	GetTotalVisitorStats(string, ...any) (*TotalVisitorStats, error)

	// SelectVisitorStats selects VisitorStats.
	SelectVisitorStats(Period, string, ...any) ([]VisitorStats, error)

	// SelectTimeSpentStats selects TimeSpentStats.
	SelectTimeSpentStats(Period, string, ...any) ([]TimeSpentStats, error)

	// GetGrowthStats returns the GrowthStats.
	GetGrowthStats(string, ...any) (*GrowthStats, error)

	// SelectVisitorHourStats selects VisitorHourStats.
	SelectVisitorHourStats(string, ...any) ([]VisitorHourStats, error)

	// SelectPageStats selects PageStats.
	SelectPageStats(bool, bool, string, ...any) ([]PageStats, error)

	// SelectAvgTimeSpentStats selects AvgTimeSpentStats.
	SelectAvgTimeSpentStats(string, ...any) ([]AvgTimeSpentStats, error)

	// SelectEntryStats selects EntryStats.
	SelectEntryStats(bool, string, ...any) ([]EntryStats, error)

	// SelectExitStats selects ExitStats.
	SelectExitStats(bool, string, ...any) ([]ExitStats, error)

	// SelectTotalVisitorSessionStats selects TotalVisitorSessionStats.
	SelectTotalVisitorSessionStats(string, ...any) ([]TotalVisitorSessionStats, error)

	// GetPageConversionsStats returns the PageConversionsStats.
	GetPageConversionsStats(string, ...any) (*PageConversionsStats, error)

	// SelectEventStats selects EventStats.
	SelectEventStats(bool, string, ...any) ([]EventStats, error)

	// SelectEventListStats selects EventListStats.
	SelectEventListStats(string, ...any) ([]EventListStats, error)

	// SelectReferrerStats selects ReferrerStats.
	SelectReferrerStats(string, ...any) ([]ReferrerStats, error)

	// GetPlatformStats returns the PlatformStats.
	GetPlatformStats(string, ...any) (*PlatformStats, error)

	// SelectLanguageStats selects LanguageStats.
	SelectLanguageStats(string, ...any) ([]LanguageStats, error)

	// SelectCountryStats selects CountryStats.
	SelectCountryStats(string, ...any) ([]CountryStats, error)

	// SelectCityStats selects CityStats.
	SelectCityStats(string, ...any) ([]CityStats, error)

	// SelectBrowserStats selects BrowserStats.
	SelectBrowserStats(string, ...any) ([]BrowserStats, error)

	// SelectOSStats selects OSStats.
	SelectOSStats(string, ...any) ([]OSStats, error)

	// SelectScreenClassStats selects ScreenClassStats.
	SelectScreenClassStats(string, ...any) ([]ScreenClassStats, error)

	// SelectUTMSourceStats selects UTMSourceStats.
	SelectUTMSourceStats(string, ...any) ([]UTMSourceStats, error)

	// SelectUTMMediumStats selects UTMMediumStats.
	SelectUTMMediumStats(string, ...any) ([]UTMMediumStats, error)

	// SelectUTMCampaignStats selects UTMCampaignStats.
	SelectUTMCampaignStats(string, ...any) ([]UTMCampaignStats, error)

	// SelectUTMContentStats selects UTMContentStats.
	SelectUTMContentStats(string, ...any) ([]UTMContentStats, error)

	// SelectUTMTermStats selects UTMTermStats.
	SelectUTMTermStats(string, ...any) ([]UTMTermStats, error)

	// SelectOSVersionStats selects OSVersionStats.
	SelectOSVersionStats(string, ...any) ([]OSVersionStats, error)

	// SelectBrowserVersionStats selects BrowserVersionStats.
	SelectBrowserVersionStats(string, ...any) ([]BrowserVersionStats, error)
}

Store is the database storage interface.

type TimeSpentStats

type TimeSpentStats struct {
	Day                     null.Time `json:"day"`
	Week                    null.Time `json:"week"`
	Month                   null.Time `json:"month"`
	Year                    null.Time `json:"year"`
	Path                    string    `json:"path"`
	Title                   string    `json:"title"`
	AverageTimeSpentSeconds int       `db:"average_time_spent_seconds" json:"average_time_spent_seconds"`
}

TimeSpentStats is the result type for average time spent statistics (sessions, time on page).

type TotalVisitorSessionStats added in v3.10.0

type TotalVisitorSessionStats struct {
	Path     string
	Visitors int
	Views    int
	Sessions int
}

TotalVisitorSessionStats are the total amount of visitors, views, and sessions for a page.

type TotalVisitorStats added in v3.4.3

type TotalVisitorStats struct {
	Visitors   int     `json:"visitors"`
	Views      int     `json:"views"`
	Sessions   int     `json:"sessions"`
	Bounces    int     `json:"bounces"`
	BounceRate float64 `db:"bounce_rate" json:"bounce_rate"`
}

TotalVisitorStats is the result type for total visitor statistics.

type Tracker

type Tracker struct {
	// contains filtered or unexported fields
}

Tracker provides methods to track requests. Make sure you call Stop to make sure the hits get stored before shutting down the server.

func NewTracker

func NewTracker(client Store, salt string, config *TrackerConfig) *Tracker

NewTracker creates a new tracker for given client, salt and config. Pass nil for the config to use the defaults. The salt is mandatory. It creates the same amount of workers for both, hits and events.

func (*Tracker) ClearSessionCache

func (tracker *Tracker) ClearSessionCache()

ClearSessionCache clears the session cache.

func (*Tracker) Event

func (tracker *Tracker) Event(r *http.Request, eventOptions EventOptions, options *HitOptions)

Event stores the given request as a new event. The event name in the options must be set, or otherwise the request will be ignored. The request might be ignored if it meets certain conditions. The HitOptions, if passed, will overwrite the Tracker configuration. It's save (and recommended!) to call this function in its own goroutine.

func (*Tracker) ExtendSession added in v3.2.1

func (tracker *Tracker) ExtendSession(r *http.Request, options *HitOptions)

ExtendSession looks up and extends the session for given request and client ID (optional). This function does not Store a hit or event in database.

func (*Tracker) Flush

func (tracker *Tracker) Flush()

Flush flushes all hits to client that are currently buffered by the workers. Call Tracker.Stop to also save hits that are in the queue.

func (*Tracker) Hit

func (tracker *Tracker) Hit(r *http.Request, options *HitOptions)

Hit stores the given request. The request might be ignored if it meets certain conditions. The HitOptions, if passed, will overwrite the Tracker configuration. It's safe (and recommended!) to call this function in its own goroutine.

func (*Tracker) SetGeoDB

func (tracker *Tracker) SetGeoDB(geoDB *GeoDB)

SetGeoDB sets the GeoDB for the Tracker. The call to this function is thread safe to enable live updates of the database. Pass nil to disable the feature.

func (*Tracker) Stop

func (tracker *Tracker) Stop()

Stop flushes and stops all workers.

type TrackerConfig

type TrackerConfig struct {
	// Worker sets the number of workers that are used to client hits.
	// Must be greater or equal to 1.
	Worker int

	// WorkerBufferSize is the size of the buffer used to client hits.
	// Must be greater than 0. The hits are stored in batch when the buffer is full.
	WorkerBufferSize int

	// WorkerTimeout sets the timeout used to client hits.
	// This is used to allow the workers to client hits even if the buffer is not full yet.
	// It's recommended to set this to a few seconds.
	// If you leave it 0, the default timeout is used, else it is limited to 60 seconds.
	WorkerTimeout time.Duration

	// ReferrerDomainBlacklist see HitOptions.ReferrerDomainBlacklist.
	ReferrerDomainBlacklist []string

	// ReferrerDomainBlacklistIncludesSubdomains see HitOptions.ReferrerDomainBlacklistIncludesSubdomains.
	ReferrerDomainBlacklistIncludesSubdomains bool

	// SessionCache is the session cache implementation to be used.
	// This will be set to NewSessionCacheMem by default.
	SessionCache SessionCache

	// MaxSessions sets the maximum size for the session cache.
	// If you leave it 0, the default will be used.
	MaxSessions int

	// SessionMaxAge see HitOptions.SessionMaxAge.
	SessionMaxAge time.Duration

	// HeaderParser see HitOptions.HeaderParser.
	// Set it to nil to use the DefaultHeaderParser list.
	HeaderParser []HeaderParser

	// AllowedProxySubnets see HitOptions.AllowedProxySubnets.
	// Set it to nil to allow any IP.
	AllowedProxySubnets []net.IPNet

	// MinDelay see HitOptions.MinDelay.
	MinDelay int64

	// IsBotThreshold see HitOptions.IsBotThreshold.
	// Will be set to 5 by default.
	IsBotThreshold uint8

	// DisableFlaggingBots disables MinDelay and IsBotThreshold (otherwise these would be set to their default values).
	DisableFlaggingBots bool

	// GeoDB enables/disabled mapping IPs to country codes.
	// Can be set/updated at runtime by calling Tracker.SetGeoDB.
	GeoDB *GeoDB

	// Logger is the log.Logger used for logging.
	// The default log will be used printing to os.Stdout with "pirsch" in its prefix in case it is not set.
	Logger *log.Logger
}

TrackerConfig is the optional configuration for the Tracker.

type UTMCampaignStats

type UTMCampaignStats struct {
	MetaStats
	UTMCampaign string `db:"utm_campaign" json:"utm_campaign"`
}

UTMCampaignStats is the result type for utm campaign statistics.

type UTMContentStats

type UTMContentStats struct {
	MetaStats
	UTMContent string `db:"utm_content" json:"utm_content"`
}

UTMContentStats is the result type for utm content statistics.

type UTMMediumStats

type UTMMediumStats struct {
	MetaStats
	UTMMedium string `db:"utm_medium" json:"utm_medium"`
}

UTMMediumStats is the result type for utm medium statistics.

type UTMSourceStats

type UTMSourceStats struct {
	MetaStats
	UTMSource string `db:"utm_source" json:"utm_source"`
}

UTMSourceStats is the result type for utm source statistics.

type UTMTermStats

type UTMTermStats struct {
	MetaStats
	UTMTerm string `db:"utm_term" json:"utm_term"`
}

UTMTermStats is the result type for utm term statistics.

type UserAgent

type UserAgent struct {
	// Time is the creation date for the database record.
	Time time.Time

	// UserAgent is the full User-Agent for the database record.
	UserAgent string `db:"user_agent"`

	// Browser is the browser name.
	Browser string `db:"-"`

	// BrowserVersion is the browser (non technical) version number.
	BrowserVersion string `db:"-"`

	// OS is the operating system.
	OS string `db:"-"`

	// OSVersion is the operating system version number.
	OSVersion string `db:"-"`
}

UserAgent contains information extracted from the User-Agent header. The creation time and User-Agent string are stored in the database to find bots.

func ParseUserAgent

func ParseUserAgent(ua string) UserAgent

ParseUserAgent parses given User-Agent header and returns the extracted information. This just supports major browsers and operating systems, we don't care about browsers and OSes that have no market share, unless you prove us wrong.

func (*UserAgent) IsDesktop

func (ua *UserAgent) IsDesktop() bool

IsDesktop returns true if the user agent is a desktop device.

func (*UserAgent) IsMobile

func (ua *UserAgent) IsMobile() bool

IsMobile returns true if the user agent is a mobile device.

type VisitorHourStats

type VisitorHourStats struct {
	Hour       int     `json:"hour"`
	Visitors   int     `json:"visitors"`
	Views      int     `json:"views"`
	Sessions   int     `json:"sessions"`
	Bounces    int     `json:"bounces"`
	BounceRate float64 `db:"bounce_rate" json:"bounce_rate"`
}

VisitorHourStats is the result type for visitor statistics grouped by time of day.

type VisitorStats

type VisitorStats struct {
	Day        null.Time `json:"day"`
	Week       null.Time `json:"week"`
	Month      null.Time `json:"month"`
	Year       null.Time `json:"year"`
	Visitors   int       `json:"visitors"`
	Views      int       `json:"views"`
	Sessions   int       `json:"sessions"`
	Bounces    int       `json:"bounces"`
	BounceRate float64   `db:"bounce_rate" json:"bounce_rate"`
}

VisitorStats is the result type for visitor statistics.

Directories

Path Synopsis
demos
scripts

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL