Skip to content
Patrol

Changelog

Every release of the library

Read from the HISTORY file of kataras/patrol at build time, so this page and the repository say the same thing. Breaking changes come first and each one names what a caller has to do.

v0.0.8

Unreleased

Shutting a Server down properly, and the last piece a custom server needed.

Added

  • Server.Close(ctx) stops accepting batches, waits for the deliveries already in flight and then closes every flusher that implements Closer. A Server answers a POST before it delivers, so http.Server.Shutdown returning told you nothing about whether the events arrived, and a flusher holding a resource, a SQL pool for instance, was never closed at all. When ctx ends first it returns ctx.Err() and leaves the deliveries running, without closing the flushers: closing one underneath a delivery is worse than leaking it. It is idempotent, and afterwards a POST is refused with 503 and UNAVAILABLE while GET still answers OK, so a health check can watch the drain.
  • SortEvents(evts), the order Producer and Server put a batch in before handing it to the flushers. A program that runs its own server needs it to satisfy FlushAll's contract, and was reimplementing it.

v0.0.7

Everything a program needs to run its own server that speaks the Server protocol, plus a single-token credential. Additive: code written against v0.0.6 keeps compiling.

Added

  • FlushAll(ctx, flushers, evts), the concurrent fan-out Producer and Server deliver through, for programs that run their own server. Every flusher runs to completion and the errors are joined with the flusher names.
  • DecodeEvents(w, r, maxBytes), WriteServerError(w, status, code, message), MaxRequestBody and the ErrorCode* constants (METHOD_NOT_ALLOWED, UNAUTHENTICATED, INVALID_ARGUMENT, PAYLOAD_TOO_LARGE, RESOURCE_EXHAUSTED, UNAVAILABLE), so a server that speaks the Server protocol writes the same bytes and a Client decodes them as ServerError.
  • ClientOptions.Token (token in JSON, Token in YAML and TOML) sends one bearer token instead of a username and password; ServerOptions.Tokens (tokens / Tokens) lists the accepted ones, compared in constant time, alongside BasicAuth. Either credential unlocks a request when both are set.

Fixed

  • A batch above 32 MiB is refused with 413 and PAYLOAD_TOO_LARGE instead of 400 and INVALID_ARGUMENT, so a sender can tell "shrink the batch" from "bad JSON".

v0.0.6

Go 1.27 refactor. The public API changed in several places; every change is listed here with what a caller must do.

Breaking changes

  • NewInbox, NewSlack and NewTwilio now return (T, error) and validate their required fields, like NewDiscord and NewSQL already did. Callers add an error check.
  • Producer.WithErrorLogger is gone. Set ProducerOptions.OnError instead. The default logs through log/slog.
  • Server.WithErrorListener and Server.WithBasicAuth are gone. Set ServerOptions.OnError and ServerOptions.BasicAuth (a username to password map) instead.
  • Server.Handler and Server.HandlerFunc are gone. Server is a plain http.Handler. When BasicAuth is set, GET requests are authenticated too, so Client.Test now verifies the credentials.
  • EventConsumer and EventConsumerFunc are gone. NewServer takes EventFlushers and EventFlusherFunc adapts a function. Every integration lost its ListenEvents method.
  • EventFlusher is now the single method FlushEvents. Test moved to the optional Tester interface and String is optional. Custom flushers keep working; they just have fewer methods to implement.
  • Zone and ZoneOffset (LocationUTCOffset in YAML) are replaced by TimeZone, an IANA name such as Europe/Athens, on InboxOptions, DiscordOptions and TwilioOptions. SlackOptions never used its zone and no longer has one.
  • NewSQL and NewSQLWithDatabase take a context.Context first.
  • Mentions are a typed Event.Mentions []string (JSON mentions) instead of a Mentions field inside Fields. WithMentions keeps its name.
  • Removed: Chunk (use slices.Chunk), Now, EventGroup and RemoveEventByFunc, DefaultErrorLogger, CollapseText, the never-populated Frame fields (Symbol, Colno, PreContext, ContextLine, PostContext, Vars), Stacktrace.FramesOmitted, and the never-set ServerError fields (Details, Validation, Data).
  • Frame.AbsPath is now the plain file path; the line number lives only in Lineno.
  • EmailTemplate is an html/template and escapes its data. Template data changed: each event's Stacktrace is a list of frames with Function, Module, Location (path:line) and Link (vscode://file/path:line).
  • BufferInterval values below one second are honoured instead of being replaced by 5s. Zero or negative still means 5s.
  • SendEvent keeps an event's own ProjectName and only fills in the producer's when empty.
  • Debug events are dropped at SendEvent time while debug mode is off, instead of at flush time. Debugging sessions therefore deliver their event reliably.

Fixed

  • WithMentions followed by SendEvent panicked (hash of unhashable type), and any slice or map field value did the same. Field de-duplication no longer hashes values.
  • Slack mentions were never rendered (case mismatch on the field name).
  • Events received by Server were delivered on the already-cancelled request context.
  • One failing flusher cancelled the others mid-flight. Flushers now run independently and OnError receives one joined error naming each failed flusher.
  • Concurrent SendEvent and Close could panic with "send on closed channel"; Debugging raced with Close on a WaitGroup.
  • Every flusher sorted the shared batch in place, concurrently. Batches are now sorted once and are read-only for flushers.
  • Inbox.Test failed against real servers because it authenticated without STARTTLS.
  • WithFieldsPrepended and WithFields dropped every pair when given an odd number of arguments and mishandled Fields values in the list.
  • Close(ctx) ignored its context. It now cancels the in-flight flush and returns ctx.Err() when the deadline passes; the shutdown completes in the background.
  • Emails carry From, To, Date and an encoded Subject; group, file and mention order is deterministic; the 405 response sets Allow correctly; Discord calls honour the context.

Added

  • Producer.Test(ctx) runs the Test of every flusher that implements Tester.
  • ErrClosed, returned by SendEvent and Debugging after Close.
  • NewSlack(opts, ...slack.Option) and NewClient(opts, ...httpclient.Option) accept client options, for proxies and tests.
  • Event IDs are UUID v7 from the standard library uuid package.

Dependencies

  • Removed github.com/google/uuid and golang.org/x/sync. The go/build import is gone too, so binaries no longer link the Go parser.
  • Requires Go 1.27.
  • Requires github.com/kataras/basicauth v0.0.8. The BasicAuth map of ServerOptions is checked through basicauth.AllowUsersMap, which now compares passwords in constant time and compares an unknown username against a decoy, so the response time does not reveal which usernames exist.

Migration for the known consumers

  • Every wrapper that does patrol.NewProducer(opts, flushers...).WithErrorLogger(fn) becomes patrol.NewProducer(patrol.ProducerOptions{..., OnError: fn}, flushers...), and every patrol.NewInbox(o), patrol.NewSlack(o), patrol.NewTwilio(o) call gains an error check. SlackOptions.AcceptChannelEvent, Event.Error, WithStacktrace(nil), WithFieldsPrepended, WithStringField, WithField, WithError, WithMessage, NewEvent, NewException, NewStacktrace, AddSkipModuleFrames, SendEvent, Close and Debugging are unchanged.

v0.0.8 is the newest entry. Older tags and the full commit history are onGitHub.