Skip to content

Commit

Permalink
Add http client/server example (#131)
Browse files Browse the repository at this point in the history
  • Loading branch information
elskwid authored and fbogsany committed Nov 12, 2019
1 parent 8d55c57 commit 1bc697c
Show file tree
Hide file tree
Showing 8 changed files with 200 additions and 1 deletion.
5 changes: 5 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ services:
context: .
working_dir: /app

ex-http:
<<: *base
command: ./start_server.sh
working_dir: /app/examples/http

sdk:
<<: *base
working_dir: /app/sdk
Expand Down
8 changes: 8 additions & 0 deletions examples/http/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

source "https://rubygems.org"

gem "faraday", "~> 0.16.1"
gem "opentelemetry-api", path: "../../api"
gem "opentelemetry-sdk", path: "../../sdk"
gem "sinatra", "~> 2.0"
39 changes: 39 additions & 0 deletions examples/http/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
PATH
remote: ../../api
specs:
opentelemetry-api (0.0.0)

PATH
remote: ../../sdk
specs:
opentelemetry-sdk (0.0.0)
opentelemetry-api (~> 0.0)

GEM
remote: https://rubygems.org/
specs:
faraday (0.16.2)
multipart-post (>= 1.2, < 3)
multipart-post (2.1.1)
mustermann (1.0.3)
rack (2.0.7)
rack-protection (2.0.7)
rack
sinatra (2.0.7)
mustermann (~> 1.0)
rack (~> 2.0)
rack-protection (= 2.0.7)
tilt (~> 2.0)
tilt (2.0.10)

PLATFORMS
ruby

DEPENDENCIES
faraday (~> 0.16.1)
opentelemetry-api!
opentelemetry-sdk!
sinatra (~> 2.0)

BUNDLED WITH
2.0.2
21 changes: 21 additions & 0 deletions examples/http/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# OpenTelemetry Ruby Example

## HTTP

This is a simple example that demonstrates tracing an HTTP request from client to server. The example shows several aspects of tracing, such as:

* Using the `TracerFactory`
* Span Attributes
* Using the console exporter

### Running the example

The example uses Docker Compose to make it a bit easier to get things up and running.

1. Follow the `Developer Setup` instructions in [the main README](../../README.md)
1. Run the server using the `ex-http` compose service
* `docker-compose run ex-http`
1. After a few seconds, an interactive shell should appear
1. Run the client
* `./client.rb`
1. You should see console exporter output for both the client and server sessions
49 changes: 49 additions & 0 deletions examples/http/client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

# Copyright 2019 OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0
require 'rubygems'
require 'bundler/setup'
require 'faraday'
# Require otel-ruby
require 'opentelemetry/sdk'

# Allow setting the host from the ENV
host = ENV.fetch('HTTP_EXAMPLE_HOST', '0.0.0.0')

SDK = OpenTelemetry::SDK
OpenTelemetry.tracer_factory = SDK::Trace::TracerFactory.new

# Configure tracer
exporter = SDK::Trace::Export::ConsoleSpanExporter.new
processor = SDK::Trace::Export::SimpleSpanProcessor.new(exporter)
OpenTelemetry.tracer_factory.add_span_processor(processor)
tracer = OpenTelemetry.tracer_factory.tracer('faraday', 'semver:1.0')
formatter = OpenTelemetry.tracer_factory.http_text_format

connection = Faraday.new("http://#{host}:4567")
url = '/hello'

# For attribute naming, see:
# https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-semantic-conventions.md#http-client

# Span name should be set to URI path value:
tracer.in_span(
url,
attributes: {
'component' => 'http',
'http.method' => 'GET',
},
kind: :client
) do |span|
response = connection.get(url) do |request|
# Inject context into request headers
formatter.inject(span.context, request.headers)
end

span.set_attribute('http.url', response.env.url.to_s)
span.set_attribute('http.status_code', response.status)
span.set_attribute('http.status_text', response.reason_phrase)
end
73 changes: 73 additions & 0 deletions examples/http/server.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

# Copyright 2019 OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

require 'rubygems'
require 'bundler/setup'
require 'sinatra/base'
# Require otel-ruby
require 'opentelemetry/sdk'

SDK = OpenTelemetry::SDK
OpenTelemetry.tracer_factory = SDK::Trace::TracerFactory.new

exporter = SDK::Trace::Export::ConsoleSpanExporter.new
processor = SDK::Trace::Export::SimpleSpanProcessor.new(exporter)
OpenTelemetry.tracer_factory.add_span_processor(processor)

# Rack middleware to extract span context, create child span, and add
# attributes/events to the span
class OpenTelemetryMiddleware
def initialize(app)
@app = app
@formatter = OpenTelemetry.tracer_factory.http_text_format
@tracer = OpenTelemetry.tracer_factory.tracer('sinatra', 'semver:1.0')
end

def call(env)
# Extract context from request headers
context = @formatter.extract(env)

status, headers, response_body = 200, {}, ''

# Span name SHOULD be set to route:
span_name = env['PATH_INFO']

# For attribute naming, see
# https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-semantic-conventions.md#http-server

# Span kind MUST be `:server` for a HTTP server span
@tracer.in_span(
span_name,
attributes: {
'component' => 'http',
'http.method' => env['REQUEST_METHOD'],
'http.route' => env['PATH_INFO'],
'http.url' => env['REQUEST_URI'],
},
kind: :server,
with_parent_context: context
) do |span|
# Run application stack
status, headers, response_body = @app.call(env)

span.set_attribute('http.status_code', status)
end

[status, headers, response_body]
end
end

class App < Sinatra::Base
set :bind, '0.0.0.0'
use OpenTelemetryMiddleware

get '/hello' do
'Hello World!'
end

run! if app_file == $0
end
4 changes: 4 additions & 0 deletions examples/http/start_server.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#! /bin/bash

# Start the server, wait a bit, and provide a command line to run the client
./server.rb & (sleep 5; /bin/bash)
2 changes: 1 addition & 1 deletion sdk/lib/opentelemetry/sdk/trace/tracer_factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module OpenTelemetry
module SDK
module Trace
# {TracerFactory} is the SDK implementation of {OpenTelemetry::Trace::TracerFactory}.
class TracerFactory
class TracerFactory < OpenTelemetry::Trace::TracerFactory
Key = Struct.new(:name, :version)
private_constant(:Key)

Expand Down

0 comments on commit 1bc697c

Please sign in to comment.