From 4d274e7a55829a1af0e7df7c7754d5924237fa11 Mon Sep 17 00:00:00 2001 From: Alan Braithwaite Date: Wed, 23 Aug 2023 11:58:38 -0700 Subject: [PATCH 1/2] readme: add more docs --- README.md | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 133 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 7ebe8b2..124b049 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,13 @@ +   + [![Go Reference](https://pkg.go.dev/badge/github.com/runreveal/kawa.svg)](https://pkg.go.dev/github.com/runreveal/kawa) [![GoFrame CI](https://github.com/runreveal/kawa/actions/workflows/ci.yml/badge.svg)](https://github.com/runreveal/kawa/actions/workflows/ci.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/runreveal/kawa)](https://goreportcard.com/report/github.com/runreveal/kawa) [![License](https://img.shields.io/github/license/runreveal/kawa.svg?style=flat)](https://github.com/runreveal/kawa) + kawa is an opinionated framework for scalable, reliable stream processing. @@ -17,6 +20,8 @@ kawa also provides a daemon for collecting system logs and metrics. # Installation +## The Daemon + Find the package for your OS and architecture on the releases page. Download that file to the machine, and install somewhere visible on your $path. @@ -26,6 +31,14 @@ Copy an example config from the examples/ directory, then run it! There is also an example for deploying as a systemd service. Additionally, we'll have kubernetes examples soon. +## The library + +Add the library to your project as you would any other Go library: + +```go +go get -u github.com/runreveal/kawa +``` + # Design and Rationale See https://blog.runreveal.com/kawa-the-event-processor-for-the-grug-brained-developer/ @@ -48,6 +61,7 @@ shape the direction of the project by giving us feedback! An example use case might be shipping your nginx logs to s3. Save the following config.json, and fill in the config file. + ``` { "sources": [ @@ -68,6 +82,7 @@ config.json, and fill in the config file. ``` Next, add the following line to your nginx server config. + ``` server { access_log syslog:server=127.0.0.1:5514; @@ -76,24 +91,124 @@ server { ``` Run it! + ``` $ kawa run --config config.json ``` +# Development & Extending + +The source and destination interfaces are designed for simplicity of use and +implementation. It should be easy to use the sources and destinations in an +abstract manner without knowing the underlying implementation, and it should +be relatively easy to implement sources and destinations of various types. + +The library provides multiple abstractions suitable for different purposes. + +The easiest way to get started is by using the polling/batch implementations +for sources/destinations, respectively, since they require less overhead in +terms of accounting for offset tracking to ensure at-least-once reliable +processing. + +## Configure and Run Design Pattern + +The "Configure and Run" pattern is a pattern discovered while writing this +framework that works nicely with other patterns and libraries in Go. + +The general idea is as follows. Each struct maintaining long running goroutines +can be made easy to reason about and operate by splitting it's configuration and +runtime into two separate stages. + +The first stage, "Configure", is simply the initialization of the struct. Most +often, this is the New function for the struct, with required arguments passed +in first, and options passed in as a variadic functional options slice +afterwards. Occasionally, this may involve also implementing a translation +layer for serialization of the struct from JSON or some other serialization +format. + +The next stage, "Run", involves implementing the simple Runner interface: + +``` +type Runner interface { + Run(ctx context.Context) error +} +``` + +Implementing this interface consistently across all instances of structs that +have long-running processes means that we can easily implement cancellation +across a broad number of distinct types via a common context variable. + +It also means that any goroutine can trigger a shutdown by returning an error +from the Run routine. + +While not absolutely required, following this pattern will enable the source or +destination to be seamlessly integrated into the daemon. + +## Implementing Sources + +Sources are things that you read message-oriented data from. + +### Polling Source + +We recommend implementing polling sources when querying an API, or whenever +it's easiest to implement a function to periodically get called. The following +is the interface which needs to be satisfied to implement a polling source. + +``` +type Poller[T any] interface { + Poll(context.Context, int) ([]kawa.Message[T], func(), error) +} +``` + +### Streaming Source + +We recommend implementing streaming sources when the source either implements +it's own batching semantics (like Kafka), or when message latency is more +important than message volume. + +## Implementing Destinations + +Destinations are things that you write message-oriented data to. + +### Batch Destination + +Implementing a batch destination is the easiest way to process messages as a +batch being written to some persistent storage. It handles timeouts, batch size, +and parallel writes at the configuration level so destinations only have to implement +a single method "Flush". + +``` +type Flusher[T any] interface { + Flush(context.Context, []kawa.Message[T]) error +} +``` + +### Streaming Destination + +We recommend implementing streaming destinations when the destination either +implements it's own batching semantics (like Kafka), or when message latency is +more important than message volume. # Supported sources + - syslog - scanner - journald # Supported destinations + - s3 / r2 - printer - runreveal -# Source Configuration -## syslog +# Configuring the Daemon + +## Source Configuration + +### syslog + With the syslog config, and address and content type can be set. + ``` { "type":"syslog", @@ -101,7 +216,8 @@ With the syslog config, and address and content type can be set. } ``` -## journald +### journald + Journald has no configuration, just set the type and kawa will read from journald. ``` { @@ -109,8 +225,10 @@ Journald has no configuration, just set the type and kawa will read from journal } ``` -## scanner +### scanner + Read from stdin. Useful for testing or doing something you probably shouldn't. + ``` { "type":"scanner", @@ -118,9 +236,12 @@ Read from stdin. Useful for testing or doing something you probably shouldn't. ``` -# Destination Configuration -## RunReveal +## Destination Configuration + +### RunReveal + WebhookURL is the only config argument and it is required. + ``` { "type":"runreveal", @@ -128,7 +249,8 @@ WebhookURL is the only config argument and it is required. } ``` -## S3 +### S3 + The s3 destination is compatible with s3 and other s3 compatible interfaces. By default the s3 destination will pull credentials from the standard places the aws sdk looks, but they can optionally be set in the configuration. customEndpoint must be set for custom destinations, and in that case bucketRegion probably will not be set. bucketName is the only required argument. @@ -144,7 +266,8 @@ For high volume or low volume, the batchSize can be tweaked but is set to 100 by } ``` -## Printer +### Printer + Printer will print the results to stdout. Useful for testing and development. ``` { @@ -152,7 +275,8 @@ Printer will print the results to stdout. Useful for testing and development. } ``` -# Source / Destination Wishlist +## Source / Destination Wishlist + - Kafka - redis - NATS From 7419334e7df176621f36cb2675fbb6178b71261b Mon Sep 17 00:00:00 2001 From: Alan Braithwaite Date: Wed, 23 Aug 2023 13:30:58 -0700 Subject: [PATCH 2/2] convert markdown to html because jekyll --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 124b049..6ca8503 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,10 @@    -[![Go Reference](https://pkg.go.dev/badge/github.com/runreveal/kawa.svg)](https://pkg.go.dev/github.com/runreveal/kawa) -[![GoFrame CI](https://github.com/runreveal/kawa/actions/workflows/ci.yml/badge.svg)](https://github.com/runreveal/kawa/actions/workflows/ci.yml) -[![Go Report Card](https://goreportcard.com/badge/github.com/runreveal/kawa)](https://goreportcard.com/report/github.com/runreveal/kawa) -[![License](https://img.shields.io/github/license/runreveal/kawa.svg?style=flat)](https://github.com/runreveal/kawa) +Go Reference +GoFrame CI +Go Report Card +License