Skip to content

Commit

Permalink
Merge pull request #80 from instana/minor_readme_updates
Browse files Browse the repository at this point in the history
Minor readme updates
  • Loading branch information
Andrew Slotin authored Feb 5, 2020
2 parents 37630c4 + 3b96bb7 commit eb476ac
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 40 deletions.
81 changes: 44 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,111 +9,115 @@ The Instana Go sensor consists of two parts:
* [OpenTracing](http://opentracing.io) tracer

[![Build Status](https://travis-ci.org/instana/go-sensor.svg?branch=master)](https://travis-ci.org/instana/go-sensor)
[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/instana/go-sensor)
[![OpenTracing Badge](https://img.shields.io/badge/OpenTracing-enabled-blue.svg)](http://opentracing.io)

## Common Operations

The Instana Go sensor offers a set of quick features to support tracing of the most common operations like handling HTTP requests and executing HTTP requests.

To create an instance of the Instana sensor just request a new instance using the _instana.NewSensor_ factory method and providing the name of the application. It is recommended to use a single Instana only. The sensor implementation is fully thread-safe and can be shared by multiple threads.
To create an instance of the Instana sensor just request a new instance using the `instana.NewSensor` factory method and providing the name of the application. It is recommended to use a single Instana only. The sensor implementation is fully thread-safe and can be shared by multiple threads.

```go
var sensor = instana.NewSensor("my-service")
```

A full example can be found under the examples folder in _example/webserver/instana/http.go_.
A full example can be found under the examples folder in [example/webserver/instana/http.go](./example/webserver/instana/http.go).

### HTTP Server Handlers

With support to wrap a _http.HandlerFunc_, Instana quickly adds the possibility to trace requests and collect child spans, executed in the context of the request span.
With support to wrap a `http.HandlerFunc`, Instana quickly adds the possibility to trace requests and collect child spans, executed in the context of the request span.

Minimal changes are required for Instana to be able to capture the necessary information. By simply wrapping the currently existing _http.HandlerFunc_ Instana collects and injects necessary information automatically.
Minimal changes are required for Instana to be able to capture the necessary information. By simply wrapping the currently existing `http.HandlerFunc` Instana collects and injects necessary information automatically.

That said, a simple handler function like the following will simple be wrapped and registered like normal.

For your own preference registering the handler and wrapping it can be two separate steps or a single one. The following example code shows both versions, starting with two steps.

```go
import (
"net/http"
instana "github.com/instana/go-sensor"
ot "github.com/opentracing/opentracing-go"

instana "github.com/instana/go-sensor"
ot "github.com/opentracing/opentracing-go"
)

// Doing registration and wrapping in two separate steps
func main() {
http.HandleFunc(
"/path/to/handler",
sensor.TracingHandler("myHandler", myHandler),
)
http.HandleFunc(
"/path/to/handler",
sensor.TracingHandler("myHandler", myHandler),
)
}

// Doing registration and wrapping in a single step
func main() {
http.HandleFunc(
sensor.TraceHandler("myHandler", "/path/to/handler", myHandler),
)
http.HandleFunc(
sensor.TraceHandler("myHandler", "/path/to/handler", myHandler),
)
}

// Accessing the parent request inside a handler
func myHandler(w http.ResponseWriter, req. *http.Request) {
ctx := req.Context()
parentSpan := ctx.Value("parentSpan").(ot.Span) // use this TracingHttpRequest
tracer := parent.Tracer()
spanCtx := parent.Context().(instana.SpanContext)
traceID := spanCtx.TraceID // use this with EumSnippet
func myHandler(w http.ResponseWriter, req *http.Request) {
ctx := req.Context()
parentSpan := ctx.Value("parentSpan").(ot.Span) // use this TracingHttpRequest
tracer := parent.Tracer()
spanCtx := parent.Context().(instana.SpanContext)
traceID := spanCtx.TraceID // use this with EumSnippet
}
```

### Executing HTTP Requests

Requesting data or information from other, often external systems, is commonly implemented through HTTP requests. To make sure traces contain all spans, especially over all the different systems, certain span information have to be injected into the HTTP request headers before sending it out. Instana's Go sensor provides support to automate this process as much as possible.

To have Instana inject information into the request headers, create the _http.Request_ as normal and wrap it with the Instana sensor function as in the following example.
To have Instana inject information into the request headers, create the `http.Request` as normal and wrap it with the Instana sensor function as in the following example.

```go
req, err := http.NewRequest("GET", url, nil)
client := &http.Client{}
resp, err := sensor.TracingHttpRequest(
"myExternalCall",
parentSpan,
req,
client
"myExternalCall",
parentSpan,
req,
client,
)
```

The provided _parentSpan_ is the incoming request from the request handler (see above) and provides the necessary tracing and span information to create a child span and inject it into the request.
The provided `parentSpan` is the incoming request from the request handler (see above) and provides the necessary tracing and span information to create a child span and inject it into the request.

The request is, after injection, executing using the provided _http.Client_ instance. Like the normal _client.Do_ operation, the call will return a _http.Response_ instance or an error proving information of the failure reason.
The request is, after injection, executing using the provided `http.Client` instance. Like the normal `(*http.Client).Do()` operation, the call will return a `http.Response` instance or an error proving information of the failure reason.

## Sensor

To use sensor only without tracing ability, import the `instana` package and run

```Go
```go
instana.InitSensor(opt)
```

in your main function. The init function takes an `Options` object with the following optional fields:

* **Service** - global service name that will be used to identify the program in the Instana backend
* **AgentHost**, **AgentPort** - default to localhost:42699, set the coordinates of the Instana proxy agent
* **LogLevel** - one of Error, Warn, Info or Debug
* **AgentHost**, **AgentPort** - default to `localhost:42699`, set the coordinates of the Instana proxy agent
* **LogLevel** - one of `Error`, `Warn`, `Info` or `Debug`

Once initialized, the sensor will try to connect to the given Instana agent and in case of connection success will send metrics and snapshot information through the agent to the backend.

## OpenTracing

In case you want to use the OpenTracing tracer, it will automatically initialize the sensor and thus also activate the metrics stream. To activate the global tracer, run for example

```Go
```go
ot.InitGlobalTracer(instana.NewTracerWithOptions(&instana.Options{
Service: SERVICE,
LogLevel: instana.DEBUG}))
LogLevel: instana.DEBUG,
}))
```

in your main function. The tracer takes the same options that the sensor takes for initialization, described above.

The tracer is able to protocol and piggyback OpenTracing baggage, tags and logs. Only text mapping is implemented yet, binary is not supported. Also, the tracer tries to map the OpenTracing spans to the Instana model based on OpenTracing recommended tags. See `simple` example for details on how recommended tags are used.
The tracer is able to protocol and piggyback OpenTracing baggage, tags and logs. Only text mapping is implemented yet, binary is not supported. Also, the tracer tries to map the OpenTracing spans to the Instana model based on OpenTracing recommended tags. See [simple.go](./example/ot-simple/simple.go) example for details on how recommended tags are used.

The Instana tracer will remap OpenTracing HTTP headers into Instana Headers, so parallel use with some other OpenTracing model is not possible. The Instana tracer is based on the OpenTracing Go basictracer with necessary modifications to map to the Instana tracing model. Also, sampling isn't implemented yet and will be focus of future work.

Expand All @@ -125,9 +129,12 @@ To learn more, see the [Events API](https://github.com/instana/go-sensor/blob/ma

## Examples

Following examples are included in the `examples` folder:
Following examples are included in the `example` folder:

* **ot-simple/simple.go** - Demonstrates basic usage of the tracer
* **webserver/http.go** - Demonstrates how http server and client should be instrumented
* **rpc/rpc.go** - Demonstrates a basic RPC service
* **event/** - Demonstrates usage of the event API
* [ot-simple/simple.go](./example/ot-simple/simple.go) - Demonstrates basic usage of the tracer
* [webserver/http.go](./example/webserver/http.go) - Demonstrates how http server and client should be instrumented
* [rpc/rpc.go](./example/rpc/rpc.go) - Demonstrates a basic RPC service
* [event/](./example/event/) - Demonstrates usage of the Events API
* [database/elasticsearch.go](./example/database/elasticsearch.go) - Demonstrates how to instrument a database client (Elasticsearch in this case)
* [httpclient/multi_request.go](./example/httpclient/multi_request.go) - Demonstrates the instrumentation of an HTTP client
* [many.go](./example/many.go) - Demonstrates how to create nested spans within the same execution context
6 changes: 3 additions & 3 deletions example/many.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ func simple(ctx context.Context) {
parentSpan.SetTag(string(ext.HTTPUrl), "/golang/many/one")
parentSpan.SetTag(string(ext.HTTPMethod), "GET")
parentSpan.SetTag(string(ext.HTTPStatusCode), 200)
parentSpan.LogFields(
log.String("foo", "bar"))
parentSpan.LogFields(log.String("foo", "bar"))

childSpan := ot.StartSpan("child", ot.ChildOf(parentSpan.Context()))
childSpan.SetTag(string(ext.SpanKind), string(ext.SpanKindRPCClientEnum))
Expand All @@ -46,7 +45,8 @@ func main() {
ot.InitGlobalTracer(instana.NewTracerWithOptions(&instana.Options{
Service: Service,
ForceTransmissionStartingAt: 10000,
LogLevel: instana.Debug}))
LogLevel: instana.Debug,
}))

go forever()
go forever()
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module github.com/instana/go-sensor

go 1.7

require (
github.com/felixge/httpsnoop v1.0.0
github.com/gogo/protobuf v1.2.1 // indirect
Expand Down

0 comments on commit eb476ac

Please sign in to comment.