Documentation
¶
Overview ¶
Package sqltrace runs live SQL Server Extended Events captures: it creates the XE session, drains its target, and commits every captured event as a row of a sql_xevent record stream, which is where every reader — a result profile, a follower, a step's checkpoint window — reads them back from.
Index ¶
- Constants
- func CreateXESession(ctx context.Context, db *sql.DB, opts xetrace.CreateOptions) (XESession, Opened, error)
- func CurrentDatabase(ctx context.Context, db *sql.DB) (string, error)
- type ActiveTrace
- func (t *ActiveTrace) Checkpoint(ctx context.Context) (query.EventsRef, error)
- func (t *ActiveTrace) Done() <-chan struct{}
- func (t *ActiveTrace) Err() error
- func (t *ActiveTrace) EventsRef() query.EventsRef
- func (t *ActiveTrace) Preview(from, to int64) []xetrace.Event
- func (t *ActiveTrace) Result() xetrace.TraceResult
- func (t *ActiveTrace) Running() bool
- func (t *ActiveTrace) Summary() xetrace.Summary
- type EventRow
- type Opened
- type RecordStore
- type Registry
- type RegistryOptions
- type StartOptions
- type XEFactory
- type XESession
Constants ¶
const RowKind = "sql_xevent"
RowKind is the record kind a capture's stream holds: one EventRow per captured event.
Variables ¶
This section is empty.
Functions ¶
func CreateXESession ¶ added in v0.1.42
func CreateXESession(ctx context.Context, db *sql.DB, opts xetrace.CreateOptions) (XESession, Opened, error)
CreateXESession is the production XEFactory: a session on db, over the ring buffer or — when opts.File is set — a .xel event_file target on the server, or the built-in system_health session when opts.Session names it.
Types ¶
type ActiveTrace ¶
type ActiveTrace struct {
ID string
SessionName string
// Statements created and started the XE session, as the factory ran them.
Statements []string
// Database is a readable label for the database patterns the capture's
// session is predicated on (the context's database when none were asked for).
Database string
StartedAt time.Time
StopAt time.Time
StoppedAt time.Time
Options xetrace.CreateOptions
Error string
// contains filtered or unexported fields
}
ActiveTrace is one live or finished XE capture. Its ID is the record stream its rows are committed to.
func (*ActiveTrace) Checkpoint ¶ added in v0.1.42
Checkpoint blocks until every row captured so far has been committed and returns the stream's ref over them. See eventWriter.Checkpoint.
func (*ActiveTrace) Done ¶ added in v0.1.42
func (t *ActiveTrace) Done() <-chan struct{}
Done is closed once the capture has finished: rows committed, stream sealed, session dropped and lease released.
func (*ActiveTrace) Err ¶
func (t *ActiveTrace) Err() error
Err returns the terminal capture, store or cleanup failure, if one occurred.
func (*ActiveTrace) EventsRef ¶ added in v0.1.42
func (t *ActiveTrace) EventsRef() query.EventsRef
EventsRef is the stream's ref as of its last commit, without waiting.
func (*ActiveTrace) Preview ¶ added in v0.1.42
func (t *ActiveTrace) Preview(from, to int64) []xetrace.Event
Preview returns the latest committed events whose seq is within from..to; a bound of 0 is open.
func (*ActiveTrace) Result ¶
func (t *ActiveTrace) Result() xetrace.TraceResult
Result is the capture's metadata and whole-capture summary. Its rows are in the record stream; a caller attaches the ref and preview it reports.
func (*ActiveTrace) Running ¶
func (t *ActiveTrace) Running() bool
Running reports whether the drain goroutine is still polling.
func (*ActiveTrace) Summary ¶ added in v0.1.42
func (t *ActiveTrace) Summary() xetrace.Summary
Summary is the IO/CPU/timing aggregate over every committed event.
type EventRow ¶ added in v0.1.42
type EventRow struct {
Name string `json:"name" pretty:"label=Event" filter:"terms"`
StatementType string `json:"statementType" pretty:"label=Type" filter:"terms"`
Timestamp time.Time `json:"timestamp" pretty:"label=Time" sort:"timestamp"`
DurationMs float64 `json:"durationMs" pretty:"label=Duration,type=duration,unit=ms" sort:"durationMs"`
CPUMs float64 `json:"cpuMs" pretty:"label=CPU,type=duration,unit=ms" sort:"cpuMs"`
LogicalReads int64 `json:"logicalReads" pretty:"label=Logical reads" sort:"logicalReads"`
PhysicalReads int64 `json:"physicalReads" pretty:"label=Physical reads" sort:"physicalReads"`
Writes int64 `json:"writes" sort:"writes"`
RowCount int64 `json:"rowCount" pretty:"label=Rows" sort:"rowCount"`
Database string `json:"database" filter:"terms"`
ClientApp string `json:"clientApp" pretty:"label=App" filter:"terms"`
ClientHost string `json:"clientHost" pretty:"label=Host" filter:"terms"`
Username string `json:"username" pretty:"label=User" filter:"terms"`
SessionID int `json:"sessionId" pretty:"label=Session" filter:"exact"`
SQL string `json:"sql" pretty:"label=SQL" filter:"text"`
RawStatement string `json:"rawStatement" pretty:"hide"`
Tables []string `json:"tables"`
ErrorNumber int `json:"errorNumber" pretty:"label=Error"`
ErrorMessage string `json:"errorMessage" pretty:"label=Error message" filter:"text"`
ObjectName string `json:"objectName" pretty:"label=Object" filter:"terms"`
ObjectType string `json:"objectType" pretty:"label=Object type" filter:"terms"`
AdditionalFields map[string]any `json:"additionalFields,omitempty" pretty:"hide"`
Deadlock *deadlocks.Graph `json:"deadlock,omitempty" pretty:"hide"`
ActivityID string `json:"activityId" pretty:"hide"`
ActivitySeq int `json:"activitySeq" pretty:"hide"`
Children []EventRow `json:"children" pretty:"hide"`
}
EventRow is one captured event as a capture stores it: its metrics in milliseconds, its identity and text, and, for a deadlock report, the decoded graph.
type Opened ¶ added in v0.1.42
Opened is what an XEFactory reports about the session it created: its name and the statements that created and started it.
type RecordStore ¶ added in v0.1.42
type RecordStore interface {
Append(ctx context.Context, stream, kind string, rows []recordstore.Row) (recordstore.AppendResult, error)
Seal(ctx context.Context, stream string) error
EventsRef(ctx context.Context, stream string, from, to int64) (query.EventsRef, error)
}
RecordStore is where a capture commits its rows. EventsRef describes a window of a stream the way the store holding it reports it, so a reader can replay the rows after the capturing process is gone.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry starts and stops XE captures. One is built per capture start, over the record store the starting request's environment routes to.
func NewRegistry ¶
func NewRegistry(opts RegistryOptions) (*Registry, error)
NewRegistry builds a Registry over opts, refusing a missing seam.
func (*Registry) Start ¶
func (r *Registry) Start(ctx context.Context, opts StartOptions) (*ActiveTrace, error)
Start creates the XE session, opens its record stream and starts the drain. Every store call the capture makes runs under ctx's values with its cancellation detached, so the rows reach the environment ctx names even after the request that started the capture has ended.
type RegistryOptions ¶ added in v0.1.42
type RegistryOptions struct {
// DB leases the context's write pool for one capture; the release runs
// after the capture's final drain and session drop.
DB func(context.Context) (*sql.DB, func(), error)
// Store is where captured rows are committed.
Store RecordStore
// NewSession creates the XE session (CreateXESession in production).
NewSession XEFactory
// CurrentDatabase names the context's database, which a capture scopes to
// when it names none (CurrentDatabase in production).
CurrentDatabase func(context.Context, *sql.DB) (string, error)
}
RegistryOptions are the seams a Registry needs. Every one is required.
type StartOptions ¶
type StartOptions struct {
xetrace.CreateOptions
// Duration bounds the trace. Zero means run until Stop.
Duration time.Duration
// Poll is the ring-buffer poll interval. Zero defaults to 1s.
Poll time.Duration
}
StartOptions collapses everything a caller can pass to Start. An XE session is server-wide: CreateOptions.Databases narrows it in SQL Server's own predicate, and an empty Databases scopes the capture to the context's database.