{"id":34109755,"url":"https://github.com/cartertemm/logsetup","last_synced_at":"2026-04-10T10:33:01.563Z","repository":{"id":62576792,"uuid":"348037500","full_name":"cartertemm/logsetup","owner":"cartertemm","description":"painless log initialization for any project","archived":false,"fork":false,"pushed_at":"2025-09-06T23:54:34.000Z","size":28,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-17T02:14:38.659Z","etag":null,"topics":["logging","python"],"latest_commit_sha":null,"homepage":"","language":"Python","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/cartertemm.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-03-15T16:08:13.000Z","updated_at":"2025-11-26T03:04:21.000Z","dependencies_parsed_at":"2025-07-04T18:20:53.806Z","dependency_job_id":"49a34451-1d22-434c-bd52-2addbf88dc9d","html_url":"https://github.com/cartertemm/logsetup","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cartertemm/logsetup","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cartertemm%2Flogsetup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cartertemm%2Flogsetup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cartertemm%2Flogsetup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cartertemm%2Flogsetup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cartertemm","download_url":"https://codeload.github.com/cartertemm/logsetup/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cartertemm%2Flogsetup/sbom","scorecard":{"id":266887,"data":{"date":"2025-08-11","repo":{"name":"github.com/cartertemm/logsetup","commit":"05875b91ff7a7cdf3a6c5160f1ba7d7d38e31b3d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4,"checks":[{"name":"Maintained","score":7,"reason":"9 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 7","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":0,"reason":"Found 1/23 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: license:0","Info: FSF or OSI recognized license: MIT License: license:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T12:19:21.102Z","repository_id":62576792,"created_at":"2025-08-17T12:19:21.102Z","updated_at":"2025-08-17T12:19:21.102Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31638492,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-10T07:40:12.752Z","status":"ssl_error","status_checked_at":"2026-04-10T07:40:11.664Z","response_time":98,"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":["logging","python"],"created_at":"2025-12-14T18:37:41.243Z","updated_at":"2026-04-10T10:33:01.556Z","avatar_url":"https://github.com/cartertemm.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LogSetup\n\nLogsetup eases the often tedious and repetitive process of log initialization, without compromising flexibility.\n\nIt augments the builtin logging facility by providing a straightforward API, scores of seamless third-party integrations, thread-independent exception catching, and more.\n\nNever write another redundant logging procedure again.\n\n## Installation\n\nJust do:\n\n```\npip install logsetup\n```\n\n## why?\n\nThough python's builtin log facility provides a lot of flexibility and functionality straight out of the box, it unfortunately requires a lot of messy configuration, especially when used in complex applications.\n\nTo illustrate this, the following snippet is a typical log setup, where all events are printed to stderr and errors are sent to errors.log.\n\n```\nimport logging\n\nformatter = logging.Formatter(\"%(levelname)s:%(name)s:%(message)s\")\n\nlogger = logging.getLogger()\nlogger.setLevel(logging.DEBUG)\nerror_handler = logging.FileHandler(\"errors.log\")\nerror_handler.setLevel(logging.ERROR)\nerror_handler.setFormatter(formatter)\nlogger.addHandler(error_handler)\n\nstream_handler = logging.StreamHandler()\nstream_handler.setLevel(logging.DEBUG)\nstream_handler.setFormatter(formatter)\nlogger.addHandler(stream_handler)\n```\n\nThat was awfully verbose.\n\nEnter logsetup!\n\n```\nimport logging\nimport logsetup\n\nlogsetup.set_level(logging.DEBUG)\n\nlogsetup.log_to_stream(logging.DEBUG)\nlogsetup.log_to_file(logging.ERROR, \"errors.log\")\n```\n\nand we're done\n\n```\n\u003e\u003e\u003e logger = logging.getLogger()\n\u003e\u003e\u003e logger.debug(\"debug message\")\nDEBUG root - \u003cstdin\u003e.\u003cmodule\u003e (2021-03-16 09:54:17) - MainThread (13828):\ndebug message\n\n\u003e\u003e\u003e try:\n... \t0/0\n... except:\n... \tlogger.exception(\"while calculating 0/0\")\n\nERROR root - \u003cstdin\u003e.\u003cmodule\u003e (2021-03-16 09:55:47) - MainThread (13828):\nwhile calculating 0/0\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 2, in \u003cmodule\u003e\nZeroDivisionError: division by zero\n\u003e\u003e\u003e\n```\n\n### What about basicConfig?\n\nlogging.basicConfig works fine in tiny console applications, but due to limited scope will quickly prove inadequate for anything more sophisticated.\n\n## How it works\n\nThe following assumes a solid understanding of logging levels, handlers, and how they interact to functionally send messages to different destinations.\nIf you need to quickly brush up on these concepts, have a look at the [Advanced Logging Tutorial](https://docs.python.org/3/howto/logging.html).\n\n\nAt the start of your application, import and initialize logsetup with a level which will be applied to the root logger.\n\n```\nimport logging\nimport logsetup\n\nlogsetup.set_level(logging.DEBUG)\n```\n\nTo log all exceptions at a severity of logging.ERROR, you can:\n\n```\nlogsetup.log_unhandled_exceptions()\n```\n\nand for the same behavior across threads:\n\n```\nlogsetup.log_threaded_exceptions\n```\n\nNote that `log_unhandled_exceptions` takes an optional callback, in cases where you need to notify your UI for example.\n\nAny logging implementation would be useless without handlers, which send messages to a destination of your choosing. In logsetup, handlers are created and applied in a single `logsetup.log_to_*` function call, each of which require a severity level and variable number of parameters.\n\n```\n\u003e\u003e\u003e logsetup.log_to_file(logging.DEBUG, \"debug.log\")\n\u003cFileHandler debug.log (DEBUG)\u003e\n```\n\nIn short, this means write out all events with a severity of DEBUG or above to \"debug.log\".\n\nThere is no limit to the number of handlers a given logger can have. In fact, in production you'll probably want multiple. For instance, one to print messages to the console, another to pipe everything to a file for later review, and yet another to send critical errors to your team via email or Slack.\nIf you have a user-facing application, it's only a matter of time before something somewhere goes wrong. With permission, get peace of mind by automatically sending diagnostic data, crashes, errors and other issues along to those that can work to develop a patch.\n\n### Custom formats\n\nBy default, logsetup uses `logsetup.DEFAULT_FMT` and `logsetup.DEFAULT_DATEFMT` for it's log and date formatting.\n\nIf you'd like to change this for individual handlers, you can do so by passing the `fmt` and `datefmt` keyword arguments, like so:\n\n```\nfmt = \"%(asctime)s %(levelname)s:%(name)s:%(message)s\"\nlog_to_socket(logging.ERROR, host, port, fmt=fmt)\n```\n\n## Handlers\n\nThe following builtin handlers are currently supported. Refer to the code or corresponding handler's documentation for more info.\n\n* stream - writes to IO streams\n* file - writes to a file on disk\n* rotating_file - writes to a set of files on disk, switching out when one reaches a certain size\n* timed_rotating_file - like rotating_file, but switches out after a set time period\n* socket - writes pickled records to a socket listening over TCP. Use `logging.makeLogRecord` to turn the data into a python object\n* SMTP - writes to an email message, sent using the provided SMTP server\n\nThe following are implemented in logsetup directly:\n\n* [Mailgun](https://www.mailgun.com/) - cheap and hassle free email delivery API\n* [Prowl](https://www.prowlapp.com/) - sends iOS push notifications\n\n### Notifiers Integration\n\nIf the [Notifiers](https://github.com/liiight/notifiers) packages is installed, additional logsetup handler functions will be defined at runtime for each supported provider.\nUsing them is as simple as:\n\n```\nlogsetup.log_to_pushover(logging.ERROR, user, message, token)\nlogsetup.log_to_slack(logging.WARNING, webhook_url, message)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcartertemm%2Flogsetup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcartertemm%2Flogsetup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcartertemm%2Flogsetup/lists"}