Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AO-16209 otel tracer #174

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4cae6a5
[otTrace] stubs for Provider, Tracer, Span, etc
jiwen624 May 6, 2020
1fd3b33
[otTrace] Provider implementation
jiwen624 May 6, 2020
b1bbfcb
[otTrace] tracer prototype
jiwen624 May 7, 2020
460d154
[otTrace] span prototype
jiwen624 May 7, 2020
8445526
[otTrace] store span in context
jiwen624 May 8, 2020
ccfdc58
[otTrace] fix bugs in event report
jiwen624 May 8, 2020
23b1b02
[otTrace] gRPC span context injection/extraction
jiwen624 May 8, 2020
464d627
[otTrace] OT span start/end timestamp
jiwen624 May 8, 2020
f21fe75
Merge branch 'master' into AO-16209-otel-tracer
jiwen624 Apr 9, 2021
9970f1a
[otTrace] comly with api changes
jiwen624 Apr 12, 2021
b757e47
update go versions
jiwen624 Apr 12, 2021
277aee7
fix nil context test case
jiwen624 Apr 12, 2021
ee5722f
[otTrace] report attributes and errors
jiwen624 Apr 12, 2021
6b2835b
[otTrace] add event
jiwen624 Apr 14, 2021
ab68a4b
[otTrace] add event attributes
jiwen624 Apr 14, 2021
b4e96b6
misc updates
jiwen624 Apr 16, 2021
92eff7c
[otTracer] remove ot context check
jiwen624 Apr 19, 2021
ce17402
[otTracer] sample app for ot
jiwen624 Apr 23, 2021
5d94dc8
[otTracer] gin demo app
jiwen624 Apr 23, 2021
53ae2de
[otTracer] distributed demo app
jiwen624 Apr 24, 2021
857aa46
[otTracer] demo app otto
jiwen624 Apr 26, 2021
a5e7b14
[otTracer] xtrace text map propagator
jiwen624 Apr 27, 2021
db13e0c
[otTracer] set AO text map propagator in demo app
jiwen624 Apr 28, 2021
862b3c2
[otTracer] gin app set text map propagator
jiwen624 Apr 29, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
goversion: ['1.12', '1.13', '1.14', '1.15']
goversion: ['1.14', '1.15', '1.16']
name: Go ${{ matrix.goversion }} tests
env:
GO15VENDOREXPERIMENT: 1
Expand Down
4 changes: 4 additions & 0 deletions examples/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ require (
github.com/gin-gonic/gin v1.6.3
github.com/opentracing/opentracing-go v1.1.0
github.com/stretchr/testify v1.7.0
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.19.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.19.0
go.opentelemetry.io/otel v0.19.0
go.opentelemetry.io/otel/trace v0.19.0
)

replace github.com/appoptics/appoptics-apm-go => ../
83 changes: 51 additions & 32 deletions examples/go.sum

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions examples/otel/distributed_app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
distributed_app
bob/bob
11 changes: 11 additions & 0 deletions examples/otel/distributed_app/alice/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM golang:1.12

# Based on https://hub.docker.com/_/golang/
WORKDIR /go/src/app
COPY . .
RUN go-wrapper download
RUN go-wrapper install

# Start app. APPOPTICS_SERVICE_KEY must be set to enable AppOptics.
CMD /go/bin/app -testClients true -addr :8890
EXPOSE 8890
123 changes: 123 additions & 0 deletions examples/otel/distributed_app/alice/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Test web app
// Wraps a standard HTTP handler with AppOptics instrumentation

package main

import (
"fmt"
"io/ioutil"
"log"
"math/rand"
"net/http"
"sync"

"context"

"github.com/appoptics/appoptics-apm-go/v1/ao"
)

// hard-coded service discovery
var urls = []string{
"http://bob:8081/bob",
"http://carol:8082/carol",
"http://dave:8083/",
"http://otto:8084/otto",
}

func aliceHandler(w http.ResponseWriter, r *http.Request) {
// trace this request, overwriting w with wrapped ResponseWriter
t, w, r := ao.TraceFromHTTPRequestResponse("aliceHandler", w, r)
ctx := ao.NewContext(context.Background(), t)
defer t.End()
log.Printf("%s %s", r.Method, r.URL)

// call an HTTP endpoint and propagate the distributed trace context
url := urls[rand.Intn(len(urls))]

// create HTTP client and set trace metadata header
httpClient := &http.Client{}
httpReq, _ := http.NewRequest("GET", url, nil)
// begin layer for the client side of the HTTP service request
l := ao.BeginHTTPClientSpan(ctx, httpReq)

// make HTTP request to external API
resp, err := httpClient.Do(httpReq)
l.AddHTTPResponse(resp, err)
if err != nil {
w.WriteHeader(500)
w.Write([]byte(fmt.Sprintf("err: %v", err)))
l.End() // end HTTP client timing
return
}

// read response body
defer resp.Body.Close()
buf, err := ioutil.ReadAll(resp.Body)
l.End() // end HTTP client timing
//w.WriteHeader(200)
if err != nil {
w.Write([]byte(`{"error":true}`))
} else {
w.Write(buf) // return API response to caller
}
}

func concurrentAliceHandler(w http.ResponseWriter, r *http.Request) {
// trace this request, overwriting w with wrapped ResponseWriter
t, w, _ := ao.TraceFromHTTPRequestResponse("aliceHandler", w, r)
ctx := ao.NewContext(context.Background(), t)
t.SetAsync(true)
defer t.End()

// call an HTTP endpoint and propagate the distributed trace context
var wg sync.WaitGroup
wg.Add(len(urls))
var out []byte
outCh := make(chan []byte)
doneCh := make(chan struct{})
go func() {
for buf := range outCh {
out = append(out, buf...)
}
close(doneCh)
}()
for _, u := range urls {
go func(url string) {
// create HTTP client and set trace metadata header
client := &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
// begin layer for the client side of the HTTP service request
l := ao.BeginHTTPClientSpan(ctx, req)

// make HTTP request to external API
resp, err := client.Do(req)
l.AddHTTPResponse(resp, err)
if err != nil {
l.End() // end HTTP client timing
w.WriteHeader(500)
return
}
// read response body
defer resp.Body.Close()
buf, err := ioutil.ReadAll(resp.Body)
l.End() // end HTTP client timing
if err != nil {
outCh <- []byte(fmt.Sprintf(`{"error":"%v"}`, err))
} else {
outCh <- buf
}
wg.Done()
}(u)
}
wg.Wait()
close(outCh)
<-doneCh

w.Write(out)
}

func main() {
http.HandleFunc("/alice", aliceHandler)
http.HandleFunc("/concurrent", concurrentAliceHandler)
http.ListenAndServe(":8890", nil)
}
27 changes: 27 additions & 0 deletions examples/otel/distributed_app/alice/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main_test

import (
"io/ioutil"
"net/http"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestClient(t *testing.T) {
if testing.Short() {
t.Skip("Skipping this test case in short mode")
}
// run distributed_app server

// test request to distributed_app example
httpClient := &http.Client{}
resp, err := httpClient.Get("http://127.0.0.1:8890/lookup")
require.NoError(t, err)
defer resp.Body.Close()

body, err := ioutil.ReadAll(resp.Body)
assert.NoError(t, err)
t.Logf("httpClient.Do body: %v, err: %v", string(body), err)
}
11 changes: 11 additions & 0 deletions examples/otel/distributed_app/bob/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM golang:1.12

# Based on https://hub.docker.com/_/golang/
WORKDIR /go/src/app
COPY . .
RUN go-wrapper download
RUN go-wrapper install

# Start app. APPOPTICS_SERVICE_KEY must be set to enable AppOptics.
CMD /go/bin/app -addr :8081
EXPOSE 8081
21 changes: 21 additions & 0 deletions examples/otel/distributed_app/bob/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Test web app
// Wraps a standard HTTP handler with AppOptics instrumentation

package main

import (
"log"
"net/http"

"github.com/appoptics/appoptics-apm-go/v1/ao"
)

func bobHandler(w http.ResponseWriter, r *http.Request) {
log.Printf("%s %s", r.Method, r.URL)
w.Write([]byte(`{"result":"hello from bob"}`))
}

func main() {
http.HandleFunc("/bob", ao.HTTPHandler(bobHandler))
http.ListenAndServe(":8081", nil)
}
16 changes: 16 additions & 0 deletions examples/otel/distributed_app/caroljs/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM ubuntu:16.04

# Install Node.js
RUN apt-get update && apt-get -y install build-essential nodejs npm
RUN ln -s /usr/bin/nodejs /usr/bin/node

# Install Node app
RUN mkdir -p /nodejs
COPY app.js /nodejs
WORKDIR /nodejs
RUN npm install --save appoptics

# Script to run before testing to start services such as tracelyzer and app
ADD start_services.sh /start_services.sh
EXPOSE 8082
CMD [ "bash", "/start_services.sh" ]
9 changes: 9 additions & 0 deletions examples/otel/distributed_app/caroljs/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
var ao = require('appoptics');
var http = require('http');

var server = http.createServer(function(req, res) {
console.log(new Date().toISOString(), req.method, req.url);
res.writeHead(200);
res.end('Hello from app.js\n');
});
server.listen(8082);
2 changes: 2 additions & 0 deletions examples/otel/distributed_app/caroljs/start_services.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
APP_PATH=/nodejs/app.js
node $APP_PATH
16 changes: 16 additions & 0 deletions examples/otel/distributed_app/carolpy/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM ubuntu:17.10

RUN apt-get update
RUN apt-get -y install build-essential python-dev python-pip

# Install Node app
RUN mkdir -p /carolpy
COPY app.py /carolpy
COPY requirements.txt /carolpy
WORKDIR /carolpy
RUN pip install -r requirements.txt

# Script to run before testing to start services such as tracelyzer and app
ADD start_services.sh /start_services.sh
EXPOSE 8082
CMD [ "bash", "/start_services.sh" ]
13 changes: 13 additions & 0 deletions examples/otel/distributed_app/carolpy/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from flask import Flask
from appoptics.middleware import AppOpticsMiddleware

application = Flask(__name__)
application.wsgi_app = AppOpticsMiddleware(application.wsgi_app)


@application.route('/carol')
def hello():
return "Hello from carolpy/app.py"

if __name__ == '__main__':
application.run()
3 changes: 3 additions & 0 deletions examples/otel/distributed_app/carolpy/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
appoptics
flask
uwsgi
2 changes: 2 additions & 0 deletions examples/otel/distributed_app/carolpy/start_services.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cd /carolpy
uwsgi --socket 0.0.0.0:8082 --protocol=http -w app
16 changes: 16 additions & 0 deletions examples/otel/distributed_app/davepy/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM ubuntu:16.04

# Install uWSGI and instrumentation
RUN apt-get update && apt-get -y install python-pip python-dev build-essential
RUN pip install appoptics
RUN pip install uwsgi flask

# Script to run before testing to start services such as tracelyzer and apache
ADD start_services.sh /start_services.sh

# uWSGI stack
ADD app /home/app/

EXPOSE 8083
CMD [ "bash", "/start_services.sh" ]

10 changes: 10 additions & 0 deletions examples/otel/distributed_app/davepy/app/helloworld.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# https://docs.appoptics.com/kb/apm_tracing/python/install/#flask-and-generic-wsgi
from flask import Flask
from appoptics.middleware import AppOpticsMiddleware

application = Flask(__name__)
application.wsgi_app = AppOpticsMiddleware(application.wsgi_app)

@application.route("/")
def hello():
return "Hello from Flask!"
5 changes: 5 additions & 0 deletions examples/otel/distributed_app/davepy/app/wsgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from helloworld import application

if __name__ == "__main__":
application.run()

2 changes: 2 additions & 0 deletions examples/otel/distributed_app/davepy/start_services.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cd /home/app/
uwsgi --socket 0.0.0.0:8083 --protocol=http -w wsgi
57 changes: 57 additions & 0 deletions examples/otel/distributed_app/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Example distributed app using AppOptics
# http://www.appoptics.com
version: '2'
services:
redis:
image: redis

# Alice is a Go service
alice:
build:
context: ./alice
environment:
APPOPTICS_SERVICE_KEY: ${APPOPTICS_API_TOKEN}:example-alice
links:
- bob
- carolpy:carol
- davepy:dave
- otto:otto
ports:
- "8890:8890"

# Bob is a Go service
bob:
build:
context: ./bob
environment:
APPOPTICS_SERVICE_KEY: ${APPOPTICS_API_TOKEN}:example-bob
links:
- redis
- carolpy:carol

# Carol runs Python
carolpy:
build:
context: ./carolpy
environment:
APPOPTICS_SERVICE_KEY: ${APPOPTICS_API_TOKEN}:example-carol

# Dave is a Flask app running on uWSGI
davepy:
build:
context: ./davepy
environment:
APPOPTICS_SERVICE_KEY: ${APPOPTICS_API_TOKEN}:example-dave

# Otto is a Go app using the OpenTracing API
otto:
build:
context: ./otto
environment:
APPOPTICS_SERVICE_KEY: ${APPOPTICS_API_TOKEN}:example-otto
links:
- bob
- carolpy:carol
- davepy:dave
ports:
- "8084:8084"
11 changes: 11 additions & 0 deletions examples/otel/distributed_app/otto/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM golang:1.12

# Based on https://hub.docker.com/_/golang/
WORKDIR /go/src/app
COPY . .
RUN go-wrapper download
RUN go-wrapper install

# Start app. APPOPTICS_SERVICE_KEY must be set to enable AppOptics.
CMD /go/bin/app
EXPOSE 8084
Loading