> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mezmo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 6 - Create an OpenTelemetry Metric Handler Pipeline

> Build a responsive metric pipeline that aggregates metrics and limits tag cardinality, routing data by operational state.

<Note>
  If you run into any issues or have feedback on either the workshop or Pipeline, please reach out to us at [support@mezmo.com](mailto:support@mezmo.com).
</Note>

In this step you will create a responsive pipeline to handle the OpenTelemetry metrics data.

## Pipeline Architecture

This schematic shows the architecture of the Pipeline you will create in this stop. The numbers in the schematic correspond to the step in the build process.

<img src="https://mintcdn.com/mezmo-9a59581a/uS5U7z9j4833qA9M/images/guide-to-pipeline-architecture/vcwybagsiq6u93xd6v6nwabwsy0ipu3fuxy81wkpujksryzd5nhiolvx2mj1mml5.png?fit=max&auto=format&n=uS5U7z9j4833qA9M&q=85&s=eddf96094037ede0f49124708f28aabf" alt="" width="3342" height="622" data-path="images/guide-to-pipeline-architecture/vcwybagsiq6u93xd6v6nwabwsy0ipu3fuxy81wkpujksryzd5nhiolvx2mj1mml5.png" />

## 1 - Create the Pipeline and Add the Source

1. In the Mezmo Web app, click **New Pipeline** and name it `Metric Handler`.
2. In the Pipeline Map, click **Add Source**, then select the OpenTelemetry Metric source you created in Step 2.

## 2 - Add State Variables

A responsive pipeline changes its functioning based on detection of state changes. For this example, you will use the [Script Execution Processor](/telemetry-pipelines/js-script-processor) to add variables to the data that indicate the operational state of the pipeline.

1. Click the `...`menu in the upper-right corner of the OpenTelemetry Metric source.
2. Select **Add Node > Add Processor > Script Execution.**
3. Copy and paste this script into the **Script** field in the processor configuration panel, then click **Save**.

```javascript theme={null}
function processEvent(message, metadata, timestamp, annotations) {
  const state = getPipelineStateVariable("operational_state")
  message.op_state = state
  
  message.name = message.name.toString()
  message.tags.op_state = state

  metadata.resource.attributes["pipeline.path"] = "with_mezmo"

  if( message == null ){ return null }
  
  return message
}

```

## 3 - Route Data Based on State

You can now set the Pipeline to route data based `on operational_state` with the [Route Processor](/telemetry-pipelines/route-processor).

1. **In the Pipeline Map, click Add Processor.**
2. Select **Route Processor,** and for **Title**, enter `State Router`.
3. You will create three routes, one for the `Normal` state, one for the `Incident` state, and one for the `Deploy` state. After you configure the options for the `Normal` state, click **Add route** to configure the `Incident` and `Deploy` routes.

### Normal Route Configuration

| Configuration Option      | Setting                               |
| ------------------------- | ------------------------------------- |
| **Title**                 | `Normal`                              |
| **Conditional Statement** | `if message.op_state contains normal` |

### Incident State Configuration

| Configuration Option      | Setting                                 |
| ------------------------- | --------------------------------------- |
| **Title**                 | `Incident`                              |
| **Conditional Statement** | `if message.op_state contains incident` |

### Deploy State Configuration

| Configuration Option      | Setting                               |
| ------------------------- | ------------------------------------- |
| **Title**                 | `Deploy`                              |
| **Conditional Statement** | `if message.op_state contains deploy` |

## 4 - Create the Metric Data Optimization Processor Chain

In normal functioning, a common approach to reducing metric volume is to aggregate metrics and reduce tag cardinality. In this step, you will connect a Script Execution Processor, a [Tag Cardinality Limit Processor](/telemetry-pipelines/metrics-tag-cardinality-limit-processor), and an [Aggregate Processor](/telemetry-pipelines/aggregate-processor), in that order, to the normal and unmatched routes of the Route Processor.

### Script Execution Processor Configuration

1. In the Pipeline Map, add a Script Execution Processor to the Pipeline, and connect it to both the unmatched and normal routes.
2. Copy and paste this script into the processor configuration.

```javascript theme={null}
function processEvent(message, metadata, timestamp, annotations) {

  let service_name = message.tags.service_name
  let host_id = message.tags.host_id
  
  if( service_name == null ){
    service_name = metadata.resource.attributes['service.name']
  }
  if( service_name == null ){ service_name = 'NA' }
  if( host_id == null ){
    host_id = metadata.resource.attributes['host.id']
  }
  if( host_id == null ){ host_id = 'NA' }

  message.tags = {
    'service_name': service_name,
    'host_id': host_id
  }
  
  return message
}

```

### Tag Cardinality Limit Processor Configuration

This configuration will limit the number of tags for the `host_id field` to 10.

1. In the Pipeline Map, add a Tag Cardinality Limit Processor and connect it to the Script Execution Processor.
2. Enter these configuration options for the processor.

| Configuration Option | Setting                |
| -------------------- | ---------------------- |
| **Tags**             | `message.tags.host_id` |
| **Action**           | `drop_tag`             |
| **Value Limit**      | `10`                   |
| **Mode**             | `Probablistic`         |

### Aggregate Processor Configuration

This configuration will aggregate metrics based on a five minute interval.

1. In the Pipeline Map, add an Aggregate Processor and connect it to the Tag Cardinality LImit Processor.
2. Keep the default configuration settings, but set **Interval (seconds)** to `300`.

## 5 - Add the Blackhole Destination

You can send your optimized data to any of Mezmo's [Supported Telemetry Data Destinations](/telemetry-pipelines/supported-telemetry-data-destinations), but in this case, the route will terminate in a [Blackhole](/telemetry-pipelines/blackhole-destination) destination that drops all data sent to it. This is useful for testing the data processing of your Pipeline before sending it to production destination.

1. In the Pipeline Map, click **Add Destination**.
2. Select **Blackhole**, and connect it to the to outgoing routes of the Route Processor as shown in the pipeline architecture schematic.

## Deploy the Pipeline

To activate the Pipeline, click **Deploy**.

## Initialize State and Get State ID

As you did with the Log Handler Pipeline, you need to initialize the state of the Pipeline and get the `State ID` of the pipeline for reference in Step 8.

1. In the Pipeline Map, click on the **State** setting in the upper-left corner, and change it to `Incident`.
2. Change the **State** setting back to `Normal`. This will initialize the Normal state, and generate the`Pipeline_ID` for the pipeline `state-variable`.
3. In a terminal, run this command with the

First, flip the State in the UX from Normal to Incident and back to Normal to initialize.

Then, in your terminal run the following command with the metric `pipeline's ID` and grab that `State ID`.

```bash theme={null}
curl --request GET \
 --url 'https://api.mezmo.com/v3/pipeline/state-variable?pipeline_id=PIPELINE_ID' \
 --header 'Authorization: Token PIPELINE_API_KEY'

```
