snapshot of https://github.com/grpc/grpc-go.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
codecov / upload (push) Failing after 13m59s
CodeQL / Analyze (push) Failing after 1s
Testing / vet-proto (push) Failing after 1s
Testing / tests (arm, latest) (push) Waiting to run
Testing / extras (latest) (push) Failing after 1s
Testing / static checks (latest-1) (push) Failing after 1s
Testing / tests (-race, latest) (push) Failing after 1s
Testing / tests (i386, latest) (push) Failing after 1s
Testing / tests (latest) (push) Failing after 1s
Testing / tests (latest-1) (push) Failing after 1s
Lock Threads / lock (push) Failing after 1s
govulncheck / govulncheck (.) (push) Failing after 1s
govulncheck / govulncheck (./cmd/protoc-gen-go-grpc) (push) Failing after 1s
govulncheck / govulncheck (./gcp/observability) (push) Failing after 1s
govulncheck / govulncheck (./security/advancedtls) (push) Failing after 1s
govulncheck / govulncheck (./stats/opencensus) (push) Failing after 1s
Stale bot / stale (push) Failing after 1s

This commit is contained in:
upstream-mirror
2026-09-15 20:40:15 +05:00
commit e241b33f26
1365 changed files with 339570 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
# CSM Observability
This examples shows how to configure CSM Observability for gRPC client and
server applications (configured once per binary), and shows what type of
telemetry data it can produce for certain RPCs with additional CSM Labels. The
gRPC Client accepts configuration from an xDS Control plane as the default
address that it connects to is "xds:///helloworld:50051", but this can be
overridden with the command line flag --server_addr. This can be plugged into
the steps outlined in the CSM Observability User Guide.
## Try it (locally if overwritten xDS Address)
```
go run server/main.go
```
```
go run client/main.go
```
Curl to the port where Prometheus exporter is outputting metrics data:
```
curl localhost:9464/metrics
```
# Building
From the grpc-go directory:
Client:
docker build -t <TAG> -f examples/features/csm_observability/client/Dockerfile .
Server:
docker build -t <TAG> -f examples/features/csm_observability/server/Dockerfile .
Note that this example will not work by default, as the client uses an xDS
Scheme and thus needs xDS Resources to connect to the server. Deploy the built
client and server containers within Cloud Service Mesh in order for this example
to work, or overwrite target to point to :<server serving port>.

View File

@@ -0,0 +1,35 @@
# Copyright 2024 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Dockerfile for building the example client. To build the image, run the
# following command from grpc-go directory:
# docker build -t <TAG> -f examples/features/csm_observability/client/Dockerfile .
FROM golang:1.25-alpine as build
RUN apk --no-cache add curl
# Make a grpc-go directory and copy the repo into it.
WORKDIR /go/src/grpc-go
COPY . .
# Build a static binary without cgo so that we can copy just the binary in the
# final image, and can get rid of the Go compiler and gRPC-Go dependencies.
RUN cd examples/features/csm_observability/client && go build -tags osusergo,netgo .
FROM alpine
RUN apk --no-cache add curl
COPY --from=build /go/src/grpc-go/examples/features/csm_observability/client/client .
ENV GRPC_GO_LOG_VERBOSITY_LEVEL=99
ENV GRPC_GO_LOG_SEVERITY_LEVEL="info"
ENTRYPOINT ["./client"]

View File

@@ -0,0 +1,88 @@
/*
*
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// Binary client is a client for the CSM Observability example.
package main
import (
"context"
"flag"
"fmt"
"log"
"net/http"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
xdscreds "google.golang.org/grpc/credentials/xds"
pb "google.golang.org/grpc/examples/helloworld/helloworld"
"google.golang.org/grpc/stats/opentelemetry"
"google.golang.org/grpc/stats/opentelemetry/csm"
_ "google.golang.org/grpc/xds" // To install the xds resolvers and balancers.
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.opentelemetry.io/otel/exporters/prometheus"
"go.opentelemetry.io/otel/sdk/metric"
)
const defaultName = "world"
var (
target = flag.String("target", "xds:///helloworld:50051", "the server address to connect to")
prometheusEndpoint = flag.String("prometheus_endpoint", ":9464", "the Prometheus exporter endpoint")
name = flag.String("name", defaultName, "Name to greet")
)
func main() {
flag.Parse()
exporter, err := prometheus.New()
if err != nil {
log.Fatalf("Failed to start prometheus exporter: %v", err)
}
provider := metric.NewMeterProvider(metric.WithReader(exporter))
go http.ListenAndServe(*prometheusEndpoint, promhttp.Handler())
cleanup := csm.EnableObservability(context.Background(), opentelemetry.Options{MetricsOptions: opentelemetry.MetricsOptions{MeterProvider: provider}})
defer cleanup()
// Set up xds credentials that fall back to insecure as described in:
// https://cloud.google.com/service-mesh/docs/service-routing/security-proxyless-setup#workloads_are_unable_to_communicate_in_the_security_setup.
creds, err := xdscreds.NewClientCredentials(xdscreds.ClientOptions{FallbackCreds: insecure.NewCredentials()})
if err != nil {
log.Fatalf("Failed to create xDS credentials: %v", err)
}
cc, err := grpc.NewClient(*target, grpc.WithTransportCredentials(creds))
if err != nil {
log.Fatalf("Failed to start NewClient: %v", err)
}
defer cc.Close()
c := pb.NewGreeterClient(cc)
// Make an RPC every second. This should trigger telemetry to be emitted from
// the client and the server.
for {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
r, err := c.SayHello(ctx, &pb.HelloRequest{Name: *name})
if err != nil {
log.Fatalf("Could not greet: %v", err)
}
fmt.Println(r)
time.Sleep(time.Second)
cancel()
}
}

View File

@@ -0,0 +1,34 @@
# Copyright 2024 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Dockerfile for building the example server. To build the image, run the
# following command from grpc-go directory:
# docker build -t <TAG> -f examples/features/csm_observability/server/Dockerfile .
FROM golang:1.25-alpine as build
RUN apk --no-cache add curl
# Make a grpc-go directory and copy the repo into it.
WORKDIR /go/src/grpc-go
COPY . .
# Build a static binary without cgo so that we can copy just the binary in the
# final image, and can get rid of the Go compiler and gRPC-Go dependencies.
RUN cd examples/features/csm_observability/server && go build -tags osusergo,netgo .
FROM alpine
RUN apk --no-cache add curl
COPY --from=build /go/src/grpc-go/examples/features/csm_observability/server/server .
ENV GRPC_GO_LOG_VERBOSITY_LEVEL=99
ENV GRPC_GO_LOG_SEVERITY_LEVEL="info"
ENTRYPOINT ["./server"]

View File

@@ -0,0 +1,91 @@
/*
*
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// Binary server is a server for the CSM Observability example.
package main
import (
"context"
"flag"
"log"
"net"
"net/http"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
xdscreds "google.golang.org/grpc/credentials/xds"
pb "google.golang.org/grpc/examples/helloworld/helloworld"
"google.golang.org/grpc/stats/opentelemetry"
"google.golang.org/grpc/stats/opentelemetry/csm"
"google.golang.org/grpc/xds"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.opentelemetry.io/otel/exporters/prometheus"
"go.opentelemetry.io/otel/sdk/metric"
)
var (
port = flag.String("port", "50051", "the server address to connect to")
prometheusEndpoint = flag.String("prometheus_endpoint", ":9464", "the Prometheus exporter endpoint")
)
// server is used to implement helloworld.GreeterServer.
type server struct {
pb.UnimplementedGreeterServer
addr string
}
// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(_ context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
}
func main() {
flag.Parse()
exporter, err := prometheus.New()
if err != nil {
log.Fatalf("Failed to start prometheus exporter: %v", err)
}
provider := metric.NewMeterProvider(metric.WithReader(exporter))
go http.ListenAndServe(*prometheusEndpoint, promhttp.Handler())
cleanup := csm.EnableObservability(context.Background(), opentelemetry.Options{MetricsOptions: opentelemetry.MetricsOptions{MeterProvider: provider}})
defer cleanup()
lis, err := net.Listen("tcp4", "0.0.0.0:"+*port)
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
// Set up xds credentials that fall back to insecure as described in:
// https://cloud.google.com/service-mesh/docs/service-routing/security-proxyless-setup#workloads_are_unable_to_communicate_in_the_security_setup.
creds, err := xdscreds.NewServerCredentials(xdscreds.ServerOptions{FallbackCreds: insecure.NewCredentials()})
if err != nil {
log.Fatalf("Failed to create xDS credentials: %v", err)
}
s, err := xds.NewGRPCServer(grpc.Creds(creds))
if err != nil {
log.Fatalf("Failed to start xDS Server: %v", err)
}
pb.RegisterGreeterServer(s, &server{addr: ":" + *port})
log.Printf("Serving on %s\n", *port)
if err := s.Serve(lis); err != nil {
log.Fatalf("Failed to serve: %v", err)
}
}