Dynatrace Managed Q&A
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Looking to upgrade from Dynatrace Managed to SaaS? See how

Problem duration metric sorted by longest duration

Khejazi
Guide

Hi all,

 

I want to create tile in dynatrace managed dashboard to show top list of problems with longest duration in a specitic time of period sorted descendingly

 

Any support how to do this? 

 

I tried to filter problems and sorted by duration and then pin to dashboard, but it is showing me a single value and i cannot configure it in Data Explorer.

9 REPLIES 9

ChadTurner
DynaMight Legend
DynaMight Legend

If you are using the Gen1/2 Problem page and you save the tile, it will only save filter constructs and time frames, not sorting preferences on the table view. Additionally the tile will only show you a problem count. If you want a table version say a top 10 list, you will need to do this in the Gen3 UI with the new problems page: 

ChadTurner_0-1787058514572.png

Granted this is in a Scatter plot but you can put it into a table format, or even a record format. 





-Chad

Unfortunately, i am using Dynatrace managed where I cannot write DQL , so I was playing with the metrics but could not reach to a solution

 

@Khejazi Managed does not have any built-in metrics related to problems. You cannot create metric on problem data directly in Managed. You can only do that externally by fetching the data using Problem V2 API and sending a metric data. For example, by an ActiveGate extension. 

Dynatrace Ambassador | Alanata a.s., Slovakia, Dynatrace Master Partner

Well,

Can you guide me how to do that if you please

Hi @Khejazi ,

Quick and dirty approach (Sorry, vibecoded due to time pressure), you need to install the python modules requests and dynatrace-metric-utils.

#!/usr/bin/env python3
"""Fetch open problems from Dynatrace Problems v2 API, print them, and push duration as metric.ingest."""

import os
import sys
from datetime import datetime, timezone

import requests
from dynatrace.metric.utils import DynatraceMetricsFactory, DynatraceMetricsSerializer, MetricError

DT_ENVIRONMENT = os.environ.get("DT_ENVIRONMENT")  # e.g. https://abc12345.live.dynatrace.com
DT_APITOKEN = os.environ.get("DT_APITOKEN")

METRIC_KEY = "problems.active"

factory = DynatraceMetricsFactory()
serializer = DynatraceMetricsSerializer()


def duration_seconds(start_ms, end_ms):
    end_ms = end_ms if end_ms and end_ms > 0 else int(datetime.now(timezone.utc).timestamp() * 1000)
    return (end_ms - start_ms) // 1000


def format_duration(seconds):
    hours, remainder = divmod(seconds, 3600)
    minutes, seconds = divmod(remainder, 60)
    return f"{hours}h {minutes}m"


def get_open_problems():
    if not DT_ENVIRONMENT or not DT_APITOKEN:
        sys.exit("Set DT_ENVIRONMENT and DT_APITOKEN environment variables.")

    url = f"{DT_ENVIRONMENT.rstrip('/')}/api/v2/problems"
    headers = {"Authorization": f"Api-Token {DT_APITOKEN}"}
    params = {
        "problemSelector": 'status("open")',
        "fields": "impactLevel,severityLevel",
    }

    problems = []
    while True:
        resp = requests.get(url, headers=headers, params=params, timeout=30)
        resp.raise_for_status()
        data = resp.json()
        problems.extend(data.get("problems", []))

        next_page_key = data.get("nextPageKey")
        if not next_page_key:
            break
        params = {"nextPageKey": next_page_key}

    return problems


def build_metric_line(problem, seconds):
    dimensions = {
        "problemId": problem["problemId"],
        "displayId": problem.get("displayId", "N/A"),
        "title": problem.get("title", "N/A"),
    }
    metric = factory.create_int_gauge(METRIC_KEY, seconds, dimensions)
    return serializer.serialize(metric)


def ingest_metrics(lines):
    url = f"{DT_ENVIRONMENT.rstrip('/')}/api/v2/metrics/ingest"
    headers = {
        "Authorization": f"Api-Token {DT_APITOKEN}",
        "Content-Type": "text/plain; charset=utf-8",
    }
    resp = requests.post(url, headers=headers, data="\n".join(lines), timeout=30)
    resp.raise_for_status()
    return resp.json()


def main():
    problems = get_open_problems()

    if not problems:
        print("No open problems.")
        return

    lines = []
    for p in problems:
        seconds = duration_seconds(p["startTime"], p.get("endTime", -1))
        print(
            f"{p['problemId']}\t"
            f"{p.get('severityLevel', 'N/A')}\t"
            f"{p.get('impactLevel', 'N/A')}\t"
            f"{p.get('title', 'N/A')}\t"
            f"{format_duration(seconds)}"
        )
        try:
            lines.append(build_metric_line(p, seconds))
        except MetricError as e:
            print(f"  skipped metric for {p['problemId']}: {e}")

    result = ingest_metrics(lines)
    print(f"Ingested: {result.get('linesOk', 0)} ok, {result.get('linesInvalid', 0)} invalid")

if __name__ == "__main__":
    main()



Julius_Loman_0-1787641928935.png

 

Dynatrace Ambassador | Alanata a.s., Slovakia, Dynatrace Master Partner

This would indeed be the only way -- to ingest the problems as a metric, as there isn’t currently a metric for this in Managed.

You could use the Problem ID and optionally the title as dimensions and then build your dashboard tile based on that.

Just keep in mind that this will come with a certain DDU cost, as each problem will generate a data points that consumes some of your DDU's.

Well,

I think then it would not be the best way to implement it as it will consume the DDU in some time as 

Thanks for both of you @Julius_Loman  & @dylan_taelemans for your contribution

@Khejazi there is no other way of doing that in Managed when you need the data to be displayed on a Dynatrace dashboard. 

Dynatrace Ambassador | Alanata a.s., Slovakia, Dynatrace Master Partner

Khejazi
Guide

Still looking for a solution here please

Featured Posts