elvanja

elvanja

Observability ecosystem, aka what to choose / how to organise?

In short, I am rather confused to the direction one should choose to setup observability for a phoenix app I am working on (API actually), or rather which components are needed and how to connect the dots in between. And now for the longer version :slight_smile:

So far have managed to setup observability cluster like this:

  • otel collector
    • collects traces emitted from phoenix app
    • using otel/opentelemetry-collector-contrib:0.83.0 docker image
  • loki
    • grafana source
    • for collecting logs
    • using grafana/loki:2.8.4 docker image
    • not working at the moment
  • tempo
    • grafana source
    • moves traces between otel collector and grafana
    • using grafana/tempo:2.2.1 docker image
  • prometheus
    • grafana source
    • scraps metrics from phoenix app
    • using prom/prometheus:v2.37.9 docker image
  • grafana
    • for visualising all the metrics, traces, logs
    • using grafana/grafana:8.2.6 docker image

And from phoenix app perspective, it has several parts/options:

  • opentelemetry*
  • prom_ex*
  • telemetry*

As far as I can tell, opentelemetry* works for traces only. With only this in the app, and otel + tempo + grafana I can get the traces via tempo in grafana and inspect them, no issues. However, I see no metrics exposed. At least I could not find a way to do that. tempo seems to be compatible as well, so maybe otel is not needed and I can just use tempo (above architecture with tempo and otel is only because we already use otel for other service in our stack).

The prom_ex* part, along with prometheus + grafana solves the metrics part of the system. I can see e.g. VM or Ecto metrics in auto-generated dashboards. It has a set of predefined metrics it exposes, which is nice. It does not have anything to do with traces or telemetry* part though. I found that prom_ex has a plan to work with opentelemetry stack in the future but we’re not there yet (unless I’m mistaken).

The telemetry* part relates to Telemetry — Phoenix v1.8.8 and related exporters, e.g. could use telemetry_metrics_prometheus_core | Hex to export metrics to prometheus. This looks like a preferred way of doing things in Phoenix (basing that on the presence of this section in the documentation). But it does mean I need to compile metrics by hand and prepare related dashboards, something that comes out of the box with prom_ex*.

I am not entirely sure that this is the most optimised way of doing things. It seems to me that we have some overlapping going on. At least telemetry* and prom_ex seem to be doing the same thing. Any pointers? Maybe some combo is actually a good idea, e.g. do the defaults via prom_ex and custom stuff via telemetry approaches (even though custom things can be done in both)? Has anyone had success in connecting the dots across logs/traces/metrics and make it possible to navigate from one to the other in grafana even though the sources are actually different?

Thank you for your time! :bowing_man:

Most Liked

mgibowski

mgibowski

I think the standard at the moment would be to use OpenTelemetry for traces and Prometheus (via PromEx) for metrics.

Once OpenTelemetry metrics get complete and widely used, they will be compatible with Prometheus so you should be good with such setup.

It seems to me that we have some overlapping going on. At least telemetry* and prom_ex seem to be doing the same thing.

In my opinion the name telemetry of this library might be a bit misleading, as what it offers is actually intrumentation rather than telemetry (see the definitions here).

From the readme of telemetry:

Telemetry is a lightweight library for dynamic dispatching of events, with a focus on metrics and instrumentation. Any Erlang or Elixir library can use telemetry to emit events. Application code and other libraries can then hook into those events and run custom handlers.

So the telemetry library is basically a way for your code to provide some kind of hooks and dynamically adding/removing handlers for such hooks. It is used mostly to instrument code. telemetry handlers is where the integration with the actual telemetry solution takes place (via OpenTelemetry, Prometheus, or whatever you’d like…). At least that’s the standard in the libraries and allows for ecosystem to evolve and be pluggable. In your own code you could skip telemetry and for example emit OpenTelemetry traces directly… or choose to emit telemetry events and implement integration (for example with PromEx) as a telemetry handler. That’s how all the standard PromEx integrations are implemented.

Hope that helps a bit!

dimitarvp

dimitarvp

Apologies for shilling but just making sure it’s on your radar: have you checked this all-in-one thingy?

https://github.com/openobserve/openobserve

I have already used it successfully for both OpenTelemetry spans (in Golang and Rust) and for logs (Golang). Haven’t open-sourced the Golang log converter / exporter yet but can very easily show it to you to orient you how to use it – assuming you have the time budget to put finishing touches on your setup and are not strictly looking for something 100% ready. (It’s pretty easy to use but still, it has to be said that not everyone wants to write their own HTTP client for it; though that’s also very easy in Elixir.)

I have been impressed with the speed and reliability of OpenObserve but I admit I haven’t looked into their aggregation abilities yet so my recommendation could be misguided.

Where Next?

Popular in Questions Top

9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
vac
Hi, I’m quite new in Elixir and I’m trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and I...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Other popular topics Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
Lily
In templates/appointment/index.html.eex: <%= for appointment <- @appointments do %> <tr> <td><%= appoi...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement