{"id":15554160,"url":"https://github.com/zarqman/log_sanity","last_synced_at":"2026-02-06T18:04:51.587Z","repository":{"id":55451766,"uuid":"243897229","full_name":"zarqman/log_sanity","owner":"zarqman","description":"LogSanity - Bring sanity to Rails logs by reducing verbosity, using json output, and more.","archived":false,"fork":false,"pushed_at":"2025-12-13T19:26:14.000Z","size":101,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-15T14:17:42.306Z","etag":null,"topics":["logging","rails","ruby"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","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/zarqman.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2020-02-29T03:24:25.000Z","updated_at":"2025-12-13T19:26:18.000Z","dependencies_parsed_at":"2025-04-11T15:47:44.229Z","dependency_job_id":"904c1797-cdd9-46d8-844b-4badfdc84672","html_url":"https://github.com/zarqman/log_sanity","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/zarqman/log_sanity","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zarqman%2Flog_sanity","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zarqman%2Flog_sanity/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zarqman%2Flog_sanity/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zarqman%2Flog_sanity/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zarqman","download_url":"https://codeload.github.com/zarqman/log_sanity/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zarqman%2Flog_sanity/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29171052,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-06T16:33:35.550Z","status":"ssl_error","status_checked_at":"2026-02-06T16:33:30.716Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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","rails","ruby"],"created_at":"2024-10-02T14:50:31.347Z","updated_at":"2026-02-06T18:04:51.570Z","avatar_url":"https://github.com/zarqman.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LogSanity\n\nLogSanity is another attempt at taming Rails logging and making logs more viable in production.\n\nIt's quite opinionated (partly intentional, partly a byproduct of being a young project) and yet strives for sane defaults and to play nicely within the natural order of Rails.\n\nAt its core, it aggregates various logging variables and then outputs one JSON-formatted, primary request log line. It's quite easy to add extra variables to this output, great for appending info about the authenticated user, active account, etc.\n\nHowever, just because the primary output is a single line doesn't make it a one-line logging system. Taking inspiration from elsewhere[^1], the intent is for each conceptual event to have its own log entry. The default request line is just an http(s) request event. If the user takes other actions and those should be logged, do so--and give them their own entry. To this end, a small number of default Rails events are logged individually, such as sending an email, some ActiveJob processing, and a few others.\n\nExample output: (Multi-line and extra whitespace added for readability; normally all one line.)\n\n```json\n{ \"at\" : \"2017-01-18T00:27:50.947Z\",\n  \"event\" : \"https_get\",\n  \"ip\" : \"127.0.0.1\",\n  \"rq\" : \"ec337729-dbf3-4c6f-86b9-8d1a06c2277e\",\n  \"route\" : \"ArticlesController#index\",\n  \"format\" : \"html\",\n  \"params\" : {\"id\":\"123456\"},\n  \"duration\" : {\"total\":20, \"views\":9, \"activerecord\":1},\n  \"status\" : 200\n}\n```\n\n\n\n### Installation\n\nFor Rails 7.1+, use log_sanity 2.x:\n```ruby\ngem 'log_sanity'\n```\n\nFor Rails 5.2, 6.x, or 7.0, use log_sanity 1.x:\n```ruby\ngem 'log_sanity', '~\u003e 1'\n```\n\nBy default, LogSanity does not enable itself. To do so, in `config/environments/production.rb` add:\n```ruby\nconfig.logsanity.enabled = true\nconfig.log_level = :info\n```\n\nYou can go less verbose than `:info` (say, `:warn`), but more verbose (ie: `:debug`) is not recommended.\n\n\n##### A note on initialization order\n\nLogSanity initializes after running `application.rb` and `config/environments/*.rb`, but before `config/initializers/*.rb`. Most `config.logsanity.*` settings must be in one of the former or they will be ignored (`config.logsanity.silence_paths` being an exception).\n\nHowever, `initializers/*.rb` may be used to reduce the scope of what's logged. For example, to skip logging of ActiveJob requests only:\n```ruby\n# initializers/log_sanity.rb\nLogSanity::LogSubscriber::ActiveJob.detach_from :active_job\n```\n\n\n### Usage\n\nBasic usage may require nothing more than enabling LogSanity as outlined above. Some common configuration settings include silencing logging for certain paths (like health checks) or adding information about the currently authenticated user.\n\n##### Adding attributes\n\nThe most common way to add attributes is via controllers. Helper methods are provided for this. For example, to log the current user's ID, you might add the following to `application_controller.rb`:\n\n```ruby\nafter_action do\n  if current_user\n    log_field 'user', current_user.id\n  end\nend\n```\n\nThe syntax is simply `log_field(key, value)`. Since the output is JSON, `value` can even be a hash or array:\n```ruby\nlog_field 'user', {id: current_user.id, name: current_user.name}\n```\n\nYou can log multiple fields by calling `log_field` multiple times.\n\nIf you must, you can get to the full fields hash:\n```ruby\nLogSanity.fields['user'] ||= {}\nLogSanity.fields['user']['id'] = current_user.id\n```\n\nIt's also possible to add attributes via Rails' existing `log_tags` facility, which is documented more below.\n\n\n##### Logging complete entries\n\nTo log a complete event (a complete log entry), try something like:\n```ruby\nlogger.info 'event'=\u003e'user_signup', 'source'=\u003e'ppc', 'campaign'=\u003e'awesomeness', 'rq'=\u003erequest.uuid, 'user'=\u003ecurrent_user.id\n```\n\nIf you pass in a hash to any `logger` method, it automatically becomes JSON output. The timestamp will be automatically added.\n\n\n\n### Configuration options\n\nWhile the above covers most of it, there are a handful of other potentially useful settings.\n\n##### Silence logging for certain paths\n\nThis is particularly useful if you have any kind of health check path, as there's no need to fill up log files with that stuff. Both exact strings and regexps are supported.\n\n```ruby\nconfig.logsanity.silence_paths += [\"/health\", %r{^/healthcheck}]\n```\n\nBoth exact path matches (Strings) and Regex's are supported.\n\n\n##### Logging of strings\n\nBy default, strings are logged as-is and not stuck inside a JSON object. If you prefer the opposite:\n\n```ruby\nconfig.logsanity.json_strings = true\n```\n\nWith `json_strings` as `false` (default), `logger.info \"This is fantastic!\"` would normally just output:\n```\nThis is fantastic!\n```\nHowever, if `true`, you'll see:\n```json\n{\"at\":\"2017-01-18T00:27:50.947Z\",\"message\":\"This is fantastic!\"}\n```\n\n\n##### String formatting\n\nWhen LogSanity initializes, it replaces the Rails log formatter with its own, but saves the old one for outputting strings (used when `json_strings` is `false`). This means you can still configure the formatting of those. For example, to use Logger's default formatting (instead of Rails' default):\n\n```ruby\nconfig.log_formatter = ::Logger::Formatter.new\n```\n\n\n##### Tagged logging\n\nAs noted above, you can either add extra attributes directly or via `log_tags`. We discussed direct already. Now let's take a look at tagged logging, which is a bit different in a JSON world.\n\n```ruby\nconfig.log_tags = [ :subdomain ]\n```\n\nJust like Rails' support for text-style logs, you may use symbols (which call the named method on the `request` object), strings (logged literally), and Procs (which are passed `request` as a parameter).\n\nLogSanity takes these and adds them to the default request log entry (but _not_ other log entries). If a tagged method (via symbol or Proc) returns a hash, it's merged directly into the output. Otherwise the return value is used as a string and given a key in the form `tag#` where # is automatically calculated.\n\n\n### Additional notes\n\nLogSanity is intended for production use at log_level info. At level debug, some logs are simply turned off. Others may continue to output as normal strings (such as ActiveRecord queries).\n\nIf not using tags, there is no need to use ActiveSupport::TaggedLogging with your logger. Just set the logger directly (if not using the default):\n```ruby\nconfig.logger = ActiveSupport::Logger.new(STDOUT)\n```\n\nAll default output includes the :uuid/:request_id using the key \"rq\". There is no need to add \\[:uuid] to `config.log_tags`.\n\nThe request path is not included, as it mostly just duplicates `route` and `params`. If you need it, you could add it using `config.log_tags = [:filtered_path]`. Alternatively, consider adding X-Request-Id to your `nginx` (or other webserver) logs and correlating to those logs instead.\n\nThe `total` duration may be longer than you're used to seeing. By default, Rails only counts the time inside the application controller. In contrast, LogSanity also includes all the middleware between itself and the application controller. While this isn't the entire picture, it is closer to the actual real time elapsed.\n\n\n### What does it do behind the scenes?\n\nIn short:\n* Removes all default Rails logging, replacing it with its own\n* Replaces Rails::Rack::Logger middleware with its own\n* Replaces the current logger's formatter\n\n\n### Final notes\n\nThere are still some things that could be handled better (such as multi-line strings in json_strings mode).\n\nPull requests are welcomed and encouraged. The only goal is to avoid making things unnecessarily complex.\n\nLicense: MIT\n\n\n[^1]: Parts [one](https://medium.com/@jlsuttles/structured-logging-part-1-what-s-the-big-deal-b7c6011e2504), [two](https://medium.com/@jlsuttles/structured-logging-part-2-usage-7754db10b6c), and [three](https://medium.com/@jlsuttles/structured-logging-part-3-practical-application-for-ruby-b5023f29f0af).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzarqman%2Flog_sanity","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzarqman%2Flog_sanity","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzarqman%2Flog_sanity/lists"}