> For the complete documentation index, see llms.txt.
Skip to main content

Check out Port for yourself ➜ 

Datadog

Loading version...

Port's Datadog integration allows you to model Datadog resources in Port and ingest data into them.

SLO History, Service Metric and Service Dependency resources are not collected out of the box.
Follow the examples here to configure blueprints and resource mappings.

Setup

Choose your preferred installation method below. Not sure which to pick? See the installation methods overview.

Configuration

Port integrations use a YAML mapping block to ingest data from the third-party api into Port.

The mapping makes use of the JQ JSON processor to select, modify, concatenate, transform and perform other operations on existing fields and values from the integration API.

Default mapping configuration

This is the default mapping configuration for this integration:

Default mapping configuration (click to expand)
deleteDependentEntities: true
createMissingRelatedEntities: true
enableMergeEntity: true
resources:
- kind: monitor
selector:
query: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .name
blueprint: '"datadogMonitor"'
properties:
tags: .tags
monitorType: .type
overallState: .overall_state
thresholds: .thresholds
priority: .priority
createdBy: .creator.email
createdAt: .created
updatedAt: .modified
link: (\"https://app.datadoghq.com/monitors/\" + (.id | tostring))
relations:
owner_team_datadog: .tags | map(select(startswith("team:"))) | unique | map(split(":")[1])
service_datadog: .tags | map(select(startswith("service:"))) | unique | map(split(":")[1])
service:
combinator: '"and"'
rules:
- property: '"datadog_service_id"'
operator: '"in"'
value: .tags | map(select(startswith("service:"))) | unique | map(split(":")[1])
- kind: service
selector:
query: "true"
port:
entity:
mappings:
identifier: .attributes.schema.\"dd-service\"
title: .attributes.schema.\"dd-service\"
blueprint: '"datadogService"'
properties:
application: .attributes.schema.application
languages: .attributes.schema.languages
description: .attributes.schema.description
tags: .attributes.schema.tags
type: .attributes.schema.type
links: (\"https://app.datadoghq.com/services?selectedService=\" + (.attributes.schema.\"dd-service\"))
owners: '[.attributes.schema.contacts[]? | select(.type == "email") | .contact]'
relations:
owner_team_datadog: .team_it_doesnt_work_yet
- kind: slo
selector:
query: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .name
blueprint: '"datadogSlo"'
properties:
tags: .tags
sloType: .type
description: .description
warningThreshold: .warning_threshold
targetThreshold: .target_threshold
createdBy: .creator.email
createdAt: .created_at | todate
updatedAt: .modified_at | todate
link: (\"https://app.datadoghq.com/slo/manage?sp=\" + (\"%5B%7B%22p%22%3A%7B%22id%22%3A%22\" + (.id | tostring) + \"%22%7D%2C%22i%22%3A%22slo-panel%22%7D%5D\"))
relations:
monitors: .monitor_ids | map(tostring)
owner_team_datadog: .monitor_tags + .tags | map(select(startswith("team:"))) | unique | map(split(":")[1])
service_datadog: .monitor_tags + .tags | map(select(startswith("service:"))) | unique | map(split(":")[1])
service:
combinator: '"and"'
rules:
- property: '"datadog_service_id"'
operator: '"in"'
value: .monitor_tags + .tags | map(select(startswith("service:"))) | unique | map(split(":")[1])
- kind: host
selector:
query: '[.sources[] | . as $source | ["azure", "gcp", "gce", "aws"] | contains([$source])] | any(.)'
port:
entity:
mappings:
identifier: .id | tostring
title: .aws_name // .host_name
blueprint: '"datadogCloudResource"'
properties:
up: .up
host_name: .host_name
platform: .meta.platform
is_muted: .is_muted
machine: .meta.machine
description: .description
sources: .sources
cpu_cores: .meta.cpuCores
agent_version: .meta.agent_version
tags: .tags_by_source
- kind: host
selector:
query: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .aws_name // .host_name
blueprint: '"datadogHost"'
properties:
up: .up
host_name: .host_name
platform: .meta.platform
is_muted: .is_muted
machine: .meta.machine
description: .description
sources: .sources
cpu_cores: .meta.cpuCores
agent_version: .meta.agent_version
tags: .tags_by_source
- kind: user
selector:
query: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .attributes.name
blueprint: '"datadogUser"'
properties:
email: .attributes.email
handle: .attributes.handle
status: .attributes.status
disabled: .attributes.disabled
verified: .attributes.verified
createdAt: .attributes.created_at | todate
- kind: team
selector:
query: "true"
port:
entity:
mappings:
identifier: .id
title: .id
blueprint: '"datadogTeam"'
- kind: team
selector:
query: "true"
includeMembers: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .attributes.name
blueprint: '"datadogTeam"'
properties:
description: .attributes.description
handle: .attributes.handle
userCount: .attributes.user_count
summary: .attributes.summary
createdAt: .attributes.created_at | todate
relations:
members: if .__members then .__members[].id else [] end
- kind: role
selector:
query: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .attributes.name
blueprint: '"datadogRole"'
properties:
createdAt: .attributes.created_at | todate
modifiedAt: .attributes.modified_at | todate
custom: if .attributes.managed == true then false else true end
userCount: .attributes.user_count

Mapping & selectors per resource

Use the explorer below to view sample payloads and the resulting Port entities for each resource type. For additional resources and advanced configurations, see the examples page.

Service definitions vs APM services

Port's Datadog integration syncs Service entities from service definitions in the Datadog Service Catalog API (via the GET /api/v2/services/definitions endpoint).

That is separate from APM services, which Datadog discovers automatically from APM tracing. The integration does not fetch APM-discovered services.

Set up live events

The Datadog integration keeps your catalog up to date in near real time through two complementary channels. Both are available for all installation methods.

The two channels carry different event types and are not interchangeable. Configure both for full coverage:

ChannelCarries
1. Monitor notificationsMonitor state transitions (for example OKAlertOK) and service dependency updates
2. Audit trail forwardingConfiguration changes to monitors, SLOs, users, roles and teams, plus restriction policy changes
Monitor state transitions are only available through channel 1

The Datadog audit trail records user and API initiated actions, so a monitor changing state on its own does not appear in it. The overallState property on your monitor entities is therefore updated in real time only through channel 1; with channel 2 alone it refreshes on the next scheduled resync.

Live events base URL

For integrations installed using the Hosted by Port method, you can obtain the live events base URL from the Get an integration API. The response includes liveEventsUuid and liveEventsIngestHostname in the appSpec section.

Call the endpoint with your integration's identifier:

curl -X GET \
'https://api.port.io/v1/integration/<INTEGRATION_IDENTIFIER>' \
-H 'Authorization: Bearer <PORT_ACCESS_TOKEN>'
Selecting a Port API URL by account region

The port_region, port.baseUrl, portBaseUrl, port_base_url and OCEAN__PORT__BASE_URL parameters select which Port API instance to use:

In the response, look for the following fields under spec.appSpec:

{
"spec": {
"appSpec": {
"liveEventsUuid": "abcdefghijk",
"liveEventsIngestHostname": "ingest.ocean.getport.io"
}
}
}

Combine them to build the live events base URL:

https://<liveEventsIngestHostname>/live-events/<liveEventsUuid>

For example, with the values above, the live events base URL is:

https://ingest.ocean.getport.io/live-events/abcdefghijk

This is the same URL configured for the integration.

1. Monitor notifications (automatic)

When the integration starts, it automatically registers a Datadog webhook and creates a monitor notification rule. Any monitor matching the configured scope sends state change events directly to Port - no manual setup required.

Required application key permissions

To register these objects automatically, the Datadog application key used by the integration must have the following permissions:

PermissionUsed for
integrations_readRead existing webhook configuration
create_webhooksCreate the Port webhook
manage_integrationsUpdate the Port webhook
monitors_readList existing notification rules
monitor_config_policy_writeCreate or update the monitor notification rule

The following monitor alert types are supported: ci_pipelines_alert, ci_tests_alert, composite_monitor, error_tracking_alert, event_alert, event_v2_alert, log_alert, monitor_slo_alert, metric_slo_alert, outlier_monitor, process_alert, query_alert_monitor, rum_alert, service_check, synthetics_alert, trace_analytics_alert.

Use the monitorNotificationRuleScope configuration parameter to control which monitors trigger notifications (default: service:*, which captures all service monitors).

Example values:

  • service:* - all service monitors (default).
  • service:my-service AND env:prod - monitors for a specific service and environment only.

Note that the default scope only matches monitors carrying a service tag. If your monitors are tagged differently, widen the scope accordingly, or those monitors will not send state change events to Port.

Manual registration (optional)

The webhook and the notification rule can also be created by a Datadog administrator rather than by the integration. The integration consumes the resulting events either way - automatic registration is a convenience, not a requirement.

You might prefer manual registration if you:

  • manage Datadog resources as code, or through a change management process
  • want explicit control over the naming, scope, and lifecycle of both objects
  • want to reuse an existing webhook or notification rule instead of having a second one created
  • cannot grant the application key the write permissions listed above, for example under a read-only credential policy

Automatic registration is the only part being replaced. You still need a live events base URL configured, and the application key still needs read access to monitors so the integration can fetch each monitor when an event arrives.

Registration steps (click to expand)

Step 1: Create the webhook in Datadog

  1. In Datadog, go to Integrations > Webhooks.
  2. Click New Webhook and fill in the following:
    • Name: Any name you choose. Note it down - you will reference it in the next step.
    • URL: Append /integration/webhook/monitor-events to your live events base URL.
    • Payload: Enable Encode as JSON and enter the payload below exactly as shown.
    • Custom headers: If you have set a webhookSecret, add the following, replacing <your_webhook_secret> with its value. Skip this if you have not set a webhook secret.
      {"X-Port-Ocean-Webhook-Secret": "<your_webhook_secret>"}
  3. Save the webhook.

The payload template:

{
"id": "$ID",
"message": "$TEXT_ONLY_MSG",
"priority": "$PRIORITY",
"last_updated": "$LAST_UPDATED",
"event_type": "$EVENT_TYPE",
"event_url": "$LINK",
"service": "$HOSTNAME",
"service_id": "$SERVICE_ID",
"service_name": "$SERVICE_NAME",
"creator": "$USER",
"title": "$EVENT_TITLE",
"date": "$DATE",
"org_id": "$ORG_ID",
"org_name": "$ORG_NAME",
"alert_id": "$ALERT_ID",
"alert_metric": "$ALERT_METRIC",
"alert_status": "$ALERT_STATUS",
"alert_title": "$ALERT_TITLE",
"alert_type": "$ALERT_TYPE",
"tags": "$TAGS",
"body": "$EVENT_MSG"
}
Use the payload exactly as shown

Events missing event_type or alert_id are discarded, as are events missing org_name in multi-organization installations. Discards are silent, so an altered payload is difficult to diagnose.

Step 2: Create the monitor notification rule

  1. In Datadog, go to Monitors > Settings > Notification Rules.
  2. Create a new rule and add the webhook from step 1 as a recipient. Webhook recipients take the form @webhook-<name>, where <name> is the webhook name from step 1.
  3. Set the rule's scope to match the monitors you want to send state change events to Port.
  4. Save the rule.

Alternatively, add @webhook-<name> to the notification message of each individual monitor you want covered. A notification rule is usually preferable, since it applies to many monitors at once.

Step 3: Disable automatic registration

Set the skipWebhookCreation configuration parameter to true (integration.config.skipWebhookCreation for Helm installations), so the integration no longer attempts automatic registration on startup. It continues to receive and process live events normally.

2. Audit trail forwarding (manual setup required)

The integration processes Datadog audit trail events to reflect near-real-time changes to monitors, users, teams, SLOs, and roles in your catalog.

Catalog entityDatadog audit event
MonitorMonitor
MonitorAccess Management (restriction policy)
SLOSLO
SLOAccess Management (restriction policy)
UserAccess Management
RoleAccess Management
TeamTeams Management
Manual setup required

Datadog does not support managing audit trail forwarding destinations via its API. You must configure this destination manually in the Datadog UI, as described below.

To configure audit trail forwarding in Datadog:

  1. In Datadog, go to Organization Settings > Compliance > Audit Trail Settings.
  2. Under Forward Audit Events > Custom Destinations, click New Destination.
  3. Choose HTTP as the destination type and fill in the following:
    • Destination URL: Append /integration/webhook/audit-trail to your live events base URL.
    • Query filter: Enter the following query so that only events this integration handles are forwarded:
      @asset.type:(monitor OR slo) OR @evt.name:("Access Management" OR "Teams Management")
    • Authentication: Select Request Header and provide:
      • Header name: X-Port-Ocean-Webhook-Secret
      • Header value: The value of your webhookSecret configuration. If you have not set a webhook secret, enter any random string - Datadog requires a non-empty value, and the integration will accept all requests regardless.
    • Enable GZIP compression for payloads: Disable this option. It is enabled by default, but the integration expects uncompressed payloads.
  4. Save the destination.

Monitoring and sync status

To learn more about how to monitor and check the sync status of your integration, see the relevant documentation.

Examples

To view and test the integration's mapping against examples of the third-party API responses, use the jq playground in your data sources page. Find the integration in the list of data sources and click on it to open the playground.

Examples of blueprints and the relevant integration configurations can be found on the datadog examples page

Relevant Guides

For relevant guides and examples, see the guides section.