insights

package module
v1.12.0 Latest Latest
Warning

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

Go to latest
Published: Apr 6, 2026 License: MIT Imports: 28 Imported by: 0

README

Hanzo Insights Go SDK

Go Reference Go Report Card

Go client SDK for Hanzo Insights (product analytics).

Install

go get github.com/hanzoai/insights-go

Quick Start

package main

import (
    "os"

    insights "github.com/hanzoai/insights-go"
)

func main() {
    client, _ := insights.NewWithConfig(
        os.Getenv("INSIGHTS_API_KEY"),
        insights.Config{
            Endpoint: "https://insights.hanzo.ai",
        },
    )
    defer client.Close()

    // Capture an event
    client.Enqueue(insights.Capture{
        DistinctId: "user-123",
        Event:      "purchase",
        Properties: insights.NewProperties().
            Set("plan", "enterprise").
            Set("amount", 99),
    })
}

Common Operations

Capture Events
client.Enqueue(insights.Capture{
    DistinctId: "user-123",
    Event:      "page_view",
    Properties: insights.NewProperties().
        Set("$current_url", "https://example.com/pricing"),
})
Identify Users
client.Enqueue(insights.Identify{
    DistinctId: "user-123",
    Properties: insights.NewProperties().
        Set("email", "alice@example.com").
        Set("name", "Alice").
        Set("plan", "pro"),
})
Feature Flags
// Check if a flag is enabled
enabled, err := client.IsFeatureEnabled(
    insights.FeatureFlagPayload{
        Key:        "new-dashboard",
        DistinctId: "user-123",
    },
)

if enabled == true {
    // Show new dashboard
}

// Get flag variant
variant, err := client.GetFeatureFlag(
    insights.FeatureFlagPayload{
        Key:        "checkout-flow",
        DistinctId: "user-123",
    },
)
Group Analytics
// Associate a user with a group
client.Enqueue(insights.GroupIdentify{
    Type: "company",
    Key:  "hanzo-ai",
    Properties: insights.NewProperties().
        Set("name", "Hanzo AI").
        Set("industry", "technology"),
})

// Capture event with group context
client.Enqueue(insights.Capture{
    DistinctId: "user-123",
    Event:      "deploy",
    Groups: insights.NewGroups().
        Set("company", "hanzo-ai"),
})
Alias Users
client.Enqueue(insights.Alias{
    DistinctId: "user-123",
    Alias:      "user-456",
})

Configuration

client, _ := insights.NewWithConfig(
    os.Getenv("INSIGHTS_API_KEY"),
    insights.Config{
        Endpoint:       "https://insights.hanzo.ai",
        PersonalApiKey: os.Getenv("INSIGHTS_PERSONAL_KEY"), // For local feature flag evaluation
        BatchSize:      100,
        Interval:       5 * time.Second,
        MaxRetries:     insights.Ptr(3),
        RetryAfter: func(attempt int) time.Duration {
            return time.Duration(100<<attempt) * time.Millisecond
        },
    },
)

Event Delivery

The SDK includes automatic retry logic with configurable backoff. Events are retried on transient network failures (EOF, connection reset, temporary unavailability). Events are dropped after max retries are exhausted (default: 10 attempts), on non-retryable errors (4xx responses), or if the client is closed during retry.

Monitor delivery with a callback:

type DeliveryLogger struct{}

func (d *DeliveryLogger) Success(msg insights.APIMessage) {
    log.Printf("delivered: %v", msg)
}

func (d *DeliveryLogger) Failure(msg insights.APIMessage, err error) {
    log.Printf("dropped: %v err=%v", msg, err)
}

client, _ := insights.NewWithConfig(apiKey, insights.Config{
    Callback: &DeliveryLogger{},
})

Development

make dependencies   # Install deps
make build          # Run tests and build
make test           # Run tests only

Attribution

Based on PostHog Go SDK. See upstream LICENSE for attribution.

License

MIT License. Copyright (c) Hanzo AI Inc.

Documentation

Index

Examples

Constants

View Source
const (
	SDKName = "insights-go"

	// DefaultEndpoint constant sets the default endpoint to which client instances send
	// messages if none was explicitly set.
	DefaultEndpoint = "https://insights.hanzo.ai"

	// DefaultInterval constant sets the default flush interval used by client instances if
	// none was explicitly set.
	DefaultInterval = 5 * time.Second

	// DefaultFeatureFlagsPollingInterval the default interval at which to fetch new feature flags
	DefaultFeatureFlagsPollingInterval = 5 * time.Minute

	// DefaultFeatureFlagRequestTimeout the default timeout for fetching feature flags
	DefaultFeatureFlagRequestTimeout = 3 * time.Second

	// DefaultBatchSize sets the default batch size used by client instances if none
	// was explicitly set.
	DefaultBatchSize = 250

	// DefaultBatchUploadTimeout is the default timeout for uploading batched
	// events to the /batch/ endpoint.
	DefaultBatchUploadTimeout = 10 * time.Second

	// DefaultBatchSubmitTimeout is the default timeout for submitting batches
	// to the worker pool when the queue is full. This allows workers time to
	// complete during transient latency spikes, reducing unnecessary data loss.
	DefaultBatchSubmitTimeout = 100 * time.Millisecond

	// DefaultMaxEnqueuedRequests is the default maximum number of batches that
	// can be queued for sending.
	DefaultMaxEnqueuedRequests = 1000
)
View Source
const (
	// FeatureFlagErrorErrorsWhileComputing indicates the server returned errorsWhileComputingFlags=true
	FeatureFlagErrorErrorsWhileComputing = "errors_while_computing_flags"

	// FeatureFlagErrorFlagMissing indicates the requested flag was not in the API response
	FeatureFlagErrorFlagMissing = "flag_missing"

	// FeatureFlagErrorEvaluationFailed indicates the flag was present but failed to evaluate due to a transient server error
	FeatureFlagErrorEvaluationFailed = "evaluation_failed"

	// FeatureFlagErrorQuotaLimited indicates rate/quota limit was exceeded
	FeatureFlagErrorQuotaLimited = "quota_limited"

	// FeatureFlagErrorTimeout indicates request timed out
	FeatureFlagErrorTimeout = "timeout"

	// FeatureFlagErrorConnectionError indicates network connectivity issue
	FeatureFlagErrorConnectionError = "connection_error"

	// FeatureFlagErrorUnknownError indicates an unexpected error occurred
	FeatureFlagErrorUnknownError = "unknown_error"

	// FeatureFlagErrorAPIErrorPrefix is the prefix for API errors with status codes
	FeatureFlagErrorAPIErrorPrefix = "api_error_"
)

Feature flag error type constants for the $feature_flag_error property. These values are sent in analytics events to track flag evaluation failures. They should not be changed without considering impact on existing dashboards and queries that filter on these values.

View Source
const (
	CACHE_DEFAULT_SIZE = 300_000

	// DefaultIdleConns is the default max idle connections for the HTTP client.
	DefaultIdleConns = 100
	// DefaultIdleConnsPerHost is the default max idle connections per host.
	// This is higher than http.DefaultTransport's value of 2 to reduce
	// connection churn when sending batches.
	DefaultIdleConnsPerHost = 10
)
View Source
const (
	LONG_SCALE = 0xfffffffffffffff
)
View Source
const Version = "1.10.0"

Version of the client.

Variables

View Source
var (
	// This error is returned by methods of the `Client` interface when they are
	// called after the client was already closed.
	ErrClosed = errors.New("the client was already closed")

	// This error is used to notify the application that too many requests are
	// already being sent and no more messages can be accepted.
	ErrTooManyRequests = errors.New("too many requests are already in-flight")

	// This error is used to notify the client callbacks that a message send
	// failed because the JSON representation of a message exceeded the upper
	// limit.
	ErrMessageTooBig = errors.New("the message exceeds the maximum allowed size")

	// ErrNoPersonalAPIKey is returned when one tries to use feature flags
	// without specifying a PersonalAPIKey.
	ErrNoPersonalAPIKey = errors.New("no PersonalAPIKey provided")
)
View Source
var ErrFlagNotFound = errors.New("feature flag not found")

ErrFlagNotFound is returned when a feature flag does not exist or is disabled. Use errors.Is(err, ErrFlagNotFound) to check for this error.

Functions

func Ptr

func Ptr[T any](v T) *T

Ptr is a helper to easily make reference from value.

func SimpleInAppDecider

func SimpleInAppDecider(frame runtime.Frame) bool

SimpleInAppDecider a naive implementation of InAppDecider which checks the file paths. It's good enough for 90% of the cases.

Types

type APIError

type APIError struct {
	StatusCode int
	Message    string
}

APIError represents an HTTP API error with a status code. This allows classifyError to generate api_error_{status} strings.

func NewAPIError

func NewAPIError(statusCode int, message string) *APIError

NewAPIError creates a new APIError with the given status code.

func (*APIError) Error

func (e *APIError) Error() string

type APIMessage

type APIMessage interface{}

type Alias

type Alias struct {
	// This field is exported for serialization purposes and shouldn't be set by
	// the application, its value is always overwritten by the library.
	Type string
	// Uuid is optional. If not provided, a random UUID will be generated.
	Uuid string

	Alias        string
	DistinctId   string
	Timestamp    time.Time
	DisableGeoIP bool
}

This type represents object sent in a alias call

func (Alias) APIfy

func (msg Alias) APIfy() APIMessage

func (Alias) Validate

func (msg Alias) Validate() error

type AliasInApi

type AliasInApi struct {
	Type           string    `json:"type"`
	Uuid           string    `json:"uuid"`
	Library        string    `json:"library"`
	LibraryVersion string    `json:"library_version"`
	Timestamp      time.Time `json:"timestamp"`

	Properties AliasInApiProperties `json:"properties"`

	Event string `json:"event"`
}

type AliasInApiProperties

type AliasInApiProperties struct {
	DistinctId   string `json:"distinct_id"`
	Alias        string `json:"alias"`
	Lib          string `json:"$lib"`
	LibVersion   string `json:"$lib_version"`
	DisableGeoIP bool   `json:"$geoip_disable,omitempty"`
}

type Backoff

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

func DefaultBackoff

func DefaultBackoff() *Backoff

Creates a backoff instance with the following defaults:

base: 100 milliseconds
factor: 2
jitter: 0
cap: 10 seconds

func NewBackoff

func NewBackoff(base time.Duration, factor uint8, jitter float64, cap time.Duration) *Backoff

Creates a backo instance with the given parameters

func (*Backoff) Duration

func (b *Backoff) Duration(attempt int) time.Duration

Duration returns the backoff interval for the given attempt.

func (*Backoff) NewTicker

func (b *Backoff) NewTicker() *Ticker

func (*Backoff) Sleep

func (b *Backoff) Sleep(attempt int)

Sleep pauses the current goroutine for the backoff interval for the given attempt.

type Callback

type Callback interface {

	// This method is called for every message that was successfully sent to
	// the API.
	Success(APIMessage)

	// This method is called for every message that failed to be sent to the
	// API and will be discarded by the client.
	Failure(APIMessage, error)
}

Values implementing this interface are used by insights clients to notify the application when a message send succeeded or failed.

Callback methods are called by a client's internal goroutines, there are no guarantees on which goroutine will trigger the callbacks, the calls can be made sequentially or in parallel, the order doesn't depend on the order of messages were queued to the client.

Callback methods must return quickly and not cause long blocking operations to avoid interferring with the client's internal work flow.

type Capture

type Capture struct {
	// This field is exported for serialization purposes and shouldn't be set by
	// the application, its value is always overwritten by the library.
	Type string
	// You don't usually need to specify this field - Insights will generate it automatically.
	// Use it only when necessary - for example, to prevent duplicate events.
	Uuid             string
	DistinctId       string
	Event            string
	Timestamp        time.Time
	Properties       Properties
	Groups           Groups
	SendFeatureFlags SendFeatureFlagsValue
}

This type represents object sent in a capture call

Example
body, server := mockServer()
defer server.Close()

client, _ := NewWithConfig("Csyjlnlun3OzyNJAafdlv", Config{
	Endpoint:  server.URL,
	BatchSize: 1,
	now:       mockTime,
})
defer client.Close()

client.Enqueue(Capture{
	Uuid:       "00000000-0000-0000-0000-000000000000",
	Event:      "Download",
	DistinctId: "123456",
	Properties: Properties{
		"application": "Insights Go",
		"version":     "1.0.0",
		"platform":    "macos", // :)
	},
	SendFeatureFlags: SendFeatureFlags(false),
})

fmt.Printf("%s\n", <-body)
Output:
{
  "api_key": "Csyjlnlun3OzyNJAafdlv",
  "batch": [
    {
      "distinct_id": "123456",
      "event": "Download",
      "library": "insights-go",
      "library_version": "1.0.0",
      "properties": {
        "$geoip_disable": true,
        "$lib": "insights-go",
        "$lib_version": "1.0.0",
        "application": "Insights Go",
        "platform": "macos",
        "version": "1.0.0"
      },
      "send_feature_flags": false,
      "timestamp": "2009-11-10T23:00:00Z",
      "type": "capture",
      "uuid": "00000000-0000-0000-0000-000000000000"
    }
  ]
}

func (Capture) APIfy

func (msg Capture) APIfy() APIMessage

func (Capture) Validate

func (msg Capture) Validate() error

type CaptureInApi

type CaptureInApi struct {
	Type           string    `json:"type"`
	Uuid           string    `json:"uuid"`
	Library        string    `json:"library"`
	LibraryVersion string    `json:"library_version"`
	Timestamp      time.Time `json:"timestamp"`

	DistinctId       string                `json:"distinct_id"`
	Event            string                `json:"event"`
	Properties       Properties            `json:"properties"`
	SendFeatureFlags SendFeatureFlagsValue `json:"send_feature_flags"`
}

type Client

type Client interface {
	io.Closer
	EnqueueClient

	// IsFeatureEnabled returns if a feature flag is on for a given user based on their distinct ID
	IsFeatureEnabled(FeatureFlagPayload) (interface{}, error)

	// GetFeatureFlag returns variant value if multivariant flag or otherwise a boolean indicating
	// if the given flag is on or off for the user
	GetFeatureFlag(FeatureFlagPayload) (interface{}, error)

	// GetFeatureFlagResult returns the flag value and payload together.
	// Use this instead of calling GetFeatureFlag and GetFeatureFlagPayload separately.
	// Returns an error if the flag cannot be evaluated (e.g., flag missing or cannot be computed
	// when using OnlyEvaluateLocally).
	GetFeatureFlagResult(FeatureFlagPayload) (*FeatureFlagResult, error)

	// GetFeatureFlagPayload returns feature flag's payload value matching key for user (supports multivariate flags).
	// Deprecated: Use GetFeatureFlagResult instead, which returns both
	// the flag value and payload while properly tracking feature flag usage.
	GetFeatureFlagPayload(FeatureFlagPayload) (string, error)

	// GetRemoteConfigPayload returns decrypted feature flag payload value for remote config flags.
	GetRemoteConfigPayload(string) (string, error)

	// GetAllFlags returns all flags for a user
	GetAllFlags(FeatureFlagPayloadNoKey) (map[string]interface{}, error)

	// ReloadFeatureFlags forces a reload of feature flags
	// NB: This is only available when using a PersonalApiKey
	ReloadFeatureFlags() error

	// GetFeatureFlags gets all feature flags, for testing only.
	// NB: This is only available when using a PersonalApiKey
	GetFeatureFlags() ([]FeatureFlag, error)

	// CloseWithContext gracefully shuts down the client with the provided context.
	// The context can be used to control the shutdown deadline.
	CloseWithContext(context.Context) error
}

Client interface is the main API exposed by the insights package. Values that satisfy this interface are returned by the client constructors provided by the package and provide a way to send messages via the HTTP API.

func New

func New(apiKey string) Client

Instantiate a new client that uses the write key passed as first argument to send messages to the backend. The client is created with the default configuration.

func NewWithConfig

func NewWithConfig(apiKey string, config Config) (cli Client, err error)

NewWithConfig instantiate a new client that uses the write key and configuration passed as arguments to send messages to the backend. The function will return an error if the configuration contained impossible values (like a negative flush interval for example). When the function returns an error the returned client will always be nil.

type CommonResponseFields

type CommonResponseFields struct {
	QuotaLimited              []string `json:"quota_limited"`
	RequestId                 string   `json:"requestId"`
	EvaluatedAt               *int64   `json:"evaluatedAt"`
	ErrorsWhileComputingFlags bool     `json:"errorsWhileComputingFlags"`
}

CommonResponseFields contains fields common to all flags response versions

type CompressionMode added in v1.12.0

type CompressionMode uint8

CompressionMode specifies the compression algorithm for batch payloads.

const (
	// CompressionNone disables compression (default).
	CompressionNone CompressionMode = 0
	// CompressionGzip enables GZIP compression for batch payloads.
	CompressionGzip CompressionMode = 1
)

type Config

type Config struct {

	// The endpoint to which the client connect and send their messages, set to
	// `DefaultEndpoint` by default.
	Endpoint string

	// Specifying a Personal API key will make feature flag evaluation more performant,
	// but it's not required for feature flags.  If you don't have a personal API key,
	// you can leave this field empty, and all of the relevant feature flag evaluation
	// methods will still work.
	// Information on how to get a personal API key: https://insights.hanzo.ai/docs/api/overview
	PersonalApiKey string

	// DisableGeoIP will disable GeoIP lookup for events and when fetching feature flags
	DisableGeoIP *bool

	// The flushing interval of the client. Messages will be sent when they've
	// been queued up to the maximum batch size or when the flushing interval
	// timer triggers. If zero, defaults to 5 seconds.
	Interval time.Duration

	// Interval at which to fetch new feature flag definitions, 5min by default
	DefaultFeatureFlagsPollingInterval time.Duration

	// Timeout for fetching feature flags, 3 seconds by default
	FeatureFlagRequestTimeout time.Duration

	// Calculate when feature flag definitions should be polled next. Setting this property
	// will override DefaultFeatureFlagsPollingInterval.
	NextFeatureFlagsPollingTick func() time.Duration

	// Flag to enable historical migration
	// See more in our migration docs: https://insights.hanzo.ai/docs/migrate
	HistoricalMigration bool

	// The HTTP transport used by the client, this allows an application to
	// redefine how requests are being sent at the HTTP level (for example,
	// to change the connection pooling policy).
	// If none is specified the client uses `http.DefaultTransport`.
	Transport http.RoundTripper

	// Logger used by the client to output info or error messages when that
	// are generated by background operations.
	// If none is specified the client uses a standard logger that outputs to
	// `os.Stderr`. Override this to suppress log messages.
	Logger Logger

	// Properties that will be included in every event sent by the client.
	// This is useful for adding common metadata like service name or app version across all events.
	// If a property conflict occurs, the value from DefaultEventProperties will overwrite any existing value.
	DefaultEventProperties Properties

	// The callback object that will be used by the client to notify the
	// application when messages sends to the backend API succeeded or failed.
	Callback Callback

	// The maximum number of messages that will be sent in one API call.
	// Messages will be sent when they've been queued up to the maximum batch
	// size or when the flushing interval timer triggers. If zero, defaults to 250.
	// Note that the API will still enforce a 500KB limit on each HTTP request
	// which is independent from the number of embedded messages.
	BatchSize int

	// When set to true the client will send more frequent and detailed messages
	// to its logger.
	Verbose bool

	// The retry policy used by the client to resend requests that have failed.
	// The function is called with how many times the operation has been retried
	// and is expected to return how long the client should wait before trying
	// again.
	// If not set the client will fallback to use a default retry policy.
	RetryAfter func(int) time.Duration

	// MaxRetries is the maximum number of times a request is retried on failure.
	// Must be in range [0,9]. If nil, defaults to 9 (10 total attempts).
	MaxRetries *int

	// ShutdownTimeout is the maximum time to wait for in-flight messages
	// to be sent during Close(). If zero or negative, waits indefinitely
	// (preserving backward-compatible behavior). Set to a positive duration
	// to enable timeout-based shutdown.
	ShutdownTimeout time.Duration

	// BatchUploadTimeout is the timeout for uploading batched events to the
	// /batch/ endpoint. If zero, defaults to 10 seconds.
	BatchUploadTimeout time.Duration

	// BatchSubmitTimeout is the maximum time to wait when submitting a batch
	// to the worker pool if the queue is full. This provides backpressure
	// smoothing during transient backend latency spikes, reducing data loss.
	// If zero, defaults to 100ms. Set to a negative value for non-blocking
	// behavior (immediate drop when queue is full).
	BatchSubmitTimeout time.Duration

	// MaxEnqueuedRequests is the maximum number of batches that can be queued
	// for sending. When the queue is full, new batches are dropped and the
	// failure callback is invoked. If zero, defaults to 1000.
	MaxEnqueuedRequests int

	// Compression specifies the compression mode for batch payloads.
	// When set to CompressionGzip, payloads are GZIP compressed before
	// sending, and appropriate headers/query params are added.
	// Defaults to CompressionNone (no compression).
	Compression CompressionMode
	// contains filtered or unexported fields
}

Config carries the different configuration options that may be set when instantiating a client.

Each field's zero-value is either meaningful or interpreted as using the default value defined by the library.

func (Config) GetDisableGeoIP

func (c Config) GetDisableGeoIP() bool

GetDisableGeoIP instructs the client to set $geoip_disable on event properties or feature flag requests. It is on by default as Go is mainly used on server side.

func (*Config) Validate

func (c *Config) Validate() error

Validate verifies that fields that don't have zero-values are set to valid values, returns an error describing the problem if a field was invalid.

type ConfigError

type ConfigError struct {

	// A human-readable message explaining why the configuration field's value
	// is invalid.
	Reason string

	// The name of the configuration field that was carrying an invalid value.
	Field string

	// The value of the configuration field that caused the error.
	Value interface{}
}

Returned by the `NewWithConfig` function when the one of the configuration fields was set to an impossible value (like a negative duration).

func (ConfigError) Error

func (e ConfigError) Error() string

type DecideRequestData

type DecideRequestData struct {
	ApiKey           string                `json:"api_key"`
	DistinctId       string                `json:"distinct_id"`
	Groups           Groups                `json:"groups"`
	PersonProperties Properties            `json:"person_properties"`
	GroupProperties  map[string]Properties `json:"group_properties"`
}

type DecideResponse

type DecideResponse struct {
	FeatureFlags        map[string]interface{}     `json:"featureFlags"`
	FeatureFlagPayloads map[string]json.RawMessage `json:"featureFlagPayloads"`
}

type DefaultStackTraceExtractor

type DefaultStackTraceExtractor struct {
	InAppDecider InAppDecider
}

DefaultStackTraceExtractor is provided by default as a sane / simple implementation of a StackTraceExtractor. It should be enough for most use cases, however, you're free to create your own implementation if you require more flexibility.

func (DefaultStackTraceExtractor) GetStackTrace

func (d DefaultStackTraceExtractor) GetStackTrace(skip int) *ExceptionStacktrace

type DescriptionExtractor

type DescriptionExtractor interface {
	ExtractDescription(r slog.Record) string
}

DescriptionExtractor defines the interface for extracting a human-readable description from a slog.Record for use in exception capture.

Implementations should always return a non-empty string; returning an empty string will prevent the error from being captured.

type EnqueueClient

type EnqueueClient interface {
	// Enqueue queues a message to be sent by the client when the conditions for a batch
	// upload are met.
	// This is the main method you'll be using, a typical flow would look like
	// this:
	//
	//	client := insights.New(apiKey)
	//	...
	//	client.Enqueue(insights.Capture{ ... })
	//	...
	//	client.Close()
	//
	// The method returns an error if the message queue could not be queued, which
	// happens if the client was already closed at the time the method was
	// called or if the message was malformed.
	Enqueue(Message) error
}

type ErrorExtractor

type ErrorExtractor struct {
	ErrorKeys []string
	Fallback  string
}

ErrorExtractor implements DescriptionExtractor by scanning a slog.Record for attributes containing an error.

ErrorKeys specifies the list of attribute keys (case-insensitive) to check. The first matching attribute with an error value is returned as the description. If no matching error is found, the Fallback is returned.

func (ErrorExtractor) ExtractDescription

func (e ErrorExtractor) ExtractDescription(r slog.Record) string

type Exception

type Exception struct {
	// This field is exported for serialization purposes and shouldn't be set by
	// the application, its value is always overwritten by the library.
	Type string
	// Uuid is optional. If not provided, a random UUID will be generated.
	Uuid string

	DistinctId   string
	Timestamp    time.Time
	DisableGeoIP bool

	// Typed properties that end up in the API "properties" object:
	ExceptionList        []ExceptionItem
	ExceptionFingerprint *string
}

func NewDefaultException

func NewDefaultException(
	timestamp time.Time,
	distinctID, title, description string,
) Exception

NewDefaultException is a convenience function to build an Exception object (usable for `client.Enqueue`) with sane defaults. If you want more control, please manually build the Exception object.

func (Exception) APIfy

func (msg Exception) APIfy() APIMessage

func (Exception) Validate

func (msg Exception) Validate() error

type ExceptionInApi

type ExceptionInApi struct {
	Type           string                   `json:"type"`
	Uuid           string                   `json:"uuid"`
	Library        string                   `json:"library"`
	LibraryVersion string                   `json:"library_version"`
	Timestamp      time.Time                `json:"timestamp"`
	Event          string                   `json:"event"`
	Properties     ExceptionInApiProperties `json:"properties"`
}

type ExceptionInApiProperties

type ExceptionInApiProperties struct {
	Lib                  string          `json:"$lib"`
	LibVersion           string          `json:"$lib_version"`
	DistinctId           string          `json:"distinct_id"`
	DisableGeoIP         bool            `json:"$geoip_disable,omitempty"`
	ExceptionList        []ExceptionItem `json:"$exception_list"`
	ExceptionFingerprint *string         `json:"$exception_fingerprint,omitempty"`
}

type ExceptionItem

type ExceptionItem struct {
	// Type will be rendered as title in the UI
	Type string `json:"type"`
	// Value will be rendered as description in the UI
	Value     string              `json:"value"`
	Mechanism *ExceptionMechanism `json:"mechanism,omitempty"`
	// Stacktrace can conveniently be generated through the use of StackTraceExtractor
	Stacktrace *ExceptionStacktrace `json:"stacktrace,omitempty"`
}

func (ExceptionItem) Validate

func (msg ExceptionItem) Validate() error

type ExceptionMechanism

type ExceptionMechanism struct {
	Handled   *bool `json:"handled,omitempty"`
	Synthetic *bool `json:"synthetic,omitempty"`
}

type ExceptionStacktrace

type ExceptionStacktrace struct {
	Type   string       `json:"type"`
	Frames []StackFrame `json:"frames"`
}

type FeatureFlag

type FeatureFlag struct {
	Key                        string   `json:"key"`
	RolloutPercentage          *float64 `json:"rollout_percentage"`
	Active                     bool     `json:"active"`
	Filters                    Filter   `json:"filters"`
	EnsureExperienceContinuity *bool    `json:"ensure_experience_continuity"`
	BucketingIdentifier        *string  `json:"bucketing_identifier"`
}

type FeatureFlagCondition

type FeatureFlagCondition struct {
	Properties        []FlagProperty `json:"properties"`
	RolloutPercentage *float64       `json:"rollout_percentage"`
	Variant           *string        `json:"variant"`
}

type FeatureFlagPayload

type FeatureFlagPayload struct {
	Key                   string
	DistinctId            string
	DeviceId              *string
	Groups                Groups
	PersonProperties      Properties
	GroupProperties       map[string]Properties
	OnlyEvaluateLocally   bool
	SendFeatureFlagEvents *bool
}

type FeatureFlagPayloadNoKey

type FeatureFlagPayloadNoKey struct {
	DistinctId            string
	DeviceId              *string
	Groups                Groups
	PersonProperties      Properties
	GroupProperties       map[string]Properties
	OnlyEvaluateLocally   bool
	SendFeatureFlagEvents *bool
}

type FeatureFlagResult

type FeatureFlagResult struct {
	// Key is the feature flag key that was evaluated
	Key string

	// Enabled indicates whether the feature flag evaluation determined
	// the flag to be in an enabled state.
	Enabled bool

	// RawPayload is the serialized JSON payload associated with the flag variant.
	// Nil if no payload is configured.
	// Use GetPayloadAs to unmarshal the payload into a specific type.
	RawPayload *string

	// Variant is the variant key if this is a multivariate flag.
	// Nil for boolean flags.
	Variant *string
}

FeatureFlagResult represents the result of a feature flag evaluation, containing both the flag value and its payload.

func (*FeatureFlagResult) GetPayloadAs added in v1.12.0

func (r *FeatureFlagResult) GetPayloadAs(v interface{}) error

GetPayloadAs unmarshals the JSON payload into the provided type. Returns an error if the payload is empty or cannot be unmarshaled.

type FeatureFlagsPoller

type FeatureFlagsPoller struct {
	Logger   Logger
	Endpoint string
	// contains filtered or unexported fields
}

func (*FeatureFlagsPoller) ForceReload

func (poller *FeatureFlagsPoller) ForceReload()

func (*FeatureFlagsPoller) GetAllFlags

func (poller *FeatureFlagsPoller) GetAllFlags(flagConfig FeatureFlagPayloadNoKey) (map[string]interface{}, error)

func (*FeatureFlagsPoller) GetFeatureFlag

func (poller *FeatureFlagsPoller) GetFeatureFlag(flagConfig FeatureFlagPayload) (interface{}, error)

func (*FeatureFlagsPoller) GetFeatureFlagPayload

func (poller *FeatureFlagsPoller) GetFeatureFlagPayload(flagConfig FeatureFlagPayload) (string, error)

func (*FeatureFlagsPoller) GetFeatureFlags

func (poller *FeatureFlagsPoller) GetFeatureFlags() ([]FeatureFlag, error)

type FeatureFlagsResponse

type FeatureFlagsResponse struct {
	Flags            []FeatureFlag            `json:"flags"`
	GroupTypeMapping *map[string]string       `json:"group_type_mapping"`
	Cohorts          map[string]PropertyGroup `json:"cohorts"`
}

type FieldError

type FieldError struct {

	// The human-readable representation of the type of structure that wasn't
	// initialized properly.
	Type string

	// The name of the field that wasn't properly initialized.
	Name string

	// The value of the field that wasn't properly initialized.
	Value interface{}
}

Instances of this type are used to represent errors returned when a field was no initialize properly in a structure passed as argument to one of the functions of this package.

func (FieldError) Error

func (e FieldError) Error() string

type Filter

type Filter struct {
	AggregationGroupTypeIndex *uint8                     `json:"aggregation_group_type_index"`
	Groups                    []FeatureFlagCondition     `json:"groups"`
	Multivariate              *Variants                  `json:"multivariate"`
	Payloads                  map[string]json.RawMessage `json:"payloads"`
}

type FlagDetail

type FlagDetail struct {
	Key      string       `json:"key"`
	Enabled  bool         `json:"enabled"`
	Variant  *string      `json:"variant"`
	Reason   *FlagReason  `json:"reason"`
	Metadata FlagMetadata `json:"metadata"`
	Failed   *bool        `json:"failed,omitempty"`
}

FlagDetail represents a feature flag in v4 format

func NewFlagDetail

func NewFlagDetail(key string, value interface{}, payload json.RawMessage) FlagDetail

NewFlagDetail creates a new FlagDetail from a key, value, and optional payload

func (FlagDetail) GetValue

func (f FlagDetail) GetValue() interface{}

GetValue returns the variant if it exists, otherwise returns the enabled status

type FlagMetadata

type FlagMetadata struct {
	ID          int             `json:"id"`
	Version     int             `json:"version"`
	Payload     json.RawMessage `json:"payload"`
	Description *string         `json:"description,omitempty"`
}

FlagMetadata contains additional information about a flag

type FlagProperty

type FlagProperty struct {
	Key             string      `json:"key"`
	Operator        string      `json:"operator"`
	Value           interface{} `json:"value"`
	Type            string      `json:"type"` // Supported types: "person", "group", "cohort", "flag"
	Negation        bool        `json:"negation"`
	DependencyChain []string    `json:"dependency_chain"` // For flag dependencies
}

type FlagReason

type FlagReason struct {
	Code           string `json:"code"`
	Description    string `json:"description"`
	ConditionIndex *int   `json:"condition_index"`
}

FlagReason represents why a flag was enabled/disabled

type FlagVariant

type FlagVariant struct {
	Key               string   `json:"key"`
	Name              string   `json:"name"`
	RolloutPercentage *float64 `json:"rollout_percentage"`
}

type FlagVariantMeta

type FlagVariantMeta struct {
	ValueMin float64
	ValueMax float64
	Key      string
}

type FlagsRequestData

type FlagsRequestData struct {
	ApiKey           string                `json:"api_key"`
	DistinctId       string                `json:"distinct_id"`
	DeviceId         *string               `json:"device_id,omitempty"`
	Groups           Groups                `json:"groups"`
	PersonProperties Properties            `json:"person_properties"`
	GroupProperties  map[string]Properties `json:"group_properties"`
	DisableGeoIP     bool                  `json:"geoip_disable,omitempty"`
}

type FlagsResponse

type FlagsResponse struct {
	CommonResponseFields

	// v4 flags format
	Flags map[string]FlagDetail `json:"flags,omitempty"`

	// v3 legacy fields
	FeatureFlags        map[string]interface{}     `json:"featureFlags"`
	FeatureFlagPayloads map[string]json.RawMessage `json:"featureFlagPayloads"`
}

FlagsResponse represents the response from the flags endpoint v1 or v2. It is a normalized super set of the v1 and v2 formats.

func (*FlagsResponse) UnmarshalJSON

func (r *FlagsResponse) UnmarshalJSON(data []byte) error

UnmarshalJSON implements custom unmarshaling to handle both v3 and v4 formats

type GroupIdentify

type GroupIdentify struct {
	Type string
	Key  string
	// Uuid is optional. If not provided, a random UUID will be generated.
	Uuid string

	DistinctId   string
	Timestamp    time.Time
	Properties   Properties
	DisableGeoIP bool
}

func (GroupIdentify) APIfy

func (msg GroupIdentify) APIfy() APIMessage

func (GroupIdentify) Validate

func (msg GroupIdentify) Validate() error

type GroupIdentifyInApi

type GroupIdentifyInApi struct {
	Uuid           string    `json:"uuid"`
	Library        string    `json:"library"`
	LibraryVersion string    `json:"library_version"`
	Timestamp      time.Time `json:"timestamp"`

	Event      string     `json:"event"`
	DistinctId string     `json:"distinct_id"`
	Properties Properties `json:"properties"`
}

type Groups

type Groups map[string]interface{}

Groups is used to represent groups in messages that support it. It is a free-form object so the application can set any value it sees fit but a few helper methods are defined to make it easier to instantiate groups with common fields.

func NewGroups

func NewGroups() Groups

func (Groups) Set

func (p Groups) Set(name string, value interface{}) Groups

type Identify

type Identify struct {
	// This field is exported for serialization purposes and shouldn't be set by
	// the application, its value is always overwritten by the library.
	Type string
	// Uuid is optional. If not provided, a random UUID will be generated.
	Uuid string

	DistinctId   string
	Timestamp    time.Time
	Properties   Properties
	DisableGeoIP bool
}

This type represents object sent in an identify call

func (Identify) APIfy

func (msg Identify) APIfy() APIMessage

func (Identify) Validate

func (msg Identify) Validate() error

type IdentifyInApi

type IdentifyInApi struct {
	Type           string    `json:"type"`
	Uuid           string    `json:"uuid"`
	Library        string    `json:"library"`
	LibraryVersion string    `json:"library_version"`
	Timestamp      time.Time `json:"timestamp"`

	Event      string     `json:"event"`
	DistinctId string     `json:"distinct_id"`
	Properties Properties `json:"properties"`
	Set        Properties `json:"$set"`
}

type InAppDecider

type InAppDecider func(frame runtime.Frame) bool

InAppDecider reports whether a stack frame should be considered “in-app” (i.e., part of the calling application’s own code) as opposed to external dependencies, standard library, or tooling internals. The UI can use this signal to visually emphasize frames that are likely actionable.

type InconclusiveMatchError

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

func (*InconclusiveMatchError) Error

func (e *InconclusiveMatchError) Error() string

type Insights added in v1.12.0

type Insights = Client

Insights is an alias for Client, provided for convenience. Both insights.Insights and insights.Client refer to the same interface.

func NewInsights added in v1.12.0

func NewInsights(apiKey string) Insights

NewInsights creates a new Insights client. Equivalent to New.

func NewInsightsWithConfig added in v1.12.0

func NewInsightsWithConfig(apiKey string, config InsightsConfig) (Insights, error)

NewInsightsWithConfig creates a new Insights client with config. Equivalent to NewWithConfig.

type InsightsConfig added in v1.12.0

type InsightsConfig = Config

InsightsConfig is an alias for Config, provided for convenience.

type Logger

type Logger interface {
	// Debugf is called by the Insights client to log debug messages about the
	// operations it performs. Messages logged by this method are usually
	// tagged with a `DEBUG` log level in common logging libraries.
	Debugf(format string, args ...interface{})

	// Logf is called by the Insights client to log regular messages about the
	// operations it performs. Messages logged by this method are usually
	// tagged with an `INFO` log level in common logging libraries.
	Logf(format string, args ...interface{})

	// Warnf is called by the Insights client to log warning messages about
	// the operations it performs. Messages logged by this method are usually
	// tagged with a `WARN` log level in common logging libraries.
	Warnf(format string, args ...interface{})

	// Errorf is called by the Insights client to log errors encountered
	// while sending events to the backend servers.
	// Messages logged by this method are usually tagged with an `ERROR` log
	// level in common logging libraries.
	Errorf(format string, args ...interface{})
}

Logger defines an interface for a logger used by the Insights client.

func StdLogger

func StdLogger(logger *log.Logger, verbose bool) Logger

StdLogger creates an object that satisfies the insights.Logger interface and sends logs to the standard logger passed as argument.

type Message

type Message interface {

	// Validate validates the internal structure of the message, the method must return
	// nil if the message is valid, or an error describing what went wrong.
	Validate() error
	APIfy() APIMessage
	// contains filtered or unexported methods
}

This interface is used to represent insights objects that can be sent via a client.

Types like insights.Capture, insights.Alias, etc... implement this interface and therefore can be passed to the insights.Client.Enqueue method.

type Properties

type Properties map[string]interface{}

Properties is used to represent properties in messages that support it. It is a free-form object so the application can set any value it sees fit but a few helper method are defined to make it easier to instantiate properties with common fields. Here's a quick example of how this type is meant to be used:

insights.Capture{
	DistinctId: "0123456789",
	Properties: insights.NewProperties().
		Set("revenue", 10.0).
		Set("currency", "USD"),
}

func NewProperties

func NewProperties() Properties

func (Properties) Merge

func (p Properties) Merge(props Properties) Properties

Merge adds the properties from the provided `props` into the receiver `p`. If a property in `props` already exists in `p`, its value will be overwritten.

func (Properties) Set

func (p Properties) Set(name string, value interface{}) Properties

type PropertyGroup

type PropertyGroup struct {
	Type string `json:"type"`
	// []PropertyGroup or []FlagProperty
	Values []any `json:"values"`
}

type RequiresServerEvaluationError

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

RequiresServerEvaluationError is returned when feature flag evaluation requires server-side data that is not available locally (e.g., static cohorts, experience continuity). This error should propagate immediately to trigger API fallback, unlike InconclusiveMatchError which allows trying other conditions.

func (*RequiresServerEvaluationError) Error

type SendFeatureFlagsBool

type SendFeatureFlagsBool bool

SendFeatureFlagsBool wraps a boolean value to implement SendFeatureFlagsValue

func (SendFeatureFlagsBool) GetOptions

func (SendFeatureFlagsBool) ShouldSend

func (b SendFeatureFlagsBool) ShouldSend() bool

Implement SendFeatureFlagsValue interface for SendFeatureFlagsBool

type SendFeatureFlagsOptions

type SendFeatureFlagsOptions struct {
	// OnlyEvaluateLocally forces evaluation to only use local flags and never make API requests
	OnlyEvaluateLocally bool
	// DeviceId provides a device_id for remote flag evaluation requests
	DeviceId *string
	// PersonProperties provides explicit person properties for local flag evaluation
	PersonProperties Properties
	// GroupProperties provides explicit group properties for local flag evaluation
	GroupProperties map[string]Properties
}

SendFeatureFlagsOptions allows for more granular control over feature flag evaluation

func (*SendFeatureFlagsOptions) GetOptions

func (*SendFeatureFlagsOptions) ShouldSend

func (opts *SendFeatureFlagsOptions) ShouldSend() bool

Implement SendFeatureFlagsValue interface for SendFeatureFlagsOptions

type SendFeatureFlagsValue

type SendFeatureFlagsValue interface {
	ShouldSend() bool
	GetOptions() *SendFeatureFlagsOptions
}

SendFeatureFlagsValue defines the interface for feature flag configuration

func SendFeatureFlags

func SendFeatureFlags(enabled bool) SendFeatureFlagsValue

Constructor functions for easier usage

func SendFeatureFlagsWithOptions

func SendFeatureFlagsWithOptions(opts *SendFeatureFlagsOptions) SendFeatureFlagsValue

type SlogCaptureHandler

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

SlogCaptureHandler wraps a slog.Handler and mirrors qualifying records to Insights error tracking using client.Enqueue(Exception{...}).

func NewSlogCaptureHandler

func NewSlogCaptureHandler(next slog.Handler, client EnqueueClient, opts ...SlogOption) *SlogCaptureHandler

NewSlogCaptureHandler creates a new log handler wrapper. You typically wrap your existing handler:

client, err := insights.NewWithConfig(...)
// error handling and `defer client.Close()` call
base := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})
logger := slog.New(insights.NewSlogCaptureHandler(base, client,
  insights.WithDistinctIDFn(func(ctx context.Context, r slog.Record) string {
    return "my-user-id" // or pull from ctx
  }),
))

func (*SlogCaptureHandler) Enabled

func (h *SlogCaptureHandler) Enabled(ctx context.Context, level slog.Level) bool

func (*SlogCaptureHandler) Handle

func (h *SlogCaptureHandler) Handle(ctx context.Context, r slog.Record) error

func (*SlogCaptureHandler) WithAttrs

func (h *SlogCaptureHandler) WithAttrs(attrs []slog.Attr) slog.Handler

func (*SlogCaptureHandler) WithGroup

func (h *SlogCaptureHandler) WithGroup(name string) slog.Handler

type SlogOption

type SlogOption func(*captureConfig)

func WithDescriptionExtractor

func WithDescriptionExtractor(extractor DescriptionExtractor) SlogOption

func WithDistinctIDFn

func WithDistinctIDFn(fn func(ctx context.Context, r slog.Record) string) SlogOption

func WithFingerprintFn

func WithFingerprintFn(fn func(ctx context.Context, r slog.Record) *string) SlogOption

func WithMinCaptureLevel

func WithMinCaptureLevel(l slog.Level) SlogOption

func WithSkip

func WithSkip(n int) SlogOption

func WithStackTraceExtractor

func WithStackTraceExtractor(extractor StackTraceExtractor) SlogOption

type StackFrame

type StackFrame struct {
	Filename  string `json:"filename"`
	LineNo    int    `json:"lineno"`
	Function  string `json:"function"`
	InApp     bool   `json:"in_app"`
	Synthetic bool   `json:"synthetic"`
	Platform  string `json:"platform"`
}

StackFrame represents a single "Frame" within a stack trace.

type StackTraceExtractor

type StackTraceExtractor interface {
	// GetStackTrace returns an Insights-compatible stack trace.
	//
	// The skip parameter controls how many leading frames to omit before
	// recording. Use it to drop extractor/logging internals and start at the
	// application call site. For example, a skip of 3–5 is typically enough to
	// hide wrapper layers when called from a slog handler.
	GetStackTrace(skip int) *ExceptionStacktrace
}

StackTraceExtractor produces a stack trace for the current goroutine to enrich captured exceptions with call-site context.

type Ticker

type Ticker struct {
	C <-chan time.Time
	// contains filtered or unexported fields
}

func (*Ticker) Stop

func (t *Ticker) Stop()

type Variants

type Variants struct {
	Variants []FlagVariant `json:"variants"`
}

Directories

Path Synopsis
cmd
cli command

Jump to

Keyboard shortcuts

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