forked from jaegertracing/jaeger
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create README for developing grpc storage plugins jaegertracing#1518 (j…
…aegertracing#1525) * Create README for developing grpc storage plugins jaegertracing#1518 Signed-off-by: Charles Dixon <chvckd@gmail.com>
- Loading branch information
1 parent
7ae02d4
commit 2aacfaf
Showing
1 changed file
with
97 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
gRPC Storage Plugins | ||
==================== | ||
gRPC Storage Plugins currently use the [Hashicorp go-plugin](https://github.com/hashicorp/go-plugin). This requires the | ||
implementer of a plugin to develop the "server" side of the go-plugin system. At a high level this looks like: | ||
|
||
``` | ||
+----------------------------------+ +-----------------------------+ | ||
| | | | | ||
| +-------------+ | unix-socket | +-------------+ | | ||
| | | | | | | | | ||
| jaeger-component | grpc-client +----------------------> grpc-server | plugin-impl | | ||
| | | | | | | | | ||
| +-------------+ | | +-------------+ | | ||
| | | | | ||
+----------------------------------+ +-----------------------------+ | ||
parent process child sub-process | ||
``` | ||
|
||
Implementing a plugin | ||
---------------------- | ||
|
||
Although the instructions below are limited to Go, plugins can be implemented any language. Languages other than | ||
Go would implement a gRPC server using the `storage_v1.proto` interfaces. The `proto` file can be found in `plugin/storage/grpc/proto/`. | ||
To generate the bindings for your language you would use `protoc` with the appropriate `xx_out=` flag. This is detailed | ||
in the [protobuf documentation](https://developers.google.com/protocol-buffers/docs/tutorials) and you can see an example of | ||
how it is done for Go in the top level Jaeger `Makefile`. | ||
|
||
There are instructions on implementing a `go-plugin` server for non-Go languages in the | ||
[go-plugin non-go guide](https://github.com/hashicorp/go-plugin/blob/master/docs/guide-plugin-write-non-go.md). | ||
Take note of the required [health check service](https://github.com/hashicorp/go-plugin/blob/master/docs/guide-plugin-write-non-go.md#3-add-the-grpc-health-checking-service). | ||
|
||
A Go plugin is a standalone application which calls `grpc.Serve(&plugin)` in its `main` function, where the `grpc` package | ||
is `github.com/jaegertracing/jaeger/plugin/storage/grpc`. | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"flag" | ||
"github.com/jaegertracing/jaeger/plugin/storage/grpc" | ||
) | ||
|
||
func main() { | ||
var configPath string | ||
flag.StringVar(&configPath, "config", "", "A path to the plugin's configuration file") | ||
flag.Parse() | ||
|
||
plugin := myStoragePlugin{} | ||
|
||
grpc.Serve(&plugin) | ||
} | ||
``` | ||
|
||
A plugin must implement the StoragePlugin interface of: | ||
|
||
```go | ||
type StoragePlugin interface { | ||
SpanReader() spanstore.Reader | ||
SpanWriter() spanstore.Writer | ||
DependencyReader() dependencystore.Reader | ||
} | ||
``` | ||
|
||
As your plugin will be dependent on the protobuf implementation within Jaeger you will likely need to `vendor` your | ||
dependencies, you can also use `go.mod` to achieve the same goal of pinning your plugin to a Jaeger point in time. | ||
|
||
A simple plugin which uses the memstore storage implementation can be found in the `examples` directory of the top level | ||
of the Jaeger project. | ||
|
||
Running with a plugin | ||
--------------------- | ||
A plugin can be run using the `all-in-one` application within the top level `cmd` package of the Jaeger project. To do this | ||
an environment variable must be set to tell the `all-in-one` application to use the gRPC plugin storage: | ||
`export SPAN_STORAGE_TYPE="grpc-plugin"` | ||
|
||
Once this has been set then there are two command line flags that can be used to configure the plugin. The first is | ||
`--grpc-storage-plugin.binary` which is required and is the path to the plugin **binary**. The second is | ||
`--grpc-storage-plugin.configuration-file` which is optional and is the path to the configuration file which will be | ||
provided to your plugin as a command line flag. This command line flag is `config`, as can be seen in the code sample | ||
above. An example invocation would be: | ||
|
||
``` | ||
./all-in-one --grpc-storage-plugin.binary=/path/to/my/plugin --grpc-storage-plugin.configuration-file=/path/to/my/config | ||
``` | ||
|
||
As well as passing configuration values via the command line through the configuration file it is also possible to use | ||
environment variables. When you invoke `all-in-one` any environment variables that have been set will also be accessible | ||
from within your plugin, this is useful if using Docker. | ||
|
||
Logging | ||
------- | ||
If the plugin uses a `hclog` (`"github.com/hashicorp/go-hclog"`) logger then any logs created at the `WARN` or above level will be | ||
included in the log output of the `all-in-one` application. Bear in mind that any logging performed before `grpc.Serve` | ||
is called will not be included. As well as this `grpc.Serve` should likely be called at the end of your `main` function | ||
as once running Jaeger may start calling to read/write spans straight away. This can mean that logging output during any | ||
setup can be challenging. |