SigNoz
Docs
PricingCustomers
Get Started - Free
Docs
IntroductionContributingMigrate from DatadogSigNoz API
OpenTelemetry
What is OpenTelemetryOpenTelemetry Collector GuideOpenTelemetry Demo
Community
Support
Slack
X
Launch Week
Changelog
Dashboard Templates
DevOps Wordle
Newsletter
KubeCon, Atlanta 2025
More
SigNoz vs DatadogSigNoz vs New RelicSigNoz vs GrafanaSigNoz vs Dynatrace
Careers
AboutTermsPrivacySecurity & Compliance
SigNoz Logo
SigNoz
All systems operational
HIPAASOC-2
SigNoz Cloud - This page applies to SigNoz Cloud editions.
Self-Host - This page applies to self-hosted SigNoz editions.

Scala OpenTelemetry Setup Guide

This guide walks you through instrumenting your Scala application with OpenTelemetry and sending traces to SigNoz. Scala runs on the JVM, so the OpenTelemetry Java agent works directly—no additional SDK or Scala-specific library required.

Most steps are identical. To adapt this guide, update the endpoint and remove the ingestion key header as shown in Cloud → Self-Hosted.

Prerequisites

  • Java 8+
  • Scala 2.x or 3.x
  • SBT, Maven, or Gradle
  • An instance of SigNoz (either Cloud or Self-Hosted)

Auto-instrumented frameworks

The OpenTelemetry Java agent instruments these Scala frameworks automatically—no code changes required:

FrameworkMin versionWhat's instrumented
Play MVC2.4HTTP routes, controller spans
Play WS1.0HTTP client spans and metrics
Akka HTTP10.0Server spans, client spans, metrics, routes
Akka Actors2.3Context propagation
Apache Pekko1.0Context propagation, HTTP instrumentation
ZIO2.0Context propagation
ZIO HTTP3.0Route span naming
Scala ForkJoinPool2.8Context propagation

See the full supported libraries list for all frameworks and versions.

Send traces to SigNoz

A VM is a virtual computer that runs on physical hardware. This includes:

  • Cloud VMs: AWS EC2, Google Compute Engine, Azure VMs, DigitalOcean Droplets
  • On-premise VMs: VMware, VirtualBox, Hyper-V, KVM
  • Bare metal servers: Physical servers running Linux/Unix directly

Use this section if you're deploying your Scala application directly on a server or VM without containerization.

Step 1. Download the OpenTelemetry Java agent

wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar

Step 2. Set environment variables

export OTEL_RESOURCE_ATTRIBUTES="service.name=<service-name>,service.version=<service-version>"
export OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.<region>.signoz.cloud:443"
export OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=<your-ingestion-key>"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_METRICS_EXPORTER="none"
export OTEL_LOGS_EXPORTER="none"

The OpenTelemetry Java agent enables all three signals (traces, metrics, and logs) by default. Since this guide focuses on traces, we disable metrics and logs to avoid sending unwanted data to SigNoz.

If you want to collect metrics or logs later, change the respective exporter to otlp or remove the variable entirely.

Verify these values:

  • <region>: Your SigNoz Cloud region.
  • <your-ingestion-key>: Your SigNoz ingestion key.
  • <service-name>: A descriptive name for your service (e.g., checkout-service).
  • <service-version> (optional): Your release version, image tag, or git SHA (e.g., 1.4.2, a01dbef8).

Set service.version to a per-build value, not a static string. SigNoz detects a deployment each time this value changes. Common sources:

  • Bash / shell: service.version=$(git rev-parse --short HEAD)
  • GitHub Actions: service.version=${{ github.sha }}
  • GitLab CI: service.version=$CI_COMMIT_SHORT_SHA
  • Kubernetes: inject from your Helm chart image tag or CI variable

Step 3. Run your application

SBT (recommended)

SBT runs tasks in the same JVM process by default, so the agent can't attach. Enable forking in your build.sbt:

build.sbt
fork := true
run / javaOptions += "-javaagent:/path/to/opentelemetry-javaagent.jar"

Then run:

sbt run

When running a Play application from its generated startup script, prefix the javaagent flag with -J:

/path/to/bin/<project-name> -J-javaagent:/path/to/opentelemetry-javaagent.jar

The -J prefix tells Play's launcher to pass the flag to the underlying JVM instead of treating it as an application argument.

Assembly or fat JAR

If you package your application with sbt-assembly or a similar plugin, attach the agent at startup:

java -javaagent:./opentelemetry-javaagent.jar -jar your-app-assembly.jar

For centralized instrumentation management or auto-injection without code changes, see the OTel Operator tab.

Step 1. Add the agent to your Dockerfile

Dockerfile
FROM eclipse-temurin:17-jre
WORKDIR /app

COPY target/scala-2.13/<my-app>-assembly.jar app.jar

RUN wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar -O opentelemetry-javaagent.jar

ENTRYPOINT ["java", "-javaagent:/app/opentelemetry-javaagent.jar", "-jar", "app.jar"]

Replace <my-app> with your assembled JAR name.

Step 2. Deploy to Kubernetes

Add these environment variables to your deployment manifest:

deployment.yaml
env:
  - name: OTEL_RESOURCE_ATTRIBUTES
    value: 'service.name=<service-name>,service.version=<service-version>'
  - name: OTEL_EXPORTER_OTLP_ENDPOINT
    value: 'https://ingest.<region>.signoz.cloud:443'
  - name: OTEL_EXPORTER_OTLP_HEADERS
    value: 'signoz-ingestion-key=<your-ingestion-key>'
  - name: OTEL_EXPORTER_OTLP_PROTOCOL
    value: 'http/protobuf'
  - name: OTEL_METRICS_EXPORTER
    value: 'none'
  - name: OTEL_LOGS_EXPORTER
    value: 'none'

The OpenTelemetry Java agent enables all three signals (traces, metrics, and logs) by default. Since this guide focuses on traces, we disable metrics and logs to avoid sending unwanted data to SigNoz.

If you want to collect metrics or logs later, change the respective exporter to otlp or remove the variable entirely.

Verify these values:

  • <region>: Your SigNoz Cloud region.
  • <your-ingestion-key>: Your SigNoz ingestion key.
  • <service-name>: A descriptive name for your service (e.g., checkout-service).
  • <service-version> (optional): Your release version, image tag, or git SHA (e.g., 1.4.2, a01dbef8).

Set service.version to a per-build value, not a static string. SigNoz detects a deployment each time this value changes. Common sources:

  • Bash / shell: service.version=$(git rev-parse --short HEAD)
  • GitHub Actions: service.version=${{ github.sha }}
  • GitLab CI: service.version=$CI_COMMIT_SHORT_SHA
  • Kubernetes: inject from your Helm chart image tag or CI variable

The OpenTelemetry Operator auto-injects the Java agent into your pods without modifying your container image.

Step 1. Set up the OpenTelemetry Operator

Install the Operator and Collector following the K8s OTel Operator installation guide.

Step 2. Create the Instrumentation resource

Create instrumentation.yaml to configure Java auto-instrumentation:

instrumentation.yaml
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: scala-instrumentation
spec:
  exporter:
    endpoint: http://otel-collector-collector:4318
  propagators:
    - tracecontext
    - baggage
  env:
    - name: OTEL_EXPORTER_OTLP_PROTOCOL
      value: "http/protobuf"
    - name: OTEL_METRICS_EXPORTER
      value: "none"
    - name: OTEL_LOGS_EXPORTER
      value: "none"
  java:
    image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:latest

The OpenTelemetry Java agent enables all three signals (traces, metrics, and logs) by default. Since this guide focuses on traces, we disable metrics and logs to avoid sending unwanted data to your collector.

If you want to collect metrics or logs later, change the respective exporter to otlp or remove the variable entirely.

Deploy this resource to your cluster.

Step 3. Add annotations to your deployment

Add these annotations to your pod template's metadata.annotations:

deployment.yaml
instrumentation.opentelemetry.io/inject-java: 'true'
resource.opentelemetry.io/service.name: '<service-name>'
resource.opentelemetry.io/service.version: '<service-version>'

Verify these values:

  • <service-name>: A descriptive name for your service (e.g., checkout-service).
  • <service-version> (optional): Your release version, image tag, or git SHA (e.g., 1.4.2, a01dbef8).

Set service.version to a per-build value, not a static string. SigNoz detects a deployment each time this value changes. Common sources:

  • Bash / shell: service.version=$(git rev-parse --short HEAD)
  • GitHub Actions: service.version=${{ github.sha }}
  • GitLab CI: service.version=$CI_COMMIT_SHORT_SHA
  • Kubernetes: inject from your Helm chart image tag or CI variable

Step 1. Add the agent to your Dockerfile

Dockerfile
FROM eclipse-temurin:17-jre
WORKDIR /app

COPY target/scala-2.13/<my-app>-assembly.jar app.jar

RUN wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar -O opentelemetry-javaagent.jar

ENTRYPOINT ["java", "-javaagent:/app/opentelemetry-javaagent.jar", "-jar", "app.jar"]

Replace <my-app> with your assembled JAR name.

Step 2. Build and run

docker build -t my-scala-app .
docker run -p 8080:8080 \
  -e OTEL_RESOURCE_ATTRIBUTES="service.name=<service-name>,service.version=<service-version>" \
  -e OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.<region>.signoz.cloud:443" \
  -e OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=<your-ingestion-key>" \
  -e OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf" \
  -e OTEL_METRICS_EXPORTER="none" \
  -e OTEL_LOGS_EXPORTER="none" \
  my-scala-app

The agent enables traces, metrics, and logs by default. Setting both exporters to none avoids sending data you didn't ask for.

To collect metrics or logs later, set the exporter to otlp or remove the variable entirely.

Verify these values:

  • <region>: Your SigNoz Cloud region.
  • <your-ingestion-key>: Your SigNoz ingestion key.
  • <service-name>: A descriptive name for your service (e.g., checkout-service).
  • <service-version> (optional): Your release version, image tag, or git SHA (e.g., 1.4.2, a01dbef8).

Set service.version to a per-build value, not a static string. SigNoz detects a deployment each time this value changes. Common sources:

  • Bash / shell: service.version=$(git rev-parse --short HEAD)
  • GitHub Actions: service.version=${{ github.sha }}
  • GitLab CI: service.version=$CI_COMMIT_SHORT_SHA
  • Kubernetes: inject from your Helm chart image tag or CI variable

Step 1. Download the OpenTelemetry Java agent

Invoke-WebRequest -Uri "https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar" -OutFile "opentelemetry-javaagent.jar"

Step 2. Set environment variables

$env:OTEL_RESOURCE_ATTRIBUTES = "service.name=<service-name>,service.version=<service-version>"
$env:OTEL_EXPORTER_OTLP_ENDPOINT = "https://ingest.<region>.signoz.cloud:443"
$env:OTEL_EXPORTER_OTLP_HEADERS = "signoz-ingestion-key=<your-ingestion-key>"
$env:OTEL_EXPORTER_OTLP_PROTOCOL = "http/protobuf"
$env:OTEL_METRICS_EXPORTER = "none"
$env:OTEL_LOGS_EXPORTER = "none"

The OpenTelemetry Java agent enables all three signals (traces, metrics, and logs) by default. Since this guide focuses on traces, we disable metrics and logs to avoid sending unwanted data to SigNoz.

If you want to collect metrics or logs later, change the respective exporter to otlp or remove the variable entirely.

Verify these values:

  • <region>: Your SigNoz Cloud region.
  • <your-ingestion-key>: Your SigNoz ingestion key.
  • <service-name>: A descriptive name for your service (e.g., checkout-service).
  • <service-version> (optional): Your release version, image tag, or git SHA (e.g., 1.4.2, a01dbef8).

Set service.version to a per-build value, not a static string. SigNoz detects a deployment each time this value changes. Common sources:

  • Bash / shell: service.version=$(git rev-parse --short HEAD)
  • GitHub Actions: service.version=${{ github.sha }}
  • GitLab CI: service.version=$CI_COMMIT_SHORT_SHA
  • Kubernetes: inject from your Helm chart image tag or CI variable

Step 3. Run your application

SBT (recommended)

Add to your build.sbt:

build.sbt
fork := true
run / javaOptions += "-javaagent:C:\\path\\to\\opentelemetry-javaagent.jar"

Then run:

sbt run

Assembly or fat JAR

java -javaagent:.\opentelemetry-javaagent.jar -jar your-app-assembly.jar

Validate

With your application running, verify traces are flowing to SigNoz:

  1. Send a few requests to your application.
  2. In SigNoz, open the Services tab and click Refresh. Your service should appear.
  3. Go to the Traces tab to see your application's traces.

Troubleshooting

No traces in SigNoz after sbt run

The most common cause: SBT shares its JVM with your application by default, so the agent flag in javaOptions has no effect.

Fix: add fork := true to your build.sbt:

build.sbt
fork := true
run / javaOptions += "-javaagent:/path/to/opentelemetry-javaagent.jar"

Traces not showing up in SigNoz

Check environment variables:

echo $OTEL_EXPORTER_OTLP_ENDPOINT
echo $OTEL_RESOURCE_ATTRIBUTES

Enable debug logging:

OTEL_LOG_LEVEL=debug java -javaagent:./opentelemetry-javaagent.jar -jar app.jar

Look for span output in stdout. If spans appear locally but not in SigNoz, check your endpoint URL and ingestion key.

Test connectivity:

curl -v https://ingest.<region>.signoz.cloud:443/v1/traces

"Sharing is only supported for boot loader classes" warning

SBT prints this as [error] but it is harmless:

[error] OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended

The Java agent modifies the bootstrap classpath, which disables JVM class-data sharing (CDS). It does not affect instrumentation or trace collection.

Agent not attaching

Make sure -javaagent comes before -jar:

# Correct
java -javaagent:./agent.jar -jar app.jar

# Wrong — agent flag after -jar is ignored
java -jar app.jar -javaagent:./agent.jar

Setup OpenTelemetry Collector (Optional)

The Collector sits between your app and SigNoz. Your app sends traces to the Collector, which then forwards them to SigNoz. Use it to filter noisy spans, redact sensitive data, or fan out to multiple backends.

See Switch from direct export to Collector for setup instructions.

Next steps

  • Add manual instrumentation for custom spans and business context
  • Set up alerts on your Scala service

Get Help

If you need help with the steps in this topic, please reach out to us on SigNoz Community Slack.

If you are a SigNoz Cloud user, please use in product chat support located at the bottom right corner of your SigNoz instance or contact us at cloud-support@signoz.io.

Last updated: May 19, 2026

Edit on GitHub

Was this page helpful?

Your response helps us improve this page.

Prev
JBoss / WildFly
Next
Manual Instrumentation
On this page
Prerequisites
Auto-instrumented frameworks
Send traces to SigNoz
Step 1. Download the OpenTelemetry Java agent
Step 2. Set environment variables
Step 3. Run your application
Step 1. Add the agent to your Dockerfile
Step 2. Deploy to Kubernetes
Step 1. Set up the OpenTelemetry Operator
Step 2. Create the Instrumentation resource
Step 3. Add annotations to your deployment
Step 1. Add the agent to your Dockerfile
Step 2. Build and run
Step 1. Download the OpenTelemetry Java agent
Step 2. Set environment variables
Step 3. Run your application
Validate
Troubleshooting
No traces in SigNoz after `sbt run`
Traces not showing up in SigNoz
"Sharing is only supported for boot loader classes" warning
Agent not attaching
Setup OpenTelemetry Collector (Optional)
Next steps
Get Help

Is this page helpful?

Your response helps us improve this page.