Skip to content

Commit 590f2d2

Browse files
arvindbr8yashykt
andauthored
add: Setup Basic OpenTelemetry Plugin In gRPC-Go (#9)
Co-authored-by: Yash Tibrewal <[email protected]>
1 parent 4912032 commit 590f2d2

File tree

10 files changed

+582
-0
lines changed

10 files changed

+582
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Here is a list of available codelabs in this repository:
2424
- [Getting Started with gRPC-Java (Streaming)](codelabs/Getting_Started_with_gRPC_Java_Streaming)
2525
- [Setup Basic gRPC OpenTelemetry Plugin in gRPC C++](codelabs/gRPC_Cpp_OpenTelemetry_Plugin)
2626
- [Setup Basic gRPC OpenTelemetry Plugin in gRPC-Python](codelabs/gRPC_Python_OpenTelemetry_Plugin)
27+
- [Setup Basic gRPC OpenTelemetry Plugin in gRPC-Go](codelabs/Setup_Basic_OpenTelemetry_Plugin_in_gRPC_Go)
2728

2829
Please note that this list will keep updating as new codelabs are added to the
2930
repository. Make sure to check back regularly for new content!
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Setup Basic OpenTelemetry Plugin in gRPC-Go
2+
3+
Get hands-on with gRPC's OpenTelemetry plugin for gRPC-Go in this interactive codelab! <!-- TODO(arvindbr8): Insert link once codelab is published. -->
4+
5+
6+
Designed for developers already familiar with gRPC and wanting to learn how to instrument their gRPC usage with OpenTelemetry.
7+
8+
#### You'll learn how to:
9+
- setup gRPC's OpenTelemetry plugin in gRPC-Go.
10+
- setup Prometheus exporter with OpenTelemetry.
11+
- explore collected metrics using Prometheus.
12+
13+
## How to use this directory
14+
15+
- [start_here](start_here/) directory serves as a starting point for the
16+
codelab.
17+
- [completed](completed/) directory showcases the finished code, giving you a
18+
peek of how the final implementation should look like.
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
*
3+
* Copyright 2024 gRPC authors.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package main
20+
21+
import (
22+
"context"
23+
"flag"
24+
"log"
25+
"net/http"
26+
"time"
27+
28+
"github.com/prometheus/client_golang/prometheus/promhttp"
29+
"go.opentelemetry.io/otel/exporters/prometheus"
30+
"go.opentelemetry.io/otel/sdk/metric"
31+
"google.golang.org/grpc"
32+
"google.golang.org/grpc/credentials/insecure"
33+
"google.golang.org/grpc/stats/opentelemetry"
34+
35+
pb "google.golang.org/grpc/examples/features/proto/echo"
36+
)
37+
38+
var (
39+
addr = flag.String("addr", ":50051", "the server address to connect to")
40+
prometheusEndpoint = flag.String("prometheus_endpoint", ":9465", "the Prometheus exporter endpoint")
41+
)
42+
43+
func main() {
44+
flag.Parse()
45+
46+
// Create a new prometheus exporter.
47+
exporter, err := prometheus.New()
48+
if err != nil {
49+
log.Fatalf("Failed to start prometheus exporter: %v", err)
50+
}
51+
52+
// Start the Prometheus exporter.
53+
go http.ListenAndServe(*prometheusEndpoint, promhttp.Handler())
54+
55+
// Create DialOption with OpenTelemetry plugin.
56+
provider := metric.NewMeterProvider(metric.WithReader(exporter))
57+
do := opentelemetry.DialOption(opentelemetry.Options{MetricsOptions: opentelemetry.MetricsOptions{MeterProvider: provider}})
58+
59+
// Set up a connection to the server.
60+
cc, err := grpc.NewClient(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()), do)
61+
if err != nil {
62+
log.Fatalf("Failed to start NewClient: %v", err)
63+
}
64+
defer cc.Close()
65+
66+
// Create a new EchoClient.
67+
c := pb.NewEchoClient(cc)
68+
69+
// Make a RPC every second. This should trigger telemetry to be emitted from
70+
// the client and the server.
71+
ctx := context.Background()
72+
for {
73+
r, err := c.UnaryEcho(ctx, &pb.EchoRequest{Message: "this is examples/opentelemetry"})
74+
if err != nil {
75+
log.Fatalf("UnaryEcho failed: %v", err)
76+
}
77+
log.Printf("%s", r)
78+
79+
// Sleep for a second.
80+
time.Sleep(time.Second)
81+
}
82+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module github.com/grpc-ecosystem/codelabs/setup_basic_otel_plugin
2+
3+
go 1.22.1
4+
5+
require (
6+
github.com/prometheus/client_golang v1.20.1
7+
go.opentelemetry.io/otel/exporters/prometheus v0.50.0
8+
go.opentelemetry.io/otel/sdk/metric v1.28.0
9+
google.golang.org/grpc v1.67.0-dev.0.20240821211139-9ab8b62505c8
10+
google.golang.org/grpc/examples v0.0.0-20240821211139-9ab8b62505c8
11+
google.golang.org/grpc/stats/opentelemetry v0.0.0-20240821211139-9ab8b62505c8
12+
)
13+
14+
require (
15+
github.com/beorn7/perks v1.0.1 // indirect
16+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
17+
github.com/go-logr/logr v1.4.2 // indirect
18+
github.com/go-logr/stdr v1.2.2 // indirect
19+
github.com/google/uuid v1.6.0 // indirect
20+
github.com/klauspost/compress v1.17.9 // indirect
21+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
22+
github.com/prometheus/client_model v0.6.1 // indirect
23+
github.com/prometheus/common v0.55.0 // indirect
24+
github.com/prometheus/procfs v0.15.1 // indirect
25+
go.opentelemetry.io/otel v1.28.0 // indirect
26+
go.opentelemetry.io/otel/metric v1.28.0 // indirect
27+
go.opentelemetry.io/otel/sdk v1.28.0 // indirect
28+
go.opentelemetry.io/otel/trace v1.28.0 // indirect
29+
golang.org/x/net v0.28.0 // indirect
30+
golang.org/x/sys v0.24.0 // indirect
31+
golang.org/x/text v0.17.0 // indirect
32+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
33+
google.golang.org/protobuf v1.34.2 // indirect
34+
)
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
cel.dev/expr v0.16.0 h1:yloc84fytn4zmJX2GU3TkXGsaieaV7dQ057Qs4sIG2Y=
2+
cel.dev/expr v0.16.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg=
3+
cloud.google.com/go v0.115.1 h1:Jo0SM9cQnSkYfp44+v+NQXHpcHqlnRJk2qxh6yvxxxQ=
4+
cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY=
5+
cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
6+
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
7+
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
8+
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
9+
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
10+
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
11+
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
12+
github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 h1:N+3sFI5GUjRKBi+i0TxYVST9h4Ie192jJWpHvthBBgg=
13+
github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
14+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
15+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
16+
github.com/envoyproxy/go-control-plane v0.13.0 h1:HzkeUz1Knt+3bK+8LG1bxOO/jzWZmdxpwC51i202les=
17+
github.com/envoyproxy/go-control-plane v0.13.0/go.mod h1:GRaKG3dwvFoTg4nj7aXdZnvMg4d7nvT/wl9WgVXn3Q8=
18+
github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
19+
github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
20+
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
21+
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
22+
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
23+
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
24+
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
25+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
26+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
27+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
28+
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
29+
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
30+
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
31+
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
32+
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
33+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
34+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
35+
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
36+
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
37+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
38+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
39+
github.com/prometheus/client_golang v1.20.1 h1:IMJXHOD6eARkQpxo8KkhgEVFlBNm+nkrFUyGlIu7Na8=
40+
github.com/prometheus/client_golang v1.20.1/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
41+
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
42+
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
43+
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
44+
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
45+
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
46+
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
47+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
48+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
49+
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
50+
go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
51+
go.opentelemetry.io/otel/exporters/prometheus v0.50.0 h1:2Ewsda6hejmbhGFyUvWZjUThC98Cf8Zy6g0zkIimOng=
52+
go.opentelemetry.io/otel/exporters/prometheus v0.50.0/go.mod h1:pMm5PkUo5YwbLiuEf7t2xg4wbP0/eSJrMxIMxKosynY=
53+
go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
54+
go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
55+
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
56+
go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
57+
go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08=
58+
go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg=
59+
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
60+
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
61+
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
62+
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
63+
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
64+
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
65+
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
66+
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
67+
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
68+
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
69+
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
70+
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
71+
google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 h1:oLiyxGgE+rt22duwci1+TG7bg2/L1LQsXwfjPlmuJA0=
72+
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8=
73+
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo=
74+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
75+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
76+
google.golang.org/grpc v1.67.0-dev.0.20240821211139-9ab8b62505c8 h1:b61arqKMyICRrCxna/qIyjYGWlfem3U2iLpF7LMnDaU=
77+
google.golang.org/grpc v1.67.0-dev.0.20240821211139-9ab8b62505c8/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
78+
google.golang.org/grpc/examples v0.0.0-20240821211139-9ab8b62505c8 h1:DPv3YM1LnhcQJujo5PD4uaGABa8n40m8/VeQ4yhOx0o=
79+
google.golang.org/grpc/examples v0.0.0-20240821211139-9ab8b62505c8/go.mod h1:1AgAZVBaON5Td374gBe47GmKy2quldl0WelzgpAzbfI=
80+
google.golang.org/grpc/stats/opentelemetry v0.0.0-20240821211139-9ab8b62505c8 h1:xx5o4BW7Nf4VU1SNMktPhKI56FXoKTgskA1Yw9K2LNA=
81+
google.golang.org/grpc/stats/opentelemetry v0.0.0-20240821211139-9ab8b62505c8/go.mod h1:5IIo2rbK2R+uM02S11lPORvQDEYKrGviCutd96TAUNQ=
82+
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
83+
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
84+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
85+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
*
3+
* Copyright 2024 gRPC authors.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package main
20+
21+
import (
22+
"context"
23+
"flag"
24+
"fmt"
25+
"log"
26+
"net"
27+
"net/http"
28+
"time"
29+
30+
"github.com/prometheus/client_golang/prometheus/promhttp"
31+
"go.opentelemetry.io/otel/exporters/prometheus"
32+
"go.opentelemetry.io/otel/sdk/metric"
33+
"google.golang.org/grpc"
34+
"google.golang.org/grpc/stats/opentelemetry"
35+
36+
pb "google.golang.org/grpc/examples/features/proto/echo"
37+
)
38+
39+
var (
40+
addr = flag.String("addr", ":50051", "the server address to connect to")
41+
prometheusEndpoint = flag.String("prometheus_endpoint", ":9464", "the Prometheus exporter endpoint")
42+
)
43+
44+
// echoServer is used to implement pb.EchoServer.
45+
type echoServer struct {
46+
pb.UnimplementedEchoServer
47+
48+
addr string
49+
}
50+
51+
// UnaryEcho implements pb.EchoServer UnaryEcho service. The method will return
52+
// the message with the server address.
53+
func (s *echoServer) UnaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) {
54+
time.Sleep(2 * time.Second)
55+
return &pb.EchoResponse{Message: fmt.Sprintf("%s (from %s)", req.Message, s.addr)}, nil
56+
}
57+
58+
func main() {
59+
flag.Parse()
60+
61+
// Create a new prometheus exporter.
62+
exporter, err := prometheus.New()
63+
if err != nil {
64+
log.Fatalf("Failed to start prometheus exporter: %v", err)
65+
}
66+
67+
// Create a new meter provider with the prometheus exporter.
68+
provider := metric.NewMeterProvider(metric.WithReader(exporter))
69+
go http.ListenAndServe(*prometheusEndpoint, promhttp.Handler())
70+
71+
so := opentelemetry.ServerOption(opentelemetry.Options{MetricsOptions: opentelemetry.MetricsOptions{MeterProvider: provider}})
72+
73+
// Create a listener on the TCP port.
74+
lis, err := net.Listen("tcp", *addr)
75+
if err != nil {
76+
log.Fatalf("Failed to listen: %v", err)
77+
}
78+
79+
// Create a gRPC server with the stats handler.
80+
s := grpc.NewServer(so)
81+
pb.RegisterEchoServer(s, &echoServer{addr: *addr})
82+
83+
log.Printf("Serving on %s\n", *addr)
84+
85+
if err := s.Serve(lis); err != nil {
86+
log.Fatalf("Failed to serve: %v", err)
87+
}
88+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
*
3+
* Copyright 2024 gRPC authors.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package main
20+
21+
import (
22+
"context"
23+
"flag"
24+
"log"
25+
"time"
26+
27+
"google.golang.org/grpc"
28+
"google.golang.org/grpc/credentials/insecure"
29+
30+
pb "google.golang.org/grpc/examples/features/proto/echo"
31+
)
32+
33+
var (
34+
addr = flag.String("addr", ":50051", "the server address to connect to")
35+
prometheusEndpoint = flag.String("prometheus_endpoint", ":9465", "the Prometheus exporter endpoint")
36+
)
37+
38+
func main() {
39+
flag.Parse()
40+
41+
///////////////////////////////////////////////////////////////////////////
42+
// Codelab hint: Add code to setup the gRPC Go Otel plugin.
43+
//
44+
// Steps include:
45+
// - Create a new prometheus exporter.
46+
// - Start the Prometheus exporter.
47+
// - Create DialOption with OpenTelemetry plugin.
48+
// - Pass the DialOption to grpc.NewClient.
49+
///////////////////////////////////////////////////////////////////////////
50+
51+
// Set up a connection to the server.
52+
cc, err := grpc.NewClient(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()), do)
53+
if err != nil {
54+
log.Fatalf("Failed to start NewClient: %v", err)
55+
}
56+
defer cc.Close()
57+
58+
// Create a new EchoClient.
59+
c := pb.NewEchoClient(cc)
60+
61+
// Make a RPC every second. This should trigger telemetry to be emitted from
62+
// the client and the server.
63+
ctx := context.Background()
64+
for {
65+
r, err := c.UnaryEcho(ctx, &pb.EchoRequest{Message: "this is examples/opentelemetry"})
66+
if err != nil {
67+
log.Fatalf("UnaryEcho failed: %v", err)
68+
}
69+
log.Printf("%s", r)
70+
71+
// Sleep for a second.
72+
time.Sleep(time.Second)
73+
}
74+
}

0 commit comments

Comments
 (0)