Search code examples
erlangelixiropen-telemetry

How to use `otel_resource_detector` from OpenTelemetry in Elixir


I'm an Erlang/Elixir noob and I'm doing a research on how to use the otel_resource_detector in Elixir. I've managed to get this working in Erlang some time ago, but I'm struggling to get things right in Elixir. This is what I have in Erlang:

-module(extra_metadata).
-behaviour(otel_resource_detector).
-export([get_resource/1]).

get_resource(_) ->
    Resource1 = otel_resource:create(otel_resource_app_env:parse(get_metadata("/data/extrametadata.properties")), []),
    {ok, HiddenMetadataFile} = file:read_file("/data/hiddenpath.properties"),
    Resource2 = otel_resource:create(otel_resource_app_env:parse(get_metadata(HiddenMetadataFile)), []),
    otel_resource:merge(Resource1, Resource2).

get_metadata(FileName) ->
try
    {ok, MetadataFile} = file:read_file(FileName),
    Lines = binary:split(MetadataFile, <<"\n">>, [trim, global]),
    make_tuples(Lines, [])
catch _:_ -> "Extra Metadata not found"
end.

make_tuples([Line|Lines], Acc) ->
    [Key, Value] = binary:split(Line, <<"=">>),
    make_tuples(Lines, [{Key, Value}|Acc]);
make_tuples([], Acc) -> Acc.

Full Erlang app here: https://github.com/julianocosta89/erlang_otel_hello_server/tree/main

I'm trying to make use of the otel_resource_detector from OpenTelemetry: https://github.com/open-telemetry/opentelemetry-erlang/blob/37f3cecd9ad2a7b8f3b94c89118585991f0023b1/apps/opentelemetry/src/otel_resource_detector.erl

How would I use that in Elixir?


Solution

  • One can easily call modules from . The first module would look like

    defmodule ExtraMetadata do
    
      @behaviour :otel_resource_detector
    
      def get_resource(_) do
        resource1 =
          :otel_resource.create(
            :otel_resource_app_env.parse(
              get_metadata("/data/extrametadata.properties")), [])
    
        {:ok, hidden_metadata_file} =
          File.read("/data/hiddenpath.properties")
    
        resource2 =
          :otel_resource.create(
            :otel_resource_app_env.parse(
              get_metadata(hidden_metadata_file)), [])
    
        :otel_resource.merge(resource1, resource2)
      end
    
      defp get_metadata(file_name) do
        try do
          {:ok, metadata_file} = File.read(file_name)
          lines = :binary.split(metadata_file, <<"\n">>, [:trim, :global])
          make_tuples(lines) 
        catch
          _ -> "Extra Metadata not found"
        end
      end
    
      # Enum.map/2 would be probably more idiomatic
      defp make_tuples(lines, acc \\ [])
      defp make_tuples([line|lines], acc) do
        [key, value] = :binary.split(line, <<"=">>)
        make_tuples(lines, [{key, value}|cc])
      defp make_tuples([], acc), do: acc
    end
    

    NB I obviously did not check the code above, some glitches might need some additional handling.