Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ open_telemetry_decorator-*.tar

# Intellij nonsense
.idea/
*.iml
*.iml
.history/
4 changes: 2 additions & 2 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
elixir 1.14.4
erlang 25.3.1
erlang 25.3.2.7
elixir 1.15.7-otp-25
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# OpenTelemetryDecorator

## v1.4.7
- Fixes a bug causing the attribute prefix to be appended twice when using the include option
- Update and remove unused dependencies

## v1.4.6
- Updates dependencies, notably minor versions of the opentelemetry api and sdk
```shell
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ TEST := $(shell find test -name \*.ex)
check: _build/dev _build/test
mix test
mix credo --strict
mix deps.unlock --check-unused
mix hex.outdated
mix dialyzer
mix format
Expand Down
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,13 @@ config :open_telemetry_decorator, attr_joiner: "."
```

Thanks to @benregn for the examples and inspiration for these two options!

### Changing the default behavior for expanding nested maps
By default, nested attributes need to be explicitly selected in the `with_span/3` macro (See additional examples to see this in action). However if you want the default behavior across your application to always expand variables that are maps/structs, you can specify the following config
```elixir
config :open_telemetry_decorator, expand_maps: true
```

<!-- MDOC -->

### Additional Examples
Expand Down Expand Up @@ -176,6 +183,20 @@ defmodule MyApp.Worker do
end
```

Grab all nested map/struct properties:

```elixir
defmodule MyApp.Worker do
use OpenTelemetryDecorator

@decorate with_span("my_app.worker.do_work", include: [:arg1, :arg2], expand_maps: true)
def do_work(arg1, arg2) do
total = some_calculation(arg1.count, arg2.count)
{:ok, total}
end
end
```

```elixir
defmodule MyApp.Worker do
use OpenTelemetryDecorator
Expand Down
1 change: 1 addition & 0 deletions config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Config

config :open_telemetry_decorator, attr_prefix: ""
config :open_telemetry_decorator, attr_joiner: "."
config :open_telemetry_decorator, expand_maps: false

# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
Expand Down
19 changes: 16 additions & 3 deletions lib/open_telemetry_decorator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ defmodule OpenTelemetryDecorator do
alias OpenTelemetryDecorator.Attributes
alias OpenTelemetryDecorator.Validator

@default_expand_maps Application.compile_env(:open_telemetry_decorator, :expand_maps, false)

def trace(span_name, opts \\ [], body, context), do: with_span(span_name, opts, body, context)

@doc """
Expand All @@ -40,18 +42,21 @@ defmodule OpenTelemetryDecorator do
"""
def with_span(span_name, opts \\ [], body, context) do
include = Keyword.get(opts, :include, [])
kind = get_kind(opts)
decorator_attributes = Keyword.get(opts, :attributes, [])
expand_maps = Keyword.get(opts, :expand_maps, @default_expand_maps)
Validator.validate_args(span_name, include)

quote location: :keep do
require OpenTelemetry.Tracer, as: Tracer
require OpenTelemetry.Span, as: Span

Tracer.with_span unquote(span_name) do
Tracer.with_span unquote(span_name), %{kind: unquote(kind)} do
span_context = Tracer.current_span_ctx()

input_params =
Kernel.binding()
|> Attributes.get(unquote(include))
|> Attributes.get(unquote(include), unquote(expand_maps))
|> Keyword.delete(:result)

Attributes.set(input_params)
Expand All @@ -62,12 +67,13 @@ defmodule OpenTelemetryDecorator do
attrs =
Kernel.binding()
|> Keyword.put(:result, result)
|> Attributes.get(unquote(include))
|> Attributes.get(unquote(include), unquote(expand_maps))
|> Keyword.merge(input_params)
|> Enum.map(fn {k, v} -> {Atom.to_string(k), v} end)

# Called functions can mess up Tracer's current span context, so ensure we at least write to ours
Attributes.set(span_context, attrs)
Attributes.set(span_context, unquote(decorator_attributes))

result
rescue
Expand All @@ -83,4 +89,11 @@ defmodule OpenTelemetryDecorator do
target = "#{inspect(context.module)}.#{context.name}/#{context.arity} @decorate telemetry"
reraise %ArgumentError{message: "#{target} #{e.message}"}, __STACKTRACE__
end

def get_kind(opts) do
case Keyword.get(opts, :kind, :internal) do
kind when kind in [:internal, :server, :client, :producer, :consumer] -> kind
_ -> :internal
end
end
end
31 changes: 26 additions & 5 deletions lib/open_telemetry_decorator/attributes.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,40 @@ defmodule OpenTelemetryDecorator.Attributes do
set(Tracer.current_span_ctx(), attributes)
end

def get(all_attributes, requested_attributes) do
def get(all_attributes, requested_attributes, expand_maps \\ false) do
Enum.reduce(requested_attributes, [], fn requested_attribute, taken_attributes ->
case get_attribute(all_attributes, requested_attribute) do
case get_attribute(all_attributes, requested_attribute, expand_maps) do
attributes when is_list(attributes) -> taken_attributes ++ attributes
{name, value} -> Keyword.put(taken_attributes, name, value)
_ -> taken_attributes
end
end)
end

defp get_attribute(attributes, [attribute_name | nested_keys]) do
defp get_attribute(attributes, attribute_name, true) do
requested_attribute = recursive_get_in(attributes, List.wrap(attribute_name))

if is_map(requested_attribute) do
requested_attribute
|> as_map()
|> Map.keys()
|> Enum.map(&get_attribute(attributes, List.wrap(attribute_name) ++ [&1], true))
|> Enum.reject(&(&1 == nil))
|> List.flatten()
else
get_attribute(attributes, attribute_name, false)
end
end

defp get_attribute(attributes, [attribute_name | nested_keys], false) do
requested_obj = attributes |> Keyword.get(attribute_name) |> as_map()

if value = recursive_get_in(requested_obj, nested_keys) do
{derived_name([attribute_name | nested_keys]), to_otlp_value(value)}
end
end

defp get_attribute(attributes, attribute_name) do
defp get_attribute(attributes, attribute_name, false) do
if value = Keyword.get(attributes, attribute_name) do
{derived_name(attribute_name), to_otlp_value(value)}
end
Expand Down Expand Up @@ -86,7 +102,12 @@ defmodule OpenTelemetryDecorator.Attributes do

defp prefix_name(name) when is_binary(name) do
prefix = Application.get_env(:open_telemetry_decorator, :attr_prefix) || ""
String.to_atom(prefix <> name)

if String.starts_with?(name, prefix) do
String.to_atom(name)
else
String.to_atom(prefix <> name)
end
end

defp remove_underscore(name) when is_atom(name) do
Expand Down
14 changes: 7 additions & 7 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule OpenTelemetryDecorator.MixProject do
use Mix.Project

@version "1.4.6"
@version "1.4.7"
@github_page "https://github.com/marcdel/open_telemetry_decorator"

def project do
Expand Down Expand Up @@ -36,12 +36,12 @@ defmodule OpenTelemetryDecorator.MixProject do
# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:credo, "~> 1.6", only: [:dev, :test], runtime: false},
{:decorator, "~> 1.4"},
{:dialyxir, "~> 1.2", only: :dev, runtime: false},
{:ex_doc, "~> 0.30.3", only: :dev, runtime: false},
{:excoveralls, "~> 0.17.0", only: :test, runtime: false},
{:opentelemetry_exporter, "~> 1.4", only: :test},
{:credo, "~> 1.6", only: [:dev, :test]},
{:decorator, github: "/withbelay/decorator", tag: "v1.4.1"},
{:dialyxir, "~> 1.2", only: [:dev, :test]},
{:ex_doc, "~> 0.30.3", only: [:dev, :test]},
{:excoveralls, "~> 0.18.0", only: [:dev, :test]},
{:opentelemetry_exporter, "~> 1.4", only: [:dev, :test]},
{:opentelemetry_api, "~> 1.2"},
{:opentelemetry, "~> 1.3", only: :test}
]
Expand Down
17 changes: 5 additions & 12 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,35 +1,28 @@
%{
"acceptor_pool": {:hex, :acceptor_pool, "1.0.0", "43c20d2acae35f0c2bcd64f9d2bde267e459f0f3fd23dab26485bf518c281b21", [:rebar3], [], "hexpm", "0cbcd83fdc8b9ad2eee2067ef8b91a14858a5883cb7cd800e6fcd5803e158788"},
"bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"},
"certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"},
"chatterbox": {:hex, :ts_chatterbox, "0.13.0", "6f059d97bcaa758b8ea6fffe2b3b81362bd06b639d3ea2bb088335511d691ebf", [:rebar3], [{:hpack, "~> 0.2.3", [hex: :hpack_erl, repo: "hexpm", optional: false]}], "hexpm", "b93d19104d86af0b3f2566c4cba2a57d2e06d103728246ba1ac6c3c0ff010aa7"},
"credo": {:hex, :credo, "1.7.1", "6e26bbcc9e22eefbff7e43188e69924e78818e2fe6282487d0703652bc20fd62", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "e9871c6095a4c0381c89b6aa98bc6260a8ba6addccf7f6a53da8849c748a58a2"},
"ctx": {:hex, :ctx, "0.6.0", "8ff88b70e6400c4df90142e7f130625b82086077a45364a78d208ed3ed53c7fe", [:rebar3], [], "hexpm", "a14ed2d1b67723dbebbe423b28d7615eb0bdcba6ff28f2d1f1b0a7e1d4aa5fc2"},
"decorator": {:hex, :decorator, "1.4.0", "a57ac32c823ea7e4e67f5af56412d12b33274661bb7640ec7fc882f8d23ac419", [:mix], [], "hexpm", "0a07cedd9083da875c7418dea95b78361197cf2bf3211d743f6f7ce39656597f"},
"dialyxir": {:hex, :dialyxir, "1.4.1", "a22ed1e7bd3a3e3f197b68d806ef66acb61ee8f57b3ac85fc5d57354c5482a93", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "84b795d6d7796297cca5a3118444b80c7d94f7ce247d49886e7c291e1ae49801"},
"decorator": {:git, "https://github.com//withbelay/decorator.git", "4e7022f43987bcbbdbda4013344c6429bb4fed67", [tag: "v1.4.1"]},
"dialyxir": {:hex, :dialyxir, "1.4.2", "764a6e8e7a354f0ba95d58418178d486065ead1f69ad89782817c296d0d746a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "516603d8067b2fd585319e4b13d3674ad4f314a5902ba8130cd97dc902ce6bbd"},
"earmark_parser": {:hex, :earmark_parser, "1.4.37", "2ad73550e27c8946648b06905a57e4d454e4d7229c2dafa72a0348c99d8be5f7", [:mix], [], "hexpm", "6b19783f2802f039806f375610faa22da130b8edc21209d0bff47918bb48360e"},
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
"ex_doc": {:hex, :ex_doc, "0.30.6", "5f8b54854b240a2b55c9734c4b1d0dd7bdd41f71a095d42a70445c03cf05a281", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "bd48f2ddacf4e482c727f9293d9498e0881597eae6ddc3d9562bd7923375109f"},
"excoveralls": {:hex, :excoveralls, "0.17.1", "83fa7906ef23aa7fc8ad7ee469c357a63b1b3d55dd701ff5b9ce1f72442b2874", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "95bc6fda953e84c60f14da4a198880336205464e75383ec0f570180567985ae0"},
"ex_doc": {:hex, :ex_doc, "0.30.9", "d691453495c47434c0f2052b08dd91cc32bc4e1a218f86884563448ee2502dd2", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "d7aaaf21e95dc5cddabf89063327e96867d00013963eadf2c6ad135506a8bc10"},
"excoveralls": {:hex, :excoveralls, "0.18.0", "b92497e69465dc51bc37a6422226ee690ab437e4c06877e836f1c18daeb35da9", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "1109bb911f3cb583401760be49c02cbbd16aed66ea9509fc5479335d284da60b"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
"gproc": {:hex, :gproc, "0.8.0", "cea02c578589c61e5341fce149ea36ccef236cc2ecac8691fba408e7ea77ec2f", [:rebar3], [], "hexpm", "580adafa56463b75263ef5a5df4c86af321f68694e7786cb057fd805d1e2a7de"},
"grpcbox": {:hex, :grpcbox, "0.16.0", "b83f37c62d6eeca347b77f9b1ec7e9f62231690cdfeb3a31be07cd4002ba9c82", [:rebar3], [{:acceptor_pool, "~> 1.0.0", [hex: :acceptor_pool, repo: "hexpm", optional: false]}, {:chatterbox, "~> 0.13.0", [hex: :ts_chatterbox, repo: "hexpm", optional: false]}, {:ctx, "~> 0.6.0", [hex: :ctx, repo: "hexpm", optional: false]}, {:gproc, "~> 0.8.0", [hex: :gproc, repo: "hexpm", optional: false]}], "hexpm", "294df743ae20a7e030889f00644001370a4f7ce0121f3bbdaf13cf3169c62913"},
"hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~> 2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"},
"hpack": {:hex, :hpack_erl, "0.2.3", "17670f83ff984ae6cd74b1c456edde906d27ff013740ee4d9efaa4f1bf999633", [:rebar3], [], "hexpm", "06f580167c4b8b8a6429040df36cc93bba6d571faeaec1b28816523379cbb23a"},
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"},
"makeup_erlang": {:hex, :makeup_erlang, "0.1.2", "ad87296a092a46e03b7e9b0be7631ddcf64c790fa68a9ef5323b6cbb36affc72", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f3f5a1ca93ce6e092d92b6d9c049bcda58a3b617a8d888f8e7231c85630e8108"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"},
"opentelemetry": {:hex, :opentelemetry, "1.3.1", "f0a342a74379e3540a634e7047967733da4bc8b873ec9026e224b2bd7369b1fc", [:rebar3], [{:opentelemetry_api, "~> 1.2.2", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}, {:opentelemetry_semantic_conventions, "~> 0.2", [hex: :opentelemetry_semantic_conventions, repo: "hexpm", optional: false]}], "hexpm", "de476b2ac4faad3e3fe3d6e18b35dec9cb338c3b9910c2ce9317836dacad3483"},
"opentelemetry_api": {:hex, :opentelemetry_api, "1.2.2", "693f47b0d8c76da2095fe858204cfd6350c27fe85d00e4b763deecc9588cf27a", [:mix, :rebar3], [{:opentelemetry_semantic_conventions, "~> 0.2", [hex: :opentelemetry_semantic_conventions, repo: "hexpm", optional: false]}], "hexpm", "dc77b9a00f137a858e60a852f14007bb66eda1ffbeb6c05d5fe6c9e678b05e9d"},
"opentelemetry_exporter": {:hex, :opentelemetry_exporter, "1.6.0", "f4fbf69aa9f1541b253813221b82b48a9863bc1570d8ecc517bc510c0d1d3d8c", [:rebar3], [{:grpcbox, ">= 0.0.0", [hex: :grpcbox, repo: "hexpm", optional: false]}, {:opentelemetry, "~> 1.3", [hex: :opentelemetry, repo: "hexpm", optional: false]}, {:opentelemetry_api, "~> 1.2", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}, {:tls_certificate_check, "~> 1.18", [hex: :tls_certificate_check, repo: "hexpm", optional: false]}], "hexpm", "1802d1dca297e46f21e5832ecf843c451121e875f73f04db87355a6cb2ba1710"},
"opentelemetry_semantic_conventions": {:hex, :opentelemetry_semantic_conventions, "0.2.0", "b67fe459c2938fcab341cb0951c44860c62347c005ace1b50f8402576f241435", [:mix, :rebar3], [], "hexpm", "d61fa1f5639ee8668d74b527e6806e0503efc55a42db7b5f39939d84c07d6895"},
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},
"tls_certificate_check": {:hex, :tls_certificate_check, "1.19.0", "c76c4c5d79ee79a2b11c84f910c825d6f024a78427c854f515748e9bd025e987", [:rebar3], [{:ssl_verify_fun, "~> 1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "4083b4a298add534c96125337cb01161c358bb32dd870d5a893aae685fd91d70"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
"tls_certificate_check": {:hex, :tls_certificate_check, "1.20.0", "1ac0c53f95e201feb8d398ef9d764ae74175231289d89f166ba88a7f50cd8e73", [:rebar3], [{:ssl_verify_fun, "~> 1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "ab57b74b1a63dc5775650699a3ec032ec0065005eff1f020818742b7312a8426"},
}
Loading