Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds major version 10 featuring WASM #3

Merged
merged 6 commits into from
Dec 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
debug/
target/

Cargo.lock
Cargo.lock
example-govrl
131 changes: 114 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,58 @@ Experimental go bindings for [Vector Remap Language](https://vector.dev/docs/ref

> Vector Remap Language (VRL) is an expression-oriented language designed for transforming observability data (logs and metrics) in a safe and performant manner. It features a simple syntax and a rich set of built-in functions tailored specifically to observability use cases.

## Versions
There are two major versions of this module and consumers must choose which is a
better fit for their use case.

They aim to support as similar an interface as possible, with the key
distinction being how VRL programs are executed.

- **V5** uses `cgo` to interface with a custom library built from VRL. This has
better performance with the main downside being that it relies on `cgo`, which
some applications may not care for.
- **V10** uses `wasm` to execute VRL. It performs worse, on the order of 2-3 times
slower, however VRL is quite efficient so this still offers relatively good
absolute performance.

## Usage

### Feature Support

| | V5 | V10 |
|-------------------------- | ------------------- | --- |
| Compiling a VRL Program | ✅ | ✅ |
| Running a VRL Program | ✅ | ✅ |
| VRL Runtime "Basic"\* API | ✅ | ✅ |
| Environment Kinds | 'Byte' and 'Object' | ❌ |
| Secrets | ❌ | ❌ |
| Metadata | ❌ | ❌ |
| Timezones | ❌ | ❌ |
| Requires CGO | ✅ | ❌ |
| Full VRL stdlib support | ✅ | ❌\* |


\* "Basic" API currently means:
Copy link
Owner

@gh123man gh123man Dec 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    • compile

- `compile`
- `resolve` (run) the compiled program
- `clear`
- `is_empty`

\* WASM supports almost most of VRL's stdlib functions, the unsupported ones can
be found [with this GH issues
search](https://github.com/vectordotdev/vector/issues?q=is%3Aopen+is%3Aissue+label%3A%22vrl%3A+playground%22+wasm+compatible)

### Building and importing

Not quite ready yet. It's difficult to distribute a go module that depends on an external build system (However I am open to suggestions)
Not quite ready yet. It's difficult to distribute a go module that depends on an external build system, we have some ideas though.

To use this repo as-is, its required to manually compile the rust dependency.
For V5: `cd v5; cargo build --release; cd example/; go run .`
For V10: `cd v10; cargo build --target wasm32-wasi --release; cd example/; go run .`

To use this repo as-is. `./run.sh` to build and run `main.go`
### Examples

### Example
#### V5

```go
program, err := govrl.CompileWithExternal(`replace(., "go", "rust")`, govrl.GetExternalEnv(govrl.Bytes, govrl.Bytes))
Expand All @@ -35,21 +78,75 @@ $ go run .
"hello rust"
```

[see `./example/main.go` for more examples](./example/main.go)
[see `./v5/example/main.go` for more examples](./v5/example/main.go)

## What works
#### V10

```go
package main

- Compiling VRL programs (and handling errors)
- Supports bytes and object external environment kinds
- Initializing the VRL runtime including:
- `resolve` (run) the compled program
- `clear`
- `is_empty`
import (
"context"
"fmt"
"log"

govrl "github.com/gh123man/go-vrl/v10"
)

func main() {
simpleDefault()
}

func simpleDefault() {
ctx := context.Background()
wasmInterface := govrl.NewWasmInterface(ctx)
program, err := wasmInterface.Compile(`
. = parse_json!(string!(.))
del(.foo)

.timestamp = now()

http_status_code = parse_int!(.http_status)
del(.http_status)

if http_status_code >= 200 && http_status_code <= 299 {
.status = "success"
} else {
.status = "error"
}
.
`)

if err != nil {
log.Panicln(err)
return
}

runtime, err := wasmInterface.NewRuntime()
if err != nil {
log.Panicln(err)
}

res, err := runtime.Resolve(program, `{
"message": "Hello VRL",
"foo": "delete me",
"http_status": "200"
}
`)
if err != nil {
fmt.Println(err)
return
}

fmt.Println(res)
runtime.Clear()
}
```

```bash
$ go run .
{ "message": "Hello VRL", "status": "success", "timestamp": t'2022-01-01T00:00:00Z' }
```

## What doesn't work/missing bindings
[see `./v10/example/main.go` for more examples](./v10/example/main.go)

- secrets
- metadata
- timezone
- environment configuration (partially implemented)
- most input types (other than bytes and object)
3 changes: 0 additions & 3 deletions build.sh

This file was deleted.

7 changes: 0 additions & 7 deletions example/go.mod

This file was deleted.

3 changes: 0 additions & 3 deletions go.mod

This file was deleted.

157 changes: 157 additions & 0 deletions v10/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
[package]
name = "vrl-bridge"
version = "0.1.0"
edition = "2021"

[profile.release]
debug=true

[lib]
name = "vrl_bridge"
crate-type = ["rlib", "cdylib"]

[dependencies]
libc = "0.2"
serde_json = "1.0.87"

# TODO: pin to stable version
value = { git = "https://github.com/vectordotdev/vector", default-features = false }
vrl = { git = "https://github.com/vectordotdev/vector", default-features = false }
vrl-diagnostic = { git = "https://github.com/vectordotdev/vector", package = "vrl-diagnostic" }

[dependencies.vrl-stdlib]
package = "vrl-stdlib"
git = "https://github.com/vectordotdev/vector"
default-features = false
# list of wasm-supported features taken from https://github.com/vectordotdev/vector/blob/master/lib/vrl/web-playground/Cargo.toml
features = [
"append",
"array",
"assert",
"assert_eq",
"ceil",
"chunks",
"compact",
"contains",
"decode_base64",
"decode_percent",
"del",
"downcase",
"encode_base64",
"encode_json",
"encode_key_value",
"encode_logfmt",
"encode_percent",
"ends_with",
"exists",
"filter",
"find",
"flatten",
"float",
"floor",
"for_each",
"format_int",
"format_number",
"format_timestamp",
"get",
"get_env_var",
"includes",
"ip_aton",
"ip_cidr_contains",
"ip_ntoa",
"ip_ntop",
"ip_pton",
"ip_subnet",
"ip_to_ipv6",
"ipv6_to_ipv4",
"is_array",
"is_boolean",
"is_empty",
"is_float",
"is_integer",
"is_ipv4",
"is_ipv6",
"is_json",
"is_null",
"is_nullish",
"is_object",
"is_regex",
"is_string",
"is_timestamp",
"join",
"keys",
"length",
"map_keys",
"map_values",
"match",
"match_any",
"match_array",
"match_datadog_query",
"md5",
"merge",
"mod",
"now",
"object",
"parse_apache_log",
"parse_aws_alb_log",
"parse_aws_cloudwatch_log_subscription_message",
"parse_aws_vpc_flow_log",
"parse_common_log",
"parse_csv",
"parse_duration",
"parse_glog",
"parse_int",
"parse_json",
"parse_key_value",
"parse_klog",
"parse_linux_authorization",
"parse_logfmt",
"parse_nginx_log",
"parse_query_string",
"parse_regex",
"parse_regex_all",
"parse_ruby_hash",
"parse_syslog",
"parse_timestamp",
"parse_tokens",
"parse_url",
"parse_user_agent",
"parse_xml",
"push",
"redact",
"remove",
"replace",
"round",
"set",
"sha1",
"sha2",
"sha3",
"slice",
"split",
"starts_with",
"string",
"strip_ansi_escape_codes",
"strip_whitespace",
"strlen",
"tally",
"tally_value",
"tag_types_externally",
"timestamp",
"to_bool",
"to_float",
"to_int",
"to_regex",
"to_string",
"to_syslog_facility",
"to_syslog_level",
"to_syslog_severity",
"to_timestamp",
"to_unix_timestamp",
"truncate",
"type_def",
"unique",
"unnest",
"upcase",
"values",
]

9 changes: 9 additions & 0 deletions v10/example/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module example-govrl

go 1.18

replace github.com/gh123man/go-vrl/v10 => ../

require github.com/gh123man/go-vrl/v10 v10.0.0

require github.com/tetratelabs/wazero v1.0.0-pre.4 // indirect
2 changes: 2 additions & 0 deletions v10/example/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/tetratelabs/wazero v1.0.0-pre.4 h1:RBJQT5OzmORkSp6MmZDWoFEr0zXjk4pmvMKAdeUnsaI=
github.com/tetratelabs/wazero v1.0.0-pre.4/go.mod h1:u8wrFmpdrykiFK0DFPiFm5a4+0RzsdmXYVtijBKqUVo=
Loading