From 1366ea1f8fe40b5439b5cb7af7d4035e8557ca9e Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 3 May 2026 05:36:49 +0000 Subject: [PATCH] feat(observability): add OpenTelemetry layer across all services Wire OTel SDK / auto-instrumentation into all six ZylkerKart services (.NET, Node.js, Python, Go, Java x2). Activated by S247_OTEL_ENABLED=true and exports traces + metrics over OTLP/HTTP to a configurable Site24x7 endpoint, with the license key sent as the Api-Key header. - docker-compose.yml: per-service entrypoint branch installs the matching OTel agent/SDK at runtime and exports OTEL_EXPORTER_OTLP_* env vars; OTel takes precedence over the proprietary APM agents to avoid dual-agent collisions. - auth-service (.NET): OpenTelemetry NuGet packages + tracer/meter provider configured in Program.cs, gated on S247_OTEL_ENABLED. - order-service (Node.js): tracing.js bootstrap registered via --require, with auto-instrumentations + OTLP HTTP exporters. - payment-service (Python): opentelemetry-distro + instrumentations bootstrapped via opentelemetry-instrument. - search-service (Go): observability/otel.go initialises the global TracerProvider; otelgin middleware wraps Gin. - product-service / storefront (Java): OpenTelemetry javaagent JAR downloaded and attached via -javaagent. - k8s/site24x7-otel-secret.yaml: new Kubernetes Secret holding the license key plus a sibling ConfigMap with endpoint/protocol settings. - baremetal/config/*.env.example: documented OTel env block (regional endpoints, OTLP headers) for systemd deployments. --- .../baremetal/config/auth-service.env.example | 11 ++ .../config/order-service.env.example | 11 ++ .../config/payment-service.env.example | 11 ++ .../config/product-service.env.example | 11 ++ .../config/search-service.env.example | 11 ++ .../baremetal/config/storefront.env.example | 11 ++ .../ZylkerKart_Ecommerce/docker-compose.yml | 127 +++++++++++++++++- .../k8s/site24x7-otel-secret.yaml | 51 +++++++ .../services/auth-service/AuthService.csproj | 7 + .../services/auth-service/Program.cs | 27 ++++ .../services/order-service/package.json | 8 ++ .../services/order-service/src/tracing.js | 39 ++++++ .../services/payment-service/requirements.txt | 6 + .../services/search-service/go.mod | 5 + .../services/search-service/main.go | 15 +++ .../search-service/observability/otel.go | 64 +++++++++ 16 files changed, 410 insertions(+), 5 deletions(-) create mode 100644 Applications/ZylkerKart_Ecommerce/k8s/site24x7-otel-secret.yaml create mode 100644 Applications/ZylkerKart_Ecommerce/services/order-service/src/tracing.js create mode 100644 Applications/ZylkerKart_Ecommerce/services/search-service/observability/otel.go diff --git a/Applications/ZylkerKart_Ecommerce/baremetal/config/auth-service.env.example b/Applications/ZylkerKart_Ecommerce/baremetal/config/auth-service.env.example index 56045a6..7cf255d 100644 --- a/Applications/ZylkerKart_Ecommerce/baremetal/config/auth-service.env.example +++ b/Applications/ZylkerKart_Ecommerce/baremetal/config/auth-service.env.example @@ -30,3 +30,14 @@ CHAOS_SDK_CONFIG_DIR=/var/site24x7-labs/faults # S247_APM_ENABLED=false # S247_LICENSE_KEY= # SITE24X7_APP_NAME=ZylkerKart-Auth + +# ── Site24x7 OpenTelemetry (Optional) ─────────────────────────────────────── +# Mutually exclusive with S247_APM_ENABLED. License key is sent as the OTLP +# `Api-Key` header. Pick the regional endpoint matching your datacenter. +# S247_OTEL_ENABLED=false +# S247_LICENSE_KEY= +# OTEL_SERVICE_NAME=ZylkerKart-Auth +# OTEL_EXPORTER_OTLP_ENDPOINT=https://otel.site24x7.com:443 +# OTEL_EXPORTER_OTLP_HEADERS=Api-Key=${S247_LICENSE_KEY} +# OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf +# OTEL_RESOURCE_ATTRIBUTES=service.name=ZylkerKart-Auth,service.version=1.0.0,deployment.environment=baremetal diff --git a/Applications/ZylkerKart_Ecommerce/baremetal/config/order-service.env.example b/Applications/ZylkerKart_Ecommerce/baremetal/config/order-service.env.example index 79e487f..b437cf8 100644 --- a/Applications/ZylkerKart_Ecommerce/baremetal/config/order-service.env.example +++ b/Applications/ZylkerKart_Ecommerce/baremetal/config/order-service.env.example @@ -34,3 +34,14 @@ CHAOS_SDK_CONFIG_DIR=/var/site24x7-labs/faults # APMINSIGHT_LICENSE_KEY= # APMINSIGHT_APP_NAME=ZylkerKart-Order # APMINSIGHT_APP_PORT=8082 + +# ── Site24x7 OpenTelemetry (Optional) ─────────────────────────────────────── +# Mutually exclusive with S247_APM_ENABLED. License key is sent as the OTLP +# `Api-Key` header. Pick the regional endpoint matching your datacenter. +# S247_OTEL_ENABLED=false +# S247_LICENSE_KEY= +# OTEL_SERVICE_NAME=ZylkerKart-Order +# OTEL_EXPORTER_OTLP_ENDPOINT=https://otel.site24x7.com:443 +# OTEL_EXPORTER_OTLP_HEADERS=Api-Key=${S247_LICENSE_KEY} +# OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf +# OTEL_RESOURCE_ATTRIBUTES=service.name=ZylkerKart-Order,service.version=1.0.0,deployment.environment=baremetal diff --git a/Applications/ZylkerKart_Ecommerce/baremetal/config/payment-service.env.example b/Applications/ZylkerKart_Ecommerce/baremetal/config/payment-service.env.example index 2b18557..ca875bf 100644 --- a/Applications/ZylkerKart_Ecommerce/baremetal/config/payment-service.env.example +++ b/Applications/ZylkerKart_Ecommerce/baremetal/config/payment-service.env.example @@ -24,3 +24,14 @@ CHAOS_SDK_CONFIG_DIR=/var/site24x7-labs/faults # S247_APM_ENABLED=false # S247_LICENSE_KEY= # APM_APP_NAME=ZylkerKart-Payment + +# ── Site24x7 OpenTelemetry (Optional) ─────────────────────────────────────── +# Mutually exclusive with S247_APM_ENABLED. License key is sent as the OTLP +# `Api-Key` header. Pick the regional endpoint matching your datacenter. +# S247_OTEL_ENABLED=false +# S247_LICENSE_KEY= +# OTEL_SERVICE_NAME=ZylkerKart-Payment +# OTEL_EXPORTER_OTLP_ENDPOINT=https://otel.site24x7.com:443 +# OTEL_EXPORTER_OTLP_HEADERS=Api-Key=${S247_LICENSE_KEY} +# OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf +# OTEL_RESOURCE_ATTRIBUTES=service.name=ZylkerKart-Payment,service.version=1.0.0,deployment.environment=baremetal diff --git a/Applications/ZylkerKart_Ecommerce/baremetal/config/product-service.env.example b/Applications/ZylkerKart_Ecommerce/baremetal/config/product-service.env.example index 92cc3cf..c81733b 100644 --- a/Applications/ZylkerKart_Ecommerce/baremetal/config/product-service.env.example +++ b/Applications/ZylkerKart_Ecommerce/baremetal/config/product-service.env.example @@ -27,3 +27,14 @@ CHAOS_SDK_CONFIG_DIR=/var/site24x7-labs/faults # ── Site24x7 APM (Optional) ───────────────────────────────────────────────── # S247_APM_ENABLED=false # S247_LICENSE_KEY= + +# ── Site24x7 OpenTelemetry (Optional) ─────────────────────────────────────── +# Mutually exclusive with S247_APM_ENABLED. License key is sent as the OTLP +# `Api-Key` header. Pick the regional endpoint matching your datacenter. +# S247_OTEL_ENABLED=false +# S247_LICENSE_KEY= +# OTEL_SERVICE_NAME=ZylkerKart-Product +# OTEL_EXPORTER_OTLP_ENDPOINT=https://otel.site24x7.com:443 +# OTEL_EXPORTER_OTLP_HEADERS=Api-Key=${S247_LICENSE_KEY} +# OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf +# OTEL_RESOURCE_ATTRIBUTES=service.name=ZylkerKart-Product,service.version=1.0.0,deployment.environment=baremetal diff --git a/Applications/ZylkerKart_Ecommerce/baremetal/config/search-service.env.example b/Applications/ZylkerKart_Ecommerce/baremetal/config/search-service.env.example index 25fbcbc..a068d3e 100644 --- a/Applications/ZylkerKart_Ecommerce/baremetal/config/search-service.env.example +++ b/Applications/ZylkerKart_Ecommerce/baremetal/config/search-service.env.example @@ -32,3 +32,14 @@ CHAOS_SDK_CONFIG_DIR=/var/site24x7-labs/faults # ── Site24x7 APM (Optional) ───────────────────────────────────────────────── # S247_APM_ENABLED=false # S247_LICENSE_KEY= + +# ── Site24x7 OpenTelemetry (Optional) ─────────────────────────────────────── +# Mutually exclusive with S247_APM_ENABLED. License key is sent as the OTLP +# `Api-Key` header. Pick the regional endpoint matching your datacenter. +# S247_OTEL_ENABLED=false +# S247_LICENSE_KEY= +# OTEL_SERVICE_NAME=ZylkerKart-Search +# OTEL_EXPORTER_OTLP_ENDPOINT=https://otel.site24x7.com:443 +# OTEL_EXPORTER_OTLP_HEADERS=Api-Key=${S247_LICENSE_KEY} +# OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf +# OTEL_RESOURCE_ATTRIBUTES=service.name=ZylkerKart-Search,service.version=1.0.0,deployment.environment=baremetal diff --git a/Applications/ZylkerKart_Ecommerce/baremetal/config/storefront.env.example b/Applications/ZylkerKart_Ecommerce/baremetal/config/storefront.env.example index c12cb8f..ac0d931 100644 --- a/Applications/ZylkerKart_Ecommerce/baremetal/config/storefront.env.example +++ b/Applications/ZylkerKart_Ecommerce/baremetal/config/storefront.env.example @@ -30,3 +30,14 @@ CHAOS_SDK_CONFIG_DIR=/var/site24x7-labs/faults # S247_APM_ENABLED=false # S247_LICENSE_KEY= # SITE24X7_RUM_KEY= + +# ── Site24x7 OpenTelemetry (Optional) ─────────────────────────────────────── +# Mutually exclusive with S247_APM_ENABLED. License key is sent as the OTLP +# `Api-Key` header. Pick the regional endpoint matching your datacenter. +# S247_OTEL_ENABLED=false +# S247_LICENSE_KEY= +# OTEL_SERVICE_NAME=ZylkerKart-Storefront +# OTEL_EXPORTER_OTLP_ENDPOINT=https://otel.site24x7.com:443 +# OTEL_EXPORTER_OTLP_HEADERS=Api-Key=${S247_LICENSE_KEY} +# OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf +# OTEL_RESOURCE_ATTRIBUTES=service.name=ZylkerKart-Storefront,service.version=1.0.0,deployment.environment=baremetal diff --git a/Applications/ZylkerKart_Ecommerce/docker-compose.yml b/Applications/ZylkerKart_Ecommerce/docker-compose.yml index f24ebb2..fafab60 100644 --- a/Applications/ZylkerKart_Ecommerce/docker-compose.yml +++ b/Applications/ZylkerKart_Ecommerce/docker-compose.yml @@ -25,6 +25,28 @@ version: "3.9" # S247_LICENSE_KEY=your_license_key_here # # When S247_APM_ENABLED=false (default), services run without any APM overhead. +# +# Site24x7 OpenTelemetry Integration +# ────────────────────────────────── +# Alternatively (and mutually exclusive with the proprietary APM agents above), +# every service can export traces/metrics to Site24x7 via the OpenTelemetry +# OTLP/HTTP protocol: +# +# S247_OTEL_ENABLED=true \ +# S247_LICENSE_KEY= \ +# S247_OTEL_ENDPOINT=https://otel.site24x7.com:443 \ +# docker compose up +# +# Regional endpoints (set S247_OTEL_ENDPOINT accordingly): +# US https://otel.site24x7.com:443 +# EU https://otel.site24x7.eu:443 +# India https://otel.site24x7.in:443 +# China https://otel.site24x7.cn:443 +# Australia https://otel.site24x7.com.au:443 +# +# The license key is sent as the `Api-Key` OTLP header. When S247_OTEL_ENABLED +# and S247_APM_ENABLED are both true, OTel takes precedence per service to +# avoid agent collisions (e.g. dual -javaagent loaders). # ───────────────────────────────────────────────────────────────────────────── services: @@ -87,9 +109,28 @@ services: REDIS_HOST: redis REDIS_PORT: 6379 S247_APM_ENABLED: ${S247_APM_ENABLED:-false} + S247_OTEL_ENABLED: ${S247_OTEL_ENABLED:-false} S247_LICENSE_KEY: ${S247_LICENSE_KEY:-} + S247_OTEL_ENDPOINT: ${S247_OTEL_ENDPOINT:-https://otel.site24x7.com:443} + OTEL_SERVICE_NAME: ZylkerKart-Product entrypoint: ["/bin/sh", "-c", " - if [ \"$$S247_APM_ENABLED\" = \"true\" ]; then + if [ \"$$S247_OTEL_ENABLED\" = \"true\" ]; then + echo '[OTel] Enabled for Product Service (Java)'; + if [ ! -f /opt/otel-agent/opentelemetry-javaagent.jar ]; then + echo '[OTel] Downloading OpenTelemetry Java agent...'; + apt-get update -qq && apt-get install -y -qq wget > /dev/null 2>&1; + mkdir -p /opt/otel-agent; + wget -q -O /opt/otel-agent/opentelemetry-javaagent.jar https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar; + echo '[OTel] Java agent installed.'; + fi; + export OTEL_EXPORTER_OTLP_ENDPOINT=$$S247_OTEL_ENDPOINT; + export OTEL_EXPORTER_OTLP_HEADERS=\"Api-Key=$$S247_LICENSE_KEY\"; + export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf; + export OTEL_RESOURCE_ATTRIBUTES=service.name=$$OTEL_SERVICE_NAME,service.version=1.0.0,deployment.environment=demo; + exec java -Xms256m -Xmx512m + -javaagent:/opt/otel-agent/opentelemetry-javaagent.jar + -jar app.jar; + elif [ \"$$S247_APM_ENABLED\" = \"true\" ]; then echo '[Site24x7] APM enabled for Product Service (Java)'; if [ ! -f /opt/s247-agent/apminsight-javaagent.jar ]; then echo '[Site24x7] Downloading Java agent...'; @@ -113,6 +154,7 @@ services: "] volumes: - s247_java_agent:/opt/s247-agent + - otel_java_product:/opt/otel-agent depends_on: mysql: condition: service_healthy @@ -150,12 +192,31 @@ services: PAYMENT_SERVICE_URL: http://payment-service:8084 AUTH_SERVICE_URL: http://auth-service:8085 S247_APM_ENABLED: ${S247_APM_ENABLED:-false} + S247_OTEL_ENABLED: ${S247_OTEL_ENABLED:-false} S247_LICENSE_KEY: ${S247_LICENSE_KEY:-} + S247_OTEL_ENDPOINT: ${S247_OTEL_ENDPOINT:-https://otel.site24x7.com:443} + OTEL_SERVICE_NAME: ZylkerKart-Order APMINSIGHT_LICENSE_KEY: ${S247_LICENSE_KEY:-} APMINSIGHT_APP_NAME: ZylkerKart-Order APMINSIGHT_APP_PORT: 8082 command: ["/bin/sh", "-c", " - if [ \"$$S247_APM_ENABLED\" = \"true\" ]; then + if [ \"$$S247_OTEL_ENABLED\" = \"true\" ]; then + echo '[OTel] Enabled for Order Service (Node.js)'; + npm install --silent --no-save \ + @opentelemetry/api \ + @opentelemetry/sdk-node \ + @opentelemetry/auto-instrumentations-node \ + @opentelemetry/exporter-trace-otlp-http \ + @opentelemetry/exporter-metrics-otlp-http \ + @opentelemetry/sdk-metrics \ + @opentelemetry/resources \ + @opentelemetry/semantic-conventions 2>/dev/null; + export OTEL_EXPORTER_OTLP_ENDPOINT=$$S247_OTEL_ENDPOINT; + export OTEL_EXPORTER_OTLP_HEADERS=\"Api-Key=$$S247_LICENSE_KEY\"; + export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf; + export OTEL_RESOURCE_ATTRIBUTES=service.name=$$OTEL_SERVICE_NAME,service.version=1.0.0,deployment.environment=demo; + exec node --require ./src/tracing.js src/app.js; + elif [ \"$$S247_APM_ENABLED\" = \"true\" ]; then echo '[Site24x7] APM enabled for Order Service (Node.js)'; npm install apminsight --silent 2>/dev/null; echo '[Site24x7] Node.js agent installed.'; @@ -197,6 +258,13 @@ services: DB_NAME: db_search REDIS_HOST: redis REDIS_PORT: 6379 + S247_OTEL_ENABLED: ${S247_OTEL_ENABLED:-false} + S247_LICENSE_KEY: ${S247_LICENSE_KEY:-} + OTEL_SERVICE_NAME: ZylkerKart-Search + OTEL_EXPORTER_OTLP_ENDPOINT: ${S247_OTEL_ENDPOINT:-https://otel.site24x7.com:443} + OTEL_EXPORTER_OTLP_HEADERS: "Api-Key=${S247_LICENSE_KEY:-}" + OTEL_EXPORTER_OTLP_PROTOCOL: http/protobuf + OTEL_RESOURCE_ATTRIBUTES: "service.name=ZylkerKart-Search,service.version=1.0.0,deployment.environment=demo" depends_on: mysql: condition: service_healthy @@ -232,10 +300,24 @@ services: REDIS_HOST: redis REDIS_PORT: 6379 S247_APM_ENABLED: ${S247_APM_ENABLED:-false} + S247_OTEL_ENABLED: ${S247_OTEL_ENABLED:-false} S247_LICENSE_KEY: ${S247_LICENSE_KEY:-} + S247_OTEL_ENDPOINT: ${S247_OTEL_ENDPOINT:-https://otel.site24x7.com:443} + OTEL_SERVICE_NAME: ZylkerKart-Payment APM_APP_NAME: ZylkerKart-Payment command: ["/bin/sh", "-c", " - if [ \"$$S247_APM_ENABLED\" = \"true\" ]; then + if [ \"$$S247_OTEL_ENABLED\" = \"true\" ]; then + echo '[OTel] Enabled for Payment Service (Python)'; + pip install -q opentelemetry-distro opentelemetry-exporter-otlp \ + opentelemetry-instrumentation-fastapi opentelemetry-instrumentation-mysql \ + opentelemetry-instrumentation-httpx opentelemetry-instrumentation-logging 2>/dev/null; + opentelemetry-bootstrap -a install >/dev/null 2>&1 || true; + export OTEL_EXPORTER_OTLP_ENDPOINT=$$S247_OTEL_ENDPOINT; + export OTEL_EXPORTER_OTLP_HEADERS=\"Api-Key=$$S247_LICENSE_KEY\"; + export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf; + export OTEL_RESOURCE_ATTRIBUTES=service.name=$$OTEL_SERVICE_NAME,service.version=1.0.0,deployment.environment=demo; + exec opentelemetry-instrument uvicorn app.main:app --host 0.0.0.0 --port 8084; + elif [ \"$$S247_APM_ENABLED\" = \"true\" ]; then echo '[Site24x7] APM enabled for Payment Service (Python)'; if [ ! -f /opt/S247DataExporter/bin/service.sh ]; then echo '[Site24x7] Installing S247DataExporter...'; @@ -292,10 +374,20 @@ services: JWT_EXPIRY_MINUTES: 15 JWT_REFRESH_EXPIRY_DAYS: 7 S247_APM_ENABLED: ${S247_APM_ENABLED:-false} + S247_OTEL_ENABLED: ${S247_OTEL_ENABLED:-false} S247_LICENSE_KEY: ${S247_LICENSE_KEY:-} + S247_OTEL_ENDPOINT: ${S247_OTEL_ENDPOINT:-https://otel.site24x7.com:443} + OTEL_SERVICE_NAME: ZylkerKart-Auth + OTEL_EXPORTER_OTLP_ENDPOINT: ${S247_OTEL_ENDPOINT:-https://otel.site24x7.com:443} + OTEL_EXPORTER_OTLP_HEADERS: "Api-Key=${S247_LICENSE_KEY:-}" + OTEL_EXPORTER_OTLP_PROTOCOL: http/protobuf + OTEL_RESOURCE_ATTRIBUTES: "service.name=ZylkerKart-Auth,service.version=1.0.0,deployment.environment=demo" SITE24X7_APP_NAME: ZylkerKart-Auth entrypoint: ["/bin/sh", "-c", " - if [ \"$$S247_APM_ENABLED\" = \"true\" ]; then + if [ \"$$S247_OTEL_ENABLED\" = \"true\" ]; then + echo '[OTel] Enabled for Auth Service (.NET) — exporter wired via OpenTelemetry SDK'; + exec dotnet AuthService.dll; + elif [ \"$$S247_APM_ENABLED\" = \"true\" ]; then echo '[Site24x7] APM enabled for Auth Service (.NET)'; if [ ! -f /opt/apminsight/dotnet/ApmInsightDotNetCoreAgent/DotNetCoreAgent/apminsight.conf ]; then echo '[Site24x7] Downloading .NET agent...'; @@ -357,9 +449,28 @@ services: REDIS_HOST: redis REDIS_PORT: 6379 S247_APM_ENABLED: ${S247_APM_ENABLED:-false} + S247_OTEL_ENABLED: ${S247_OTEL_ENABLED:-false} S247_LICENSE_KEY: ${S247_LICENSE_KEY:-} + S247_OTEL_ENDPOINT: ${S247_OTEL_ENDPOINT:-https://otel.site24x7.com:443} + OTEL_SERVICE_NAME: ZylkerKart-Storefront entrypoint: ["/bin/sh", "-c", " - if [ \"$$S247_APM_ENABLED\" = \"true\" ]; then + if [ \"$$S247_OTEL_ENABLED\" = \"true\" ]; then + echo '[OTel] Enabled for Storefront (Java)'; + if [ ! -f /opt/otel-agent/opentelemetry-javaagent.jar ]; then + echo '[OTel] Downloading OpenTelemetry Java agent...'; + apt-get update -qq && apt-get install -y -qq wget > /dev/null 2>&1; + mkdir -p /opt/otel-agent; + wget -q -O /opt/otel-agent/opentelemetry-javaagent.jar https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar; + echo '[OTel] Java agent installed.'; + fi; + export OTEL_EXPORTER_OTLP_ENDPOINT=$$S247_OTEL_ENDPOINT; + export OTEL_EXPORTER_OTLP_HEADERS=\"Api-Key=$$S247_LICENSE_KEY\"; + export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf; + export OTEL_RESOURCE_ATTRIBUTES=service.name=$$OTEL_SERVICE_NAME,service.version=1.0.0,deployment.environment=demo; + exec java -Xms256m -Xmx512m + -javaagent:/opt/otel-agent/opentelemetry-javaagent.jar + -jar app.jar; + elif [ \"$$S247_APM_ENABLED\" = \"true\" ]; then echo '[Site24x7] APM enabled for Storefront (Java)'; if [ ! -f /opt/s247-agent/apminsight-javaagent.jar ]; then echo '[Site24x7] Downloading Java agent...'; @@ -383,6 +494,7 @@ services: "] volumes: - s247_java_storefront:/opt/s247-agent + - otel_java_storefront:/opt/otel-agent depends_on: - product-service - order-service @@ -436,6 +548,11 @@ volumes: driver: local s247_java_storefront: driver: local + # OTel javaagent cache volumes (persist across restarts) + otel_java_product: + driver: local + otel_java_storefront: + driver: local # ── Networks ─────────────────────────────────────────────────────────────── networks: diff --git a/Applications/ZylkerKart_Ecommerce/k8s/site24x7-otel-secret.yaml b/Applications/ZylkerKart_Ecommerce/k8s/site24x7-otel-secret.yaml new file mode 100644 index 0000000..331522c --- /dev/null +++ b/Applications/ZylkerKart_Ecommerce/k8s/site24x7-otel-secret.yaml @@ -0,0 +1,51 @@ +# ───────────────────────────────────────────────────────────────────────────── +# ZylkerKart — Site24x7 OpenTelemetry credentials +# ───────────────────────────────────────────────────────────────────────────── +# This Secret holds the Site24x7 license key used by the OTel exporter as the +# OTLP `Api-Key` header. Apply it before rolling out workloads with +# S247_OTEL_ENABLED=true: +# +# 1. Replace REPLACE_WITH_YOUR_SITE24X7_LICENSE_KEY below (or apply via +# `kubectl create secret generic ...` with --from-literal). +# 2. kubectl apply -f k8s/site24x7-otel-secret.yaml +# 3. In each Deployment, source S247_LICENSE_KEY from this Secret (see the +# ConfigMap-based deployments in `Terraform Deployment/k8s-resources.tf` +# — switch the `value_from.config_map_key_ref` for S247_LICENSE_KEY to a +# `secret_key_ref` pointing at this Secret). +# +# Regional OTLP endpoints (set via the ConfigMap or per-Deployment env): +# US https://otel.site24x7.com:443 +# EU https://otel.site24x7.eu:443 +# India https://otel.site24x7.in:443 +# China https://otel.site24x7.cn:443 +# Australia https://otel.site24x7.com.au:443 +# ───────────────────────────────────────────────────────────────────────────── +apiVersion: v1 +kind: Secret +metadata: + name: site24x7-otel + namespace: zylkerkart + labels: + app.kubernetes.io/part-of: zylkerkart + app.kubernetes.io/component: observability +type: Opaque +stringData: + # Site24x7 device license key — used as the OTLP `Api-Key` header. + S247_LICENSE_KEY: "REPLACE_WITH_YOUR_SITE24X7_LICENSE_KEY" +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: site24x7-otel-config + namespace: zylkerkart + labels: + app.kubernetes.io/part-of: zylkerkart + app.kubernetes.io/component: observability +data: + # Toggle OTel export on/off without touching service Deployments. + S247_OTEL_ENABLED: "true" + # Pick the regional endpoint matching your Site24x7 datacenter. + S247_OTEL_ENDPOINT: "https://otel.site24x7.com:443" + OTEL_EXPORTER_OTLP_ENDPOINT: "https://otel.site24x7.com:443" + OTEL_EXPORTER_OTLP_PROTOCOL: "http/protobuf" + OTEL_RESOURCE_ATTRIBUTES: "deployment.environment=demo,service.namespace=zylkerkart" diff --git a/Applications/ZylkerKart_Ecommerce/services/auth-service/AuthService.csproj b/Applications/ZylkerKart_Ecommerce/services/auth-service/AuthService.csproj index 5ea6ecb..d79eb6b 100644 --- a/Applications/ZylkerKart_Ecommerce/services/auth-service/AuthService.csproj +++ b/Applications/ZylkerKart_Ecommerce/services/auth-service/AuthService.csproj @@ -14,6 +14,13 @@ + + + + + + + diff --git a/Applications/ZylkerKart_Ecommerce/services/auth-service/Program.cs b/Applications/ZylkerKart_Ecommerce/services/auth-service/Program.cs index cc4712c..3c301d4 100644 --- a/Applications/ZylkerKart_Ecommerce/services/auth-service/Program.cs +++ b/Applications/ZylkerKart_Ecommerce/services/auth-service/Program.cs @@ -2,12 +2,39 @@ using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.EntityFrameworkCore; using Microsoft.IdentityModel.Tokens; +using OpenTelemetry.Metrics; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; using Site24x7.Chaos.Extensions; using ZylkerKart.AuthService.Data; using ZylkerKart.AuthService.Services; var builder = WebApplication.CreateBuilder(args); +// ─── OpenTelemetry → Site24x7 ─────────────────────────────── +// Activated by S247_OTEL_ENABLED=true. Exporter reads OTEL_EXPORTER_OTLP_* +// env vars, which the entrypoint script populates with the Site24x7 endpoint +// and license-key header. +var otelEnabled = string.Equals(Environment.GetEnvironmentVariable("S247_OTEL_ENABLED"), "true", + StringComparison.OrdinalIgnoreCase); +if (otelEnabled) +{ + var serviceName = Environment.GetEnvironmentVariable("OTEL_SERVICE_NAME") ?? "ZylkerKart-Auth"; + builder.Services.AddOpenTelemetry() + .ConfigureResource(r => r.AddService(serviceName, serviceVersion: "1.0.0")) + .WithTracing(t => t + .AddAspNetCoreInstrumentation() + .AddHttpClientInstrumentation() + .AddEntityFrameworkCoreInstrumentation() + .AddOtlpExporter()) + .WithMetrics(m => m + .AddAspNetCoreInstrumentation() + .AddHttpClientInstrumentation() + .AddRuntimeInstrumentation() + .AddOtlpExporter()); + Console.WriteLine($"[otel] Auth Service tracing → {Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "default OTLP endpoint"}"); +} + // ─── Database ─────────────────────────────────────────────── var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? $"Server={Environment.GetEnvironmentVariable("DB_HOST") ?? "mysql"};" + diff --git a/Applications/ZylkerKart_Ecommerce/services/order-service/package.json b/Applications/ZylkerKart_Ecommerce/services/order-service/package.json index a3a1df0..444d516 100644 --- a/Applications/ZylkerKart_Ecommerce/services/order-service/package.json +++ b/Applications/ZylkerKart_Ecommerce/services/order-service/package.json @@ -9,6 +9,14 @@ }, "dependencies": { "site24x7-chaos-sdk": "1.1.2", + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/auto-instrumentations-node": "^0.52.0", + "@opentelemetry/exporter-trace-otlp-http": "^0.54.0", + "@opentelemetry/exporter-metrics-otlp-http": "^0.54.0", + "@opentelemetry/sdk-node": "^0.54.0", + "@opentelemetry/sdk-metrics": "^1.27.0", + "@opentelemetry/resources": "^1.27.0", + "@opentelemetry/semantic-conventions": "^1.27.0", "axios": "^1.6.5", "cors": "^2.8.5", "express": "^4.18.2", diff --git a/Applications/ZylkerKart_Ecommerce/services/order-service/src/tracing.js b/Applications/ZylkerKart_Ecommerce/services/order-service/src/tracing.js new file mode 100644 index 0000000..39a690e --- /dev/null +++ b/Applications/ZylkerKart_Ecommerce/services/order-service/src/tracing.js @@ -0,0 +1,39 @@ +'use strict'; + +// OpenTelemetry bootstrap for ZylkerKart Order Service. +// Loaded via `node --require ./src/tracing.js` when S247_OTEL_ENABLED=true. +// Exporter targets the Site24x7 OTLP/HTTP endpoint configured via standard +// OTEL_EXPORTER_OTLP_* env vars. The license key is injected as the `Api-Key` +// header by the entrypoint script. + +const { NodeSDK } = require('@opentelemetry/sdk-node'); +const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node'); +const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http'); +const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-http'); +const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics'); +const { resourceFromAttributes } = require('@opentelemetry/resources'); +const { + ATTR_SERVICE_NAME, + ATTR_SERVICE_VERSION, +} = require('@opentelemetry/semantic-conventions'); + +const sdk = new NodeSDK({ + resource: resourceFromAttributes({ + [ATTR_SERVICE_NAME]: process.env.OTEL_SERVICE_NAME || 'ZylkerKart-Order', + [ATTR_SERVICE_VERSION]: process.env.OTEL_SERVICE_VERSION || '1.0.0', + 'deployment.environment': process.env.OTEL_DEPLOYMENT_ENVIRONMENT || 'demo', + }), + traceExporter: new OTLPTraceExporter(), + metricReader: new PeriodicExportingMetricReader({ + exporter: new OTLPMetricExporter(), + exportIntervalMillis: 30000, + }), + instrumentations: [getNodeAutoInstrumentations()], +}); + +sdk.start(); +console.log('[otel] Order Service tracing initialised → ' + (process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'default OTLP endpoint')); + +process.on('SIGTERM', () => { + sdk.shutdown().finally(() => process.exit(0)); +}); diff --git a/Applications/ZylkerKart_Ecommerce/services/payment-service/requirements.txt b/Applications/ZylkerKart_Ecommerce/services/payment-service/requirements.txt index ff25c71..1b881a6 100644 --- a/Applications/ZylkerKart_Ecommerce/services/payment-service/requirements.txt +++ b/Applications/ZylkerKart_Ecommerce/services/payment-service/requirements.txt @@ -6,3 +6,9 @@ python-dotenv==1.0.0 httpx==0.26.0 python-multipart==0.0.6 site24x7-chaos[fastapi]==1.1.2 +opentelemetry-distro==0.50b0 +opentelemetry-exporter-otlp==1.29.0 +opentelemetry-instrumentation-fastapi==0.50b0 +opentelemetry-instrumentation-mysql==0.50b0 +opentelemetry-instrumentation-httpx==0.50b0 +opentelemetry-instrumentation-logging==0.50b0 diff --git a/Applications/ZylkerKart_Ecommerce/services/search-service/go.mod b/Applications/ZylkerKart_Ecommerce/services/search-service/go.mod index f1134bd..6645dce 100644 --- a/Applications/ZylkerKart_Ecommerce/services/search-service/go.mod +++ b/Applications/ZylkerKart_Ecommerce/services/search-service/go.mod @@ -8,6 +8,11 @@ require ( github.com/go-sql-driver/mysql v1.7.1 github.com/redis/go-redis/v9 v9.4.0 github.com/site24x7/observe-labs/sdks/go v1.1.2 + go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.56.0 + go.opentelemetry.io/otel v1.31.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 + go.opentelemetry.io/otel/sdk v1.31.0 ) require ( diff --git a/Applications/ZylkerKart_Ecommerce/services/search-service/main.go b/Applications/ZylkerKart_Ecommerce/services/search-service/main.go index 8a422dc..88333b7 100644 --- a/Applications/ZylkerKart_Ecommerce/services/search-service/main.go +++ b/Applications/ZylkerKart_Ecommerce/services/search-service/main.go @@ -1,12 +1,14 @@ package main import ( + "context" "fmt" "log" "os" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" + "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin" chaos "github.com/site24x7/observe-labs/sdks/go" "github.com/site24x7/observe-labs/sdks/go/fault" @@ -14,9 +16,19 @@ import ( "zylkerkart/search-service/config" "zylkerkart/search-service/handlers" + "zylkerkart/search-service/observability" ) func main() { + // OpenTelemetry → Site24x7 (no-op when S247_OTEL_ENABLED != "true") + otelShutdown, err := observability.InitTracer(context.Background(), + config.GetEnv("OTEL_SERVICE_NAME", "ZylkerKart-Search")) + if err != nil { + log.Printf("[otel] init failed: %v", err) + } else if otelShutdown != nil { + defer otelShutdown(context.Background()) + } + // Initialize Site24x7 Labs Chaos SDK chaosInstance, err := chaos.InitChaos( config.GetEnv("CHAOS_SDK_APP_NAME", "search-service"), @@ -43,6 +55,9 @@ func main() { r := gin.Default() + // OTel HTTP server instrumentation (no-op if tracer provider is the default no-op) + r.Use(otelgin.Middleware(config.GetEnv("OTEL_SERVICE_NAME", "ZylkerKart-Search"))) + // Chaos SDK middleware (inbound HTTP faults) if chaosInstance != nil { r.Use(ginmw.ChaosMiddleware(chaosInstance.Engine)) diff --git a/Applications/ZylkerKart_Ecommerce/services/search-service/observability/otel.go b/Applications/ZylkerKart_Ecommerce/services/search-service/observability/otel.go new file mode 100644 index 0000000..0bd2cd5 --- /dev/null +++ b/Applications/ZylkerKart_Ecommerce/services/search-service/observability/otel.go @@ -0,0 +1,64 @@ +// Package observability wires the OpenTelemetry SDK to a Site24x7 OTLP/HTTP +// endpoint. Activated when S247_OTEL_ENABLED=true; otherwise InitTracer is a +// no-op and returns a nil shutdown function. +package observability + +import ( + "context" + "log" + "os" + "strings" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.26.0" +) + +// InitTracer initialises the global tracer provider. Returns a shutdown +// function (nil if OTel is disabled) that flushes spans before exit. +func InitTracer(ctx context.Context, serviceName string) (func(context.Context) error, error) { + if !strings.EqualFold(os.Getenv("S247_OTEL_ENABLED"), "true") { + return nil, nil + } + + exporter, err := otlptracehttp.New(ctx) + if err != nil { + return nil, err + } + + res, err := resource.Merge( + resource.Default(), + resource.NewWithAttributes( + semconv.SchemaURL, + semconv.ServiceName(serviceName), + semconv.ServiceVersion("1.0.0"), + semconv.DeploymentEnvironmentName(envDefault("OTEL_DEPLOYMENT_ENVIRONMENT", "demo")), + ), + ) + if err != nil { + return nil, err + } + + tp := sdktrace.NewTracerProvider( + sdktrace.WithBatcher(exporter), + sdktrace.WithResource(res), + ) + otel.SetTracerProvider(tp) + otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator( + propagation.TraceContext{}, + propagation.Baggage{}, + )) + + log.Printf("[otel] Search Service tracing → %s", envDefault("OTEL_EXPORTER_OTLP_ENDPOINT", "default OTLP endpoint")) + return tp.Shutdown, nil +} + +func envDefault(key, fallback string) string { + if v := os.Getenv(key); v != "" { + return v + } + return fallback +}