{"id":24355537,"url":"https://github.com/mishankov/logman","last_synced_at":"2025-04-15T14:04:21.938Z","repository":{"id":270729896,"uuid":"911269737","full_name":"mishankov/logman","owner":"mishankov","description":"🍲 Deeply configurable logging library for Go with no configuration required to start","archived":false,"fork":false,"pushed_at":"2025-02-03T06:38:04.000Z","size":1773,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-03T07:33:08.439Z","etag":null,"topics":["golang","logging","tdd"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/mishankov/logman","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/mishankov.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":"2025-01-02T16:16:30.000Z","updated_at":"2025-02-03T06:38:04.000Z","dependencies_parsed_at":"2025-01-02T18:24:26.283Z","dependency_job_id":"e109c653-1825-4a46-a300-2b13b67b909e","html_url":"https://github.com/mishankov/logman","commit_stats":null,"previous_names":["mishankov/logman"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mishankov%2Flogman","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mishankov%2Flogman/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mishankov%2Flogman/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mishankov%2Flogman/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mishankov","download_url":"https://codeload.github.com/mishankov/logman/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243176262,"owners_count":20248620,"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":["golang","logging","tdd"],"created_at":"2025-01-18T17:57:41.759Z","updated_at":"2025-04-15T14:04:21.932Z","avatar_url":"https://github.com/mishankov.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Logman\n\n[![Coverage Status](https://coveralls.io/repos/github/mishankov/logman/badge.svg)](https://coveralls.io/github/mishankov/logman)\n[![CI](https://img.shields.io/github/actions/workflow/status/mishankov/logman/ci.yml)](https://github.com/mishankov/logman/actions/workflows/ci.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/mishankov/logman)](https://goreportcard.com/report/github.com/mishankov/logman)\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./images/logo.png\" alt=\"logo\" width=\"200\"/\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n Deeply configurable logging library for Go with no configuration required to start\n\u003c/p\u003e\n\n# Installation\n\n```bash\ngo get -u github.com/mishankov/logman\n```\n\n# Usage\n## Default logger\n\nFor basic log output to stdout, the default logger can be used:\n\n```go\npackage main\n\nimport \"github.com/mishankov/logman/loggers\"\n\nfunc main() {\n\tlogger := loggers.NewDefaultLogger()\n\tlogger.Info(\"Hello, world!\")\n}\n```\n\nOutput:\n\n```\n[2009-11-10 23:00:00 GMT+0000] [main.main:7] [Info] - Hello, world!\n```\n\n## Available logging functions\n\n### Default functions\n\n```go\npackage main\n\nimport (\n\t\"github.com/mishankov/logman\"\n\t\"github.com/mishankov/logman/loggers\"\n)\n\nfunc main() {\n\tlogger := loggers.NewDefaultLogger()\n\n\tlogger.Debug(\"Hello,\", \"world!\")\n\tlogger.Info(\"Hello,\", \"world!\")\n\tlogger.Warn(\"Hello,\", \"world!\")\n\tlogger.Error(\"Hello,\", \"world!\")\n\tlogger.Fatal(\"Hello,\", \"world!\")\n\n\tlogger.Log(logman.Info, \"Hello,\", \"world!\")\n}\n```\n\nOutput:\n```\n[2009-11-10 23:00:00 GMT+0000] [main.main:11] [Debug] - Hello, world!\n[2009-11-10 23:00:00 GMT+0000] [main.main:12] [Info] - Hello, world!    \n[2009-11-10 23:00:00 GMT+0000] [main.main:13] [Warn] - Hello, world!    \n[2009-11-10 23:00:00 GMT+0000] [main.main:14] [Error] - Hello, world!   \n[2009-11-10 23:00:00 GMT+0000] [main.main:15] [Fatal] - Hello, world!   \n[2009-11-10 23:00:00 GMT+0000] [main.main:17] [Info] - Hello, world!\n```\n\n### Functions with string formatting\n\n```go\npackage main\n\nimport (\n\t\"github.com/mishankov/logman\"\n\t\"github.com/mishankov/logman/loggers\"\n)\n\nfunc main() {\n\tlogger := loggers.NewDefaultLogger()\n\n\tlogger.Debugf(\"Hello, %s!\", \"world\")\n\tlogger.Infof(\"Hello, %s!\", \"world\")\n\tlogger.Warnf(\"Hello, %s!\", \"world\")\n\tlogger.Errorf(\"Hello, %s!\", \"world\")\n\tlogger.Fatalf(\"Hello, %s!\", \"world\")\n\n\tlogger.Logf(logman.Info, \"Hello, %s!\", \"world\")\n}\n```\n\nOutput:\n```\n[2009-11-10 23:00:00 GMT+0000] [main.main:11] [Debug] - Hello, world!\n[2009-11-10 23:00:00 GMT+0000] [main.main:12] [Info] - Hello, world!\n[2009-11-10 23:00:00 GMT+0000] [main.main:13] [Warn] - Hello, world!\n[2009-11-10 23:00:00 GMT+0000] [main.main:14] [Error] - Hello, world!\n[2009-11-10 23:00:00 GMT+0000] [main.main:15] [Fatal] - Hello, world!\n[2009-11-10 23:00:00 GMT+0000] [main.main:17] [Info] - Hello, world!\n```\n\n### Structured logging\n\nStructured logging functions allow to add key-value pairs to messages\n\n```go\npackage main\n\nimport (\n\t\"github.com/mishankov/logman\"\n\t\"github.com/mishankov/logman/loggers\"\n)\n\nfunc main() {\n\tlogger := loggers.NewDefaultLogger()\n\n\tlogger.Debugs(\"Hello, world!\", \"key1\", \"value\", \"key2\", 1234)\n\tlogger.Infos(\"Hello, world!\", \"key1\", \"value\", \"key2\", 1234)\n\tlogger.Warns(\"Hello, world!\", \"key1\", \"value\", \"key2\", 1234)\n\tlogger.Errors(\"Hello, world!\", \"key1\", \"value\", \"key2\", 1234)\n\tlogger.Fatals(\"Hello, world!\", \"key1\", \"value\", \"key2\", 1234)\n\n\tlogger.Logs(logman.Info, \"Hello, world!\", \"key1\", \"value\", \"key2\", 1234)\n}\n```\n\nOutput:\n```\n[2009-11-10 23:00:00 GMT+0000] [main.main:11] [Debug] - Hello, world! key1=value key2=1234\n[2009-11-10 23:00:00 GMT+0000] [main.main:12] [Info] - Hello, world! key1=value key2=1234\n[2009-11-10 23:00:00 GMT+0000] [main.main:13] [Warn] - Hello, world! key1=value key2=1234\n[2009-11-10 23:00:00 GMT+0000] [main.main:14] [Error] - Hello, world! key1=value key2=1234\n[2009-11-10 23:00:00 GMT+0000] [main.main:15] [Fatal] - Hello, world! key1=value key2=1234\n[2009-11-10 23:00:00 GMT+0000] [main.main:17] [Info] - Hello, world! key1=value key2=1234\n```\n\n### Logging values from context\n\n`logman` supports logging methods that recieves `context.Context` as first parameters to log values from it. In default logger it does nothing. Only way to utilize it is to use custom or one of provided formatters (`DefaultContextFormatter`, `JSONContextFormatter`) with custom logger (more about it later). \n\nExample:\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/mishankov/logman\"\n\t\"github.com/mishankov/logman/formatters\"\n)\n\ntype ContextValueKey string\n\nfunc (cvk ContextValueKey) String() string {\n\treturn string(cvk)\n}\n\nconst (\n\tContextValueKey1 ContextValueKey = \"key1\"\n\tContextValueKey2 ContextValueKey = \"key2\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\tctx = context.WithValue(ctx, ContextValueKey1, \"value 1\")\n\tctx = context.WithValue(ctx, ContextValueKey2, 4)\n\n\tlogger := logman.NewLogger(os.Stdout, formatters.NewDefaultContextFormatter(formatters.DefaultTimeLayout, []fmt.Stringer{ContextValueKey1, ContextValueKey2}), nil)\n\tlogger.DebugsCtx(ctx, \"default logger\", \"param1\", \"value1\")\n\n\tloggerJSON := logman.NewLogger(os.Stdout, formatters.NewJSONContextFormatter(formatters.DefaultTimeLayout, []fmt.Stringer{ContextValueKey1, ContextValueKey2}), nil)\n\tloggerJSON.DebugsCtx(ctx, \"json logger\", \"param1\", \"value1\")\n}\n```\n\nOutput:\n```\ntime=\"2009-11-10 23:00:00 GMT+0000\" level=Debug location=main.main:29 msg=\"default logger\" key1=\"value 1\" key2=4 param1=value1\n{\"key1\":\"value 1\",\"key2\":4,\"level\":\"Debug\",\"location\":\"main.main:32\",\"msg\":\"json logger\",\"param1\":\"value1\",\"time\":\"2009-11-10 23:00:00 GMT+0000\"}\n```\n\n## Custom logger\n\nYou can use `logman.NewLogger` to create a custom logger. For example, this is how to mimic `loggers.NewDefaultLogger` using `logman.NewLogger`:\n\n```go\npackage main\n\nimport (\n\t\"os\"\n\t\"github.com/mishankov/logman\"\n\t\"github.com/mishankov/logman/formatters\"\n)\n\nfunc main() {\n\tlogger := logman.NewLogger(os.Stdout, formatters.NewDefaultFormatter(formatters.DefaultFormat, formatters.DefaultTimeLayout), nil)\n}\n```\n\n## Writers\n\nWriters output logs to some destination. Every writer should implement the `io.Writer` interface. Logman provides `FileWriter`:\n\n```go\npackage main\n\nimport \"github.com/mishankov/logman/writers\"\n\nfunc main() {\n\tfw, _ := writers.NewFileWriter(\"test.log\")\n}\n```\n\n`DefaultLogger` uses `os.Stdout` as writer.\n\n## Formatters\n\nFormatters format log messages before they are passed to the writer. Every formatter should implement the `logman.Formatter` interface. Logman provides `DefaultFormatter`, `JSONFormatter`, `DefaultContextFormatter` and `JSONContextFormatter`:\n\n```go\npackage main\n\nimport \"github.com/mishankov/logman/formatters\"\n\nfunc main() {\n\tformatter := formatters.NewDefaultFormatter(formatters.DefaultFormat, formatters.DefaultTimeLayout)\n\tjsonFormatter := formatters.NewJSONFormatter()\n}\n```\n\n## Filters\n\nFilters filter log messages. Every filter should implement the `logman.Filter` interface. Logman provides `LevelFilter`:\n\n```go\npackage main\n\nimport \"github.com/mishankov/logman/filters\"\n\nfunc main() {\n\tfilter := filters.NewLevelFilter(logman.Info)\n}\n```\n\n## Examples\n\nLet's see how to create a custom logger that outputs Error or higher level messages in JSON format to a file:\n\n```go\npackage main\n\nimport (\n\t\"github.com/mishankov/logman\"\n\t\"github.com/mishankov/logman/filters\"\n\t\"github.com/mishankov/logman/formatters\"\n\t\"github.com/mishankov/logman/writers\"\n)\n\nfunc main() {\n\tfw, _ := writers.NewFileWriter(\"error.log\")\n\tformatter := formatters.NewJSONFormatter()\n\tfilter := filters.NewLevelFilter(logman.Error)\n\tlogger := logman.NewLogger(fw, formatter, filter)\n\n\tlogger.Error(\"Hello,\", \"world!\")\n\tlogger.Debug(\"I am not logged\")\n}\n```\n\n`error.log` content:\n```json\n{\"callLocation\":\"main.main:16\",\"logLevel\":\"Error\",\"message\":\"Hello, world!\",\"time\":\"2009-11-10 23:00:00 GMT+0000\"}\n```\n\n# Motivation\n\n- Practice Golang and TDD skills\n- Simple but flexible logging for personal projects\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmishankov%2Flogman","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmishankov%2Flogman","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmishankov%2Flogman/lists"}