|
22 | 22 | Proposal,
|
23 | 23 | )
|
24 | 24 | from PIL import Image
|
| 25 | +from prometheus_client import Counter, Gauge |
25 | 26 | from pydantic import BaseModel
|
26 | 27 | from sqlalchemy import func
|
27 | 28 | from sqlalchemy.exc import OperationalError
|
|
50 | 51 | from murfey.server.api.spa import _cryolo_model_path
|
51 | 52 | from murfey.server.gain import Camera, prepare_eer_gain, prepare_gain
|
52 | 53 | from murfey.server.murfey_db import murfey_db
|
53 |
| -from murfey.util import secure_path |
| 54 | +from murfey.util import safe_run, secure_path |
54 | 55 | from murfey.util.config import MachineConfig, from_file, settings
|
55 | 56 | from murfey.util.db import (
|
56 | 57 | AutoProcProgram,
|
@@ -1616,33 +1617,59 @@ def remove_session_by_id(session_id: MurfeySessionID, db=murfey_db):
|
1616 | 1617 | sessions_for_visit = db.exec(
|
1617 | 1618 | select(Session).where(Session.visit == session.visit)
|
1618 | 1619 | ).all()
|
| 1620 | + # Don't remove prometheus metrics if there are other sessions using them |
1619 | 1621 | if len(sessions_for_visit) == 1:
|
1620 |
| - # Don't remove prometheus metrics if there are other sessions using them |
1621 |
| - try: |
1622 |
| - prom.monitoring_switch.remove(session.visit) |
1623 |
| - except KeyError: |
1624 |
| - pass |
| 1622 | + safe_run( |
| 1623 | + prom.monitoring_switch.remove, |
| 1624 | + args=(session.visit,), |
| 1625 | + label="monitoring_switch", |
| 1626 | + ) |
1625 | 1627 | rsync_instances = db.exec(
|
1626 | 1628 | select(RsyncInstance).where(RsyncInstance.session_id == session_id)
|
1627 | 1629 | ).all()
|
1628 | 1630 | for ri in rsync_instances:
|
1629 |
| - prom.seen_files.remove(ri.source, session.visit) |
1630 |
| - prom.transferred_files.remove(ri.source, session.visit) |
1631 |
| - prom.transferred_files_bytes.remove(ri.source, session.visit) |
1632 |
| - prom.seen_data_files.remove(ri.source, session.visit) |
1633 |
| - prom.transferred_data_files.remove(ri.source, session.visit) |
1634 |
| - prom.transferred_data_files_bytes.remove(ri.source, session.visit) |
| 1631 | + safe_run( |
| 1632 | + prom.seen_files.remove, |
| 1633 | + args=(ri.source, session.visit), |
| 1634 | + label="seen_files", |
| 1635 | + ) |
| 1636 | + safe_run( |
| 1637 | + prom.transferred_files.remove, |
| 1638 | + args=(ri.source, session.visit), |
| 1639 | + label="transferred_files", |
| 1640 | + ) |
| 1641 | + safe_run( |
| 1642 | + prom.transferred_files_bytes.remove, |
| 1643 | + args=(ri.source, session.visit), |
| 1644 | + label="transferred_files_bytes", |
| 1645 | + ) |
| 1646 | + safe_run( |
| 1647 | + prom.seen_data_files.remove, |
| 1648 | + args=(ri.source, session.visit), |
| 1649 | + label="seen_data_files", |
| 1650 | + ) |
| 1651 | + safe_run( |
| 1652 | + prom.transferred_data_files.remove, |
| 1653 | + args=(ri.source, session.visit), |
| 1654 | + label="transferred_data_files", |
| 1655 | + ) |
| 1656 | + safe_run( |
| 1657 | + prom.transferred_data_files_bytes.remove, |
| 1658 | + args=(ri.source, session.visit), |
| 1659 | + label="transferred_data_file_bytes", |
| 1660 | + ) |
1635 | 1661 | collected_ids = db.exec(
|
1636 | 1662 | select(DataCollectionGroup, DataCollection, ProcessingJob)
|
1637 | 1663 | .where(DataCollectionGroup.session_id == session_id)
|
1638 | 1664 | .where(DataCollection.dcg_id == DataCollectionGroup.id)
|
1639 | 1665 | .where(ProcessingJob.dc_id == DataCollection.id)
|
1640 | 1666 | ).all()
|
1641 | 1667 | for c in collected_ids:
|
1642 |
| - try: |
1643 |
| - prom.preprocessed_movies.remove(c[2].id) |
1644 |
| - except KeyError: |
1645 |
| - continue |
| 1668 | + safe_run( |
| 1669 | + prom.preprocessed_movies.remove, |
| 1670 | + args=(c[2].id,), |
| 1671 | + label="preprocessed_movies", |
| 1672 | + ) |
1646 | 1673 | db.delete(session)
|
1647 | 1674 | db.commit()
|
1648 | 1675 | return
|
@@ -1954,3 +1981,30 @@ def update_current_gain_ref(
|
1954 | 1981 | session.current_gain_ref = new_gain_ref.path
|
1955 | 1982 | db.add(session)
|
1956 | 1983 | db.commit()
|
| 1984 | + |
| 1985 | + |
| 1986 | +@router.get("/prometheus/{metric_name}") |
| 1987 | +def inspect_prometheus_metrics( |
| 1988 | + metric_name: str, |
| 1989 | +): |
| 1990 | + """ |
| 1991 | + A debugging endpoint that returns the current contents of any Prometheus |
| 1992 | + gauges and counters that have been set up thus far. |
| 1993 | + """ |
| 1994 | + |
| 1995 | + # Extract the Prometheus metric defined in the Prometheus module |
| 1996 | + metric: Optional[Counter | Gauge] = getattr(prom, metric_name, None) |
| 1997 | + if metric is None or not isinstance(metric, (Counter, Gauge)): |
| 1998 | + raise LookupError("No matching metric was found") |
| 1999 | + |
| 2000 | + # Package contents into dict and return |
| 2001 | + results = {} |
| 2002 | + if hasattr(metric, "_metrics"): |
| 2003 | + for i, (label_tuple, sub_metric) in enumerate(metric._metrics.items()): |
| 2004 | + labels = dict(zip(metric._labelnames, label_tuple)) |
| 2005 | + labels["value"] = sub_metric._value.get() |
| 2006 | + results[i] = labels |
| 2007 | + return results |
| 2008 | + else: |
| 2009 | + value = metric._value.get() |
| 2010 | + return {"value": value} |
0 commit comments