{"id":343939,"date":"2023-01-15T03:00:26","date_gmt":"2023-01-15T03:00:26","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=343939"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=343939","title":{"rendered":"<span>\u0422\u0440\u0435\u0439\u0441\u0438\u043d\u0433 \u0432 Go \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e<\/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>\u0412 \u044d\u043f\u043e\u0445\u0443 \u0431\u044b\u0441\u0442\u0440\u043e\u0440\u0430\u0441\u0442\u0443\u0449\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0432\u0430\u0436\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0432 \u043b\u044e\u0431\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438<strong>.<\/strong> \u041e\u0434\u043d\u0438\u043c\u0438 \u0438\u0437 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043b\u043e\u0433\u0438 \u0438 \u043c\u0435\u0442\u0440\u0438\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0442 \u043d\u0430\u043c \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u043c\u043d\u043e\u0433\u0438\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438, \u0442\u0430\u043a\u0438\u043c\u0438 \u043a\u0430\u043a \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443 (RPS), \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, \u043f\u0440\u043e\u0446\u0435\u043d\u0442 \u0437\u0430\u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u0418\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043b\u043e\u0433\u0438 \u0438 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442 \u043d\u0430\u0448\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0442\u0430\u043a\u0443\u044e \u0432\u0430\u0436\u043d\u0443\u044e \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a\u0443, \u043a\u0430\u043a <strong>\u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u043e\u0441\u0442\u044c<\/strong> (<strong>Observability<\/strong>)<\/p>\n<p><strong>\u041d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u043e\u0441\u0442\u044c<\/strong> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u043b\u0435\u0433\u043a\u043e \u0443\u0441\u0442\u0440\u0430\u043d\u044f\u0442\u044c \u0431\u0430\u0433\u0438 \u0438 \u0440\u0435\u0448\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043e\u0442\u0432\u0435\u0447\u0430\u044f \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441 &#171;<em>\u041f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442?<\/em>&#171;.<\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0441\u043f\u0443\u0441\u0442\u044f \u043c\u0435\u0441\u044f\u0446\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043b\u043e\u0441\u044c \u0432 2 \u0440\u0430\u0437\u0430, \u043e \u0447\u0435\u043c \u043c\u044b \u0443\u0437\u043d\u0430\u043b\u0438 \u043f\u043e \u043c\u0435\u0442\u0440\u0438\u043a\u0430\u043c. \u0421\u0445\u043e\u0434\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u043e \u0432 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u0441 \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0430 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u044f\u0432\u043d\u043e\u0439. \u0427\u0442\u043e, \u0435\u0441\u043b\u0438 \u043d\u0430\u0447\u0430\u043b\u0438 \u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0447\u0430\u0441\u0442\u0435\u0439 \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430?  \u0412 \u0442\u0430\u043a\u0438\u0445 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u0445 \u043e\u0431\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u043c \u043d\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e, \u043d\u0438 \u0441\u0442\u043e\u0440\u043e\u043d\u0443, \u043a\u0443\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u043a\u043e\u043f\u0430\u0442\u044c. \u041d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u043d\u0430\u043c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <strong>\u0442\u0440\u0435\u0439\u0441\u0438\u043d\u0433 <\/strong>(<strong>tracing<\/strong>).<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043e\u0441\u043d\u043e\u0432\u044b \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0442\u0440\u0435\u0439\u0441\u0438\u043d\u0433\u0430 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 <a href=\"https:\/\/go.dev\/\" rel=\"noopener noreferrer nofollow\">\u044f\u0437\u044b\u043a\u0435 Go<\/a> c \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f<a href=\"https:\/\/opentelemetry.io\/\" rel=\"noopener noreferrer nofollow\"> OpenTelemetry<\/a> \u0438 <a href=\"https:\/\/www.jaegertracing.io\/\" rel=\"noopener noreferrer nofollow\">Jaeger<\/a>. \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0432\u0437\u044f\u0442\u0430 \u0438\u0437 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u044d\u0442\u0443 \u0442\u0435\u043c\u0443.<\/p>\n<h2>OpenTelemetry<\/h2>\n<p><a href=\"https:\/\/opentelemetry.io\/\" rel=\"noopener noreferrer nofollow\">OpenTelemetry<\/a> (OTel) &#8212; \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u0441\u0431\u043e\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e \u0440\u0430\u0431\u043e\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0438\u0434\u0435\u0439 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a OpenCensus \u0438 OpenTracing. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 &#8212; \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043d\u0430\u0431\u043e\u0440 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 SDK, API \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0441\u0435\u0440\u0432\u0438\u0441\u044b (<strong>observability back-end<\/strong>) \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0441\u0438\u0441\u0442\u0435\u043c.<\/p>\n<p>\u0412 OTel \u0432\u0445\u043e\u0434\u044f\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u043e\u0432 (C++, Java, Python, .NET, PHP, Rust <a href=\"https:\/\/opentelemetry.io\/docs\/instrumentation\/\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a<\/a>), \u0430 \u0442\u0430\u043a\u0436\u0435 \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0438\u043d\u0441\u0442\u0443\u043c\u0435\u043d\u0442\u044b \u043e\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430 \u0434\u043b\u044f \u0442\u0440\u0435\u0439\u0441\u0438\u043d\u0433\u0430 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432. \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043d\u0430\u0447\u0430\u0442\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0433\u043b\u0430\u0432\u043d\u044b\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u0432 OpenTelemetry, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c. \u041f\u0435\u0440\u0432\u044b\u043c \u0432\u0430\u0436\u043d\u044b\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c OpenTelemetry \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <strong>span.<\/strong><\/p>\n<h2>Span<\/h2>\n<p>Span \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0435\u0434\u0438\u043d\u0438\u0446\u0443 \u0440\u0430\u0431\u043e\u0442\u044b (\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f) \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u041e\u043d \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f (events), \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441, \u0440\u0438\u0441\u0443\u044f \u043a\u0430\u0440\u0442\u0438\u043d\u0443 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0437\u0430 \u0432\u0440\u0435\u043c\u044f, \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044d\u0442\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0431\u044b\u043b\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430. \u041e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043c\u044f, \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 (\u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b) \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0431 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u043c\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 span http \u0437\u0430\u043f\u0440\u043e\u0441\u0430: <\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/63f\/693\/b70\/63f693b700057166b611f5db6bffa91f.png\" alt=\"\u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0435, \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 + \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438 \u0432\u0435\u0440\u0441\u0438\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \" title=\"\u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0435, \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 + \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438 \u0432\u0435\u0440\u0441\u0438\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \" width=\"446\" height=\"583\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/63f\/693\/b70\/63f693b700057166b611f5db6bffa91f.png\"\/><figcaption>\u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0435, \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 + \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438 \u0432\u0435\u0440\u0441\u0438\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. <\/figcaption><\/figure>\n<p>\u041e\u043d\u0438 \u0434\u0435\u043b\u044f\u0442\u0441\u044f \u043d\u0430 \u0434\u0432\u0430 \u0442\u0438\u043f\u0430: <strong>Parent (root) span<\/strong> \u0438 <strong>Child span<\/strong>. \u0414\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u0441\u043f\u0430\u043d\u044b \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u043f\u0440\u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u0430\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u044e\u0442\u0441\u044f \u043e\u0442 \u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e. \u0412 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u044f\u0437\u044b\u043a\u0430 Go \u0438\u0445 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442 \u0447\u0435\u0440\u0435\u0437<a href=\"https:\/\/pkg.go.dev\/context#Context%5C\" rel=\"noopener noreferrer nofollow\"> context.Context<\/a>. <\/p>\n<p>\u041f\u0440\u0430\u0432\u0438\u043b\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0435: \u0435\u0441\u043b\u0438 \u0432 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0441\u043f\u0430\u043d, \u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0439 \u043e\u0442 \u043d\u0435\u0433\u043e. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0436\u0435 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 (root) span.<\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 span \u0438\u043c\u0435\u0435\u0442 <strong>span_id<\/strong> \u0438 <strong>trace_id.<\/strong> \u0412\u0430\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u043e\u0442 \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438 \u0434\u043e \u043a\u043e\u043d\u0446\u0430 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u0441\u043f\u0430\u043d\u043e\u0432 <strong>trace_id \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f<\/strong>, \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a <strong>span_id<\/strong> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043f\u0430\u043d\u0430 <strong>\u0443\u043d\u0438\u043a\u0430\u043b\u0435\u043d<\/strong>. \u0422\u0430\u043a\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0438 \u0432\u0435\u0442\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/48b\/3a6\/01a\/48b3a601a7ca76491436864324426157.jpeg\" alt=\"\" title=\"\" width=\"700\" height=\"518\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/48b\/3a6\/01a\/48b3a601a7ca76491436864324426157.jpeg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c <strong>trace_id<\/strong> \u043c\u0435\u0436\u0434\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u0432 \u043a\u043e\u043d\u0446\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0432\u044b\u0437\u043e\u0432\u043e\u0432. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044f \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0432\u0441\u0435\u0445 \u0435\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430\u0445 \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0438 (\u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e).<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/05d\/01e\/d97\/05d01ed97fd53e388661164f4bb7213e.png\" alt=\"\u041f\u0440\u0438\u043c\u0435\u0440 \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0441 \u043e\u0434\u043d\u0438\u043c trace_id  \" title=\"\u041f\u0440\u0438\u043c\u0435\u0440 \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0441 \u043e\u0434\u043d\u0438\u043c trace_id  \" width=\"666\" height=\"296\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/05d\/01e\/d97\/05d01ed97fd53e388661164f4bb7213e.png\"\/><figcaption>\u041f\u0440\u0438\u043c\u0435\u0440 \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0441 \u043e\u0434\u043d\u0438\u043c trace_id  <\/figcaption><\/figure>\n<p>\u0421\u0442\u0430\u0442\u0443\u0441 \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u0437 \u0434\u0432\u0443\u0445 \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u0432: <strong>Error<\/strong> \u0438 <strong>Ok<\/strong> . \u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u0438\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f, \u0441\u0442\u0430\u0442\u0443\u0441 <strong>Error <\/strong>\u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430, \u0430 <strong>Ok <\/strong>\u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442 &#8212; \u0432\u0441\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b\u0438\u0441\u044c \u0443\u0441\u043f\u0435\u0448\u043d\u043e<\/p>\n<h2>Jaeger<\/h2>\n<p>\u0420\u0430\u043d\u0435\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c, \u0447\u0442\u043e OpenTelemetry \u0442\u043e\u043b\u044c\u043a\u043e \u0433\u043e\u0442\u043e\u0432\u0438\u0442 (\u043d\u0435 \u0445\u0440\u0430\u043d\u0438\u0442!) \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 <strong>observability back-end<\/strong>. \u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0442\u0430\u043a\u043e\u0433\u043e \u0431\u044d\u043a\u0435\u043d\u0434\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <a href=\"https:\/\/www.jaegertracing.io\/\" rel=\"noopener noreferrer nofollow\">Jaeger<\/a>.<\/p>\n<p>\u041d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 \u0431\u044b\u043b\u0430 <code>1.41.0<\/code>. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0431 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c <a href=\"https:\/\/www.jaegertracing.io\/docs\/1.41\/getting-started\/\" rel=\"noopener noreferrer nofollow\">\u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a><\/p>\n<p><strong> \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<\/strong><\/p>\n<details class=\"spoiler\">\n<summary>Docker<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">docker run -d --name jaeger \\   -p 16686:16686 \\   -p 14268:14268 \\   jaegertracing\/all-in-one:1.41<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>Docker-compose<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">version: '3.8'  services:   jaeger:     image: jaegertracing\/all-in-one     ports:       - \"14268:14268\"       - \"16686:16686\" <\/code><\/pre>\n<pre><code class=\"bash\">docker compose up -d<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u0430\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0421\u043a\u0430\u0447\u0430\u0442\u044c \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a <a href=\"https:\/\/www.jaegertracing.io\/download\/\" rel=\"noopener noreferrer nofollow\">https:\/\/www.jaegertracing.io\/download\/<\/a> <\/p>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0438 <code>http:\/\/localhost:16686 <\/code> \u0432\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u0443:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0a9\/5bb\/2b6\/0a95bb2b6089213afd48e85633242e7d.png\" width=\"1600\" height=\"701\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0a9\/5bb\/2b6\/0a95bb2b6089213afd48e85633242e7d.png\"\/><figcaption><\/figcaption><\/figure>\n<h2>\u041f\u0438\u0448\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u0441\u0435\u0440\u0432\u0438\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442 \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u0437\u0430\u043c\u0435\u0442\u043a\u0438 \u0438\u0437 Redis. <\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>\u251c\u2500\u2500 storage \u2502\u00a0\u00a0 \u2514\u2500\u2500 redis.go \u251c\u2500\u2500 server \u2502\u00a0\u00a0 \u2514\u2500\u2500 http.go \u251c\u2500\u2500 models \u2502\u00a0\u00a0 \u2514\u2500\u2500 note.go \u251c\u2500\u2500 main.go \u251c\u2500\u2500 go.sum \u251c\u2500\u2500 go.mod \u251c\u2500\u2500 docker-compose.yaml \u2514\u2500\u2500 cmd     \u2514\u2500\u2500 main.go<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>models\/note.go<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"go\">package models  import ( \"errors\" \"time\" ) import \"github.com\/google\/uuid\"  var ErrNotFound = errors.New(\"note not found\")  type Note struct { NoteID  uuid.UUID `json:\"note_id\"` Title   string    `json:\"title\"` Content string    `json:\"content\"` Created time.Time `json:\"created\"` }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>storage\/redis.go<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"go\">package storage  import ( \"context\" \"encoding\/json\" \"fmt\" \"github.com\/go-redis\/redis\/v9\" \"github.com\/google\/uuid\" \"trace-example\/models\" )  type NotesStorage struct { client redis.UniversalClient }  func NewNotesStorage(client redis.UniversalClient) NotesStorage { return NotesStorage{client: client} }  func (s NotesStorage) Store(ctx context.Context, note models.Note) error { data, err := json.Marshal(note) if err != nil { return fmt.Errorf(\"marshal note: %w\", err) }  if err = s.client.Set(ctx, note.NoteID.String(), data, -1).Err(); err != nil { return fmt.Errorf(\"redis set: %w\", err) }  return nil }  func (s NotesStorage) Get(ctx context.Context, noteID uuid.UUID) (*models.Note, error) { data, err := s.client.Get(ctx, noteID.String()).Bytes() if err != nil { if err == redis.Nil { return nil, models.ErrNotFound } return nil, fmt.Errorf(\"redis get: %w\", err) }  var note models.Note if err = json.Unmarshal(data, &amp;note); err != nil { return nil, fmt.Errorf(\"unmarshal note: %w\", err) }  return &amp;note, nil } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>server\/http.go<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"go\">package server  import ( \"errors\" \"github.com\/gofiber\/fiber\/v2\" \"github.com\/google\/uuid\" \"time\" \"trace-example\/models\" \"trace-example\/storage\" )  type FiberHandler struct { notesStorage storage.NotesStorage }  func NewFiberHandler(notesStorage storage.NotesStorage) FiberHandler { return FiberHandler{notesStorage: notesStorage} }  func (h FiberHandler) CreateNote(fiberctx *fiber.Ctx) error { input := struct { Title   string `json:\"title\"` Content string `json:\"content\"` }{}  if err := fiberctx.BodyParser(&amp;input); err != nil { return err }  noteID := uuid.New() err := h.notesStorage.Store(fiberctx.UserContext(), models.Note{ NoteID:  noteID, Title:   input.Title, Content: input.Content, Created: time.Now(), }) if err != nil { return fiber.NewError(fiber.StatusInternalServerError, err.Error()) }  return fiberctx.JSON(map[string]any{ \"note_id\": noteID, }) }  func (h FiberHandler) GetNote(fiberctx *fiber.Ctx) error { noteID, err := uuid.Parse(fiberctx.Query(\"note_id\")) if err != nil { return fiber.NewError(fiber.StatusBadRequest, err.Error()) }  note, err := h.notesStorage.Get(fiberctx.UserContext(), noteID) if err != nil { if errors.Is(err, models.ErrNotFound) { return fiber.NewError(fiber.StatusNotFound, err.Error()) } return fiber.NewError(fiber.StatusInternalServerError, err.Error()) }  return fiberctx.JSON(note) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>cmd\/main.go<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"go\">package main  import ( \"context\" \"github.com\/go-redis\/redis\/v9\" \"github.com\/gofiber\/fiber\/v2\" \"log\" \"trace-example\/server\" \"trace-example\/storage\" )  func main() { app := fiber.New()  \/\/ \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c\u0441\u044f \u043a Redis client := redis.NewClient(&amp;redis.Options{ Addr: \"localhost:6379\", }) if err := client.Ping(context.TODO()).Err(); err != nil { log.Fatal(\"create redis client\", err) }  \/\/ \u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0440\u043e\u0443\u0442\u0435\u0440 handler := server.NewFiberHandler(storage.NewNotesStorage(client)) app.Post(\"\/create\", handler.CreateNote) app.Get(\"\/get\", handler.GetNote)  log.Fatal(app.Listen(\":8080\")) } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>docker-compose.yaml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"go\">version: '3.8'  services:    jaeger:     image: jaegertracing\/all-in-one     ports:       - \"14268:14268\"       - \"16686:16686\"     redis:     restart: on-failure      image: \"redis:latest\"      command: redis-server --port 6380      ports:       - \"6379:6379\"      environment:       REDIS_REPLICATION_MODE: master      volumes:       - redis-data:\/var\/lib\/redis  volumes:   redis-data:<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0441 Redis \u0438 Jaeger<\/p>\n<pre><code class=\"bash\">docker compose up -d<\/code><\/pre>\n<p>\u0418 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0438\u0441<\/p>\n<pre><code class=\"go\">go run cmd\/main.go<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0441\u0442\u0430\u0440\u0442\u0430 \u043c\u043e\u0436\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u043c\u0435\u0442\u043a\u0443:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f4d\/55c\/11d\/f4d55c11d84fe0ecf3c6ee2bb07af421.png\" width=\"584\" height=\"408\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f4d\/55c\/11d\/f4d55c11d84fe0ecf3c6ee2bb07af421.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0418 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0435\u0451 \u043e\u0431\u0440\u0430\u0442\u043d\u043e:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cee\/92f\/3d0\/cee92f3d027d5ca7dcfe49c12db22476.png\" width=\"572\" height=\"474\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cee\/92f\/3d0\/cee92f3d027d5ca7dcfe49c12db22476.png\"\/><figcaption><\/figcaption><\/figure>\n<details class=\"spoiler\">\n<summary>curl \u0437\u0430\u043f\u0440\u043e\u0441\u044b<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u043c\u0435\u0442\u043a\u0438<\/p>\n<pre><code class=\"bash\">curl --location --request POST 'localhost:8080\/create' \\ --header 'Content-Type: application\/json' \\ --data-raw '{     \"title\":\"Something interesting\",     \"content\": \"Lorem ipsum...\" }'<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u043c\u0435\u0442\u043a\u0438<\/p>\n<pre><code class=\"bash\">curl --location --request GET 'localhost:8080\/get?note_id=7411ff79-fd1d-46ab-b9f8-21105cd770ce'<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e OpenTelemetry \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f <strong>\u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0435\u0440\u0430 (exporter) <\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 (\u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442) \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 <strong>observability back-end <\/strong>\u0438<strong> <\/strong>\u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438\u043d\u0442\u0435\u0444\u0435\u0439\u0441<\/p>\n<pre><code class=\"go\">type SpanExporter interface {     ExportSpans(ctx context.Context, spans []ReadOnlySpan) error     Shutdown(ctx context.Context) error }<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0432\u0438\u0434 \u0441\u043f\u0430\u043d\u043e\u0432 &#8212; <strong>ReadOnlySpan. <\/strong>\u042d\u0442\u043e \u043d\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0442\u0438\u043f, \u0430 \u043f\u0440\u043e\u0441\u0442\u043e  \u0438\u043d\u0442\u0435\u0444\u0435\u0439\u0441 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u0441\u043f\u0430\u043d\u0435.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c <strong>exporter<\/strong> \u0434\u043b\u044f Jaeger:<\/p>\n<pre><code class=\"go\">package tracer  import ( \"go.opentelemetry.io\/otel\/exporters\/jaeger\" tracesdk \"go.opentelemetry.io\/otel\/sdk\/trace\" )  \/\/ NewJaegerExporter creates new jaeger exporter \/\/ \/\/url example - http:\/\/localhost:14268\/api\/traces func NewJaegerExporter(url string) (tracesdk.SpanExporter, error) { return jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url))) } <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c <strong>\u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 (provider),<\/strong> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c <strong>\u0442\u0440\u0435\u0439\u0441\u0435\u0440\u044b (tracers)<\/strong><\/p>\n<pre><code class=\"go\">package tracer  import ( \"go.opentelemetry.io\/otel\/exporters\/jaeger\" \"go.opentelemetry.io\/otel\/sdk\/resource\" tracesdk \"go.opentelemetry.io\/otel\/sdk\/trace\" semconv \"go.opentelemetry.io\/otel\/semconv\/v1.12.0\" )  func NewTraceProvider(exp tracesdk.SpanExporter, ServiceName string) (*tracesdk.TracerProvider, error) { \/\/ Ensure default SDK resources and the required service name are set. r, err := resource.Merge( resource.Default(), resource.NewWithAttributes( semconv.SchemaURL, semconv.ServiceNameKey.String(ServiceName), ), ) if err != nil { return nil, err }  return tracesdk.NewTracerProvider( tracesdk.WithBatcher(exp), tracesdk.WithResource(r), ), nil } <\/code><\/pre>\n<p>\u0420\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043a\u043e\u0434:<\/p>\n<pre><code class=\"go\">return tracesdk.NewTracerProvider( tracesdk.WithBatcher(exp), tracesdk.WithResource(r), ), nil<\/code><\/pre>\n<p>\u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043e\u043f\u0446\u0438\u0438:<\/p>\n<ul>\n<li>\n<p><strong>WithBatcher<\/strong> &#8212; \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0435\u0440\u0443 \u043f\u0430\u0447\u043a\u0430\u043c\u0438, \u043f\u043e\u0432\u044b\u0448\u0430\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c<\/p>\n<\/li>\n<li>\n<p><strong>WithResourse<\/strong> &#8212; \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0432 \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0440\u0435\u0439\u0441 \u0434\u0430\u043d\u043d\u044b\u0435 (\u0440\u0435\u0441\u0443\u0440\u0441\u044b)<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"go\">resource.Merge( resource.Default(), resource.NewWithAttributes( semconv.SchemaURL, semconv.ServiceNameKey.String(ServiceName), ), )<\/code><\/pre>\n<p><strong>resource.Merge<\/strong> \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432. \u0412\u043c\u0435\u0441\u0442\u0435 \u0441\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c\u0438 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0435\u0440\u0441\u0438\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u0447\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0435\u0439\u0441\u044b \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0440\u0435\u0439\u0441\u0435\u0440:<\/p>\n<pre><code class=\"go\">package tracer  import ( \"fmt\" \"go.opentelemetry.io\/otel\" \"go.opentelemetry.io\/otel\/exporters\/jaeger\" \"go.opentelemetry.io\/otel\/sdk\/resource\" tracesdk \"go.opentelemetry.io\/otel\/sdk\/trace\" semconv \"go.opentelemetry.io\/otel\/semconv\/v1.12.0\" \"go.opentelemetry.io\/otel\/trace\" )  func InitTracer(jaegerURL string, serviceName string) (trace.Tracer, error) { exporter, err := NewJaegerExporter(jaegerURL) if err != nil { return nil, fmt.Errorf(\"initialize exporter: %w\", err) }  tp, err := NewTraceProvider(exporter, serviceName) if err != nil { return nil, fmt.Errorf(\"initialize provider: %w\", err) }  otel.SetTracerProvider(tp) \/\/ !!!!!!!!!!!  return tp.Tracer(\"main tracer\"), nil } <\/code><\/pre>\n<p><code>otel.SetTracerProvider(tp)<\/code>  &#8212; \u043e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430. \u041e\u043d\u0430 \u0437\u0430\u0434\u0430\u0435\u0442 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u0434\u0440\u0443\u0433\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0441 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u043c \u043c\u043e\u0433\u043b\u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0442\u0440\u0435\u0439\u0441\u044b<\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0432 main.go \u0432\u044b\u0437\u043e\u0432 <code>InitTracer <\/code>:<\/p>\n<pre><code class=\"go\">func main() { tracer, err := trace.InitTracer(\"http:\/\/localhost:14268\/api\/traces\", \"Note Service\") if err != nil { log.Fatal(\"init tracer\", err) } ........<\/code><\/pre>\n<h2>\u0418\u0449\u0435\u043c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0438\u043d\u0441\u0442\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439:<\/h2>\n<blockquote>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439 \u043d\u0430\u0439\u0442\u0438 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435<\/p>\n<\/blockquote>\n<p>\u0412\u0441\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u0442\u0440\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u043f\u043e\u0438\u0441\u043a\u0430 \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f<\/p>\n<ol>\n<li>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 <a href=\"https:\/\/github.com\/open-telemetry\/opentelemetry-go-contrib\/tree\/main\/instrumentation\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/open-telemetry\/opentelemetry-go-contrib\/tree\/main\/instrumentation<\/a><\/p>\n<\/li>\n<li>\n<p> \u041d\u0430\u0439\u0442\u0438 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043d\u0443\u0436\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043f\u0430\u043a\u0435\u0442 <code>otelXxx<\/code> (Xxx &#8212; \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438)<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0433\u0443\u0433\u043b\u0438\u0442\u044c \ud83d\ude42 <code>golang \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435_\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 OpenTelemetry<\/code><\/p>\n<\/li>\n<\/ol>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0439\u0434\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0434\u043b\u044f <a href=\"https:\/\/github.com\/gofiber\/fiber\" rel=\"noopener noreferrer nofollow\">github.com\/gofiber\/fiber<\/a>:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4d7\/5eb\/c13\/4d75ebc13ea7463aa0ee71bcf9d5edd3.png\" width=\"398\" height=\"295\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4d7\/5eb\/c13\/4d75ebc13ea7463aa0ee71bcf9d5edd3.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/246\/992\/08c\/24699208c9b01b25ea96611def8f6307.png\" width=\"858\" height=\"173\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/246\/992\/08c\/24699208c9b01b25ea96611def8f6307.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0437\u0430\u0430\u0440\u0445\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u043d, \u043d\u043e \u0435\u0433\u043e \u043a\u043e\u0434 \u0431\u044b\u043b \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0432 <a href=\"https:\/\/github.com\/gofiber\/contrib\/tree\/main\/otelfiber\" rel=\"noopener noreferrer nofollow\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439<\/a><\/p>\n<p>\u041c\u043d\u043e\u0433\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0435 \u0438\u043c\u0435\u044e\u0442 <code>readme.md<\/code> \u0444\u0430\u0439\u043b\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0435\u0433\u0434\u0430 \u043b\u0443\u0447\u0448\u0435 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 <a href=\"https:\/\/github.com\/gofiber\/contrib\/tree\/main\/otelfiber\/example\" rel=\"noopener noreferrer nofollow\">\u043f\u0430\u043f\u043a\u0443 example<\/a>. \u041d\u0430\u0445\u043e\u0434\u0438\u043c \u0441\u0442\u0440\u043e\u043a\u0443 <code>app.Use(otelfiber.Middleware(\"my-server\"))<\/code><em> . <\/em>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0435\u0451 \u0432 \u043d\u0430\u0448 \u043a\u043e\u0434!<\/p>\n<pre><code class=\"go\">import \"github.com\/gofiber\/contrib\/otelfiber\"  func main() {     _, err := trace.InitTracer(\"http:\/\/localhost:14268\/api\/traces\", \"Note Service\")     ....... app := fiber.New() app.Use(otelfiber.Middleware(\"my-server\")) \/\/ &lt;-------     .......<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u0432\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u0432 Jaeger:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c72\/3ba\/364\/c723ba3648fdd7c7ae7c7961a1ef9282.png\" alt=\"\u041d\u0430\u0448 \u0441\u0435\u0440\u0432\u0438\u0441 \u0432\u0438\u0434\u0435\u043d \u0432 \u0441\u043f\u0438\u0441\u043a\u0435!\" title=\"\u041d\u0430\u0448 \u0441\u0435\u0440\u0432\u0438\u0441 \u0432\u0438\u0434\u0435\u043d \u0432 \u0441\u043f\u0438\u0441\u043a\u0435!\" width=\"393\" height=\"152\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c72\/3ba\/364\/c723ba3648fdd7c7ae7c7961a1ef9282.png\"\/><figcaption>\u041d\u0430\u0448 \u0441\u0435\u0440\u0432\u0438\u0441 \u0432\u0438\u0434\u0435\u043d \u0432 \u0441\u043f\u0438\u0441\u043a\u0435!<\/figcaption><\/figure>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5fd\/420\/93d\/5fd42093dda2d080802428856daac113.png\" alt=\"\u041d\u0430\u0436\u0438\u043c\u0430\u0435\u043c Find Traces!\" title=\"\u041d\u0430\u0436\u0438\u043c\u0430\u0435\u043c Find Traces!\" width=\"385\" height=\"140\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5fd\/420\/93d\/5fd42093dda2d080802428856daac113.png\"\/><figcaption>\u041d\u0430\u0436\u0438\u043c\u0430\u0435\u043c Find Traces!<\/figcaption><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u043d\u0430 Find Traces \u0443\u0432\u0438\u0434\u0438\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u043d\u0430\u0448\u0438\u0445 \u0442\u0440\u0435\u0439\u0441\u043e\u0432:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e4d\/5e6\/c4a\/e4d5e6c4a99c07b4a2939686e53e7e56.png\" width=\"1221\" height=\"619\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e4d\/5e6\/c4a\/e4d5e6c4a99c07b4a2939686e53e7e56.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0432 \u043d\u0443\u0436\u043d\u044b\u0439 \u043d\u0430\u043c \u0442\u0440\u0435\u0439\u0441 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 \u0435\u0433\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435. <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/505\/c83\/0b9\/505c830b921b4e2480af6014e9eacb41.png\" width=\"968\" height=\"631\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/505\/c83\/0b9\/505c830b921b4e2480af6014e9eacb41.png\"\/><figcaption><\/figcaption><\/figure>\n<h3>\u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442?<\/h3>\n<p>\u0420\u0430\u043d\u0435\u0435 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043c\u0438\u0434\u043b\u0432\u0430\u0440\u044c \u0434\u043b\u044f \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 fiber, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0441\u043f\u0430\u043d \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u0435\u0433\u043e \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0435. \u0417\u0430\u043c\u0435\u0442\u044c\u0442\u0435, \u0447\u0442\u043e \u0431\u0435\u0437 \u0441\u0442\u0440\u043e\u043a\u0438 <code>otel.SetTracerProvider<\/code> \u044d\u0442\u043e\u0442 \u0442\u0440\u0435\u0439\u0441 <strong>\u043d\u0438\u0433\u0434\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f.<\/strong><\/p>\n<p>\u0412 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043f\u0430\u043d\u0430 \u043e\u043d \u0432\u043a\u043b\u044e\u0447\u0438\u043b \u0434\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438 \u043e\u0442\u0432\u0435\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0432\u0430\u0436\u043d\u044b\u043c\u0438 \u043f\u0440\u0438 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0443 \u0434\u043b\u044f \u0440\u0435\u0434\u0438\u0441\u0430: \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u043f\u043e\u0438\u0441\u043a\u0430 \u0443\u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u0443\u0436\u0435 \u043b\u0435\u0436\u0438\u0442 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 <em>go-redis<\/em> &#8212; <a href=\"https:\/\/github.com\/go-redis\/redis\/tree\/master\/extra\/redisotel\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/go-redis\/redis\/tree\/master\/extra\/redisotel<\/a>. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0435\u0433\u043e \u0432 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"go\">import \"github.com\/go-redis\/redis\/extra\/redisotel\/v9\"  func main() {     ......... \/\/ \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c\u0441\u044f \u043a Redis client := redis.NewClient(&amp;redis.Options{ Addr: \"localhost:6379\", }) if err := client.Ping(context.TODO()).Err(); err != nil { log.Fatal(\"create redis client\", err) } if err := redisotel.InstrumentTracing(client); err != nil { \/\/ &lt;------ log.Fatal(\"enable instrument tracing\", err) }     .........<\/code><\/pre>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u043c \u0435\u0449\u0451 \u0440\u0430\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0442\u0440\u0435\u0439\u0441\u044b. \u041d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u043d\u0430\u0436\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 <code>Find Traces<\/code> \u0435\u0449\u0451 \u0440\u0430\u0437 (\u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443)<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5a1\/980\/10a\/5a198010aa3a1215c8b5d181eb66f358.png\" width=\"1600\" height=\"639\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5a1\/980\/10a\/5a198010aa3a1215c8b5d181eb66f358.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0444\u0438\u0431\u0435\u0440\u0430, \u043d\u043e \u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0432 \u0431\u0434!<\/p>\n<h2>\u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442?<\/h2>\n<p><code>redisotel <\/code>\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0445\u0443\u043a \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043b\u044e\u0431\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0441\u043f\u0430\u043d  \u0441 \u043d\u0443\u0436\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438.<\/p>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u0432\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u043d\u043e \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0439\u0442\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0442\u0435\u043d \u0434\u043b\u044f \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a. \u041f\u0440\u0438\u043c\u0435\u0440\u044b:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/github.com\/open-telemetry\/opentelemetry-go-contrib\/tree\/main\/instrumentation\/google.golang.org\/grpc\/otelgrpc\" rel=\"noopener noreferrer nofollow\">otelgrpc<\/a> &#8212; \u0443\u043d\u0430\u0440\u043d\u044b\u0439 interceptor \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 gRPC<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/open-telemetry\/opentelemetry-go-contrib\/tree\/main\/instrumentation\/go.mongodb.org\/mongo-driver\/mongo\/otelmongo\" rel=\"noopener noreferrer nofollow\">otelmongo<\/a> &#8212; \u0442\u0440\u0435\u0439\u0441\u0435\u0440 \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 mongodb<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/open-telemetry\/opentelemetry-go-contrib\/tree\/main\/instrumentation\/net\/http\/otelhttp\" rel=\"noopener noreferrer nofollow\">otelhttp<\/a> &#8212; middleware \u0434\u043b\u044f net\/http<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/open-telemetry\/opentelemetry-go-contrib\/tree\/main\/instrumentation\/github.com\/Shopify\/sarama\/otelsarama\" rel=\"noopener noreferrer nofollow\">otelsarama<\/a> &#8212;  \u0442\u0440\u0435\u0439\u0441\u0435\u0440 \u0434\u043b\u044f sarama, \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 kafka<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/gofiber\/contrib\/otelfiber\" rel=\"noopener noreferrer nofollow\">otelfiber<\/a>, <a href=\"https:\/\/github.com\/open-telemetry\/opentelemetry-go-contrib\/tree\/main\/instrumentation\/github.com\/gin-gonic\/gin\/otelgin\" rel=\"noopener noreferrer nofollow\">otelgin<\/a>, <a href=\"https:\/\/github.com\/open-telemetry\/opentelemetry-go-contrib\/tree\/main\/instrumentation\/github.com\/astaxie\/beego\/otelbeego\" rel=\"noopener noreferrer nofollow\">otelbeego<\/a>,<a href=\"https:\/\/github.com\/open-telemetry\/opentelemetry-go-contrib\/tree\/main\/instrumentation\/github.com\/labstack\/echo\/otelecho\" rel=\"noopener noreferrer nofollow\"> otelecho<\/a> &#8212; \u043c\u0438\u0434\u043b\u0432\u0430\u0440\u0438 \u0434\u043b\u044f \u0432\u0435\u0431-\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/open-telemetry\/opentelemetry-go-contrib\/tree\/main\/instrumentation\/github.com\/bradfitz\/gomemcache\/memcache\/otelmemcache\" rel=\"noopener noreferrer nofollow\">otelmemcached<\/a> &#8212; \u0442\u0440\u0435\u0439\u0441\u0435\u0440 \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 memcached<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/open-telemetry\/opentelemetry-go-contrib\/tree\/main\/instrumentation\/github.com\/go-kit\/kit\/otelkit\" rel=\"noopener noreferrer nofollow\">otelkit<\/a> &#8212; \u0442\u0440\u0435\u0439\u0441\u0435\u0440 \u0434\u043b\u044f \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u043e\u0433\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 kit<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/open-telemetry\/opentelemetry-go-contrib\/tree\/main\/instrumentation\/github.com\/gocql\/gocql\/otelgocql\" rel=\"noopener noreferrer nofollow\">otelgocql<\/a> &#8212; \u0442\u0440\u0435\u0439\u0441\u0435\u0440 \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 Cassandra<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/exaring\/otelpgx\" rel=\"noopener noreferrer nofollow\">otelpgx<\/a> &#8212; \u0442\u0440\u0435\u0439\u0441\u0435\u0440 \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 PostresSQL<a href=\"https:\/\/github.com\/jackc\/pgx\" rel=\"noopener noreferrer nofollow\"> pgx<\/a> (\u0438 <a href=\"https:\/\/pkg.go.dev\/github.com\/jackc\/pgx\/v5\/pgxpool\" rel=\"noopener noreferrer nofollow\">pgxpool<\/a>)<\/p>\n<\/li>\n<li>\n<p>\u0418 \u043c\u043d\u043e\u0433\u043e \u0434\u0440\u0443\u0433\u0438\u0445!<\/p>\n<\/li>\n<\/ul>\n<hr\/>\n<h2>\u0420\u0443\u0447\u043d\u043e\u0439 \u0442\u0440\u0435\u0439\u0441\u0438\u043d\u0433<\/h2>\n<p>\u041a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b, \u0447\u0442\u043e \u0441 \u0442\u0430\u043a\u0438\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u043c \u043c\u044b \u0443\u0436\u0435 \u043d\u0430 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043f\u043e\u0432\u044b\u0448\u0430\u0435\u043c <strong>observability <\/strong>\u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u041d\u043e \u0447\u0430\u0441\u0442\u043e \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0441\u043f\u0430\u043d\u044b \u0441 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439. \u0412\u0437\u0433\u043b\u044f\u043d\u0435\u043c \u043d\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0442\u0440\u0435\u0439\u0441\u0435\u0440\u0430:<\/p>\n<pre><code class=\"go\">type Tracer interface {     Start(ctx context.Context, spanName string, opts ...SpanStartOption) (context.Context, Span) }<\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0435\u0433\u043e \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <code>FiberHandlers<\/code><\/p>\n<pre><code class=\"go\">type FiberHandler struct { notesStorage storage.NotesStorage tracer       trace.Tracer \/\/ &lt;------- }  func NewFiberHandler(notesStorage storage.NotesStorage, tracer trace.Tracer) FiberHandler { return FiberHandler{notesStorage: notesStorage, tracer: tracer} }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0432\u043e\u0439 \u0441\u043f\u0430\u043d:<\/p>\n<pre><code class=\"go\">ctx, span := h.tracer.Start(fiberctx.UserContext(), \"GetNote\") defer span.End() .... note, err := h.notesStorage.Get(ctx, noteID) ....<\/code><\/pre>\n<p>\u0412\u0430\u0436\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b:<\/p>\n<ul>\n<li>\n<p>\u0412\u043e \u0432\u0441\u0435\u0445 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0438\u0437 <code>tracer.Start<\/code><\/p>\n<\/li>\n<li>\n<p><code>defer span.End()<\/code> \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442 \u0441\u043f\u0430\u043d. <em>\u0412\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043f\u0430\u043d\u0430<\/em> = <em>\u0432\u0440\u0435\u043c\u044f \u0432\u044b\u0437\u043e\u0432\u0430<\/em> <code>span.End()<\/code> &#8212; <em>\u0432\u0440\u0435\u043c\u044f \u0432\u044b\u0437\u043e\u0432\u0430<\/em> <code>tracer.Start()<\/code><\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0432\u043e\u0435\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0432 \u0441\u043f\u0430\u043d \u043d\u0443\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>trace.WithAttributes()<\/code><\/p>\n<pre><code class=\"go\">ctx, span := h.tracer.Start(fiberctx.UserContext(), \"GetNote\", trace.WithAttributes( attribute.String(\"MyKey\", \"MyValue\")), )<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043d\u043e\u0432\u044b\u0439 \u0442\u0440\u0435\u0439\u0441:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3ab\/5b7\/f64\/3ab5b7f64f7abac0cae82a750558ab16.png\" width=\"1086\" height=\"535\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3ab\/5b7\/f64\/3ab5b7f64f7abac0cae82a750558ab16.png\"\/><figcaption><\/figcaption><\/figure>\n<h2>\u0421\u043e\u0431\u044b\u0442\u0438\u044f (events):<\/h2>\n<p>\u0417\u0430\u0447\u0430\u0441\u0442\u0443\u044e \u043d\u0430\u0448\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u0435\u043b\u0430\u044e\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0434\u0440\u0443\u0433\u0438\u0445. \u0414\u043b\u044f \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0441\u043f\u0430\u043d \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>span.AddEvent()<\/code>. \u0412 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u0434\u0430\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b:<\/p>\n<pre><code class=\"go\">func (h FiberHandler) GetNote(fiberctx *fiber.Ctx) error { ctx, span := h.tracer.Start(fiberctx.UserContext(), \"GetNote\") defer span.End()  span.AddEvent(\"parse note_id\") \/\/ &lt;------ noteID, err := uuid.Parse(fiberctx.Query(\"note_id\")) if err != nil { return fiber.NewError(fiber.StatusBadRequest, err.Error()) }  span.AddEvent(\"call redis storage\", trace.WithAttributes( \/\/ &lt;----        attribute.String(\"MyEventKey\", \"MyEventValue\")), ) note, err := h.notesStorage.Get(ctx, noteID) if err != nil { if errors.Is(err, models.ErrNotFound) { return fiber.NewError(fiber.StatusNotFound, err.Error()) } return fiber.NewError(fiber.StatusInternalServerError, err.Error()) }  span.AddEvent(\"write note in json\") \/\/ &lt;------ return fiberctx.JSON(note) }<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043e\u0442\u043a\u0440\u043e\u0435\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u043f\u0430\u043d\u0430, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/19f\/af5\/e43\/19faf5e43fc8fd0931116d374b65a1f6.png\" width=\"513\" height=\"249\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/19f\/af5\/e43\/19faf5e43fc8fd0931116d374b65a1f6.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0426\u0438\u0444\u0440\u044b \u0437\u0434\u0435\u0441\u044c &#8212; \u044d\u0442\u043e \u043d\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043f\u0440\u043e\u0439\u0434\u0435\u043d\u043d\u043e\u0435 \u0441 \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043f\u0430\u043d\u0430 (\u0438\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438 offset). \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432 \u0440\u0435\u0434\u0438\u0441 = <em>\u0432\u0440\u0435\u043c\u044f \u0441\u043f\u0430\u043d\u0430 &#8212; \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u0441\u0434\u0432\u0438\u0433<\/em> =   <em>914 &#8212; 43<\/em> = <em>871 <\/em>\u043c\u0438\u043a\u0440\u043e\u0441\u0435\u043a\u0443\u043d\u0434.<\/p>\n<h2>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0441\u043f\u0430\u043d\u043e\u0432 \u0438 \u043e\u0448\u0438\u0431\u043a\u0438<\/h2>\n<p>\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c Redis \u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441:<\/p>\n<pre><code class=\"bash\">$ docker ps --format '{{.ID}} {{.Names}}' 3d69134be67f trace-example-redis-1 830c81a3b071 trace-example-jaeger-1 $ docker stop 3d69134be67f 3d69134be67f<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e82\/c03\/ac6\/e82c03ac6262cf3e7104546c25025e5c.png\" width=\"559\" height=\"338\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e82\/c03\/ac6\/e82c03ac6262cf3e7104546c25025e5c.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/12a\/63a\/8dd\/12a63a8dd8b73ecf070c6b81b0de308f.png\" alt=\"\u0423 \u0442\u0440\u0435\u0439\u0441\u0430 \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u043e\u0448\u0438\u0431\u043a\u0438\" title=\"\u0423 \u0442\u0440\u0435\u0439\u0441\u0430 \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u043e\u0448\u0438\u0431\u043a\u0438\" width=\"398\" height=\"152\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/12a\/63a\/8dd\/12a63a8dd8b73ecf070c6b81b0de308f.png\"\/><figcaption>\u0423 \u0442\u0440\u0435\u0439\u0441\u0430 \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u043e\u0448\u0438\u0431\u043a\u0438<\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a81\/732\/b66\/a81732b662e2b6960d8cb19410d431f8.png\" width=\"1048\" height=\"418\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a81\/732\/b66\/a81732b662e2b6960d8cb19410d431f8.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e \u0442\u0440\u0435\u0439\u0441\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u043a\u043b\u0438\u0435\u043d\u0442 \u0440\u0435\u0434\u0438\u0441\u0430 \u043f\u043e\u043f\u044b\u0442\u0430\u043b\u0441\u044f 4 \u0440\u0430\u0437\u0430 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435, \u043d\u043e \u0432 \u043a\u043e\u043d\u0446\u0435 \u0432\u0435\u0440\u043d\u0443\u043b \u043e\u0448\u0438\u0431\u043a\u0443. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u0435\u043c \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0432 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c \u0441\u043f\u0430\u043d\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b82\/1bf\/59e\/b821bf59e88db55106cbb21df748c8ba.png\" width=\"1031\" height=\"327\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b82\/1bf\/59e\/b821bf59e88db55106cbb21df748c8ba.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041d\u043e \u043f\u043e\u0447\u0435\u043c\u0443 \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0442\u0438\u043f <code>*fiber.Error<\/code>? \u0420\u0430\u043d\u0435\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0439 middleware \u043e\u0442 <code>otelfiber<\/code> \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 (handler&#8217;\u0430). \u0415\u0441\u043b\u0438 err != nil, \u0442\u043e \u043e\u043d \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 \u0432 \u0441\u043f\u0430\u043d \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <code>span.RecordError(err)<\/code> . \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u044d\u0442\u0443 \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 \u043d\u0430\u0448 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"go\">import \"go.opentelemetry.io\/otel\/codes\" ....     err := h.notesStorage.Store(ctx, ......) if err != nil { span.RecordError(err) span.SetStatus(codes.Error, err.Error())        return fiber.NewError(fiber.StatusInternalServerError, err.Error()) } ....<\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 <code>span.SetStatus<\/code> . \u0418\u0437 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f RecordError:<\/p>\n<blockquote>\n<p><em>An additional <\/em><strong><em>call to SetStatus<\/em><\/strong><em> is required if the Status of the Span should be set to Error, as this method does not change the Span status<\/em><\/p>\n<\/blockquote>\n<p>\u0420\u0430\u043d\u0435\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0441\u043f\u0430\u043d \u0438\u043c\u0435\u0435\u0442 \u043e\u0434\u0438\u043d \u0438\u0437 \u0434\u0432\u0443\u0445 \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u0432: <strong>Ok<\/strong> \u0438 <strong>Error .<\/strong> \u0412 \u043a\u043e\u0434\u0435 \u0432\u044b\u0448\u0435 \u043c\u044b \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u0434\u0430\u0435\u043c \u044d\u0442\u043e\u0442 \u0441\u0442\u0430\u0442\u0443\u0441 (\u0445\u043e\u0442\u044f Jeager \u0441\u0447\u0438\u0442\u0430\u0435\u0442 \u0442\u0440\u0435\u0439\u0441 \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439 \u0434\u0430\u0436\u0435 \u0431\u0435\u0437 \u043d\u0435\u0433\u043e).<\/p>\n<p>\u0412 \u0437\u0430\u043f\u0438\u0441\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u0440\u0442\u0438\u0431\u0443\u0442\u044b, \u043a\u0430\u043a \u0432 \u0441\u043f\u0430\u043d \u0438 \u0435\u0433\u043e \u0438\u0432\u0435\u043d\u0442\u044b:<\/p>\n<pre><code class=\"go\">span.RecordError(err, trace.WithAttributes(     attribute.String(\"SomeErrorInfo\", \"FATAL!!!!\")), )<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/7ed\/10f\/a5c\/7ed10fa5c6b545c03d25dfa446ae4bfb.png\" width=\"878\" height=\"413\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7ed\/10f\/a5c\/7ed10fa5c6b545c03d25dfa446ae4bfb.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0448\u0438\u0431\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439, \u043d\u043e \u0438 \u0432 \u043d\u0430\u0448\u0435\u043c \u043a\u043e\u0434\u0435. \u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442\u0435 \u0432\u0441\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u043d\u0430\u0432\u0435\u0440\u0445, \u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <code>span.RecordError<\/code> \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u0430 \u0438\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 (\u0435\u0441\u043b\u0438 \u043e\u0448\u0438\u0431\u043a\u0438 \u043b\u043e\u0433\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043d\u0430 \u043c\u0435\u0441\u0442\u0435), \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u044d\u0442\u0430\u043f\u0435.<\/p>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041a\u043e\u0434: <a href=\"https:\/\/github.com\/illiafox\/tracing-example\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/illiafox\/tracing-example<\/a><\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0442\u0435\u043b \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0441\u0442\u0440\u0430\u0448\u043d\u043e\u0435 \u0441\u043b\u043e\u0432\u043e <em>\u0442\u0440\u0435\u0439\u0441\u0438\u043d\u0433 <\/em>&#8212; \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u043f\u043e\u043b\u0447\u0430\u0441\u0430 \u0447\u0442\u0435\u043d\u0438\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. \u0414\u043e\u0431\u0430\u0432\u0438\u0432 \u0431\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u043e\u0447\u0435\u043a \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043b\u0435\u0433\u043a\u043e \u043e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c \u043b\u044e\u0431\u043e\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0441 \u043c\u0430\u043b\u0435\u0439\u0448\u0438\u043c\u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u044f\u043c\u0438, \u0430 \u0441 \u0440\u0443\u0447\u043d\u044b\u043c\u0438 \u0441\u043f\u0430\u043d\u0430\u043c\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u0443\u0437\u043d\u0430\u0442\u044c \u0432\u0441\u044e \u043d\u0443\u0436\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043d\u0435 \u0437\u0430\u043b\u0435\u0437\u0430\u044f \u0432 \u043a\u043e\u0434. <\/p>\n<p>\u041c\u043d\u043e\u0433\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0431\u044b\u043b\u043e \u0432\u0437\u044f\u0442\u043e \u0438\u0437 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0439:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/opentelemetry.io\/docs\/instrumentation\/go\/\" rel=\"noopener noreferrer nofollow\">https:\/\/opentelemetry.io\/docs\/instrumentation\/go\/<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/www.jaegertracing.io\/docs\/1.41\/getting-started\/\" rel=\"noopener noreferrer nofollow\">https:\/\/www.jaegertracing.io\/docs\/1.41\/getting-started\/<\/a><\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u0440\u0435\u0439\u0441\u0438\u043d\u0433 \u043c\u0435\u0436\u0434\u0443 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 (\u0441\u043f\u043e\u0439\u043b\u0435\u0440) \u0442\u043e\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439. <\/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\/post\/710644\/\"> https:\/\/habr.com\/ru\/post\/710644\/<\/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>\u0412 \u044d\u043f\u043e\u0445\u0443 \u0431\u044b\u0441\u0442\u0440\u043e\u0440\u0430\u0441\u0442\u0443\u0449\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0432\u0430\u0436\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0432 \u043b\u044e\u0431\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438<strong>.<\/strong> \u041e\u0434\u043d\u0438\u043c\u0438 \u0438\u0437 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043b\u043e\u0433\u0438 \u0438 \u043c\u0435\u0442\u0440\u0438\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0442 \u043d\u0430\u043c \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u043c\u043d\u043e\u0433\u0438\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438, \u0442\u0430\u043a\u0438\u043c\u0438 \u043a\u0430\u043a \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443 (RPS), \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, \u043f\u0440\u043e\u0446\u0435\u043d\u0442 \u0437\u0430\u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u0418\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043b\u043e\u0433\u0438 \u0438 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442 \u043d\u0430\u0448\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0442\u0430\u043a\u0443\u044e \u0432\u0430\u0436\u043d\u0443\u044e \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a\u0443, \u043a\u0430\u043a <strong>\u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u043e\u0441\u0442\u044c<\/strong> (<strong>Observability<\/strong>)<\/p>\n<p><strong>\u041d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u043e\u0441\u0442\u044c<\/strong> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u043b\u0435\u0433\u043a\u043e \u0443\u0441\u0442\u0440\u0430\u043d\u044f\u0442\u044c \u0431\u0430\u0433\u0438 \u0438 \u0440\u0435\u0448\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043e\u0442\u0432\u0435\u0447\u0430\u044f \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441 &#171;<em>\u041f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442?<\/em>&#171;.<\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0441\u043f\u0443\u0441\u0442\u044f \u043c\u0435\u0441\u044f\u0446\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043b\u043e\u0441\u044c \u0432 2 \u0440\u0430\u0437\u0430, \u043e \u0447\u0435\u043c \u043c\u044b \u0443\u0437\u043d\u0430\u043b\u0438 \u043f\u043e \u043c\u0435\u0442\u0440\u0438\u043a\u0430\u043c. \u0421\u0445\u043e\u0434\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u043e \u0432 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u0441 \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0430 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u044f\u0432\u043d\u043e\u0439. \u0427\u0442\u043e, \u0435\u0441\u043b\u0438 \u043d\u0430\u0447\u0430\u043b\u0438 \u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0447\u0430\u0441\u0442\u0435\u0439 \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430?  \u0412 \u0442\u0430\u043a\u0438\u0445 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u0445 \u043e\u0431\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u043c \u043d\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e, \u043d\u0438 \u0441\u0442\u043e\u0440\u043e\u043d\u0443, \u043a\u0443\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u043a\u043e\u043f\u0430\u0442\u044c. \u041d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u043d\u0430\u043c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <strong>\u0442\u0440\u0435\u0439\u0441\u0438\u043d\u0433 <\/strong>(<strong>tracing<\/strong>).<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043e\u0441\u043d\u043e\u0432\u044b \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0442\u0440\u0435\u0439\u0441\u0438\u043d\u0433\u0430 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 <a href=\"https:\/\/go.dev\/\" rel=\"noopener noreferrer nofollow\">\u044f\u0437\u044b\u043a\u0435 Go<\/a> c \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f<a href=\"https:\/\/opentelemetry.io\/\" rel=\"noopener noreferrer nofollow\"> OpenTelemetry<\/a> \u0438 <a href=\"https:\/\/www.jaegertracing.io\/\" rel=\"noopener noreferrer nofollow\">Jaeger<\/a>. \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0432\u0437\u044f\u0442\u0430 \u0438\u0437 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u044d\u0442\u0443 \u0442\u0435\u043c\u0443.<\/p>\n<h2>OpenTelemetry<\/h2>\n<p><a href=\"https:\/\/opentelemetry.io\/\" rel=\"noopener noreferrer nofollow\">OpenTelemetry<\/a> (OTel) &#8212; \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u0441\u0431\u043e\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e \u0440\u0430\u0431\u043e\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0438\u0434\u0435\u0439 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a OpenCensus \u0438 OpenTracing. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 &#8212; \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043d\u0430\u0431\u043e\u0440 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 SDK, API \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0441\u0435\u0440\u0432\u0438\u0441\u044b (<strong>observability back-end<\/strong>) \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0441\u0438\u0441\u0442\u0435\u043c.<\/p>\n<p>\u0412 OTel \u0432\u0445\u043e\u0434\u044f\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u043e\u0432 (C++, Java, Python, .NET, PHP, Rust <a href=\"https:\/\/opentelemetry.io\/docs\/instrumentation\/\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a<\/a>), \u0430 \u0442\u0430\u043a\u0436\u0435 \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0438\u043d\u0441\u0442\u0443\u043c\u0435\u043d\u0442\u044b \u043e\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430 \u0434\u043b\u044f \u0442\u0440\u0435\u0439\u0441\u0438\u043d\u0433\u0430 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432. \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043d\u0430\u0447\u0430\u0442\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0433\u043b\u0430\u0432\u043d\u044b\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u0432 OpenTelemetry, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c. \u041f\u0435\u0440\u0432\u044b\u043c \u0432\u0430\u0436\u043d\u044b\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c OpenTelemetry \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <strong>span.<\/strong><\/p>\n<h2>Span<\/h2>\n<p>Span \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0435\u0434\u0438\u043d\u0438\u0446\u0443 \u0440\u0430\u0431\u043e\u0442\u044b (\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f) \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u041e\u043d \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f (events), \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441, \u0440\u0438\u0441\u0443\u044f \u043a\u0430\u0440\u0442\u0438\u043d\u0443 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0437\u0430 \u0432\u0440\u0435\u043c\u044f, \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044d\u0442\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0431\u044b\u043b\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430. \u041e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043c\u044f, \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 (\u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b) \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0431 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u043c\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 span http \u0437\u0430\u043f\u0440\u043e\u0441\u0430: <\/p>\n<figure class=\"\"><figcaption>\u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0435, \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 + \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438 \u0432\u0435\u0440\u0441\u0438\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. <\/figcaption><\/figure>\n<p>\u041e\u043d\u0438 \u0434\u0435\u043b\u044f\u0442\u0441\u044f \u043d\u0430 \u0434\u0432\u0430 \u0442\u0438\u043f\u0430: <strong>Parent (root) span<\/strong> \u0438 <strong>Child span<\/strong>. \u0414\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u0441\u043f\u0430\u043d\u044b \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u043f\u0440\u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u0430\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u044e\u0442\u0441\u044f \u043e\u0442 \u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e. \u0412 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u044f\u0437\u044b\u043a\u0430 Go \u0438\u0445 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442 \u0447\u0435\u0440\u0435\u0437<a href=\"https:\/\/pkg.go.dev\/context#Context%5C\" rel=\"noopener noreferrer nofollow\"> context.Context<\/a>. <\/p>\n<p>\u041f\u0440\u0430\u0432\u0438\u043b\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0435: \u0435\u0441\u043b\u0438 \u0432 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0441\u043f\u0430\u043d, \u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0439 \u043e\u0442 \u043d\u0435\u0433\u043e. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0436\u0435 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 (root) span.<\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 span \u0438\u043c\u0435\u0435\u0442 <strong>span_id<\/strong> \u0438 <strong>trace_id.<\/strong> \u0412\u0430\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u043e\u0442 \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438 \u0434\u043e \u043a\u043e\u043d\u0446\u0430 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u0441\u043f\u0430\u043d\u043e\u0432 <strong>trace_id \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f<\/strong>, \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a <strong>span_id<\/strong> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043f\u0430\u043d\u0430 <strong>\u0443\u043d\u0438\u043a\u0430\u043b\u0435\u043d<\/strong>. \u0422\u0430\u043a\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0438 \u0432\u0435\u0442\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c <strong>trace_id<\/strong> \u043c\u0435\u0436\u0434\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u0432 \u043a\u043e\u043d\u0446\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0432\u044b\u0437\u043e\u0432\u043e\u0432. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044f \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0432\u0441\u0435\u0445 \u0435\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430\u0445 \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0438 (\u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e).<\/p>\n<figure class=\"full-width\"><figcaption>\u041f\u0440\u0438\u043c\u0435\u0440 \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0441 \u043e\u0434\u043d\u0438\u043c trace_id  <\/figcaption><\/figure>\n<p>\u0421\u0442\u0430\u0442\u0443\u0441 \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u0437 \u0434\u0432\u0443\u0445 \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u0432: <strong>Error<\/strong> \u0438 <strong>Ok<\/strong> . \u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u0438\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f, \u0441\u0442\u0430\u0442\u0443\u0441 <strong>Error <\/strong>\u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430, \u0430 <strong>Ok <\/strong>\u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442 &#8212; \u0432\u0441\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b\u0438\u0441\u044c \u0443\u0441\u043f\u0435\u0448\u043d\u043e<\/p>\n<h2>Jaeger<\/h2>\n<p>\u0420\u0430\u043d\u0435\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c, \u0447\u0442\u043e OpenTelemetry \u0442\u043e\u043b\u044c\u043a\u043e \u0433\u043e\u0442\u043e\u0432\u0438\u0442 (\u043d\u0435 \u0445\u0440\u0430\u043d\u0438\u0442!) \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 <strong>observability back-end<\/strong>. \u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0442\u0430\u043a\u043e\u0433\u043e \u0431\u044d\u043a\u0435\u043d\u0434\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <a href=\"https:\/\/www.jaegertracing.io\/\" rel=\"noopener noreferrer nofollow\">Jaeger<\/a>.<\/p>\n<p>\u041d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 \u0431\u044b\u043b\u0430 <code>1.41.0<\/code>. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0431 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c <a href=\"https:\/\/www.jaegertracing.io\/docs\/1.41\/getting-started\/\" rel=\"noopener noreferrer nofollow\">\u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a><\/p>\n<p><strong> \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<\/strong><\/p>\n<details class=\"spoiler\">\n<summary>Docker<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">docker run -d --name jaeger \\   -p 16686:16686 \\   -p 14268:14268 \\   jaegertracing\/all-in-one:1.41<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>Docker-compose<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">version: '3.8'  services:   jaeger:     image: jaegertracing\/all-in-one     ports:       - \"14268:14268\"       - \"16686:16686\" <\/code><\/pre>\n<pre><code class=\"bash\">docker compose up -d<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u0430\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0421\u043a\u0430\u0447\u0430\u0442\u044c \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a <a href=\"https:\/\/www.jaegertracing.io\/download\/\" rel=\"noopener noreferrer nofollow\">https:\/\/www.jaegertracing.io\/download\/<\/a> <\/p>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0438 <code>http:\/\/localhost:16686 <\/code> \u0432\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u0443:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<h2>\u041f\u0438\u0448\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u0441\u0435\u0440\u0432\u0438\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442 \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u0437\u0430\u043c\u0435\u0442\u043a\u0438 \u0438\u0437 Redis. <\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>\u251c\u2500\u2500 storage \u2502\u00a0\u00a0 \u2514\u2500\u2500 redis.go \u251c\u2500\u2500 server \u2502\u00a0\u00a0 \u2514\u2500\u2500 http.go \u251c\u2500\u2500 models \u2502\u00a0\u00a0 \u2514\u2500\u2500 note.go \u251c\u2500\u2500 main.go \u251c\u2500\u2500 go.sum \u251c\u2500\u2500 go.mod \u251c\u2500\u2500 docker-compose.yaml \u2514\u2500\u2500 cmd     \u2514\u2500\u2500 main.go<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>models\/note.go<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"go\">package models  import ( \"errors\" \"time\" ) import \"github.com\/google\/uuid\"  var ErrNotFound = errors.New(\"note not found\")  type Note struct { NoteID  uuid.UUID `json:\"note_id\"` Title   string    `json:\"title\"` Content string    `json:\"content\"` Created time.Time `json:\"created\"` }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>storage\/redis.go<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"go\">package storage  import ( \"context\" \"encoding\/json\" \"fmt\" \"github.com\/go-redis\/redis\/v9\" \"github.com\/google\/uuid\" \"trace-example\/models\" )  type NotesStorage struct { client redis.UniversalClient }  func NewNotesStorage(client redis.UniversalClient) NotesStorage { return NotesStorage{client: client} }  func (s NotesStorage) Store(ctx context.Context, note models.Note) error { data, err := json.Marshal(note) if err != nil { return fmt.Errorf(\"marshal note: %w\", err) }  if err = s.client.Set(ctx, note.NoteID.String(), data, -1).Err(); err != nil { return fmt.Errorf(\"redis set: %w\", err) }  return nil }  func (s NotesStorage) Get(ctx context.Context, noteID uuid.UUID) (*models.Note, error) { data, err := s.client.Get(ctx, noteID.String()).Bytes() if err != nil { if err == redis.Nil { return nil, models.ErrNotFound } return nil, fmt.Errorf(\"redis get: %w\", err) }  var note models.Note if err = json.Unmarshal(data, &amp;note); err != nil { return nil, fmt.Errorf(\"unmarshal note: %w\", err) }  return &amp;note, nil } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>server\/http.go<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"go\">package server  import ( \"errors\" \"github.com\/gofiber\/fiber\/v2\" \"github.com\/google\/uuid\" \"time\" \"trace-example\/models\" \"trace-example\/storage\" )  type FiberHandler struct { notesStorage storage.NotesStorage }  func NewFiberHandler(notesStorage storage.NotesStorage) FiberHandler { return FiberHandler{notesStorage: notesStorage} }  func (h FiberHandler) CreateNote(fiberctx *fiber.Ctx) error { input := struct { Title   string `json:\"title\"` Content string `json:\"content\"` }{}  if err := fiberctx.BodyParser(&amp;input); err != nil { return err }  noteID := uuid.New() err := h.notesStorage.Store(fiberctx.UserContext(), models.Note{ NoteID:  noteID, Title:   input.Title, Content: input.Content, Created: time.Now(), }) if err != nil { return fiber.NewError(fiber.StatusInternalServerError, err.Error()) }  return fiberctx.JSON(map[string]any{ \"note_id\": noteID, }) }  func (h FiberHandler) GetNote(fiberctx *fiber.Ctx) error { noteID, err := uuid.Parse(fiberctx.Query(\"note_id\")) if err != nil { return fiber.NewError(fiber.StatusBadRequest, err.Error()) }  note, err := h.notesStorage.Get(fiberctx.UserContext(), noteID) if err != nil { if errors.Is(err, models.ErrNotFound) { return fiber.NewError(fiber.StatusNotFound, err.Error()) } return fiber.NewError(fiber.StatusInternalServerError, err.Error()) }  return fiberctx.JSON(note) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>cmd\/main.go<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"go\">package main  import ( \"context\" \"github.com\/go-redis\/redis\/v9\" \"github.com\/gofiber\/fiber\/v2\" \"log\" \"trace-example\/server\" \"trace-example\/storage\" )  func main() { app := fiber.New()  \/\/ \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c\u0441\u044f \u043a Redis client := redis.NewClient(&amp;redis.Options{ Addr: \"localhost:6379\", }) if err := client.Ping(context.TODO()).Err(); err != nil { log.Fatal(\"create redis client\", err) }  \/\/ \u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0440\u043e\u0443\u0442\u0435\u0440 handler := server.NewFiberHandler(storage.NewNotesStorage(client)) app.Post(\"\/create\", handler.CreateNote) app.Get(\"\/get\", handler.GetNote)  log.Fatal(app.Listen(\":8080\")) } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>docker-compose.yaml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"go\">version: '3.8'  services:    jaeger:     image: jaegertracing\/all-in-one     ports:       - \"14268:14268\"       - \"16686:16686\"     redis:     restart: on-failure      image: \"redis:latest\"      command: redis-server --port 6380      ports:       - \"6379:6379\"      environment:       REDIS_REPLICATION_MODE: master      volumes:       - redis-data:\/var\/lib\/redis  volumes:   redis-data:<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0441 Redis \u0438 Jaeger<\/p>\n<pre><code class=\"bash\">docker compose up -d<\/code><\/pre>\n<p>\u0418 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0438\u0441<\/p>\n<pre><code class=\"go\">go run cmd\/main.go<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0441\u0442\u0430\u0440\u0442\u0430 \u043c\u043e\u0436\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u043c\u0435\u0442\u043a\u0443:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0418 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0435\u0451 \u043e\u0431\u0440\u0430\u0442\u043d\u043e:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<details class=\"spoiler\">\n<summary>curl \u0437\u0430\u043f\u0440\u043e\u0441\u044b<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u043c\u0435\u0442\u043a\u0438<\/p>\n<pre><code class=\"bash\">curl --location --request POST 'localhost:8080\/create' \\ --header 'Content-Type: application\/json' \\ --data-raw '{     \"title\":\"Something interesting\",     \"content\": \"Lorem ipsum...\" }'<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u043c\u0435\u0442\u043a\u0438<\/p>\n<pre><code class=\"bash\">curl --location --request GET 'localhost:8080\/get?note_id=7411ff79-fd1d-46ab-b9f8-21105cd770ce'<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e OpenTelemetry \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f <strong>\u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0435\u0440\u0430 (exporter) <\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 (\u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442) \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 <strong>observability back-end <\/strong>\u0438<strong> <\/strong>\u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438\u043d\u0442\u0435\u0444\u0435\u0439\u0441<\/p>\n<pre><code class=\"go\">type SpanExporter interface {     ExportSpans(ctx context.Context, spans []ReadOnlySpan) error     Shutdown(ctx context.Context) error }<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0432\u0438\u0434 \u0441\u043f\u0430\u043d\u043e\u0432 &#8212; <strong>ReadOnlySpan. <\/strong>\u042d\u0442\u043e \u043d\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0442\u0438\u043f, \u0430 \u043f\u0440\u043e\u0441\u0442\u043e  \u0438\u043d\u0442\u0435\u0444\u0435\u0439\u0441 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u0441\u043f\u0430\u043d\u0435.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c <strong>exporter<\/strong> \u0434\u043b\u044f Jaeger:<\/p>\n<pre><code class=\"go\">package tracer  import ( \"go.opentelemetry.io\/otel\/exporters\/jaeger\" tracesdk \"go.opentelemetry.io\/otel\/sdk\/trace\" )  \/\/ NewJaegerExporter creates new jaeger exporter \/\/ \/\/url example - http:\/\/localhost:14268\/api\/traces func NewJaegerExporter(url string) (tracesdk.SpanExporter, error) { return jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url))) } <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c <strong>\u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 (provider),<\/strong> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c <strong>\u0442\u0440\u0435\u0439\u0441\u0435\u0440\u044b (tracers)<\/strong><\/p>\n<pre><code class=\"go\">package tracer  import ( \"go.opentelemetry.io\/otel\/exporters\/jaeger\" \"go.opentelemetry.io\/otel\/sdk\/resource\" tracesdk<\/code><\/pre>\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-343939","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/343939","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=343939"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/343939\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=343939"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=343939"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=343939"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}