{"id":22377436,"url":"https://github.com/dl1998/go-logging","last_synced_at":"2025-03-26T18:21:01.895Z","repository":{"id":225746607,"uuid":"766372488","full_name":"dl1998/go-logging","owner":"dl1998","description":"Logger implementation for Go.","archived":false,"fork":false,"pushed_at":"2024-04-11T19:44:34.000Z","size":7399,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-04-12T07:41:57.115Z","etag":null,"topics":["async","colored-log","colored-logging","file-logger","file-logging","go","golang","golang-library","logger","logging","logging-library","structured-logging"],"latest_commit_sha":null,"homepage":"","language":"Go","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/dl1998.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}},"created_at":"2024-03-03T04:31:25.000Z","updated_at":"2024-04-28T05:20:18.069Z","dependencies_parsed_at":"2024-04-15T01:43:10.151Z","dependency_job_id":"7dacd12b-86cc-4c67-8ae5-d4c188570037","html_url":"https://github.com/dl1998/go-logging","commit_stats":null,"previous_names":["dl1998/go-logging"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dl1998%2Fgo-logging","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dl1998%2Fgo-logging/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dl1998%2Fgo-logging/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dl1998%2Fgo-logging/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dl1998","download_url":"https://codeload.github.com/dl1998/go-logging/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245708966,"owners_count":20659626,"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":["async","colored-log","colored-logging","file-logger","file-logging","go","golang","golang-library","logger","logging","logging-library","structured-logging"],"created_at":"2024-12-04T22:14:03.789Z","updated_at":"2025-03-26T18:21:01.871Z","avatar_url":"https://github.com/dl1998.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Go Logger\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/dl1998/go-logging.svg)](https://pkg.go.dev/github.com/dl1998/go-logging)\n[![Go Report Card](https://goreportcard.com/badge/github.com/dl1998/go-logging)](https://goreportcard.com/report/github.com/dl1998/go-logging)\n[![Coverage Status](https://coveralls.io/repos/github/dl1998/go-logging/badge.svg)](https://coveralls.io/github/dl1998/go-logging)\n\nGo logger implements logger for Golang, current implementation is majorly inspired by Python logger.\n\n## Installation\n\n```bash\ngo get github.com/dl1998/go-logging\n```\n\nor\n\n```bash\ngo install github.com/dl1998/go-logging@[version]\n```\n\n***Note: replace `[version]` with the version you want to install.***\n\n## Usage\n\nCheck examples provided in the [examples](./examples).\n\nLogger supports 11 logging levels + 2 (when not set):\n\n- All (special level, cannot be used for logging)\n- Trace\n- Debug\n- Verbose\n- Info\n- Notice\n- Warning\n- Severe\n- Error\n- Alert\n- Critical\n- Emergency\n- Null (special level, cannot be used for logging)\n\n### Default Logger\n\nDefault logger could be used like in the following example:\n\n- Standard logger\n\n  ```go\n  logger.Warning(\"Message for logging: %s.\", \"my message\")\n  ```\n\n- Structured logger\n\n  ```go\n  structuredlogger.Warning(\"message\", \"My message.\")\n  ```\n  \n  or\n  \n  ```go\n  structuredlogger.Warning(map[string]string{\n      \"message\": \"My message.\",\n  })\n  ```\n\nBy default, root logger prints on console only, and starting from Warning level. It could be changed by setting logging\nlevel:\n\n- Standard logger\n\n  ```go\n  logger.Configure(logger.NewConfiguration(logger.WithFromLevel(level.All)))\n  ```\n\n- Structured logger\n\n  ```go\n  structuredlogger.Configure(logger.NewConfiguration(logger.WithFromLevel(level.All)))\n  ```\n\nAfter changing log level to \"All\" it will print messages for any level.\n\nYou could also change the format of the default structured logger by setting the format (default: json).\n\n```go\nstructuredlogger.Configure(logger.NewConfiguration(logger.WithFormat(\"key-value\")))\n```\n\nAll options available for the configuration are:\n\n For Standard Logger\n\n  | Method               |               Default               | Description                                                                        |\n  |----------------------|:-----------------------------------:|------------------------------------------------------------------------------------|\n  | WithErrorLevel       |             level.Error             | Set logging level used to log raised or captured error.                            |\n  | WithPanicLevel       |           level.Critical            | Set logging level used to log panic.                                               |\n  | WithRequestTemplate  |     \"Request: [{Method}] {URL}\"     | Set template for the http.Request wrapper.                                         |\n  | WithResponseTemplate | \"Response: [{StatusCode}] {Status}\" | Set template for the http.Response wrapper.                                        |\n  | WithFromLevel        |            level.Warning            | Set logging level from which logger should log messages.                           |\n  | WithToLevel          |             level.Null              | Set logging level till which logger should log messages.                           |\n  | WithTemplate         |    \"%(level):%(name):%(message)\"    | Set template for logging message.                                                  |\n  | WithFile             |                 \"\"                  | Set file where to log messages, if not set, then logging to file will be disabled. |\n  | WithName             |               \"root\"                | Set logger name.                                                                   |\n  | WithTimeFormat       |            time.RFC3339             | Set time format for logging message.                                               |\n\n For Structured Logger\n\n  | Method                |                                                       Default                                                       | Description                                                                                                                           |\n  |-----------------------|:-------------------------------------------------------------------------------------------------------------------:|---------------------------------------------------------------------------------------------------------------------------------------|\n  | WithErrorLevel        |                                                     level.Error                                                     | Set logging level used to log raised or captured error.                                                                               |\n  | WithPanicLevel        |                                                   level.Critical                                                    | Set logging level used to log panic.                                                                                                  |\n  | WithRequestMapping    |                         map[string]string {\u003cbr/\u003e\"url\": \"URL\",\u003cbr/\u003e\"method\": \"Method\",\u003cbr/\u003e}                         | Set mapping for the http.Request wrapper.                                                                                             |\n  | WithResponseMapping   |                 map[string]string {\u003cbr/\u003e\"status\": \"Status\",\u003cbr/\u003e\"status-code\": \"StatusCode\",\u003cbr/\u003e}                  | Set mapping for the http.Response wrapper.                                                                                            |\n  | WithFromLevel         |                                                    level.Warning                                                    | Set logging level from which logger should log messages.                                                                              |\n  | WithToLevel           |                                                     level.Null                                                      | Set logging level till which logger should log messages.                                                                              |\n  | WithTemplate          | map[string]string {\u003cbr/\u003e\"timestamp\": \"%(timestamp)\",\u003cbr/\u003e\"level\":     \"%(level)\",\u003cbr/\u003e\"name\":      \"%(name)\",\u003cbr/\u003e} | Set template for logging structure.                                                                                                   |\n  | WithFile              |                                                         \"\"                                                          | Set file where to log messages, if not set, then logging to file will be disabled.                                                    |\n  | WithFormat            |                                                       \"json\"                                                        | Set format for structured logging.\u003cbr/\u003e\u003cbr/\u003eCould be one of the following\u003cbr/\u003e\u003cul\u003e\u003cli\u003ejson\u003c/li\u003e\u003cli\u003ekey-value\u003c/li\u003e\u003c/ul\u003e                |\n  | WithPretty            |                                                        false                                                        | Set if json message should be pretty printed.\u003cbr/\u003e*Option works only with \"json\" format.*                                             |\n  | WithKeyValueDelimiter |                                                         \"=\"                                                         | Set key-value delimiter (eg. \"key=value\", where '=' is the delimiter).\u003cbr/\u003e*Option works only with \"key-value\" format.*               |\n  | WithPairSeparator     |                                                         \" \"                                                         | Set key-value separator (eg. \"key1=value1,key2=value2\", where ',' is the separator).\u003cbr/\u003e*Option works only with \"key-value\" format.* |\n  | WithName              |                                                       \"root\"                                                        | Set logger name.                                                                                                                      |\n  | WithTimeFormat        |                                                    time.RFC3339                                                     | Set time format for logging message.                                                                                                  |\n\n### Custom Logger\n\nAlternatively you could create application logger. To do this you would need to create a new logger.\n\n- Standard logger\n\n  ```go\n  applicationLogger := logger.New(\"application-logger\", time.RFC3339)\n  ```\n\n- Standard async logger\n\n  ```go\n  applicationLogger := logger.NewAsyncLogger(\"application-logger\", time.RFC3339, 100)\n  ```\n\n- Structured logger\n\n  ```go\n  applicationLogger := structuredlogger.New(\"application-logger\", time.RFC3339)\n  ```\n\n- Structured async logger\n\n  ```go\n  applicationLogger := structuredlogger.NewAsyncLogger(\"application-logger\", time.RFC3339, 100)\n  ```\n\nAfter this you need to set up it, for this create a new formatter that says how to log the message by providing a\ntemplate.\n\n#### Formatter\n\nAvailable template options:\n\n|    Option    |      Scope      | Description                                                                  |\n|:------------:|:---------------:|------------------------------------------------------------------------------|\n|   %(name)    |      Both       | Logger name.                                                                 |\n|   %(level)   |      Both       | Log level name.                                                              |\n|  %(levelnr)  |      Both       | Log level number.                                                            |\n| %(datetime)  |      Both       | Current date and/or time formatted using time format. Default: time.RFC3339. |\n| %(timestamp) |      Both       | Current timestamp.                                                           |\n|   %(fname)   |      Both       | Name of the file from which logger has been called.                          |\n|   %(fline)   |      Both       | Line in the file in which logger has been called.                            |\n|  %(message)  | standard logger | Log message.                                                                 |\n\n- Standard logger\n\n  ```go\n  applicationFormatter := formatter.New(\"%(datetime) [%(level)] %(message)\")\n  ```\n\n- Structured logger\n    - JSON format\n\n      ```go\n      applicationFormatter := formatter.NewJSON(map[string]string{\n          \"time\":    \"%(timestamp)\",\n          \"level\":   \"%(level)\",\n      }, false)\n      ```\n\n    - Key-Value format\n\n      ```go\n      applicationFormatter := formatter.NewKeyValue(map[string]string{\n          \"time\":    \"%(timestamp)\",\n          \"level\":   \"%(level)\",\n      }, \"=\", \" \")\n      ```\n\nAfter creation of the formatter, you need to create a new handler that tells where to write log messages.\n\n#### Handler\n\nThere are three predefined types of handler (for standard and structured logger each):\n\n- Console Handler - it takes log level starting from which it would log messages, log level till which it would log\n  messages, and formatter that tells how to log message. It logs messages to standard output.\n\n  ```go\n  newConsoleHandler := handler.NewConsoleHandler(level.Debug, level.Null, applicationFormatter)\n  ```\n\n- Console Error Handler - it takes log level starting from which it would log messages, log level till which it would\n  log messages, and formatter that tells how to log message. It logs messages to error output.\n\n  ```go\n  newConsoleErrorHandler := handler.NewConsoleErrorHandler(level.Debug, level.Null, applicationFormatter)\n  ```\n\n- File Handler - it takes log level starting from which it would log messages, log level till which it would\n  log messages, formatter that tells how to log message, and path to the file where to log those data.\n\n  ```go\n  newFileHandler := handler.NewFileHandler(level.Debug, level.Null, applicationFormatter, \"system.log\")\n  ```\n\nYou could create your custom handler:\n\n```go\ncustomHandler := handler.New(level.Debug, level.Null, applicationFormatter, os.Stdout)\n```\n\nIt takes two additional arguments writer for standard messages and for error messages. Standard message logs till\n\"Error\" level, after this error writer is used.\n\nAfter handler has been created it shall be registered.\n\n```go\n// Register console stdout handler.\napplicationLogger.AddHandler(newConsoleHandler)\n// Register console stderr handler.\napplicationLogger.AddHandler(newConsoleErrorHandler)\n// Register file handler.\napplicationLogger.AddHandler(newFileHandler)\n```\n\nNow it could be used to log the message, simply by calling respective level of logging and providing message with\narguments.\n\n- Standard logger\n\n  ```go\n  applicationLogger.Info(\"My message: %s.\", \"logged using application logger\")\n  ```\n\n- Standard async logger\n\n  ```go\n  applicationLogger.Info(\"My message: %s.\", \"logged using application async logger\")\n  \n  // Wait for all messages to be logged before exiting the program.\n  applicationLogger.WaitToFinishLogging()\n  ```\n\n- Structured logger\n  - Varargs\n\n    ```go\n    applicationLogger.Info(\"message\", \"Logged using structured logger with varargs.\")\n    ```\n\n  - Map\n\n    ```go\n    applicationLogger.Info(map[string]string{\n        \"message\": \"Logged using structured logger with map.\",\n    })\n    ```\n\n- Structured async logger\n  - Varargs\n\n    ```go\n    applicationLogger.Info(\"message\", \"Logged using structured logger with varargs.\")\n    \n    // Wait for all messages to be logged before exiting the program.\n\tapplicationLogger.WaitToFinishLogging()\n    ```\n\n  - Map\n\n    ```go\n    applicationLogger.Info(map[string]string{\n        \"message\": \"Logged using structured logger with map.\",\n    })\n    \n    // Wait for all messages to be logged before exiting the program.\n\tapplicationLogger.WaitToFinishLogging()\n    ```\n\n#### Async Loggers - Additional Information\n\nAsync loggers are used to log messages asynchronously. It is useful when you want to log messages without blocking the\nmain thread. However, you need to wait for all messages to be logged before exiting the program. You can do this by\ncalling the `WaitToFinishLogging` method, it will block the main thread until all messages are logged. Alternatively,\nyou can close the logger by calling the `Close` method, it will close the message queue without waiting for all messages\nto be logged. This is useful when you want to exit the program without waiting for all messages to be logged. After\ncalling the `Close` method, you can open the logger again by calling the `Open` method, it accepts the new message queue\nsize as an argument. `Open` method will open the logger with the new message queue size and start listening for the\nmessages.\n\nExample that waits for all messages to be logged, then close the logger and open it again with a new message queue size:\n\n```go\nfor index := 0; index \u003c 1000; index++ {\n    applicationLogger.Info(\"Counter: %d.\", index)\n}\n\n// Wait for all messages to be logged before exiting the program.\napplicationLogger.WaitToFinishLogging()\n\n// Close the logger.\napplicationLogger.Close()\n\n// Open the logger with a new message queue size.\nif err := applicationLogger.Open(100); err != nil {\n    panic(err)\n}\n```\n\n*Note: if you assign a new message queue size that is smaller than the number of messages sent to the queue, the logger\nwill add messages to the queue until it is not full, then it will wait (blocking the process) until the message from the\nqueue will be processed and free up the space in the message queue.*\n\n### Wrappers\n\n#### Error / Panic\n\nYou could wrap error or raise a new error and log error message using the logger. By default, it will log error message\nusing the `level.Error` level. However, it could be changed by setting the error level in the logger configuration.\n\n- Standard logger\n\n  ```go\n  var err error\n  \n  // Raise Error with default error level (level.Error)\n  err = applicationLogger.RaiseError(\"exit code: %d\", 1)\n  \n  // Change error level\n  applicationLogger.SetErrorLevel(level.Alert)\n  \n  // Capture Error with new error level (level.Alert)\n  applicationLogger.CaptureError(err)\n  ```\n\n- Structured logger\n\n  ```go\n  var err error\n  \n  // Raise Error with default error level (level.Error) and additional fields\n  err = applicationLogger.RaiseError(\"exit code: 1\", \"hostname\", \"localhost\")\n  \n  // Change error level\n  applicationLogger.SetErrorLevel(level.Alert)\n  \n  // Capture Error with new error level (level.Alert) and additional fields\n  applicationLogger.CaptureError(err, \"hostname\", \"localhost\")\n  ```\n  \nSimilarly, you could panic and log panic message using the logger. By default, it will log panic message using the\n`level.Critical` level. However, it could be changed by setting the panic level in the logger configuration.\n\n- Standard logger\n\n  ```go\n  // Change panic level\n  applicationLogger.SetPanicLevel(level.Emergency)\n\n  // Raise Panic with new panic level (level.Emergency)\n  applicationLogger.Panic(\"exit code: %d\", 1)\n  ```\n\n- Structured logger\n\n  ```go\n  // Change panic level\n  applicationLogger.SetPanicLevel(level.Emergency)\n  \n  // Raise Panic with new panic level (level.Emergency) and additional fields\n  applicationLogger.Panic(\"exit code: 1\", \"hostname\", \"localhost\")\n  ```\n\n#### Struct\n\nYou could wrap a struct and log its public fields using the logger. To do this, you need to provide template (standard\nlogger), mapping (structured logger) of the struct fields to the logger fields. Optionally, for structured logger you\ncould also provide additional fields that will be logged with the struct fields.\n\n- Standard logger\n\n  ```go\n  type MyStruct struct {\n      String string\n      Int int\n  }\n  \n  myStruct := MyStruct{\n      String: \"example\",\n      Int: 10,\n  }\n  \n  applicationLogger.WrapStruct(level.Info, \"{String}: {Int}\", myStruct)\n  ```\n\n- Structured logger\n\n  ```go\n  type MyStruct struct {\n      String string\n      Int int\n  }\n  \n  myStruct := MyStruct{\n      String: \"example\",\n      Int: 10,\n  }\n  \n  applicationLogger.WrapStruct(level.Info, map[string]string{\n      \"log-string\": \"String\",\n      \"log-int\": \"Int\",\n  }, myStruct, \"hostname\", \"localhost\")\n  ```\n\n#### http.Request and http.Response\n\nYou could wrap http.Request and http.Response and log their fields using the logger. By default, logger has predefined\ntemplate (standard logger), mapping (structured logger) for http.Request and http.Response fields. However, you could\nchange it by providing your own template / mapping. Optionally, for structured logger you could also provide additional\nfields that will be logged with the http.Request and http.Response fields.\n\n- Standard logger\n\n  ```go\n  request, _ := http.NewRequest(\"GET\", \"http://example.com\", nil)\n  response, _ := http.Get(\"http://example.com\")\n  \n  // Set custom template for http.Request and http.Response\n  applicationLogger.SetRequestTemplate(\"[{Method}] {URL}\")\n  applicationLogger.SetResponseTemplate(\"[{StatusCode}] {Status}\")\n  \n  applicationLogger.WrapRequest(level.Info, request)\n  applicationLogger.WrapResponse(level.Info, response)\n  ```\n\n- Structured logger\n\n  ```go\n  request, _ := http.NewRequest(\"GET\", \"http://example.com\", nil)\n  response, _ := http.Get(\"http://example.com\")\n  \n  // Set custom mapping for http.Request and http.Response\n  applicationLogger.SetRequestMapping(map[string]string{\n      \"Method\": \"Method\",\n      \"Url\": \"URL\",\n  })\n  applicationLogger.SetResponseMapping(map[string]string{\n      \"StatusCode\": \"StatusCode\",\n      \"Status\": \"Status\",\n  })\n  \n  applicationLogger.WrapRequest(level.Info, request, \"hostname\", \"localhost\")\n  applicationLogger.WrapResponse(level.Info, response, \"hostname\", \"localhost\")\n  ```\n\n### Reading Configuration from File\n\nYou could also read configuration from a file. Configuration file should be in one of the following formats: `*.json`,\n`*.yaml`, `*.xml`. Configuration file should contain the following fields:\n\n```text\n- Loggers (array of loggers)\n  - Name (string)\n  - Time Format (string)\n  - Error Level (string)\n  - Panic Level (string)\n  - Request Template (string)\n  - Response Template (string)\n  - Request Mapping (map of string to string)\n  - Response Mapping (map of string to string)\n  - Message Queue Size (int)\n  - Handlers (array of handlers)\n    - Type (string)\n    - From Level (string)\n    - To Level (string)\n    - File (string)\n    - Formatter (string)\n      - Type (string)\n      - Pretty Print (bool)\n      - Pair Separator (string)\n      - Key Value Delimiter (string)\n      - Template (template)\n        - String Value (string)\n        - Map Value (map of string to string)\n```\n\nExample of the configuration files:\n\n- JSON\n\n  ```json\n  {\n    \"loggers\": [\n      {\n        \"name\": \"example-logger\",\n        \"time-format\": \"2006-01-02 15:04:05\",\n        \"error-level\": \"error\",\n        \"panic-level\": \"critical\",\n        \"request-template\": \"Request: [{Method}] {URL}\",\n        \"response-template\": \"Response: [{StatusCode}] {Status}\",\n        \"request-mapping\": {\n          \"method\": \"Method\",\n          \"url\": \"URL\"\n        },\n        \"response-mapping\": {\n          \"status-code\": \"StatusCode\",\n          \"status\": \"Status\"\n        },\n        \"message-queue-size\": 100,\n        \"handlers\": [\n          {\n            \"type\": \"stdout\",\n            \"from-level\": \"all\",\n            \"to-level\": \"severe\",\n            \"formatter\": {\n              \"type\": \"json\",\n              \"pretty-print\": false,\n              \"template\": {\n                \"string\": \"%(datetime) - %(level) - %(message)\",\n                \"map\": {\n                  \"timestamp\": \"%(datetime)\",\n                  \"level\": \"%(level)\",\n                  \"name\": \"%(name)\"\n                }\n              }\n            }\n          },\n          {\n            \"type\": \"stderr\",\n            \"from-level\": \"error\",\n            \"to-level\": \"null\",\n            \"formatter\": {\n              \"type\": \"key-value\",\n              \"pair-separator\": \" \",\n              \"key-value-delimiter\": \":\",\n              \"template\": {\n                \"string\": \"%(datetime) - %(level) - %(message)\",\n                \"map\": {\n                  \"timestamp\": \"%(datetime)\",\n                  \"level\": \"%(level)\",\n                  \"name\": \"%(name)\"\n                }\n              }\n            }\n          },\n          {\n            \"type\": \"file\",\n            \"from-level\": \"all\",\n            \"to-level\": \"null\",\n            \"file\": \"example.log\",\n            \"formatter\": {\n              \"type\": \"json\",\n              \"pretty-print\": true,\n              \"template\": {\n                \"string\": \"%(datetime) - %(level) - %(message)\",\n                \"map\": {\n                  \"timestamp\": \"%(datetime)\",\n                  \"level\": \"%(level)\",\n                  \"name\": \"%(name)\"\n                }\n              }\n            }\n          }\n        ]\n      }\n    ]\n  }\n  ```\n\n- YAML\n\n  ```yaml\n  loggers:\n    - name: example-logger\n      time-format: \"2006-01-02 15:04:05\"\n      error-level: error\n      panic-level: critical\n      request-template: \"Request: [{Method}] {URL}\"\n      response-template: \"Response: [{StatusCode}] {Status}\"\n      request-mapping:\n        method: Method\n        url: URL\n      response-mapping:\n        status-code: StatusCode\n        status: Status\n      message-queue-size: 100\n      handlers:\n        - type: stdout\n          from-level: all\n          to-level: severe\n          formatter:\n            type: json\n            pretty-print: false\n            template:\n            string: \"%(datetime) - %(level) - %(message)\"\n            map:\n              timestamp: \"%(datetime)\"\n              level: \"%(level)\"\n              name: \"%(name)\"\n        - type: stderr\n          from-level: error\n          to-level: \"null\"\n          formatter:\n            type: key-value\n            pair-separator: \" \"\n            key-value-delimiter: \":\"\n            template:\n            string: \"%(datetime) - %(level) - %(message)\"\n            map:\n              timestamp: \"%(datetime)\"\n              level: \"%(level)\"\n              name: \"%(name)\"\n        - type: file\n          from-level: all\n          to-level: \"null\"\n          file: example.log\n          formatter:\n            type: json\n            pretty-print: true\n            template:\n            string: \"%(datetime) - %(level) - %(message)\"\n            map:\n              timestamp: \"%(datetime)\"\n              level: \"%(level)\"\n              name: \"%(name)\"\n  ```\n  \n- XML\n\n  ```xml\n  \u003croot\u003e\n    \u003cloggers\u003e\n      \u003clogger\u003e\n        \u003cname\u003eexample-logger\u003c/name\u003e\n        \u003ctime-format\u003e2006-01-02 15:04:05\u003c/time-format\u003e\n        \u003cerror-level\u003eerror\u003c/error-level\u003e\n        \u003cpanic-level\u003ecritical\u003c/panic-level\u003e\n        \u003crequest-template\u003eRequest: [{Method}] {URL}\u003c/request-template\u003e\n        \u003cresponse-template\u003eResponse: [{StatusCode}] {Status}\u003c/response-template\u003e\n        \u003crequest-mapping\u003e\n          \u003cmethod\u003eMethod\u003c/method\u003e\n          \u003curl\u003eURL\u003c/url\u003e\n        \u003c/request-mapping\u003e\n        \u003cresponse-mapping\u003e\n          \u003cstatus-code\u003eStatusCode\u003c/status-code\u003e\n          \u003cstatus\u003eStatus\u003c/status\u003e\n        \u003c/response-mapping\u003e\n        \u003cmessage-queue-size\u003e100\u003c/message-queue-size\u003e\n        \u003chandlers\u003e\n          \u003chandler\u003e\n            \u003ctype\u003estdout\u003c/type\u003e\n            \u003cfrom-level\u003eall\u003c/from-level\u003e\n            \u003cto-level\u003esevere\u003c/to-level\u003e\n            \u003cformatter\u003e\n              \u003ctype\u003ejson\u003c/type\u003e\n              \u003cpretty-print\u003efalse\u003c/pretty-print\u003e\n              \u003ctemplate\u003e\n                \u003cstring\u003e%(datetime) - %(level) - %(message)\u003c/string\u003e\n                \u003cmap\u003e\n                  \u003ctimestamp\u003e%(datetime)\u003c/timestamp\u003e\n                  \u003clevel\u003e%(level)\u003c/level\u003e\n                  \u003cname\u003e%(name)\u003c/name\u003e\n                \u003c/map\u003e\n              \u003c/template\u003e\n            \u003c/formatter\u003e\n          \u003c/handler\u003e\n          \u003chandler\u003e\n            \u003ctype\u003estderr\u003c/type\u003e\n            \u003cfrom-level\u003eerror\u003c/from-level\u003e\n            \u003cto-level\u003enull\u003c/to-level\u003e\n            \u003cformatter\u003e\n              \u003ctype\u003ekey-value\u003c/type\u003e\n              \u003cpair-separator\u003e \u003c/pair-separator\u003e\n              \u003ckey-value-delimiter\u003e:\u003c/key-value-delimiter\u003e\n              \u003ctemplate\u003e\n                \u003cstring\u003e%(datetime) - %(level) - %(message)\u003c/string\u003e\n                \u003cmap\u003e\n                  \u003ctimestamp\u003e%(datetime)\u003c/timestamp\u003e\n                  \u003clevel\u003e%(level)\u003c/level\u003e\n                  \u003cname\u003e%(name)\u003c/name\u003e\n                \u003c/map\u003e\n              \u003c/template\u003e\n            \u003c/formatter\u003e\n          \u003c/handler\u003e\n          \u003chandler\u003e\n            \u003ctype\u003efile\u003c/type\u003e\n            \u003cfrom-level\u003eall\u003c/from-level\u003e\n            \u003cto-level\u003enull\u003c/to-level\u003e\n            \u003cfile\u003eexample.log\u003c/file\u003e\n            \u003cformatter\u003e\n              \u003ctype\u003ejson\u003c/type\u003e\n              \u003cpretty-print\u003etrue\u003c/pretty-print\u003e\n              \u003ctemplate\u003e\n                \u003cstring\u003e%(datetime) - %(level) - %(message)\u003c/string\u003e\n                \u003cmap\u003e\n                  \u003ctimestamp\u003e%(datetime)\u003c/timestamp\u003e\n                  \u003clevel\u003e%(level)\u003c/level\u003e\n                  \u003cname\u003e%(name)\u003c/name\u003e\n                \u003c/map\u003e\n              \u003c/template\u003e\n            \u003c/formatter\u003e\n          \u003c/handler\u003e\n        \u003c/handlers\u003e\n      \u003c/logger\u003e\n    \u003c/loggers\u003e\n  \u003c/root\u003e\n  ```\n\nTo create a logger from the configuration file, you need to:\n\n1. Create a new Parser with the Configuration object. You shall use parser from the `logger` or `structuredlogger`.\n   1. Create a new Configuration object manually and initialize parser with it.\n      1. Parse configuration file to receive the Configuration. You could do this by calling the `ReadFromJSON`,\n      `ReadFromYAML`, `ReadFromXML` methods respectively, it will return the Configuration object.\n\n          ```go\n          // Parse configuration from JSON file.\n          newConfiguration, err := parser.ReadFromJSON(\"path/to/configuration/file.json\")\n          if err != nil {\n              panic(err)\n          }\n          \n          // Parse configuration from YAML file.\n          newConfiguration, err := parser.ReadFromYAML(\"path/to/configuration/file.yaml\")\n          if err != nil {\n              panic(err)\n          }\n          \n          // Parse configuration from XML file.\n          newConfiguration, err := parser.ReadFromXML(\"path/to/configuration/file.xml\")\n          if err != nil {\n              panic(err)\n          }\n          ```\n      2. Create a new Parser with the Configuration object. You shall use parser from the `logger` or `structuredlogger`\n      packages respectively, depending on which one you need.\n\n          ```go\n          newParser := parser.NewParser(newConfiguration)\n          ```\n   2. Create Parser from the configuration file directly.\n\n      ```go\n      // Create a new Parser from JSON configuration file.\n      newParser, err := parser.ParseJSON(\"path/to/configuration/file.json\")\n      if err != nil {\n          panic(err)\n      }\n      \n      // Create a new Parser from YAML configuration file.\n\t  newParser, err := parser.ParseYAML(\"path/to/configuration/file.yaml\")\n      if err != nil {\n          panic(err)\n      }\n\t\t\n      // Create a new Parser from XML configuration file.\n\t  newParser, err := parser.ParseXML(\"path/to/configuration/file.xml\")\n      if err != nil {\n          panic(err)\n      }\n      ```\n\n2. Get a logger from the Parser.\n\n    ```go\n    // Standard Logger\n    newLogger := newParser.GetLogger(\"example-logger\")\n    \n    // Async Logger\n    newLogger := newParser.GetAsyncLogger(\"example-logger\")\n    ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdl1998%2Fgo-logging","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdl1998%2Fgo-logging","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdl1998%2Fgo-logging/lists"}