{"id":370021,"date":"2024-05-21T04:16:17","date_gmt":"2024-05-21T04:16:17","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=370021"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=370021","title":{"rendered":"<span>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 Go \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Slog<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0411\u043e\u043b\u0435\u0435 10 \u043b\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043d\u0430 Go \u0436\u0430\u043b\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u043d\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u044f\u0434\u0440\u0435 Golang. \u0423\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430 Golang \u0434\u0430\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a Logrus, Zap \u0438 Zerolog. \u0412 2023 \u0433\u043e\u0434\u0443, \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 Google Go \u043d\u0430\u043a\u043e\u043d\u0435\u0446-\u0442\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043b\u0430 Slog \u2014 \u0432\u044b\u0441\u043e\u043a\u043e\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u0434\u043b\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043b\u043e\u0433\u043e\u0432 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 Go. \u041c\u044b \u043f\u0435\u0440\u0435\u0432\u0435\u043b\u0438 \u0433\u0430\u0439\u0434 \u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u0445 slog.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bf1\/2b8\/ea3\/bf12b8ea302fa7ab933320a44eabca25.png\" width=\"780\" height=\"440\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bf1\/2b8\/ea3\/bf12b8ea302fa7ab933320a44eabca25.png\"\/><\/figure>\n<h2>\u041f\u0440\u0435\u0434\u044b\u0441\u0442\u043e\u0440\u0438\u044f<\/h2>\n<p>\u041f\u0430\u043a\u0435\u0442 <a href=\"https:\/\/pkg.go.dev\/log\/slog\"><u>Slog<\/u><\/a> \u0431\u0435\u0440\u0435\u0442 \u0441\u0432\u043e\u0435 \u043d\u0430\u0447\u0430\u043b\u043e <a href=\"https:\/\/github.com\/golang\/go\/discussions\/54763\"><u>\u0432 \u0434\u0438\u0441\u043a\u0443\u0441\u0441\u0438\u0438 \u043d\u0430 GitHub, \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0439 \u0414\u0436\u043e\u043d\u0430\u0442\u0430\u043d\u043e\u043c \u0410\u043c\u0441\u0442\u0435\u0440\u0434\u0430\u043c\u043e\u043c<\/u><\/a>. \u0412 \u043d\u0435\u0439 \u0431\u044b\u043b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u0430\u043a\u0435\u0442\u0430. \u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u043d \u0431\u044b\u043b \u0432\u044b\u043f\u0443\u0449\u0435\u043d \u0432 <a href=\"https:\/\/tip.golang.org\/doc\/go1.21\"><u>Go v1.21<\/u><\/a> \u0438 \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 <code>log\/slog<\/code>.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 Slog \u0441 \u0441\u043e\u043f\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438. \u0414\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u043c\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 Go \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044c \u043a \u044d\u0442\u043e\u043c\u0443 <a href=\"https:\/\/github.com\/betterstack-community\/go-logging-benchmarks\"><u>\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044e GitHub<\/u><\/a>.<\/p>\n<h2>\u041d\u0430\u0447\u0430\u043b\u043e \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e Slog<\/h2>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0435\u043c \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 \u043f\u0430\u043a\u0435\u0442\u043e\u043c <code>log\/slog<\/code> \u0441 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043e\u043d \u0441\u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d. \u041e\u043d \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u0440\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0442\u0438\u043f\u0430, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0432\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0437\u043d\u0430\u043a\u043e\u043c\u044b:<\/p>\n<ul>\n<li>\n<p><code>Logger<\/code>: \u044d\u0442\u043e &#171;\u0444\u0440\u043e\u043d\u0442\u044d\u043d\u0434&#187; \u043b\u043e\u0433\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u0435\u0442\u043e\u0434\u044b \u0443\u0440\u043e\u0432\u043d\u044f (<code>Info()<\/code> \u0438 <code>Error()<\/code>) \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439.<\/p>\n<\/li>\n<li>\n<p><code>Record<\/code>: \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0436\u0443\u0440\u043d\u0430\u043b\u0430, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e <code>Logger<\/code>.<\/p>\n<\/li>\n<li>\n<p><code>Handler<\/code>: \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u0431\u0443\u0434\u0443\u0447\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e <code>Record<\/code>. \u0412 \u043f\u0430\u043a\u0435\u0442 <code>log\/slog<\/code> \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u0434\u0432\u0430 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430: <code>TextHandler<\/code> \u0438 <code>JSONHandler<\/code> \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <code>key=value<\/code> \u0438 JSON \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u0430\u043a \u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 Go, \u043f\u0430\u043a\u0435\u0442 <code>slog<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 <code>Logger<\/code>, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u0447\u0435\u0440\u0435\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f. \u042d\u0442\u043e\u0442 \u043b\u043e\u0433\u0435\u0440 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u043f\u043e\u0447\u0442\u0438 \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u043a\u0430\u043a \u0438 \u0441\u0442\u0430\u0440\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <code>log.Printf()<\/code>, \u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u0436\u0443\u0440\u043d\u0430\u043b\u0430:<\/p>\n<pre><code class=\"go\">package main  import (     \"log\"     \"log\/slog\" )  func main() {     log.Print(\"Info message\")     slog.Info(\"Info message\") } <\/code><\/pre>\n<pre><code>2024\/01\/03 10:24:22 Info message 2024\/01\/03 10:24:22 INFO Info message<\/code><\/pre>\n<p>\u042d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u0430\u043d\u043d\u043e, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f, \u0447\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0446\u0435\u043b\u044c Slog \u2014 \u043f\u0440\u0438\u0432\u043d\u0435\u0441\u0442\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043b\u043e\u0433\u043e\u0432 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443.<\/p>\n<p>\u0418\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e, \u0441\u043e\u0437\u0434\u0430\u0432 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>Logger<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <code>slog.New()<\/code>. \u041e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <code>Handler<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u043a\u0430\u043a \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0436\u0443\u0440\u043d\u0430\u043b\u044b \u0438 \u043a\u0443\u0434\u0430 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u044b.<\/p>\n<p>\u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0439 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f <code>JSONHandler<\/code> \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 JSON-\u043b\u043e\u0433\u043e\u0432 \u0432 <code>stdout<\/code>:<\/p>\n<pre><code class=\"go\">func main() {     logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))     logger.Debug(\"Debug message\")     logger.Info(\"Info message\")     logger.Warn(\"Warning message\")     logger.Error(\"Error message\") } <\/code><\/pre>\n<pre><code>{\"time\":\"2023-03-15T12:59:22.227408691+01:00\",\"level\":\"INFO\",\"msg\":\"Info message\"} {\"time\":\"2023-03-15T12:59:22.227468972+01:00\",\"level\":\"WARN\",\"msg\":\"Warning message\"} {\"time\":\"2023-03-15T12:59:22.227472149+01:00\",\"level\":\"ERROR\",\"msg\":\"Error message\"}<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0432\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>TextHandler<\/code>, \u043a\u0430\u0436\u0434\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u043c Logfmt:<\/p>\n<pre><code class=\"go\">logger := slog.New(slog.NewTextHandler(os.Stdout, nil))<\/code><\/pre>\n<pre><code>time=2023-03-15T13:00:11.333+01:00 level=INFO msg=\"Info message\" time=2023-03-15T13:00:11.333+01:00 level=WARN msg=\"Warning message\" time=2023-03-15T13:00:11.333+01:00 level=ERROR msg=\"Error message\"<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b <code>Logger<\/code> \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432\u0435\u0434\u0443\u0442 \u0436\u0443\u0440\u043d\u0430\u043b \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 <code>INFO<\/code>, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043f\u043e\u0434\u0430\u0432\u043b\u0435\u043d\u0438\u044e \u0437\u0430\u043f\u0438\u0441\u0438 <code>DEBUG<\/code>, \u043d\u043e \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043b\u0435\u0433\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u044d\u0442\u043e \u043f\u043e \u0441\u0432\u043e\u0435\u043c\u0443 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044e.<\/p>\n<h2>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043b\u043e\u0433\u0435\u0440\u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e<\/h2>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 <code>Logger<\/code> \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>slog.SetDefault()<\/code>, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043b\u043e\u0433\u0435\u0440 \u043d\u0430 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439.<\/p>\n<pre><code class=\"go\">func main() {     logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))      slog.SetDefault(logger)      slog.Info(\"Info message\") }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u043c\u0435\u0442\u043e\u0434\u044b \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u043f\u0430\u043a\u0435\u0442\u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u044b\u0434\u0430\u044e\u0442 JSON, \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0438\u0436\u0435:<\/p>\n<pre><code>{\"time\":\"2023-03-15T13:07:39.105777557+01:00\",\"level\":\"INFO\",\"msg\":\"Info message\"}<\/code><\/pre>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 <code>SetDefault()<\/code> \u0442\u0430\u043a\u0436\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 <code>log.Logger<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u043f\u0430\u043a\u0435\u0442\u043e\u043c <code>log<\/code>. \u0422\u0430\u043a\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u043c \u0441\u0442\u0430\u0440\u044b\u0439 <code>log<\/code>, \u043f\u043b\u0430\u0432\u043d\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c\u0443 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e:<\/p>\n<pre><code class=\"go\">func main() {     logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))      slog.SetDefault(logger)      \/\/ elsewhere in the application     log.Println(\"Hello from old logger\") }<\/code><\/pre>\n<pre><code>{\"time\":\"2023-03-16T15:20:33.783681176+01:00\",\"level\":\"INFO\",\"msg\":\"Hello from old logger\"}<\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>slog.NewLogLogger()<\/code> \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f <code>slog.Logger<\/code> \u0432 <code>log.Logger<\/code>, \u043a\u043e\u0433\u0434\u0430 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c API, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>http.Server.ErrorLog<\/code>):<\/p>\n<pre><code class=\"go\">func main() {     handler := slog.NewJSONHandler(os.Stdout, nil)      logger := slog.NewLogLogger(handler, slog.LevelError)      _ = http.Server{         \/\/ this API only accepts `log.Logger`         ErrorLog: logger,     } } <\/code><\/pre>\n<h2>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u0432 \u0437\u0430\u043f\u0438\u0441\u0438 \u0436\u0443\u0440\u043d\u0430\u043b\u0430<\/h2>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u043d\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0444\u043e\u0440\u043c\u0430\u0442\u0430\u043c\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u0432 \u0432\u0438\u0434\u0435 \u043f\u0430\u0440 \u043a\u043b\u044e\u0447\/\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u0437\u0430\u043f\u0438\u0441\u0438 \u0436\u0443\u0440\u043d\u0430\u043b\u0430.<\/p>\n<p>\u042d\u0442\u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0438. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0434\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447, \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043d\u0435\u043f\u043e\u043b\u0430\u0434\u043e\u043a, \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043c\u0435\u0442\u0440\u0438\u043a, \u0430\u0443\u0434\u0438\u0442 \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u0446\u0435\u043b\u0435\u0439.<\/p>\n<p>\u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0439, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 Slog:<\/p>\n<pre><code class=\"go\">logger.Info(   \"incoming request\",   \"method\", \"GET\",   \"time_taken_ms\", 158,   \"path\", \"\/hello\/world?q=search\",   \"status\", 200,   \"user_agent\", \"Googlebot\/2.1 (+http:\/\/www.google.com\/bot.html)\", )<\/code><\/pre>\n<pre><code>{   \"time\":\"2023-02-24T11:52:49.554074496+01:00\",   \"level\":\"INFO\",   \"msg\":\"incoming request\",   \"method\":\"GET\",   \"time_taken_ms\":158,   \"path\":\"\/hello\/world?q=search\",   \"status\":200,   \"user_agent\":\"Googlebot\/2.1 (+http:\/\/www.google.com\/bot.html)\" }<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0443\u0440\u043e\u0432\u043d\u044f (<code>Info()<\/code>, <code>Debug()<\/code> \u0438 \u0442. \u0434.) \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430, \u0430 \u0437\u0430\u0442\u0435\u043c \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043b\u0430\u0431\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u0430\u0440 \u043a\u043b\u044e\u0447\/\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.<\/p>\n<p>\u042d\u0442\u043e\u0442 API \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 SugaredLogger API \u0432 Zap (\u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u044b \u0443\u0440\u043e\u0432\u043d\u044f, \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u043d\u0430 <code>w<\/code>), \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432 \u043d\u0435\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043e\u0442\u0434\u0430\u0435\u0442\u0441\u044f \u043a\u0440\u0430\u0442\u043a\u043e\u0441\u0442\u0438 \u0437\u0430 \u0441\u0447\u0435\u0442 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p>\u041d\u043e \u0431\u0443\u0434\u044c\u0442\u0435 \u043e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u044b, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u044b\u043c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u043d\u0435\u0441\u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0430\u0440\u044b \u043a\u043b\u044e\u0447\/\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u043c\u0443 \u0432\u044b\u0432\u043e\u0434\u0443:<\/p>\n<pre><code class=\"go\">logger.Info(   \"incoming request\",   \"method\", \"GET\",   \"time_taken_ms\", \/\/ the value for this key is missing )<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043a\u043b\u044e\u0447 <code>time_taken_ms<\/code> \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441 \u043a\u043b\u044e\u0447\u043e\u043c <code>!BADKEY<\/code>. \u042d\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0435\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043b\u043e\u0445\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0435 \u0437\u043d\u0430\u0442\u044c \u043e\u0431 \u044d\u0442\u043e\u043c \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u0432\u0430\u043c \u043d\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0436\u0443\u0440\u043d\u0430\u043b\u044b.<\/p>\n<pre><code>{   \"time\": \"2023-03-15T13:15:29.956566795+01:00\",   \"level\": \"INFO\",   \"msg\": \"incoming request\",   \"method\": \"GET\",   \"!BADKEY\": \"time_taken_ms\" }<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <a href=\"https:\/\/pkg.go.dev\/cmd\/vet\"><u>vet<\/u><\/a> \u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/github.com\/go-simpler\/sloglint\"><u>\u043b\u0438\u043d\u0442\u0435\u0440<\/u><\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u043e \u0442\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0445.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5fe\/73d\/1d6\/5fe73d1d62e05e139cc154c126ff83a8.png\" alt=\"\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\" title=\"\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\" width=\"650\" height=\"244\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5fe\/73d\/1d6\/5fe73d1d62e05e139cc154c126ff83a8.png\"\/><\/p>\n<div><figcaption><a href=\"https:\/\/betterstack.com\/community\/guides\/logging\/logging-in-go\/#customizing-the-default-logger\"><u>\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a<\/u><\/a><\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u0440\u0443\u0433\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/pkg.go.dev\/log\/slog#Attr\"><u>\u0441\u0438\u043b\u044c\u043d\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b<\/u><\/a>, \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0438\u0436\u0435:<\/p>\n<pre><code class=\"go\">logger.Info(   \"incoming request\",   slog.String(\"method\", \"GET\"),   slog.Int(\"time_taken_ms\", 158),   slog.String(\"path\", \"\/hello\/world?q=search\"),   slog.Int(\"status\", 200),   slog.String(     \"user_agent\",     \"Googlebot\/2.1 (+http:\/\/www.google.com\/bot.html)\",   ), )<\/code><\/pre>\n<p>\u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c\u0443 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043b\u0443\u0447\u0448\u0435, \u043d\u043e \u043e\u043d \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u043c, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0438\u0447\u0442\u043e \u043d\u0435 \u043c\u0435\u0448\u0430\u0435\u0442 \u0432\u0430\u043c \u0441\u043c\u0435\u0448\u0438\u0432\u0430\u0442\u044c \u0441\u0438\u043b\u044c\u043d\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0438 \u0441\u043b\u0430\u0431\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0430\u0440\u044b \u043a\u043b\u044e\u0447\/\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"go\">logger.Info(   \"incoming request\",   \"method\", \"GET\",   slog.Int(\"time_taken_ms\", 158),   slog.String(\"path\", \"\/hello\/world?q=search\"),   \"status\", 200,   slog.String(     \"user_agent\",     \"Googlebot\/2.1 (+http:\/\/www.google.com\/bot.html)\",   ), )<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c \u0442\u0438\u043f\u043e\u0432 \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u043a \u0437\u0430\u043f\u0438\u0441\u044f\u043c, \u0432\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>LogAttrs()<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"go\">logger.LogAttrs(   context.Background(),   slog.LevelInfo,   \"incoming request\",   slog.String(\"method\", \"GET\"),   slog.Int(\"time_taken_ms\", 158),   slog.String(\"path\", \"\/hello\/world?q=search\"),   slog.Int(\"status\", 200),   slog.String(     \"user_agent\",     \"Googlebot\/2.1 (+http:\/\/www.google.com\/bot.html)\",   ), ) <\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0438\u043f <code>slog.Attr<\/code> \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0435\u0441\u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u043f\u0430\u0440\u0443 \u043a\u043b\u044e\u0447\/\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041e\u0434\u043d\u0430\u043a\u043e \u0435\u0433\u043e API \u0431\u043e\u043b\u0435\u0435 \u0437\u0430\u043f\u0443\u0442\u0430\u043d\u043d\u044b\u0439, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044e \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c \u0432 \u043c\u0435\u0442\u043e\u0434 \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 (\u0438\u043b\u0438 <code>nil<\/code>) \u0438 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0436\u0443\u0440\u043d\u0430\u043b\u0430.<\/p>\n<h2>\u0413\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432<\/h2>\n<p>Slog \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u043f\u043e\u0434 \u043e\u0434\u043d\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c, \u043d\u043e \u0432\u044b\u0432\u043e\u0434 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0433\u043e \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 <code>JSONHandler<\/code> \u043a\u0430\u0436\u0434\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430 \u0432\u043b\u043e\u0436\u0435\u043d\u0430 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442 JSON:<\/p>\n<pre><code class=\"go\">logger.LogAttrs(   context.Background(),   slog.LevelInfo,   \"image uploaded\",   slog.Int(\"id\", 23123),   slog.Group(\"properties\",     slog.Int(\"width\", 4000),     slog.Int(\"height\", 3000),     slog.String(\"format\", \"jpeg\"),   ), ) <\/code><\/pre>\n<pre><code>{   \"time\":\"2023-02-24T12:03:12.175582603+01:00\",   \"level\":\"INFO\",   \"msg\":\"image uploaded\",   \"id\":23123,   \"properties\":{     \"width\":4000,     \"height\":3000,     \"format\":\"jpeg\"   } }<\/code><\/pre>\n<p>\u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 <code>TextHandler<\/code> \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043b\u044e\u0447 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0432 \u0432\u0438\u0434\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b, \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0438\u0436\u0435:<\/p>\n<pre><code>time=2023-02-24T12:06:20.249+01:00 level=INFO msg=\"image uploaded\" id=23123   properties.width=4000 properties.height=3000 properties.format=jpeg<\/code><\/pre>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043b\u043e\u0433\u0435\u0440\u043e\u0432<\/h2>\n<p>\u0418\u043d\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0432\u043e \u0432\u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0431\u0435\u0437 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0449\u0438\u0445\u0441\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u043b\u043e\u0433.<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u043b\u043e\u0433\u0435\u0440\u044b. \u041e\u043d\u0438 \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u043d\u043e\u0432\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043b\u043e\u0433\u0435\u0440\u0430, \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u044f.<\/p>\n<p>\u0412 Slog \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043b\u043e\u0433\u0435\u0440\u043e\u0432 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <code>Logger.With()<\/code>. \u041e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u0434\u043d\u0443 \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u0440 \u043a\u043b\u044e\u0447\/\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 <code>Logger<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u043a\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 program&#8217;s process ID \u0438 \u0432\u0435\u0440\u0441\u0438\u044e Go, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u043a \u043a\u0430\u0436\u0434\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u043b\u043e\u0433 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0438\u0445 \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0435 <code>program_info<\/code>.<\/p>\n<pre><code class=\"go\">func main() {     handler := slog.NewJSONHandler(os.Stdout, nil)     buildInfo, _ := debug.ReadBuildInfo()      logger := slog.New(handler)      child := logger.With(         slog.Group(\"program_info\",             slog.Int(\"pid\", os.Getpid()),             slog.String(\"go_version\", buildInfo.GoVersion),         ),     )      . . . } <\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0442\u0430\u043a\u0430\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0437\u0430\u0434\u0430\u043d\u0430, \u0442\u043e \u0432\u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0438, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u043b\u043e\u0433\u0435\u0440\u043e\u043c <code>child<\/code>, \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0435 <code>program_info<\/code>, \u043f\u043e\u043a\u0430 \u043e\u043d\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e \u0432 \u0442\u043e\u0447\u043a\u0435 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<pre><code class=\"go\">func main() {     . . .      child.Info(\"image upload successful\", slog.String(\"image_id\", \"39ud88\"))     child.Warn(         \"storage is 90% full\",         slog.String(\"available_space\", \"900.1 mb\"),     ) } <\/code><\/pre>\n<pre><code>{   \"time\": \"2023-02-26T19:26:46.046793623+01:00\",   \"level\": \"INFO\",   \"msg\": \"image upload successful\",   \"program_info\": {     \"pid\": 229108,     \"go_version\": \"go1.20\"   },   \"image_id\": \"39ud88\" } {   \"time\": \"2023-02-26T19:26:46.046847902+01:00\",   \"level\": \"WARN\",   \"msg\": \"storage is 90% full\",   \"program_info\": {     \"pid\": 229108,     \"go_version\": \"go1.20\"   },   \"available_space\": \"900.1 MB\" }<\/code><\/pre>\n<p>\u0412\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>WithGroup()<\/code> \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0433\u043e \u043b\u043e\u0433\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0433\u0440\u0443\u043f\u043f\u0443. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u0441\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u043a \u043b\u043e\u0433\u0435\u0440\u0443 (\u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u0442\u043e\u0447\u043a\u0435 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f), \u0431\u0443\u0434\u0443\u0442 \u0432\u043b\u043e\u0436\u0435\u043d\u044b \u043f\u043e\u0434 \u0438\u043c\u0435\u043d\u0435\u043c \u0433\u0440\u0443\u043f\u043f\u044b.<\/p>\n<pre><code class=\"go\">handler := slog.NewJSONHandler(os.Stdout, nil) buildInfo, _ := debug.ReadBuildInfo() logger := slog.New(handler).WithGroup(\"program_info\")  child := logger.With(   slog.Int(\"pid\", os.Getpid()),   slog.String(\"go_version\", buildInfo.GoVersion), )  child.Warn(   \"storage is 90% full\",   slog.String(\"available_space\", \"900.1 MB\"), ) <\/code><\/pre>\n<pre><code>{   \"time\": \"2023-05-24T19:00:18.384136084+01:00\",   \"level\": \"WARN\",   \"msg\": \"storage is 90% full\",   \"program_info\": {     \"pid\": 1971993,     \"go_version\": \"go1.20.2\",     \"available_space\": \"900.1 mb\"   } }<\/code><\/pre>\n<h2>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 Slog<\/h2>\n<p>\u041f\u0430\u043a\u0435\u0442 <code>log\/slog<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0447\u0435\u0442\u044b\u0440\u0435 \u0443\u0440\u043e\u0432\u043d\u044f \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0432\u044f\u0437\u0430\u043d \u0441 \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c: <code>DEBUG<\/code> (-4), <code>INFO<\/code> (0), <code>WARN<\/code> (4) \u0438 <code>ERROR<\/code> (8).<\/p>\n<p>\u0420\u0430\u0437\u043d\u0438\u0446\u0430 \u0432 \u0447\u0435\u0442\u044b\u0440\u0435 \u0435\u0434\u0438\u043d\u0438\u0446\u044b \u043c\u0435\u0436\u0434\u0443 \u0443\u0440\u043e\u0432\u043d\u044f\u043c\u0438 \u2014 \u044d\u0442\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435. \u041e\u043d\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u0445\u0435\u043c\u044b \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c\u0438 \u0443\u0440\u043e\u0432\u043d\u044f\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u0443\u0440\u043e\u0432\u043d\u044f\u043c\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043c\u0435\u0436\u0434\u0443 <code>INFO<\/code> \u0438 <code>WARN<\/code> \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c 1, 2 \u0438\u043b\u0438 3.<\/p>\n<p>\u0420\u0430\u043d\u0435\u0435 \u043c\u044b \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u043b\u0438, \u0447\u0442\u043e \u0432\u0441\u0435 \u043b\u043e\u0433\u0435\u0440\u044b \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u043d\u0430 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 <code>INFO<\/code>, \u0438\u0437-\u0437\u0430 \u0447\u0435\u0433\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0441 \u043c\u0435\u043d\u044c\u0448\u0435\u0439 \u0441\u0435\u0440\u044c\u0451\u0437\u043d\u043e\u0441\u0442\u044c\u044e (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>DEBUG<\/code>), \u043f\u043e\u0434\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u044d\u0442\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 \u0442\u0438\u043f <a href=\"https:\/\/pkg.go.dev\/log\/slog#HandlerOptions\"><u>HandlerOptions<\/u><\/a>, \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0438\u0436\u0435.<\/p>\n<pre><code class=\"go\">func main() {     opts := &amp;slog.HandlerOptions{         Level: slog.LevelDebug,     }      handler := slog.NewJSONHandler(os.Stdout, opts)      logger := slog.New(handler)     logger.Debug(\"Debug message\")     logger.Info(\"Info message\")     logger.Warn(\"Warning message\")     logger.Error(\"Error message\") } <\/code><\/pre>\n<pre><code>{\"time\":\"2023-05-24T19:03:10.70311982+01:00\",\"level\":\"DEBUG\",\"msg\":\"Debug message\"} {\"time\":\"2023-05-24T19:03:10.703187713+01:00\",\"level\":\"INFO\",\"msg\":\"Info message\"} {\"time\":\"2023-05-24T19:03:10.703190419+01:00\",\"level\":\"WARN\",\"msg\":\"Warning message\"} {\"time\":\"2023-05-24T19:03:10.703192892+01:00\",\"level\":\"ERROR\",\"msg\":\"Error message\"}<\/code><\/pre>\n<p>\u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u0443\u0440\u043e\u0432\u043d\u044f \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u0442 \u0443\u0440\u043e\u0432\u0435\u043d\u044c <code>handler<\/code> \u043d\u0430 \u043f\u0440\u043e\u0442\u044f\u0436\u0435\u043d\u0438\u0438 \u0432\u0441\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0435\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u044b. \u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u043b\u0441\u044f, \u0432\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0438\u043f <code>LevelVar<\/code>, \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0438\u0436\u0435:<\/p>\n<pre><code class=\"go\">func main() {     logLevel := &amp;slog.LevelVar{} \/\/ INFO      opts := &amp;slog.HandlerOptions{         Level: logLevel,     }      handler := slog.NewJSONHandler(os.Stdout, opts)      . . . } <\/code><\/pre>\n<p>\u0412\u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0432 \u043b\u044e\u0431\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"go\">logLevel.Set(slog.LevelDebug) <\/code><\/pre>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u0436\u0443\u0440\u043d\u0430\u043b\u0430<\/h2>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0443\u0440\u043e\u0432\u043d\u0438, \u043f\u043e\u043c\u0438\u043c\u043e \u0442\u0435\u0445, \u0447\u0442\u043e Slog \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u0445 \u0447\u0435\u0440\u0435\u0437 <a href=\"https:\/\/pkg.go.dev\/log\/slog#Leveler\"><u>\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Leveler<\/u><\/a>, \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"go\">type Leveler interface {     Level() Level } <\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043b\u0435\u0433\u043a\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0442\u0438\u043f <code>Level<\/code>, \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043d\u0438\u0436\u0435 (\u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0441\u0430\u043c <code>Level<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 <code>Leveler<\/code>):<\/p>\n<pre><code class=\"go\">const (     LevelTrace  = slog.Level(-8)     LevelFatal  = slog.Level(12) ) <\/code><\/pre>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u0443\u0440\u043e\u0432\u043d\u0438, \u043a\u0430\u043a \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0432\u044b\u0448\u0435, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u0442\u043e\u0434 <code>Log()<\/code> \u0438\u043b\u0438 <code>LogAttrs()<\/code>:<\/p>\n<pre><code class=\"go\">opts := &amp;slog.HandlerOptions{     Level: LevelTrace, }  logger := slog.New(slog.NewJSONHandler(os.Stdout, opts))  ctx := context.Background() logger.Log(ctx, LevelTrace, \"Trace message\") logger.Log(ctx, LevelFatal, \"Fatal level\") <\/code><\/pre>\n<pre><code>{\"time\":\"2023-02-24T09:26:41.666493901+01:00\",\"level\":\"DEBUG-4\",\"msg\":\"Trace level\"} {\"time\":\"2023-02-24T09:26:41.666602404+01:00\",\"level\":\"ERROR+4\",\"msg\":\"Fatal level\"}<\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u043a\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u0443\u0440\u043e\u0432\u043d\u0438 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u044b \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e. \u042d\u0442\u043e \u043d\u0435 \u0442\u043e \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438\u043c\u0435\u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 \u0442\u0438\u043f <code>HandlerOptions<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"go\">. . .  var LevelNames = map[slog.Leveler]string{     LevelTrace:      \"TRACE\",     LevelFatal:      \"FATAL\", }  func main() {     opts := slog.HandlerOptions{         Level: LevelTrace,         ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {             if a.Key == slog.LevelKey {                 level := a.Value.Any().(slog.Level)                 levelLabel, exists := LevelNames[level]                 if !exists {                     levelLabel = level.String()                 }                  a.Value = slog.StringValue(levelLabel)             }              return a         },     }      . . . } <\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>ReplaceAttr()<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043a\u0430\u0436\u0434\u0430\u044f \u043f\u0430\u0440\u0430 \u043a\u043b\u044e\u0447\/\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 <code>Record<\/code> \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f <code>Handler<\/code>. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043c\u043e\u0447\u044c \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0438\u043c\u0435\u043d\u0430 \u043a\u043b\u044e\u0447\u0435\u0439 \u0438\u043b\u0438 \u043a\u0430\u043a\u0438\u043c-\u043b\u0438\u0431\u043e \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u043c \u0432\u044b\u0448\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u0443\u0440\u043e\u0432\u043d\u0438 \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0441 \u0438\u0445 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u043c\u0435\u0442\u043a\u0430\u043c\u0438, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u044f\u0449\u0438\u043c\u0438 <code>TRACE<\/code> \u0438 <code>FATAL<\/code> \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<pre><code>{\"time\":\"2023-02-24T09:27:51.747625912+01:00\",\"level\":\"TRACE\",\"msg\":\"Trace level\"} {\"time\":\"2023-02-24T09:27:51.747737319+01:00\",\"level\":\"FATAL\",\"msg\":\"Fatal level\"}<\/code><\/pre>\n<h2>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 Slog<\/h2>\n<p>\u041a\u0430\u043a \u0443\u0436\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c, \u0438 <code>TextHandler<\/code>, \u0438 <code>JSONHandler<\/code> \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u0438\u043f\u0430 <code>HandlerOptions<\/code>. \u0412\u044b \u0443\u0436\u0435 \u0432\u0438\u0434\u0435\u043b\u0438, \u043a\u0430\u043a \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u043f\u0438\u0441\u044c\u044e \u0432 \u0436\u0443\u0440\u043d\u0430\u043b.<\/p>\n<p>\u0415\u0449\u0435 \u043e\u0434\u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>HandlerOptions<\/code>, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0436\u0443\u0440\u043d\u0430\u043b\u0430, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e:<\/p>\n<pre><code class=\"go\">opts := &amp;slog.HandlerOptions{     AddSource: true,     Level:     slog.LevelDebug, } <\/code><\/pre>\n<pre><code>{   \"time\": \"2024-01-03T11:06:50.971029852+01:00\",   \"level\": \"DEBUG\",   \"source\": {     \"function\": \"main.main\",     \"file\": \"\/home\/ayo\/dev\/betterstack\/demo\/slog\/main.go\",     \"line\": 17   },   \"msg\": \"Debug message\" }<\/code><\/pre>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043c\u043e\u0436\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u043c\u0435\u043d\u044f\u0442\u044c \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u044b \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u0440\u0435\u0434\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>TextHandler<\/code> \u0434\u043b\u044f \u0436\u0443\u0440\u043d\u0430\u043b\u043e\u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0435\u0433\u043e \u043b\u0435\u0433\u0447\u0435 \u0447\u0438\u0442\u0430\u0442\u044c, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043d\u0430 <code>JSONHandler<\/code> \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u0438 \u0438 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438 \u0441 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>\u0422\u0430\u043a\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043b\u0435\u0433\u043a\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"go\">var appEnv = os.Getenv(\"APP_ENV\")  func main() {     opts := &amp;slog.HandlerOptions{         Level: slog.LevelDebug,     }      var handler slog.Handler = slog.NewTextHandler(os.Stdout, opts)     if appEnv == \"production\" {         handler = slog.NewJSONHandler(os.Stdout, opts)     }      logger := slog.New(handler)      logger.Info(\"Info message\") } <\/code><\/pre>\n<pre><code>go run main.go <\/code><\/pre>\n<pre><code>time=2023-02-24T10:36:39.697+01:00 level=INFO msg=\"Info message\"<\/code><\/pre>\n<pre><code class=\"go\">APP_ENV=production go run main.go <\/code><\/pre>\n<pre><code>{\"time\":\"2023-02-24T10:35:16.964821548+01:00\",\"level\":\"INFO\",\"msg\":\"Info message\"} <\/code><\/pre>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432<\/h2>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <code>Handler<\/code> \u2014 \u044d\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u043e\u0433\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0436\u0443\u0440\u043d\u0430\u043b\u043e\u0432 \u0438\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438\u0445 \u0432 \u0434\u0440\u0443\u0433\u0438\u0435 \u043c\u0435\u0441\u0442\u0430.<\/p>\n<p>\u0415\u0433\u043e \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"go\">type Handler interface {     Enabled(context.Context, Level) bool     Handle(context.Context, r Record) error     WithAttrs(attrs []Attr) Handler     WithGroup(name string) Handler } <\/code><\/pre>\n<p>\u0412\u043e\u0442 \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043c\u0435\u0442\u043e\u0434\u043e\u0432:<\/p>\n<ul>\n<li>\n<p><code>Enabled()<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043b\u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0438\u043b\u0438 \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u044c \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0435\u0435 \u0443\u0440\u043e\u0432\u043d\u044f. \u0414\u043b\u044f \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <code>context<\/code>.<\/p>\n<\/li>\n<li>\n<p><code>Handle()<\/code> \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043a\u0430\u0436\u0434\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u0436\u0443\u0440\u043d\u0430\u043b\u0430, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0443. \u041e\u043d\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 <code>Enabled()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>true<\/code>.<\/p>\n<\/li>\n<li>\n<p><code>WithAttrs()<\/code> \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0437 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0432 \u043d\u0435\u0433\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b.<\/p>\n<\/li>\n<li>\n<p><code>WithGroup()<\/code> \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0437 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0432 \u043d\u0435\u0433\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0435 \u0438\u043c\u044f \u0433\u0440\u0443\u043f\u043f\u044b \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0438\u043c\u044f \u043a\u0432\u0430\u043b\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043b\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0439 \u043f\u0430\u043a\u0435\u0442\u044b <code>log<\/code>, <code>json<\/code> \u0438 <a href=\"https:\/\/github.com\/fatih\/color\"><u>color<\/u><\/a> \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u0440\u0430\u0441\u0438\u0432\u043e\u0433\u043e \u0432\u044b\u0432\u043e\u0434\u0430 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0436\u0443\u0440\u043d\u0430\u043b\u0430:<\/p>\n<pre><code class=\"go\">\/\/ NOTE: Not well tested, just an illustration of what's possible package main  import (     \"context\"     \"encoding\/json\"     \"io\"     \"log\"     \"log\/slog\"      \"github.com\/fatih\/color\" )  type PrettyHandlerOptions struct {     SlogOpts slog.HandlerOptions }  type PrettyHandler struct {     slog.Handler     l *log.Logger }  func (h *PrettyHandler) Handle(ctx context.Context, r slog.Record) error {     level := r.Level.String() + \":\"      switch r.Level {     case slog.LevelDebug:         level = color.MagentaString(level)     case slog.LevelInfo:         level = color.BlueString(level)     case slog.LevelWarn:         level = color.YellowString(level)     case slog.LevelError:         level = color.RedString(level)     }      fields := make(map[string]interface{}, r.NumAttrs())     r.Attrs(func(a slog.Attr) bool {         fields[a.Key] = a.Value.Any()          return true     })      b, err := json.MarshalIndent(fields, \"\", \"  \")     if err != nil {         return err     }      timeStr := r.Time.Format(\"[15:05:05.000]\")     msg := color.CyanString(r.Message)      h.l.Println(timeStr, level, msg, color.WhiteString(string(b)))      return nil }  func NewPrettyHandler(     out io.Writer,     opts PrettyHandlerOptions, ) *PrettyHandler {     h := &amp;PrettyHandler{         Handler: slog.NewJSONHandler(out, &amp;opts.SlogOpts),         l:       log.New(out, \"\", 0),     }      return h } <\/code><\/pre>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 <code>PrettyHandler<\/code> \u0432 \u0441\u0432\u043e\u0435\u043c \u043a\u043e\u0434\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0430\u043a:<\/p>\n<pre><code class=\"go\">func main() {     opts := PrettyHandlerOptions{         SlogOpts: slog.HandlerOptions{             Level: slog.LevelDebug,         },     }     handler := NewPrettyHandler(os.Stdout, opts)     logger := slog.New(handler)     logger.Debug(         \"executing database query\",         slog.String(\"query\", \"SELECT * FROM users\"),     )     logger.Info(\"image upload successful\", slog.String(\"image_id\", \"39ud88\"))     logger.Warn(         \"storage is 90% full\",         slog.String(\"available_space\", \"900.1 MB\"),     )     logger.Error(         \"An error occurred while processing the request\",         slog.String(\"url\", \"https:\/\/example.com\"),     ) } <\/code><\/pre>\n<p>\u041f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0440\u0430\u0441\u043a\u0440\u0430\u0448\u0435\u043d\u043d\u044b\u0439 \u0432\u044b\u0432\u043e\u0434:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/61f\/778\/8dc\/61f7788dc479053399e5e57b56904bd8.png\" alt=\"\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\" title=\"\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\" width=\"650\" height=\"459\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/61f\/778\/8dc\/61f7788dc479053399e5e57b56904bd8.png\"\/><\/p>\n<div><figcaption><a href=\"https:\/\/betterstack.com\/community\/guides\/logging\/logging-in-go\/#customizing-the-default-logger\"><u>\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a<\/u><\/a><\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0430 <a href=\"https:\/\/github.com\/search?q=slog-+language%3AGo&amp;type=repositories&amp;l=Go\">GitHub<\/a> \u0438 \u043d\u0430 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 <a href=\"https:\/\/tip.golang.org\/wiki\/Resources-for-slog\">Go Wiki<\/a> \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0439\u0442\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u043e\u0432, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e\u043c. \u0421\u0440\u0435\u0434\u0438 \u044f\u0440\u043a\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0437\u0432\u0430\u0442\u044c:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/github.com\/lmittmann\/tint\">tint<\/a> \u2014 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0442\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 (\u043e\u043a\u0440\u0430\u0448\u0435\u043d\u043d\u044b\u0435) \u0436\u0443\u0440\u043d\u0430\u043b\u044b.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/samber\/slog-sampling\">slog-sampling<\/a> \u2014 \u043f\u043e\u0432\u044b\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043d\u0443\u044e \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0437\u0430 \u0441\u0447\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0449\u0438\u0445\u0441\u044f \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0436\u0443\u0440\u043d\u0430\u043b\u0430.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/samber\/slog-multi\">slog-multi<\/a> \u2014 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0442\u0430\u043a\u0438\u0435 \u0440\u0430\u0431\u043e\u0447\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b, \u043a\u0430\u043a \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0435 \u041f\u041e, fanout, \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f, \u043e\u0431\u0445\u043e\u0434 \u043e\u0442\u043a\u0430\u0437\u043e\u0432, \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0430 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/samber\/slog-formatter\">slog-formatter<\/a> \u2014 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u0433\u0438\u0431\u043a\u043e\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<h2>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u0430 context \u0432 Slog<\/h2>\n<p>\u0414\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0443\u0440\u043e\u0432\u043d\u044f, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a <code>Info()<\/code>, <code>Debug()<\/code> \u0438 \u0434\u0440\u0443\u0433\u0438\u0435, \u043d\u043e Slog \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>context.Context<\/code>. \u0412\u043e\u0442 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u043d\u0438\u0445:<\/p>\n<pre><code class=\"go\">func (ctx context.Context, msg string, args ...any) <\/code><\/pre>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u0430\u043a\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u044f\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043c\u0435\u0436\u0434\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044f \u0438\u0445 \u0432 <code>Context<\/code>, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0438 \u044d\u0442\u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u043e\u043d\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b\u0438\u0441\u044c \u043a \u043b\u044e\u0431\u044b\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u043c \u0437\u0430\u043f\u0438\u0441\u044f\u043c.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443:<\/p>\n<pre><code class=\"go\">package main  import (     \"context\"     \"log\/slog\"     \"os\" )  func main() {     logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))      ctx := context.WithValue(context.Background(), \"request_id\", \"req-123\")      logger.InfoContext(ctx, \"image uploaded\", slog.String(\"image_id\", \"img-998\")) } <\/code><\/pre>\n<p>\u0412 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>ctx<\/code> \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>request_id<\/code> \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043c\u0435\u0442\u043e\u0434 <code>InfoContext<\/code>. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043f\u043e\u043b\u0435 <code>request_id<\/code> \u043d\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0436\u0443\u0440\u043d\u0430\u043b\u0435:<\/p>\n<pre><code>{   \"time\": \"2024-01-02T11:04:28.590527494+01:00\",   \"level\": \"INFO\",   \"msg\": \"image uploaded\",   \"image_id\": \"img-998\" }<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e, \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438 \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>Handle<\/code>, \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0438\u0436\u0435:<\/p>\n<pre><code class=\"go\">type ctxKey string  const (     slogFields ctxKey = \"slog_fields\" )  type ContextHandler struct {     slog.Handler }  \/\/ Handle adds contextual attributes to the Record before calling the underlying \/\/ handler func (h ContextHandler) Handle(ctx context.Context, r slog.Record) error {     if attrs, ok := ctx.Value(slogFields).([]slog.Attr); ok {         for _, v := range attrs {             r.AddAttrs(v)         }     }      return h.Handler.Handle(ctx, r) }  \/\/ AppendCtx adds an slog attribute to the provided context so that it will be \/\/ included in any Record created with such context func AppendCtx(parent context.Context, attr slog.Attr) context.Context {     if parent == nil {         parent = context.Background()     }      if v, ok := parent.Value(slogFields).([]slog.Attr); ok {         v = append(v, attr)         return context.WithValue(parent, slogFields, v)     }      v := []slog.Attr{}     v = append(v, attr)     return context.WithValue(parent, slogFields, v) } <\/code><\/pre>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <code>ContextHandler<\/code> \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>slog.Handler<\/code> \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 <code>Handle<\/code>. \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b Slog, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435. \u0415\u0441\u043b\u0438 \u043e\u043d\u0438 \u043d\u0430\u0439\u0434\u0435\u043d\u044b, \u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043a <code>Record<\/code> \u043f\u0435\u0440\u0435\u0434 \u0432\u044b\u0437\u043e\u0432\u043e\u043c \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e <code>Handler<\/code> \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0432\u044b\u0432\u043e\u0434\u0430 \u0437\u0430\u043f\u0438\u0441\u0438.<\/p>\n<p>\u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>AppendCtx<\/code> \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b Slog \u0432 <code>context.Context<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043b\u044e\u0447\u0430 <code>slogFields<\/code>, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u0431\u044b\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0434\u043b\u044f <code>ContextHandler<\/code>.<\/p>\n<p>\u0412\u043e\u0442 \u043a\u0430\u043a \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c:<\/p>\n<pre><code class=\"go\">func main() {     h := &amp;ContextHandler{slog.NewJSONHandler(os.Stdout, nil)}      logger := slog.New(h)      ctx := AppendCtx(context.Background(), slog.String(\"request_id\", \"req-123\"))      logger.InfoContext(ctx, \"image uploaded\", slog.String(\"image_id\", \"img-998\")) } <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435, \u0447\u0442\u043e <code>request_id<\/code> \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043e \u0432\u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0438, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 <code>ctx<\/code>:<\/p>\n<pre><code>{   \"time\": \"2024-01-02T11:29:15.229984723+01:00\",   \"level\": \"INFO\",   \"msg\": \"image uploaded\",   \"image_id\": \"img-998\",   \"request_id\": \"req-123\" }<\/code><\/pre>\n<h2>\u041b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0448\u0438\u0431\u043e\u043a \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Slog<\/h2>\n<p>\u0414\u043b\u044f \u0442\u0438\u043f\u0430 <code>error<\/code> \u043d\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0445\u0435\u043b\u043f\u0435\u0440, \u043a\u0430\u043a \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>slog.Any()<\/code>, \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0437\u0434\u0435\u0441\u044c:<\/p>\n<pre><code class=\"go\">err := errors.New(\"something happened\")  logger.ErrorContext(ctx, \"upload failed\", slog.Any(\"error\", err)) <\/code><\/pre>\n<pre><code>{   \"time\": \"2024-01-02T14:13:44.41886393+01:00\",   \"level\": \"ERROR\",   \"msg\": \"upload failed\",   \"error\": \"something happened\" }<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u043b\u043e\u0433 \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0443 \u0441\u0442\u0435\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u043a\u0430\u043a <a href=\"https:\/\/github.com\/MDobak\/go-xerrors\"><u>xerrors<\/u><\/a>, \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043e\u043a \u0441 \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u043e\u0439 \u0441\u0442\u0435\u043a\u0430.<\/p>\n<pre><code class=\"go\">err := xerrors.New(\"something happened\")  logger.ErrorContext(ctx, \"upload failed\", slog.Any(\"error\", err)) <\/code><\/pre>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0443 \u0441\u0442\u0435\u043a\u0430 \u0432 \u0436\u0443\u0440\u043d\u0430\u043b\u0435 \u043e\u0448\u0438\u0431\u043e\u043a, \u0432\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0438\u0437\u0432\u043b\u0435\u0447\u044c, \u043e\u0442\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0451 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 <code>Record<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>ReplaceAttr()<\/code>, \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0440\u0430\u043d\u0435\u0435.<\/p>\n<p>\u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"go\">package main  import (     \"context\"     \"log\/slog\"     \"os\"     \"path\/filepath\"      \"github.com\/mdobak\/go-xerrors\" )  type stackFrame struct {     Func   string `json:\"func\"`     Source string `json:\"source\"`     Line   int    `json:\"line\"` }  func replaceAttr(_ []string, a slog.Attr) slog.Attr {     switch a.Value.Kind() {     case slog.KindAny:         switch v := a.Value.Any().(type) {         case error:             a.Value = fmtErr(v)         }     }      return a }  \/\/ marshalStack extracts stack frames from the error func marshalStack(err error) []stackFrame {     trace := xerrors.StackTrace(err)      if len(trace) == 0 {         return nil     }      frames := trace.Frames()      s := make([]stackFrame, len(frames))      for i, v := range frames {         f := stackFrame{             Source: filepath.Join(                 filepath.Base(filepath.Dir(v.File)),                 filepath.Base(v.File),             ),             Func: filepath.Base(v.Function),             Line: v.Line,         }          s[i] = f     }      return s }  \/\/ fmtErr returns a slog.Value with keys `msg` and `trace`. If the error \/\/ does not implement interface { StackTrace() errors.StackTrace }, the `trace` \/\/ key is omitted. func fmtErr(err error) slog.Value {     var groupValues []slog.Attr      groupValues = append(groupValues, slog.String(\"msg\", err.Error()))      frames := marshalStack(err)      if frames != nil {         groupValues = append(groupValues,             slog.Any(\"trace\", frames),         )     }      return slog.GroupValue(groupValues...) }  func main() {     h := slog.NewJSONHandler(os.Stdout, &amp;slog.HandlerOptions{         ReplaceAttr: replaceAttr,     })      logger := slog.New(h)      ctx := context.Background()      err := xerrors.New(\"something happened\")      logger.ErrorContext(ctx, \"image uploaded\", slog.Any(\"error\", err)) } <\/code><\/pre>\n<p>\u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u0441\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>xerrors.New()<\/code>, \u0431\u0443\u0434\u0443\u0442 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u0445\u043e\u0440\u043e\u0448\u043e \u043e\u0442\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u043e\u0439 \u0441\u0442\u0435\u043a\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code>{   \"time\": \"2024-01-03T07:09:31.013954119+01:00\",   \"level\": \"ERROR\",   \"msg\": \"image uploaded\",   \"error\": {     \"msg\": \"something happened\",     \"trace\": [       {         \"func\": \"main.main\",         \"source\": \"slog\/main.go\",         \"line\": 82       },       {         \"func\": \"runtime.main\",         \"source\": \"runtime\/proc.go\",         \"line\": 267       },       {         \"func\": \"runtime.goexit\",         \"source\": \"runtime\/asm_amd64.s\",         \"line\": 1650       }     ]   } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u043b\u0435\u0433\u043a\u043e \u043f\u0440\u043e\u0441\u043b\u0435\u0434\u0438\u0442\u044c \u043f\u0443\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u043f\u0440\u0438\u0432\u043e\u0434\u044f\u0449\u0438\u0439 \u043a \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u044b\u043c \u043e\u0448\u0438\u0431\u043a\u0430\u043c \u0432 \u0432\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438.<\/p>\n<h2>\u041a\u0430\u043a \u0441\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u044f \u0441 \u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 LogValuer<\/h2>\n<p>\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>LogValuer<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u044b\u0432\u043e\u0434 \u043b\u043e\u0433\u043e\u0432, \u0443\u043a\u0430\u0437\u0430\u0432, \u043a\u0430\u043a \u0434\u043e\u043b\u0436\u043d\u044b \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u0442\u0438\u043f\u044b.<\/p>\n<p>\u0412\u043e\u0442 \u0435\u0433\u043e \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430:<\/p>\n<pre><code class=\"go\">type LogValuer interface {     LogValue() Value } <\/code><\/pre>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e\u0442 \u0442\u0438\u043f <code>User<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>LogValuer<\/code>. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u043a\u0430\u043a \u043a\u043e\u043d\u0444\u0438\u0434\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u0435\u0442\u0430\u043b\u0438 \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043f\u0440\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u0432 \u043b\u043e\u0433:<\/p>\n<pre><code class=\"go\">\/\/ User does not implement `LogValuer` here type User struct {     ID        string `json:\"id\"`     FirstName string `json:\"first_name\"`     LastName  string `json:\"last_name\"`     Email     string `json:\"email\"`     Password  string `json:\"password\"` }  func main() {     handler := slog.NewJSONHandler(os.Stdout, nil)     logger := slog.New(handler)      u := &amp;User{         ID:        \"user-12234\",         FirstName: \"Jan\",         LastName:  \"Doe\",         Email:     \"jan@example.com\",         Password:  \"pass-12334\",     }      logger.Info(\"info\", \"user\", u) } <\/code><\/pre>\n<pre><code>{   \"time\": \"2023-02-26T22:11:30.080656774+01:00\",   \"level\": \"INFO\",   \"msg\": \"info\",   \"user\": {     \"id\": \"user-12234\",     \"first_name\": \"Jan\",     \"last_name\": \"Doe\",     \"email\": \"jan@example.com\",     \"password\": \"pass-12334\"   } }<\/code><\/pre>\n<p>\u042d\u0442\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u0438\u043f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043f\u043e\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432 \u043b\u043e\u0433\u0430\u0445 (\u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u044b\u0435 \u043f\u0438\u0441\u044c\u043c\u0430 \u0438 \u043f\u0430\u0440\u043e\u043b\u0438), \u0438 \u044d\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0430\u0448\u0438 \u043b\u043e\u0433\u0438 \u0438\u0437\u043b\u0438\u0448\u043d\u0435 \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u0438\u043c\u0438.<\/p>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0440\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443, \u0443\u043a\u0430\u0437\u0430\u0432, \u043a\u0430\u043a \u0432\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u0431\u044b, \u0447\u0442\u043e\u0431\u044b \u0442\u0438\u043f \u0431\u044b\u043b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0432 \u043b\u043e\u0433\u0430\u0445. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0432 \u043b\u043e\u0433 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0435 <code>ID<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"go\">\/\/ implement the `LogValuer` interface on the User struct func (u User) LogValue() slog.Value {     return slog.StringValue(u.ID) } <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code>{   \"time\": \"2023-02-26T22:43:28.184363059+01:00\",   \"level\": \"INFO\",   \"msg\": \"info\",   \"user\": \"user-12234\" } <\/code><\/pre>\n<p>\u0412\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"go\">func (u User) LogValue() slog.Value {     return slog.GroupValue(         slog.String(\"id\", u.ID),         slog.String(\"name\", u.FirstName+\" \"+u.LastName),     ) } <\/code><\/pre>\n<pre><code>{   \"time\": \"2023-03-15T14:44:24.223381036+01:00\",   \"level\": \"INFO\",   \"msg\": \"info\",   \"user\": {     \"id\": \"user-12234\",     \"name\": \"Jan Doe\"   } }<\/code><\/pre>\n<h2>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u0431\u044d\u043a\u0435\u043d\u0434\u043e\u0432 \u0434\u043b\u044f \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Slog<\/h2>\n<p>\u041e\u0434\u043d\u0430 \u0438\u0437 \u0433\u043b\u0430\u0432\u043d\u044b\u0445 \u0446\u0435\u043b\u0435\u0439 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f Slog \u2014 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0443\u043d\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f (<code>slog.Logger<\/code>) \u0434\u043b\u044f Go-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a \u0431\u044d\u043a\u0435\u043d\u0434 (<code>slog.Handler<\/code>) \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u044b\u043c \u043e\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435.<\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, API \u0434\u043b\u044f \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0432\u043e \u0432\u0441\u0435\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u0445, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0431\u044d\u043a\u0435\u043d\u0434\u044b \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f. \u042d\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u043f\u0430\u043a\u0435\u0442\u043e\u043c, \u0434\u0435\u043b\u0430\u044f \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0431\u044d\u043a\u0435\u043d\u0434, \u0435\u0441\u043b\u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u0432\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f.<\/p>\n<p>\u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Slog \u0441 Zap backend, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u044d\u0442\u043e \u043b\u0443\u0447\u0448\u0435\u0435 \u0438\u0437 \u043e\u0431\u043e\u0438\u0445 \u043c\u0438\u0440\u043e\u0432:<\/p>\n<pre><code>go get go.uber.org\/zap <\/code><\/pre>\n<pre><code>go get go.uber.org\/zap\/exp\/zapslog <\/code><\/pre>\n<pre><code class=\"go\">package main  import (     \"log\/slog\"      \"go.uber.org\/zap\"     \"go.uber.org\/zap\/exp\/zapslog\" )  func main() {     zapL := zap.Must(zap.NewProduction())      defer zapL.Sync()      logger := slog.New(zapslog.NewHandler(zapL.Core(), nil))      logger.Info(         \"incoming request\",         slog.String(\"method\", \"GET\"),         slog.String(\"path\", \"\/api\/user\"),         slog.Int(\"status\", 200),     ) } <\/code><\/pre>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0435 \u043a\u043e\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u043b\u043e\u0433\u0435\u0440 Zap \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f \u043f\u0430\u043a\u0435\u0442\u0430 Slog \u0447\u0435\u0440\u0435\u0437 <code>zapslog.NewHandler()<\/code>. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043b\u043e\u0433\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043c\u0435\u0442\u043e\u0434\u044b, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0435 \u0432 <code>slog.Logger<\/code>. \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0431\u0443\u0434\u0443\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0435\u0439 <code>zapL<\/code> .<\/p>\n<pre><code>{\"level\":\"info\",\"ts\":1697453912.4535635,\"msg\":\"incoming request\",\"method\":\"GET\",\"path\":\"\/api\/user\",\"status\":200}<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u043b\u043e\u0433\u0435\u0440 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u0445 <code>slog.Logger<\/code>. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u0441 Zap \u043d\u0430 Zerolog \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code>go get github.com\/rs\/zerolog <\/code><\/pre>\n<pre><code>go get github.com\/samber\/slog-zerolog <\/code><\/pre>\n<pre><code class=\"go\">package main  import (     \"log\/slog\"     \"os\"      \"github.com\/rs\/zerolog\"     slogzerolog \"github.com\/samber\/slog-zerolog\" )  func main() {     zerologL := zerolog.New(os.Stdout).Level(zerolog.InfoLevel)      logger := slog.New(         slogzerolog.Option{Logger: &amp;zerologL}.NewZerologHandler(),     )      logger.Info(         \"incoming request\",         slog.String(\"method\", \"GET\"),         slog.String(\"path\", \"\/api\/user\"),         slog.Int(\"status\", 200),     ) } <\/code><\/pre>\n<pre><code>{\"level\":\"info\",\"time\":\"2023-10-16T13:22:33+02:00\",\"method\":\"GET\",\"path\":\"\/api\/user\",\"status\":200,\"message\":\"incoming request\"}<\/code><\/pre>\n<p>\u0412 \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d\u043d\u043e\u043c \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0435 \u043a\u043e\u0434\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a Zap \u0431\u044b\u043b \u0437\u0430\u043c\u0435\u043d\u0451\u043d \u043d\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a <a href=\"https:\/\/github.com\/samber\/slog-zerolog\"><u>Zerolog<\/u><\/a>. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 API \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u0432\u0441\u0435\u0433\u043e \u043f\u0430\u0440\u0443 \u043c\u0438\u043d\u0443\u0442 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0435\u0439, \u043a\u043e\u0433\u0434\u0430 \u0432\u0430\u043c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0437\u0430\u043c\u0435\u043d\u044f\u0442\u044c \u043e\u0434\u0438\u043d API \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0432\u043e \u0432\u0441\u0451\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438.<\/p>\n<h2>Best practices \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043b\u043e\u0433\u043e\u0432 \u0432 Go:<\/h2>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u0432\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b\u0438 Slog \u0438\u043b\u0438 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u0435\u043c\u044b\u0439 \u0432\u0430\u043c\u0438 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c \u043f\u0440\u0438\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043b\u0443\u0447\u0448\u0438\u0445 \u043f\u0440\u0430\u043a\u0442\u0438\u043a:<\/p>\n<p><strong>1. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0438\u0437\u0438\u0440\u0443\u0439\u0442\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u0434\u043b\u044f \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. <\/strong>\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>LogValuer<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u043e\u0441\u043e\u0431 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u042d\u0442\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442 \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u044d\u0442\u0438\u0445 \u0442\u0438\u043f\u043e\u0432 \u0432 \u043b\u043e\u0433\u0430\u0445 \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e \u044d\u0442\u0430 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0443\u0442\u0435\u0447\u043a\u0443 \u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u043b\u043e\u0433\u043e\u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p><strong>2. \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0439\u0442\u0435 \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0443 \u0441\u0442\u0435\u043a\u0430 \u0432 \u043b\u043e\u0433\u0438 \u043e\u0448\u0438\u0431\u043e\u043a. <\/strong>\u0421 \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u043e\u0439 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043b\u0435\u0433\u0447\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u0433\u0434\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u0432 \u043a\u043e\u0434\u043e\u0432\u043e\u0439 \u0431\u0430\u0437\u0435 \u0438 \u043a\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u043f\u0440\u0438\u0432\u0451\u043b \u043a \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0435.<\/p>\n<p>Slog \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u0441\u0442\u0435\u043a\u0430 \u043a \u043e\u0448\u0438\u0431\u043a\u0430\u043c, \u043d\u043e, \u043a\u0430\u043a \u043c\u044b \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0440\u0430\u043d\u0435\u0435, \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0432\u0440\u043e\u0434\u0435 <a href=\"https:\/\/github.com\/pkg\/errors\"><u>pkgerrors<\/u><\/a> \u0438\u043b\u0438 <a href=\"https:\/\/github.com\/MDobak\/go-xerrors\"><u>go-xerrors<\/u><\/a> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0430\u0440\u044b \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<p><strong>3. \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0439\u0442\u0435 \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0437\u043e\u0432\u043e\u0432 Slog. <\/strong>\u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u0433\u043b\u0430\u0432\u043d\u044b\u0445 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u0432 API Slog \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u043e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0432\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u0430 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043d\u0435\u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u043e\u0441\u0442\u0438 \u0432 \u043a\u043e\u0434\u043e\u0432\u043e\u0439 \u0431\u0430\u0437\u0435. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0432\u044b \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u044c\u0442\u0435 \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u043d\u043e\u0441\u0442\u044c \u0432 \u0438\u043c\u0435\u043d\u0430\u0445 \u043a\u043b\u044e\u0447\u0435\u0439 (snake_case, camelCase \u0438 \u0442. \u0434.) \u0438\u043b\u0438 \u0447\u0442\u043e\u0431\u044b \u043b\u043e\u0433\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0432\u044b\u0437\u043e\u0432\u044b \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043b\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 context.<\/p>\n<p>\u041b\u0438\u043d\u0442\u0435\u0440, \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 <a href=\"https:\/\/github.com\/go-simpler\/sloglint\/releases\"><u>sloglint<\/u><\/a>, \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043c\u043e\u0447\u044c \u0432\u0430\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043b\u044f Slog. \u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0439 \u0447\u0435\u0440\u0435\u0437 <a href=\"https:\/\/freshman.tech\/linting-golang\/\"><u>golangci-lint<\/u><\/a>:<\/p>\n<pre><code class=\"yaml\">linters-settings:   sloglint:     # Enforce not mixing key-value pairs and attributes.     # Default: true     no-mixed-args: false     # Enforce using key-value pairs only (overrides no-mixed-args, incompatible with attr-only).     # Default: false     kv-only: true     # Enforce using attributes only (overrides no-mixed-args, incompatible with kv-only).     # Default: false     attr-only: true     # Enforce using methods that accept a context.     # Default: false     context-only: true     # Enforce using static values for log messages.     # Default: false     static-msg: true     # Enforce using constants instead of raw keys.     # Default: false     no-raw-keys: true     # Enforce a single key naming convention.     # Values: snake, kebab, camel, pascal     # Default: \"\"     key-naming-case: snake     # Enforce putting arguments on separate lines.     # Default: false     args-on-sep-lines: true <\/code><\/pre>\n<p><strong>4. \u0414\u0435\u043b\u0430\u0439\u0442\u0435 \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043b\u043e\u0433\u043e\u0432, \u043d\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0439\u0442\u0435 \u0438\u0445 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b. <\/strong>\u041e\u0431\u044b\u0447\u043d\u043e \u043b\u0443\u0447\u0448\u0435 \u043e\u0442\u0434\u0435\u043b\u044f\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u0437\u0430\u043f\u0438\u0441\u0438 \u043b\u043e\u0433\u043e\u0432 \u043e\u0442 \u0438\u0445 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0432 \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043b\u043e\u0433\u0430\u043c\u0438. \u0417\u0430\u043f\u0438\u0441\u044c \u043b\u043e\u0433\u043e\u0432 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u0443\u044e \u043a\u043e\u043f\u0438\u044e \u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043b\u043e\u0433\u0430\u043c\u0438 \u0438\u043b\u0438 \u0441\u0435\u0442\u044c\u044e. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u0443\u044e \u043f\u043e\u0442\u0435\u0440\u044e \u0432\u0430\u0436\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043b\u043e\u0433\u043e\u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u043e\u0439 \u0441\u043b\u0443\u0436\u0438\u0442 \u0431\u0443\u0444\u0435\u0440\u043e\u043c. \u042d\u0442\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u0438 \u0441\u043d\u0438\u0437\u0438\u0442\u044c \u0432\u043b\u0438\u044f\u043d\u0438\u0435 \u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043b\u043e\u0433\u043e\u0432 \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c. \u0415\u0441\u043b\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 \u0434\u0440\u0443\u0433\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043b\u043e\u0433\u0430\u043c\u0438, \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u043f\u043e\u0441\u043e\u0431 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438, \u0430 \u043d\u0435 \u0432\u0435\u0441\u044c \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 (\u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c) \u043e\u0431 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u043b\u043e\u0433\u043e\u0432, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a Vector \u0438\u043b\u0438 Fluentd.<\/p>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u0444\u0430\u0439\u043b\u044b \u043c\u043e\u0436\u043d\u043e \u043f\u043e-\u0440\u0430\u0437\u043d\u043e\u043c\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, Systemd \u043c\u043e\u0436\u0435\u0442 \u043b\u0435\u0433\u043a\u043e \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0432\u044b\u0432\u043e\u0434\u0430 \u0438 \u043e\u0448\u0438\u0431\u043e\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u0444\u0430\u0439\u043b. Docker \u0442\u0430\u043a\u0436\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0432\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0432 \u043e\u0431\u0430 \u043f\u043e\u0442\u043e\u043a\u0430, \u0438 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0445 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043d\u0430 \u0445\u043e\u0441\u0442-\u043c\u0430\u0448\u0438\u043d\u0435.<\/p>\n<p><strong>5. \u0414\u0435\u043b\u0430\u0439\u0442\u0435 \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u0443 \u0432\u044b\u0431\u043e\u0440\u043e\u043a \u0438\u0437 \u043b\u043e\u0433\u043e\u0432.<\/strong> \u0412\u044b\u0433\u0440\u0443\u0437\u043a\u0430 \u0432\u044b\u0431\u043e\u0440\u043e\u043a \u0438\u0437 \u043b\u043e\u0433\u043e\u0432 (log sampling) \u2014 \u044d\u0442\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 \u0437\u0430\u043f\u0438\u0441\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0440\u0435\u043f\u0440\u0435\u0437\u0435\u043d\u0442\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043b\u043e\u0433\u043e\u0432 \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u0441\u0435\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439. \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u043b\u0435\u0437\u0435\u043d \u0432 \u0441\u0440\u0435\u0434\u0430\u0445 \u0441 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439, \u043a\u043e\u0433\u0434\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e\u0442 \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043e\u0431\u044a\u0451\u043c\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043b\u043e\u0433\u043e\u0432, \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u043e\u0440\u043e\u0433\u043e\u0441\u0442\u043e\u044f\u0449\u0435\u0439.<\/p>\n<pre><code class=\"go\">package main  import (     \"fmt\"     \"log\/slog\"     \"os\"      slogmulti \"github.com\/samber\/slog-multi\"     slogsampling \"github.com\/samber\/slog-sampling\" )  func main() {     \/\/ Will print 20% of entries.     option := slogsampling.UniformSamplingOption{         Rate: 0.2,     }      logger := slog.New(         slogmulti.             Pipe(option.NewMiddleware()).             Handler(slog.NewJSONHandler(os.Stdout, nil)),     )      for i := 1; i &lt;= 10; i++ {         logger.Info(fmt.Sprintf(\"a message from the gods: %d\", i))     } } <\/code><\/pre>\n<pre><code>{\"time\":\"2023-10-18T19:14:09.820090798+02:00\",\"level\":\"INFO\",\"msg\":\"a message from the gods: 4\"} {\"time\":\"2023-10-18T19:14:09.820117844+02:00\",\"level\":\"INFO\",\"msg\":\"a message from the gods: 5\"}<\/code><\/pre>\n<p>\u0421\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a Zerolog \u0438 Zap, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u0438 \u0432\u044b\u0431\u043e\u0440\u043e\u043a \u0438\u0437 \u043b\u043e\u0433\u043e\u0432. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 Slog \u0432\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u0442\u0430\u043a\u043e\u0439 \u043a\u0430\u043a <a href=\"https:\/\/github.com\/samber\/slog-sampling\"><u>slog-sampling<\/u><\/a>, \u0438\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435. \u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u0443 \u0432\u044b\u0431\u043e\u0440\u043e\u043a \u0447\u0435\u0440\u0435\u0437 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u043b\u043e\u0433\u043e\u0432, \u0442\u0430\u043a\u0443\u044e \u043a\u0430\u043a Vector.<\/p>\n<p><strong>6. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043b\u043e\u0433\u0430\u043c\u0438.<\/strong> \u041a\u043e\u0433\u0434\u0430 \u043b\u043e\u0433\u0438 \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043b\u0435\u0433\u043a\u043e \u0438\u0441\u043a\u0430\u0442\u044c, \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0441\u0435\u0440\u0432\u0435\u0440\u0430\u0445 \u0438 \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f\u0445. \u041a\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u043b\u043e\u0433\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435, \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u0441\u043a\u043e\u0440\u044f\u0435\u0442\u0441\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u0442\u0430\u043a \u043a\u0430\u043a \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0435.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/eb5\/cf9\/540\/eb5cf954012a4fc1ddf99e22392ce3ae.png\" alt=\"\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\" title=\"\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\" width=\"650\" height=\"466\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/eb5\/cf9\/540\/eb5cf954012a4fc1ddf99e22392ce3ae.png\"\/><\/p>\n<div><figcaption><a href=\"https:\/\/betterstack.com\/community\/guides\/logging\/logging-in-go\/#customizing-the-default-logger\"><u>\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a<\/u><\/a><\/figcaption><\/div>\n<\/figure>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u042f \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043e\u0431\u0437\u043e\u0440 \u043f\u043e\u043c\u043e\u0433 \u0432\u0430\u043c \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 Go, \u0438 \u043a\u0430\u043a \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0447\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u0441\u0432\u043e\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445. \u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u044d\u0442\u0443 \u0442\u0435\u043c\u0443 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435, \u044f \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u043f\u043e\u043b\u043d\u044b\u043c <a href=\"https:\/\/go.googlesource.com\/proposal\/+\/master\/design\/56345-structured-logging.md\"><u>\u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c<\/u><\/a> \u0438 <a href=\"https:\/\/pkg.go.dev\/log\/slog\"><u>\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439<\/u><\/a> \u043a \u043f\u0430\u043a\u0435\u0442\u0443.<\/p>\n<hr\/>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0438\u0437\u0443\u0447\u0430\u0435\u0442\u0435 Golang, \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0435 \u0432 \u0421\u043b\u0451\u0440\u043c \u043d\u0430 \u043a\u0443\u0440\u0441\u044b <a href=\"https:\/\/slurm.io\/go-for-ops?utm_medium=article&amp;utm_source=habr&amp;utm_campaign=golang\">Golang \u0434\u043b\u044f \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u043e\u0432<\/a> \u0438 <a href=\"https:\/\/slurm.io\/go?utm_medium=article&amp;utm_source=habr&amp;utm_campaign=golang\">Golang-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a<\/a>. \u041e\u043d\u0438 \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u0432\u0430\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u043d\u0438\u044f \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u043f\u044b\u0442.<\/p>\n<p>\u261d\ufe0f \u0421\u0435\u0433\u043e\u0434\u043d\u044f 5 \u043c\u0430\u0440\u0442\u0430 \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0434\u0451\u043c <strong>\u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439 \u0432\u0435\u0431\u0438\u043d\u0430\u0440<\/strong> \u00ab<a href=\"https:\/\/www.youtube.com\/live\/JT5MViAu3W8?si=PC31l_Hr26FUyS_5\"><u>Goro \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0442\u0430\u0440\u0442\u0430. \u041a\u0443\u0434\u0430 \u0443\u0445\u043e\u0434\u0438\u0442 \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430?<\/u><\/a>\u00bb \u041d\u0430 \u043d\u0451\u043c \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Goro, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0434\u043e\u0440\u043e\u0432\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b. \u0412\u0435\u0431\u0438\u043d\u0430\u0440 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432 \u0437\u0430\u043f\u0438\u0441\u0438.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/798207\/\"> https:\/\/habr.com\/ru\/articles\/798207\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0411\u043e\u043b\u0435\u0435 10 \u043b\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043d\u0430 Go \u0436\u0430\u043b\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u043d\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u044f\u0434\u0440\u0435 Golang. \u0423\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430 Golang \u0434\u0430\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a Logrus, Zap \u0438 Zerolog. \u0412 2023 \u0433\u043e\u0434\u0443, \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 Google Go \u043d\u0430\u043a\u043e\u043d\u0435\u0446-\u0442\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043b\u0430 Slog \u2014 \u0432\u044b\u0441\u043e\u043a\u043e\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u0434\u043b\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043b\u043e\u0433\u043e\u0432 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 Go. \u041c\u044b \u043f\u0435\u0440\u0435\u0432\u0435\u043b\u0438 \u0433\u0430\u0439\u0434 \u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u0445 slog.<\/p>\n<figure class=\"full-width\"><\/figure>\n<h2>\u041f\u0440\u0435\u0434\u044b\u0441\u0442\u043e\u0440\u0438\u044f<\/h2>\n<p>\u041f\u0430\u043a\u0435\u0442 <a href=\"https:\/\/pkg.go.dev\/log\/slog\"><u>Slog<\/u><\/a> \u0431\u0435\u0440\u0435\u0442 \u0441\u0432\u043e\u0435 \u043d\u0430\u0447\u0430\u043b\u043e <a href=\"https:\/\/github.com\/golang\/go\/discussions\/54763\"><u>\u0432 \u0434\u0438\u0441\u043a\u0443\u0441\u0441\u0438\u0438 \u043d\u0430 GitHub, \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0439 \u0414\u0436\u043e\u043d\u0430\u0442\u0430\u043d\u043e\u043c \u0410\u043c\u0441\u0442\u0435\u0440\u0434\u0430\u043c\u043e\u043c<\/u><\/a>. \u0412 \u043d\u0435\u0439 \u0431\u044b\u043b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u0430\u043a\u0435\u0442\u0430. \u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u043d \u0431\u044b\u043b \u0432\u044b\u043f\u0443\u0449\u0435\u043d \u0432 <a href=\"https:\/\/tip.golang.org\/doc\/go1.21\"><u>Go v1.21<\/u><\/a> \u0438 \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 <code>log\/slog<\/code>.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 Slog \u0441 \u0441\u043e\u043f\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438. \u0414\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u043c\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 Go \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044c \u043a \u044d\u0442\u043e\u043c\u0443 <a href=\"https:\/\/github.com\/betterstack-community\/go-logging-benchmarks\"><u>\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044e GitHub<\/u><\/a>.<\/p>\n<h2>\u041d\u0430\u0447\u0430\u043b\u043e \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e Slog<\/h2>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0435\u043c \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 \u043f\u0430\u043a\u0435\u0442\u043e\u043c <code>log\/slog<\/code> \u0441 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043e\u043d \u0441\u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d. \u041e\u043d \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u0440\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0442\u0438\u043f\u0430, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0432\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0437\u043d\u0430\u043a\u043e\u043c\u044b:<\/p>\n<ul>\n<li>\n<p><code>Logger<\/code>: \u044d\u0442\u043e &#171;\u0444\u0440\u043e\u043d\u0442\u044d\u043d\u0434&#187; \u043b\u043e\u0433\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u0435\u0442\u043e\u0434\u044b \u0443\u0440\u043e\u0432\u043d\u044f (<code>Info()<\/code> \u0438 <code>Error()<\/code>) \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439.<\/p>\n<\/li>\n<li>\n<p><code>Record<\/code>: \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0436\u0443\u0440\u043d\u0430\u043b\u0430, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e <code>Logger<\/code>.<\/p>\n<\/li>\n<li>\n<p><code>Handler<\/code>: \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u0431\u0443\u0434\u0443\u0447\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e <code>Record<\/code>. \u0412 \u043f\u0430\u043a\u0435\u0442 <code>log\/slog<\/code> \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u0434\u0432\u0430 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430: <code>TextHandler<\/code> \u0438 <code>JSONHandler<\/code> \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <code>key=value<\/code> \u0438 JSON \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u0430\u043a \u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 Go, \u043f\u0430\u043a\u0435\u0442 <code>slog<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 <code>Logger<\/code>, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u0447\u0435\u0440\u0435\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f. \u042d\u0442\u043e\u0442 \u043b\u043e\u0433\u0435\u0440 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u043f\u043e\u0447\u0442\u0438 \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u043a\u0430\u043a \u0438 \u0441\u0442\u0430\u0440\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <code>log.Printf()<\/code>, \u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u0436\u0443\u0440\u043d\u0430\u043b\u0430:<\/p>\n<pre><code class=\"go\">package main  import (     \"log\"     \"log\/slog\" )  func main() {     log.Print(\"Info message\")     slog.Info(\"Info message\") } <\/code><\/pre>\n<pre><code>2024\/01\/03 10:24:22 Info message 2024\/01\/03 10:24:22 INFO Info message<\/code><\/pre>\n<p>\u042d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u0430\u043d\u043d\u043e, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f, \u0447\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0446\u0435\u043b\u044c Slog \u2014 \u043f\u0440\u0438\u0432\u043d\u0435\u0441\u0442\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043b\u043e\u0433\u043e\u0432 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443.<\/p>\n<p>\u0418\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e, \u0441\u043e\u0437\u0434\u0430\u0432 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>Logger<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <code>slog.New()<\/code>. \u041e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <code>Handler<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u043a\u0430\u043a \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0436\u0443\u0440\u043d\u0430\u043b\u044b \u0438 \u043a\u0443\u0434\u0430 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u044b.<\/p>\n<p>\u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0439 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f <code>JSONHandler<\/code> \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 JSON-\u043b\u043e\u0433\u043e\u0432 \u0432 <code>stdout<\/code>:<\/p>\n<pre><code class=\"go\">func main() {     logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))     logger.Debug(\"Debug message\")     logger.Info(\"Info message\")     logger.Warn(\"Warning message\")     logger.Error(\"Error message\") } <\/code><\/pre>\n<pre><code>{\"time\":\"2023-03-15T12:59:22.227408691+01:00\",\"level\":\"INFO\",\"msg\":\"Info message\"} {\"time\":\"2023-03-15T12:59:22.227468972+01:00\",\"level\":\"WARN\",\"msg\":\"Warning message\"} {\"time\":\"2023-03-15T12:59:22.227472149+01:00\",\"level\":\"ERROR\",\"msg\":\"Error message\"}<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0432\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>TextHandler<\/code>, \u043a\u0430\u0436\u0434\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u043c Logfmt:<\/p>\n<pre><code class=\"go\">logger := slog.New(slog.NewTextHandler(os.Stdout, nil))<\/code><\/pre>\n<pre><code>time=2023-03-15T13:00:11.333+01:00 level=INFO msg=\"Info message\" time=2023-03-15T13:00:11.333+01:00 level=WARN msg=\"Warning message\" time=2023-03-15T13:00:11.333+01:00 level=ERROR msg=\"Error message\"<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b <code>Logger<\/code> \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432\u0435\u0434\u0443\u0442 \u0436\u0443\u0440\u043d\u0430\u043b \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 <code>INFO<\/code>, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043f\u043e\u0434\u0430\u0432\u043b\u0435\u043d\u0438\u044e \u0437\u0430\u043f\u0438\u0441\u0438 <code>DEBUG<\/code>, \u043d\u043e \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043b\u0435\u0433\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u044d\u0442\u043e \u043f\u043e \u0441\u0432\u043e\u0435\u043c\u0443 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044e.<\/p>\n<h2>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043b\u043e\u0433\u0435\u0440\u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e<\/h2>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 <code>Logger<\/code> \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>slog.SetDefault()<\/code>, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043b\u043e\u0433\u0435\u0440 \u043d\u0430 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439.<\/p>\n<pre><code class=\"go\">func main() {     logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))      slog.SetDefault(logger)      slog.Info(\"Info message\") }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u043c\u0435\u0442\u043e\u0434\u044b \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u043f\u0430\u043a\u0435\u0442\u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u044b\u0434\u0430\u044e\u0442 JSON, \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0438\u0436\u0435:<\/p>\n<pre><code>{\"time\":\"2023-03-15T13:07:39.105777557+01:00\",\"level\":\"INFO\",\"msg\":\"Info message\"}<\/code><\/pre>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 <code>SetDefault()<\/code> \u0442\u0430\u043a\u0436\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 <code>log.Logger<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u043f\u0430\u043a\u0435\u0442\u043e\u043c <code>log<\/code>. \u0422\u0430\u043a\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u043c \u0441\u0442\u0430\u0440\u044b\u0439 <code>log<\/code>, \u043f\u043b\u0430\u0432\u043d\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c\u0443 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e:<\/p>\n<pre><code class=\"go\">func main() {     logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))      slog.SetDefault(logger)      \/\/ elsewhere in the application     log.Println(\"Hello from old logger\") }<\/code><\/pre>\n<pre><code>{\"time\":\"2023-03-16T15:20:33.783681176+01:00\",\"level\":\"INFO\",\"msg\":\"Hello from old logger\"}<\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>slog.NewLogLogger()<\/code> \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f <code>slog.Logger<\/code> \u0432 <code>log.Logger<\/code>, \u043a\u043e\u0433\u0434\u0430 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c API, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>http.Server.ErrorLog<\/code>):<\/p>\n<pre><code class=\"go\">func main() {     handler := slog.NewJSONHandler(os.Stdout, nil)      logger := slog.NewLogLogger(handler, slog.LevelError)      _ = http.Server{         \/\/ this API only accepts `log.Logger`         ErrorLog: logger,     } } <\/code><\/pre>\n<h2>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u0432 \u0437\u0430\u043f\u0438\u0441\u0438 \u0436\u0443\u0440\u043d\u0430\u043b\u0430<\/h2>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u043d\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0444\u043e\u0440\u043c\u0430\u0442\u0430\u043c\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u0432 \u0432\u0438\u0434\u0435 \u043f\u0430\u0440 \u043a\u043b\u044e\u0447\/\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u0437\u0430\u043f\u0438\u0441\u0438 \u0436\u0443\u0440\u043d\u0430\u043b\u0430.<\/p>\n<p>\u042d\u0442\u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0438. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0434\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447, \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043d\u0435\u043f\u043e\u043b\u0430\u0434\u043e\u043a, \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043c\u0435\u0442\u0440\u0438\u043a, \u0430\u0443\u0434\u0438\u0442 \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u0446\u0435\u043b\u0435\u0439.<\/p>\n<p>\u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0439, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 Slog:<\/p>\n<pre><code class=\"go\">logger.Info(   \"incoming request\",   \"method\", \"GET\",   \"time_taken_ms\", 158,   \"path\", \"\/hello\/world?q=search\",   \"status\", 200,   \"user_agent\", \"Googlebot\/2.1 (+http:\/\/www.google.com\/bot.html)\", )<\/code><\/pre>\n<pre><code>{   \"time\":\"2023-02-24T11:52:49.554074496+01:00\",   \"level\":\"INFO\",   \"msg\":\"incoming request\",   \"method\":\"GET\",   \"time_taken_ms\":158,   \"path\":\"\/hello\/world?q=search\",   \"status\":200,   \"user_agent\":\"Googlebot\/2.1 (+http:\/\/www.google.com\/bot.html)\" }<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0443\u0440\u043e\u0432\u043d\u044f (<code>Info()<\/code>, <code>Debug()<\/code> \u0438 \u0442. \u0434.) \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430, \u0430 \u0437\u0430\u0442\u0435\u043c \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043b\u0430\u0431\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u0430\u0440 \u043a\u043b\u044e\u0447\/\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.<\/p>\n<p>\u042d\u0442\u043e\u0442 API \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 SugaredLogger API \u0432 Zap (\u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u044b \u0443\u0440\u043e\u0432\u043d\u044f, \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u043d\u0430 <code>w<\/code>), \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432 \u043d\u0435\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043e\u0442\u0434\u0430\u0435\u0442\u0441\u044f \u043a\u0440\u0430\u0442\u043a\u043e\u0441\u0442\u0438 \u0437\u0430 \u0441\u0447\u0435\u0442 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p>\u041d\u043e \u0431\u0443\u0434\u044c\u0442\u0435 \u043e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u044b, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u044b\u043c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u043d\u0435\u0441\u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0430\u0440\u044b \u043a\u043b\u044e\u0447\/\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u043c\u0443 \u0432\u044b\u0432\u043e\u0434\u0443:<\/p>\n<pre><code class=\"go\">logger.Info(   \"incoming request\",   \"method\", \"GET\",   \"time_taken_ms\", \/\/ the value for this key is missing )<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043a\u043b\u044e\u0447 <code>time_taken_ms<\/code> \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441 \u043a\u043b\u044e\u0447\u043e\u043c <code>!BADKEY<\/code>. \u042d\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0435\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043b\u043e\u0445\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0435 \u0437\u043d\u0430\u0442\u044c \u043e\u0431 \u044d\u0442\u043e\u043c \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u0432\u0430\u043c \u043d\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0436\u0443\u0440\u043d\u0430\u043b\u044b.<\/p>\n<pre><code>{   \"time\": \"2023-03-15T13:15:29.956566795+01:00\",   \"level\": \"INFO\",   \"msg\": \"incoming request\",   \"method\": \"GET\",   \"!BADKEY\": \"time_taken_ms\" }<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <a href=\"https:\/\/pkg.go.dev\/cmd\/vet\"><u>vet<\/u><\/a> \u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/github.com\/go-simpler\/sloglint\"><u>\u043b\u0438\u043d\u0442\u0435\u0440<\/u><\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u043e \u0442\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0445.<\/p>\n<figure class=\"full-width\">\n<div><figcaption><a href=\"https:\/\/betterstack.com\/community\/guides\/logging\/logging-in-go\/#customizing-the-default-logger\"><u>\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a<\/u><\/a><\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u0440\u0443\u0433\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/pkg.go.dev\/log\/slog#Attr\"><u>\u0441\u0438\u043b\u044c\u043d\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b<\/u><\/a>, \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0438\u0436\u0435:<\/p>\n<pre><code class=\"go\">logger.Info(   \"incoming request\",   slog.String(\"method\", \"GET\"),   slog.Int(\"time_taken_ms\", 158),   slog.String(\"path\", \"\/hello\/world?q=search\"),   slog.Int(\"status\", 200),   slog.String(     \"user_agent\",     \"Googlebot\/2.1 (+http:\/\/www.google.com\/bot.html)\",   ), )<\/code><\/pre>\n<p>\u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c\u0443 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043b\u0443\u0447\u0448\u0435, \u043d\u043e \u043e\u043d \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u043c, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0438\u0447\u0442\u043e \u043d\u0435 \u043c\u0435\u0448\u0430\u0435\u0442 \u0432\u0430\u043c \u0441\u043c\u0435\u0448\u0438\u0432\u0430\u0442\u044c \u0441\u0438\u043b\u044c\u043d\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0438 \u0441\u043b\u0430\u0431\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0430\u0440\u044b \u043a\u043b\u044e\u0447\/\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"go\">logger.Info(   \"incoming request\",   \"method\", \"GET\",   slog.Int(\"time_taken_ms\", 158),   slog.String(\"path\", \"\/hello\/world?q=search\"),   \"status\", 200,   slog.String(     \"user_agent\",     \"Googlebot\/2.1 (+http:\/\/www.google.com\/bot.html)\",   ), )<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c \u0442\u0438\u043f\u043e\u0432 \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u043a \u0437\u0430\u043f\u0438\u0441\u044f\u043c, \u0432\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>LogAttrs()<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"go\">logger.LogAttrs(   context.Background(),   slog.LevelInfo,   \"incoming request\",   slog.String(\"method\", \"GET\"),   slog.Int(\"time_taken_ms\", 158),   slog.String(\"path\", \"\/hello\/world?q=search\"),   slog.Int(\"status\", 200),   slog.String(     \"user_agent\",     \"Googlebot\/2.1 (+http:\/\/www.google.com\/bot.html)\",   ), ) <\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0438\u043f <code>slog.Attr<\/code> \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0435\u0441\u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u043f\u0430\u0440\u0443 \u043a\u043b\u044e\u0447\/\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041e\u0434\u043d\u0430\u043a\u043e \u0435\u0433\u043e API \u0431\u043e\u043b\u0435\u0435 \u0437\u0430\u043f\u0443\u0442\u0430\u043d\u043d\u044b\u0439, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044e \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c \u0432 \u043c\u0435\u0442\u043e\u0434 \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 (\u0438\u043b\u0438 <code>nil<\/code>) \u0438 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0436\u0443\u0440\u043d\u0430\u043b\u0430.<\/p>\n<h2>\u0413\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432<\/h2>\n<p>Slog \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u043f\u043e\u0434 \u043e\u0434\u043d\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c, \u043d\u043e \u0432\u044b\u0432\u043e\u0434 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0433\u043e \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 <code>JSONHandler<\/code> \u043a\u0430\u0436\u0434\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430 \u0432\u043b\u043e\u0436\u0435\u043d\u0430 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442 JSON:<\/p>\n<pre><code class=\"go\">logger.LogAttrs(   context.Background(),   slog.LevelInfo,   \"image uploaded\",   slog.Int(\"id\", 23123),   slog.Group(\"properties\",     slog.Int(\"width\", 4000),     slog.Int(\"height\", 3000),     slog.String(\"format\", \"jpeg\"),   ), ) <\/code><\/pre>\n<pre><code>{   \"time\":\"2023-02-24T12:03:12.175582603+01:00\",   \"level\":\"INFO\",   \"msg\":\"image uploaded\",   \"id\":23123,   \"properties\":{     \"width\":4000,     \"height\":3000,     \"format\":\"jpeg\"   } }<\/code><\/pre>\n<p>\u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 <code>TextHandler<\/code> \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043b\u044e\u0447 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0432 \u0432\u0438\u0434\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b, \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0438\u0436\u0435:<\/p>\n<pre><code>time=2023-02-24T12:06:20.249+01:00 level=INFO msg=\"image uploaded\" id=23123   properties.width=4000 properties.height=3000 properties.format=jpeg<\/code><\/pre>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043b\u043e\u0433\u0435\u0440\u043e\u0432<\/h2>\n<p>\u0418\u043d\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0432\u043e \u0432\u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0431\u0435\u0437 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0449\u0438\u0445\u0441\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u043b\u043e\u0433.<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u043b\u043e\u0433\u0435\u0440\u044b. \u041e\u043d\u0438 \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u043d\u043e\u0432\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043b\u043e\u0433\u0435\u0440\u0430, \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u044f.<\/p>\n<p>\u0412 Slog \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043b\u043e\u0433\u0435\u0440\u043e\u0432 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <code>Logger.With()<\/code>. \u041e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u0434\u043d\u0443 \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u0440 \u043a\u043b\u044e\u0447\/\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 <code>Logger<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b.<\/p>\n<p>\u0420<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-370021","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/370021","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=370021"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/370021\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=370021"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=370021"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=370021"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}