client

package
v1.7.29 Latest Latest
Warning

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

Go to latest
Published: Jun 4, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package client is the HTTP client and types for talking to a Traceway instance.

This package has no dependencies on Cobra, Viper, or any CLI machinery so that a future MCP server can import it directly.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrUnauthorized = errors.New("unauthorized (401)")
	ErrForbidden    = errors.New("forbidden (403)")
	ErrNotFound     = errors.New("not found (404)")
	ErrRateLimited  = errors.New("rate limited (429)")
)

Sentinel errors returned by client methods. Use errors.Is to test.

Functions

This section is empty.

Types

type APIError

type APIError struct {
	StatusCode int
	Body       string
}

APIError is returned for any non-2xx response that isn't covered by a sentinel. Inspect StatusCode and Body for diagnostics.

func (*APIError) Error

func (e *APIError) Error() string

type Client

type Client struct {
	BaseURL    string
	HTTPClient *http.Client
	JWT        string
	UserAgent  string
}

Client talks to a Traceway HTTP API.

func New

func New(baseURL string, opts ...Option) *Client

New returns a Client with sane defaults. The baseURL is normalized by stripping trailing slashes; do() prepends "/api/..." paths.

func (*Client) ArchiveExceptions

func (c *Client) ArchiveExceptions(ctx context.Context, projectID string, hashes []string) error

ArchiveExceptions marks the given exception hashes as archived for the project. The upstream response is just {"success": true}; on success this returns nil and the caller can report the count back to the user.

func (*Client) GetException

func (c *Client) GetException(ctx context.Context, projectID, hash string, page PaginationParams) (*GetExceptionResponse, error)

GetException returns the group + paginated occurrences for the given hash.

func (*Client) ListEndpoints

func (c *Client) ListEndpoints(ctx context.Context, projectID string, req ListEndpointsRequest) (*ListEndpointsResponse, error)

ListEndpoints returns p50/p95/p99 stats grouped by endpoint route. We use the /grouped variant rather than the bare /endpoints (which returns one row per request).

func (*Client) ListExceptions

func (c *Client) ListExceptions(ctx context.Context, projectID string, req ListExceptionsRequest) (*ListExceptionsResponse, error)

ListExceptions returns one page of grouped exceptions for the given project.

func (*Client) ListProjects

func (c *Client) ListProjects(ctx context.Context) ([]Project, error)

ListProjects returns all projects visible to the authenticated user. Upstream: GET /api/projects → []Project (direct array, no pagination wrapper).

func (*Client) Login

func (c *Client) Login(ctx context.Context, email, password string) (string, error)

Login exchanges an email + password for a JWT. The returned token should be stored by the caller and passed to subsequent Client constructions via WithJWT.

func (*Client) QueryLogs

func (c *Client) QueryLogs(ctx context.Context, projectID string, req QueryLogsRequest) (*QueryLogsResponse, error)

QueryLogs returns one page of log records for the given project and filters.

func (*Client) QueryMetrics

func (c *Client) QueryMetrics(ctx context.Context, projectID string, req QueryMetricsRequest) (*QueryMetricsResponse, error)

QueryMetrics runs one or more metric queries against the project.

func (*Client) UnarchiveExceptions

func (c *Client) UnarchiveExceptions(ctx context.Context, projectID string, hashes []string) error

UnarchiveExceptions reverses ArchiveExceptions for the given hashes.

type EndpointStats

type EndpointStats struct {
	Endpoint     string        `json:"endpoint"`
	Count        uint64        `json:"count"`
	P50Duration  time.Duration `json:"p50Duration"`
	P95Duration  time.Duration `json:"p95Duration"`
	P99Duration  time.Duration `json:"p99Duration"`
	AvgDuration  time.Duration `json:"avgDuration"`
	LastSeen     time.Time     `json:"lastSeen"`
	Impact       float64       `json:"impact"`
	ImpactReason string        `json:"impactReason"`
}

EndpointStats matches the upstream models.EndpointStats. Durations are time.Duration values which Go marshals/unmarshals as nanoseconds.

type ExceptionGroup

type ExceptionGroup struct {
	ExceptionHash string                `json:"exceptionHash"`
	StackTrace    string                `json:"stackTrace"`
	FirstSeen     time.Time             `json:"firstSeen"`
	LastSeen      time.Time             `json:"lastSeen"`
	Count         uint64                `json:"count"`
	HourlyTrend   []ExceptionTrendPoint `json:"hourlyTrend,omitempty"`
}

ExceptionGroup matches Traceway's models.ExceptionGroup. Hourly trends are only present on list responses; on the detail endpoint they're absent.

type ExceptionStackTrace

type ExceptionStackTrace struct {
	Id                 uuid.UUID         `json:"id"`
	ExceptionHash      string            `json:"exceptionHash"`
	StackTrace         string            `json:"stackTrace"`
	RecordedAt         time.Time         `json:"recordedAt"`
	TraceId            *uuid.UUID        `json:"traceId,omitempty"`
	TraceType          string            `json:"traceType,omitempty"`
	ServerName         string            `json:"serverName,omitempty"`
	AppVersion         string            `json:"appVersion,omitempty"`
	IsMessage          bool              `json:"isMessage,omitempty"`
	Attributes         map[string]string `json:"attributes,omitempty"`
	DistributedTraceId *uuid.UUID        `json:"distributedTraceId,omitempty"`
	SessionId          *uuid.UUID        `json:"sessionId,omitempty"`
}

ExceptionStackTrace is one occurrence of a grouped exception.

type ExceptionTrendPoint

type ExceptionTrendPoint struct {
	Timestamp time.Time `json:"timestamp"`
	Count     uint64    `json:"count"`
}

ExceptionTrendPoint is one entry in an exception's hourly trend.

type GetExceptionResponse

type GetExceptionResponse struct {
	Group       *ExceptionGroup       `json:"group"`
	Occurrences []ExceptionStackTrace `json:"occurrences"`
	Pagination  Pagination            `json:"pagination"`
}

GetExceptionResponse is the upstream ExceptionDetailResponse minus the session-recording blob (we don't expose recordings in v1).

type ListEndpointsRequest

type ListEndpointsRequest struct {
	TimeRange     TimeRange        `json:"-"`
	Pagination    PaginationParams `json:"pagination"`
	OrderBy       string           `json:"orderBy,omitempty"`
	SortDirection string           `json:"sortDirection,omitempty"`
	Search        string           `json:"search,omitempty"`
}

ListEndpointsRequest is the body for POST /api/endpoints/grouped.

func (ListEndpointsRequest) MarshalJSON

func (r ListEndpointsRequest) MarshalJSON() ([]byte, error)

MarshalJSON expands TimeRange into top-level fromDate/toDate.

type ListEndpointsResponse

type ListEndpointsResponse struct {
	Data       []EndpointStats `json:"data"`
	Pagination Pagination      `json:"pagination"`
}

ListEndpointsResponse mirrors PaginatedResponse[EndpointStats].

type ListExceptionsRequest

type ListExceptionsRequest struct {
	TimeRange       TimeRange        `json:"-"` // serialized as fromDate/toDate via MarshalJSON
	Pagination      PaginationParams `json:"pagination"`
	OrderBy         string           `json:"orderBy,omitempty"`
	Search          string           `json:"search,omitempty"`
	SearchType      string           `json:"searchType,omitempty"`
	IncludeArchived bool             `json:"includeArchived,omitempty"`
}

ListExceptionsRequest is the body for POST /api/exception-stack-traces. projectId travels as a URL query param (handled by ListExceptions), not in the body — the upstream RequireProjectAccess middleware reads it via c.Query("projectId").

func (ListExceptionsRequest) MarshalJSON

func (r ListExceptionsRequest) MarshalJSON() ([]byte, error)

MarshalJSON expands TimeRange.From / TimeRange.To into top-level fromDate / toDate so the wire shape matches Traceway's ExceptionSearchRequest.

type ListExceptionsResponse

type ListExceptionsResponse struct {
	Data       []ExceptionGroup `json:"data"`
	Pagination Pagination       `json:"pagination"`
}

ListExceptionsResponse mirrors the upstream PaginatedResponse[ExceptionGroup].

type LogRecord

type LogRecord struct {
	Id                 uuid.UUID         `json:"id"`
	Timestamp          time.Time         `json:"timestamp"`
	SeverityText       string            `json:"severityText"`
	SeverityNumber     uint8             `json:"severityNumber"`
	ServiceName        string            `json:"serviceName"`
	Body               string            `json:"body"`
	TraceId            string            `json:"traceId,omitempty"`
	SpanId             string            `json:"spanId,omitempty"`
	ResourceAttributes map[string]string `json:"resourceAttributes,omitempty"`
	ScopeName          string            `json:"scopeName,omitempty"`
	LogAttributes      map[string]string `json:"logAttributes,omitempty"`
}

LogRecord matches the upstream models.LogRecord (subset — we drop fields we don't surface in v1, like resource/scope schema URLs).

type MetricQueryItem

type MetricQueryItem struct {
	Name        string            `json:"name"`
	Aggregation string            `json:"aggregation,omitempty"`
	TagFilters  map[string]string `json:"tagFilters,omitempty"`
	GroupBy     string            `json:"groupBy,omitempty"`
}

MetricQueryItem is one query within a QueryMetricsRequest.

type MetricQueryResult

type MetricQueryResult struct {
	Name   string                       `json:"name"`
	Unit   string                       `json:"unit"`
	Series map[string][]TimeSeriesPoint `json:"series"`
}

MetricQueryResult is one query's results, optionally grouped by tag. The map key is the group label ("all" if no GroupBy was specified).

type Option

type Option func(*Client)

Option mutates a Client during construction.

func WithHTTPClient

func WithHTTPClient(h *http.Client) Option

WithHTTPClient injects a custom *http.Client (useful for tests).

func WithJWT

func WithJWT(jwt string) Option

WithJWT sets the bearer token to send on every request.

type Pagination

type Pagination struct {
	Page       int   `json:"page"`
	PageSize   int   `json:"pageSize"`
	Total      int64 `json:"total"`
	TotalPages int64 `json:"totalPages"`
}

Pagination is the response-side pagination block. Traceway returns this on every paginated list endpoint.

type PaginationParams

type PaginationParams struct {
	Page     int `json:"page"`
	PageSize int `json:"pageSize"`
}

PaginationParams is the request-side pagination control.

type Project

type Project struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

Project is the minimal project shape we need today. Add fields as commands require them; do not pre-emptively mirror the entire upstream model.

type QueryLogsRequest

type QueryLogsRequest struct {
	TimeRange     TimeRange        `json:"-"`
	Pagination    PaginationParams `json:"pagination"`
	OrderBy       string           `json:"orderBy,omitempty"`
	SortDirection string           `json:"sortDirection,omitempty"`
	Search        string           `json:"search,omitempty"`
	SearchType    string           `json:"searchType,omitempty"`
	MinSeverity   uint8            `json:"minSeverity,omitempty"`
	ServiceName   string           `json:"serviceName,omitempty"`
	TraceId       string           `json:"traceId,omitempty"`
}

QueryLogsRequest is the body for POST /api/logs.

func (QueryLogsRequest) MarshalJSON

func (r QueryLogsRequest) MarshalJSON() ([]byte, error)

MarshalJSON expands TimeRange into top-level fromDate/toDate.

type QueryLogsResponse

type QueryLogsResponse struct {
	Data       []LogRecord `json:"data"`
	Pagination Pagination  `json:"pagination"`
}

QueryLogsResponse mirrors the upstream PaginatedResponse[LogRecord].

type QueryMetricsRequest

type QueryMetricsRequest struct {
	TimeRange       TimeRange         `json:"-"`
	IntervalMinutes int               `json:"intervalMinutes,omitempty"`
	Queries         []MetricQueryItem `json:"queries"`
}

QueryMetricsRequest is the body for POST /api/metrics/query.

Note: metrics uses `from`/`to` (NOT fromDate/toDate like the other endpoints) and has no pagination — results are time-bucketed via IntervalMinutes.

func (QueryMetricsRequest) MarshalJSON

func (r QueryMetricsRequest) MarshalJSON() ([]byte, error)

MarshalJSON expands TimeRange into top-level from/to (NOT fromDate/toDate).

type QueryMetricsResponse

type QueryMetricsResponse struct {
	Results []MetricQueryResult `json:"results"`
}

QueryMetricsResponse is the upstream MetricQueryResponse.

type TimeRange

type TimeRange struct {
	From time.Time
	To   time.Time
}

TimeRange is an inclusive [From, To] interval used in resource queries. It marshals to RFC3339 strings via the request structs that embed it.

func TimeRangeFromExplicit

func TimeRangeFromExplicit(from, to time.Time) TimeRange

TimeRangeFromExplicit constructs a TimeRange from two explicit instants. Caller is responsible for ensuring From <= To.

func TimeRangeFromSince

func TimeRangeFromSince(d time.Duration) TimeRange

TimeRangeFromSince returns a TimeRange ending now and starting `d` ago. Equivalent to TimeRangeFromSinceAt(d, time.Now()).

func TimeRangeFromSinceAt

func TimeRangeFromSinceAt(d time.Duration, now time.Time) TimeRange

TimeRangeFromSinceAt is the testable form: caller supplies "now".

type TimeSeriesPoint

type TimeSeriesPoint struct {
	Timestamp time.Time `json:"timestamp"`
	Value     float64   `json:"value"`
}

TimeSeriesPoint is one data point in a metric query result.

Jump to

Keyboard shortcuts

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