Skip to content

Commit

Permalink
Round table rows in system status (#3883)
Browse files Browse the repository at this point in the history
* round table sizes in system status

* fix typing

* Use compact_number/compactNumber across the board

* Update compact_number docstring

Co-authored-by: Michael Matloka <dev@twixes.com>
  • Loading branch information
mariusandra and Twixes authored Apr 7, 2021
1 parent 864dd60 commit e068568
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 70 deletions.
8 changes: 4 additions & 4 deletions frontend/src/lib/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,10 @@ describe('compactNumber()', () => {
expect(compactNumber(10)).toEqual('10')
expect(compactNumber(293)).toEqual('293')
expect(compactNumber(5001)).toEqual('5K')
expect(compactNumber(5312)).toEqual('5.3K')
expect(compactNumber(5392)).toEqual('5.4K')
expect(compactNumber(2833102, 2)).toEqual('2.83M')
expect(compactNumber(8283310234)).toEqual('8.3B')
expect(compactNumber(5312)).toEqual('5.31K')
expect(compactNumber(5392)).toEqual('5.39K')
expect(compactNumber(2833102)).toEqual('2.83M')
expect(compactNumber(8283310234)).toEqual('8.28B')
})
})
describe('pluralize()', () => {
Expand Down
33 changes: 11 additions & 22 deletions frontend/src/lib/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -776,28 +776,17 @@ export function pluralize(count: number, singular: string, plural?: string, incl
return includeNumber ? `${count} ${form}` : form
}

function suffixFormatted(value: number, base: number, suffix: string, maxDecimals: number): string {
/* Helper function for compactNumber */
const multiplier = 10 ** maxDecimals
return `${Math.round((value * multiplier) / base) / multiplier}${suffix}`
}

export function compactNumber(value: number, maxDecimals: number = 1): string {
/*
Returns a number in a compact format with a thousands or millions suffix if applicable.
Server-side equivalent posthog_filters.py#compact_number
Example:
compactNumber(5500000)
=> "5.5M"
*/
if (value < 1000) {
return Math.floor(value).toString()
} else if (value < 1000000) {
return suffixFormatted(value, 1000, 'K', maxDecimals)
} else if (value < 1000000000) {
return suffixFormatted(value, 1000000, 'M', maxDecimals)
}
return suffixFormatted(value, 1000000000, 'B', maxDecimals)
/** Return a number in a compact format, with a SI suffix if applicable.
* Server-side equivalent: utils.py#compact_number.
*/
export function compactNumber(value: number): string {
value = parseFloat(value.toPrecision(3))
let magnitude = 0
while (Math.abs(value) >= 1000) {
magnitude++
value /= 1000
}
return value.toString() + ['', 'K', 'M', 'B', 'T', 'P', 'E', 'Z', 'Y'][magnitude]
}

export function sortedKeys(object: Record<string, any>): Record<string, any> {
Expand Down
28 changes: 3 additions & 25 deletions posthog/templatetags/posthog_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,13 @@

from django import template

from posthog.utils import compact_number

register = template.Library()

Number = Union[int, float]


@register.filter
def compact_number(value: Number, max_decimals: int = 1) -> str:
"""
Returns a number in a compact format with a thousands or millions suffix if applicable.
Client-side equivalent utils.tsx#compactNumber
Example:
{% compact_number 5500000 %}
=> "5.5M"
"""

def suffix_formatted(value: Number, base: float, suffix: str) -> str:
multiplier: int = 10 ** max_decimals
return f"{str(math.floor(value * multiplier / base) / multiplier).rstrip('0').rstrip('.')}{suffix}"

if value < 1000:
return str(math.floor(value))

if value < 1_000_000:
return suffix_formatted(value, 1_000.0, "K")

if value < 1_000_000_000:
return suffix_formatted(value, 1_000_000.0, "M")

return suffix_formatted(value, 1_000_000_000.0, "B")
register.filter(compact_number)


@register.filter
Expand Down
8 changes: 4 additions & 4 deletions posthog/test/test_templatetags.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ def test_utmify_email_url(self):

def test_compact_number(self):
self.assertEqual(compact_number(5001), "5K")
self.assertEqual(compact_number(5312), "5.3K")
self.assertEqual(compact_number(5392), "5.3K") # rounds down
self.assertEqual(compact_number(2833102, 2), "2.83M")
self.assertEqual(compact_number(8283310234), "8.2B")
self.assertEqual(compact_number(5312), "5.31K")
self.assertEqual(compact_number(5392), "5.39K")
self.assertEqual(compact_number(2833102), "2.83M")
self.assertEqual(compact_number(8283310234), "8.28B")

def test_percentage(self):
self.assertEqual(percentage(0.1829348, 2), "18.29%")
Expand Down
20 changes: 16 additions & 4 deletions posthog/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ def get_machine_id() -> str:
return hashlib.md5(uuid.getnode().to_bytes(6, "little")).hexdigest()


def get_table_size(table_name):
def get_table_size(table_name) -> str:
from django.db import connection

query = (
Expand All @@ -430,16 +430,28 @@ def get_table_size(table_name):
)
cursor = connection.cursor()
cursor.execute(query)
return dict_from_cursor_fetchall(cursor)
return dict_from_cursor_fetchall(cursor)[0]["size"]


def get_table_approx_count(table_name):
def get_table_approx_count(table_name) -> str:
from django.db import connection

query = f"SELECT reltuples::BIGINT as \"approx_count\" FROM pg_class WHERE relname = '{table_name}'"
cursor = connection.cursor()
cursor.execute(query)
return dict_from_cursor_fetchall(cursor)
return compact_number(dict_from_cursor_fetchall(cursor)[0]["approx_count"])


def compact_number(value: Union[int, float]) -> str:
"""Return a number in a compact format, with a SI suffix if applicable.
Client-side equivalent: utils.tsx#compactNumber.
"""
value = float("{:.3g}".format(value))
magnitude = 0
while abs(value) >= 1000:
magnitude += 1
value /= 1000.0
return "{:f}".format(value).rstrip("0").rstrip(".") + ["", "K", "M", "B", "T", "P", "E", "Z", "Y"][magnitude]


def is_postgres_alive() -> bool:
Expand Down
20 changes: 9 additions & 11 deletions posthog/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,27 +118,25 @@ def system_status(request):
"value": f"{postgres_version // 10000}.{(postgres_version // 100) % 100}.{postgres_version % 100}",
}
)
event_table_count = get_table_approx_count(Event._meta.db_table)[0]["approx_count"]
event_table_size = get_table_size(Event._meta.db_table)[0]["size"]
event_table_count = get_table_approx_count(Event._meta.db_table)
event_table_size = get_table_size(Event._meta.db_table)

element_table_count = get_table_approx_count(Element._meta.db_table)[0]["approx_count"]
element_table_size = get_table_size(Element._meta.db_table)[0]["size"]
element_table_count = get_table_approx_count(Element._meta.db_table)
element_table_size = get_table_size(Element._meta.db_table)

session_recording_event_table_count = get_table_approx_count(SessionRecordingEvent._meta.db_table)[0][
"approx_count"
]
session_recording_event_table_size = get_table_size(SessionRecordingEvent._meta.db_table)[0]["size"]
session_recording_event_table_count = get_table_approx_count(SessionRecordingEvent._meta.db_table)
session_recording_event_table_size = get_table_size(SessionRecordingEvent._meta.db_table)

metrics.append(
{"metric": "Postgres elements table size", "value": f"~{element_table_count} rows (~{element_table_size})"}
{"metric": "Postgres elements table size", "value": f"{element_table_count} rows (~{element_table_size})"}
)
metrics.append(
{"metric": "Postgres events table size", "value": f"~{event_table_count} rows (~{event_table_size})"}
{"metric": "Postgres events table size", "value": f"{event_table_count} rows (~{event_table_size})"}
)
metrics.append(
{
"metric": "Postgres session recording table size",
"value": f"~{session_recording_event_table_count} rows (~{session_recording_event_table_size})",
"value": f"{session_recording_event_table_count} rows (~{session_recording_event_table_size})",
}
)

Expand Down

0 comments on commit e068568

Please sign in to comment.