mirror of
https://github.com/lnbits/lnbits.git
synced 2025-08-02 23:12:34 +02:00
feat: better stats
This commit is contained in:
@@ -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(
|
||||||
|
@@ -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
|
||||||
);
|
);
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
@@ -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)
|
||||||
|
@@ -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>
|
||||||
|
@@ -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,
|
||||||
|
Reference in New Issue
Block a user