Batched event delivery for Go
A producer buffers the events your program sends it and flushes them in batches to Slack, Discord, Twilio, email, SQL or a server you run. Each destination runs on its own, so the one that is down cannot hold up the rest.
The library is open source and released. Patrol Cloud, the hosted service that will receive events and show them in a console, is still being built, so there is no sign-up yet.
Build a flusher for each destination, hand them to a producer, and send from anywhere in your program. This is the whole of it.
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/kataras/patrol"
)
func main() {
ctx := context.Background()
slack, err := patrol.NewSlack(patrol.SlackOptions{
Token: "xoxb-...",
Channels: []string{"C0123456789"},
})
if err != nil {
log.Fatal(err)
}
producer := patrol.NewProducer(patrol.ProducerOptions{
ProjectName: "My Project",
BufferInterval: 5 * time.Second,
OnError: func(err error) { log.Println("patrol:", err) },
}, slack)
defer producer.Close(ctx)
e := patrol.NewException(fmt.Errorf("payment failed")).
WithField("UserEmail", "user@example.com").
WithMentions("U0123456789")
if err := producer.SendEvent(ctx, e); err != nil {
log.Fatal(err)
}
}NewException captures a filtered stacktrace with editor deep links. Builders such as WithField, WithUserEmail, WithFile and WithMentions add the rest.
Each one takes an options struct with json, yaml and toml tags, so it loads straight from a config file, and each constructor checks the required fields before it builds anything.
NewSlack
Block Kit attachments, file uploads and user mentions, one message per channel.
NewDiscord
One rendered message per project group, posted to the channels you list.
NewTwilio
SMS, or WhatsApp by prefixing both numbers with whatsapp:.
NewInbox
HTML mail over SMTP, with STARTTLS when the server offers it.
NewSQL
A patrol_events table, written in one transaction, 1,000 rows a statement.
NewClient
Posts JSON batches to a patrol server, with basic auth or one bearer token.
NewServer
An http.Handler that receives batches and hands them to its own flushers.
EventFlusher
Any type with a FlushEvents method is a destination. Add Test, Close and String and the producer will use those too.
Four steps, and the third is the one that matters at three in the morning.
A call to SendEvent hands the event to the producer and returns. It never panics, and it never blocks forever: when the buffer is full it returns the context error instead of stalling the caller.
Buffered events go out together when the batch reaches its maximum size or when the buffer interval elapses, whichever comes first. One delivery carries many events rather than one request per error.
The batch fans out to all of your destinations at once. A failing or slow one cannot cancel the others, and the errors come back joined into a single value, each prefixed with the name of the integration that raised it, through your OnError callback.
Close flushes what is still buffered and shuts the integrations down. Give it a context with a deadline and it honours it: the in-flight flush is cancelled, Close returns the context error, and the rest finishes in the background.
Both sides speak the same wire format, because both sides are the same code. Whichever you start with, the other is a change of base URL.
Run a patrol server where the integrations live, so one service holds the Slack token and the SMTP password and the rest of your fleet never sees them. Point clients at it from everywhere else. It answers the sender before it delivers, so a slow integration never slows the caller down.
The hosted side takes the server off your hands: events land in a project you own, stay there for a retention window, and show up in a console with their fields and stacktraces. It is being built now and it is not open, so nothing on this page asks you to sign up for it.
Go 1.27 or later is the only requirement. No agent beside your process, no code generator, no CLI.
$ go get github.com/kataras/patrol@latestDocumentation at pkg.go.dev/github.com/kataras/patrol. Released under the BSD-3-Clause license.
Patrol is an open-source Go library for event production and delivery. A producer buffers the events a program sends it and flushes them in batches, when the batch fills or when the buffer interval elapses, to 7 kinds of destination: Slack, Discord, Twilio for SMS and WhatsApp, email over SMTP, a SQL table, an HTTP client that forwards to a remote patrol server, and that server itself. Each destination runs independently, so a Slack outage cannot stop the email going out, and every failure reaches one OnError callback carrying the name of the integration that produced it. Patrol needs Go 1.27 or later and nothing else, is licensed BSD-3-Clause, and is published as the Go module github.com/kataras/patrol. The current release is 0.0.7.
Not yet. The Patrol library is the part that ships today: it is public, tagged 0.0.7, and it installs into a Go program in one command. Patrol Cloud, the hosted service that will receive events, store them per project and show them in a console at https://patrol.hellenic.dev, is still being built. There is no sign-up, no account and no API key to ask for. Until it opens, you get the same delivery by running the integrations inside your own process, or by running a patrol server of your own and pointing your other services at it with a patrol client. Both paths use the code Patrol Cloud will use, so a program written against the library now keeps working when the hosted service arrives. Changing the base URL and adding a key is the whole migration.
Install Patrol by running go get github.com/kataras/patrol@latest inside a Go module, then import github.com/kataras/patrol. Go 1.27 or later is the only requirement: no agent running beside your process, no code generator, and no CLI to install first. Build a flusher for each destination you want, hand them to NewProducer, and call SendEvent from anywhere in your program. NewException captures a filtered stacktrace with editor deep links, and Close drains whatever is still buffered before the process exits. The API reference is at pkg.go.dev/github.com/kataras/patrol, and the repository carries runnable examples for every integration with a sample configuration file beside each one.
Yes. Patrol is open source under the BSD-3-Clause license, which permits commercial use, modification, and redistribution as long as the copyright notice travels with the code. There is no paid tier, no license key, and no cap on how many events a process delivers. The source is at github.com/kataras/patrol and the API reference is on pkg.go.dev. Patrol Cloud, the hosted service still in development, will publish its own prices when it opens, and the library stays free either way. Running the integrations yourself is not a trial or a reduced edition: it is the same code, and it is what Patrol Cloud runs internally.
Yes, and that is the intended way to use Patrol before Patrol Cloud opens. NewServer returns an http.Handler holding the integrations you configured, so one service owns the Slack token and the SMTP credentials and the rest of your fleet never sees them. Every other service builds a client with NewClient, points it at that server, and sends events the same way it would send them to Slack directly. The server accepts a POST with a JSON array of events and answers a GET with OK for connectivity checks, both protected by a username and password pair or by a bearer token you list. It answers the sender before it delivers, so a slow integration never slows the caller down.