Files
PandeyandGitHub 070c294f33 refactor(ledger): extract domain primitives and centralize tracking (#113)
## Summary

- Extract \`DistinctID\`, \`Event\`, and \`Properties\` value objects
from \`internal/ledger\` into \`internal/domain\` so they can be reused
without coupling callers to ledger orchestration. Move the analytics
serializer to \`api/v1alpha1\` as \`Casting.TrackableProperties()\`.
Tighten \`Ledger.Track\` to take \`domain.Event\` and
\`domain.Properties\`.
- Add \`cmd/foundryctl/root.go\` with shared
\`rootLogger\`/\`rootTracker\` initialized via \`PersistentPreRunE\`,
plus \`recoverRunE\` — a wrapper that converts panics to \`TypeFatal\`
errors and centralizes log + ledger tracking of success/failure for
every command. Each \`runX\` collapses to \`(domain.Properties, error)\`
with no in-function tracking.
- Add \`WithStacktrace\` on \`*base\` errors so the recovered panic
stack flows through the existing \`LogAttr\` machinery.
2026-05-04 23:36:04 +05:30

58 lines
1.4 KiB
Go

package segmentledger
import (
"context"
"fmt"
"runtime"
segment "github.com/segmentio/analytics-go/v3"
"github.com/signoz/foundry/internal/domain"
"github.com/signoz/foundry/internal/ledger"
"github.com/signoz/foundry/internal/ledger/noopledger"
"github.com/signoz/foundry/internal/version"
)
// provider implements ledger.Ledger using Segment.
type provider struct {
client segment.Client
}
// New creates a new Segment ledger provider.
// Returns a noop provider if the write key is not set.
func New(config ledger.Config) ledger.Ledger {
if config.Segment.Key == "" || config.Segment.Key == "<unset>" {
return noopledger.New()
}
client, err := segment.NewWithConfig(config.Segment.Key, segment.Config{})
if err != nil {
return noopledger.New()
}
return &provider{
client: client,
}
}
func (p *provider) Track(_ context.Context, event domain.Event, properties domain.Properties) {
properties = properties.
Set("os", runtime.GOOS).
Set("arch", runtime.GOARCH).
Set("foundry_version", version.Info.Version())
props := segment.NewProperties()
for k, v := range properties.Map() {
props.Set(k, v)
}
_ = p.client.Enqueue(segment.Track{
AnonymousId: domain.MustNewDistinctID().String(),
Event: fmt.Sprintf("foundryctl: %s", event.String()),
Properties: props,
})
}
func (p *provider) Close() error {
return p.client.Close()
}