Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/solarwinds/apm-go
OpenTelemetry-based SolarWinds APM Go library
https://github.com/solarwinds/apm-go
Last synced: 4 days ago
JSON representation
OpenTelemetry-based SolarWinds APM Go library
- Host: GitHub
- URL: https://github.com/solarwinds/apm-go
- Owner: solarwinds
- License: apache-2.0
- Created: 2023-09-14T09:23:13.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-10-30T22:42:56.000Z (15 days ago)
- Last Synced: 2024-10-30T23:22:04.457Z (15 days ago)
- Language: Go
- Homepage:
- Size: 6.33 MB
- Stars: 3
- Watchers: 4
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Codeowners: CODEOWNERS
- Security: SECURITY.md
Awesome Lists containing this project
README
# SolarWinds APM Go
## Getting started
ℹ️ Check out the [usage examples](examples) to see how easy it is to get
started. The following code snippets are adapted from the [http
example](examples/http).To use in your Go project:
### Initialize the library
```go
// Initialize the SolarWinds APM library
cb, err := swo.Start(
// Optionally add service-level resource attributes
semconv.ServiceName("my-service"),
semconv.ServiceVersion("v0.0.1"),
attribute.String("environment", "testing"),
)
if err != nil {
// Handle error
}
// This function returned from `Start()` will tell the apm library to
// shut down, often deferred until the end of `main()`.
defer cb()
```### Instrument your code
Many packages have instrumentation-enabled versions. We provide a simple
wrapper for `net/http` server requests. Here's an example:```go
// Create a new handler to respond to any request with the text it was given
echoHandler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
if text, err := io.ReadAll(req.Body); err != nil {
// The `trace` package is from the OpenTelemetry Go SDK. Here we
// retrieve the current span for this request...
span := trace.SpanFromContext(req.Context())
// ...so that we can record the error.
span.RecordError(err)
span.SetStatus(codes.Error, "failed to read body")
w.WriteHeader(http.StatusInternalServerError)
} else {
// If no error, we simply echo back.
_, _ = w.Write(text)
}
})
mux := http.NewServeMux()
// Wrap the route handler with otelhttp instrumentation, adding the route tag
mux.Handle("/echo", otelhttp.WithRouteTag("/echo", echoHandler))
// Wrap the mux (base handler) with our instrumentation
http.ListenAndServe(":8080", swohttp.WrapBaseHandler(mux, "server"))
```There are many instrumented libraries available. Here are the libraries we
currently support:* Any of the instrumentation in [opentelemetry-go-contrib
](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/instrumentation)
* _Caveat_: For `net/http` servers, it's best to use our wrapper (as seen
in the above example) to correctly attribute distributed trace data.
* For SQL: [XSAM/otelsql](https://github.com/XSAM/otelsql)OpenTelemetry provides a
[registry](https://opentelemetry.io/ecosystem/registry/?language=go&component=instrumentation)
for these libraries, just note that each is at a different maturity
level, as the OpenTelemetry landscape is developing at a rapid pace.### Manual instrumentation
You may also [manually
instrument](https://opentelemetry.io/docs/instrumentation/go/manual/) your code
using the OpenTelemetry SDK and it will be properly propagated to SolarWinds
Observability.To create a new Span, first acquire a `Tracer`. Often, this will be a
package-level variable.```go
tracer := otel.GetTracerProvider().Tracer("example.com/foo")
```Next, create a Span and defer its `End()`
```go
func myFunc(ctx context.Context) {
ctx, span := tracer.Start(ctx, "span name here")
defer span.End()
// ...do some work
}
```In this example, the span will be created at the beginning of the function and
ended at the end of the function (via [defer](https://go.dev/tour/flowcontrol/12)).Span context is propagated via [`context.Context`](https://pkg.go.dev/context),
making it easy to nest spans:```go
ctx, spanA := tracer.Start(ctx, "outer span")
defer spanA.End()
ctx, spanB := tracer.Start(ctx, "inner span")
defer spanB.End()
```### Configuration
The only environment variable you need to set before kicking off is the service key:
| Variable Name | Required | Description |
|--------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------|
| SW_APM_SERVICE_KEY | Yes | The service key identifies the service being instrumented within your Organization. It should be in the form of ``:``. |## Compatibility
We support the same environments as
[OpenTelemetry-Go](https://github.com/open-telemetry/opentelemetry-go#compatibility).## License
Copyright (C) 2023 SolarWinds, LLC
Released under [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0)
## Miscellaneous
Originally forked from the [appoptics-apm-go](https://github.com/appoptics/appoptics-apm-go) repository.