/posts/distributed-tracing-and-opentelemetry: init
3 files changed, 169 insertions(+), 1 deletions(-)

A => data/posts/distributed-tracing-and-opentelemetry.md
M hashes.nix
M site.nix
A => data/posts/distributed-tracing-and-opentelemetry.md +152 -0
@@ 0,0 1,152 @@ 
+{---
+title = "Monitoring Go Apps with Distributed Tracing and OpenTelemetry";
+tags = [ "code" "go" "tracing" "telemetry" "uptrace" ];
+date = "2022-04-28";
+path = "/posts/distributed-tracing-and-opentelemetry";
+author = {
+  name = "Vladimir Mihailenco";
+  url = https://github.com/vmihailenco;
+};
+---}
+
+{{ templates.partials.taxonomyTermsList "tags" meta.tags }}
+
+*The following is a guest article written by [Vladimir Mihailenco](https://github.com/vmihailenco) from [Uptrace](https://uptrace.dev).*
+
+# Monitoring Go Apps with Distributed Tracing and OpenTelemetry
+
+## What is tracing?
+
+[Distributed tracing](https://opentelemetry.uptrace.dev/guide/distributed-tracing.html) allows to
+precisely pinpoint the problem in complex systems, especially those built using a microservices
+architecture.
+
+Tracing allow to follow requests as they travel through distributed systems. You get a full context
+of what is different, what is broken, and which logs & errors are relevant.
+
+![Distributed Tracing]({{ meta.path }}/tracing-graph.png)
+
+Using tracing, you can break down requests into
+[spans](https://opentelemetry.uptrace.dev/guide/distributed-tracing.html#spans). A **span** is an
+operation (unit of work) your app performs handling a request, for example, a database query or a
+network call.
+
+A **trace** is a tree of spans that shows the path that a request makes through an app.
+The root span is the first span in a trace.
+
+![Trace]({{ meta.path }}/trace-graph.png)
+
+To learn more about tracing, see
+[Distributed tracing using OpenTelemetry](https://opentelemetry.uptrace.dev/guide/distributed-tracing.html).
+
+## What is OpenTelemetry?
+
+[OpenTelemetry](https://opentelemetry.uptrace.dev/) is an open-source observability framework for
+[distributed tracing](https://opentelemetry.uptrace.dev/guide/distributed-tracing.html) (including
+logs and errors) and [metrics](https://opentelemetry.uptrace.dev/guide/metrics.html).
+
+Otel allows developers to collect and export telemetry data in a vendor agnostic way. With
+OpenTelemetry, you can [instrument](https://opentelemetry.uptrace.dev/instrumentations/) your
+application once and then add or change vendors without changing the instrumentation, for example,
+here is a list [popular DataDog alternatives](https://get.uptrace.dev/compare/datadog-competitors.html) that support
+OpenTelemetry.
+
+## How to use OpenTelemetry?
+
+OpenTelemetry is available for most programming languages and provides interoperability across
+different languages and environments.
+
+You can [get started with OpenTelemetry](https://opentelemetry.uptrace.dev/) by following these 5 steps:
+
+- **Step 1**. Install a
+  [distributed tracing tool](https://get.uptrace.dev/compare/distributed-tracing-tools.html).
+
+- **Step 2**. Browse
+  [OpenTelemetry instrumentations](https://opentelemetry.uptrace.dev/instrumentations/) to find
+  examples for your framework and libraries.
+
+- **Step 3**. [Configure](https://docs.uptrace.dev/#getting-started) the OpenTelemetry SDK to export
+  telemetry data to the tracing tool.
+
+- **Step 4**. Learn about
+  [OpenTelemetry Tracing API](https://opentelemetry.uptrace.dev/guide/distributed-tracing.html#what-s-next)
+  for your programming language to create custom instrumentations.
+
+- **Step 5**. Install
+  [OpenTelemetry Collector](https://opentelemetry.uptrace.dev/guide/collector.html) to gather
+  [infrastructure metrics](https://opentelemetry.uptrace.dev/guide/collector.html#host-metrics).
+
+## OpenTelemetry Go API
+
+You can create spans using
+[OpenTelemetry Go API](https://opentelemetry.uptrace.dev/guide/go-tracing.html) like this:
+
+```go
+import "go.opentelemetry.io/otel"
+
+var tracer = otel.Tracer("app_or_package_name")
+
+func someFunc(ctx context.Context) error {
+	ctx, span := tracer.Start(ctx, "some-func")
+	defer span.End()
+
+	// the code you are measuring
+
+	return nil
+}
+```
+
+You can also record
+[attributes](https://opentelemetry.uptrace.dev/guide/distributed-tracing.html#attributes) and
+errors:
+
+```go
+func someFunc(ctx context.Context) error {
+	ctx, span := tracer.Start(ctx, "some-func")
+	defer span.End()
+
+	if span.IsRecording() {
+		span.SetAttributes(
+			attribute.Int64("enduser.id", userID),
+			attribute.String("enduser.email", userEmail),
+		)
+	}
+
+	if err := someOtherFunc(ctx); err != nil {
+		span.RecordError(err)
+		span.SetStatus(codes.Error, err.Error())
+	}
+
+	return nil
+}
+```
+
+## What is Uptrace?
+
+[Uptrace](https://uptrace.dev/) is an open source
+[DataDog alternative](https://get.uptrace.dev/compare/datadog-competitors.html) that helps developers pinpoint failures and
+find performance bottlenecks. Uptrace can process billions of spans on a single server and allows to
+monitor your software at 10x lower cost.
+
+Uptrace accepts data from OpenTelemetry and stores it in a ClickHouse database. ClickHouse is a
+columnar database that is much more efficient for traces and logs than, for example, Elastic Search.
+On the same hardware, ClickHouse can store 10x more traces and, at the same time, provide much
+better performance.
+
+You can [install Uptrace](https://get.uptrace.dev/guide/opentelemetry-tracing-tool.html) by downloading a DEB/RPM package
+or a pre-compiled binary.
+
+![Uptrace tracing tool]({{ meta.path }}/uptrace.png)
+
+## What's next?
+
+Next, you can continue exploring [OpenTelemetry](https://opentelemetry.uptrace.dev) or start
+instrumenting your app using popular instrumentations:
+
+- [OpenTelemetry guide for Gin and GORM](https://get.uptrace.dev/opentelemetry/gin-gorm.html)
+- [gRPC OpenTelemetry](https://opentelemetry.uptrace.dev/instrumentations/go-grpc.html)
+- [Golang ORM OpenTelemetry](https://bun.uptrace.dev/guide/performance-monitoring.html)
+- [Go Redis OpenTelemetry](https://redis.uptrace.dev/guide/go-redis-monitoring.html)
+- [Zap OpenTelemetry](https://opentelemetry.uptrace.dev/instrumentations/go-zap.html)
+
+{{ lib.strings.replaceStrings [ "\n\n" ] [ "\n" ] (templates.services.disqus { inherit (meta) path; }) }}

          
M hashes.nix +5 -0
@@ 1,4 1,9 @@ 
 {
+  # 2022-04-28
+  uptrace = "sha256-xGXB7jpiaj07nqIXuEgSEdyXl5zcyg3zkM6289gFc40=";
+  trace-graph = "sha256-5Xv6FSL4Y3dRTmWGQU3pKX4qhLRXCaYu7mzB1P3KwEY=";
+  tracing-graph = "sha256-xT/2ThI7gyIuDdszdzOYFso4MxMtU+P2NNf1MNsMbV4=";
+
   # 2022-04-25
   "github_NixOS_nix_issues_6083" = "sha256-YQEgQMhNbbq5JQ0k3OxePLcRw57WyddsBnZfmhUtj3g=";
   "github_divnix_data-merge_issues_1" = "sha256-ABbyJn8nn4URJue0liNNWWKYvQNCfiho9CiFe787mLM=";

          
M site.nix +12 -1
@@ 109,13 109,24 @@ rec {
       inherit (conf) siteUrl;
     };
 
-    postGen = ''
+    postGen = let
+      libPkgs = lib.theme.dermetfan.pkgs {
+        inherit pkgs;
+        inherit (conf.data) secrets hashes;
+      };
+    in ''
       asciidoctor_css=$(dirname $(realpath ${pkgs.asciidoctor}/bin/asciidoctor))/../lib/ruby/gems/*/gems/${pkgs.asciidoctor.meta.name}/data/stylesheets/asciidoctor-default.css
       head -n 185 $asciidoctor_css | tail -n 3 > $out/styles/asciidoctor-default-anchor.css
 
       cd $out/posts/zig-with-c-web-servers
       tar -chaf h2o.tar.gz h2o
       tar -chaf facil.io.tar.gz facil.io
+
+      mkdir $out/posts/distributed-tracing-and-opentelemetry
+      cd $out/posts/distributed-tracing-and-opentelemetry
+      cp ${libPkgs.fetchurlCentral rec { url = "https://get.uptrace.dev/opentelemetry-and-uptrace/${name}.png"; name = "tracing-graph"; }} tracing-graph.png
+      cp ${libPkgs.fetchurlCentral rec { url = "https://get.uptrace.dev/opentelemetry-and-uptrace/${name}.png"; name = "trace-graph"; }} trace-graph.png
+      cp ${libPkgs.fetchurlCentral rec { url = "https://get.uptrace.dev/opentelemetry-and-uptrace/${name}.png"; name = "uptrace"; }} uptrace.png
     '';
   }) // {
     overrideArgs = f: (import ./site.nix (args // (f args))).site;