feat: better stats

This commit is contained in:
Vlad Stan
2024-11-26 11:48:08 +02:00
parent e0d40b96a1
commit d948a1cc77
5 changed files with 24 additions and 63 deletions

View File

@@ -29,11 +29,6 @@ async def get_audit_entries(
async def delete_expired_audit_entries( async def delete_expired_audit_entries(
conn: Optional[Connection] = None, conn: Optional[Connection] = None,
): ):
q = f"""
DELETE from audit
WHERE delete_at < {db.timestamp_now}
"""
print("### q", q)
await (conn or db).execute( await (conn or db).execute(
f""" f"""
DELETE from audit DELETE from audit
@@ -42,70 +37,29 @@ async def delete_expired_audit_entries(
) )
async def get_request_method_stats( async def get_count_stats(
field: str,
filters: Optional[Filters[AuditFilters]] = None, filters: Optional[Filters[AuditFilters]] = None,
conn: Optional[Connection] = None, conn: Optional[Connection] = None,
) -> list[AuditCountStat]: ) -> list[AuditCountStat]:
if field not in ["request_method", "component", "response_code"]:
return []
if not filters: if not filters:
filters = Filters() filters = Filters()
clause = filters.where() clause = filters.where()
request_methods = await (conn or db).fetchall( data = await (conn or db).fetchall(
query=f""" query=f"""
SELECT request_method as field, count(request_method) as total SELECT {field} as field, count({field}) as total
FROM audit FROM audit
{clause} {clause}
GROUP BY request_method GROUP BY {field}
ORDER BY request_method ORDER BY {field}
""", """,
values=filters.values(), values=filters.values(),
model=AuditCountStat, model=AuditCountStat,
) )
return request_methods return data
async def get_component_stats(
filters: Optional[Filters[AuditFilters]] = None,
conn: Optional[Connection] = None,
) -> list[AuditCountStat]:
if not filters:
filters = Filters()
clause = filters.where()
components = await (conn or db).fetchall(
query=f"""
SELECT component as field, count(component) as total
FROM audit
{clause}
GROUP BY component
ORDER BY component
""",
values=filters.values(),
model=AuditCountStat,
)
return components
async def get_response_codes_stats(
filters: Optional[Filters[AuditFilters]] = None,
conn: Optional[Connection] = None,
) -> list[AuditCountStat]:
if not filters:
filters = Filters()
clause = filters.where()
request_methods = await (conn or db).fetchall(
query=f"""
SELECT response_code as field, count(response_code) as total
FROM audit
{clause}
GROUP BY response_code
ORDER BY response_code
""",
values=filters.values(),
model=AuditCountStat,
)
return request_methods
async def get_long_duration_stats( async def get_long_duration_stats(

View File

@@ -681,7 +681,8 @@ async def m029_create_audit_table(db):
response_code TEXT, response_code TEXT,
duration REAL NOT NULL, duration REAL NOT NULL,
delete_at TIMESTAMP, delete_at TIMESTAMP,
created_at TIMESTAMP NOT NULL DEFAULT {db.timestamp_now} created_at TIMESTAMP NOT NULL DEFAULT {db.timestamp_now},
created_at_minute INT NOT NULL
); );
""" """
) )

View File

@@ -22,6 +22,9 @@ class AuditEntry(BaseModel):
duration: float duration: float
delete_at: Optional[datetime] = None delete_at: Optional[datetime] = None
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
created_at_minute: int = Field(
default_factory=lambda: int(datetime.now(timezone.utc).timestamp() / 60)
)
def __init__(self, **data): def __init__(self, **data):
super().__init__(**data) super().__init__(**data)

View File

@@ -124,7 +124,12 @@
<span v-text="props.row[col.name]"></span> <span v-text="props.row[col.name]"></span>
</q-tooltip> </q-tooltip>
</div> </div>
<span v-else v-text="props.row[col.name]"></span> <span
v-else
v-text="props.row[col.name]"
@click="searchAuditBy(col.name, props.row[col.name])"
class="cursor-pointer"
></span>
</q-td> </q-td>
</q-tr> </q-tr>
</template> </template>

View File

@@ -2,10 +2,8 @@ from fastapi import APIRouter, Depends
from lnbits.core.crud.audit import ( from lnbits.core.crud.audit import (
get_audit_entries, get_audit_entries,
get_component_stats, get_count_stats,
get_long_duration_stats, get_long_duration_stats,
get_request_method_stats,
get_response_codes_stats,
) )
from lnbits.core.models import AuditEntry, AuditFilters from lnbits.core.models import AuditEntry, AuditFilters
from lnbits.core.models.audit import AuditStats from lnbits.core.models.audit import AuditStats
@@ -39,9 +37,9 @@ async def api_get_audit(
async def api_get_audit_stats( async def api_get_audit_stats(
filters: Filters = Depends(parse_filters(AuditFilters)), filters: Filters = Depends(parse_filters(AuditFilters)),
) -> AuditStats: ) -> AuditStats:
request_mothod_stats = await get_request_method_stats(filters) request_mothod_stats = await get_count_stats("request_method", filters)
response_code_stats = await get_response_codes_stats(filters) response_code_stats = await get_count_stats("response_code", filters)
components_stats = await get_component_stats(filters) components_stats = await get_count_stats("component", filters)
long_duration_stats = await get_long_duration_stats(filters) long_duration_stats = await get_long_duration_stats(filters)
return AuditStats( return AuditStats(
request_method=request_mothod_stats, request_method=request_mothod_stats,