James Hefford

14 papers A* 1B 1Journal 6Unranked 6
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
Matthew Wilson, James Hefford, Timothée Hoffreumon
2025 J jnl
CoRR
James Hefford, Matthew Wilson
2024 A* conf
LICS
James Hefford, Matthew Wilson
2024 J jnl
CoRR
James Hefford, Matthew Wilson
2024 B conf
CSL
Matt Earnshaw, James Hefford, Mario Román
2023 conf
ACT
James Hefford, Mario Román
2023 J jnl
CoRR
Matt Earnshaw, James Hefford, Mario Román
2022 conf
ACT
James Hefford, Cole Comfort
2022 conf
ACT
James Hefford, Aleks Kissinger
2021 conf
QPL
James Hefford, Stefano Gogioso
2021 J jnl
Quantum
Oscar Higgott, Matthew Wilson, James Hefford, James Dborin, Farhan Hanif, Simon Burton, Dan E. Browne
2020 J jnl
CoRR
James Hefford, Vincent Wang, Matthew Wilson
2020 conf
QPL
James Hefford, Stefano Gogioso
2020 conf
ACT
Matthew Wilson, James Hefford, Guillaume Boisseau, Vincent Wang
redb/logging_utils.py
← Index redb/logging_utils.py python
"""
Logging utilities and shared enums for REDB.

Contains the ImportResult enum, log formatters, and logger setup functions
used across the ingestor pipeline.
"""
import logging
from logging.handlers import QueueHandler
import os
from enum import Enum


class ImportResult(Enum):
    CORRECTLY = 0
    PARTIALLY = 1
    FAILED = 2
    PENDING = 3
    SKIPPED = 4


class FileNameFormatter(logging.Formatter):
    def format(self, record):
        record.filenameinfo = getattr(record, "filenameinfo", "unknown")
        return super().format(record)


def setup_logger(log_queue, filename):
    logger = logging.getLogger(filename)
    if not logger.handlers:
        if os.getenv("SERVER_ENV") == "prod":
            logger.setLevel(logging.INFO)
        else:
            logger.setLevel(logging.DEBUG)
        handler = QueueHandler(log_queue)
        logger.addHandler(handler)
        logger.propagate = False  # Prevent propagation to parent loggers
    return logger


def logger_thread(log_queue, log_file):
    handler = logging.FileHandler(log_file)
    formatter = FileNameFormatter(
        "%(asctime)s - %(filenameinfo)s - %(levelname)s - %(message)s"
    )
    handler.setFormatter(formatter)

    while True:
        try:
            record = log_queue.get()
            if record is None:
                break
            # Format and write the log record
            message = formatter.format(record)
            handler.stream.write(message + "\n")
            handler.stream.flush()
        except Exception:
            import traceback
            import sys

            print("[ERR] Error in logger thread:", file=sys.stderr)
            traceback.print_exc(file=sys.stderr)


def setup_direct_logger(log_file, filename, pid=None):
    """Setup a logger that writes directly to the log file without using a queue."""
    # Create a unique logger name using the process ID
    logger_name = f"{filename}_{pid}" if pid else filename
    logger = logging.getLogger(logger_name)

    if not logger.handlers:
        handler = logging.FileHandler(log_file)
        formatter = logging.Formatter("%(asctime)s - %(filenameinfo)s - %(levelname)s - %(message)s")
        handler.setFormatter(formatter)
        logger.addHandler(handler)

        if os.getenv("SERVER_ENV") == "prod":
            logger.setLevel(logging.INFO)
        else:
            logger.setLevel(logging.DEBUG)

    # Add filename info to the logger's extra info
    extra = {"filenameinfo": filename}
    logger = logging.LoggerAdapter(logger, extra)

    return logger