diff --git a/getting-started-guides/compose.yaml b/getting-started-guides/compose.yaml index a4c29f36..4ed16824 100644 --- a/getting-started-guides/compose.yaml +++ b/getting-started-guides/compose.yaml @@ -83,6 +83,19 @@ services: # - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE ports: - 8080 + rust: + build: rust + environment: + - OTEL_SERVICE_NAME=getting-started-rust + - OTEL_RESOURCE_ATTRIBUTES=service.instance.id=123 + - OTEL_EXPORTER_OTLP_ENDPOINT + - OTEL_EXPORTER_OTLP_HEADERS + - OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT + - OTEL_EXPORTER_OTLP_COMPRESSION + - OTEL_EXPORTER_OTLP_PROTOCOL + - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE + ports: + - 8080 envoy: image: envoyproxy/envoy:v1.29.4 ports: @@ -97,6 +110,8 @@ services: depends_on: - dotnet - go + - java - javascript - python - ruby + - rust diff --git a/getting-started-guides/rust/Cargo.lock b/getting-started-guides/rust/Cargo.lock index 237ae6ff..2f8d469b 100644 --- a/getting-started-guides/rust/Cargo.lock +++ b/getting-started-guides/rust/Cargo.lock @@ -1683,6 +1683,7 @@ dependencies = [ "axum", "base64 0.21.7", "bytes", + "flate2", "h2", "http", "http-body", diff --git a/getting-started-guides/rust/Cargo.toml b/getting-started-guides/rust/Cargo.toml index 224a3a45..133f1bf5 100644 --- a/getting-started-guides/rust/Cargo.toml +++ b/getting-started-guides/rust/Cargo.toml @@ -7,6 +7,6 @@ edition = "2021" actix-web = "4.8.0" actix-web-opentelemetry = "0.18.0" opentelemetry = "0.23.0" -opentelemetry-otlp = { version = "0.16.0", features = ["tls-roots"] } +opentelemetry-otlp = { version = "0.16.0", features = ["tls-roots", "gzip-tonic"] } opentelemetry_sdk = { version = "0.23.0", features = ["rt-tokio"] } serde = { version = "1.0.205", features = ["derive"] } diff --git a/getting-started-guides/rust/Dockerfile b/getting-started-guides/rust/Dockerfile new file mode 100644 index 00000000..2f00967e --- /dev/null +++ b/getting-started-guides/rust/Dockerfile @@ -0,0 +1,48 @@ +# syntax=docker/dockerfile:1 + +ARG RUST_VERSION=1.79.0 +ARG APP_NAME=fibonacci + +FROM rust:${RUST_VERSION}-alpine AS build +ARG APP_NAME +WORKDIR /app + +RUN apk add --no-cache clang lld musl-dev git + +# Build the application. +# Leverage a cache mount to /usr/local/cargo/registry/ +# for downloaded dependencies, a cache mount to /usr/local/cargo/git/db +# for git repository dependencies, and a cache mount to /app/target/ for +# compiled dependencies which will speed up subsequent builds. +# Leverage a bind mount to the src directory to avoid having to copy the +# source code into the container. Once built, copy the executable to an +# output directory before the cache mounted /app/target is unmounted. +RUN --mount=type=bind,source=src,target=src \ + --mount=type=bind,source=Cargo.toml,target=Cargo.toml \ + --mount=type=bind,source=Cargo.lock,target=Cargo.lock \ + --mount=type=cache,target=/app/target/ \ + --mount=type=cache,target=/usr/local/cargo/git/db \ + --mount=type=cache,target=/usr/local/cargo/registry/ \ +cargo build --locked --release && \ +cp ./target/release/$APP_NAME /bin/server + +FROM alpine:3.18 AS final + +# Create a non-privileged user that the app will run under. +# See https://docs.docker.com/go/dockerfile-user-best-practices/ +ARG UID=10001 +RUN adduser \ + --disabled-password \ + --gecos "" \ + --home "/nonexistent" \ + --shell "/sbin/nologin" \ + --no-create-home \ + --uid "${UID}" \ + appuser +USER appuser + +COPY --from=build /bin/server /bin/ + +EXPOSE 8080 + +CMD ["/bin/server"] diff --git a/getting-started-guides/rust/src/main.rs b/getting-started-guides/rust/src/main.rs index c3b0370f..32382805 100644 --- a/getting-started-guides/rust/src/main.rs +++ b/getting-started-guides/rust/src/main.rs @@ -6,7 +6,7 @@ use opentelemetry::{global, KeyValue}; use opentelemetry::trace::{Span, Status, Tracer}; use opentelemetry_sdk::runtime; use opentelemetry_sdk::propagation::TraceContextPropagator; -use opentelemetry_sdk::resource::{Resource, ResourceDetector, TelemetryResourceDetector}; +use opentelemetry_sdk::resource::{EnvResourceDetector, ResourceDetector, SdkProvidedResourceDetector, TelemetryResourceDetector}; use opentelemetry_sdk::trace::Config; use serde::{Serialize, Deserialize}; @@ -82,13 +82,12 @@ fn compute_fibonacci(n: i64) -> Result> { async fn main() -> std::io::Result<()> { global::set_text_map_propagator(TraceContextPropagator::new()); + let sdk_provided_resource = SdkProvidedResourceDetector.detect(Duration::from_secs(0)); + let env_resource = EnvResourceDetector::new().detect(Duration::from_secs(0)); let telemetry_resource = TelemetryResourceDetector.detect(Duration::from_secs(0)); - let service_name_resource = Resource::new(vec![KeyValue::new( - "service.name", - "getting-started-rust" - )]); - - let resource = service_name_resource.merge(&telemetry_resource); + let resource = sdk_provided_resource + .merge(&env_resource) + .merge(&telemetry_resource); let _tracer = opentelemetry_otlp::new_pipeline() .tracing() @@ -102,7 +101,7 @@ async fn main() -> std::io::Result<()> { .wrap(RequestTracing::new()) .route("/fibonacci", web::get().to(fibonacci)) }) - .bind(("127.0.0.1", 8080))? + .bind(("0.0.0.0", 8080))? .run() .await?; diff --git a/getting-started-guides/supporting-files/envoy.yaml b/getting-started-guides/supporting-files/envoy.yaml index cac2fb41..641bde7c 100644 --- a/getting-started-guides/supporting-files/envoy.yaml +++ b/getting-started-guides/supporting-files/envoy.yaml @@ -30,6 +30,8 @@ static_resources: route: { cluster: python, prefix_rewrite: "/fibonacci" } - match: { prefix: "/ruby/fibonacci" } route: { cluster: ruby, prefix_rewrite: "/fibonacci" } + - match: { prefix: "/rust/fibonacci" } + route: { cluster: rust, prefix_rewrite: "/fibonacci" } http_filters: - name: envoy.filters.http.router typed_config: @@ -108,3 +110,15 @@ static_resources: socket_address: address: ruby port_value: 8080 + - name: rust + type: STRICT_DNS + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: rust + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: rust + port_value: 8080 diff --git a/getting-started-guides/supporting-files/loadgenerator.py b/getting-started-guides/supporting-files/loadgenerator.py index 63158a21..47afa8be 100644 --- a/getting-started-guides/supporting-files/loadgenerator.py +++ b/getting-started-guides/supporting-files/loadgenerator.py @@ -6,7 +6,7 @@ def signal_handler(signal, frame): signal.signal(signal.SIGINT, signal_handler) -languages = ["dotnet", "go", "java", "javascript", "python", "ruby"] +languages = ["dotnet", "go", "java", "javascript", "python", "ruby", "rust"] while True: n = random.randint(1, 100)