Documentation
¶
Overview ¶
Read VSL logs (like varnishlog, varnishncsa, etc.)
Index ¶
- type Grouping
- type LogErr
- type LogReader
- type LogReaderBuilder
- func (b *LogReaderBuilder) Attach() (*LogReader, error)
- func (b *LogReaderBuilder) SetBacklog(enable bool) *LogReaderBuilder
- func (b *LogReaderBuilder) SetErrHandler(h func(LogErr)) *LogReaderBuilder
- func (b *LogReaderBuilder) SetFile(filename string) *LogReaderBuilder
- func (b *LogReaderBuilder) SetGrouping(g Grouping) *LogReaderBuilder
- func (b *LogReaderBuilder) SetLive(live bool) *LogReaderBuilder
- func (b *LogReaderBuilder) SetName(name string) *LogReaderBuilder
- func (b *LogReaderBuilder) SetQuery(query string) *LogReaderBuilder
- func (b *LogReaderBuilder) SetTimeout(timeout time.Duration) *LogReaderBuilder
- type Reason
- type Record
- type Tag
- type Transaction
- type TransactionType
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Grouping ¶
type Grouping int
How VSL records are grouped into transactions.
const ( // Each record is delivered as its own transaction, with no parent-child relationships. // Use this to notably read Backend_health records and logs occuring outside of sessions and requests. GroupingRaw Grouping = Grouping(C.VSL_g_raw) // Records are grouped into a single transaction GroupingVXID Grouping = Grouping(C.VSL_g_vxid) // HTTP transactions are grouped using the Link records, a group will contain the backend requests, // restarts and ESI transactions it directly or indirectly triggered. GroupingRequest Grouping = Grouping(C.VSL_g_request) // Same as [GroupingRequest] but the entry point is the connection itself, meaning the group will // contain all the transactions triggered by the connection. GroupingSession Grouping = Grouping(C.VSL_g_session) )
type LogErr ¶
type LogErr int
LogErr describes a recoverable VSL read condition — equivalent to the diagnostic messages that varnishlog prints to stderr during normal operation. These are non-fatal: LogReader.Run always reconnects and keeps going, but you can specify a callback with LogReaderBuilder.SetErrHandler to be notified when they occur.
const ( // Varnish wrote log records faster than they were consumed // and some were lost (vsl_e_overrun). ErrOverrun LogErr = iota // The VSL segment was abandoned by the writer, usually because Varnish // stopped (possibly killed) // (vsl_e_abandon). ErrAbandoned // Varnish worker process restarted; the // current cursor is no longer valid (VSM_WRK_RESTARTED). ErrWorkerRestarted // VSL_CursorVSM failed to map the log segment, // typically because the worker is still starting up. ErrCursorLost // ErrIO means an I/O read error occurred on the VSL segment (vsl_e_io). ErrIO )
func (LogErr) MarshalText ¶
MarshalText encodes the error as its string name. Implements encoding.TextMarshaler; see https://pkg.go.dev/encoding#TextMarshaler.
func (LogErr) String ¶
String returns a human-readable description of the error. Implements fmt.Stringer.
type LogReader ¶
type LogReader struct {
// contains filtered or unexported fields
}
LogReader reads VSL log records from a live Varnish instance or a file. Obtain one via LogReaderBuilder.Attach and LogReader.Run to start streaming. Call LogReader.Close when done.
func (*LogReader) Close ¶
func (r *LogReader) Close()
Close releases all resources held by the LogReader. It must be called exactly once when the LogReader is no longer needed.
func (*LogReader) Run ¶
Run streams VSL transactions, calling handler for each group, until ctx is cancelled or an unrecoverable error occurs. It transparently handles Varnish worker restarts: if the worker process is not running it waits and retries, but it will call the optional error handler if LogReaderBuilder.SetErrHandler was used. was used.
Run returns nil on clean EOF (file-based reading or if LogReaderBuilder.SetLive was used with false), ctx.Err() on cancellation, or the first non-nil error returned by the error handler.
Example ¶
package main
import (
"context"
"fmt"
"net/http"
"strings"
"time"
varnishlog "github.com/varnish/varnish-go/log"
"github.com/varnish/varnish-go/vtest"
)
// afterSettle fires fn after a short delay, giving Run time to acquire a cursor
// and sit at the log tail before new records are written.
func afterSettle(fn func()) {
go func() {
time.Sleep(200 * time.Millisecond)
fn()
}()
}
func main() {
v, err := vtest.New().VclString(`
backend default none;
sub vcl_recv { return(synth(200, "OK")); }
`).Start()
if err != nil {
panic(err)
}
defer v.Stop()
r, err := varnishlog.New().
SetName(v.Name()).
SetTimeout(5 * time.Second).
Attach()
if err != nil {
panic(err)
}
defer r.Close()
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
afterSettle(func() { http.Get(v.URL + "/example") }) //nolint:errcheck
r.Run(ctx, func(txns []varnishlog.Transaction) error { //nolint:errcheck
for _, txn := range txns {
for _, rec := range txn.Records {
if rec.Tag == varnishlog.TagReqURL && strings.Contains(rec.Data, "/example") {
fmt.Println(rec.Data)
cancel()
}
}
}
return nil
})
}
Output: /example
type LogReaderBuilder ¶
type LogReaderBuilder struct {
// contains filtered or unexported fields
}
LogReaderBuilder configures a connection to the Varnish VSL. Obtain one with New, configure with the Set* methods, then call LogReaderBuilder.Attach.
func (*LogReaderBuilder) Attach ¶
func (b *LogReaderBuilder) Attach() (*LogReader, error)
Attach connects to the Varnish shared memory segment and returns a LogReader. On failure, all underlying handles are freed and the builder must not be reused.
func (*LogReaderBuilder) SetBacklog ¶
func (b *LogReaderBuilder) SetBacklog(enable bool) *LogReaderBuilder
SetBacklog makes LogReader.Run process existing buffered log records before following the live tail. Equivalent to varnishlog's -d flag. Has no effect when [SetFile] is used.
func (*LogReaderBuilder) SetErrHandler ¶
func (b *LogReaderBuilder) SetErrHandler(h func(LogErr)) *LogReaderBuilder
SetErrHandler registers a callback that is invoked whenever a recoverable VSL read error occurs (overrun, abandon, worker restart, cursor loss). If not set, such conditions are silently ignored and Run keeps reconnecting.
func (*LogReaderBuilder) SetFile ¶
func (b *LogReaderBuilder) SetFile(filename string) *LogReaderBuilder
SetFile makes LogReader.Run read from a binary VSL file written by varnishlog -w, instead of connecting to a live Varnish instance. When set, [SetName] and [SetTimeout] are ignored.
func (*LogReaderBuilder) SetGrouping ¶
func (b *LogReaderBuilder) SetGrouping(g Grouping) *LogReaderBuilder
SetGrouping controls how records are grouped into transactions. The default is GroupingVXID.
func (*LogReaderBuilder) SetLive ¶
func (b *LogReaderBuilder) SetLive(live bool) *LogReaderBuilder
SetLive controls whether LogReader.Run keeps streaming after catching up to the live tail. By default (SetLive not called), Run follows new records indefinitely. Call SetLive(false) to stop cleanly once caught up.
func (*LogReaderBuilder) SetName ¶
func (b *LogReaderBuilder) SetName(name string) *LogReaderBuilder
SetName sets the Varnish instance name (workdir path, the -n argument to varnishd).
func (*LogReaderBuilder) SetQuery ¶
func (b *LogReaderBuilder) SetQuery(query string) *LogReaderBuilder
SetQuery sets a VSL query expression to filter which transactions are delivered. See vsl-query(7) for syntax.
func (*LogReaderBuilder) SetTimeout ¶
func (b *LogReaderBuilder) SetTimeout(timeout time.Duration) *LogReaderBuilder
SetTimeout sets how long LogReaderBuilder.Attach will wait for the Varnish manager. A negative duration disables the timeout (waits forever).
type Reason ¶
type Reason int
Reason describes why a transaction was initiated.
const ( // Unknown reason, should not occur in practice. ReasonUnknown Reason = Reason(C.VSL_r_unknown) // HTTP/1.x request ReasonHTTP1 Reason = Reason(C.VSL_r_http_1) // Received request ReasonRxReq Reason = Reason(C.VSL_r_rxreq) // ESI processing ReasonESI Reason = Reason(C.VSL_r_esi) // Restarted request ReasonRestart Reason = Reason(C.VSL_r_restart) // Backend request started because of a pass ReasonPass Reason = Reason(C.VSL_r_pass) // Backend request started to fetch a cache miss ReasonFetch Reason = Reason(C.VSL_r_fetch) // Backend request started to refresh a graced object ReasonBgFetch Reason = Reason(C.VSL_r_bgfetch) // Piped request ReasonPipe Reason = Reason(C.VSL_r_pipe) )
func (Reason) MarshalText ¶
MarshalText encodes the reason as its string name. Implements encoding.TextMarshaler; see https://pkg.go.dev/encoding#TextMarshaler.
func (Reason) String ¶
String returns the name of the reason. Implements fmt.Stringer.
type Record ¶
type Record struct {
Tag Tag `json:"tag" yaml:"tag"`
VXID uint64 `json:"vxid" yaml:"vxid"`
IsClient bool `json:"isClient" yaml:"isClient"`
IsBackend bool `json:"isBackend" yaml:"isBackend"`
Data string `json:"data" yaml:"data"`
}
Record is a single VSL log entry within a transaction.
type Tag ¶
type Tag int
Tag is a VSL log tag (e.g. TagReqURL, TagRespStatus). Use TagByName to look up a tag by its string name.
var ( // Common to both Varnish OSS and Enterprise. TagBackendClose Tag TagBackendHealth Tag TagBackendOpen Tag TagBackendSSL Tag TagBegin Tag TagBereqAcct Tag TagBereqHeader Tag TagBereqLost Tag TagBereqMethod Tag TagBereqProtocol Tag TagBereqReason Tag TagBereqStatus Tag TagBereqURL Tag TagBereqUnset Tag TagBerespHeader Tag TagBerespLost Tag TagBerespMethod Tag TagBerespProtocol Tag TagBerespReason Tag TagBerespStatus Tag TagBerespURL Tag TagBerespUnset Tag TagBogoHeader Tag TagCLI Tag TagDebug Tag TagEnd Tag TagError Tag TagESIXMLError Tag TagExpBan Tag TagExpKill Tag TagFetchBody Tag TagFetchError Tag TagGzip Tag TagH2RxBody Tag TagH2RxHdr Tag TagH2TxBody Tag TagH2TxHdr Tag TagHash Tag TagHit Tag TagHitMiss Tag TagHitPass Tag TagHTTPGarbage Tag TagLength Tag TagLink Tag TagLostHeader Tag TagObjHeader Tag TagObjLost Tag TagObjMethod Tag TagObjProtocol Tag TagObjReason Tag TagObjStatus Tag TagObjURL Tag TagObjUnset Tag TagPipeAcct Tag TagProxy Tag TagProxyGarbage Tag TagReqAcct Tag TagReqHeader Tag TagReqLost Tag TagReqMethod Tag TagReqProtocol Tag TagReqReason Tag TagReqStart Tag TagReqStatus Tag TagReqURL Tag TagReqUnset Tag TagRespHeader Tag TagRespLost Tag TagRespMethod Tag TagRespProtocol Tag TagRespReason Tag TagRespStatus Tag TagRespURL Tag TagRespUnset Tag TagSessClose Tag TagSessOpen Tag TagStorage Tag TagTimestamp Tag TagTLS Tag TagTTL Tag TagVCLAcl Tag TagVCLCall Tag TagVCLError Tag TagVCLLog Tag TagVCLReturn Tag TagVCLTrace Tag TagVCLUse Tag TagVfpAcct Tag TagVSL Tag TagWitness Tag TagWorkThread Tag // Varnish OSS only. TagFilters Tag TagNotice Tag TagReqTarget Tag TagSessError Tag TagVdpAcct Tag // Varnish Enterprise only. TagADNS Tag TagBackend Tag TagBackendReuse Tag TagBackendStart Tag TagBody Tag TagBrotli Tag TagConnectAcct Tag TagCrypto Tag TagDataDome Tag TagEdgestash Tag TagMSE4ChunkFault Tag TagMSE4NewObject Tag TagMSE4ObjIter Tag TagMSE4YKEYIter Tag TagNodes Tag TagOCSP Tag TagOCSPError Tag TagVHA6 Tag TagWAF Tag TagXBody Tag TagYKEY Tag )
VSL tag variables — union of all known tags across Varnish OSS and Enterprise.
Values are resolved at package init via TagByName. A zero value means the tag is not present in the installed Varnish version; callers should guard with:
if log.TagReqURL == 0 { /* tag unsupported */ }
These are vars, not constants, so they must not be written to by callers.
func TagByName ¶
TagByName looks up a Tag by name (case-insensitive; prefix match is accepted when unambiguous). Returns an error if the name matches zero or multiple tags.
func (Tag) MarshalText ¶
MarshalText encodes the tag as its Varnish name. Implements encoding.TextMarshaler; see https://pkg.go.dev/encoding#TextMarshaler.
func (Tag) String ¶
String returns the tag's name as known to Varnish (e.g. "ReqURL", "RespStatus"). Implements fmt.Stringer.
type Transaction ¶
type Transaction struct {
Level int `json:"level" yaml:"level"`
VXID int64 `json:"vxid" yaml:"vxid"`
ParentVXID int64 `json:"parentVxid" yaml:"parentVxid"`
Type TransactionType `json:"type" yaml:"type"`
Reason Reason `json:"reason" yaml:"reason"`
Records []Record `json:"records" yaml:"records"`
}
Transaction is a group of related VSL records sharing a VXID.
type TransactionType ¶
type TransactionType int
TransactionType describes what kind of processing a transaction represents.
const ( // Unknown type, should not occur in practice. TypeUnknown TransactionType = TransactionType(C.VSL_t_unknown) // Session, represents a client connection. TypeSession TransactionType = TransactionType(C.VSL_t_sess) // Client request TypeRequest TransactionType = TransactionType(C.VSL_t_req) // Backend request TypeBackend TransactionType = TransactionType(C.VSL_t_bereq) // Raw log entry TypeRaw TransactionType = TransactionType(C.VSL_t_raw) )
func (TransactionType) MarshalText ¶
func (t TransactionType) MarshalText() ([]byte, error)
MarshalText encodes the type as its string name. Implements encoding.TextMarshaler; see https://pkg.go.dev/encoding#TextMarshaler.
func (TransactionType) String ¶
func (t TransactionType) String() string
String returns the name of the transaction type. Implements fmt.Stringer.