mirror of
https://github.com/hanzoai/insights-go.git
synced 2026-09-30 22:46:12 +00:00
* intitial refactor: - Add Context-based graceful shutdown and drain phase for enqueued requests - Use buffered channels vs. mutex for concurrency mgmt. - Use atomic.Pointer vs. locks for FF mgmt - Use Callback ifc vs. lossy internal tracking for unit test result validation - Add new APIs mirroring current that accept caller's Context to control operation timeouts * expose batch submission timeout with default equiv to old hardcoded timeout * restructure event submission and batching pipeline * overhaul tests; implement new stress tests and address coverage gaps * parallelize tests where safe to do so (3x CI time savings!) * introduce faster pure Go JSON seralization library * more refactors: unit tests & benchmarks * DRY up shutdown req drain and prepareForSend serializer * use go-json in CLI utils too; remove redundant helpers * move error type to proper pkg * DRY up loop() and fix deadlock in old test case * normalize CI and Makefile test and benchmark target behavviors * more realistic feature flags benchmark * replace leaky time.After pattern with idiomatic safer Timers * internal queue size minimums decoupled from batch and worker configs * remove dead comments * fix test bug * update default http.Transport cfg to avoid conn pool as bottleneck; update batch enqueue limiting strategy and tests/benches * adjust stress test defaults to match prod * update flaky tests and rm stale file * make graceful shutdown timeout opt-in for now * fix tests that reverted to hold helper utils during rebase * fix flaky test due to overhead from -race detector now default in test flags * add more graceful shutdown test cases
158 lines
4.3 KiB
Go
158 lines
4.3 KiB
Go
package posthog
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
var _ Message = (*Exception)(nil)
|
|
|
|
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
|
|
|
|
DistinctId string
|
|
Timestamp time.Time
|
|
DisableGeoIP bool
|
|
|
|
// Typed properties that end up in the API "properties" object:
|
|
ExceptionList []ExceptionItem
|
|
ExceptionFingerprint *string
|
|
}
|
|
|
|
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"`
|
|
}
|
|
|
|
type ExceptionMechanism struct {
|
|
Handled *bool `json:"handled,omitempty"`
|
|
Synthetic *bool `json:"synthetic,omitempty"`
|
|
}
|
|
|
|
type ExceptionStacktrace struct {
|
|
Type string `json:"type"`
|
|
Frames []StackFrame `json:"frames"`
|
|
}
|
|
|
|
// StackFrame represents a single "Frame" within a stack trace.
|
|
// Documentation about the available fields can be found here:
|
|
// https://github.com/PostHog/posthog/blob/39b9326320c23acbdc6e96a8beb41b30d3c99099/rust/cymbal/src/langs/go.rs#L7
|
|
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"`
|
|
}
|
|
|
|
type ExceptionInApi struct {
|
|
Type string `json:"type"`
|
|
Library string `json:"library"`
|
|
LibraryVersion string `json:"library_version"`
|
|
Timestamp time.Time `json:"timestamp"`
|
|
Event string `json:"event"`
|
|
Properties ExceptionInApiProperties `json:"properties"`
|
|
}
|
|
|
|
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"`
|
|
}
|
|
|
|
func (msg Exception) internal() { panic(unimplementedError) }
|
|
|
|
func (msg Exception) Validate() error {
|
|
if len(msg.DistinctId) == 0 {
|
|
return FieldError{
|
|
Type: "posthog.Exception",
|
|
Name: "DistinctId",
|
|
Value: msg.DistinctId,
|
|
}
|
|
}
|
|
if len(msg.ExceptionList) == 0 {
|
|
return FieldError{
|
|
Type: "posthog.Exception",
|
|
Name: "ExceptionList",
|
|
Value: []ExceptionItem{},
|
|
}
|
|
}
|
|
for _, item := range msg.ExceptionList {
|
|
if err := item.Validate(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (msg ExceptionItem) Validate() error {
|
|
if msg.Type == "" {
|
|
return FieldError{
|
|
Type: "posthog.Exception",
|
|
Name: "Type",
|
|
Value: msg.Type,
|
|
}
|
|
}
|
|
if msg.Value == "" {
|
|
return FieldError{
|
|
Type: "posthog.Exception",
|
|
Name: "Value",
|
|
Value: msg.Value,
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (msg Exception) APIfy() APIMessage {
|
|
libVersion := getVersion()
|
|
|
|
return ExceptionInApi{
|
|
Type: msg.Type, // set to "exception" by Enqueue switch
|
|
Event: "$exception",
|
|
Library: SDKName,
|
|
LibraryVersion: libVersion,
|
|
Timestamp: msg.Timestamp,
|
|
Properties: ExceptionInApiProperties{
|
|
Lib: SDKName,
|
|
LibVersion: libVersion,
|
|
DistinctId: msg.DistinctId,
|
|
DisableGeoIP: msg.DisableGeoIP,
|
|
ExceptionList: msg.ExceptionList,
|
|
ExceptionFingerprint: msg.ExceptionFingerprint,
|
|
},
|
|
}
|
|
}
|
|
|
|
// 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 NewDefaultException(
|
|
timestamp time.Time,
|
|
distinctID, title, description string,
|
|
) Exception {
|
|
defaultStackTrace := DefaultStackTraceExtractor{InAppDecider: SimpleInAppDecider}
|
|
|
|
return Exception{
|
|
DistinctId: distinctID,
|
|
Timestamp: timestamp,
|
|
ExceptionList: []ExceptionItem{
|
|
{
|
|
Type: title,
|
|
Value: description,
|
|
Stacktrace: defaultStackTrace.GetStackTrace(3),
|
|
},
|
|
},
|
|
}
|
|
}
|