Append debug message to log file with timestamp.
(message)
| 27 | |
| 28 | |
| 29 | def debug_log(message): |
| 30 | """Append debug message to log file with timestamp.""" |
| 31 | try: |
| 32 | # Ensure parent dir exists — first hook invocation on a fresh install |
| 33 | # creates ~/.claude/security/ if it isn't already there. 0700 so other |
| 34 | # local users can't read review/debug output (only applies on creation). |
| 35 | try: |
| 36 | os.makedirs(os.path.dirname(DEBUG_LOG_FILE), mode=0o700, exist_ok=True) |
| 37 | except OSError: |
| 38 | pass |
| 39 | try: |
| 40 | if os.path.getsize(DEBUG_LOG_FILE) > DEBUG_LOG_MAX_BYTES: |
| 41 | # os.replace is atomic on POSIX; under a racing fleet the loser |
| 42 | # gets FileNotFoundError, which is fine — the append below |
| 43 | # recreates the file. |
| 44 | os.replace(DEBUG_LOG_FILE, DEBUG_LOG_FILE + ".1") |
| 45 | except OSError: |
| 46 | pass |
| 47 | timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3] |
| 48 | # 0600 on creation; existing files keep their mode. |
| 49 | fd = os.open(DEBUG_LOG_FILE, os.O_WRONLY | os.O_CREAT | os.O_APPEND, 0o600) |
| 50 | with os.fdopen(fd, "a") as f: |
| 51 | f.write(f"[{timestamp}] {message}\n") |
| 52 | except Exception: |
| 53 | pass |
| 54 | |
| 55 | |
| 56 | # Provenance tag prepended to injected/emitted text so a reader (especially a |
no outgoing calls
no test coverage detected