Using Vector tap
Learn how to use the Vector tap
CLI command to examine events as they flow through your pipeline and troubleshoot issues.
Before you begin, this guide assumes the following:
- You understand the basic Vector concepts
- You understand how to set up a basic pipeline
Vector’s tap
CLI command allows you to observe events as they flow to and from components in your pipelines. If you’ve ever attached a console
sink to an output for debug purposes and wondered if there’s a better way, you’re in the right place. This guide walks you through how vector tap
can be used to level up your troubleshooting experience.
Getting Started
To start, we’ll reference the following base configuration, but feel free to substitute your own. Just note that the Vector API must be enabled for vector tap
to work. See under the hood for more details.
[api] enabled = true [sources.in] type = "demo_logs" format = "shuffle" lines = [ "test1", "test2", ] [sinks.out] type = "blackhole" inputs = ["in*"]
Run Vector with this configuration and watch the configuration for changes.
vector --config path/to/config.toml -w
Now run vector tap
! You should start seeing a stream of notifications (sent to stderr
) and events (sent to stdout
) in your terminal.
[tap] Pattern "*" successfully matched. {"message":"test1","source_type":"demo_logs","timestamp":"2022-02-22T19:20:40.487671258Z"} {"message":"test2","source_type":"demo_logs","timestamp":"2022-02-22T19:20:41.486858019Z"} ...
Notifications are informative messages prefixed with [tap]
and, in this case, events are logs flowing out of the demo_logs
component in
. There’s a lot going on here – component patterns, events from outputs, JSON formatting – so let’s start by unpacking it all.
Usage Basics
Component Patterns
You can tap
both the output events of components (sources or transforms) and the input events of components (transforms or sinks) by providing component ID patterns in the --outputs-of
and --inputs-of
options respectively. More specifically, glob patterns are accepted in these options. You can also specify output patterns as additional arguments.
Running the bare vector tap
command invokes sensible defaults and is equivalent to specifying --outputs-of "*"
where "*"
matches any component ID.
Try running vector tap --inputs-of "out"
. The events should be the same as before, but you’re now tapping the input events of the blackhole
sink out
.
Customizing output
tap
notifications provide additional context such as information about pattern matching success or failure and improper usage of patterns. If you’d like to hide notifications, use the --quiet
option.
By default, tap
outputs events encoded in JSON format. YAML and logfmt are also supported and can be enabled by using the --format
option.
Events in tap
are actually sampled from their tapped components for performance and reliability. You can change the time interval of each sample with --interval
and the maximum number of events to sample per interval with --limit
.
Try running vector tap --quiet --format logfmt
. You’ll now see no notifications and events encoded as logfmt.
... message=test1 source_type=demo_logs timestamp=2022-02-22T20:57:01.430905309Z message=test1 source_type=demo_logs timestamp=2022-02-22T20:57:02.430987800Z ...
Configuration reloading support
tap
is compatible with configuration reloading. In other words, if you add, remove, or edit existing components in your configuration, tap
will adapt accordingly by re-matching your provided patterns.
With vector tap
running, add the following demo_logs
source to the base configuration.
[sources.in-2] type = "demo_logs" format = "shuffle" lines = [ "new test1", "new test2", ]
You’ll now see events from component in-2
appear in tap
output.
... {"message":"new test2","source_type":"demo_logs","timestamp":"2022-02-22T21:07:50.106793803Z"} {"message":"test1","source_type":"demo_logs","timestamp":"2022-02-22T21:07:50.490873070Z"} {"message":"new test1","source_type":"demo_logs","timestamp":"2022-02-22T21:07:51.106744949Z"} ...
You can read more about all available options in the Vector tap docs or by running vector tap --help
.
Troubleshooting Example
With the basic mechanics out of the way, let’s see how you might use tap
to troubleshoot a pipeline.
We’ll use the following Vector configuration.
[api] enabled = true [sources.in] type = "demo_logs" format = "shuffle" lines = [ '{ "type": "icecream", "flavor": "strawberry" }', '{ "type": "icecream", "flavor": "chocolate" }', '{ "type": "icecream", "flavor": "wasabi" }', ] [transforms.picky] type = "remap" inputs = ["in"] drop_on_abort = true reroute_dropped = true source = ''' if .flavor == "strawberry" { .happiness = 10 } else if .flavor == "chocolate" { .happiness = 5 } else { abort } ''' [sinks.store] type = "console" inputs = ["picky"] target = "stdout" encoding.codec = "json" [sinks.trash] type = "blackhole" inputs = ["picky.dropped"]
Running this configuration, we expect to see our favorite ice cream logs appear in stdout
. Unfortunately, we see nothing at all. The desired events don’t look like they’re ever reaching their destination.
We can verify this by examining the inputs of the store
sink with vector tap --inputs-of "store"
: indeed, no events appear. We can also narrow in and inspect the output of relevant upstream components like our remap
transform. vector tap --outputs-of "picky"
(which, in this case, is effectively the same as inspecting the inputs of store
) shows that events are not flowing.
Are all the events being dropped instead? A quick glance with vector tap --outputs-of "picky.dropped"
confirms that suspicion as tap
starts displaying a stream of all our dropped logs. On closer examination, it’s clear that our events don’t have the shape we expected.
{"message":"{ \"type\": \"icecream\", \"flavor\": \"strawberry\" } }
There’s no .flavor
field for our conditional to run on. Instead, the entire payload from our source has been included in the default message
field. Right, we forgot to parse the payload into JSON. We need to add the following line in our VRL source code:
. = parse_json!(.message)
With that modification and a quick reload of the configuration, we start seeing our precious ice cream logs in the console. Hurray!
While this was a highly contrived example, the issues highlighted are relevant to many real world troubleshooting scenarios: unexpected input from sources, misconfigured transformations, missing clarity on where events end up and how they’re structured. We hope vector tap
eases the troubleshooting burden especially in larger, more complex setups where mistakes are not easy to find by simply reading a configuration file.
Ultimately, vector tap
is one tool in the wide range of Vector features that lets you safely and reliably set up your observability pipelines. Be sure to also check out Vector unit testing to verify the expected behavior of your transforms and Vector internal observability for more insight into Vector itself.
Under the hood
Under the hood, vector tap
is powered by the Vector API, specifically by the outputEventsByComponentIdPatterns
subscription. If you’d like a more direct and programmatic way to examine events in your pipeline, consider interacting with the API directly.
vector tap
will work! Simply use the --url
option to specify a non-default API address. This allows you to troubleshoot remote Vector instances.We encourage contributions and suggestions for improving vector tap
!