---
title: Getting Started with APM Tracing
description: >-
  Set up Application Performance Monitoring (APM) to identify bottlenecks,
  troubleshoot issues, and send traces to Datadog.
breadcrumbs: Docs > Getting Started > Getting Started with APM Tracing
---

# Getting Started with APM Tracing

## Overview{% #overview %}

Datadog Application Performance Monitoring (APM) provides deep visibility into your applications, enabling you to identify performance bottlenecks, troubleshoot issues, and optimize your services.

This guide demonstrates how to get started with APM and send your first trace to Datadog:

1. Set up Datadog APM to send traces to Datadog.
1. Run your application to generate data.
1. Explore the collected data in Datadog.

## Prerequisites{% #prerequisites %}

To complete this guide, you need the following:

1. [Create a Datadog account](https://www.datadoghq.com/free-datadog-trial/) if you haven't already.
1. Find or create a [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys/).
1. Start up a Linux host or VM.

## Create an application{% #create-an-application %}

To create an application to observe in Datadog:

1. On your Linux host or VM, create a new Python application named `hello.py`. For example, `nano hello.py`.

1. Add the following code to `hello.py`:

In the `hello.py` file:

   ```python
     from flask import Flask
     import random
   
     app = Flask(__name__)
     
     quotes = [
         "Strive not to be a success, but rather to be of value. - Albert Einstein",
         "Believe you can and you're halfway there. - Theodore Roosevelt",
         "The future belongs to those who believe in the beauty of their dreams. - Eleanor Roosevelt"
     ]
     
     @app.route('/')
     def index():
         quote = random.choice(quotes)+"\n"
         return quote
     
     if __name__ == '__main__':
         app.run(host='0.0.0.0', port=5050)
     
```

## Set up Datadog APM{% #set-up-datadog-apm %}

To set up Datadog APM without needing to modify your application's code or the deployment process, use Single Step APM Instrumentation, or alternatively, you can set up APM using [Datadog tracing](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/) libraries.

1. Run the installation command:

   ```shell
    DD_API_KEY=<YOUR_DD_API_KEY> DD_SITE="<YOUR_DD_SITE>" DD_APM_INSTRUMENTATION_ENABLED=host DD_APM_INSTRUMENTATION_LIBRARIES=python:4 DD_ENV=<AGENT_ENV> bash -c "$(curl -L https://install.datadoghq.com/scripts/install_script_agent7.sh)"
   ```

Replace `<YOUR_DD_API_KEY>` with your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys/), `<YOUR_DD_SITE>` with your [Datadog site](https://docs.datadoghq.com/getting_started/site/), and `<AGENT_ENV>` with the environment your Agent is installed on (for example, `development`).

1. Restart the services on your host or VM.

1. Verify the Agent is running:

   ```shell
   sudo datadog-agent status
   ```

This approach automatically installs the Datadog Agent, enables Datadog APM, and [instruments](https://docs.datadoghq.com/tracing/glossary/#instrumentation) your application at runtime.

## Run the application{% #run-the-application %}

When you set up Datadog APM with Single Step Instrumentation, Datadog automatically instruments your application at runtime.

To run `hello.py`:

1. Create a Python virtual environment in the current directory:

   ```shell
   python3 -m venv ./venv
   ```

1. Activate the `venv` virtual environment:

   ```shell
   source ./venv/bin/activate
   ```

1. Install `pip` and `flask`:

   ```shell
   sudo apt-get install python3-pip
   pip install flask
   ```

1. Set the service name and run `hello.py`:

   ```shell
   export DD_SERVICE=hello
   python3 hello.py
   ```

## Test the application{% #test-the-application %}

Test the application to send traces to Datadog:

1. In a new command prompt, run the following:

   ```shell
   curl http://0.0.0.0:5050/
   ```

1. Confirm that a random quote is returned.

   ```text
   Believe you can and you're halfway there. - Theodore Roosevelt
   ```

Each time you run the `curl` command, a new trace is sent to Datadog.

## Explore traces in Datadog{% #explore-traces-in-datadog %}

1. In Datadog, go to [**APM** > **Services**](https://app.datadoghq.com/services). You should see a Python service named `hello`:

   {% image
      source="https://datadog-docs.imgix.net/images/getting_started/apm/service-catalog.4dc8fb71fb6660c11877221587bc4324.png?auto=format"
      alt="Software Catalog shows the new Python service." /%}

1. Select the service to view its performance metrics, such as latency, throughput, and error rates.

1. Go to [**APM** > **Traces**](https://app.datadoghq.com/apm/traces). You should see a trace for the `hello` service:

   {% image
      source="https://datadog-docs.imgix.net/images/getting_started/apm/trace-explorer.9041969b75ee34dd3478b88e4dd2b72c.png?auto=format"
      alt="Trace explorer shows the trace for the hello service." /%}

1. Select a trace to see its details, including the flame graph, which helps identify performance bottlenecks.

## Advanced APM setup{% #advanced-apm-setup %}

Up until this point, you let Datadog automatically instrument the `hello.py` application using Single Step Instrumentation. This approach is recommended if you want to capture essential traces across common libraries and languages without touching code or manually installing libraries.

However, if you need to collect traces from custom code or require more fine-grained control, you can add [custom instrumentation](https://docs.datadoghq.com/tracing/trace_collection/custom_instrumentation/).

To illustrate this, you will import the Datadog Python tracing library into `hello.py` and create a custom span and span tag.

To add custom instrumentation:

1. Install the Datadog tracing library:

   ```shell
   pip install ddtrace
   ```

1. Add the highlighted lines to the code in `hello.py` to create a custom span tag `get_quote` and a custom span tag `quote`:

   ```python
    from flask import Flask
    import random
    from ddtrace import tracer
   
    app = Flask(__name__)
   
    quotes = [
        "Strive not to be a success, but rather to be of value. - Albert Einstein",
        "Believe you can and you're halfway there. - Theodore Roosevelt",
        "The future belongs to those who believe in the beauty of their dreams. - Eleanor Roosevelt"
    ]
   
    @app.route('/')
    def index():
        with tracer.trace("get_quote") as span:
            quote = random.choice(quotes)+"\n"
            span.set_tag("quote", quote)
            return quote
   
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=5050)
```

1. Run `hello.py` in the virtual environment from earlier:

   ```shell
   ddtrace-run python hello.py
   ```

1. Run a few `curl` commands in a separate command prompt:

   ```shell
   curl http://0.0.0.0:5050/
   ```

1. In Datadog, go to [**APM** > **Traces**](https://app.datadoghq.com/apm/traces).

1. Select the **hello** trace.

1. Find the new custom `get_quote` span in the flame graph and hover over it:

   {% image
      source="https://datadog-docs.imgix.net/images/getting_started/apm/custom-instrumentation.60549f45067927cb330b8e3af9b05097.png?auto=format"
      alt="The get_quote custom span displays in the flame graph. On hover, the quote span tag is displayed. " /%}

1. Notice that the custom `quote` span tag displays on the **Info** tab.

## What's next?{% #whats-next %}

After you set up tracing and your application is sending data to Datadog, explore additional APM features:

### Software Catalog{% #software-catalog %}

[Software Catalog](https://docs.datadoghq.com/internal_developer_portal/software_catalog/) provides a consolidated view of your services, combining ownership metadata, performance insights, security analysis, and cost allocation in one place. Configure [service metadata](https://docs.datadoghq.com/internal_developer_portal/software_catalog/entity_model/) using tags, annotations, or a `service.datadog.yaml` file to enrich your services with ownership information, runbooks, and documentation links.

### Trace ingestion and retention{% #trace-ingestion-and-retention %}

Control costs and manage data volume by configuring [ingestion controls](https://docs.datadoghq.com/tracing/trace_pipeline/ingestion_controls/) and [retention filters](https://docs.datadoghq.com/tracing/trace_pipeline/trace_retention/). Ingestion controls let you customize sampling rates at the Datadog Agent or tracing library level, while retention filters determine which spans are indexed for search and analytics.

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

- [Learn more about APM features](https://docs.datadoghq.com/tracing/)
- [Enable runtime metrics](https://docs.datadoghq.com/tracing/metrics/runtime_metrics/)
- [Tutorials for various ways to enable tracing](https://docs.datadoghq.com/tracing/guide/#enabling-tracing-tutorials)
- [Introduction to Application Performance Monitoring](https://learn.datadoghq.com/courses/intro-to-apm)
- [Join an interactive session to boost your APM understanding](https://dtdg.co/fe)
