From 66edb36d42338ad3f0394ec9244a300f8130c8c2 Mon Sep 17 00:00:00 2001 From: Mike Dame Date: Wed, 26 Jul 2023 13:54:11 -0400 Subject: [PATCH] Add Go sample app (#35) --- README.md | 2 +- sample-apps/README.md | 2 +- sample-apps/go/Makefile | 26 +++++++++++++++ sample-apps/go/README.md | 54 ++++++++++++++++++++++++++++++++ sample-apps/go/app/Dockerfile | 18 +++++++++++ sample-apps/go/app/go.mod | 3 ++ sample-apps/go/app/main.go | 42 +++++++++++++++++++++++++ sample-apps/go/k8s/app.yaml | 40 +++++++++++++++++++++++ sample-apps/go/k8s/service.yaml | 51 ++++++++++++++++++++++++++++++ sample-apps/go/server/Dockerfile | 18 +++++++++++ sample-apps/go/server/go.mod | 3 ++ sample-apps/go/server/main.go | 33 +++++++++++++++++++ 12 files changed, 290 insertions(+), 2 deletions(-) create mode 100644 sample-apps/go/Makefile create mode 100644 sample-apps/go/README.md create mode 100644 sample-apps/go/app/Dockerfile create mode 100644 sample-apps/go/app/go.mod create mode 100644 sample-apps/go/app/main.go create mode 100644 sample-apps/go/k8s/app.yaml create mode 100644 sample-apps/go/k8s/service.yaml create mode 100644 sample-apps/go/server/Dockerfile create mode 100644 sample-apps/go/server/go.mod create mode 100644 sample-apps/go/server/main.go diff --git a/README.md b/README.md index b0e93d8..f3854fb 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ the operator in various languages: * [Java](sample-apps/java) * [Python](sample-apps/python) * DotNET (coming soon) -* Go (coming soon) +* [Go](sample-apps/go) * [NodeJS + Java](sample-apps/nodejs-java) Each of these sample apps works well with the [recipes](recipes) listed below. diff --git a/sample-apps/README.md b/sample-apps/README.md index 1e69d0c..8901db0 100644 --- a/sample-apps/README.md +++ b/sample-apps/README.md @@ -7,7 +7,7 @@ the operator and auto-instrumentation. See below to get started: * [Java](java) * [Python](python) * DotNET -* Go +* [Go](go) * [NodeJS + Java](nodejs-java) ## Setup diff --git a/sample-apps/go/Makefile b/sample-apps/go/Makefile new file mode 100644 index 0000000..c914147 --- /dev/null +++ b/sample-apps/go/Makefile @@ -0,0 +1,26 @@ +# Copyright 2023 Google LLC +# +# 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 +# +# https://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. + +include ../../Makefile + +.PHONY: build +build: sample-replace + docker build -t ${REGISTRY_LOCATION}-docker.pkg.dev/${GCLOUD_PROJECT}/${CONTAINER_REGISTRY}/go-sample-app app + docker build -t ${REGISTRY_LOCATION}-docker.pkg.dev/${GCLOUD_PROJECT}/${CONTAINER_REGISTRY}/go-sample-server server + +.PHONY: push +push: + docker push ${REGISTRY_LOCATION}-docker.pkg.dev/${GCLOUD_PROJECT}/${CONTAINER_REGISTRY}/go-sample-app:latest + docker push ${REGISTRY_LOCATION}-docker.pkg.dev/${GCLOUD_PROJECT}/${CONTAINER_REGISTRY}/go-sample-server:latest + diff --git a/sample-apps/go/README.md b/sample-apps/go/README.md new file mode 100644 index 0000000..03baa8a --- /dev/null +++ b/sample-apps/go/README.md @@ -0,0 +1,54 @@ +# Go sample app + +This is a sample app consisting of a basic client and server written in Go. The +server listens for requests which the client makes on a timed loop. + +## Prerequisites + +* OpenTelemetry Operator installed in your cluster +* Artifact Registry set up in your GCP project (see the +[main README.md](../../README.md#sample-applications)) +* An `OpenTelemetryCollector` object already created in the current namespace, + such as [the sample `collector-config.yaml`](../../README.md#starting-the-Collector) + from the main [README](../../README.md) +* An `Instrumentation` object already created in the current namespace, + such as [the sample `instrumentation.yaml`](../../README.md#auto-instrumenting-applications) + from the main [README](../../README.md) + +## Running + +1. Build the sample app: + ``` + make build + ``` + This command will also update the local [manifests](k8s) + to refer to your image location. + +2. Push the local image to the Artifact Registry you created + in the setup steps (if you did not create one, or are using an already created registry, + make sure to set the `REGISTRY_LOCATION` and `CONTAINER_REGISTRY` variables): + ``` + make push + ``` + +3. Deploy the app in your cluster: + ``` + kubectl apply -f k8s/. + ``` + If you want to run the sample app in a specific namespace, pass `-n `. + +4. Run the following commands to patch the `app` and `server` deployments for auto-instrumentation: + ``` + kubectl patch deployment.apps/goshowcase-app -p '{"spec":{"template":{"metadata":{"annotations":{"instrumentation.opentelemetry.io/inject-go": "true", "instrumentation.opentelemetry.io/otel-go-auto-target-exe": "/app/main"}}}}}' + kubectl patch deployment.apps/goshowcase-server -p '{"spec":{"template":{"metadata":{"annotations":{"instrumentation.opentelemetry.io/inject-go": "true", "instrumentation.opentelemetry.io/otel-go-auto-target-exe": "/server/main"}}}}}' + ``` + These commands will use the `Instrumentation` created as part of the Prerequisites. + +## View your Spans + +To stream logs from the otel-collector, which will include spans from this sample application, run: +``` +kubectl logs deployment/otel-collector -f +``` + +Alternatively, follow the [cloud-trace recipe](../../recipes/cloud-trace/) to view your spans in Google Cloud Trace. diff --git a/sample-apps/go/app/Dockerfile b/sample-apps/go/app/Dockerfile new file mode 100644 index 0000000..737852c --- /dev/null +++ b/sample-apps/go/app/Dockerfile @@ -0,0 +1,18 @@ +# Copyright 2023 Google LLC +# +# 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 +# +# https://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. + +FROM golang:1.19 +WORKDIR /app +COPY . . +RUN go build -o main diff --git a/sample-apps/go/app/go.mod b/sample-apps/go/app/go.mod new file mode 100644 index 0000000..7cea7cd --- /dev/null +++ b/sample-apps/go/app/go.mod @@ -0,0 +1,3 @@ +module github.com/GoogleCloudPlatform/opentelemetry-operator-sample/sample-apps/go/app + +go 1.20 diff --git a/sample-apps/go/app/main.go b/sample-apps/go/app/main.go new file mode 100644 index 0000000..8d16837 --- /dev/null +++ b/sample-apps/go/app/main.go @@ -0,0 +1,42 @@ +// Copyright 2023 Google LLC +// +// 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 +// +// https://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. + +package main + +import ( + "io" + "log" + "net/http" + "time" +) + +func main() { + for { + resp, err := http.Get("http://goshowcase-server/hello") + if err != nil { + log.Fatal(err) + } + body, err := io.ReadAll(resp.Body) + if err != nil { + log.Fatal(err) + } + + log.Printf("Body: %s\n", string(body)) + err = resp.Body.Close() + if err != nil { + log.Fatal(err) + } + time.Sleep(5 * time.Second) + } +} diff --git a/sample-apps/go/k8s/app.yaml b/sample-apps/go/k8s/app.yaml new file mode 100644 index 0000000..8082d9d --- /dev/null +++ b/sample-apps/go/k8s/app.yaml @@ -0,0 +1,40 @@ +# Copyright 2023 Google LLC +# +# 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 +# +# https://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. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: goshowcase-app +spec: + selector: + matchLabels: + app: goshowcase-app + template: + metadata: + name: goshowcase-app + labels: + app: goshowcase-app + spec: + containers: + - name: goshowcase-app + image: "%REGISTRY_LOCATION%-docker.pkg.dev/%GCLOUD_PROJECT%/%CONTAINER_REGISTRY%/go-sample-app:latest" + command: ['/app/main'] + resources: + requests: + memory: "256Mi" + cpu: "250m" + limits: + memory: "256Mi" + cpu: "250m" + restartPolicy: Always diff --git a/sample-apps/go/k8s/service.yaml b/sample-apps/go/k8s/service.yaml new file mode 100644 index 0000000..eb9889e --- /dev/null +++ b/sample-apps/go/k8s/service.yaml @@ -0,0 +1,51 @@ +# Copyright 2023 Google LLC +# +# 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 +# +# https://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. + +apiVersion: v1 +kind: Service +metadata: + name: goshowcase-server +spec: + selector: + app: goshowcase-server + ports: + - port: 80 + targetPort: 8080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: goshowcase-server +spec: + selector: + matchLabels: + app: goshowcase-server + template: + metadata: + labels: + app: goshowcase-server + spec: + containers: + - name: goshowcase-server + image: "%REGISTRY_LOCATION%-docker.pkg.dev/%GCLOUD_PROJECT%/%CONTAINER_REGISTRY%/go-sample-server:latest" + command: ['/server/main'] + ports: + - containerPort: 8080 + resources: + requests: + memory: "256Mi" + cpu: "250m" + limits: + memory: "256Mi" + cpu: "250m" diff --git a/sample-apps/go/server/Dockerfile b/sample-apps/go/server/Dockerfile new file mode 100644 index 0000000..6429d71 --- /dev/null +++ b/sample-apps/go/server/Dockerfile @@ -0,0 +1,18 @@ +# Copyright 2023 Google LLC +# +# 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 +# +# https://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. + +FROM golang:1.19 +WORKDIR /server +COPY . . +RUN go build -o main diff --git a/sample-apps/go/server/go.mod b/sample-apps/go/server/go.mod new file mode 100644 index 0000000..91d70cd --- /dev/null +++ b/sample-apps/go/server/go.mod @@ -0,0 +1,3 @@ +module github.com/GoogleCloudPlatform/opentelemetry-operator-sample/sample-apps/go/server + +go 1.20 diff --git a/sample-apps/go/server/main.go b/sample-apps/go/server/main.go new file mode 100644 index 0000000..7848ca0 --- /dev/null +++ b/sample-apps/go/server/main.go @@ -0,0 +1,33 @@ +// Copyright 2023 Google LLC +// +// 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 +// +// https://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. + +package main + +import ( + "fmt" + "log" + "net/http" +) + +func hello(w http.ResponseWriter, _ *http.Request) { + fmt.Fprintf(w, "hello\n") +} + +func main() { + http.HandleFunc("/hello", hello) + err := http.ListenAndServe(":8080", nil) + if err != nil { + log.Fatal(err) + } +}