{"id":16068117,"url":"https://github.com/ged/loggability","last_synced_at":"2025-03-18T05:31:05.676Z","repository":{"id":3204924,"uuid":"4238731","full_name":"ged/loggability","owner":"ged","description":"A composable Ruby logging system built on the standard Logger library.","archived":false,"fork":false,"pushed_at":"2020-12-28T23:53:35.000Z","size":211,"stargazers_count":10,"open_issues_count":0,"forks_count":6,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-16T17:23:56.563Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://bitbucket.org/ged/loggability","language":"Ruby","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"mathiasbynens/dotfiles","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ged.png","metadata":{"files":{"readme":"README.md","changelog":"History.rdoc","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-05-06T05:20:23.000Z","updated_at":"2024-08-25T21:11:06.000Z","dependencies_parsed_at":"2022-08-26T03:01:40.651Z","dependency_job_id":null,"html_url":"https://github.com/ged/loggability","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ged%2Floggability","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ged%2Floggability/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ged%2Floggability/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ged%2Floggability/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ged","download_url":"https://codeload.github.com/ged/loggability/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244164836,"owners_count":20408993,"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","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":"2024-10-09T06:08:36.650Z","updated_at":"2025-03-18T05:31:03.680Z","avatar_url":"https://github.com/ged.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# loggability\n\nhome\n: https://hg.sr.ht/~ged/Loggability\n\ncode\n: https://hg.sr.ht/~ged/Loggability/browse\n\ndocs\n: https://deveiate.org/code/loggability\n\ngithub\n: https://github.com/ged/loggability\n\n\n## Description\n\nA composable logging system built on the standard Logger library.\n\nYou can add Loggability to large libraries and systems, then hook everything\nup later when you know where you want logs to be written, at what level of\nseverity, and in which format.\n\nAn example:\n\n    # Load a bunch of libraries that use Loggability\n    require 'strelka'\n    require 'inversion'\n    require 'treequel'\n    require 'loggability'\n\n    # Set up our own library\n    module MyProject\n        extend Loggability\n        log_as :my_project\n\n        class Server\n            extend Loggability\n            log_to :my_project\n\n            def initialize\n                self.log.debug \"Listening.\"\n            end\n        end\n\n    end\n\n    # Now tell everything that's using Loggability to log to an HTML\n    # log file at INFO level\n    Loggability.write_to( '/usr/local/www/htdocs/log.html' )\n    Loggability.format_as( :html )\n    Loggability.level = :info\n\n\n## Prerequisites\n\n* Ruby 2.4+\n\nIt will probably work under any other interpreter in which Logger works, but\nit's only tested in the above.\n\n\n## Installation\n\n    $ gem install loggability\n\n\n## Usage\n\nLoggability is split up into two parts: [log hosts](rdoc-ref:Loggability::LogHost)\nand [log clients](rdoc-ref:Loggability::LogClient). A \u003cb\u003elog\nhost\u003c/b\u003e is an object that contains a Logger instance that will be used to\nlog stuff. A \u003cb\u003elog client\u003c/b\u003e is an object that will write logging messages to a\nparticular \u003cb\u003elog host\u003c/b\u003e's Logger.\n\nBoth parts require that you extend the object with Loggability.\n\n### Setting Up A 'Log Host'\n\nTo install a Logger into an object, you use the +log_as+ declaration with a\nSymbol that will be used as the key for the object's Logger:\n\n    module MyProject\n        extend Loggability\n        log_as :my_project\n    end\n\nAfter declaring itself as a log host, it will have an associated Loggability::Logger\nobject that's a wrapper around a Logger instance:\n\n    MyProject.logger\n    # =\u003e #\u003cLoggability::Logger:0x4e0c :my_project ...\u003e\n\nSince it's still a Logger object, you can call all the regular Logger methods:\n\n    MyProject.logger.level = Logger::WARN\n\n    MyProject.logger.debug(\"Created logger\")\n    MyProject.logger.info(\"Program started\")\n    MyProject.logger.warn(\"Nothing to do!\")\n\n    begin\n        File.each_line(path) do |line|\n            unless line =~ /^(\\w+) = (.*)$/\n                MyProject.logger.error(\"Line in wrong format: #{line}\")\n            end\n        end\n    rescue =\u003e err\n        MyProject.logger.fatal(\"Caught exception; exiting\")\n        MyProject.logger.fatal(err)\n    end\n\nor use a few new convenience methods for changing the logging level:\n\n    MyProject.logger.level = :debug\n\n...installing a different formatter:\n\n    MyProject.logger.format_as( :html )\n\n...changing the output destination:\n\n    log_messages = []\n    MyProject.logger.output_to( log_messages )\n\n...[and more](rdoc-ref:Loggability::Logger).\n\n\n### Setting Up A 'Log Client'\n\nTo add an object that will log to your log host, after you \u003ctt\u003eextend Loggability\u003c/tt\u003e,\nuse the +log_to+ declaration to hook up the object (and instances of the object if\nyou use +log_to+ in a Class) to the log host you specify:\n\n    class MyProject::Server\n        extend Loggability\n        log_to :my_project\n\n        def initialize( config={} )\n            self.log.debug \"Creating a server with config: %p\" % [ config ]\n            #...\n        end\n    end\n\nYou can fetch any object's Logger through the Loggability object:\n\n    Loggability[ MyProject ]\n    # =\u003e #\u003cLoggability::Logger:0x007f88ca3bf510 ...\u003e\n\n    Loggability[ MyProject::Server ]\n    # =\u003e #\u003cLoggability::Logger:0x007f88ca3bf510 ...\u003e\n\nCalling the object's \u003ctt\u003e#log\u003c/tt\u003e method will return a Proxy for its host's Logger object that will include the object's name in the log messages 'progname'.\n\nYou can also use the \u003cb\u003elog host\u003c/b\u003e itself as the argument to +log_to+:\n\n    class MyProject::Client\n        extend Loggability\n        log_to MyProject\n    end\n\n\n### Aggregate Logging\n\nIf you have several \u003cb\u003elog hosts\u003c/b\u003e, and you want to affect them all simultaneously,\nyou can do that using the aggregate functions of Loggability. They're the same as the\nmethods on Loggability::Logger:\n\n    # Set all logs to log at INFO level\n    Loggability.level = :info\n\n    # Write HTML logs\n    Loggability.format_with( :html )\n\n    # Log everything to the same logfile\n    Loggability.output_to( \"/tmp/my_project_log.html\" )\n\n\n### Temporarily Overriding Logging  Behavior\n\nSometimes you want to log one particular chunk of code at a different\nlevel, or to a different destination, and then restore everything back\nto the way it was afterwards.\n\nLoggability has a few ways of doing that:\n\n    # Log only fatal errors...\n    Loggability.with_level( :fatal ) do\n        ...\n    end\n\n    # Log everything to an array for the block\n    logs = []\n    Loggability.outputting_to( logs ) do\n        ...\n    end\n\n    # Log using the HTML formatter\n    Loggability.formatted_with( :html ) do\n        ...\n    end\n\n    # Or chain them together:\n    Loggability.with_level( :debug ).outputting_to( $stderr ).formatted_with( :color ) do\n        Client.connect!\n    end\n\nYou can also make the override only apply to the loggers for a subset of log hosts:\n\n    # Log only fatal errors on the loggers for the specified two classes\n    Loggability.with_level( :fatal ).for_loggers( ACME::Model, ACME::Adapter ) do\n      ACME.start_up\n    end\n\n    # Debug a particular class:\n    Loggability.with_level( :debug ).for_logger( ACME::Server ) do\n      ACME.start_up\n    end\n\n### Configurability\n\nLoggability has support for the Configurability[https://rubygems.org/gems/configurability]\nlibrary, which does the same thing for configuration that Loggability does for\nlogging.\n\nYou can configure all registered loggers from the 'logging' section of the config:\n\n    logging:\n      __default__: warn STDERR\n      mongrel2: info STDOUT (html)\n      strelka: debug (html)\n      inversion: error /var/log/templating.log (default)\n\nThe format of the value of each logger is:\n\n    SEVERITY [TARGET] [(FORMAT)]\n\nwhere:\n\n+SEVERITY+\n:  The log level; one of: +debug+, +info+, +warn+, +error+, or +fatal+\n\n+TARGET+\n:  The destination for log messages. This can be the path to a log file, or\n   one of \u003ctt\u003e'STDOUT'\u003c/tt\u003e or \u003ctt\u003e'STDERR'\u003c/tt\u003e, which get mapped to the\n   equivalent filehandle. Optional.\n\n+FORMAT+\n:  The name of one of the formatters. Loggability comes with +default+\n   (plaintext), +color+ (ANSI colored text), and +html+ formatters. Optional.\n\nIf the special key \u003ctt\u003e__default__\u003c/tt\u003e is included, its config will be used to\nset global defaults before the individual configs are applied.\n\nIf either of the optional values is unspecified, it is left unchanged from what\nit was before configuration.\n\n\n### RSpec Helpers\n\nLoggability includes a couple of helper functions for RSpec that allow you to\ncontrol log levels for particular specs.\n\nTo use it, require \u003ctt\u003eloggability/spechelpers\u003c/tt\u003e in your specs (we put it in\nthe spec helpers file) and then include the helpers from your RSpec config:\n\n    require 'loggability/spechelpers'\n    RSpec.configure do |c|\n      # ...\n      c.include( Loggability::SpecHelpers )\n    end\n\nThis will install a before and after `:all` hook to set the logging levels\nbefore each example group and then reset it before moving on to the next group.\n\nYou can also access the bodies of those hooks manually:\n\n  setup_logging( level=:fatal )\n  reset_logging()\n\nThe helpers also allow you to set logging levels for a whole example group, for\nparticular contexts, or even for individual examples using RSpec's metadata\nhash syntax:\n\n  # Set logging to 'error' level for each example in this group\n  describe MyClass, logging: :error do\n\n    # ...but for examples in this context, set it to 'fatal'\n    context 'created with a target', log: :fatal do\n\n      # ...except for this one, which logs at 'debug' level\n      it \"does something to it\", logging: :debug do\n\n      end\n\n      it \"does some other stuff, too\"\n\n    end\n\n  end\n\nThe [setup_logging](rdoc-ref:Loggability::SpecHelpers.setup_logging) helper\nalso provides support for displaying the logs inline with spec formatters for\nwhich outputting the logs to STDERR isn't optimal. The only one that's\ncurrently uses it is the\n['webkit' formatter](https://rubygems.org/gems/rspec-formatter-webkit), but\nit should be easy to adapt to other HTML displays as well.\n\nIt looks for either an +HTML_LOGGING+ environment variable, or for the\n+TM_FILENAME+ variable to be set to a filename that ends with '_spec.rb'\n(for Textmate's rspec runner). In either of those conditions, it will set\nup logging output to go to a thread-local Array called 'logger-output',\nlog using the 'html' formatter, and set the log level to 'debug'.\n\nThis can be used to append logs to each example when the formatter\nbuilds the output.\n\n\n## Contributing\n\nYou can check out the current development source with\nMercurial[http://hg.sr.ht/~ged/Loggability], or if you prefer Git, via\n[its Github mirror](https://github.com/ged/loggability).\n\n\n## Author\n\n- Michael Granger \u003cged@faeriemud.org\u003e\n\n\n## License\n\nCopyright (c) 2012-2020, Michael Granger\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice,\n  this list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of the author/s, nor the names of the project's\n  contributors may be used to endorse or promote products derived from this\n  software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fged%2Floggability","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fged%2Floggability","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fged%2Floggability/lists"}