Skip to content

Commit

Permalink
feat: rename apdex to tpdex where references subsist, implement G tpd…
Browse files Browse the repository at this point in the history
…ex on network error
  • Loading branch information
hartym committed Jun 14, 2024
1 parent 9a59a6e commit 170e5b6
Show file tree
Hide file tree
Showing 24 changed files with 86 additions and 55 deletions.
4 changes: 2 additions & 2 deletions harp/models/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ class Transaction(Entity):
elapsed: float = None
"""Elapsed time in seconds, if the transaction has ended."""

apdex: int = None
"""Apdex score, if the transaction has ended."""
tpdex: int = None
"""TPDEX score, if the transaction has ended."""

# Relations

Expand Down
16 changes: 8 additions & 8 deletions harp_apps/dashboard/controllers/overview.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,17 @@ async def get_summary_data(self, request: HttpRequest):
start_datetime=start_datetime,
)
try:
mean_apdex = mean(filter(None, [t["meanApdex"] for t in transactions_by_date_list]))
mean_tpdex = mean(filter(None, [t["meanTpdex"] for t in transactions_by_date_list]))
except StatisticsError:
mean_apdex = 100
mean_tpdex = 100

return json(
{
"apdex": {
"mean": int(mean_apdex),
"tpdex": {
"mean": int(mean_tpdex),
"data": [
{
"value": int(t["meanApdex"]) if t["meanApdex"] is not None else 100,
"value": int(t["meanTpdex"]) if t["meanTpdex"] is not None else 100,
}
for t in transactions_by_date_list
],
Expand Down Expand Up @@ -120,17 +120,17 @@ async def get_overview_data(self, request: HttpRequest):
)

try:
mean_apdex = mean(filter(None, [t["meanApdex"] for t in transactions_by_date_list]))
mean_tpdex = mean(filter(None, [t["meanTpdex"] for t in transactions_by_date_list]))
except StatisticsError:
mean_apdex = 100
mean_tpdex = 100

return json(
{
"transactions": transactions_by_date_list,
"errors": {"count": errors_count, "rate": errors_rate},
"count": transactions_count,
"meanDuration": mean_duration,
"meanApdex": mean_apdex,
"meanTpdex": mean_tpdex,
"timeRange": range,
}
)
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { classNames } from "ui/Utilities"

import { StyledJumboBadge, StyledJumboBadgeProps } from "./StyledJumboBadge.tsx"
import { apdexScale } from "./constants.ts"
import { tpdexScale } from "./constants.ts"

export default function ApdexBadge({
export default function TpdexBadge({
score,
className = undefined,
...styledProps
Expand All @@ -12,7 +12,7 @@ export default function ApdexBadge({
return null
}

for (const rating of apdexScale) {
for (const rating of tpdexScale) {
if (rating.threshold === undefined || score >= rating.threshold) {
return (
<StyledJumboBadge
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const apdexScale: { label: string; threshold?: number; className: string }[] = [
export const tpdexScale: { label: string; threshold?: number; className: string }[] = [
{ label: "A++", threshold: 98, className: "bg-teal-400" },
{ label: "A+", threshold: 96, className: "bg-emerald-400" },
{ label: "A", threshold: 93, className: "bg-green-500" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useQuery } from "react-query"
import { useApi } from "Domain/Api"

export interface SummaryData {
apdex: { mean: number; data: { value: number }[] }
tpdex: { mean: number; data: { value: number }[] }
transactions: { rate: number; period: string; data: { value: number }[] }
errors: { rate: number; period: string; data: { value: number }[] }
}
Expand Down
2 changes: 1 addition & 1 deletion harp_apps/dashboard/frontend/src/Models/Overview.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ export interface OverviewData extends OverviewTransactionsReport {
}
count: number
meanDuration: number
meanApdex: number
meanTpdex: number
timeRange: string
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"elapsed": {
"type": "number"
},
"apdex": {
"tpdex": {
"type": "integer"
},
"messages": {
Expand All @@ -40,7 +40,7 @@
"default": {}
}
},
"description": "Transaction(*, id: str = None, type: str, endpoint: str = None, started_at: datetime.datetime, finished_at: datetime.datetime = None, elapsed: float = None, apdex: int = None, messages: List[harp.models.messages.Message] = None, tags: dict = <factory>, extras: dict = <factory>)",
"description": "Transaction(*, id: str = None, type: str, endpoint: str = None, started_at: datetime.datetime, finished_at: datetime.datetime = None, elapsed: float = None, tpdex: int = None, messages: List[harp.models.messages.Message] = None, tags: dict = <factory>, extras: dict = <factory>)",
"$schema": "http://json-schema.org/draft-06/schema#",
"definitions": {
"Message": {
Expand Down
4 changes: 2 additions & 2 deletions harp_apps/dashboard/frontend/src/Models/Transaction.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

/**
* Transaction(*, id: str = None, type: str, endpoint: str = None, started_at: datetime.datetime, finished_at: datetime.datetime = None, elapsed: float = None, apdex: int = None, messages: List[harp.models.messages.Message] = None, tags: dict = <factory>, extras: dict = <factory>)
* Transaction(*, id: str = None, type: str, endpoint: str = None, started_at: datetime.datetime, finished_at: datetime.datetime = None, elapsed: float = None, tpdex: int = None, messages: List[harp.models.messages.Message] = None, tags: dict = <factory>, extras: dict = <factory>)
*/
export interface Transaction {
id?: string
Expand All @@ -15,7 +15,7 @@ export interface Transaction {
started_at: string
finished_at?: string
elapsed?: number
apdex?: number
tpdex?: number
messages?: Message[]
tags?: {
[k: string]: unknown
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
it("renders without crashing", () => {
const data: TransactionsHistoryOnQuerySuccessProps["data"] = {
meanDuration: 2000,
meanApdex: 85,
meanTpdex: 85,
errors: { count: 2, rate: 0.05 },
transactions: [],
timeRange: "month",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import ApdexBadge from "Components/Badges/ApdexBadge.tsx"
import TpdexBadge from "Components/Badges/TpdexBadge.tsx"
import { OverviewData } from "Models/Overview"
import { H3 } from "ui/Components/Typography"

Expand All @@ -16,15 +16,15 @@ export const TransactionsHistoryOnQuerySuccess = ({
className,
}: TransactionsHistoryOnQuerySuccessProps) => {
const meanDurationSeconds = Math.trunc(data.meanDuration) / 1000
const meanApdex = Math.trunc(data.meanApdex)
const meanTpdex = Math.trunc(data.meanTpdex)
const errorsRate = Math.trunc(data.errors.rate * 100)
return (
<div className={className}>
<H3>{title}</H3>
<div style={{ display: "flex", alignItems: "center" }}>
<div className="flex flex-col items-center">
<div className="flex self-center">
<ApdexBadge score={meanApdex} size="xl" />
<TpdexBadge score={meanTpdex} size="xl" />
</div>
<div className="grid grid-cols-2 text-xs text-left align-text-bottom items-center self-center ml-10 mt-10">
<span className="font-bold">Mean duration:</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { ArrowTopRightOnSquareIcon } from "@heroicons/react/24/outline"
import { Link } from "react-router-dom"
import tw, { styled } from "twin.macro"

import ApdexBadge from "Components/Badges/ApdexBadge.tsx"
import { StyledJumboBadge } from "Components/Badges/StyledJumboBadge.tsx"
import TpdexBadge from "Components/Badges/TpdexBadge.tsx"
import { OnQuerySuccess } from "Components/Utilities/OnQuerySuccess.tsx"
import { useSummaryDataQuery } from "Domain/Overview/useSummaryDataQuery.tsx"
import { Pane } from "ui/Components/Pane"
Expand Down Expand Up @@ -43,9 +43,9 @@ export const SummarySection = () => {
</div>
<OnQuerySuccess query={summaryQuery}>
{(query) => (
<SparklineChart data={mapGetValues(query.data.apdex.data)} color="#ADD8E6">
<SparklineChart data={mapGetValues(query.data.tpdex.data)} color="#ADD8E6">
<div className="flex self-center relative z-10">
<ApdexBadge score={query.data.apdex.mean} size="xl" className="ring-1 ring-white" />
<TpdexBadge score={query.data.tpdex.mean} size="xl" className="ring-1 ring-white" />
</div>
</SparklineChart>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { XMarkIcon } from "@heroicons/react/16/solid"
import { CircleStackIcon } from "@heroicons/react/24/outline"
import { formatDuration } from "date-fns"

import ApdexBadge from "Components/Badges/ApdexBadge"
import TpdexBadge from "Components/Badges/TpdexBadge.tsx"
import { classNames } from "ui/Utilities"

export function NoCacheIcon() {
Expand All @@ -16,14 +16,14 @@ export function NoCacheIcon() {

export const Duration = ({
duration,
apdex,
tpdex,
cached = false,
noCache = false,
verbose = false,
className = undefined,
}: {
duration: number | null
apdex: number | null
tpdex: number | null
cached?: boolean
noCache?: boolean
verbose?: boolean
Expand All @@ -32,7 +32,7 @@ export const Duration = ({
if (duration !== null) {
return (
<div className={classNames("flex gap-x-0.5 items-center font-normal", className)}>
{apdex !== null ? <ApdexBadge score={apdex} /> : null}
{tpdex !== null ? <TpdexBadge score={tpdex} /> : null}
<span>{formatDuration({ seconds: duration })}</span>
{cached ? (
<span className="h-4 flex text-xs text-slate-800" title="Response was cached.">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,12 @@ const transactionColumnTypes = {
label: "Duration",
get: (row: Transaction) => [
row.elapsed ? Math.trunc(row.elapsed) / 1000 : null,
row.apdex,
row.tpdex,
!!row.extras?.cached,
!!row.extras?.no_cache,
],
format: ([duration, apdex, cached, noCache]: [number | null, number | null, boolean, boolean]) => (
<Duration duration={duration} apdex={apdex} cached={cached} noCache={noCache} />
format: ([duration, tpdex, cached, noCache]: [number | null, number | null, boolean, boolean]) => (
<Duration duration={duration} tpdex={tpdex} cached={cached} noCache={noCache} />
),
},
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useLocation, useNavigate, useSearchParams } from "react-router-dom"

import { apdexScale } from "Components/Badges/constants"
import { tpdexScale } from "Components/Badges/constants"
import { useTransactionsFiltersQuery } from "Domain/Transactions"
import { ArrayFilter, Filters, MinMaxFilter } from "Types/filters"
import { Pane } from "ui/Components/Pane"
Expand All @@ -19,12 +19,12 @@ export function FiltersSidebar({ filters }: FiltersSidebarProps) {
const filtersQuery = useTransactionsFiltersQuery()

// marks and setup for range slider for tpdex
const marks = [...apdexScale].map((rating, index) => ({
const marks = [...tpdexScale].map((rating, index) => ({
value: index * 10,
label: rating.label,
className: rating.className,
}))
const markValueToThreshold = new Map([...apdexScale].map((rating, index) => [index * 10, rating.threshold]))
const markValueToThreshold = new Map([...tpdexScale].map((rating, index) => [index * 10, rating.threshold]))
const maxKey = Math.max(...Array.from(markValueToThreshold.keys()))
const minKey = Math.min(...Array.from(markValueToThreshold.keys()))
markValueToThreshold.set(maxKey, undefined)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ function Tags({ tags }: { tags: [string, string] }) {

export function TransactionDetailOnQuerySuccess({ query }: { query: QueryObserverSuccessResult<Transaction> }) {
const transaction = query.data
const [duration, apdex, cached, noCache] = [
const [duration, tpdex, cached, noCache] = [
transaction.elapsed ? Math.trunc(transaction.elapsed) / 1000 : null,
transaction.apdex ?? null,
transaction.tpdex ?? null,
!!transaction.extras?.cached,
!!transaction.extras?.no_cache,
]
Expand All @@ -42,7 +42,7 @@ export function TransactionDetailOnQuerySuccess({ query }: { query: QueryObserve
<span className="grow">Transaction</span>
<Duration
duration={duration}
apdex={apdex}
tpdex={tpdex}
cached={cached}
noCache={noCache}
verbose
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const mockOverviewData: OverviewData = {
},
count: 20,
meanDuration: 30,
meanApdex: 95,
meanTpdex: 95,
timeRange: "1h",
transactions: [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { http, HttpResponse } from "msw"
import { SummaryData } from "Domain/Overview/useSummaryDataQuery.tsx"

const mockSummaryData: SummaryData = {
apdex: {
tpdex: {
mean: 100,
data: [...Array(24).keys()].map((i) => ({
value: 100 - ((i * i * 97) % 20),
Expand Down
6 changes: 3 additions & 3 deletions harp_apps/dashboard/tests/test_controllers_overview.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ async def test_get_summary_data_no_transactions(self, controller: OverviewContro
with freezegun.freeze_time(now):
response = await controller.get_summary_data(request)
assert response == {
"apdex": {"data": Any24IntegerValues, "mean": 100},
"tpdex": {"data": Any24IntegerValues, "mean": 100},
"errors": {"data": Any24IntegerValues, "period": "day", "rate": 0},
"transactions": {"data": Any24IntegerValues, "period": "day", "rate": 0},
}
Expand All @@ -68,7 +68,7 @@ async def test_get_summary_data_with_a_few_transactions(
with freezegun.freeze_time(now):
response = await controller.get_summary_data(request)
assert response == {
"apdex": {"data": Any24IntegerValues, "mean": 100},
"tpdex": {"data": Any24IntegerValues, "mean": 100},
"errors": {"data": Any24IntegerValues, "period": "day", "rate": 0},
"transactions": {"data": Any24IntegerValues, "period": "day", "rate": 3},
}
Expand All @@ -94,7 +94,7 @@ async def test_get_summary_data_with_a_few_transactions_using_asgi(
assert response["headers"] == ((b"content-type", b"application/json"),)

assert orjson.loads(response["body"]) == {
"apdex": {"data": Any24IntegerValues, "mean": 100},
"tpdex": {"data": Any24IntegerValues, "mean": 100},
"errors": {"data": Any24IntegerValues, "period": "day", "rate": "0"},
"transactions": {"data": Any24IntegerValues, "period": "day", "rate": "3"},
}
2 changes: 1 addition & 1 deletion harp_apps/dashboard/utils/dates.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,6 @@ def generate_continuous_time_range(
continuous_transactions.append([d for d in discontinuous_transactions if d["datetime"] == t][0])
else:
continuous_transactions.append(
{"datetime": t, "count": None, "errors": None, "meanDuration": None, "meanApdex": None}
{"datetime": t, "count": None, "errors": None, "meanDuration": None, "meanTpdex": None}
)
return continuous_transactions
6 changes: 6 additions & 0 deletions harp_apps/proxy/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from harp.http.requests import WrappedHttpRequest
from harp.models import Transaction
from harp.utils.guids import generate_transaction_id_ksuid
from harp.utils.tpdex import tpdex

from .events import EVENT_TRANSACTION_ENDED, EVENT_TRANSACTION_MESSAGE, EVENT_TRANSACTION_STARTED

Expand Down Expand Up @@ -150,6 +151,11 @@ async def end_transaction(self, transaction, response: BaseHttpMessage):
else:
raise ValueError(f"Invalid final message type: {type(response)}")

if transaction.extras.get("status_class") == "ERR":
transaction.tpdex = 0
else:
transaction.tpdex = tpdex(transaction.elapsed)

# dispatch message event for response
# TODO delay after response is sent ?
await self.adispatch(EVENT_TRANSACTION_MESSAGE, MessageEvent(transaction, response))
Expand Down
4 changes: 2 additions & 2 deletions harp_apps/proxy/tests/test_controllers_http_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ async def test_basic_get(self, storage: SqlAlchemyStorage):
"type": "http",
"endpoint": None,
"elapsed": ANY,
"apdex": ANY,
"tpdex": ANY,
"started_at": ANY,
"finished_at": ANY,
"messages": ANY,
Expand Down Expand Up @@ -170,7 +170,7 @@ async def test_get_with_tags(self, storage):
"type": "http",
"endpoint": None,
"elapsed": ANY,
"apdex": ANY,
"tpdex": ANY,
"started_at": ANY,
"finished_at": ANY,
"messages": ANY,
Expand Down
Loading

0 comments on commit 170e5b6

Please sign in to comment.