{"id":26883950,"url":"https://github.com/colin-b/logging_json","last_synced_at":"2025-10-08T23:46:53.776Z","repository":{"id":44762589,"uuid":"294441963","full_name":"Colin-b/logging_json","owner":"Colin-b","description":"JSON formatter for python logging","archived":false,"fork":false,"pushed_at":"2025-02-04T17:36:41.000Z","size":59,"stargazers_count":17,"open_issues_count":0,"forks_count":7,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2025-10-06T20:13:22.314Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/Colin-b.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","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}},"created_at":"2020-09-10T15:00:49.000Z","updated_at":"2025-10-06T09:33:11.000Z","dependencies_parsed_at":"2024-05-28T00:29:43.645Z","dependency_job_id":"e5e02104-3234-4447-9943-5f1a2e5cb475","html_url":"https://github.com/Colin-b/logging_json","commit_stats":{"total_commits":19,"total_committers":5,"mean_commits":3.8,"dds":"0.26315789473684215","last_synced_commit":"0f30296811827768894a2337e062fadf5380a2bc"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/Colin-b/logging_json","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Colin-b%2Flogging_json","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Colin-b%2Flogging_json/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Colin-b%2Flogging_json/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Colin-b%2Flogging_json/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Colin-b","download_url":"https://codeload.github.com/Colin-b/logging_json/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Colin-b%2Flogging_json/sbom","scorecard":{"id":32122,"data":{"date":"2025-08-11","repo":{"name":"github.com/Colin-b/logging_json","commit":"fcff26106bc3de505ef41824666f6763cddcc960"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4,"checks":[{"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":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","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":"Code-Review","score":2,"reason":"Found 1/5 approved changesets -- score normalized to 2","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":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"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":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/Colin-b/logging_json/release.yml/develop?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/Colin-b/logging_json/release.yml/develop?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/Colin-b/logging_json/test.yml/develop?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/Colin-b/logging_json/test.yml/develop?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:21","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:22","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:28","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:32","Warn: pipCommand not pinned by hash: .github/workflows/test.yml:21","Warn: pipCommand not pinned by hash: .github/workflows/test.yml:22","Warn: pipCommand not pinned by hash: .github/workflows/test.yml:28","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   7 pipCommand dependencies pinned"],"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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/release.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"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":"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":"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":"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":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"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 30 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-14T19:22:58.815Z","repository_id":44762589,"created_at":"2025-08-14T19:22:58.815Z","updated_at":"2025-08-14T19:22:58.815Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000736,"owners_count":26082862,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2025-03-31T17:37:51.335Z","updated_at":"2025-10-08T23:46:53.717Z","avatar_url":"https://github.com/Colin-b.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch2 align=\"center\"\u003eJSON formatter for logging\u003c/h2\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://pypi.org/project/logging_json/\"\u003e\u003cimg alt=\"pypi version\" src=\"https://img.shields.io/pypi/v/logging_json\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/Colin-b/logging_json/actions\"\u003e\u003cimg alt=\"Build status\" src=\"https://github.com/Colin-b/logging_json/workflows/Release/badge.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/Colin-b/logging_json/actions\"\u003e\u003cimg alt=\"Coverage\" src=\"https://img.shields.io/badge/coverage-100%25-brightgreen\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/psf/black\"\u003e\u003cimg alt=\"Code style: black\" src=\"https://img.shields.io/badge/code%20style-black-000000.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/Colin-b/logging_json/actions\"\u003e\u003cimg alt=\"Number of tests\" src=\"https://img.shields.io/badge/tests-27 passed-blue\"\u003e\u003c/a\u003e\n\u003ca href=\"https://pypi.org/project/logging_json/\"\u003e\u003cimg alt=\"Number of downloads\" src=\"https://img.shields.io/pypi/dm/logging_json\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nThis module provides a JSON formatter for the python [`logging`](https://docs.python.org/3/library/logging.html) module that will format to JSON formatted string.\n\nUsing this formatter allows to have the proper format for logging to `Splunk` or `ElasticSearch`, but it can also be used for logging to stdout as a string is issued.\n\n- [Features](#features)\n  - [Custom fields](#adding-additional-fields-and-values)\n  - [dict logging](#logging-with-a-dictionary)\n  - [str logging](#logging-with-anything-else-such-as-a-string)\n- [Configuration](#configuration)\n  - [Using dictConfig](#using-loggingconfigdictconfig)\n\n## Features\n\n### Adding additional fields and values\n\nYou can add fields to every message that is being logged.\nTo do so, specify the `fields` parameter to the `logging_json.JSONFormatter` instance.\n\nIt must be a dictionary where keys are the keys to be appended to the resulting JSON dictionary (if not already present) and the values can be one of the following:\n* An attribute of the logging record (non-exhaustive list can be found on [the python logging documentation](https://docs.python.org/3/library/logging.html#logrecord-attributes)).\n* If not found on the record, the value will be linked to the key.\n\n#### Logging exceptions, a specific case\n\nIf [an exception is logged](https://docs.python.org/3/library/logging.html#logging.exception), the `exception` key will be appended to the resulting JSON dictionary.\n\nThis dictionary will contain 3 keys:\n* `type`: The name of the exception class (useful when the message is blank).\n* `message`: The str representation of the exception (usually the provided error message).\n* `stack`: The stack trace, formatted as a string.\n\nYou can rename the exception field key by setting the `exception_field_name` parameter with a new name for the key.\nIt is also possible to disable this behaviour by setting the `exception_field_name` parameter to `None` or an empty string\n\n### Logging with a dictionary\n\nThis formatter allows you to log dictionary as in the following:\n\n```python\nimport logging\n\nlogging.info({\"key\": \"value\", \"other key\": \"other value\"})\n```\n\nThe resulting JSON dictionary will be the one you provided (with the [additional fields](#adding-additional-fields-and-values)).\n\n### Logging with anything else (such as a string)\n\nAnything not logged using a dictionary will be handled by the standard formatter, and it can result in one of the 2 output:\n* A JSON dictionary, if [additional fields](#adding-additional-fields-and-values) are set or if `extra` parameter is used while logging, with the message available in the `message` key of the resulting JSON dictionary.\n  Default `message` key name can be changed by `message_field_name` parameter of the `logging_json.JSONFormatter` instance.\n* The formatted record, if no [additional fields](#adding-additional-fields-and-values) are set.\n\nThis handles the usual string logging as in the following:\n\n```python\nimport logging\n\nlogging.info(\"This is my message\")\n```\n\n### Changing asctime representation\n\nYou can override the default representation of asctime (`2003-07-08 16:49:45,896`) based on two different scenarii:\n\n#### Without milliseconds\n\nSet `datefmt` parameter.\n\nSetting `datefmt` to `%Y-%m-%dT%H:%M:%S` would result in `2003-07-08T16:49:45`.\n\n#### With milliseconds\n\nSet `default_time_format` to something else than `%Y-%m-%d %H:%M:%S` to change the representation part without milliseconds.\nSet `default_msec_format` to something else than `%s,%03d` to change the representation milliseconds.\nNote that `%s` in `default_msec_format` is going to be replaced by the representation without milliseconds.\n\nSetting `default_time_format` to `%Y-%m-%dT%H:%M:%S` and `default_msec_format` to `%s.%03d` would result in `2003-07-08T16:49:45.896`.\n\n## Configuration\n\nYou can create a formatter instance yourself as in the following, or you can use a logging configuration.\n\n```python\nimport logging_json\n\nformatter = logging_json.JSONFormatter(fields={\n    \"level_name\": \"levelname\",\n    \"thread_name\": \"threadName\",\n    \"process_name\": \"processName\"\n})\n```\n\n### Using logging.config.dictConfig\n\nYou can configure your logging as advertise by python, by using the `logging.config.dictConfig` function.\n\n#### dict configuration\n\n```python\nimport logging.config\n\nlogging.config.dictConfig({\n    \"version\": 1,\n    \"formatters\": {\n        \"json\": {\n            '()': 'logging_json.JSONFormatter',\n            'fields':{\n                \"level_name\": \"levelname\",\n                \"thread_name\": \"threadName\",\n                \"process_name\": \"processName\"\n            }\n        }\n    },\n    \"handlers\": {\n        \"standard_output\": {\n            'class': 'logging.StreamHandler',\n            'formatter': 'json',\n            'stream': 'ext://sys.stdout'\n        },\n    },\n    \"loggers\": {\n        \"my_app\": {\"level\": \"DEBUG\"}\n    },\n    \"root\": {\n        \"level\": \"INFO\",\n        \"handlers\": [\"standard_output\"]\n    }\n})\n```\n\n#### YAML logging configuration\n\nYou can use YAML to store your logging configuration, as in the following sample:\n\n```python\nimport logging.config\nimport yaml\n\nwith open(\"path/to/logging_configuration.yaml\", \"r\") as config_file:\n    logging.config.dictConfig(yaml.load(config_file))\n```\n\nWhere `logging_configuration.yaml` can be a file containing the following sample:\n\n```yaml\nversion: 1\nformatters:\n  json:\n    '()': logging_json.JSONFormatter\n    fields:\n      level_name: levelname\n      thread_name: threadName\n      process_name: processName\nhandlers:\n  standard_output:\n    class: logging.StreamHandler\n    formatter: json\n    stream: ext://sys.stdout\nloggers:\n  my_app:\n    level: DEBUG\nroot:\n  level: INFO\n  handlers: [standard_output]\n```\n\n## How to install\n1. [python 3.7+](https://www.python.org/downloads/) must be installed\n2. Use pip to install module:\n```sh\npython -m pip install logging_json\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcolin-b%2Flogging_json","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcolin-b%2Flogging_json","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcolin-b%2Flogging_json/lists"}