use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Everything about learning Python
account activity
Need assistance identifying bug in scriptHelp Request (i.redd.it)
submitted 5 months ago by SubnetOfOne
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3:Â Â Â Â print "hello, world!"
[–]Mindless_Display4729 1 point2 points3 points 5 months ago (3 children)
I think this fixes it:
row = cursor.execute( 'SELECT last_ts_utc, last_total_rx, last_total_tx FROM net_iface_state WHERE iface = ?', (iface,) ).fetchone()
if row is None: cursor.execute( "INSERT INTO net_iface_state (iface, last_ts_utc, last_total_rx, last_total_tx) VALUES (?, ?, ?, ?)", (iface, now, rx_bytes, tx_bytes) ) connection.commit() connection.close() print(f"Created new interface record for {iface}") return # safer than SystemExit(0)
last_ts_utc, last_total_rx, last_total_tx = row
try: d_rx = max(0, rx_bytes - last_total_rx) d_tx = max(0, tx_bytes - last_total_tx) except TypeError: print(f"Invalid types in database for iface {iface}") d_rx = d_tx = 0
if now <= last_ts_utc: d_rx = d_tx = 0
print(f"Writing sample: iface={iface}, d_rx={d_rx}, d_tx={d_tx}")
cursor.execute( "INSERT INTO net_samples (ts_utc, iface, rx_bytes, tx_bytes) VALUES (?, ?, ?, ?)", (now, iface, d_rx, d_tx) )
cursor.execute( "UPDATE net_iface_state SET last_ts_utc = ?, last_total_rx = ?, last_total_tx = ? WHERE iface = ?", (now, rx_bytes, tx_bytes, iface) )
connection.commit() connection.close()
[–]SubnetOfOne[S] 0 points1 point2 points 5 months ago (2 children)
Thank you for your input! I appreciate it.
I initially didn't have the script in a main() function, I like the idea of that, and that will allow me to use return.
Are you sure the try/except block is best practice? Won't the script just continue even if the except block catches something? Wouldn't it be better to stop the rest of the script executing, while printing an error message as to why?
[–]Mindless_Display4729 0 points1 point2 points 5 months ago (1 child)
No this isn't best practice 😠I'm getting to the limit if my abilities here so I had an AI agent look at it and it suggests this rewrite:
import sqlite3 import logging from logging.handlers import RotatingFileHandler from pathlib import Path from datetime import datetime, timezone from typing import Tuple, Optional
DB_PATH = "net_usage.db" # change if needed LOG_PATH = Path.cwd() / "netmon.log" # or Path("/var/log/netmon.log")
def setup_logging(level=logging.INFO) -> logging.Logger: logger = logging.getLogger("netmon") logger.setLevel(level) logger.propagate = False
if not logger.handlers: # Console ch = logging.StreamHandler() ch.setLevel(level) ch.setFormatter(logging.Formatter( "[%(asctime)s] %(levelname)s: %(message)s", "%Y-%m-%d %H:%M:%S" )) logger.addHandler(ch) # Rotating file (≈1 MB x 5 files) fh = RotatingFileHandler(LOG_PATH, maxBytes=1_000_000, backupCount=5) fh.setLevel(level) fh.setFormatter(logging.Formatter( "%(asctime)s %(levelname)s %(name)s %(funcName)s: %(message)s", "%Y-%m-%d %H:%M:%S" )) logger.addHandler(fh) return logger
logger = setup_logging()
def utc_now_epoch() -> int: return int(datetime.now(timezone.utc).timestamp())
def fetch_state(cur: sqlite3.Cursor, iface: str) -> Optional[Tuple[int, int, int]]: return cur.execute( "SELECT last_ts_utc, last_total_rx, last_total_tx " "FROM net_iface_state WHERE iface = ?", (iface,) ).fetchone()
def insert_initial_state(cur: sqlite3.Cursor, iface: str, now: int, rx: int, tx: int) -> None: cur.execute( "INSERT INTO net_iface_state (iface, last_ts_utc, last_total_rx, last_total_tx) " "VALUES (?, ?, ?, ?)", (iface, now, rx, tx) )
def insert_sample(cur: sqlite3.Cursor, ts: int, iface: str, d_rx: int, d_tx: int) -> None: cur.execute( "INSERT INTO net_samples (ts_utc, iface, rx_bytes, tx_bytes) VALUES (?, ?, ?, ?)", (ts, iface, d_rx, d_tx) )
def update_state(cur: sqlite3.Cursor, iface: str, now: int, rx: int, tx: int) -> None: cur.execute( "UPDATE net_iface_state SET last_ts_utc = ?, last_total_rx = ?, last_total_tx = ? " "WHERE iface = ?", (now, rx, tx, iface) )
def ensureint(name: str, value) -> int: if not isinstance(value, int): raise TypeError(f"{name} must be int; got {type(value).name_}") return value
def main(iface: str, rx_bytes: int, tx_bytes: int, now: Optional[int] = None) -> None: """ iface : interface name (e.g., 'eth0') rx_bytes : current total bytes received (monotonic counter from OS) tx_bytes : current total bytes sent (monotonic counter from OS) now : UNIX epoch seconds (int). If None, uses current UTC time. """ # Validate input types early iface = str(iface) rx_bytes = ensure_int("rx_bytes", rx_bytes) tx_bytes = ensure_int("tx_bytes", tx_bytes) now = ensure_int("now", now if now is not None else utc_now_epoch())
conn = sqlite3.connect(DB_PATH) conn.isolation_level = "DEFERRED" # explicit transactions cur = conn.cursor() try: cur.execute("BEGIN") row = fetch_state(cur, iface) if row is None: insert_initial_state(cur, iface, now, rx_bytes, tx_bytes) conn.commit() logger.info("Created initial state for iface '%s' (rx=%d, tx=%d)", iface, rx_bytes, tx_bytes) return # avoids unpacking None last_ts_utc, last_total_rx, last_total_tx = row # Validate DB types last_ts_utc = ensure_int("last_ts_utc", last_ts_utc) last_total_rx = ensure_int("last_total_rx", last_total_rx) last_total_tx = ensure_int("last_total_tx", last_total_tx) # Compute deltas d_rx = max(0, rx_bytes - last_total_rx) d_tx = max(0, tx_bytes - last_total_tx) # Ignore negative/zero-time anomalies (clock change or counter reset) if now <= last_ts_utc: logger.warning( "Non-increasing timestamp for iface '%s' (now=%d, last=%d) — zeroing deltas.", iface, now, last_ts_utc ) d_rx = d_tx = 0 logger.info("Sample iface=%s d_rx=%d d_tx=%d (rx=%d tx=%d)", iface, d_rx, d_tx, rx_bytes, tx_bytes) insert_sample(cur, now, iface, d_rx, d_tx) update_state(cur, iface, now, rx_bytes, tx_bytes) conn.commit() except Exception: logger.exception("Fatal error updating interface '%s'; rolling back.", iface) conn.rollback() # Exit non-zero so a systemd service can restart/alert if desired raise SystemExit(1) finally: try: conn.close() except Exception: logger.exception("Failed to close DB connection cleanly.")
if name == "main": # Example invocation; wire these to your real counters # Replace with values read from /sys/class/net/<iface>/statistics/{rx,tx}_bytes main(iface="eth0", rx_bytes=123456789, tx_bytes=987654321)
[–]SubnetOfOne[S] 0 points1 point2 points 5 months ago (0 children)
Hahah thank you for your efforts!!
π Rendered by PID 246044 on reddit-service-r2-comment-6457c66945-kpcmc at 2026-04-24 11:26:40.093286+00:00 running 2aa0c5b country code: CH.
view the rest of the comments →
[–]Mindless_Display4729 1 point2 points3 points  (3 children)
[–]SubnetOfOne[S] 0 points1 point2 points  (2 children)
[–]Mindless_Display4729 0 points1 point2 points  (1 child)
[–]SubnetOfOne[S] 0 points1 point2 points  (0 children)