Skip to content

Commit

Permalink
docs: Update the quick start guide (#930)
Browse files Browse the repository at this point in the history
* docs: Update the quick start guide

See #775

Co-authored-by: Robb Kidd <[email protected]>

* docs: @robbkidd PR feedback

* Update website_docs/quick_start.md

Co-authored-by: Francis Bogsanyi <[email protected]>

* Update website_docs/manual_instrumentation.md

Co-authored-by: Francis Bogsanyi <[email protected]>

* Update website_docs/quick_start.md

Co-authored-by: Francis Bogsanyi <[email protected]>

* Update website_docs/manual_instrumentation.md

Co-authored-by: Francis Bogsanyi <[email protected]>

* Update website_docs/quick_start.md

Co-authored-by: Francis Bogsanyi <[email protected]>

Co-authored-by: Robb Kidd <[email protected]>
Co-authored-by: Francis Bogsanyi <[email protected]>
  • Loading branch information
3 people authored Sep 22, 2021
1 parent 442b9f0 commit e12dab9
Show file tree
Hide file tree
Showing 8 changed files with 333 additions and 12 deletions.
2 changes: 2 additions & 0 deletions examples/otel-collector/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
OTELCOL_IMG=otel/opentelemetry-collector-contrib-dev:latest
OTELCOL_ARGS=
28 changes: 28 additions & 0 deletions examples/otel-collector/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
version: "2"
services:

# Jaeger
jaeger-all-in-one:
image: jaegertracing/all-in-one:latest
ports:
- "16686:16686"
- "14268"
- "14250"

# Zipkin
zipkin-all-in-one:
image: openzipkin/zipkin:latest
ports:
- "9411:9411"

# Collector
otel-collector:
image: ${OTELCOL_IMG}
command: ["--config=/etc/otel-collector-config.yaml", "${OTELCOL_ARGS}"]
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
ports:
- "4318:4318" # OTLP HTTP Exporter in opentelemetry-ruby is set to 4317 by default
depends_on:
- jaeger-all-in-one
- zipkin-all-in-one
30 changes: 30 additions & 0 deletions examples/otel-collector/otel-collector-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Inspired by https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/examples/demo
receivers:
otlp:
protocols:
http:

exporters:
logging:

zipkin:
endpoint: "http://zipkin-all-in-one:9411/api/v2/spans"
format: proto

jaeger:
endpoint: jaeger-all-in-one:14250
insecure: true

processors:
batch:

service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [logging, zipkin, jaeger]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [logging]
36 changes: 24 additions & 12 deletions website_docs/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ description: >
A language-specific implementation of OpenTelemetry in Ruby.
---

This is the OpenTelemetry for Ruby documentation. OpenTelemetry is an
observability framework -- an API, SDK, and tools that are designed to aid in
the generation and collection of application telemetry data such as metrics,
logs, and traces. This documentation is designed to help you understand how to
get started using OpenTelemetry for Ruby.
This is the OpenTelemetry for Ruby documentation. OpenTelemetry is an observability framework -- an API, SDK, and tools that are designed to aid in the generation and collection of application telemetry data such as metrics, logs, and traces.
This documentation is designed to help you understand how to get started using OpenTelemetry for Ruby.

## Status and Releases

Expand All @@ -19,14 +16,29 @@ as follows:

| Tracing | Metrics | Logging |
| ------- | ------- | ------- |
| Beta | Not Yet Implemented | Not Yet Implemented |
| Release Candidate | Not Yet Implemented | Not Yet Implemented |

The current release can be found [here](https://github.com/open-telemetry/opentelemetry-ruby/releases)
The current release can be found [here][releases]

## Using OpenTelemetry Ruby

- [Quick Start][quick-start]
- [Context Propagation][context-propagation]
- [Span Events][events]
- [Manual Instrumentation][manual-instrumentation]

## Further Reading

- [OpenTelemetry for Ruby on GitHub](https://github.com/open-telemetry/opentelemetry-ruby)
- [Installation](https://github.com/open-telemetry/opentelemetry-ruby#installation)
- [Quick Start](https://github.com/open-telemetry/opentelemetry-ruby#quick-start)
- [API Documentation](https://open-telemetry.github.io/opentelemetry-ruby/)
- [Examples](https://github.com/open-telemetry/opentelemetry-ruby/tree/main/examples)
- [OpenTelemetry for Ruby on GitHub][repository]
- [Ruby API Documentation][ruby-docs]
- [Examples][examples]

[quick-start]: quick_start.md
[repository]: https://github.com/open-telemetry/opentelemetry-ruby
[releases]: https://github.com/open-telemetry/opentelemetry-ruby/releases
[auto-instrumenation]: https://github.com/open-telemetry/opentelemetry-ruby#instrumentation-libraries
[context-propagation]: context_propagation.md
[events]: events.md
[manual-instrumentation]: manual_instrumentation.md
[ruby-docs]: https://open-telemetry.github.io/opentelemetry-ruby/
[examples]: https://github.com/open-telemetry/opentelemetry-ruby/tree/main/examples
34 changes: 34 additions & 0 deletions website_docs/context_propagation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
title: "Ruby Context Propagation"
weight: 24
description: >
<img width="35" src="https://raw.github.com/open-telemetry/opentelemetry.io/main/iconography/32x32/Ruby_SDK.svg"></img>
A language-specific implementation of OpenTelemetry in Ruby.
---

## Context Propagation

> Distributed Tracing tracks the progression of a single Request, called a Trace, as it is handled by Services that make up an Application. A Distributed Trace transverses process, network and security boundaries. [glossary][glossary]
This requires _context propagation_, a mechanism where identifiers for a trace are sent to remote processes.

> &#8505; The OpenTelemetry Ruby SDK will take care of context propagation as long as your service is leveraging auto-instrumented libraries. Please refer to the [README][auto-instrumentation] for more details.
In order to propagate trace context over the wire, a propagator must be registered with the OpenTelemetry SDK.
The W3 TraceContext and Baggage propagators are configured by default.
Operators may override this value by setting `OTEL_PROPAGATORS` environment variable to a comma separated list of [propagators][propagators].
For example, to add B3 propagation, set `OTEL_PROPAGATORS` to the complete list of propagation formats you wish to support:

```sh
export OTEL_PROPAGATORS=tracecontext,baggage,b3
```

Propagators other than `tracecontext` and `baggage` must be added as gem dependencies to your Gemfile, e.g.:

```ruby
gem 'opentelemetry-propagator-b3'
```

[glossary]: https://opentelemetry.io/docs/concepts/glossary/
[propagators]: https://github.com/open-telemetry/opentelemetry-ruby/tree/main/propagator
[auto-instrumentation]: https://github.com/open-telemetry/opentelemetry-ruby/tree/main/instrumentation
30 changes: 30 additions & 0 deletions website_docs/events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: "Ruby Span Events"
weight: 24
description: >
<img width="35" src="https://raw.github.com/open-telemetry/opentelemetry.io/main/iconography/32x32/Ruby_SDK.svg"></img>
A language-specific implementation of OpenTelemetry in Ruby.
---

## Events

An event is a human-readable message on a span that represents "something happening" during it's lifetime. For example, imagine a function that requires exclusive access to a resource that is under a mutex. An event could be created at two points - once, when we try to gain access to the resource, and another when we acquire the mutex.

```ruby
span.add_event("Acquiring lock")
if mutex.try_lock
span.add_event("Got lock, doing work...")
# some code here
span.add_event("Releasing lock")
else
span.add_event("Lock already in use")
end
```

A useful characteristic of events is that their timestamps are displayed as offsets from the beginning of the span, allowing you to easily see how much time elapsed between them.

Events can also have attributes of their own e.g.

```ruby
span.add_event("Cancelled wait due to external signal", attributes: { "pid" => 4328, "signal" => "SIGHUP" })
```
89 changes: 89 additions & 0 deletions website_docs/manual_instrumentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
title: "Ruby Manual Instrumentation"
weight: 24
description: >
<img width="35" src="https://raw.github.com/open-telemetry/opentelemetry.io/main/iconography/32x32/Ruby_SDK.svg"></img>
A language-specific implementation of OpenTelemetry in Ruby.
---

## Adding Manual Instrumentation

Auto-instrumentation is the easiest way to get started with instrumenting your code, but in order to get the most insight into your system, you should add manual instrumentation where appropriate.
To do this, use the OpenTelemetry SDK to access the currently executing span and add attributes to it, and/or to create new spans.

### Adding Context to Exisiting Spans

It's often beneficial to add context to a currently executing span in a trace.
For example, you may have an application or service that handles extended warranties, and you want to associate it with the span when querying your tracing datastore.
In order to do this, get the current span from the context and set an attribute with your application's domain specific data:

```ruby
def track_extended_warranty(extended_warranty)
current_span = OpenTelemetry::Trace.current_span
current_span.add_attributes({
"com.extended_warranty.id" => extended_warranty.id,
"com.extended_warranty.timestamp" => extended_warranty.timestamp
})
end
```

### Creating New Spans

Auto-instrumentation can show the shape of requests to your system, but only you know the really important parts.
In order to get the full picture of what's happening, you will have to add manual instrumentation and create some custom spans.
To do this, grab the tracer from the OpenTelemetry API and generate a span:

```ruby
# ...

def search_by(query)
tracer = OpenTelemetry.tracer_provider.tracer('my-tracer')
tracer.in_span("search_by") do |span|
# ... expensive query
end
end
```

The `in_span` convenience method is unique to Ruby implementation, which reduces some of the boilerplate code that you would have to otherwise write yourself:

```ruby
def search_by(query)
span = tracer.start_span("search_by", kind: :internal)
OpenTelemetry::Trace.with_span(span) do |span, context|
# ... expensive query
end
rescue Exception => e
span&.record_exception(e)
span&.status = OpenTelemetry::Trace::Status.error("Unhandled exception of type: #{e.class}")
raise e
ensure
span&.finish
end
```

### Attributes

Attributes are keys and values that are applied as metadata to your spans and are useful for aggregating, filtering, and grouping traces. Attributes can be added at span creation, or at any other time during the lifecycle of a span before it has completed.

```ruby
# setting attributes at creation...
tracer.in_span('foo', attributes: { "hello" => "world", "some.number" => 1024, "tags" => [ "bugs", "won't fix" ] }, kind: :internal) do |span|

# ... and after creation
span.set_attribute("animals", ["elephant", "tiger"])

span.add_attributes({ "my.cool.attribute" => "a value", "my.first.name" => "Oscar" })
end
```

> &#9888; Spans are thread safe data structures that require locks when they are mutated.
> You should therefore avoid calling `set_attribute` multiple times and instead assign attributes in bulk with a Hash, either during span creation or with `add_attributes` on an existing span.
#### Semantic Attributes

Semantic Attributes are attributes that are defined by the OpenTelemetry Specification in order to provide a shared set of attribute keys across multiple languages, frameworks, and runtimes for common concepts like HTTP methods, status codes, user agents, and more. These attributes are available in the [Semantic Conventions gem][semconv-gem].

Tracing semantic conventions can be found in [this document][semconv-spec]

[semconv-gem]: https://github.com/open-telemetry/opentelemetry-ruby/tree/main/semantic_conventions
[semconv-spec]: https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions
96 changes: 96 additions & 0 deletions website_docs/quick_start.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
---
title: "Ruby Quick Start Guide"
weight: 24
description: >
<img width="35" src="https://raw.github.com/open-telemetry/opentelemetry.io/main/iconography/32x32/Ruby_SDK.svg"></img>
A language-specific implementation of OpenTelemetry in Ruby.
---

## Quick Start

[OpenTelemetry for Ruby][repository] can be used to add automatic and manual instrumentation to your applications.
Automatic instrumentation is enabled by adding [instrumentation packages][auto-instrumentation].
Manual instrumentation can be added using the [OpenTelemetry API][manual-instrumentation].

### Requirements

These instructions will explain how to set up automatic and manual instrumentation for a Ruby service.
In order to follow along, you will need:

- Ruby 2.5 or higher
- Docker Compose

### Installation

The first step is to add these gems to your Gemfile:

```ruby
gem 'opentelemetry-sdk'
gem 'opentelemetry-exporter-otlp'
gem 'opentelemetry-instrumentation-all'
```

The inclusion of `opentelemetry-instrumentation-all` in the above list provides instrumentations for several frameworks such as Rails and Sinatra as well as database drivers and HTTP [libraries][auto-instrumentation].

### Initialization

The OpenTelemetry initialization needs to happen early in your application lifecycle.
For Rails applications, the usual way to initialize OpenTelemetry is in a Rails initializer.
For other Ruby services, perform this initialization as early as possible in the start-up process.

OpenTelemetry initialization:

```ruby
# config/initializers/opentelemetry.rb
require 'opentelemetry/sdk'
require 'opentelemetry/exporter/otlp'
require 'opentelemetry/instrumentation/all'
OpenTelemetry::SDK.configure do |c|
c.service_name = '<YOUR_SERVICE_NAME>'
c.use_all() # enables all instrumentation!
end
```

Now that you have setup your application to perform tracing, you'll need to configure the SDK to export the traces somewhere. Our example loaded the `OTLP` exporter, which the SDK tries to use by default. Next, we'll use the OpenTelemetry Collector to receive these traces and visualize them using Jaeger and Zipkin!

### Exporting Traces

The following section assumes you are new to OpenTelemetry or do not currently use a vendor that supports distributed tracing using OTLP. Please refer to your vendor's product documentation if you would like to export your traces to a vendor for analysis and vizualization.

For the purposes of this tutorial you will configure an OpenTelemetry collector that will receive the traces and vizualize them using Jaeger or Zipkin UI.

First, start up an example system:

```bash
$> git clone [email protected]:open-telemetry/opentelemetry-ruby.git; \
cd open-telemetry-ruby/examples/otel-collector; \
docker-compose up -d
```

Next, you'll have to let the SDK know where the collector endpoint is to receive traces.
Set the [`OTEL_EXPORTER_OTLP_ENDPOINT`][sdk-env] environment variable to `http://localhost:4318/v1/traces`:

```bash
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/traces
```

Now, start up your application and perform a few operations to generate tracing data, e.g. navigate around your web app or kick off background tasks.

Lastly, open a browser and navigate to the [Jaeger UI](http://localhost:16686) or [Zipkin UI](http://localhost:9411) and search for traces related to your service, which were generated by the auto-instrumentation features of OpenTelemetry!

### Achievement Unlocked: Tracing Enabled

Adding tracing to a single service is a great first step and although auto-instrumenation provides quite a bit of insight on its own, OpenTelemetry provides a few more features that will allow you gain even deeper insights!

[Context Propagation][context-propagation] is perhaps one of the most powerful concepts in OpenTelemetry because it will upgrade your single service trace into a _distributed trace_, which makes it possible for OpenTelemetry vendors to visualize a request from end-to-end accross process and network boundaries.

[Span Events][events] allow you to add a human-readable message on a span that represents "something happening" during its lifetime.

[Manual Instrumentation][manual-instrumentation] will give provide you the ability to enrich your traces with domain specific data.

[repository]: https://github.com/open-telemetry/opentelemetry-ruby
[auto-instrumentation]: https://github.com/open-telemetry/opentelemetry-ruby#instrumentation-libraries
[sdk-env]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options
[context-propagation]: context_propagation.md
[events]: events.md
[manual-instrumentation]: manual_instrumentation.md

0 comments on commit e12dab9

Please sign in to comment.