mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-30 02:46:30 +02:00
80 lines
2.3 KiB
Go
80 lines
2.3 KiB
Go
package analytics
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/pomerium/pomerium/pkg/counter"
|
|
)
|
|
|
|
const (
|
|
// activeUsersCap is the number of active users we would be able to track.
|
|
// for counter to work within the 1% error limit, actual number should be 80% of the cap.
|
|
activeUsersCap = 10_000
|
|
)
|
|
|
|
// IntervalResetFunc is a function that determines if a counter should be reset
|
|
type IntervalResetFunc func(lastReset time.Time, now time.Time) bool
|
|
|
|
// ResetMonthlyUTC resets the counter on a monthly interval
|
|
func ResetMonthlyUTC(lastReset time.Time, now time.Time) bool {
|
|
lastResetUTC := lastReset.UTC()
|
|
nowUTC := now.UTC()
|
|
return lastResetUTC.Year() != nowUTC.Year() ||
|
|
lastResetUTC.Month() != nowUTC.Month()
|
|
}
|
|
|
|
// ResetDailyUTC resets the counter on a daily interval
|
|
func ResetDailyUTC(lastReset time.Time, now time.Time) bool {
|
|
lastResetUTC := lastReset.UTC()
|
|
nowUTC := now.UTC()
|
|
return lastResetUTC.Year() != nowUTC.Year() ||
|
|
lastResetUTC.Month() != nowUTC.Month() ||
|
|
lastResetUTC.Day() != nowUTC.Day()
|
|
}
|
|
|
|
// ActiveUsersCounter is a counter that resets on a given interval
|
|
type ActiveUsersCounter struct {
|
|
*counter.Counter
|
|
lastReset time.Time
|
|
needsReset IntervalResetFunc
|
|
}
|
|
|
|
// NewActiveUsersCounter creates a new active users counter
|
|
func NewActiveUsersCounter(needsReset IntervalResetFunc, now time.Time) *ActiveUsersCounter {
|
|
return &ActiveUsersCounter{
|
|
Counter: counter.New(activeUsersCap),
|
|
lastReset: now,
|
|
needsReset: needsReset,
|
|
}
|
|
}
|
|
|
|
// LoadActiveUsersCounter loads an active users counter from a binary state
|
|
func LoadActiveUsersCounter(state []byte, lastReset time.Time, resetFn IntervalResetFunc) (*ActiveUsersCounter, error) {
|
|
c, err := counter.FromBinary(state)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &ActiveUsersCounter{
|
|
Counter: c,
|
|
lastReset: lastReset,
|
|
needsReset: resetFn,
|
|
}, nil
|
|
}
|
|
|
|
// Update updates the counter with the current users
|
|
func (c *ActiveUsersCounter) Update(users []string, now time.Time) (current uint, wasReset bool) {
|
|
if c.needsReset(c.lastReset, now) {
|
|
c.Counter.Reset()
|
|
c.lastReset = now
|
|
wasReset = true
|
|
}
|
|
for _, user := range users {
|
|
c.Mark(user)
|
|
}
|
|
return c.Count(), wasReset
|
|
}
|
|
|
|
// GetLastReset returns the last time the counter was reset
|
|
func (c *ActiveUsersCounter) GetLastReset() time.Time {
|
|
return c.lastReset
|
|
}
|