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

feature/actions: WIP #7

Merged
merged 3 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 15 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Github workflows

## Traces

`tracing.yml`:
This gh action will check if PRs are marked with the `enable tracing` label. If so, on PR creation, sycronization, or labeling, then a sample CI workflow is kicked off that generates traces.

Ephemeral OTEL collector, Grafana Tempo, and Grafana UI containers are deployed and kept up while the workflow executes (for 500 seconds). Ngrok tunnels are used to expose the Grafana UI container outside the github runner.

To view such traces, fork this repository and configure the following secrets:
NGROK_AUTH_TOKEN
NGROK_USER
NGROK_PASSWORD

The tracing workflow will log the exposed endpoint, which you can paste into any browser. Visit `/explore` and select traces to view traces.
112 changes: 112 additions & 0 deletions .github/workflows/tracing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
name: Enable Tracing for PR

on:
pull_request:
types: [opened, synchronize, labeled, unlabeled, closed]

jobs:
tracing:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Check for "enable tracing" label
id: check-label
run: |
label=$(jq -r '.pull_request.labels[].name' "$GITHUB_EVENT_PATH")
if [[ "$label" == "enable tracing" ]]; then
echo "Enable tracing label found."
echo "trace=true" >> $GITHUB_OUTPUT
else
echo "Enable tracing label not found."
echo "trace=true" >> $GITHUB_OUTPUT
fi
echo "$PWD"
- name: Build Example GRPC Server Docker Image
if: steps.check-label.outputs.trace == 'true'
run: |
# Build the Docker image
docker build -t example-grpc-server:latest -f ./internal/examples/example-grpc-client-server/server/Dockerfile .
- name: Setup Grafana and OpenTelemetry
id: docker-setup
if: steps.check-label.outputs.trace == 'true'
run: |
# Create network
docker network create tracing_network

# TODO (issues/8): order here matters

# Start Grafana
cd ./internal/examples/example-otlp-agent-tempo-grafana/
docker run -d --network=tracing_network --name=grafana -p 3000:3000 -v $PWD/grafana-datasources.yaml:/etc/grafana/provisioning/datasources/datasources.yaml -e GF_AUTH_ANONYMOUS_ENABLED=true -e GF_AUTH_ANONYMOUS_ORG_ROLE=Admin -e GF_AUTH_DISABLE_LOGIN_FORM=true -e GF_FEATURE_TOGGLES_ENABLE=traceqlEditor grafana/grafana:9.4.3

# Start Tempo
docker run -d --network=tracing_network --name=tempo -v ./tempo.yaml:/etc/tempo.yaml -v $PWD/tempo-data:/tmp/tempo grafana/tempo:latest -config.file=/etc/tempo.yaml

# Start OpenTelemetry Collector
docker run -d --network=tracing_network --name=otel-collector -v $PWD/otel-collector.yaml:/etc/otel-collector.yaml -p 4317:4317 otel/opentelemetry-collector:0.61.0 --config=/etc/otel-collector.yaml
- name: Install ngrok
id: install-ngrok
if: steps.check-label.outputs.trace == 'true'
run: |
# Install Ngrok
curl -fsSL https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip -o ngrok.zip
unzip ngrok.zip
chmod +x ngrok
- name: Expose Grafana UI
id: expose-grafana-ui
if: steps.check-label.outputs.trace == 'true'
env:
NGROK_AUTH_TOKEN: ${{ secrets.NGROK_AUTH_TOKEN }}
NGROK_USER: ${{ secrets.NGROK_USER }}
NGROK_PASSWORD: ${{ secrets.NGROK_PASSWORD }}
run: |
# Start Ngrok to expose the Grafana UI port
./ngrok authtoken $NGROK_AUTH_TOKEN
./ngrok http -auth="$NGROK_USER:$NGROK_PASSWORD" 3000 &
sleep 5 # Give ngrok some time to initialize and bind the port
echo "NGROK_URL=$(curl -s http://localhost:4040/api/tunnels | jq -r '.tunnels[0].public_url')" >> "$GITHUB_ENV"
- name: Print Grafana UI URL
id: print-grafana-ui
if: steps.check-label.outputs.trace == 'true'
run: |
echo "Grafana UI URL: $NGROK_URL"
- name: Run server
id: run-server
run: |
# Start example server
docker run -d --network=tracing_network --name=example-grpc-server -p 50051:50051 -e ENABLE_TELEMETRY=true -e TELEMETRY_TARGET=otel-collector:4317 example-grpc-server:latest
- name: Run client to generate traces
run: |
cd internal/examples/example-grpc-client-server/client
go run .
- name: Show Grafana Logs
if: steps.check-label.outputs.trace == 'true'
run: |
docker logs grafana
- name: Show Tempo Logs
if: steps.check-label.outputs.trace == 'true'
run: |
docker logs tempo
- name: Show OpenTelemetry Collector Logs
if: steps.check-label.outputs.trace == 'true'
run: |
docker logs otel-collector
- name: Set sleep time to use in future steps
if: steps.check-label.outputs.trace == 'true'
run: |
echo "SLEEP_TIME=300" >> "$GITHUB_ENV"
- name: Keep action running to view traces
if: steps.check-label.outputs.trace == 'true'
run: |
echo "Sleeping for $SLEEP_TIME seconds..."
sleep $SLEEP_TIME
- name: teardown
if: steps.check-label.outputs.trace == 'true' || github.event_name == 'pull_request' && github.event.action == 'closed'
run: |
# Stop and remove containers
docker stop grafana tempo otel-collector example-grpc-server
docker rm grafana tempo otel-collector example-grpc-server
docker network rm tracing_network
killall ngrok
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ go test ./... -v

The gRPC services in this application can be instrumented OpenTelemetry tracing. Check out `example-otlp-agent-tempo-grafana`.

Traces can also be generated in a mock tracing workflow and viewed in grafana. Checkout the Readme for the [tracing workflow](../grpc-app-auth/.github/workflows/README.md)

## Contributions

Contributions and PRs are most welcome! Feel free to fork the repository, make your changes, and submit a pull request.
Expand Down
4 changes: 2 additions & 2 deletions internal/examples/example-grpc-client-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ To give the code a try for the first time, you can run the server and client in
Navigate to the server directory and run:

```bash
cd internal/example/server
cd internal/examples/example-grpc-client-server/server
go run .
```

Expand All @@ -16,6 +16,6 @@ go run .
Similarly, for the client:

```bash
cd internal/example/client
cd internal/examples/example-grpc-client-server/client
go run .
```
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ WORKDIR /app

COPY . .

WORKDIR /app/internal/examples/example-grpc-client-server/server/
RUN ls -al

RUN go mod download

WORKDIR /app/internal/examples/example-grpc-client-server/server/

RUN go clean
RUN go build -o server server_main.go
RUN chmod +x server

# CMD ["/bin/sh"]
CMD ["./server"]
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func main() {
telemetryTarget := os.Getenv("TELEMETRY_TARGET")

opts := make([]server.ServerOption, 0, 1)
if enableTelemetry == "true" {
if enableTelemetry == "true" && telemetryTarget != "" {
opts = append(opts, server.WithOpenTelemetry(telemetryTarget))
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
version: "3"
services:

# Instrumented application configured to export traces to ...
example-grpc-server:
build:
context: ../../../
Expand All @@ -13,7 +14,7 @@ services:
- ENABLE_TELEMETRY=true
- TELEMETRY_TARGET=otel-collector:4317

# Put traces in a Grafana Agent pipeline...
# ... the OpenTelemetry Collector configured to receive traces and export to Tempo ...
otel-collector:
image: otel/opentelemetry-collector:0.61.0
command: [ "--config=/etc/otel-collector.yaml" ]
Expand All @@ -24,7 +25,7 @@ services:
depends_on:
- tempo

# To eventually offload to Tempo...
# .. Which accepts requests from grafana ...
tempo:
image: grafana/tempo:latest
command: [ "-config.file=/etc/tempo.yaml" ]
Expand Down
2 changes: 1 addition & 1 deletion server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ func (s *Server) Serve() {
s.grpcServer = grpc.NewServer(
grpc.UnaryInterceptor(
grpc_middleware.ChainUnaryServer(
otelgrpc.UnaryServerInterceptor(),
loggingUnaryServerInterceptor,
otelgrpc.UnaryServerInterceptor(),
),
),
)
Expand Down
Loading