Documentation ¶
Index ¶
- Constants
- Variables
- type AggregatedMetric
- type AggregationMethod
- type BarChartData
- type Dashboard
- type DashboardStat
- type GroupMetricBy
- type Kero
- func (k *Kero) AggregateDistinct(metricName string, groupBy GroupMetricBy, labelFilters MetricLabels, ...) ([]AggregatedMetric, error)
- func (k *Kero) Close() error
- func (k *Kero) Count(metric string, start int64, end int64) int
- func (k *Kero) CountDistinctByVisitor(metricName string, groupBy GroupMetricBy, labelFilters MetricLabels, ...) ([]AggregatedMetric, error)
- func (k *Kero) CountDistinctByVisitorAndLabel(metric string, label string, labelFilters MetricLabels, start int64, end int64) ([]AggregatedMetric, error)
- func (k *Kero) CountHistogram(metric string, start int64, end int64) [][2]int64
- func (k *Kero) CountVisitors(metric string, labelFilters MetricLabels, start int64, end int64) (int, error)
- func (k *Kero) MeasureHttpRequest(req TrackedHttpReq, handler func())
- func (k *Kero) Query(metric string, labelFilters MetricLabels, start int64, end int64) ([]Metric, error)
- func (k *Kero) ShouldTrackHttpRequest(path string) bool
- func (k *Kero) Track(metric string, labels MetricLabels, value float64) error
- func (k *Kero) TrackHttpRequest(req TrackedHttpReq) error
- func (k *Kero) TrackOne(metric string, labels MetricLabels) error
- func (k *Kero) TrackOneWithRequest(metric string, labels MetricLabels, req TrackedHttpReq) error
- func (k *Kero) TrackWithRequest(metric string, labels MetricLabels, value float64, req TrackedHttpReq) error
- func (k *Kero) VisitorsHistogram(metric string, filters MetricLabels, start int64, end int64) [][2]int64
- type KeroOption
- func WithBotsIgnored(value bool) KeroOption
- func WithDB(dbPath string) KeroOption
- func WithDashboardPath(path string) KeroOption
- func WithDntIgnored(value bool) KeroOption
- func WithGeoIPDB(geoIPDBPath string) KeroOption
- func WithPixelPath(path string) KeroOption
- func WithRequestMeasurements(value bool) KeroOption
- func WithRetention(duration time.Duration) KeroOption
- func WithWebAssetsIgnored(value bool) KeroOption
- type LabelFormatter
- type Metric
- type MetricLabels
- type TrackedHttpReq
- type Trend
Constants ¶
const ( AggregateByHour time.Duration = time.Hour AggregateByDay = time.Hour * 24 AggregateByWeek = time.Hour * 24 * 7 AggregateByMonth = time.Hour * 24 * 31 AggregateByQuarter = time.Hour * 24 * 31 * 3 AggregateByYear = time.Hour * 24 * 31 * 12 )
const BrowserDeviceLabel = "$browser_device"
const BrowserFormFactorLabel = "$browser_form_factor"
const BrowserNameLabel = "$browser_name"
const BrowserOSLabel = "$browser_os"
const BrowserOSVersionLabel = "$browser_os_version"
const BrowserVersionLabel = "$browser_version"
const CityLabel = "$city"
const ClickIdFbLabel = "$clid_fb"
const ClickIdGoogleLabel = "$clid_go"
const ClickIdMsLabel = "$clid_ms"
const ClickIdTwLabel = "$clid_tw"
const CountryLabel = "$country"
const FormFactorBot = "bot"
const FormFactorDesktop = "desktop"
const FormFactorMobile = "mobile"
const FormFactorTablet = "tablet"
const HttpMethodLabel = "$http_method"
const HttpPathLabel = "$http_path"
const HttpReqDurationMetricName = "http_req_dur"
const HttpReqMetricName = "http_req"
const HttpRouteLabel = "$http_route"
const IsBotLabel = "$is_bot"
const MetricName = labels.MetricName
const ReferrerDomainLabel = "$referrer_domain"
const ReferrerLabel = "$referrer"
const RegionLabel = "$region"
const UTMCampaignLabel = "$utm_campaign"
const UTMContentLabel = "$utm_content"
const UTMMediumLabel = "$utm_medium"
const UTMSourceLabel = "$utm_source"
const UTMTermLabel = "$utm_term"
const VisitorIdLabel = "$visitor_id"
Variables ¶
var DashboardWebAssets embed.FS
var DefaultDashboard = Dashboard{ Title: "App stats", ShowFooter: true, Rows: [][]DashboardStat{ { { Title: "Top pages", UnitDisplayLabel: "Page", CountLabel: "Visitors", QueryMetric: HttpReqMetricName, QueryLabel: HttpPathLabel, QueryByVisitor: true, QueryExcludeBots: true, }, { Title: "Top referrals", UnitDisplayLabel: "Site", CountLabel: "Visitors", QueryMetric: HttpReqMetricName, QueryLabel: ReferrerDomainLabel, QueryByVisitor: true, QueryExcludeBots: true, }, { Title: "Top locations", UnitDisplayLabel: "Country", CountLabel: "Visitors", QueryMetric: HttpReqMetricName, QueryLabel: CountryLabel, QueryByVisitor: true, QueryExcludeBots: true, FormatLabel: func(am AggregatedMetric) string { cc := am.Label return string(0x1F1E6+rune(cc[0])-'A') + string(0x1F1E6+rune(cc[1])-'A') + " " + cc }, }, }, { { Title: "Top form factors", UnitDisplayLabel: "Form factor", CountLabel: "Visitors", QueryMetric: HttpReqMetricName, QueryLabel: BrowserFormFactorLabel, QueryByVisitor: true, FormatLabel: func(am AggregatedMetric) string { if emoji, ok := formFactorEmojis[am.Label]; ok { return emoji } return am.Label }, }, { Title: "Top browsers", UnitDisplayLabel: "Browser", CountLabel: "Visitors", QueryMetric: HttpReqMetricName, QueryLabel: BrowserNameLabel, QueryByVisitor: true, QueryExcludeBots: true, }, { Title: "Top operating systems", UnitDisplayLabel: "Operating system", CountLabel: "Visitors", QueryMetric: HttpReqMetricName, QueryFilters: MetricLabels{ (BrowserFormFactorLabel + "!="): FormFactorBot, }, QueryLabel: BrowserOSLabel, QueryByVisitor: true, QueryExcludeBots: true, }, }, { { Title: "Top routes", UnitDisplayLabel: "Route", CountLabel: "Visitors", QueryMetric: HttpReqMetricName, QueryLabel: HttpRouteLabel, QueryByVisitor: true, }, { Title: "Slowest routes", UnitDisplayLabel: "Route", CountLabel: "avg ms", QueryMetric: HttpReqDurationMetricName, QueryGroupBy: groupByRoute, QueryAggregateBy: AggregateAvg, }, { Title: "Top bots and libraries", UnitDisplayLabel: "Bot", CountLabel: "Rqs", QueryMetric: HttpReqMetricName, QueryFilters: MetricLabels{ BrowserFormFactorLabel: FormFactorBot, }, QueryLabel: BrowserNameLabel, }, }, }, }
var Pixel, _ = base64.StdEncoding.DecodeString("R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==")
1x1px transparent GIF. Source must be StackOverflow
var PixelSize = int64(len(Pixel))
Functions ¶
This section is empty.
Types ¶
type AggregatedMetric ¶
type AggregationMethod ¶
type AggregationMethod int
const ( AggregateCount AggregationMethod = iota // Aggregates by counting number of matched events AggregateSum // Aggregates by summing values of matched events AggregateAvg // Aggregates by calculating an average value of matched events )
type BarChartData ¶
func (*BarChartData) FormattedTimestamp ¶
func (bcd *BarChartData) FormattedTimestamp() string
type Dashboard ¶
type Dashboard struct { Title string BasePath string VisitorsChartData []BarChartData VisitorsTrend Trend ViewsChartData []BarChartData ViewsTrend Trend Rows [][]DashboardStat }
type DashboardStat ¶
type DashboardStat struct { Title string UnitDisplayLabel string CountLabel string QueryMetric string QueryLabel string QueryGroupBy GroupMetricBy QueryFilters MetricLabels QueryByVisitor bool QueryAggregateBy AggregationMethod QueryExcludeBots bool FormatLabel LabelFormatter Data []AggregatedMetric }
type GroupMetricBy ¶
type Kero ¶
type Kero struct { DashboardPath string PixelPath string MeasureRequestDuration bool IgnoreCommonPaths bool IgnoreBots bool IgnoreDNT bool // path prefixes to which requests will be ignored. see file for default list. IgnoredPrefixes []string // path suffixes to which requestw will be ignored. see file for default list. IgnoredSuffixes []string // user-agent values to be ignored. see file for default list. IgnoredAgents []string // contains filtered or unexported fields }
func New ¶
func New(options ...KeroOption) (*Kero, error)
New automatically creates a new Kero database on-disk if one doesn't exist already. See WithXXX functions for option configuration.
func (*Kero) AggregateDistinct ¶
func (k *Kero) AggregateDistinct( metricName string, groupBy GroupMetricBy, labelFilters MetricLabels, aggregateBy AggregationMethod, start int64, end int64, ) ([]AggregatedMetric, error)
AggregateDistinct provides advanced options to query the database. Data can be filtered using the metric name or any combination of labels (including negation). Additionally data can be grouped by a calculated key and aggregated using count, sum or average. Example:
func QueryExample() { k, _ := kero.New(kero.WithDatabasePath("./kero")) data, _ := k.AggregateDistinct( "http_req", // get all "http_req" metrics func(m Metric) string { return m.Labels["$city"] }, // group them by city MetricLabels{ "country": "CH", "region!=": "ZH" } // filtering only requests coming from Switzerland, from any region except Zurich, kero.AggregateCount, // and return only the count of matched rows 0, // from beginning of time time.Now().Unix(), // ...until now ) fmt.Println("Found", len(data), "records:") for _, row := range data { fmt.Println(row.Value, "visitors from", row.Label) } }
Results are sorted by highest value first.
func (*Kero) Count ¶
Count is an optimized version of AggregateDistinct counting occurrences of a metric in the specified timeframe.
func (*Kero) CountDistinctByVisitor ¶
func (k *Kero) CountDistinctByVisitor( metricName string, groupBy GroupMetricBy, labelFilters MetricLabels, start int64, end int64, ) ([]AggregatedMetric, error)
CountDistinctByVisitor returns a number of unique visitors for which the matching events have been tracked.
func (*Kero) CountDistinctByVisitorAndLabel ¶
func (k *Kero) CountDistinctByVisitorAndLabel( metric string, label string, labelFilters MetricLabels, start int64, end int64, ) ([]AggregatedMetric, error)
CountDistinctByVisitorAndLabel is a convenience method that's groups metrics simply by using the specified label. If filtering by [Kero.HttpRouteLabel], requests are grouped by both the HTTP method and the route, this way a distinction can be made between `GET /user/:id` and `POST /user/:id`. Events without the label itselfz are excluded from the count.
func (*Kero) CountHistogram ¶
CountHistogram returns metric count within the specified timeframe for each time subdivision based on the duration between start and end time. Subdivisions are determined as follows:
- duration up to 3 days: 72 subdivisions each of 1 hour
- duration up to 31 days (ie. 1 month): 1 day
- duration up to 93 days (ie. 3 months): 1 week
- for durations longer than 3 months: 1 month
func (*Kero) CountVisitors ¶
func (k *Kero) CountVisitors(metric string, labelFilters MetricLabels, start int64, end int64) (int, error)
CountVisitors counts number of unique visitors for which an event with matching filters has been tracked within the specified timeframe.
func (*Kero) MeasureHttpRequest ¶
func (k *Kero) MeasureHttpRequest(req TrackedHttpReq, handler func())
func (*Kero) Query ¶
func (k *Kero) Query(metric string, labelFilters MetricLabels, start int64, end int64) ([]Metric, error)
Query looks for matching metrics within the specified timeframe.
func (*Kero) ShouldTrackHttpRequest ¶
func (*Kero) TrackHttpRequest ¶
func (k *Kero) TrackHttpRequest(req TrackedHttpReq) error
func (*Kero) TrackOneWithRequest ¶
func (k *Kero) TrackOneWithRequest(metric string, labels MetricLabels, req TrackedHttpReq) error
func (*Kero) TrackWithRequest ¶
func (k *Kero) TrackWithRequest(metric string, labels MetricLabels, value float64, req TrackedHttpReq) error
func (*Kero) VisitorsHistogram ¶
func (k *Kero) VisitorsHistogram(metric string, filters MetricLabels, start int64, end int64) [][2]int64
VisitorsHistogram returns a number of unique visitors per time subdivision in the specified timeframe. See Kero.CountHistogram for reference on time subdivisions.
type KeroOption ¶
func WithBotsIgnored ¶
func WithBotsIgnored(value bool) KeroOption
WithBotsIgnored sets whether Kero should ignore requests made by bots, web scrapers and HTTP libraries. Bots and libraries are detected using their `User-Agent` header.
func WithDB ¶
func WithDB(dbPath string) KeroOption
WithDB sets the location of the database folder. Automatically created if it doesn't exist.
func WithDashboardPath ¶
func WithDashboardPath(path string) KeroOption
WithDashboardPath sets the URL at which the dashboard will be mounted. Defaults to `"/_kero"`.
func WithDntIgnored ¶
func WithDntIgnored(value bool) KeroOption
WithDntIgnored sets whether Kero should ignore value of DNT header. If configured to ignore, requests with DNT: 1 (opt-out of tracking) will be still tracked.
func WithGeoIPDB ¶
func WithGeoIPDB(geoIPDBPath string) KeroOption
WithGeoIPDB loads the MaxMind GeoLine2 and GeoIP2 database for IP-reverse lookup of visitors. If not provided, IP reverse-lookup is disabled.
func WithPixelPath ¶ added in v0.2.0
func WithPixelPath(path string) KeroOption
WithPixelPath defines the route at which the pixel tracker will be available to external applications. The pixel can be referenced from static websites or services not directly served by the Go server. Requests referer header will be used as the path, with other headers and query parameters used unchanged. Response of the pixel path will be a 1x1px transparent GIF.
func WithRequestMeasurements ¶
func WithRequestMeasurements(value bool) KeroOption
WithRequestMeasurements sets whether Kero should automatically measure response of handlers time.
func WithRetention ¶
func WithRetention(duration time.Duration) KeroOption
WithRetention defines the how long data points should be kept. Defaults to 15 days.
func WithWebAssetsIgnored ¶
func WithWebAssetsIgnored(value bool) KeroOption
WithWebAssetsIgnored sets whether Kero should ignore requests made to common web assets.
Ignored paths include:
- .css and .js files
- images (.png, .svg, .jpg, .webp, etc.)
- fonts (.woff2, .ttf, .otf, etc.)
- common URLs accessed by web scrapers (.php, .asp, etc.)
- any path starting with /., /_, /wp- and /public.
Kero's resources and paths are always excluded.
type LabelFormatter ¶
type LabelFormatter func(AggregatedMetric) string
type Metric ¶
type Metric struct { Ts int64 `json:"timestamp"` Name string `json:"name"` Labels MetricLabels `json:"labels"` Value float64 `json:"value"` }