---
title: 'Data Observability: Jobs Monitoring for Spark on Kubernetes'
description: >-
  Set up Data Observability: Jobs Monitoring for Apache Spark applications on
  Kubernetes clusters using the Datadog Agent and Single Step Instrumentation.
breadcrumbs: >-
  Docs > Data Observability Overview > Data Observability: Jobs Monitoring >
  Data Observability: Jobs Monitoring for Spark on Kubernetes
---

# Data Observability: Jobs Monitoring for Spark on Kubernetes

{% callout %}
# Important note for users on the following Datadog sites: app.ddog-gov.com, us2.ddog-gov.com

{% alert level="danger" %}
This product is not supported for your selected [Datadog site](https://docs.datadoghq.com/getting_started/site.md). ({% placeholder "user-datadog-site-name" /%}).
{% /alert %}

{% /callout %}

[Data Observability: Jobs Monitoring](https://docs.datadoghq.com/data_jobs.md) gives visibility into the performance and reliability of Apache Spark applications on Kubernetes.

## Setup{% #setup %}

{% alert level="info" %}
Data Observability: Jobs Monitoring requires Datadog Agent version 7.64.0 or later, and Java tracer version 1.38.0 or later.
{% /alert %}

Follow these steps to enable Data Observability: Jobs Monitoring for Spark on Kubernetes.

1. Install the Datadog Agent on your Kubernetes cluster.
1. Enable Single Step Instrumentation.

### Install the Datadog Agent on your Kubernetes cluster{% #install-the-datadog-agent-on-your-kubernetes-cluster %}

If you have already [installed the Datadog Agent on your Kubernetes cluster](https://docs.datadoghq.com/containers/kubernetes/installation.md?tab=operator), make sure you've enabled the [Datadog Admission Controller](https://docs.datadoghq.com/containers/cluster_agent/admission_controller.md?tab=operator). You can then go to the next step, Enable Single Step Instrumentation.

You can install the Datadog Agent using the [Datadog Operator](https://docs.datadoghq.com/containers/datadog_operator.md) or [Helm](https://helm.sh).

{% tab title="Datadog Operator" %}
### Prerequisites{% #prerequisites %}

- Kubernetes cluster version v1.20.X+
- [`Helm`](https://helm.sh)
- The [`kubectl` CLI](https://kubernetes.io/docs/tasks/tools/install-kubectl/)

### Installation{% #installation %}

1. Install the Datadog Operator by running the following commands:

   ```shell
   helm repo add datadog https://helm.datadoghq.com
   helm install my-datadog-operator datadog/datadog-operator
   ```

1. Create a [Kubernetes Secret](https://kubernetes.io/docs/concepts/configuration/secret/) to store your Datadog API key.

   ```shell
   kubectl create secret generic datadog-secret --from-literal api-key=<DATADOG_API_KEY>
   ```

Replace `<DATADOG_API_KEY>` with your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys).

1. Create a file, `datadog-agent.yaml`, that contains the following configuration:

   ```yaml
   kind: DatadogAgent
   apiVersion: datadoghq.com/v2alpha1
   metadata:
     name: datadog
   spec:
     features:
       apm:
         enabled: true
         hostPortConfig:
           enabled: true
           hostPort: 8126
       admissionController:
         enabled: true
         mutateUnlabelled: false
       # (Optional) Uncomment the next three lines to enable logs collection
       # logCollection:
         # enabled: true
         # containerCollectAll: true
     global:
       site: <DATADOG_SITE>
       credentials:
         apiSecret:
           secretName: datadog-secret
           keyName: api-key
     override:
       nodeAgent:
         image:
           tag: <DATADOG_AGENT_VERSION>
   ```

Replace `<DATADOG_SITE>` with your [Datadog site](https://docs.datadoghq.com/getting_started/site.md). Your site is <YOUR_DATADOG_SITE>. (Ensure the correct SITE is selected on the right).

Replace `<DATADOG_AGENT_VERSION>` with version `7.64.0` or later.

**Optional**: Uncomment the `logCollection` section to start collecting application logs which will be correlated to Spark job run traces. Once enabled, logs are collected from all discovered containers by default. See the [Kubernetes log collection documentation](https://docs.datadoghq.com/containers/kubernetes/log.md?tab=datadogoperator#log-collection) for more details on the setup process.

1. Deploy the Datadog Agent with the above configuration file:

   ```shell
   kubectl apply -f /path/to/your/datadog-agent.yaml
   ```

{% /tab %}

{% tab title="Helm" %}

1. Create a [Kubernetes Secret](https://kubernetes.io/docs/concepts/configuration/secret/) to store your Datadog API key.

   ```shell
   kubectl create secret generic datadog-secret --from-literal api-key=<DATADOG_API_KEY>
   ```

Replace `<DATADOG_API_KEY>` with your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys).

1. Create a file, `datadog-values.yaml`, that contains the following configuration:

   ```yaml
   datadog:
     apiKeyExistingSecret: datadog-secret
     site: <DATADOG_SITE>
     apm:
       portEnabled: true
       port: 8126
     # (Optional) Uncomment the next three lines to enable logs collection
     # logs:
       # enabled: true
       # containerCollectAll: true
   
   agents:
     image:
       tag: <DATADOG_AGENT_VERSION>
   
   clusterAgent:
     admissionController:
       enabled: true
       muteUnlabelled: false
   ```

Replace `<DATADOG_SITE>` with your [Datadog site](https://docs.datadoghq.com/getting_started/site.md). Your site is <YOUR_DATADOG_SITE>. (Ensure the correct SITE is selected on the right).

Replace `<DATADOG_AGENT_VERSION>` with version `7.64.0` or later.

**Optional**: Uncomment the logs section to start collecting application logs which will be correlated to Spark job run traces. Once enabled, logs are collected from all discovered containers by default. See the [Kubernetes log collection documentation](https://docs.datadoghq.com/containers/kubernetes/log.md?tab=helm#log-collection) for more details on the setup process.

1. Run the following command:

   ```shell
   helm install <RELEASE_NAME> \
    -f datadog-values.yaml \
    --set targetSystem=<TARGET_SYSTEM> \
    datadog/datadog
   ```

   - Replace `<RELEASE_NAME>` with your release name. For example, `datadog-agent`.

   - Replace `<TARGET_SYSTEM>` with the name of your OS. For example, `linux` or `windows`.

{% /tab %}

### Enable Single Step Instrumentation{% #enable-single-step-instrumentation %}

Single Step Instrumentation (SSI) injects the Java tracer into your Spark driver and executor pods at startup. It works regardless of whether your Spark driver runs in **cluster mode** (as a dedicated Kubernetes pod) or **client mode** (as a process inside your submitter pod; for example, an Airflow scheduler or worker).

Spark automatically sets `spark-role: driver` on driver pods and `spark-role: executor` on executor pods. In client mode, replace `spark-role: driver` with the labels that identify your submitter pod instead. To find those labels, run:

```shell
kubectl get pod <SUBMITTER_POD_NAME> -n <NAMESPACE> --show-labels
```

{% tab title="Datadog Operator" %}
Requires [Datadog Operator](https://github.com/DataDog/datadog-operator/releases) version 1.13.0 or later.

Add the `features.apm.instrumentation` section to your `datadog-agent.yaml` and apply it:

```yaml
features:
  apm:
    instrumentation:
      enabled: true
      enabledNamespaces:
        - <NAMESPACE>  # namespace where your Spark jobs run
      targets:
        - name: spark-driver
          podSelector:
            matchLabels:
              spark-role: driver   # replace with your submitter pod labels if running in client mode
          ddTraceVersions:
            java: "latest"
          ddTraceConfigs:
            - name: DD_DATA_JOBS_ENABLED
              value: "true"
        - name: spark-executor
          podSelector:
            matchLabels:
              spark-role: executor
          ddTraceVersions:
            java: "latest"
          ddTraceConfigs:
            - name: DD_DATA_JOBS_ENABLED
              value: "true"
```

```shell
kubectl apply -f /path/to/your/datadog-agent.yaml
```

{% /tab %}

{% tab title="Helm" %}
Add the following to your `datadog-values.yaml` and apply it:

```yaml
datadog:
  apm:
    instrumentation:
      enabled: true
      enabledNamespaces:
        - <NAMESPACE>  # namespace where your Spark jobs run
      targets:
        - name: spark-driver
          podSelector:
            matchLabels:
              spark-role: driver   # replace with your submitter pod labels if running in client mode
          ddTraceVersions:
            java: "latest"
          ddTraceConfigs:
            - name: DD_DATA_JOBS_ENABLED
              value: "true"
        - name: spark-executor
          podSelector:
            matchLabels:
              spark-role: executor
          ddTraceVersions:
            java: "latest"
          ddTraceConfigs:
            - name: DD_DATA_JOBS_ENABLED
              value: "true"
```

```shell
helm upgrade <RELEASE_NAME> datadog/datadog -f datadog-values.yaml
```

{% /tab %}

After applying the configuration, restart the targeted pods. SSI injects the init container into each pod on startup.

## Validation{% #validation %}

In Datadog, view the [Data Observability: Jobs Monitoring](https://app.datadoghq.com/data-jobs/) page to see a list of all your data processing jobs.

## Advanced Configuration{% #advanced-configuration %}

### Set service, environment, and version tags{% #set-service-environment-and-version-tags %}

To attach service, environment, and version tags to your job traces, pass the following JVM options in your spark-submit configuration or `spark-defaults.conf`:

```
spark.driver.extraJavaOptions=-Ddd.service=<JOB_NAME> -Ddd.env=<ENV> -Ddd.version=<VERSION>
spark.executor.extraJavaOptions=-Ddd.service=<JOB_NAME> -Ddd.env=<ENV> -Ddd.version=<VERSION>
```

### Tag spans at runtime{% #tag-spans-at-runtime %}

You can set tags on Spark spans at runtime. These tags are applied *only* to spans that start after the tag is added.

```scala
// Add tag for all next Spark computations
sparkContext.setLocalProperty("spark.datadog.tags.key", "value")
spark.read.parquet(...)
```

To remove a runtime tag:

```scala
// Remove tag for all next Spark computations
sparkContext.setLocalProperty("spark.datadog.tags.key", null)
```

## Further Reading{% #further-reading %}

- [Data Observability: Jobs Monitoring](https://docs.datadoghq.com/data_jobs.md)
