{"id":18098633,"url":"https://github.com/olehan/kek","last_synced_at":"2025-04-13T13:08:08.603Z","repository":{"id":54418182,"uuid":"198860920","full_name":"olehan/kek","owner":"olehan","description":"🌚 Zero allocated, structured, leveled and very pretty Golang logger","archived":false,"fork":false,"pushed_at":"2019-10-07T12:27:36.000Z","size":90,"stargazers_count":17,"open_issues_count":2,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-13T13:08:01.418Z","etag":null,"topics":["fast","go","golang","leveled","logger","pretty-print","structured-logger","zero-alloc","zero-allocation"],"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/olehan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-07-25T15:52:49.000Z","updated_at":"2022-08-07T16:56:00.000Z","dependencies_parsed_at":"2022-08-13T15:01:00.027Z","dependency_job_id":null,"html_url":"https://github.com/olehan/kek","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olehan%2Fkek","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olehan%2Fkek/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olehan%2Fkek/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olehan%2Fkek/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/olehan","download_url":"https://codeload.github.com/olehan/kek/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248717241,"owners_count":21150389,"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":["fast","go","golang","leveled","logger","pretty-print","structured-logger","zero-alloc","zero-allocation"],"created_at":"2024-10-31T20:12:15.208Z","updated_at":"2025-04-13T13:08:08.566Z","avatar_url":"https://github.com/olehan.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/olehan/kek\"\u003e\n        \u003cimg alt=\"Kek Logo\" src=\"https://raw.githubusercontent.com/olehan/logo/master/kek.png\" width=\"546\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    Zero allocated, structured, leveled and pretty Golang logger\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/olehan/kek/actions?workflow=Lint+and+Test+with+Coverage\"\u003e\n        \u003cimg\n          src=\"https://github.com/olehan/kek/workflows/Lint%20and%20Test%20with%20Coverage/badge.svg?label=shit\"\n          alt=\"Kek Github Action Lint and Test with Coverage\"\n        \u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://travis-ci.org/olehan/kek\"\u003e\n        \u003cimg alt=\"Travis Status\" src=\"https://img.shields.io/travis/olehan/kek?logo=travis\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://codecov.io/gh/olehan/kek\"\u003e\n        \u003cimg alt=\"Kek Code Coverage\" src=\"https://codecov.io/gh/olehan/kek/branch/master/graph/badge.svg\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/olehan/kek/blob/master/LICENSE\"\u003e\n        \u003cimg alt=\"Kek License\" src=\"https://img.shields.io/github/license/olehan/kek.svg\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/olehan/kek/releases\"\u003e\n        \u003cimg alt=\"Kek Last Release\" src=\"https://img.shields.io/github/tag/olehan/kek.svg?label=release\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n----\n\n\u003cp align=\"center\"\u003e\n    \u003cstrong\u003e\u003ca href=\"#intro\"\u003eIntro\u003c/a\u003e\u003c/strong\u003e\n    |\n    \u003cstrong\u003e\u003ca href=\"#benchmarks\"\u003eBenchmarks\u003c/a\u003e\u003c/strong\u003e\n    |\n    \u003cstrong\u003e\u003ca href=\"#usage\"\u003eUsage\u003c/a\u003e\u003c/strong\u003e\n    |\n    \u003cstrong\u003e\u003ca href=\"#installation\"\u003eInstallation\u003c/a\u003e\u003c/strong\u003e\n    |\n    \u003cstrong\u003e\u003ca href=\"#license\"\u003eLicense\u003c/a\u003e\u003c/strong\u003e\n\u003c/p\u003e\n\n----\n\n\u003ch2 id=\"intro\"\u003e🌚 Intro\u003c/h2\u003e\n\n***Code:***\n```go\n// Here we are, just creating our new logger with a default 'formatter'.\n// We'll talk about formatters letter on Usage section...\nlogger := kek.NewLogger(\"logger\", \"name\")\nlogger.Debug.Println(\"And that is it!\")\n```\n***Output:***\n```\nlogger.name | debug  2019/7/28 20:54:40.683859000 [4666]:   And that is it!\n```\n\n\u003ch2 id=\"benchmarks\"\u003e🏃 Benchmarks\u003c/h2\u003e\n\n***Machine:***\n```\nIntel Xeon E3-1280 v6\nCores: 4x 3.90 GHz (Single Quad Core)\n32 GB RAM\n2x 1 TB SATA 7.2k RPM (Software RAID 1)\nUbuntu 18.04 (Bionic Beaver) LTS minimal [64bit]\n\nUptime 1 day\n```\n\n***Results in average from 15 runs:***\n```bash\nBenchmarkLogger_PrintlnWithEmptyWriter-8    \t 1530000\t       760 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkLogger_PrintlnWithStdoutWriter-8         590000\t      2010 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkLogger_PrintTMithEmptyWriter-8     \t 1450000\t       815 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkLogger_PrintTMithStdoutWriter-8          570000\t      2050 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkLogger_PrintTMWithEmptyWriter-8    \t 1350000\t       870 ns/op\t       0 B/op\t       0 allocs/op\nBenchmarkLogger_PrintTMWithStdoutWriter-8         550000\t      2100 ns/op\t       0 B/op\t       0 allocs/op\nPASS\nok  \tgithub.com/olehan/kek/benchmarks\t9s\n```\n\n\n\u003ch2 id=\"usage\"\u003e🔧 Usage\u003c/h2\u003e\n\nAight. If you're staying with me to see more complex usage of this lib - go into the [examples](examples) folder or keep reading.\n\n#### Factories\nThese are things that help you to populate logger with a specific configuration that\nis going to be 'linked' to a logger or just copied, so modification to the factory won't\naffect on other loggers.\n\n```go\nfactory := kek.NewFactory(\n    // First arg is an io.Writer\n    os.Stdout,\n    // And the second is the formatter. Don't worry, we've got some\n    // formatter packed up within the lib. But if you want, you\n    // can create your formatter and give your logs\n    // a new life.\n    sugared.Formatter,\n)\n\n// Now let's modify this factory a little bit.\nfactory.\n    SetWithColors(true).\n    SetWithDate(false).\n    SetWithMutex(true)\n\n// Alright, now our logger have extended factory configurations.\nlogger := factory.NewLogger()\n// And even can modify his own config, not affecting the factory.\nlogger.SetWithDate(true)\n\n// But for those who wants to link loggers coming out of your\n// factory, we've got NewLinkedLogger func.\n// It returns the same logger, except its configurations are linked\n// to the factory.\nlinkedLogger := factory.NewLinkedLogger()\n// So any change made for the factory is going to affect a linked\n// logger.\nfactory.SetWithNS(false)\n```\n\n#### Loggers\nThe logger is a thing that you use to write logs into a writer.\nTo use them you need to create a new one from the factory to extend\nalready specified configs or just use default configs by using the\npublic `NewLogger(name ...string) *Logger` function.\n```go\nkey.NewLogger().Info.Println(\"yeah\")\n```\n\n#### Formatters\nOke, now I know that there is a lot of projects that need a specific\nlog format and for that purposes to log stuff, you'll need\na formatter that will control every log. There is a set of configurable\n(or not) default formatters made to save your time.\n\n***Code:***\n```go\nminified := kek.NewLogger(\"minified\").SetFormatter(minified.Formatter)\nsugared := kek.NewLogger(\"sugared\").SetFormatter(sugared.Formatter)\nminified.Debug.Println(\"yeah\")\nsugared.Info.Println(\"YEAAAH\")\n``` \n***Output:***\n```\nminified - debug: yeah\nsugared  | info  2019/7/28 21:27:27.788431000 [4715]: YEAAAH\n```\n\n#### Logger names\nEvery logger can have a name and a factory can also have a prefix for\na logger. This functionality is not necessary, but I should say that\nis pretty useful when you need to separate loggers to get the context\nof a process.\n\n***Code:***\n```go\nfactory := kek.NewFactory(\"service\")\n// Oh, and there is also a name tabulation, but it will take affect\n// depends on your formatter.\nfactory.SetNameTabulation(true)\n\nuserPostsLogger := factory.NewLogger(\"user\", \"posts\")\nuserCommentsLogger := factory.NewLogger(\"user\", \"comments\")\n\n// If a property 'WithColors' is enabled, you can set a random color\n// for the loggers name.\nuserPostsLogger.SetRandomNameColor()\n\nuserPostsLogger.Debug.Println(\"Post edited\")\nuserCommentsLogger.Warn.Println(\"Comments are refreshed\")\n```\n\n***Output:***\n```\n# Welp, to see the colors - head over to the examples folder.\nservice/user.posts    | debug 2019/7/28 21:27:27.788431000 [4715]: Post edited\nservice/user.comments | warn  2019/7/28 21:27:27.788521000 [4715]: Comments are refreshed\n```\n\n#### Printer Types\nThe printer is the function that handles the job of executing a formatter and pool (🚰) management.\nFor a moment of this documentation kek delivers 3 types of printers:\n* ***Base*** - the only printer that you've seen so far (`Print`, `Println`)\n* ***Template*** - a printer that takes a format of a log and inserts values into it\n(`PrintT`, `PrintTM`, `PrintTKV`)\n* ***Structured*** - a printer that takes a message and writes key-value pairs in a specific structured way (`PrintSKV`)\n\n***Code:***\n```go\nlogger := kek.NewLogger()\nlogger.Debug.\n    PrintT(\"wassup, {} - {}\", \"boi\", 123).\n    PrintTM(\"wassup, NewMap{{name}}, Age: {{age}}\",\n        ds.NewMap().\n            Set(\"name\", \"Boi\").\n            Set(\"age\", 17),\n    ).\n    PrintTM(\"wassup, Map{{name}}\", ds.Map{\n        \"name\": \"Boi\",\n    }).\n    PrintTKV(\"wassup, KeyValue{{name}} {{34}} {{134}} - {{unknown}}\",\n        \"name\", \"Boi\",\n        \"34\", true,\n        // Skips the key that is not a string.\n        134, \"ooh\",\n        // Skips the key value pair without a value.\n        \"unknown\",\n    )\n\nlogger.Info.\n    PrintSKV(\"message for key values\",\n        \"key1\", \"value1\",\n        \"key2\", 242456246,\n        \"key3\", true,\n        \"key4\", 135135.13413,\n    )\n```\n\n***Output:***\n```\ndebug 2019/7/28 21:53:20.501202000 [4775]:   wassup, boi - 123\ndebug 2019/7/28 21:53:20.501296000 [4775]:   wassup, NewMapBoi, Age: 17\ndebug 2019/7/28 21:53:20.501300000 [4775]:   wassup, MapBoi\ndebug 2019/7/28 21:53:20.501305000 [4775]:   wassup, KeyValueBoi true {{134}} - {{unknown}}\ninfo  2019/7/28 21:56:20.501355000 [4811]:   message for key values\n \u003e key1: value1\n \u003e key2: 242456246\n \u003e key3: true\n \u003e key4: 135135.13413\n```\n\n\u003ch2 id=\"installation\"\u003e⬇️ Installation\u003c/h2\u003e\n\n```go\ngo get github.com/olehan/kek\n```\n\n\u003ch2 id=\"license\"\u003e🔖 License\u003c/h2\u003e\n\nIt's [MIT](LICENSE).\nWhat else would you expect? 🌚\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Folehan%2Fkek","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Folehan%2Fkek","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Folehan%2Fkek/lists"}