Custom Tagging

Custom tags allow you to attach metadata to captured connections based on process environment variables, container labels, or Kubernetes labels and annotations. This is especially useful for:

  • Multi-tenant environments: Tag traffic by team, customer, or tenant

  • Environment identification: Distinguish between production, staging, and development traffic

  • Cost allocation: Track usage by department, project, or business unit

  • Service organization: Identify traffic by service name, version, or component

  • Qplane filtering: Filter and organize captured traffic in the Qplane UI by custom dimensions

Custom tags appear in the tags object of Connection events (event store) alongside default tags like bin, host, ip, protocol, and strategy. Tags are connection-level metadata and do not appear in HTTP transaction objects (object store).

Configuration

Custom tags are defined in the tags section of your qtap configuration:

tags:
  - key: team
    source: env
    location: TEAM
  - key: service
    source: container.label
    location: service
  - key: environment
    source: k8s.label
    location: env

Field Reference

Field
Type
Required
Description

key

string

Yes

The name of the tag as it will appear in the tags object

source

string

Yes

Where to extract the tag value from (see Tag Sources)

location

string

Yes

The specific environment variable name, label key, or annotation key to extract

Tag Sources

Qtap supports extracting tag values from multiple sources:

Source
Description
Example

env

Environment variable from the monitored process

source: env location: APP_NAME

container.label

Docker container label

source: container.label location: service

k8s.label

Kubernetes pod label

source: k8s.label location: team

k8s.annotation

Kubernetes pod annotation

source: k8s.annotation location: version

Examples

Environment Variables

Extract tags from environment variables set on your applications:

version: 2

services:
  event_stores:
    - type: stdout

tags:
  - key: team
    source: env
    location: TEAM
  - key: app
    source: env
    location: APP_NAME
  - key: environment
    source: env
    location: ENVIRONMENT

stacks:
  default_stack:
    plugins:
      - type: http_capture
        config:
          level: summary
          format: json

tap:
  direction: egress
  ignore_loopback: true
  http:
    stack: default_stack

When you run your application with environment variables:

TEAM=platform APP_NAME=api-gateway ENVIRONMENT=production python ./app.py

The captured connections will include:

{
  "tags": {
    "app": ["api-gateway"],
    "bin": ["python"],
    "environment": ["production"],
    "host": ["qpoint"],
    "ip": ["192.168.1.100"],
    "protocol": ["http2"],
    "strategy": ["observe"],
    "team": ["platform"]
  }
}

Container Labels

Extract tags from Docker container labels:

tags:
  - key: service
    source: container.label
    location: service
  - key: version
    source: container.label
    location: version

Run containers with labels:

docker run --label service=web-frontend --label version=v2.1.0 myapp:latest

Tags in captured connections:

{
  "tags": {
    "service": ["web-frontend"],
    "version": ["v2.1.0"],
    "bin": ["node"],
    "host": ["qpoint"]
  }
}

Kubernetes Labels

Extract tags from Kubernetes pod labels:

tags:
  - key: team
    source: k8s.label
    location: team
  - key: app
    source: k8s.label
    location: app

Pod manifest with labels:

apiVersion: v1
kind: Pod
metadata:
  name: api-server
  labels:
    app: api-server
    team: backend
spec:
  containers:
    - name: api
      image: myapp:latest

Tags in captured connections:

{
  "tags": {
    "app": ["api-server"],
    "team": ["backend"],
    "bin": ["node"],
    "host": ["k8s-node-01"]
  }
}

Kubernetes Annotations

Extract tags from Kubernetes pod annotations:

tags:
  - key: version
    source: k8s.annotation
    location: app.version
  - key: owner
    source: k8s.annotation
    location: owner

Pod manifest with annotations:

apiVersion: v1
kind: Pod
metadata:
  name: api-server
  annotations:
    app.version: "2.1.0"
    owner: "platform-team"
spec:
  containers:
    - name: api
      image: myapp:latest

Combining Tag Sources

You can combine tags from multiple sources:

tags:
  # From environment variables
  - key: environment
    source: env
    location: ENVIRONMENT

  # From container labels
  - key: service
    source: container.label
    location: service

  # From Kubernetes labels
  - key: team
    source: k8s.label
    location: team

  # From Kubernetes annotations
  - key: version
    source: k8s.annotation
    location: version

All tags from different sources are merged together in the Connection event.

Static Tags (CLI Flag)

In addition to dynamic tags extracted from the YAML configuration, you can add static tags to all connections using the --tags CLI flag:

qtap --config=/path/to/qtap.yaml \
  --tags='region:us-west,deployment:production,cluster:main'

Format: The --tags flag uses key:value pairs separated by commas (not key=value).

Static tags are useful for:

  • Identifying the qtap instance or node

  • Tagging by region, datacenter, or availability zone

  • Marking deployment environment at the infrastructure level

Static tags and dynamic tags (from YAML) are merged together:

{
  "tags": {
    "app": ["api-gateway"],          // from env var (YAML)
    "team": ["platform"],             // from env var (YAML)
    "region": ["us-west"],            // from CLI --tags
    "deployment": ["production"],     // from CLI --tags
    "cluster": ["main"],              // from CLI --tags
    "bin": ["python"],                // default
    "host": ["qpoint"],               // default
    "protocol": ["http2"],            // default
    "strategy": ["observe"]           // default
  }
}

Tag Behavior

Missing Values

If a tag's source value doesn't exist, the tag is simply omitted from the output (no errors are logged):

tags:
  - key: team
    source: env
    location: TEAM  # If TEAM env var not set, tag won't appear

If the TEAM environment variable is not set on the process, the team tag won't appear in the Connection event.

Tag Merging

When the same tag key is defined in multiple sources, all values are merged into an array:

Example with environment variable and CLI flag:

tags:
  - key: team
    source: env
    location: TEAM
TEAM=platform-yaml ./my-app
qtap --tags='team:platform-cli' ...

Result:

{
  "tags": {
    "team": ["platform-yaml", "platform-cli"]
  }
}

This applies to all tag sources:

  • YAML-defined tags (env, container.label, k8s.label, k8s.annotation)

  • CLI --tags flag

  • Default qtap tags (bin, host, ip, protocol, strategy)

Even default tags can be extended:

qtap --tags='bin:my-custom-bin,host:my-custom-host' ...

Result:

{
  "tags": {
    "bin": ["curl", "my-custom-bin"],
    "host": ["qpoint", "my-custom-host"]
  }
}

All tag values from all sources are preserved in the array.

Use Cases

Multi-Tenant SaaS Platform

Tag traffic by tenant and tier for cost allocation:

tags:
  - key: tenant_id
    source: env
    location: TENANT_ID
  - key: tier
    source: env
    location: SERVICE_TIER

Run application:

TENANT_ID=customer-123 SERVICE_TIER=premium python ./app.py

Microservices Environment

Identify traffic by service, version, and team:

tags:
  - key: service
    source: k8s.label
    location: app
  - key: version
    source: k8s.annotation
    location: version
  - key: team
    source: k8s.label
    location: team

Cost Tracking by Department

Tag traffic for cost allocation across departments:

tags:
  - key: department
    source: env
    location: DEPARTMENT
  - key: cost_center
    source: env
    location: COST_CENTER
  - key: project
    source: env
    location: PROJECT_ID

Run application:

DEPARTMENT=engineering COST_CENTER=R001 PROJECT_ID=api-v2 ./my-app

Environment-Specific Tagging

Distinguish between production, staging, and development:

tags:
  - key: environment
    source: env
    location: ENV
  - key: region
    source: env
    location: AWS_REGION

Run in production:

ENV=production AWS_REGION=us-west-2 ./my-app

Run in staging:

ENV=staging AWS_REGION=us-east-1 ./my-app

Viewing Tags in Qplane

When qtap is connected to Qplane, custom tags appear in the Qplane UI and can be used for:

  • Filtering connections: Filter by team, environment, service, etc.

  • Grouping traffic: Group connections by custom dimensions

  • Creating dashboards: Visualize traffic patterns by custom tags

  • Setting alerts: Alert on traffic patterns for specific tags

Custom tags make it easy to organize and filter large volumes of captured traffic across multiple teams, services, and environments.

Best Practices

Security Considerations

# AVOID - these could contain sensitive data
tags:
  - key: api_key
    source: env
    location: API_KEY        # ❌ Never tag secrets

  - key: user_email
    source: env
    location: USER_EMAIL     # ❌ Avoid PII

# Good - safe metadata
tags:
  - key: service
    source: env
    location: SERVICE_NAME   # ✅ Safe

  - key: team
    source: env
    location: TEAM           # ✅ Safe

Use Static Tags for Infrastructure

Use the --tags CLI flag for infrastructure-level tags that don't change per process:

# Tag by region and cluster
qtap --tags='region:us-west-2,cluster:production,zone:a'

# Tag by datacenter and rack
qtap --tags='datacenter:dc1,rack:r42'

Use YAML tags for application-level tags that vary per process:

# Tag by application attributes
tags:
  - key: service
    source: env
    location: SERVICE_NAME
  - key: version
    source: env
    location: APP_VERSION

Complete Example

Here's a complete configuration combining multiple tag sources:

version: 2

services:
  event_stores:
    - type: s3
      config:
        bucket: my-qtap-events
        region: us-west-2
  object_stores:
    - type: s3
      config:
        bucket: my-qtap-objects
        region: us-west-2

tags:
  # Application-level tags from environment
  - key: service
    source: env
    location: SERVICE_NAME
  - key: version
    source: env
    location: APP_VERSION
  - key: environment
    source: env
    location: ENVIRONMENT

  # Team ownership from Kubernetes
  - key: team
    source: k8s.label
    location: team
  - key: cost_center
    source: k8s.annotation
    location: cost-center

stacks:
  default_stack:
    plugins:
      - type: http_capture
        config:
          level: summary
          format: json

tap:
  direction: egress
  ignore_loopback: true
  audit_include_dns: false
  http:
    stack: default_stack

Start qtap with static infrastructure tags:

qtap --config=/etc/qtap/config.yaml \
  --tags='region:us-west-2,cluster:production'

Run your application with environment variables:

SERVICE_NAME=api-gateway \
APP_VERSION=2.1.0 \
ENVIRONMENT=production \
python ./app.py

The resulting Connection events will include all tags:

{
  "meta": {
    "connectionId": "conn-123",
    "endpointId": "api.example.com"
  },
  "tags": {
    "service": ["api-gateway"],
    "version": ["2.1.0"],
    "environment": ["production"],
    "team": ["platform"],
    "cost_center": ["engineering-001"],
    "region": ["us-west-2"],
    "cluster": ["production"],
    "bin": ["python"],
    "host": ["k8s-node-01"],
    "ip": ["10.0.1.50"],
    "protocol": ["http2"],
    "strategy": ["observe"]
  },
  "timestamp": "2025-11-03T18:30:00Z",
  "direction": "egress-external",
  "source": {
    "exe": "/usr/bin/python3",
    "address": {
      "ip": "10.0.1.50",
      "port": 45678
    }
  },
  "destination": {
    "address": {
      "ip": "52.1.2.3",
      "port": 443
    }
  }
}

Last updated