Skip to main content

Check out Port for yourself 

Dynatrace

Port's Dynatrace integration allows you to model Dynatrace resources in your software catalog and ingest data into them.

Overview

This integration allows you to:

  • Map and organize your desired Dynatrace resources and their metadata in Port (see supported resources below).
  • Watch for Dynatrace object changes (create/update/delete) in real-time, and automatically apply the changes to your software catalog.

Supported Resources

The resources that can be ingested from Dynatrace into Port are listed below. It is possible to reference any field that appears in the API responses linked below for the mapping configuration.

Prerequisites

Generate a Dynatrace API key

  1. Navigate to <instanceURL>/ui/apps/dynatrace.classic.tokens/ui/access-tokens. For example, if you access your Dynatrace instance at https://npm82883.apps.dynatrace.com, you should navigate to https://npm82883.apps.dynatrace.com/ui/apps/dynatrace.classic.tokens/ui/access-tokens.
  2. Click Generate new token to create a new token. Ensure the permissions: DataExport, Read entities, Read problems and Read SLO are assigned to the token. The DataExport permission allows Dynatrace to perform healthchecks before ingestion starts.

Construct your Dynatrace Host URL

Your Dynatrace host URL should be https://<environment-id>.live.dynatrace.com. Note that there is a difference between the instance URL and the API host URL. The former contains apps while the latter (as shown prior) uses live. This means if your environment ID is npm82883, your API host URL should be https://npm82883.live.dynatrace.com.

Setup

Choose one of the following installation methods:

Using this installation option means that the integration will be hosted by Port, with a customizable resync interval to ingest data into Port.

Live event support

Currently, live events are not supported for integrations hosted by Port.
Resyncs will be performed periodically (with a configurable interval), or manually triggered by you via Port's UI.

Therefore, real-time events (including GitOps) will not be ingested into Port immediately.
Support for live events is WIP and will be supported in the near future.

Self-hosted installation

Alternatively, you can install the integration using the Real-time (self-hosted) method to update Port in real time using webhooks.

Installation

To install, follow these steps:

  1. Go to the Data sources page of your portal.

  2. Click on the + Data source button in the top-right corner.

  3. Click on the relevant integration in the list.

  4. Under Select your installation method, choose Hosted by Port.

  5. Configure the integration settings and application settings as you wish (see below for details).

Application settings

Every integration hosted by Port has the following customizable application settings, which are configurable after installation:

  • Resync interval: The frequency at which Port will ingest data from the integration. There are various options available, ranging from every 1 hour to once a day.

  • Send raw data examples: A boolean toggle (enabled by default). If enabled, raw data examples will be sent from the integration to Port. These examples are used when testing your mapping configuration, they allow you to run your jq expressions against real data and see the results.

Integration settings

Every integration has its own tool-specific settings, under the Integration settings section.
Each of these settings has an ⓘ icon next to it, which you can hover over to see a description of the setting.

Port secrets

Some integration settings require sensitive pieces of data, such as tokens.
For these settings, Port secrets will be used, ensuring that your sensitive data is encrypted and secure.

When filling in such a setting, its value will be obscured (shown as ••••••••).
For each such setting, Port will automatically create a secret in your organization.

To see all secrets in your organization, follow these steps.

Port source IP addresses

When using this installation method, Port will make outbound calls to your 3rd-party applications from static IP addresses.
You may need to add these addresses to your allowlist, in order to allow Port to interact with the integrated service:

54.73.167.226  
63.33.143.237
54.76.185.219

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.

Ingest additional resource types

By default, the entity kind ingests only entities of type APPLICATION and SERVICE due to the large number of available resources. However, you can configure the entity kind mapping to ingest entities of other types.

To do this, use the entityTypes selector in the entity mapping like so:

Mapping configuration (Click to expand)
createMissingRelatedEntities: true
deleteDependentEntities: true
resources:
- kind: entity
selector:
query: "true"
entityTypes: ["APPLICATION", "SERVICE"]
port:
entity:
mappings:
identifier: .entityId
title: .displayName
blueprint: '"dynatraceEntity"'
properties:
firstSeen: ".firstSeenTms / 1000 | todate"
lastSeen: ".lastSeenTms / 1000 | todate"
type: .type
tags: .tags[].stringRepresentation
managementZones: .managementZones[].name
properties: .properties
fromRelationships: .fromRelationships
toRelationships: .toRelationships

Available resource types

You can retrieve a list of available resource types by using the Dynatrace Entity Types API. Below is a list of resource types retrieved from the API:

Dynatrace entity types (Click to expand)
  • APM_SECURITY_GATEWAY
  • APPLICATION
  • APPLICATION_METHOD
  • APPLICATION_METHOD_GROUP
  • APPMON_SERVER
  • APPMON_SYSTEM_PROFILE
  • AUTO_SCALING_GROUP
  • AWS_APPLICATION_LOAD_BALANCER
  • AWS_AVAILABILITY_ZONE
  • AWS_CREDENTIALS
  • AWS_LAMBDA_FUNCTION
  • AWS_NETWORK_LOAD_BALANCER
  • AZURE_API_MANAGEMENT_SERVICE
  • AZURE_APPLICATION_GATEWAY
  • AZURE_APP_SERVICE_PLAN
  • AZURE_COSMOS_DB
  • AZURE_CREDENTIALS
  • AZURE_EVENT_HUB
  • AZURE_EVENT_HUB_NAMESPACE
  • AZURE_FUNCTION_APP
  • AZURE_IOT_HUB
  • AZURE_LOAD_BALANCER
  • AZURE_MGMT_GROUP
  • AZURE_REDIS_CACHE
  • AZURE_REGION
  • AZURE_SERVICE_BUS_NAMESPACE
  • AZURE_SERVICE_BUS_QUEUE
  • AZURE_SERVICE_BUS_TOPIC
  • AZURE_SQL_DATABASE
  • AZURE_SQL_ELASTIC_POOL
  • AZURE_SQL_SERVER
  • AZURE_STORAGE_ACCOUNT
  • AZURE_SUBSCRIPTION
  • AZURE_TENANT
  • AZURE_VM
  • AZURE_VM_SCALE_SET
  • AZURE_WEB_APP
  • BOSH_DEPLOYMENT
  • BROWSER
  • CF_FOUNDATION
  • CINDER_VOLUME
  • CLOUD_APPLICATION
  • CLOUD_APPLICATION_INSTANCE
  • CLOUD_APPLICATION_NAMESPACE
  • CONTAINER_GROUP
  • CONTAINER_GROUP_INSTANCE
  • CUSTOM_APPLICATION
  • CUSTOM_DEVICE
  • CUSTOM_DEVICE_GROUP
  • DATASTORE
  • DCRUM_APPLICATION
  • DCRUM_SERVICE
  • DCRUM_SERVICE_INSTANCE
  • DEVICE_APPLICATION_METHOD
  • DEVICE_APPLICATION_METHOD_GROUP
  • DISK
  • DOCKER_CONTAINER_GROUP
  • DOCKER_CONTAINER_GROUP_INSTANCE
  • DYNAMO_DB_TABLE
  • EBS_VOLUME
  • EC2_INSTANCE
  • ELASTIC_LOAD_BALANCER
  • ENVIRONMENT
  • EXTERNAL_SYNTHETIC_TEST
  • EXTERNAL_SYNTHETIC_TEST_STEP
  • GCP_ZONE
  • GEOLOCATION
  • GEOLOC_SITE
  • GOOGLE_COMPUTE_ENGINE
  • HOST
  • HOST_GROUP
  • HTTP_CHECK
  • HTTP_CHECK_STEP
  • HYPERVISOR
  • HYPERVISOR_CLUSTER
  • HYPERVISOR_DISK
  • KUBERNETES_CLUSTER
  • KUBERNETES_NODE
  • KUBERNETES_SERVICE
  • MOBILE_APPLICATION
  • MULTIPROTOCOL_MONITOR
  • NETWORK_INTERFACE
  • NEUTRON_SUBNET
  • OPENSTACK_AVAILABILITY_ZONE
  • OPENSTACK_COMPUTE_NODE
  • OPENSTACK_PROJECT
  • OPENSTACK_REGION
  • OPENSTACK_VM
  • OS
  • PROCESS_GROUP
  • PROCESS_GROUP_INSTANCE
  • QUEUE
  • QUEUE_INSTANCE
  • RELATIONAL_DATABASE_SERVICE
  • RUNTIME_COMPONENT
  • S3BUCKET
  • SERVICE
  • SERVICE_INSTANCE
  • SERVICE_METHOD
  • SERVICE_METHOD_GROUP
  • SOFTWARE_COMPONENT
  • SWIFT_CONTAINER
  • SYNTHETIC_LOCATION
  • SYNTHETIC_TEST
  • SYNTHETIC_TEST_STEP
  • VCENTER
  • VIRTUALMACHINE
  • VMWARE_DATACENTER
  • cloud:aws:acmprivateca
  • cloud:aws:api_gateway
  • cloud:aws:app_runner
  • cloud:aws:appstream
  • cloud:aws:appsync
  • cloud:aws:athena
  • cloud:aws:aurora
  • cloud:aws:autoscaling
  • cloud:aws:billing
  • cloud:aws:cassandra
  • cloud:aws:chatbot
  • cloud:aws:cloud_front
  • cloud:aws:cloudhsm
  • cloud:aws:cloudsearch
  • cloud:aws:codebuild
  • cloud:aws:cognito
  • cloud:aws:connect
  • cloud:aws:datasync
  • cloud:aws:dax
  • cloud:aws:dms
  • cloud:aws:documentdb
  • cloud:aws:dxcon
  • cloud:aws:dynamodb
  • cloud:aws:ebs
  • cloud:aws:ec2_spot
  • cloud:aws:ec2api
  • cloud:aws:ecs
  • cloud:aws:ecs:cluster
  • cloud:aws:efs
  • cloud:aws:eks:cluster
  • cloud:aws:elasticache
  • cloud:aws:elasticbeanstalk
  • cloud:aws:elasticinference
  • cloud:aws:elastictranscoder
  • cloud:aws:emr
  • cloud:aws:es
  • cloud:aws:events
  • cloud:aws:fsx
  • cloud:aws:gamelift
  • cloud:aws:glue
  • cloud:aws:inspector
  • cloud:aws:iot
  • cloud:aws:iot_things_graph
  • cloud:aws:iotanalytics
  • cloud:aws:kafka
  • cloud:aws:kinesis:data_analytics
  • cloud:aws:kinesis:data_firehose
  • cloud:aws:kinesis:data_stream
  • cloud:aws:kinesis:video_stream
  • cloud:aws:lambda
  • cloud:aws:lex
  • cloud:aws:logs
  • cloud:aws:media_tailor
  • cloud:aws:mediaconnect
  • cloud:aws:mediaconvert
  • cloud:aws:mediapackagelive
  • cloud:aws:mediapackagevod
  • cloud:aws:mq
  • cloud:aws:nat_gateway
  • cloud:aws:neptune
  • cloud:aws:opsworks
  • cloud:aws:polly
  • cloud:aws:qldb
  • cloud:aws:rds
  • cloud:aws:redshift
  • cloud:aws:rekognition
  • cloud:aws:robomaker
  • cloud:aws:route53
  • cloud:aws:route53resolver
  • cloud:aws:s3
  • cloud:aws:sage_maker:batch_transform_job
  • cloud:aws:sage_maker:endpoint
  • cloud:aws:sage_maker:endpoint_instance
  • cloud:aws:sage_maker:ground_truth
  • cloud:aws:sage_maker:processing_job
  • cloud:aws:sage_maker:training_job
  • cloud:aws:servicecatalog
  • cloud:aws:ses
  • cloud:aws:sns
  • cloud:aws:sqs
  • cloud:aws:ssm-runcommand
  • cloud:aws:states
  • cloud:aws:storagegateway
  • cloud:aws:swf
  • cloud:aws:textract
  • cloud:aws:transfer
  • cloud:aws:transitgateway
  • cloud:aws:translate
  • cloud:aws:trustedadvisor
  • cloud:aws:usage
  • cloud:aws:vpn
  • cloud:aws:waf
  • cloud:aws:wafv2
  • cloud:aws:workmail
  • cloud:aws:workspaces
  • cloud:azure:apimanagement:service
  • cloud:azure:app:containerapps
  • cloud:azure:app:managedenvironments
  • cloud:azure:appconfiguration:configurationstores
  • cloud:azure:appplatform:spring
  • cloud:azure:automation:automationaccounts
  • cloud:azure:batch:account
  • cloud:azure:blockchain:blockchainmembers
  • cloud:azure:cache:redis
  • cloud:azure:cdn:cdnwebapplicationfirewallpolicies
  • cloud:azure:cdn:profiles
  • cloud:azure:classic_storage_account
  • cloud:azure:classic_storage_account:blob
  • cloud:azure:classic_storage_account:file
  • cloud:azure:classic_storage_account:queue
  • cloud:azure:classic_storage_account:table
  • cloud:azure:classic_virtual_machine
  • cloud:azure:cognitiveservices:allinone
  • cloud:azure:cognitiveservices:anomalydetector
  • cloud:azure:cognitiveservices:bingautosuggest
  • cloud:azure:cognitiveservices:bingcustomsearch
  • cloud:azure:cognitiveservices:bingentitysearch
  • cloud:azure:cognitiveservices:bingsearch
  • cloud:azure:cognitiveservices:bingspellcheck
  • cloud:azure:cognitiveservices:computervision
  • cloud:azure:cognitiveservices:contentmoderator
  • cloud:azure:cognitiveservices:customvisionprediction
  • cloud:azure:cognitiveservices:customvisiontraining
  • cloud:azure:cognitiveservices:face
  • cloud:azure:cognitiveservices:immersivereader
  • cloud:azure:cognitiveservices:inkrecognizer
  • cloud:azure:cognitiveservices:luis
  • cloud:azure:cognitiveservices:luisauthoring
  • cloud:azure:cognitiveservices:openai
  • cloud:azure:cognitiveservices:personalizer
  • cloud:azure:cognitiveservices:qnamaker
  • cloud:azure:cognitiveservices:speech
  • cloud:azure:cognitiveservices:textanalytics
  • cloud:azure:cognitiveservices:translator
  • cloud:azure:containerinstance:containergroup
  • cloud:azure:containerregistry:registries
  • cloud:azure:containerservice:managedcluster
  • cloud:azure:datafactory:v1
  • cloud:azure:datafactory:v2
  • cloud:azure:datalakeanalytics:accounts
  • cloud:azure:datalakestore:accounts
  • cloud:azure:datashare:accounts
  • cloud:azure:devices:iothubs
  • cloud:azure:devices:provisioningservices
  • cloud:azure:documentdb:databaseaccounts:global
  • cloud:azure:documentdb:databaseaccounts:mongo
  • cloud:azure:eventgrid:domains
  • cloud:azure:eventgrid:systemtopics
  • cloud:azure:eventgrid:topics
  • cloud:azure:eventhub:clusters
  • cloud:azure:frontdoor
  • cloud:azure:hdinsight:cluster
  • cloud:azure:hybridcompute:machines
  • cloud:azure:insights:components
  • cloud:azure:iotcentral:iotapps
  • cloud:azure:keyvault:vaults
  • cloud:azure:kusto:clusters
  • cloud:azure:logic:integrationserviceenvironments
  • cloud:azure:logic:workflows
  • cloud:azure:machinelearningservices:workspaces
  • cloud:azure:maps:accounts
  • cloud:azure:mariadb:server
  • cloud:azure:media:mediaservices
  • cloud:azure:media:mediaservices:streamingendpoints
  • cloud:azure:mysql:flexibleservers
  • cloud:azure:mysql:server
  • cloud:azure:netapp:netappaccounts:capacitypools
  • cloud:azure:netapp:netappaccounts:capacitypools:volumes
  • cloud:azure:network:applicationgateways
  • cloud:azure:network:azurefirewalls
  • cloud:azure:network:dnszones
  • cloud:azure:network:expressroutecircuits
  • cloud:azure:network:loadbalancers:basic
  • cloud:azure:network:loadbalancers:gateway
  • cloud:azure:network:loadbalancers:standard
  • cloud:azure:network:networkinterfaces
  • cloud:azure:network:networkwatchers:connectionmonitors
  • cloud:azure:network:networkwatchers:connectionmonitors:previe
  • cloud:azure:network:privatednszones
  • cloud:azure:network:publicipaddresses
  • cloud:azure:notificationhubs:namespaces:notificationhubs
  • cloud:azure:postgresql:flexibleservers
  • cloud:azure:postgresql:server
  • cloud:azure:postgresql:serverv2
  • cloud:azure:powerbidedicated:capacities
  • cloud:azure:recoveryservices:vaults
  • cloud:azure:relay:namespaces
  • cloud:azure:search:searchservices
  • cloud:azure:servicefabricmesh:applications
  • cloud:azure:signalrservice:signalr
  • cloud:azure:sql:managed
  • cloud:azure:sql:servers
  • cloud:azure:sql:servers:databases:datawarehouse
  • cloud:azure:sql:servers:databases:dtu
  • cloud:azure:sql:servers:databases:hyperscale
  • cloud:azure:sql:servers:databases:vcore
  • cloud:azure:sql:servers:elasticpools:dtu
  • cloud:azure:sql:servers:elasticpools:vcore
  • cloud:azure:storage:storageaccounts
  • cloud:azure:storage:storageaccounts:blob
  • cloud:azure:storage:storageaccounts:file
  • cloud:azure:storage:storageaccounts:queue
  • cloud:azure:storage:storageaccounts:table
  • cloud:azure:storagesync:storagesyncservices
  • cloud:azure:streamanalytics:streamingjobs
  • cloud:azure:synapse:workspaces
  • cloud:azure:synapse:workspaces:bigdatapools
  • cloud:azure:synapse:workspaces:sqlpools
  • cloud:azure:timeseriesinsights:environments
  • cloud:azure:timeseriesinsights:eventsources
  • cloud:azure:traffic_manager_profile
  • cloud:azure:virtual_network_gateway
  • cloud:azure:web:appslots
  • cloud:azure:web:functionslots
  • cloud:azure:web:hostingenvironments:v2
  • cloud:azure:web:serverfarms
  • cloud:gcp:autoscaler
  • cloud:gcp:bigquery_biengine_model
  • cloud:gcp:cloud_function
  • cloud:gcp:cloud_run_revision
  • cloud:gcp:cloudsql_database
  • cloud:gcp:filestore_instance
  • cloud:gcp:gae_app
  • cloud:gcp:gce_instance
  • cloud:gcp:gcs_bucket
  • cloud:gcp:https_lb
  • cloud:gcp:instance_group
  • cloud:gcp:internal_http_lb_rule
  • cloud:gcp:internal_network_lb_rule
  • cloud:gcp:k8s_cluster
  • cloud:gcp:k8s_container
  • cloud:gcp:k8s_node
  • cloud:gcp:k8s_pod
  • cloud:gcp:network_lb_rule
  • cloud:gcp:project
  • cloud:gcp:pubsub_snapshot
  • cloud:gcp:pubsub_subscription
  • cloud:gcp:pubsub_topic
  • cloud:gcp:pubsublite_subscription_partition
  • cloud:gcp:pubsublite_topic_partition
  • cloud:gcp:tcp_ssl_proxy_rule
  • cloud:gcp:tpu_worker
  • os:service

Capabilities

Configure real-time updates

Currently, the Dynatrace API lacks support for programmatic webhook creation. To set up a webhook configuration in Dynatrace for sending alert notifications to the Ocean integration, follow these steps:

Webhook configuration

Prepare a webhook URL using this format: {app_host}/integration/webhook/problem.
The app_host parameter should match the ingress or external load balancer where the integration will be deployed.
For example, if your ingress or load balancer exposes the Dynatrace Ocean integration at https://myservice.domain.com, your webhook URL should be https://myservice.domain.com/integration/webhook/problem.

  1. Go to Dynatrace.
  2. Go to Settings > Integration > Problem notifications.
  3. Select Add notification.
  4. Select Custom integration from the available notification types.
  5. Configure the notification using the following details.
    1. Enabled - ensure the notification is enabled.
    2. Display name - use a meaningful name such as Port Ocean Webhook.
    3. Webhook URL - enter the value of the URL you created above.
    4. Enable Call webhook is new events merge into existing problems.
    5. Custom payload - paste the following configuration:
      {
      "State":"{State}",
      "ProblemID":"{ProblemID}",
      "ProblemTitle":"{ProblemTitle}"
      }
      You can customize to your taste, the only important thing is the ProblemID key. The webhook integration will not work without it.
    6. Alerting profile - select the corresponding alerting profile.
    7. Leave the rest of the fields as is.
  6. Click Save changes.

Examples

Examples of blueprints and the relevant integration configurations:

Entity

Entity blueprint
{
"identifier": "dynatraceEntity",
"description": "This blueprint represents a Dynatrace Entity",
"title": "Dynatrace Entity",
"icon": "Dynatrace",
"schema": {
"properties": {
"firstSeen": {
"type": "string",
"title": "First Seen",
"description": "The timestamp at which the entity was first seen, in UTC milliseconds.",
"format": "date-time"
},
"lastSeen": {
"type": "string",
"title": "Last Seen",
"description": "The timestamp at which the entity was last seen, in UTC milliseconds.",
"format": "date-time"
},
"type": {
"type": "string",
"title": "Type",
"description": "The type of the entity."
},
"tags": {
"type": "array",
"title": "Tags",
"description": "A list of tags of the entity.",
"items": {
"type": "string"
}
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Integration configuration
createMissingRelatedEntities: true
deleteDependentEntities: true
resources:
- kind: entity
selector:
query: "true"
entityTypes: ["APPLICATION", "SERVICE"] # An optional list of entity types to filter by. If not specified, defaults to ["APPLICATION", "SERVICE"].
port:
entity:
mappings:
identifier: .entityId
title: .displayName
blueprint: '"dynatraceEntity"'
properties:
firstSeen: ".firstSeenTms / 1000 | todate"
lastSeen: ".lastSeenTms / 1000 | todate"
type: .type
tags: .tags[].stringRepresentation

Problem

Problem blueprint
{
"identifier": "dynatraceProblem",
"description": "This blueprint represents a Dynatrace Problem",
"title": "Dynatrace Problem",
"icon": "Dynatrace",
"schema": {
"properties": {
"entityTags": {
"type": "array",
"title": "Entity Tags",
"description": "A list of all entity tags of the problem.",
"items": {
"type": "string"
}
},
"evidenceDetails": {
"type": "array",
"title": "Evidence Details",
"description": "A list of all evidence details of the problem.",
"items": {
"type": "string"
}
},
"managementZones": {
"type": "array",
"title": "Management Zones",
"description": "A list of all management zones that the problem belongs to.",
"items": {
"type": "string"
}
},
"problemFilters": {
"type": "array",
"title": "Problem Filters",
"description": "A list of alerting profiles that match the problem.",
"items": {
"type": "string"
}
},
"severityLevel": {
"type": "string",
"title": "Severity Level",
"description": "The severity level of the problem.",
"enum": [
"AVAILABILITY",
"CUSTOM_ALERT",
"ERROR",
"INFO",
"MONITORING_UNAVAILABLE",
"PERFORMANCE",
"RESOURCE_CONTENTION"
],
"enumColors": {
"AVAILABILITY": "blue",
"CUSTOM_ALERT": "turquoise",
"ERROR": "red",
"INFO": "green",
"MONITORING_UNAVAILABLE": "darkGray",
"PERFORMANCE": "orange",
"RESOURCE_CONTENTION": "yellow"
}
},
"status": {
"type": "string",
"title": "Status",
"description": "The status of the problem.",
"enum": ["CLOSED", "OPEN"],
"enumColors": {
"CLOSED": "green",
"OPEN": "red"
}
},
"startTime": {
"type": "string",
"title": "Start Time",
"description": "The start time of the problem, in UTC milliseconds.",
"format": "date-time"
},
"endTime": {
"type": "string",
"title": "End Time",
"description": "The end time of the problem, in UTC milliseconds.",
"format": "date-time"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"impactedEntities": {
"title": "Impacted Entities",
"target": "dynatraceEntity",
"required": false,
"many": true
},
"linkedProblemInfo": {
"title": "Linked Problem Info",
"target": "dynatraceProblem",
"required": false,
"many": false
},
"rootCauseEntity": {
"title": "Root Cause Entity",
"target": "dynatraceEntity",
"required": false,
"many": false
}
}
}
Integration configuration
createMissingRelatedEntities: true
deleteDependentEntities: true
resources:
- kind: problem
selector:
query: "true"
port:
entity:
mappings:
identifier: .problemId
title: .title
blueprint: '"dynatraceProblem"'
properties:
entityTags: .entityTags[].stringRepresentation
evidenceDetails: .evidenceDetails.details[].displayName
managementZones: .managementZones[].name
problemFilters: .problemFilters[].name
severityLevel: .severityLevel
status: .status
startTime: ".startTime / 1000 | todate"
endTime: ".endTime | if . == -1 then null else (./1000 | todate) end"
relations:
impactedEntities: .impactedEntities[].entityId.id
linkedProblemInfo: .linkedProblemInfo.problemId
rootCauseEntity: .rootCauseEntity.entityId.id

SLO

SLO blueprint
{
"identifier": "dynatraceSlo",
"description": "This blueprint represents a Dynatrace SLO",
"title": "Dynatrace SLO",
"icon": "Dynatrace",
"schema": {
"properties": {
"status": {
"type": "string",
"title": "Status",
"description": "The status of the SLO.",
"enum": ["FAILURE", "WARNING", "SUCCESS"],
"enumColors": {
"FAILURE": "red",
"WARNING": "yellow",
"SUCCESS": "green"
}
},
"target": {
"type": "number",
"title": "Target",
"description": "The target value of the SLO."
},
"enabled": {
"type": "boolean",
"title": "Enabled",
"description": "Whether the SLO is enabled."
},
"warning": {
"type": "number",
"title": "Warning",
"description": "The warning value of the SLO. At warning state the SLO is still fulfilled but is getting close to failure."
},
"error": {
"type": "string",
"title": "Error",
"description": "The error of the SLO calculation. If the value differs from NONE, there is something wrong with the SLO calculation."
},
"errorBudget": {
"type": "number",
"title": "Error Budget",
"description": "The error budget of the calculated SLO."
},
"evaluatedPercentage": {
"type": "number",
"title": "Evaluated Percentage",
"description": "The calculated status value of the SLO."
},
"evaluationType": {
"type": "string",
"title": "Evaluation Type",
"description": "The type of the SLO evaluation."
},
"filter": {
"type": "string",
"title": "Filter",
"description": "The filter for the SLO evaluation."
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Integration configuration
createMissingRelatedEntities: true
deleteDependentEntities: true
resources:
- kind: slo
selector:
query: "true"
port:
entity:
mappings:
identifier: .id
title: .name
blueprint: '"dynatraceSlo"'
properties:
status: .status
target: .target
enabled: .enabled
warning: .warning
error: .error
errorBudget: .errorBudget
evaluatedPercentage: .evaluatedPercentage
evaluationType: .evaluationType
filter: .filter

Let's Test It

This section includes a sample response data from Dynatrace. In addition, it includes the entity created from the resync event based on the Ocean configuration provided in the previous section.

Payload

Here is an example of the payload structure from Dynatrace:

Entity response data
{
"displayName": "my host",
"entityId": "HOST-06F288EE2A930951",
"firstSeenTms": 1574697667547,
"fromRelationships": {
"isInstanceOf": [
{
"id": "HOST_GROUP-0E489369D663A4BF",
"type": "HOST_GROUP"
}
]
},
"icon": {
"customIconPath": "host",
"primaryIconType": "linux",
"secondaryIconType": "microsoft-azure-signet"
},
"lastSeenTms": 1588242361417,
"managementZones": [
{
"id": "6239538939987181652",
"name": "main app"
}
],
"properties": {
"bitness": 64,
"cpuCores": 8,
"monitoringMode": "FULL_STACK",
"networkZoneId": "aws.us.east01",
"osArchitecture": "X86",
"osType": "LINUX"
},
"tags": [
{
"context": "CONTEXTLESS",
"key": "architecture",
"stringRepresentation": "architecture:x86",
"value": "x86"
},
{
"context": "ENVIRONMENT",
"key": "Infrastructure",
"stringRepresentation": "[ENVIRONMENT]Infrastructure:Linux",
"value": "Linux"
}
],
"toRelationships": {
"isDiskOf": [
{
"id": "DISK-0393340DCA3853B0",
"type": "DISK"
}
]
},
"type": "HOST"
}
Problem response data
{
"affectedEntities": [
{
"entityId": {
"id": "string",
"type": "string"
},
"name": "string"
}
],
"displayId": "string",
"endTime": 1574697669865,
"entityTags": [
{
"context": "CONTEXTLESS",
"key": "architecture",
"stringRepresentation": "architecture:x86",
"value": "x86"
},
{
"context": "ENVIRONMENT",
"key": "Infrastructure",
"stringRepresentation": "[ENVIRONMENT]Infrastructure:Linux",
"value": "Linux"
}
],
"evidenceDetails": {
"details": [
{
"displayName": "Availability evidence",
"entity": {},
"evidenceType": "AVAILABILITY_EVIDENCE",
"groupingEntity": {},
"rootCauseRelevant": true,
"startTime": 1
},
{
"displayName": "User action evidence",
"entity": {},
"evidenceType": "USER_ACTION_EVIDENCE",
"groupingEntity": {},
"rootCauseRelevant": true,
"startTime": 1
}
],
"totalCount": 1
},
"impactAnalysis": {
"impacts": [
{
"estimatedAffectedUsers": 1,
"impactType": "APPLICATION",
"impactedEntity": {}
}
]
},
"impactLevel": "APPLICATION",
"impactedEntities": [{}],
"linkedProblemInfo": {
"displayId": "string",
"problemId": "string"
},
"managementZones": [
{
"id": "string",
"name": "HOST"
}
],
"problemFilters": [
{
"id": "E2A930951",
"name": "BASELINE"
}
],
"problemId": "06F288EE2A930951",
"recentComments": {
"comments": [
{
"authorName": "string",
"content": "string",
"context": "string",
"createdAtTimestamp": 1,
"id": "string"
}
],
"nextPageKey": "AQAAABQBAAAABQ==",
"pageSize": 1,
"totalCount": 1
},
"rootCauseEntity": {},
"severityLevel": "AVAILABILITY",
"startTime": 1574697667547,
"status": "CLOSED",
"title": "title"
}
SLO response data
{
"burnRateMetricKey": "func:slo.errorBudgetBurnRate.payment_service_availability",
"denominatorValue": 90,
"description": "Rate of successful payments per week",
"enabled": true,
"error": "NONE",
"errorBudget": 1.25,
"errorBudgetBurnRate": {
"burnRateType": "SLOW",
"burnRateValue": 1.25,
"burnRateVisualizationEnabled": true,
"estimatedTimeToConsumeErrorBudget": 24,
"fastBurnThreshold": 1.5,
"sloValue": 95
},
"errorBudgetMetricKey": "func:slo.errorBudget.payment_service_availability",
"evaluatedPercentage": 96.25,
"evaluationType": "AGGREGATE",
"filter": "type(\"SERVICE\")",
"id": "123e4567-e89b-42d3-a456-556642440000",
"metricDenominator": "builtin:service.requestCount.server",
"metricExpression": "(100)*(builtin:service.errors.server.successCount:splitBy())/(builtin:service.requestCount.server:splitBy())",
"metricKey": "func:slo.payment_service_availability",
"metricNumerator": "builtin:service.errors.server.successCount",
"metricRate": "builtin:service.successes.server.rate",
"name": "Payment service availability",
"normalizedErrorBudgetMetricKey": "func:slo.normalizedErrorBudget.payment_service_availability",
"numeratorValue": 80,
"problemFilters": "[type(\"SERVICE\")]",
"relatedOpenProblems": 1,
"relatedTotalProblems": 1,
"status": "WARNING",
"target": 95,
"timeframe": "-1d",
"useRateMetric": true,
"warning": 97.5
}

Mapping Result

The combination of the sample payload and the Ocean configuration generates the following Port entity:

Entity entity in Port
{
"identifier": "HOST-06F288EE2A930951",
"title": "my host",
"blueprint": "dynatraceEntity",
"team": [],
"icon": "Dynatrace",
"properties": {
"firstSeen": "2019-11-25T14:14:27Z",
"lastSeen": "2020-04-30T14:52:41Z",
"type": "HOST",
"tags": ["architecture:x86", "[ENVIRONMENT]Infrastructure:Linux"]
},
"relations": {},
"createdAt": "2024-2-6T09:30:57.924Z",
"createdBy": "hBx3VFZjqgLPEoQLp7POx5XaoB0cgsxW",
"updatedAt": "2024-2-6T11:49:20.881Z",
"updatedBy": "hBx3VFZjqgLPEoQLp7POx5XaoB0cgsxW"
}
Problem entity in Port
{
"identifier": "06F288EE2A930951",
"title": "title",
"blueprint": "dynatraceProblem",
"team": [],
"icon": "Dynatrace",
"properties": {
"entityTags": ["architecture:x86", "[ENVIRONMENT]Infrastructure:Linux"],
"evidenceDetails": ["Availability evidence", "User action evidence"],
"managementZones": ["HOST"],
"problemFilters": ["BASELINE"],
"severityLevel": "AVAILABILITY",
"status": "CLOSED",
"startTime": "2019-11-25T14:14:27Z",
"endTime": "2020-04-30T14:52:41Z"
},
"relations": {
"impactedEntities": ["HOST-06F288EE2A930951"],
"linkedProblemInfo": "06F288EE2A930951",
"rootCauseEntity": "HOST-06F288EE2A930951"
},
"createdAt": "2024-2-6T09:30:57.924Z",
"createdBy": "hBx3VFZjqgLPEoQLp7POx5XaoB0cgsxW",
"updatedAt": "2024-2-6T11:49:20.881Z",
"updatedBy": "hBx3VFZjqgLPEoQLp7POx5XaoB0cgsxW"
}
SLO entity in Port
{
"identifier": "123e4567-e89b-42d3-a456-556642440000",
"title": "Payment service availability",
"blueprint": "dynatraceSlo",
"team": [],
"icon": "Dynatrace",
"properties": {
"status": "WARNING",
"target": 95,
"enabled": true,
"warning": 97.5,
"error": "NONE",
"errorBudget": 1.25,
"evaluatedPercentage": 96.25,
"evaluationType": "AGGREGATE",
"filter": "type(\"SERVICE\")"
},
}

Alternative installation via webhook

While the Ocean integration described above is the recommended installation method, you may prefer to use a webhook to ingest problem from Dynatrace. If so, use the following instructions:

Note that when using this method, data will be ingested into Port only when the webhook is triggered.

Webhook installation (click to expand)

Port configuration

Create the following blueprint definitions:

Dynatrace microservice blueprint
{
"identifier": "microservice",
"title": "Microservice",
"icon": "Service",
"schema": {
"properties": {
"description": {
"title": "Description",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Dynatrace problem blueprint
{
"identifier": "dynatraceProblem",
"description": "This blueprint represents a Dynatrace problem in our software catalog",
"title": "Dynatrace Problem",
"icon": "Deployment",
"schema": {
"properties": {
"state": {
"type": "string",
"title": "Problem State"
},
"url": {
"type": "string",
"format": "url",
"title": "Problem URL"
},
"details": {
"type": "string",
"title": "Details"
},
"impact": {
"type": "string",
"title": "Problem Impact"
},
"severity": {
"type": "string",
"title": "Problem Severity"
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"title": "Tags"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"microservice": {
"title": "Impacted Services",
"target": "microservice",
"required": false,
"many": true
}
}
}

Create the following webhook configuration using Port's UI:

Dynatrace problem webhook configuration
  1. Basic details tab - fill the following details:

    1. Title : Dynatrace Problem Mapper;
    2. Identifier : dynatrace_problem_mapper;
    3. Description : A webhook configuration for problem events from Dynatrace;
    4. Icon : Dynatrace;
  2. Integration configuration tab - fill the following JQ mapping:

    [
    {
    "blueprint": "dynatraceProblem",
    "entity": {
    "identifier": ".body.PID | tostring",
    "title": ".body.ProblemTitle",
    "properties": {
    "state": ".body.State",
    "url": ".body.ProblemURL",
    "details": ".body.ProblemDetailsText",
    "impact": ".body.ProblemImpact",
    "severity": ".body.ProblemSeverity",
    "tags": ".body.ProblemTags | split(\", \")"
    },
    "relations": {
    "microservice": "[.body.ImpactedEntities[].entity]"
    }
    }
    }
    ]
  3. Click Save at the bottom of the page.

note

The webhook configuration's relation mapping will function properly only when the identifiers of the Port microservice entities match the names of the entities in your Dynatrace.

If there is a mismatch, you can utilize Dynatrace Tags to align the actual identifier in Port.

To do this, create a tag with the key proj and value microservice_identifier.

Then, update the relation JQ syntax to establish a connection between the Dynatrace problem and the Port microservice. Here is the updated JQ Mappings:

{
"blueprint": "dynatraceProblem",
"entity": {
...Properties mappings,
"relations": {
"microservice": ".body.ProblemTags | split(\", \") | map(select(test(\"proj:\")) | sub(\"proj:\";\"\"))"
}
}
}
Details

JQ expression explained The above JQ expression will split the tags by comma and space, then filter the tags that start with proj: and remove the proj: prefix from the tag value.

Create a webhook in Dynatrace

  1. Log in to Dynatrace with your credentials.
  2. Click on Settings at the left sidebar of the page.
  3. Choose Integration and click on Problem notifications.
  4. Select Add notification.
  5. Select Custom integration from the available integration types.
  6. Input the following details:
    1. Display name - use a meaningful name such as Port Webhook.

    2. Webhook URL - enter the value of the url key you received after creating the webhook configuration.

    3. Overview - you can add an optional HTTP header to your webhook request.

    4. Custom payload - When a problem is detected or resolved on your entity, this payload will be sent to the webhook URL. You can enter this JSON placeholder in the textbox:

      {
      "State":"{State}",
      "PID":"{PID}",
      "ProblemTitle":"{ProblemTitle}",
      "ImpactedEntity": "{ImpactedEntity}",
      "ProblemDetailsText": "{ProblemDetailsText}",
      "ProblemImpact": "{ProblemImpact}",
      "ProblemSeverity": "{ProblemSeverity}",
      "ProblemURL": "{ProblemURL}",
      "ProblemTags": "{ProblemTags}",
      "ImpactedEntities": {ImpactedEntities}
      }
    5. Alerting profile - configure your preferred alerting rule or use the default one.

  7. Click Save changes at the bottom of the page.
tip

To view the different payloads and events available in Dynatrace webhooks, look here.

Done! Any problem detected on your Dynatrace entity will trigger a webhook event. Port will parse the events according to the mapping and update the catalog entities accordingly.

Let's Test It

This section includes a sample response data from Dynatrace. In addition, it includes the entity created from the resync event based on the Ocean configuration provided in the previous section.

Payload

Here is an example of the payload structure from Dynatrace:

Problem response data
{
"affectedEntities": [
{
"entityId": {
"id": "string",
"type": "string"
},
"name": "string"
}
],
"displayId": "string",
"endTime": 1574697669865,
"entityTags": [
{
"context": "CONTEXTLESS",
"key": "architecture",
"stringRepresentation": "architecture:x86",
"value": "x86"
},
{
"context": "ENVIRONMENT",
"key": "Infrastructure",
"stringRepresentation": "[ENVIRONMENT]Infrastructure:Linux",
"value": "Linux"
}
],
"evidenceDetails": {
"details": [
{
"displayName": "Availability evidence",
"entity": {},
"evidenceType": "AVAILABILITY_EVIDENCE",
"groupingEntity": {},
"rootCauseRelevant": true,
"startTime": 1
},
{
"displayName": "User action evidence",
"entity": {},
"evidenceType": "USER_ACTION_EVIDENCE",
"groupingEntity": {},
"rootCauseRelevant": true,
"startTime": 1
}
],
"totalCount": 1
},
"impactAnalysis": {
"impacts": [
{
"estimatedAffectedUsers": 1,
"impactType": "APPLICATION",
"impactedEntity": {}
}
]
},
"impactLevel": "APPLICATION",
"impactedEntities": [{}],
"linkedProblemInfo": {
"displayId": "string",
"problemId": "string"
},
"managementZones": [
{
"id": "string",
"name": "HOST"
}
],
"problemFilters": [
{
"id": "E2A930951",
"name": "BASELINE"
}
],
"problemId": "06F288EE2A930951",
"recentComments": {
"comments": [
{
"authorName": "string",
"content": "string",
"context": "string",
"createdAtTimestamp": 1,
"id": "string"
}
],
"nextPageKey": "AQAAABQBAAAABQ==",
"pageSize": 1,
"totalCount": 1
},
"rootCauseEntity": {},
"severityLevel": "AVAILABILITY",
"startTime": 1574697667547,
"status": "CLOSED",
"title": "title"
}

Mapping Result

The combination of the sample payload and the Ocean configuration generates the following Port entity:

Problem entity in Port
{
"identifier": "06F288EE2A930951",
"title": "title",
"blueprint": "dynatraceProblem",
"team": [],
"icon": "Dynatrace",
"properties": {
"entityTags": ["architecture:x86", "[ENVIRONMENT]Infrastructure:Linux"],
"evidenceDetails": ["Availability evidence", "User action evidence"],
"managementZones": ["HOST"],
"problemFilters": ["BASELINE"],
"severityLevel": "AVAILABILITY",
"status": "CLOSED",
"startTime": "2019-11-25T14:14:27Z",
"endTime": "2020-04-30T14:52:41Z"
},
"relations": {
"impactedEntities": ["HOST-06F288EE2A930951"],
"linkedProblemInfo": "06F288EE2A930951",
"rootCauseEntity": "HOST-06F288EE2A930951"
},
"createdAt": "2024-2-6T09:30:57.924Z",
"createdBy": "hBx3VFZjqgLPEoQLp7POx5XaoB0cgsxW",
"updatedAt": "2024-2-6T11:49:20.881Z",
"updatedBy": "hBx3VFZjqgLPEoQLp7POx5XaoB0cgsxW"

}

Ingest Dynatrace Entities

In this example, you will create a dynatrace_entity blueprint that ingests monitored entities from your Dynatrace account. You will then add a Python script to make API calls to Dynatrace REST API and fetch data for your account.