{"id":37758238,"url":"https://github.com/sancau/sherlog","last_synced_at":"2026-01-16T14:33:13.599Z","repository":{"id":57466759,"uuid":"80517777","full_name":"sancau/sherlog","owner":"sancau","description":"Logs aggregation made easy","archived":false,"fork":false,"pushed_at":"2017-03-30T10:24:01.000Z","size":39,"stargazers_count":3,"open_issues_count":3,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-08-08T22:53:29.758Z","etag":null,"topics":["log-broker","log-collector","log-management","log-monitor","logging"],"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/sancau.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-31T12:19:40.000Z","updated_at":"2024-02-17T12:11:20.000Z","dependencies_parsed_at":"2022-09-10T02:00:28.123Z","dependency_job_id":null,"html_url":"https://github.com/sancau/sherlog","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sancau/sherlog","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sancau%2Fsherlog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sancau%2Fsherlog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sancau%2Fsherlog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sancau%2Fsherlog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sancau","download_url":"https://codeload.github.com/sancau/sherlog/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sancau%2Fsherlog/sbom","scorecard":{"id":798819,"data":{"date":"2025-08-11","repo":{"name":"github.com/sancau/sherlog","commit":"f1554974016bb2a8a4df0576cda5695d41073a64"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.8,"checks":[{"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":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"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":"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 0/30 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":"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":"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":"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":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":"Vulnerabilities","score":8,"reason":"2 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2021-142 / GHSA-8q59-q68h-6hv4","Warn: Project is vulnerable to: PYSEC-2018-49 / GHSA-rprw-h62v-c2w7"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T09:49:20.269Z","repository_id":57466759,"created_at":"2025-08-23T09:49:20.269Z","updated_at":"2025-08-23T09:49:20.269Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28479396,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"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":["log-broker","log-collector","log-management","log-monitor","logging"],"created_at":"2026-01-16T14:33:12.775Z","updated_at":"2026-01-16T14:33:13.594Z","avatar_url":"https://github.com/sancau.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Sherlog. Log aggregation made easy.\r\n#### Aggregate your log messages from decoupled applications in an easy plug-and-play manner\r\n\r\n##### Based on Redis and PostgreSQL. Requires almost zero configuration.\r\n##### Sherlog provides ability to aggregate, store and monitor logging messages from different Python applications and modules in real time.\r\n\r\n## Getting started\r\n### pip install sherlog\r\n\r\n### 1. Using from Python application\r\n\r\n``` python\r\nimport sherlog\r\n\r\nconfig = {\r\n  'app': 'sherlog_example'  # your application name\r\n  'level': 'debug',  # top level for logging (look Python logging module documentation for details)\r\n  'stdout': True  # if True then default StreamHandler will be added (to see logging in your app stdout)\r\n  'dummy': False  # if True then no Redis handler will be attached to Sherlog logger (dummy mode\r\n  may useful during development)\r\n\r\n  'redis': {\r\n    'host': localhost,  \r\n    'port': 6379,\r\n    'key': 'sherlog'  # this key will be used by Sherlog to forward messages through Redis\r\n  }\r\n}\r\n\r\nlog = sherlog.set_logger(config, name='MyLoggerName')  # if no name was passed the 'root' logger will be returned\r\n```\r\n\r\nset_logger() signature: \r\n\r\n```python\r\nset_logger(config, name=None, extra_handlers=None)\r\n```\r\n\r\nThe object returned by sherlog.set_logger() is an instance of Python logger.\r\nSo all the behavior that you might expect from Python logger is there.\r\nUnder the hood Sherlog will add a handler to the logger that will allow it to forward\r\nmessages to your REDIS server. The SherlogHandler also uses special Formatter class\r\nthat basically transforms all the information Python logger provides to a dict (JSON) object.\r\nIt will also add the application name that we defined in the config above.\r\n\r\n- Note: The Python logger is a singleton. Therefore Sherlog will restrict setting a logger with the same\r\n  name more then once in runtime. You still can get an instance that is already configured by Sherlog\r\n  (for example in some sub module of your app) by calling sherlog.get_logger('your logger name').\r\n  ``` python\r\n  log = sherlog.get_logger('MyLoggerName')\r\n  ```\r\n \r\n- Note: You can add arbitrary number of custom handlers along with Sherlog handler by passing them to\r\n  extra_handlers key-value argument.\r\n\r\n- Note: There is a limitation in version (0.1.6): Python logging 'extra' kwag is not supported yet.\r\n\r\nFrom here you can use the logger exactly you would use Python default logger:\r\n\r\n```python\r\nlog.debug('Starting the party...')\r\nlog.info('Party in progress.')\r\nlog.warning('Guest number %s is too drunk', 42)\r\nlog.error('Out of beer.', stack_info=True)\r\nlog.critical('Wookie in the house!')\r\ntry:\r\n    if wookie_in_the_house:\r\n        raise WookieInTheHouse('Big wookie!!!')\r\nexcept WookieInTheHouse as e:\r\n    log.exception(e)\r\n```\r\n\r\n### 2. Sherlog worker (REDIS to PostgreSQL layer)\r\n\r\nNow then you know how to plug in Sherlog into your Python application it is time to\r\nmake the logs actually being forwarded to PostgreSQL.\r\n\r\nSherlog provides simple CLI tool to start up a worker (or many workers)\r\nin a separate process (or even from remote machine).\r\n\r\nThe config the worker will expect can be specified as a YAML or JSON file.\r\nHere is an example of YAML config:\r\n\r\n``` yaml\r\nredis:\r\n  host: localhost\r\n  port: 6379\r\n  key: sherlog\r\n \r\npostgresql:\r\n  host: localhost\r\n  port: 5432\r\n  database: \u003cyour db name\u003e\r\n  user: \u003cusername\u003e\r\n  password: \u003cpassword\u003e\r\n  schema: sherlog\r\n  table: logs\r\n```\r\n\r\nTo start the worker instance simply run in the console:\r\n\r\n```shell\r\nsherlog worker -c \u003cpath_to_your_config_file\u003e\r\n```\r\nThe worker will look for specified schema and table in the PostgreSQL DB and if need will \r\nautomatically create the schema and table of required structure.\r\n\r\nNOTE: All the user input related to the PostgreSQL will be sanitized to prevent possible SQL injection.\r\n\r\nAfter the worker is done with all the connections and preparations you should see a success message. \r\nThe worker will be monitoring the specified REDIS instance and key.\r\nWhen the message will be received from REDIS the worker will insert the event to the specified PostgreSQL schema/table.\r\nUnder the hood Sherlog uses REDIS lpush - brpop to ensure that every message will be inserted just once even\r\nif you are using multiple instances of workers (if one is not enough to process all the incoming messages from your apps).\r\n\r\n### 3. Sherlog monitor CLI\r\n\r\n#### coming soon...\r\n\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsancau%2Fsherlog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsancau%2Fsherlog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsancau%2Fsherlog/lists"}