{"id":22340024,"url":"https://github.com/mandelsoft/logging","last_synced_at":"2026-02-03T05:40:10.065Z","repository":{"id":60673181,"uuid":"542685552","full_name":"mandelsoft/logging","owner":"mandelsoft","description":"A Go Logging Wrapper with selective Log Levels","archived":false,"fork":false,"pushed_at":"2024-06-19T14:33:42.000Z","size":171,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-01T10:48:35.808Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mandelsoft.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}},"created_at":"2022-09-28T16:26:21.000Z","updated_at":"2024-06-19T14:33:45.000Z","dependencies_parsed_at":"2024-03-26T15:27:47.828Z","dependency_job_id":"9d34d466-7ae5-4087-b22f-413befcfced4","html_url":"https://github.com/mandelsoft/logging","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mandelsoft/logging","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mandelsoft%2Flogging","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mandelsoft%2Flogging/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mandelsoft%2Flogging/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mandelsoft%2Flogging/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mandelsoft","download_url":"https://codeload.github.com/mandelsoft/logging/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mandelsoft%2Flogging/sbom","scorecard":{"id":614812,"data":{"date":"2025-08-11","repo":{"name":"github.com/mandelsoft/logging","commit":"fdca28a87b0a89e31c383c7d201494abfa928810"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.7,"checks":[{"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":"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":"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":"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":"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":"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":"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":"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":"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":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: 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 'main'"],"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":"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":"Vulnerabilities","score":0,"reason":"12 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2022-0969 / GHSA-69cg-p879-7622","Warn: Project is vulnerable to: GO-2023-1495 / GHSA-fxg5-wq6x-vr4w","Warn: Project is vulnerable to: GO-2022-1144 / GHSA-xrjj-mj9h-534m","Warn: Project is vulnerable to: GO-2023-1571 / GHSA-vvpx-j8f3-3w6h","Warn: Project is vulnerable to: GO-2023-1988 / GHSA-2wrh-6pvc-2jm9","Warn: Project is vulnerable to: GO-2023-2102 / GHSA-4374-p667-p6c8","Warn: Project is vulnerable to: GHSA-qppj-fm5r-hxr3","Warn: Project is vulnerable to: GO-2024-2687 / GHSA-4v7x-pqxf-cx7m","Warn: Project is vulnerable to: GO-2024-3333","Warn: Project is vulnerable to: GO-2025-3503 / GHSA-qxp5-gwg8-xv66","Warn: Project is vulnerable to: GO-2025-3595 / GHSA-vvgc-356p-c3xw","Warn: Project is vulnerable to: GO-2022-1059 / GHSA-69ch-w2m2-3vjp"],"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-21T03:37:05.055Z","repository_id":60673181,"created_at":"2025-08-21T03:37:05.055Z","updated_at":"2025-08-21T03:37:05.055Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29034554,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-03T02:28:16.591Z","status":"ssl_error","status_checked_at":"2026-02-03T02:27:48.904Z","response_time":96,"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":[],"created_at":"2024-12-04T07:10:12.145Z","updated_at":"2026-02-03T05:40:10.046Z","avatar_url":"https://github.com/mandelsoft.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Logging for Go with context-specific Log Level Settings\n\nThis package provides a wrapper around the [logr](https://github.com/go-logr/logr)\nlogging system supporting a rule based approach to enable log levels\nfor dedicated message contexts specified at the logging location.\n\nThe rule set is configured for a logging context (`Context`). It holds\ninformation about the rule set, log level settings, a standard \n[message context](#message-contexts-and-conditions) and the configured\nbase logger (a `logr.Logger`). With this information it is then used to\ncreate `Logger` objects (optionally for sub message contexts), which can\nbe used to issue log messages for some standard levels.\nThe setting of the context decide together with the message context\nof a logger about its active log level.\n\nA new logging context can be created with:\n\n```go\n    ctx := logging.New(logrLogger)\n```\n\nAny `logr.Logger` can be passed here, the level for this logger\nis used as base level for the `ErrorLevel` of loggers provided\nby the logging context.\nIf the full control should be handed over to the logging context, \nthe maximum log level should be used for the sink of this logger.\n\nIf the used base level should always be 0, the base logger has to \nbe set with plain mode:\n\n```go\n    ctx.SetBaseLogger(logrLogger, true)\n```\n\nNow you can add rules controlling the accepted log levels for dedicated log \nlocations. First, a default log level can be set:\n\n```go\n    ctx.SetDefaultLevel(logging.InfoLevel)\n```\n\nThis level restriction is used, if no rule matches a dedicated log request.\n\nAnother way to achieve the same goal is to provide a generic level rule without any\ncondition:\n\n```go\n    ctx.AddRule(logging.NewConditionRule(logging.InfoLevel))\n```\n\nA first rule for influencing the log level could be a realm rule.\nA *Realm* represents a dedicated logical area, a good practice could be \nto use package names as realms. Realms are hierarchical consisting of\nname components separated by a slash (/).\n\n```go\n    ctx.AddRule(logging.NewConditionRule(logging.DebugLevel, logging.NewRealm(\"github.com/mandelsoft/spiff\")))\n```\n\nAlternatively `NewRealmPrefix(...)` can be used to match a complete realm hierarchy.\n\nA realm for the actual package can be defined as local variable by using the\n`Package` function:\n\n```go\nvar realm = logging.Package()\n```\n\nInstead of passing `Logger`s around, now the logging `Context` is used.\nIt provides a method to access a logger specific for a dedicated log\nrequest, for example, for a dedicated realm.\n\n```go\n  ctx.Logger(realm).Info(\"my message\")\n```\n\nThe provided logger offers the level specific functions, `Error`, `Warn`, `Info`, `Debug` and `Trace`.\nDepending on the rule set configured for the used logging context, the level\nfor the given message context decides, which message to pass to the log sink of\nthe initial `logr.Logger`.\n\nLike a traditional `logr.Logger`, the logging messages take a string and an\noptional list a key/value arguments to describe formalized logging fields\nfor a structured log output.\n\nInstead of two separate arguments for key and value, the function `KeyValue`\ncan be used to provide a key/value pair as single argument. This function\ncan be used to define standard keys for key/value pairs for dedicated usage\nscenarios (see package `keyvalue`, which provide some standards for errors, ids or names).\n\nAlternatively a traditional `logr.Logger` for the given message context can be\nobtained by using the `V` method:\n\n```go\n  ctx.V(logging.InfoLevel, realm).Info(\"my message\")\n```\n\nThose loggers do NOT support the `KeyValue` argument described above.\n\nThe sink for this logger is configured to accept messages according to the\nlog level determined by th rule set of the logging context for the given\nmessage context.\n\n*Remark*: Returned `logr.Logger`s are always using a sink with the base level 0,\nwhich is potentially shifted to the level of the base `logr.Logger`\nused to set up the context, when forwarding to the original sink. This means\nthey are always directly using the log levels 0..*n*.\n\nIt is possible to get a logging context with a predefined message context\nwith\n\n```go\n  ctx.WithContext(\"my message\")\n```\n\nAll loggers obtained from such a context will implicitly use the given\nmessage context.\n\nIf no rules are configured, the default logger of the context is used\nindependently of the  given arguments. The given message context information is\noptionally passed to the provided logger, depending on the used \nmessage context type.\n\nFor example, the realm is added to the logger's name.\n\nIt is also possible to provide dedicated attributes for the rule matching\nprocess:\n\n```go\n  ctx.Logger(realm, logging.NewAttribute(\"test\", \"value\")).Info(\"my message\")\n```\n\nSuch an attribute can be used as rule condition, also. This way, logging\ncan be enabled, for dedicated argument values of a method/function.\n\nBoth sides, the rule conditions and the message context can be a list.\nFor the conditions, all specified conditions must be evaluated to true, to\nenable the rule. A rule is evaluated against the complete message context of\nthe log requests.\nThe default `ConditionRule` evaluates the rules against the complete log\nrequest and a condition is *true*, if it matches at least one argument.\n\nThe rules are evaluated in the reverse order of their definition.\nThe first matching rule defines the finally used log level restriction and log\nsink.\n\nA `Rule` has the complete control over composing an appropriate logger.\nThe default condition based rule just enables the specified log level,\nif all conditions match the actual log request.\n\nFor more complex conditions it is possible to compose conditions\nusing an `Or`, `And`, or `Not` condition.\n\nBecause `Rule` and `Condition` are interfaces, any desired behaviour\ncan be provided by dedicated rule and/or condition implementations.\n\n## Default Logging Environment\n\nThis logging library provides a default logging context, it can be obtained\nby\n\n```go\n  ctx := logging.DefaultContext()\n```\n\nThis way it can be configured, also. It can be used for logging requests\nnot related to a dedicated logging context.\n\nThere is a shortcut to provide a logger for a message context based on\nthis default context:\n\n```go\n  logging.Log(messageContext).Debug(...)\n```\n\nor\n\n```go\n  logging.Log().V(logging.DebugLevel).Info(...\n```\n\n## Attribution Context\n\nAn `AttributionContext` is some kind of lightweight logging context.\nIt based on a regular context and holds a message context and standard\nvalue (key pair) settings for issued log messages, but no rule environment\nfor influencing the log output and no base logger. These elements are\ninherited from the base logging context.\n\nLike a logging context an attribution context can be used to obtain loggers,\nwhose activation level is determined from the base logging context and the \nadditional message context provided by the attribution context.\n\nAdditionally, they provide the possibility to create sub context for\nmore specific settings, which will be forwarded to the created logger objects. \n\n```go\nactx := logging.NewAttributionContext(ctx, logging.NewAttribute(\"name\", \"value\")).Withvalues(\"key\", \"value\")\nlogger := actx.Logger()\nlogger.Info(\"message\", \"otherkey\", \"othervalue\")\n```\n\nIn this example, the attribute setting and the key/value pair will be inherited\nby the generated logger and added to the log messages issued using this logger.\n\n## Configuration\n\nIt is possible to configure a logging context from a textual configuration\nusing `config.ConfigureWithData(ctx, bytedata)`:\n\n```yaml\ndefaultLevel: Info\nrules:\n  - rule:\n      level: Debug\n      conditions:\n        - realm: github.com/mandelsoft/spiff\n  - rule:\n      level: Trace\n      conditions:\n        - attribute:\n            name: test\n            value:\n               value: testvalue  # value is the *value* type, here\n```\n\nRules might provide a deserialization by registering a type object\nwith `config.RegisterRuleType(name, typ)`. The factory type must implement the\ninterface `scheme.RuleType` and provide a value object\ndeserializable by yaml.\n\nIn a similar way it is possible to register a deserialization for\n`Condition`s. The standard condition rule supports a condition deserialization\nbased on those registrations.\n\nThe standard names for rules are:\n - `rule`: condition rule\n\nThe standard names for conditions are:\n- `and`: AND expression for a list of sub sequent conditions\n- `or`: OR expression for a list of sub sequent conditions\n- `not`: negate given expression\n- `realm`: name for a realm condition\n- `realmprefix`: name for a realm prefix condition\n- `attribute`: attribute condition given by a map with `name` and `value`.\n  \nThe config package also offers a value deserialization using\n`config.RegisterValueType`. The default value type is `value`. \nIt supports an `interface{}` deserialization.\n\nFor all deserialization types flat names are reserved for\nthe global usage by this library. Own types should use a reverse\nDNS name to avoid conflicts by different users of this logging\nAPI.\n\nTo provide own deserialization context, an own object of type\n`config.Registry` can be created using `config.NewRegistry`.\nThe standard registry can be obtained by `config.DefaultRegistry()`\n\n## Nesting Contexts\n\nLogging contents can inherit from base contexts. This way the rule set,\nlogger and default level settings can be reused for a sub-level context.\nIn contrast to [attribution contexts](#attribution-context) such a context\nthen provides a new scope to define additional rules\nand settings only valid for this nested context. Settings done here are not\nvisible to log requests evaluated against the base context.\n\nIf a nested context defines an own base logger, the rules inherited from the base\ncontext are evaluated against this logger if evaluated for a message\ncontext passed to the nested context (extended-self principle).\n\nA logging context reusing the settings provided by the default logging\ncontext can be obtained by:\n\n```go\n  ctx := logging.NewWithBase(logging.DefaultContext())\n```\n\nor just with \n\n```go\nctx := logging.DefaultContext().WithContext(\u003cadditional message context\u003e)\n\nto directly add a sub sequent message context.\n```\n\nUsing nested logging contexts it more expensive than just using nested\nattribution contexts based on a logging context, because of the inheritance\nof the rule environment.\nIf only a subsequent settings for created loggers are required (message context,\nlogger names and key/value pairs) an attribution context should be preferred.\n\n## Preconfigured Rules, Message Contexts and Conditions\n\n### Rules\n\nThe base library provides the following basic rule implementations.\nIt is possible to define own more complex rules by implementing\nthe `logging.Rule` interface.\n\n- `NewRule(level, conditions...)` a simple rule setting a log level\nfor a message context matching all given conditions.\n\n### Message Contexts and Conditions\n\nThe message context is a set of objects describing the context of a\nlog message. It can be used\n- to enrich the log message\n- ro enrich the logger (logr.Logger features a name to represent\n  the call hierarchy when passing loggers to functions)\n- to control the effective log condition based of configuration rules.\n  (for example to enable all Info logs for log requests with a dedicated attribute)\n \nThe base library already provides some ready to use conditions\nand message contexts:\n\n- `Name`(*string*)  is attached as additional name part to the logr.Logger. \n  It cannot be used to control the log state.,\n\n- `Tag`(*string*) Just some tag for a log request.\n  Used as message context, the tag name is not added to the logger name for\n  the log request.\n\n- `Realm`(*string*) the location context of a logging request. This could\n  be some kind of denotation for a functional area or Go package. To obtain the\n  package realm for some coding the function `logging.Package()` can be used. Used as message context, the realm name is added as additional attribute (`realm`) to log message. As condition realms only match the last realm in a message context.\n\n- `RealmPrefix`(*string*) (only as condition) matches against a complete \n  realm tree specified by a base realm. It matches the last realm in a message\n  context, only.\n\n- `Attribute`(*string,interface{}*) the name of an arbitrary attribute with some\n  value. Used as message context, the key/value pair is added to the log message.\n\nMeaning of predefined objects in a message context:\n\n| Element       | Rule Condition | Message Context | Logger  | LogMessage Attribute |\n|---------------|:--------------:|:---------------:|:-------:|:--------------------:|\n| Name          |    \u0026check;     |     \u0026check;     | \u0026check; |       \u0026cross;        |\n| Tag           |    \u0026check;     |     \u0026check;     | \u0026cross; |       \u0026cross;        |\n| Realm         |    \u0026check;     |     \u0026check;     | \u0026cross; |  \u0026check;  (`realm`)  |\n| Attribute     |    \u0026check;     |     \u0026check;     | \u0026cross; |       \u0026check;        |\n| RealmPrefix   |    \u0026check;     |     \u0026cross;     | \u0026cross; |       \u0026cross;        |\n| UnboundLogger |    \u0026cross;     |     \u0026check;     | \u0026check; |  \u0026check; (partial)   |\n| Context       |    \u0026cross;     |     \u0026check;     | \u0026check; |  \u0026check; (partial)   |\n\n(* partial means, that only flattened elements matching the appropriate interface will be used)\n\nIt is possible to create own objects using the interfaces:\n- `Attacher`: attach information to a logger\n- `Condition`: to be usable as condition in a rule.\n- `MessageContextProvider`: to be usable as provider for multiple message context.\n\nOnly objects implementing at least one of those interfaces can\nusefully be passed.\n\nAn `[]MessageContext` can also be used as message context, like a `MessageContextProvider`\nit wil be expanded to flat list of effective message contexts.\n\n## Bound and Unbound Loggers\n\nBy default, logging contexts provide *bound* loggers. The activation of\nsuch a logger is bound to the settings of the rule matching at the time\nof its creation. If it does not match any rule, always context's default\nlevel is used.\n\nThis behaviour is fine, als long such a logger is used temporarily, for example\nit is created at the beginning of a dedicated call hierarchy, and passed down\nthe call tree. But it does not show the expected behaviour when stored in and\nreused from a long-living variable. If the rule settings are changed\nduring its lifetime, the activation state is NOT adapted.\n\nNevertheless, it might be useful store and reuse a configured logger.\nConfigured means, that is instantiated for a dedicated long living message\ncontext, or with a dedicated name. Such a behaviour can be achieved\nby not using a logger but a logging context. Because the context does\nnot provide logging methods a temporary logger has to be created\non-the-fly for issuing log entries.\n\nAnother possibility is to use *unbound* loggers created with a message context\nfor a logging context using the `DynamicLogger` function. It provides\na logger, which keeps track of the actual settings of the context it has been\ncreated for. Whenever the configuration changes, the next logging call will\nadapt the effectively used logger on-the-fly. Such loggers keep track of the\ncontext settings as well as the configured message context and logger values\nor names (provided by the methods `WithValues` and `WithName`).\n\nThey can be used, for example for permanent worker Go routines, to\nstatically define the log name or standard values used for all subsequent log\nrequests according to the identity of the worker.\n\n## Condition specific Loggers\n\nLoggers are always enabled according to their effective message context\nby evaluating the rules configured for the message context.\nIf a message context includes a tag, those loggers are enabled\nif there is a rule matching this tag. But they are enabled, also, if\nthere are rules matching other elements in the effective message context\nof the context used to retrieve the logger.\n\nUsing the `LoggerFor` methods a logger can be retrieved for a dedicated\nmessage context without using the inherited settings from the context.\nThis way, the retrieved logger is enabled by rules for the\ngiven message context, only.\n\n\n## Support for special logging systems\n\nThe general *logr* logging framework acts as a wrapper for\nany other logging framework to provide a uniform frontend,\nwhich can be based on any supported base.\n\nTo support this, an adapter must be provided, for example,\nthe adapter for *github.com/sirupsen.logrus* is provided\nby *github.com/bombsimon/logrusr*.\n\nBecause this logging framework is based on *logr* \nit can be based on any such supported logging framework.\n\nThis library contains some additional special mappings of *logr*, also.\n\n### `logrus`\n\nThe support includes three new logrus entry formatters in\npackage `logrusfmt`, able to be configurable to best match\nthe features of this library.\n\n- `TextFormatter` an extended logrus.TextFormatter with\n  extended capabilities to render an entry.\n  This is used by the adapter to generate more human-readable\n  logging output supporting the special fields provided by\n  this logging system.\n\n- `TextFmtFormatter` an extended `TextFormatter` able\n  to render more human-readable log messages by \n  composing a log entry's log message incorporating selected \n  log fields into a readable log message.\n\n- `JSONFormatter` an extended logrus.JSONFormatter with\n  extended capabilities to render an entry.\n  This is used by the adapter to generate more readable\n  logging output with a dedicated ordering of the special fields \n  provided by this logging system.\n\nThe package `logrusl` provides configuration methods to \nachieve a `logging.Context` based on *logrus* with special \npreconfigured configurations.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmandelsoft%2Flogging","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmandelsoft%2Flogging","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmandelsoft%2Flogging/lists"}