pirsch

package module
v1.3.1 Latest Latest
Warning

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

Go to latest
Published: Aug 12, 2020 License: MIT Imports: 17 Imported by: 0

README

Pirsch

GoDoc Go Report Card CircleCI 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.

The name is in German and refers to a special kind of hunt: the hunter carefully and quietly enters the area to be hunted, he stalks against the wind in order to get as close as possible to the prey without being noticed.

How does it work?

Pirsch generates a unique fingerprint for each visitor. The fingerprint is a hash of the visitors IP, User-Agent and a salt. The salt is re-generated at midnight to separate data for each day.

Each time a visitor opens your page, Pirsch will store a hit. The hits are analyzed later to extract meaningful data and reduce storage usage by aggregation.

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 and limitations

Pirsch tracks the following data points:

  • total visitors on each day
  • visitors per day and hour
  • visitors per day and page
  • visitors per day and language

All timestamps are stored as UTC. Each data point belongs to an (optional) tenant, 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 tenant ID for all columns!

It's theoretically possible to track the visitor flow (which page was seen first, which one was visited next, etc.), but this is not implemented at the moment. Here is a list of the limitations of Pirsch:

  • tracking sessions is not possible at the moment as the salt will prevent you from tracking a user across two days
  • bots might not always be filtered out
  • rare cases where two fingerprints collide, if two visitors are behind the same proxy for example and the User-Agent is the same (or empty)
  • the accuracy might not be as high as with client-side solutions, because Pirsch can only collect information that is available to the server

Usage

To store hits and statistics, Pirsch uses a database. Right now only Postgres is supported, but new ones can easily be added by implementing the Store interface. The schema can be found within the schema directory. Changes will be added to migrations scripts, so that you can add them to your projects database migration or run them manually.

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

// create a Postgres store using the sql.DB database connection "db"
store := pirsch.NewPostgresStore(db)

// Tracker is the main component of Pirsch
// the salt is used to prevent anyone from generating fingerprints like yours (to prevent man in the middle attacks), pick something random
// an optional configuration can be used to change things like worker count, timeouts and so on
tracker := pirsch.NewTracker(store, "secret_salt", nil)

// the Processor analyzes hits and stores the reduced data points in store
// it's recommended to run the Process method once a day, but you can run it as often as you want
// the config can be used to enable/disable certain features of the processor
processor := pirsch.NewProcessor(store, nil)
pirsch.RunAtMidnight(processor.Process) // helper function to run a function at midnight (UTC)

http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    // a call to Hit will track the request
    // note that Pirsch stores the path and URL, therefor you should make sure you only call it for the endpoints you're interested in
    // you can also modify the path by passing in the options argument
    if r.URL.Path == "/" {
        tracker.Hit(r, nil)
    }

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

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

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.

// 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 data for the past week including today
visitors, err := analyzer.Visitors(&pirsch.Filter{
    From: yesterday(),
    To: today()
})

Read the full documentation for more details and check out this article.

Changelog

1.3.1
  • added statistics for visitor count per page and referer
1.3.0

You need to update the schema by running the v1.3.0.sql migration script!

  • added cancel function to RunAtMidnight
  • added helper function for tenant IDs
  • hits for an empty User-Agent will be ignored from now on
  • added configuration options to Processor
  • IgnoreHit and HitFromRequest are now exported functions
  • added options to filter for unwanted referer, like your own domain
  • added referer statistics to Processor and Analyzer
  • added method to Analyzer to extract active visitor pages
  • Analyzer results are now sorted by visitors in descending order instead of path and referer length
1.2.0

You need to update the schema by running the v1.2.0.sql migration script!

  • the processor now returns an error
  • the processor now updates existing statistics in case it has been run before, but keep in mind that it drops hits and therefor breaks tracking users that return on the same day. It's recommended to run the processor for days in the past excluding today
  • (optional) multi-tenancy support to track multiple domains using the same database. In case you don't want to use it, use null as the tenant_id
  • improved IP extraction from X-Forwarded-For, Forwarded and X-Real-IP headers
1.1.1
  • fixed error in case values are too long
  • fixed language statistics not including today
1.1.0
  • added a secret salt to prevent generating fingerprints to identify visitors on other websites (man in the middle)
  • extended bot list
1.0.0

Initial release.

Contribution

Contributions are welcome! You can extend the bot list or processor to extract more useful data, for example. 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 Postgres database and a schema called pirsch. The user and password are set to postgres.

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

View Source
var NullTenant = NewTenantID(0)

NullTenant can be used to pass no (null) tenant to filters and functions. This is an invalid sql.NullInt64 with a value of 0.

Functions

func Fingerprint

func Fingerprint(r *http.Request, salt string) string

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

func IgnoreHit added in v1.3.0

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 NewTenantID added in v1.3.0

func NewTenantID(id int64) sql.NullInt64

NewTenantID is a helper function to return a sql.NullInt64. The ID is considered valid if greater than 0.

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.

Types

type Analyzer

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

Analyzer provides an interface to analyze processed data and hits.

func NewAnalyzer

func NewAnalyzer(store Store) *Analyzer

NewAnalyzer returns a new Analyzer for given Store.

func (*Analyzer) ActiveVisitors

func (analyzer *Analyzer) ActiveVisitors(tenantID sql.NullInt64, d time.Duration) (int, error)

ActiveVisitors returns the number of unique visitors active within the given duration.

func (*Analyzer) ActiveVisitorsPages added in v1.3.0

func (analyzer *Analyzer) ActiveVisitorsPages(tenantID sql.NullInt64, d time.Duration) ([]PageVisitors, error)

ActiveVisitorsPages returns the number of unique visitors active within the given duration and the corresponding pages.

func (*Analyzer) HourlyVisitors

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

HourlyVisitors returns the absolute and relative visitor count per language for given time frame.

func (*Analyzer) Languages

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

Languages returns the absolute and relative visitor count per language for given time frame.

func (*Analyzer) PageVisits

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

PageVisits returns the visitors per page per day for given time frame.

func (*Analyzer) Pages added in v1.3.1

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

Pages returns the absolute visitor count per page for given time frame.

func (*Analyzer) Referer added in v1.3.1

func (analyzer *Analyzer) Referer(filter *Filter) ([]VisitorReferer, error)

Referer returns the absolute visitor count per referer for given time frame.

func (*Analyzer) RefererVisits added in v1.3.0

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

RefererVisits returns the visitors per referer per day for given time frame.

func (*Analyzer) Visitors

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

Visitors returns the visitors per day for the given time frame.

type Filter

type Filter struct {
	// TenantID is the optional tenant ID used to filter results.
	TenantID sql.NullInt64

	// From is the start of the selection.
	From time.Time

	// To is the end of the selection.
	To time.Time
}

Filter is used to specify the time frame and tenant for the Analyzer.

func (*Filter) Days

func (filter *Filter) Days() int

Days returns the number of days covered by the filter.

type Hit

type Hit struct {
	ID          int64         `db:"id" json:"id"`
	TenantID    sql.NullInt64 `db:"tenant_id" json:"tenant_id"`
	Fingerprint string        `db:"fingerprint" json:"fingerprint"`
	Path        string        `db:"path" json:"path,omitempty"`
	URL         string        `db:"url" json:"url,omitempty"`
	Language    string        `db:"language" json:"language,omitempty"`
	UserAgent   string        `db:"user_agent" json:"user_agent,omitempty"`
	Ref         string        `db:"ref" json:"ref,omitempty"`
	Time        time.Time     `db:"time" json:"time"`
}

Hit represents a single data point/page visit.

func HitFromRequest added in v1.3.0

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

HitFromRequest returns a new Hit 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 (Hit) String

func (hit Hit) String() string

String implements the Stringer interface.

type HitOptions added in v1.2.0

type HitOptions struct {
	// TenantID is optionally saved with a hit to split the data between multiple tenants.
	TenantID sql.NullInt64

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

	// RefererDomainBlacklist is used to filter out unwanted referer from the Ref 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 RefererDomainBlacklistIncludesSubdomains to true.
	// This way the referer for blog.mypage.com -> mypage.com won't be saved.
	RefererDomainBlacklist []string

	// RefererDomainBlacklistIncludesSubdomains set to true to include all subdomains in the RefererDomainBlacklist,
	// 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 equally.
	RefererDomainBlacklistIncludesSubdomains bool
}

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

type HourlyVisitors

type HourlyVisitors struct {
	Hour     int `db:"hour" json:"hour"`
	Visitors int `db:"visitors" json:"visitors"`
}

HourlyVisitors is the unique visitor count per hour.

type PageVisitors added in v1.3.0

type PageVisitors struct {
	Path     string `db:"path" json:"path"`
	Visitors int    `db:"visitors" json:"visitors"`
}

PageVisitors is the visitor count for each path.

type PageVisits

type PageVisits struct {
	Path   string
	Visits []VisitorsPerDay
}

PageVisits is the visitor count per day for each path.

type PostgresStore

type PostgresStore struct {
	DB *sqlx.DB
}

PostgresStore implements the Store interface.

func NewPostgresStore

func NewPostgresStore(db *sql.DB) *PostgresStore

NewPostgresStore creates a new postgres storage for given database connection.

func (*PostgresStore) ActiveVisitors

func (store *PostgresStore) ActiveVisitors(tenantID sql.NullInt64, from time.Time) (int, error)

ActiveVisitors implements the Store interface.

func (*PostgresStore) ActiveVisitorsPerPage added in v1.3.0

func (store *PostgresStore) ActiveVisitorsPerPage(tenantID sql.NullInt64, from time.Time) ([]PageVisitors, error)

ActiveVisitorsPerPage implements the Store interface.

func (*PostgresStore) CountHits added in v1.3.0

func (store *PostgresStore) CountHits(tenantID sql.NullInt64) int

CountHits implements the Store interface.

func (*PostgresStore) CountVisitorsPerDay added in v1.3.0

func (store *PostgresStore) CountVisitorsPerDay(tenantID sql.NullInt64, day time.Time) (int, error)

VisitorsPerDay implements the Store interface.

func (*PostgresStore) CountVisitorsPerDayAndHour added in v1.3.0

func (store *PostgresStore) CountVisitorsPerDayAndHour(tenantID sql.NullInt64, day time.Time) ([]VisitorsPerHour, error)

VisitorsPerDayAndHour implements the Store interface.

func (*PostgresStore) CountVisitorsPerLanguage added in v1.3.0

func (store *PostgresStore) CountVisitorsPerLanguage(tenantID sql.NullInt64, day time.Time) ([]VisitorsPerLanguage, error)

VisitorsPerLanguage implements the Store interface.

func (*PostgresStore) CountVisitorsPerPage added in v1.3.0

func (store *PostgresStore) CountVisitorsPerPage(tenantID sql.NullInt64, day time.Time) ([]VisitorsPerPage, error)

VisitorsPerPage implements the Store interface.

func (*PostgresStore) CountVisitorsPerReferer added in v1.3.0

func (store *PostgresStore) CountVisitorsPerReferer(tenantID sql.NullInt64, day time.Time) ([]VisitorsPerReferer, error)

CountVisitorsPerReferer implements the Store interface.

func (*PostgresStore) Days

func (store *PostgresStore) Days(tenantID sql.NullInt64) ([]time.Time, error)

Days implements the Store interface.

func (*PostgresStore) DeleteHitsByDay

func (store *PostgresStore) DeleteHitsByDay(tenantID sql.NullInt64, day time.Time) error

DeleteHitsByDay implements the Store interface.

func (*PostgresStore) HourlyVisitors

func (store *PostgresStore) HourlyVisitors(tenantID sql.NullInt64, from, to time.Time) ([]HourlyVisitors, error)

VisitorLanguages implements the Store interface.

func (*PostgresStore) PageVisits

func (store *PostgresStore) PageVisits(tenantID sql.NullInt64, path string, from, to time.Time) ([]VisitorsPerDay, error)

PageVisits implements the Store interface.

func (*PostgresStore) Paths

func (store *PostgresStore) Paths(tenantID sql.NullInt64, from, to time.Time) ([]string, error)

Paths implements the Store interface.

func (*PostgresStore) Referer added in v1.3.0

func (store *PostgresStore) Referer(tenantID sql.NullInt64, from, to time.Time) ([]string, error)

Referer implements the Store interface.

func (*PostgresStore) RefererVisits added in v1.3.0

func (store *PostgresStore) RefererVisits(tenantID sql.NullInt64, referer string, from, to time.Time) ([]VisitorsPerReferer, error)

RefererVisits implements the Store interface.

func (*PostgresStore) Save

func (store *PostgresStore) Save(hits []Hit) error

Save implements the Store interface.

func (*PostgresStore) SaveVisitorsPerDay

func (store *PostgresStore) SaveVisitorsPerDay(visitors *VisitorsPerDay) error

SaveVisitorsPerDay implements the Store interface.

func (*PostgresStore) SaveVisitorsPerHour

func (store *PostgresStore) SaveVisitorsPerHour(visitors *VisitorsPerHour) error

SaveVisitorsPerHour implements the Store interface.

func (*PostgresStore) SaveVisitorsPerLanguage

func (store *PostgresStore) SaveVisitorsPerLanguage(visitors *VisitorsPerLanguage) error

SaveVisitorsPerLanguage implements the Store interface.

func (*PostgresStore) SaveVisitorsPerPage

func (store *PostgresStore) SaveVisitorsPerPage(visitors *VisitorsPerPage) error

SaveVisitorsPerPage implements the Store interface.

func (*PostgresStore) SaveVisitorsPerReferer added in v1.3.0

func (store *PostgresStore) SaveVisitorsPerReferer(visitors *VisitorsPerReferer) error

SaveVisitorsPerReferer implements the Store interface.

func (*PostgresStore) VisitorLanguages

func (store *PostgresStore) VisitorLanguages(tenantID sql.NullInt64, from, to time.Time) ([]VisitorLanguage, error)

VisitorLanguages implements the Store interface.

func (*PostgresStore) VisitorPages added in v1.3.1

func (store *PostgresStore) VisitorPages(tenantID sql.NullInt64, from time.Time, to time.Time) ([]VisitorPage, error)

VisitorPages implements the Store interface.

func (*PostgresStore) VisitorReferer added in v1.3.1

func (store *PostgresStore) VisitorReferer(tenantID sql.NullInt64, from time.Time, to time.Time) ([]VisitorReferer, error)

VisitorReferer implements the Store interface.

func (*PostgresStore) Visitors

func (store *PostgresStore) Visitors(tenantID sql.NullInt64, from, to time.Time) ([]VisitorsPerDay, error)

Visitors implements the Store interface.

func (*PostgresStore) VisitorsPerDay

func (store *PostgresStore) VisitorsPerDay(tenantID sql.NullInt64) []VisitorsPerDay

VisitorsPerDay implements the Store interface.

func (*PostgresStore) VisitorsPerHour added in v1.3.0

func (store *PostgresStore) VisitorsPerHour(tenantID sql.NullInt64) []VisitorsPerHour

VisitorsPerHour implements the Store interface.

func (*PostgresStore) VisitorsPerLanguage

func (store *PostgresStore) VisitorsPerLanguage(tenantID sql.NullInt64) []VisitorsPerLanguage

VisitorsPerLanguage implements the Store interface.

func (*PostgresStore) VisitorsPerPage

func (store *PostgresStore) VisitorsPerPage(tenantID sql.NullInt64) []VisitorsPerPage

VisitorsPerPage implements the Store interface.

func (*PostgresStore) VisitorsPerReferer added in v1.3.0

func (store *PostgresStore) VisitorsPerReferer(tenantID sql.NullInt64) []VisitorsPerReferer

VisitorsPerReferer implements the Store interface.

type Processor

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

Processor processes hits to reduce them into meaningful statistics.

func NewProcessor

func NewProcessor(store Store, config *ProcessorConfig) *Processor

NewProcessor creates a new Processor for given Store and config. Pass nil for the config to use the defaults.

func (*Processor) Process

func (processor *Processor) Process() error

Process processes all hits in database and deletes them afterwards. It will panic in case of an error.

func (*Processor) ProcessTenant added in v1.2.0

func (processor *Processor) ProcessTenant(tenantID sql.NullInt64) error

ProcessTenant processes all hits in database for given tenant and deletes them afterwards. The tenant can be set to nil if you don't split your data (which is usually the case). It will panic in case of an error.

type ProcessorConfig added in v1.3.0

type ProcessorConfig struct {
	// ProcessVisitors enables/disabled processing the visitor count.
	// The default is true (enabled).
	ProcessVisitors bool

	// ProcessVisitorPerHour enables/disabled processing the visitor count per hour.
	// The default is true (enabled).
	ProcessVisitorPerHour bool

	// ProcessLanguages enables/disabled processing the language count.
	// The default is true (enabled).
	ProcessLanguages bool

	// ProcessPageViews enables/disabled processing the page views.
	// The default is true (enabled).
	ProcessPageViews bool

	// ProcessVisitorPerReferer enables/disabled processing the visitor count per referer.
	// The default is true (enabled).
	ProcessVisitorPerReferer bool
}

ProcessorConfig is the optional configuration for the Processor.

type RefererVisits added in v1.3.0

type RefererVisits struct {
	Referer string
	Visits  []VisitorsPerReferer
}

RefererVisits is the visitor count per day for each referer.

type Store

type Store interface {
	// Save persists a list of hits.
	Save([]Hit) error

	// DeleteHitsByDay deletes all hits on given day.
	DeleteHitsByDay(sql.NullInt64, time.Time) error

	// SaveVisitorsPerDay persists unique visitors per day.
	SaveVisitorsPerDay(*VisitorsPerDay) error

	// SaveVisitorsPerHour persists unique visitors per day and hour.
	SaveVisitorsPerHour(*VisitorsPerHour) error

	// SaveVisitorsPerLanguage persists unique visitors per day and language.
	SaveVisitorsPerLanguage(*VisitorsPerLanguage) error

	// SaveVisitorsPerPage persists unique visitors per day and page.
	SaveVisitorsPerPage(*VisitorsPerPage) error

	// SaveVisitorsPerReferer persists unique visitors per day and referer.
	SaveVisitorsPerReferer(*VisitorsPerReferer) error

	// Days returns the days at least one hit exists for.
	Days(sql.NullInt64) ([]time.Time, error)

	// CountVisitorsPerDay returns the unique visitor count for per day.
	CountVisitorsPerDay(sql.NullInt64, time.Time) (int, error)

	// CountVisitorsPerDayAndHour returns the unique visitor count per day and hour.
	CountVisitorsPerDayAndHour(sql.NullInt64, time.Time) ([]VisitorsPerHour, error)

	// CountVisitorsPerLanguage returns the unique visitor count per language and day.
	CountVisitorsPerLanguage(sql.NullInt64, time.Time) ([]VisitorsPerLanguage, error)

	// CountVisitorsPerPage returns the unique visitor count per page and day.
	CountVisitorsPerPage(sql.NullInt64, time.Time) ([]VisitorsPerPage, error)

	// CountVisitorsPerReferer returns the unique visitor count per referer and day.
	CountVisitorsPerReferer(sql.NullInt64, time.Time) ([]VisitorsPerReferer, error)

	// Paths returns distinct paths for page visits.
	// This does not include today.
	Paths(sql.NullInt64, time.Time, time.Time) ([]string, error)

	// Referer returns distinct referer for page visits.
	// This does not include today.
	Referer(sql.NullInt64, time.Time, time.Time) ([]string, error)

	// Visitors returns the visitors within given time frame.
	// This does not include today.
	Visitors(sql.NullInt64, time.Time, time.Time) ([]VisitorsPerDay, error)

	// PageVisits returns the page visits within given time frame for given path.
	// This does not include today.
	PageVisits(sql.NullInt64, string, time.Time, time.Time) ([]VisitorsPerDay, error)

	// RefererVisits returns the referer visits within given time frame for given referer.
	// This does not include today.
	RefererVisits(sql.NullInt64, string, time.Time, time.Time) ([]VisitorsPerReferer, error)

	// VisitorPages returns the pages within given time frame for unique visitors.
	// It does include today.
	VisitorPages(sql.NullInt64, time.Time, time.Time) ([]VisitorPage, error)

	// VisitorLanguages returns the languages within given time frame for unique visitors.
	// It does include today.
	VisitorLanguages(sql.NullInt64, time.Time, time.Time) ([]VisitorLanguage, error)

	// VisitorReferer returns the languages within given time frame for unique visitors.
	// It does include today.
	VisitorReferer(sql.NullInt64, time.Time, time.Time) ([]VisitorReferer, error)

	// HourlyVisitors returns unique visitors per hour for given time frame.
	// It does include today.
	HourlyVisitors(sql.NullInt64, time.Time, time.Time) ([]HourlyVisitors, error)

	// ActiveVisitors returns unique visitors starting at given time.
	ActiveVisitors(sql.NullInt64, time.Time) (int, error)

	// ActiveVisitorsPerPage returns unique visitors per page starting at given time.
	ActiveVisitorsPerPage(sql.NullInt64, time.Time) ([]PageVisitors, error)

	// CountHits returns the number of hits for given tenant ID.
	CountHits(sql.NullInt64) int

	// VisitorsPerDay returns all visitors per day for given tenant ID in order.
	VisitorsPerDay(sql.NullInt64) []VisitorsPerDay

	// VisitorsPerHour returns all visitors per hour for given tenant ID in order.
	VisitorsPerHour(sql.NullInt64) []VisitorsPerHour

	// VisitorsPerLanguage returns all visitors per language for given tenant ID in alphabetical order.
	VisitorsPerLanguage(sql.NullInt64) []VisitorsPerLanguage

	// VisitorsPerPage returns all visitors per page for given tenant ID in alphabetical order.
	VisitorsPerPage(sql.NullInt64) []VisitorsPerPage

	// VisitorsPerReferer returns all visitors per referer for given tenant ID in alphabetical order.
	VisitorsPerReferer(sql.NullInt64) []VisitorsPerReferer
}

Store defines an interface to persists hits and other data. The first parameter (if required) is always the tenant ID and can be left out (pirsch.NullTenant), if you don't want to split your data. This is usually the case if you integrate Pirsch into your application.

type Tracker

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

Tracker is the main component of Pirsch. It provides methods to track requests and store them in a data store. It panics in case it cannot store requests into the configured store.

func NewTracker

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

NewTracker creates a new tracker for given store, salt and config. Pass nil for the config to use the defaults. The salt is mandatory.

func (*Tracker) Flush

func (tracker *Tracker) Flush()

Flush flushes all hits to store.

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. The actions performed within this function run in their own goroutine, so you don't need to create one yourself.

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 store hits.
	// Must be greater or equal to 1.
	Worker int

	// WorkerBufferSize is the size of the buffer used to store 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 store hits.
	// This is used to allow the workers to store hits even if the buffer is not full yet.
	// It's recommended to set this to a few seconds.
	WorkerTimeout time.Duration

	// RefererDomainBlacklist see HitOptions.RefererDomainBlacklist.
	RefererDomainBlacklist []string

	// RefererDomainBlacklistIncludesSubdomains see HitOptions.RefererDomainBlacklistIncludesSubdomains.
	RefererDomainBlacklistIncludesSubdomains bool
}

TrackerConfig is the optional configuration for the Tracker.

type VisitorLanguage

type VisitorLanguage struct {
	Language         string  `db:"language" json:"language"`
	Visitors         int     `db:"visitors" json:"visitors"`
	RelativeVisitors float64 `db:"-" json:"relative_visitors"`
}

VisitorLanguage is the unique visitor count per language.

type VisitorPage added in v1.3.1

type VisitorPage struct {
	Path     string `db:"path" json:"path"`
	Visitors int    `db:"visitors" json:"visitors"`
}

VisitorPage is the unique visitor count per page.

type VisitorReferer added in v1.3.1

type VisitorReferer struct {
	Referer  string `db:"ref" json:"referer"`
	Visitors int    `db:"visitors" json:"visitors"`
}

VisitorReferer is the unique visitor count per referer.

type VisitorsPerDay

type VisitorsPerDay struct {
	ID       int64         `db:"id" json:"id"`
	TenantID sql.NullInt64 `db:"tenant_id" json:"tenant_id"`
	Day      time.Time     `db:"day" json:"day"`
	Visitors int           `db:"visitors" json:"visitors"`
}

VisitorsPerDay is the unique visitor count per day.

type VisitorsPerHour

type VisitorsPerHour struct {
	ID         int64         `db:"id" json:"id"`
	TenantID   sql.NullInt64 `db:"tenant_id" json:"tenant_id"`
	DayAndHour time.Time     `db:"day_and_hour" json:"day_and_hour"`
	Visitors   int           `db:"visitors" json:"visitors"`
}

VisitorsPerHour is the unique visitor count per hour and day.

type VisitorsPerLanguage

type VisitorsPerLanguage struct {
	ID       int64         `db:"id" json:"id"`
	TenantID sql.NullInt64 `db:"tenant_id" json:"tenant_id"`
	Day      time.Time     `db:"day" json:"day"`
	Language string        `db:"language" json:"language"`
	Visitors int           `db:"visitors" json:"visitors"`
}

VisitorsPerLanguage is the unique visitor count per language and day.

type VisitorsPerPage

type VisitorsPerPage struct {
	ID       int64         `db:"id" json:"id"`
	TenantID sql.NullInt64 `db:"tenant_id" json:"tenant_id"`
	Day      time.Time     `db:"day" json:"day"`
	Path     string        `db:"path" json:"path"`
	Visitors int           `db:"visitors" json:"visitors"`
}

VisitorsPerPage is the unique visitor count per path and day.

type VisitorsPerReferer added in v1.3.0

type VisitorsPerReferer struct {
	ID       int64         `db:"id" json:"id"`
	TenantID sql.NullInt64 `db:"tenant_id" json:"tenant_id"`
	Day      time.Time     `db:"day" json:"day"`
	Ref      string        `db:"ref" json:"ref"`
	Visitors int           `db:"visitors" json:"visitors"`
}

VisitorsPerReferer is the unique visitor count per referer and day.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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