{"id":13763406,"url":"https://github.com/thatstoasty/stump","last_synced_at":"2026-02-22T16:44:24.655Z","repository":{"id":230291127,"uuid":"777421437","full_name":"thatstoasty/stump","owner":"thatstoasty","description":"WIP Logger for Mojo","archived":false,"fork":false,"pushed_at":"2025-01-20T19:01:35.000Z","size":725,"stargazers_count":16,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-06-20T13:07:18.221Z","etag":null,"topics":["logger","mojo","terminal"],"latest_commit_sha":null,"homepage":"","language":"Mojo","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thatstoasty.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-03-25T20:25:41.000Z","updated_at":"2025-02-22T09:04:29.000Z","dependencies_parsed_at":"2024-05-09T18:39:16.448Z","dependency_job_id":"6f13ba93-3b73-427e-9e45-58220e92fdf0","html_url":"https://github.com/thatstoasty/stump","commit_stats":null,"previous_names":["thatstoasty/stump"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/thatstoasty/stump","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thatstoasty%2Fstump","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thatstoasty%2Fstump/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thatstoasty%2Fstump/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thatstoasty%2Fstump/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thatstoasty","download_url":"https://codeload.github.com/thatstoasty/stump/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thatstoasty%2Fstump/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29718672,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-22T15:10:41.462Z","status":"ssl_error","status_checked_at":"2026-02-22T15:10:04.636Z","response_time":110,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["logger","mojo","terminal"],"created_at":"2024-08-03T15:00:44.129Z","updated_at":"2026-02-22T16:44:24.607Z","avatar_url":"https://github.com/thatstoasty.png","language":"Mojo","funding_links":[],"categories":["🗂️ Libraries"],"sub_categories":["Logging"],"readme":"# stump\n\n![Mojo 24.3](https://img.shields.io/badge/Mojo%F0%9F%94%A5-24.3-purple)\n\nWIP Logger! Inspired by charmbracelet's log package and the Python structlog package.\n\n**THIS LIBRARY IS BROKEN FOR MOJO 24.4+ UNTIL Dict.popitem() is fixed: https://github.com/modularml/mojo/issues/2756**\n\nThere are some things I'm ironing out around terminal color profile querying at compilation time. At the moment, the default styles assume a `TRUE_COLOR` enabled color profile. So, if your terminal only supports `ANSI` or `ANSI256`, try setting custom styles like in the `custom.mojo` example, or update the default profile in `stump/style.mojo` from `TRUE_COLOR` to `ANSI` or `ANSI256`.\n\nSee the examples directory for examples on setting up custom processors, styling, message only/json/logfmt logging, and logging with the styling turned off!\n\n![Example logs](https://github.com/thatstoasty/stump/blob/main/logger.png)\n\nMinimal default logger example:\n\n```py\nfrom stump import get_logger\n\n\nalias logger = get_logger()\n\n\nfn main():\n    logger.info(\"Information is good.\")\n    logger.warn(\"Warnings can be good too.\")\n    logger.error(\"An error!\")\n    logger.debug(\"Debugging...\")\n    logger.fatal(\"uh oh...\")\n```\n\nThere's support for arbitrary arg pairs and kwargs to be merged into the log statement!\n\n```mojo\nfrom stump import get_logger\n\n\nalias logger = get_logger()\n\n\nfn main():\n    logger.info(\"Information is good.\", \"key\", \"value\")\n    logger.warn(\"Warnings can be good too.\", \"no_value\")\n    logger.error(\"An error!\", erroring=True)\n    logger.fatal(\"uh oh...\", \"number\", 4, \"mojo\", \"🔥\")\n    logger.debug(\"Debugging...\")\n```\n\nOutput (no color included)\n\n```txt\n2024-04-03 14:53:56 INFO Information is good. key=value\n2024-04-03 14:53:56 WARN Warnings can be good too. no_value=\n2024-04-03 14:53:56 ERROR An error! erroring=True\n2024-04-03 14:53:56 FATAL uh oh... number=4 mojo=🔥\n```\n\nMinimal JSON logger example:\n\n```mojo\nfrom stump import (\n    DEBUG,\n    JSON_FORMAT,\n    BoundLogger,\n    PrintLogger\n)\n\n\n# The loggers are compiled at build time, so we can reuse it.\nalias LOG_LEVEL = DEBUG\nalias logger = BoundLogger(PrintLogger(LOG_LEVEL), formatter=JSON_FORMAT)\n\n\nfn main():\n    logger.info(\"Information is good.\")\n    logger.warn(\"Warnings can be good too.\")\n    logger.error(\"An error!\")\n    logger.debug(\"Debugging...\")\n    logger.fatal(\"uh oh...\")\n\n```\n\nCustomized style and processor logger example:\n\n```mojo\nfrom stump import (\n    DEBUG,\n    DEFAULT_FORMAT,\n    Processor,\n    Context,\n    Styles,\n    Sections,\n    BoundLogger,\n    PrintLogger,\n    add_log_level,\n    add_timestamp,\n    add_timestamp_with_format,\n)\nfrom external.mist import TerminalStyle, Profile, TRUE_COLOR\n\n\n# Define a custom processor to add a name to the log output.\nfn add_my_name(context: Context) -\u003e Context:\n    var new_context = Context(context)\n    new_context[\"name\"] = \"Mikhail\"\n    return new_context\n\n\n# Define custom processors to add extra information to the log output.\nfn my_processors() -\u003e List[Processor]:\n    return List[Processor](\n        add_log_level, add_timestamp_with_format[\"YYYY\"](), add_my_name\n    )\n\n\n# Define custom styles to format and colorize the log output.\nfn my_styles() -\u003e Styles:\n    # Log level styles, by default just set colors\n    var levels = Sections()\n    levels[\"FATAL\"] = TerminalStyle.new().background(\"#d4317d\")\n    levels[\"ERROR\"] = TerminalStyle.new().background(\"#d48244\")\n    levels[\"INFO\"] = TerminalStyle.new().background(\"#13ed84\")\n    levels[\"WARN\"] = TerminalStyle.new().background(\"#decf2f\")\n    levels[\"DEBUG\"] = TerminalStyle.new().background(\"#bd37db\")\n\n    var keys = Sections()\n    keys[\"name\"] = (\n        TerminalStyle.new().foreground(\"#c9a0dc\").underline()\n    )\n\n    var values = Sections()\n    values[\"name\"] = TerminalStyle.new().foreground(\"#d48244\").bold()\n\n    return Styles(\n        levels=levels,\n        key=TerminalStyle.new().faint(),\n        separator=TerminalStyle.new().faint(),\n        keys=keys,\n        values=values,\n    )\n\n\n# The loggers are compiled at build time, so we can reuse it.\nalias LOG_LEVEL = DEBUG\n\n# Build a bound logger with custom processors and styling\nalias logger = BoundLogger(\n    PrintLogger(LOG_LEVEL), formatter=DEFAULT_FORMAT, processors=my_processors, styles=my_styles\n)\n\nfn main():\n    logger.info(\"Information is good.\")\n    logger.warn(\"Warnings can be good too.\")\n    logger.error(\"An error!\")\n    logger.debug(\"Debugging...\")\n    logger.fatal(\"uh oh...\")\n```\n\nImporting the logger into other files works!\n\n```mojo\nfrom examples.default import logger\n\n\nfn main():\n    logger.info(\"Hello!\")\n```\n\n## TODO\n\n### Features\n\n- Add more processor functions.\n- Add support for logging to files via `Logger` struct that uses a writer that implement `io.Writer`.\n- Add global logger support once we have file scope support.\n- Make formatter flexible and composable. Right now it's only a few predefined formats.\n- Exiting on fatal log calls.\n- logf functions to specify a specific format for that log message.\n- Speed improvements once https://github.com/modularml/mojo/issues/2779 is resolved and enables `mist` to compile text styling at comp time instead of on each and every log call. Providing a STDOUT writer logger instead of print logger will speed it up measurably as well.\n- Simple naive JSON formatter to be improved to handle escaped chars, brackets, etc correctly.\n\n### Bugs\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthatstoasty%2Fstump","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthatstoasty%2Fstump","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthatstoasty%2Fstump/lists"}