diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cfa2fe..97ed596 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 1.25.3-1 + +* Add OpenTelemetry (OTel) module i.e. `nginx-module-otel`. +* Update observability headers: + * Add `X-Trace-ID`. +* Update logging fields: + * Add `otel_trace_id`. + ## 1.25.3 * Use `zappi/nginx:1.25.3` as the docker base image. diff --git a/Dockerfile b/Dockerfile index 839eb3a..62b23f9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,7 @@ RUN apt-get update -y && \ apt-get install --no-install-recommends -y \ build-essential \ ca-certificates \ + # headers-more libpcre3 \ libpcre3-dev \ wget \ @@ -18,7 +19,6 @@ WORKDIR /usr/src/ ARG NGINX_VERSION="1.25.3" ARG NGINX_PKG="nginx-${NGINX_VERSION}.tar.gz" ARG NGINX_SHA="64c5b975ca287939e828303fa857d22f142b251f17808dfe41733512d9cded86" - RUN wget "http://nginx.org/download/${NGINX_PKG}" && \ echo "${NGINX_SHA} *${NGINX_PKG}" | sha256sum -c - && \ tar --no-same-owner -xzf ${NGINX_PKG} --one-top-level=nginx --strip-components=1 @@ -27,7 +27,6 @@ RUN wget "http://nginx.org/download/${NGINX_PKG}" && \ ARG HEADERS_MORE_VERSION="0.37" ARG HEADERS_MORE_PKG="v${HEADERS_MORE_VERSION}.tar.gz" ARG HEADERS_MORE_SHA="cf6e169d6b350c06d0c730b0eaf4973394026ad40094cddd3b3a5b346577019d" - RUN wget "https://github.com/openresty/headers-more-nginx-module/archive/${HEADERS_MORE_PKG}" && \ echo "${HEADERS_MORE_SHA} *${HEADERS_MORE_PKG}" | sha256sum -c - && \ tar --no-same-owner -xzf ${HEADERS_MORE_PKG} --one-top-level=headers-more --strip-components=1 @@ -40,6 +39,28 @@ RUN cd nginx && \ # Production container starts here FROM zappi/nginx:1.25.3 +USER root + +# Set up official Nginx repository +RUN apt-get update -y && \ + apt-get install --no-install-recommends -y \ + ca-certificates \ + gnupg2 \ + wget && \ + rm -rf /var/lib/apt/lists/* /tmp/* && \ + wget -q -O - https://nginx.org/keys/nginx_signing.key | gpg --dearmor > /etc/apt/keyrings/nginx.gpg && \ + echo "deb [signed-by=/etc/apt/keyrings/nginx.gpg] http://nginx.org/packages/mainline/debian bookworm nginx" | tee /etc/apt/sources.list.d/nginx.list && \ + apt-get purge --auto-remove -y \ + ca-certificates \ + gnupg2 \ + wget + +# Module: OpenTelemetry (OTel) +RUN apt-get update -y && \ + apt-get install --no-install-recommends -y \ + nginx-module-otel && \ + rm -rf /var/lib/apt/lists/* /tmp/* + # Copy compiled module COPY --from=builder /usr/src/nginx/objs/*_module.so /etc/nginx/modules/ diff --git a/README.md b/README.md index 7881ef6..572df8e 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,23 @@ server { } ``` +### Tracing + +Add observability by enabling trace propagation and sending telemetry data to an +OTel collector: + +```nginx +otel_trace on; +otel_service_name example_service:nginx; +otel_trace_context propagate; +otel_exporter { + endpoint otel-collector:4317; + interval 5s; + batch_size 512; + batch_count 4; +} +``` + ## Further customisation Since you're defining a standard `server` block, you can configure it however you like over and above just header manipulation. For example, you can add a custom `location`: diff --git a/config/http.conf b/config/http.conf index 2251a1a..e7d2f86 100644 --- a/config/http.conf +++ b/config/http.conf @@ -84,6 +84,9 @@ http { add_header X-Proxy-Backend-Response-Time $upstream_response_time; add_header X-Proxy-Request-Time $request_time; + # Observability headers + add_header X-Trace-ID $otel_trace_id; + gzip on; gzip_comp_level 5; gzip_min_length 256; diff --git a/config/log.conf b/config/log.conf index b4ca20f..2e2e60c 100644 --- a/config/log.conf +++ b/config/log.conf @@ -16,6 +16,7 @@ log_format main_json escape=json '"http_x_proxy_backend_connect_time":"$upstream_connect_time",' '"http_x_proxy_backend_header_time":"$upstream_header_time",' '"http_x_proxy_backend_response_time":"$upstream_response_time",' + '"otel_trace_id":"$otel_trace_id",' '"proxy_connection":"$proxy_connection",' '"proxy_x_forwarded_port":"$proxy_x_forwarded_port",' '"proxy_x_forwarded_proto":"$proxy_x_forwarded_proto",' diff --git a/config/nginx.conf b/config/nginx.conf index bd52b2b..d1b207d 100644 --- a/config/nginx.conf +++ b/config/nginx.conf @@ -1,4 +1,5 @@ load_module modules/ngx_http_headers_more_filter_module.so; +load_module modules/ngx_otel_module.so; include /etc/nginx/main.conf; include /etc/nginx/http.conf; diff --git a/docker-compose.yml b/docker-compose.yml index 8bb26c2..1ce4647 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,6 +16,20 @@ services: - app networks: - local + jaeger: + image: jaegertracing/all-in-one:1.53 + ports: + - "16686:16686" + networks: + - local + otel-collector: + image: otel/opentelemetry-collector-contrib:0.92.0 + command: + - "--config=/etc/otel-collector/config.yml" + volumes: + - "./example/otel-collector-config.yml:/etc/otel-collector/config.yml" + networks: + - local networks: local: diff --git a/example/app.conf b/example/app.conf index 2dfba7f..e897379 100644 --- a/example/app.conf +++ b/example/app.conf @@ -1,5 +1,15 @@ # Example application configuration +otel_trace on; +otel_service_name example_service:nginx; +otel_trace_context propagate; +otel_exporter { + endpoint otel-collector:4317; + interval 5s; + batch_size 512; + batch_count 4; +} + server { listen 8080; diff --git a/example/otel-collector-config.yml b/example/otel-collector-config.yml new file mode 100644 index 0000000..8f8a84b --- /dev/null +++ b/example/otel-collector-config.yml @@ -0,0 +1,19 @@ +exporters: + debug: + otlp: + endpoint: jaeger:4317 + tls: + insecure: true +receivers: + otlp: + protocols: + grpc: + http: +service: + pipelines: + traces: + exporters: + - debug + - otlp + receivers: + - otlp