-
Notifications
You must be signed in to change notification settings - Fork 3
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
Changes from 5 commits
4e614f7
2ad1ab9
5326421
c3b0ee3
9d6e493
734b665
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
debug/ | ||
target/ | ||
|
||
Cargo.lock | ||
Cargo.lock | ||
example-govrl |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,15 +5,51 @@ 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 | ❌ | ✅ | | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. too big to fit in this table - but IIRC, the WASM version has a limited exposure to the VRL std lib right (some functions dont work)? May be worth a note. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, good call, added. |
||
|
||
\* "Basic" API currently means: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
- `resolve` (run) the compled program | ||
- `clear` | ||
- `is_empty` | ||
|
||
### 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)) | ||
|
@@ -35,21 +71,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) | ||
|
||
#### V10 | ||
|
||
```go | ||
package main | ||
|
||
## What works | ||
import ( | ||
"context" | ||
"fmt" | ||
"log" | ||
|
||
- 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` | ||
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) |
This file was deleted.
This file was deleted.
This file was deleted.
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", | ||
] | ||
|
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 |
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= |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package main | ||
|
||
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() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think
V5
andV10
are flipped here asV5
is the CGO variant and supportsKind
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely, good catch.