diff --git a/.gitignore b/.gitignore index bdbe1fe9..dd42d87c 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,5 @@ result /priv/plts/*.plt /priv/plts/*.plt.hash node_modules + +tempo-data diff --git a/bin/start b/bin/start index d6c08032..afc90a85 100755 --- a/bin/start +++ b/bin/start @@ -2,4 +2,4 @@ cd "$(dirname "$0")"/.. || exit 1 -elixir -S mix run --no-halt -e "Application.ensure_all_started(:next_ls)" -- "$@" +mix run --no-halt -e "Application.ensure_all_started(:next_ls)" -- "$@" diff --git a/config/config.exs b/config/config.exs index def8815d..cd210e21 100644 --- a/config/config.exs +++ b/config/config.exs @@ -2,6 +2,16 @@ import Config config :next_ls, :indexing_timeout, 100 -config :logger, :default_handler, config: [type: :standard_error] +config :logger, :default_handler, + config: [ + file: ~c".elixir-tools/next-ls.log", + filesync_repeat_interval: 5000, + file_check: 5000, + max_no_bytes: 10_000_000, + max_no_files: 5, + compress_on_rotate: true + ] + +config :logger, :default_formatter, format: "\n$time $metadata[$level] $message\n", metadata: [:id] import_config "#{config_env()}.exs" diff --git a/config/runtime.exs b/config/runtime.exs new file mode 100644 index 00000000..ce04f4b4 --- /dev/null +++ b/config/runtime.exs @@ -0,0 +1,12 @@ +import Config + +if System.get_env("NEXTLS_OTEL") == "1" do + config :next_ls, + otel: true + + config :opentelemetry_exporter, + otlp_protocol: :grpc, + otlp_endpoint: "http://localhost:4317" +else + config :opentelemetry, traces_exporter: :none +end diff --git a/config/test.exs b/config/test.exs index 1a09596a..26b604c5 100644 --- a/config/test.exs +++ b/config/test.exs @@ -1,3 +1,5 @@ import Config +config :logger, :default_handler, config: [type: :standard_error] + config :gen_lsp, :exit_on_end, false diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..400f462b --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,47 @@ +version: "3" +services: + tempo: + image: grafana/tempo:latest + command: [ "-config.file=/etc/tempo.yaml" ] + volumes: + - ./tempo.yaml:/etc/tempo.yaml + - ./tempo-data:/tmp/tempo + ports: + - "14268:14268" # jaeger ingest + - "3200:3200" # tempo + # - "4317:4317" # otlp grpc + # - "4318:4318" # otlp http + - "9411:9411" # zipkin + + otel-collector: + image: otel/opentelemetry-collector:0.61.0 + command: [ "--config=/etc/otel-collector.yaml" ] + volumes: + - ./otel-collector.yaml:/etc/otel-collector.yaml + ports: + - "4317:4317" # otlp grpc + - "4318:4318" # otlp http + + prometheus: + image: prom/prometheus:latest + command: + - --config.file=/etc/prometheus.yaml + - --web.enable-remote-write-receiver + - --enable-feature=exemplar-storage + volumes: + - ./prometheus.yaml:/etc/prometheus.yaml + ports: + - "9090:9090" + + grafana: + image: grafana/grafana:9.4.3 + volumes: + - ./grafana-datasources.yaml:/etc/grafana/provisioning/datasources/datasources.yaml + environment: + - GF_AUTH_ANONYMOUS_ENABLED=true + - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin + - GF_AUTH_DISABLE_LOGIN_FORM=true + - GF_FEATURE_TOGGLES_ENABLE=traceqlEditor + ports: + - "3000:3000" + diff --git a/flake.nix b/flake.nix index 8d05bb4f..b056988f 100644 --- a/flake.nix +++ b/flake.nix @@ -61,7 +61,7 @@ src = self.outPath; inherit version elixir; pname = "next-ls-deps"; - hash = "sha256-LV1DYmWi0Mcz1S5k77/jexXYqay7OpysCwOtUcafqGE="; + hash = "sha256-M8BtmnSWpABqu8ZelZkzG1BOhD8sm3MoqXFIEgCy708="; }; BURRITO_ERTS_PATH = "${beamPackages.erlang}/lib/erlang"; diff --git a/grafana-datasources.yaml b/grafana-datasources.yaml new file mode 100644 index 00000000..4a3bc2c4 --- /dev/null +++ b/grafana-datasources.yaml @@ -0,0 +1,30 @@ +apiVersion: 1 + +datasources: +- name: Prometheus + type: prometheus + uid: prometheus + access: proxy + orgId: 1 + url: http://prometheus:9090 + basicAuth: false + isDefault: false + version: 1 + editable: false + jsonData: + httpMethod: GET +- name: Tempo + type: tempo + access: proxy + orgId: 1 + url: http://tempo:3200 + basicAuth: false + isDefault: true + version: 1 + editable: false + apiVersion: 1 + uid: tempo + jsonData: + httpMethod: GET + serviceMap: + datasourceUid: prometheus diff --git a/lib/next_ls/application.ex b/lib/next_ls/application.ex index 135c6b2f..0e935ce0 100644 --- a/lib/next_ls/application.ex +++ b/lib/next_ls/application.ex @@ -7,6 +7,11 @@ defmodule NextLS.Application do @impl true def start(_type, _args) do + if Application.get_env(:next_ls, :otel, false) do + NextLS.OpentelemetrySchematic.setup() + NextLS.OpentelemetryGenLSP.setup() + end + case System.cmd("epmd", ["-daemon"], stderr_to_stdout: true) do {_, 0} -> :ok diff --git a/lib/next_ls/db.ex b/lib/next_ls/db.ex index 90ab1132..bd5819a1 100644 --- a/lib/next_ls/db.ex +++ b/lib/next_ls/db.ex @@ -4,6 +4,10 @@ defmodule NextLS.DB do import __MODULE__.Query + alias OpenTelemetry.Tracer + + require OpenTelemetry.Tracer + @type query :: String.t() def start_link(args) do @@ -11,7 +15,10 @@ defmodule NextLS.DB do end @spec query(pid(), query(), list()) :: list() - def query(server, query, opts \\ []), do: GenServer.call(server, {:query, query, opts}, :infinity) + def query(server, query, opts \\ []) do + ctx = OpenTelemetry.Ctx.get_current() + GenServer.call(server, {:query, query, opts, ctx}, :infinity) + end @spec insert_symbol(pid(), map()) :: :ok def insert_symbol(server, payload), do: GenServer.cast(server, {:insert_symbol, payload}) @@ -43,28 +50,36 @@ defmodule NextLS.DB do }} end - def handle_call({:query, query, args_or_opts}, _from, %{conn: conn} = s) do - {:message_queue_len, count} = Process.info(self(), :message_queue_len) - NextLS.DB.Activity.update(s.activity, count) - opts = if Keyword.keyword?(args_or_opts), do: args_or_opts, else: [args: args_or_opts] - - query = - if opts[:select] do - String.replace(query, ":select", Enum.map_join(opts[:select], ", ", &to_string/1)) - else - query + def handle_call({:query, query, args_or_opts, ctx}, _from, %{conn: conn} = s) do + token = OpenTelemetry.Ctx.attach(ctx) + + try do + Tracer.with_span :"db.query receive", %{attributes: %{query: query}} do + {:message_queue_len, count} = Process.info(self(), :message_queue_len) + NextLS.DB.Activity.update(s.activity, count) + opts = if Keyword.keyword?(args_or_opts), do: args_or_opts, else: [args: args_or_opts] + + query = + if opts[:select] do + String.replace(query, ":select", Enum.map_join(opts[:select], ", ", &to_string/1)) + else + query + end + + rows = + for row <- __query__({conn, s.logger}, query, opts[:args] || []) do + if opts[:select] do + opts[:select] |> Enum.zip(row) |> Map.new() + else + row + end + end + + {:reply, rows, s} end - - rows = - for row <- __query__({conn, s.logger}, query, opts[:args] || []) do - if opts[:select] do - opts[:select] |> Enum.zip(row) |> Map.new() - else - row - end - end - - {:reply, rows, s} + after + OpenTelemetry.Ctx.detach(token) + end end def handle_cast({:insert_symbol, symbol}, %{conn: conn} = s) do @@ -190,22 +205,24 @@ defmodule NextLS.DB do end def __query__({conn, logger}, query, args) do - args = Enum.map(args, &cast/1) + Tracer.with_span :"db.query process", %{attributes: %{query: query}} do + args = Enum.map(args, &cast/1) - case Exqlite.Basic.exec(conn, query, args) do - {:error, %{message: message, statement: statement}, _} -> - NextLS.Logger.warning(logger, """ - sqlite3 error: #{message} + case Exqlite.Basic.exec(conn, query, args) do + {:error, %{message: message, statement: statement}, _} -> + NextLS.Logger.warning(logger, """ + sqlite3 error: #{message} - statement: #{statement} - arguments: #{inspect(args)} - """) + statement: #{statement} + arguments: #{inspect(args)} + """) - {:error, message} + {:error, message} - result -> - {:ok, rows, _} = Exqlite.Basic.rows(result) - rows + result -> + {:ok, rows, _} = Exqlite.Basic.rows(result) + rows + end end end diff --git a/lib/next_ls/db/schema.ex b/lib/next_ls/db/schema.ex index 209e04a6..c9856fcf 100644 --- a/lib/next_ls/db/schema.ex +++ b/lib/next_ls/db/schema.ex @@ -29,7 +29,7 @@ defmodule NextLS.DB.Schema do # FIXME: this is odd tech debt. not a big deal but is confusing {_, logger} = conn - NextLS.Logger.log(logger, "Beginning DB migration...") + NextLS.Logger.info(logger, "Beginning DB migration...") DB.__query__( conn, @@ -113,7 +113,7 @@ defmodule NextLS.DB.Schema do {:ok, :reindex} end - NextLS.Logger.log(logger, "Finished DB migration...") + NextLS.Logger.info(logger, "Finished DB migration...") result end end diff --git a/lib/next_ls/extensions/credo_extension.ex b/lib/next_ls/extensions/credo_extension.ex index 2d21ac48..4370a2e4 100644 --- a/lib/next_ls/extensions/credo_extension.ex +++ b/lib/next_ls/extensions/credo_extension.ex @@ -30,7 +30,7 @@ defmodule NextLS.CredoExtension do if settings.enable do Registry.register(registry, :extensions, :credo) - NextLS.Logger.log(logger, "[extension] Credo initializing with options #{inspect(settings)}") + NextLS.Logger.info(logger, "[extension] Credo initializing with options #{inspect(settings)}") {:ok, %{ @@ -44,7 +44,7 @@ defmodule NextLS.CredoExtension do refresh_refs: Map.new() }} else - NextLS.Logger.log(logger, "[extension] Credo disabled") + NextLS.Logger.info(logger, "[extension] Credo disabled") :ignore end end diff --git a/lib/next_ls/logger.ex b/lib/next_ls/logger.ex index ba708be9..dd7423f1 100644 --- a/lib/next_ls/logger.ex +++ b/lib/next_ls/logger.ex @@ -2,6 +2,8 @@ defmodule NextLS.Logger do @moduledoc false use GenServer + require Logger + def start_link(arg) do GenServer.start_link(__MODULE__, arg, Keyword.take(arg, [:name])) end @@ -22,6 +24,14 @@ defmodule NextLS.Logger do def handle_cast({:log, type, msg}, state) do apply(GenLSP, type, [state.lsp, String.trim("[NextLS] #{msg}")]) + + case type do + :log -> Logger.debug(msg) + :warning -> Logger.warning(msg) + :error -> Logger.error(msg) + :info -> Logger.info(msg) + end + {:noreply, state} end diff --git a/lib/next_ls/opentelemetry/gen_lsp.ex b/lib/next_ls/opentelemetry/gen_lsp.ex new file mode 100644 index 00000000..f1bc0b27 --- /dev/null +++ b/lib/next_ls/opentelemetry/gen_lsp.ex @@ -0,0 +1,68 @@ +defmodule NextLS.OpentelemetryGenLSP do + @moduledoc false + require Logger + + @tracer_id __MODULE__ + + def setup do + :ok = + :telemetry.attach_many( + "gen_lsp-handler", + [ + [:gen_lsp, :notify, :server, :start], + [:gen_lsp, :notify, :server, :stop], + [:gen_lsp, :request, :server, :start], + [:gen_lsp, :request, :server, :stop], + [:gen_lsp, :request, :client, :start], + [:gen_lsp, :request, :client, :stop], + [:gen_lsp, :notification, :client, :start], + [:gen_lsp, :notification, :client, :stop], + [:gen_lsp, :handle_request, :start], + [:gen_lsp, :handle_request, :stop], + [:gen_lsp, :handle_notification, :start], + [:gen_lsp, :handle_notification, :stop], + [:gen_lsp, :handle_info, :start], + [:gen_lsp, :handle_info, :stop] + # [:gen_lsp, :buffer, :outgoing, :start], + # [:gen_lsp, :buffer, :outgoing, :stop], + # [:gen_lsp, :buffer, :incoming, :start], + # [:gen_lsp, :buffer, :incoming, :stop] + ], + &__MODULE__.process/4, + nil + ) + end + + def process([:gen_lsp, type1, type2, :start], _measurements, metadata, _config) do + OpentelemetryTelemetry.start_telemetry_span( + @tracer_id, + :"gen_lsp.#{type1}.#{type2}", + metadata, + %{kind: :server, attributes: metadata} + ) + end + + def process([:gen_lsp, handle, :start], _measurements, metadata, _config) do + if handle in [:handle_request, :handle_notification] do + # set attribute for parent span + OpenTelemetry.Tracer.set_attribute(:method, metadata[:method]) + end + + OpentelemetryTelemetry.start_telemetry_span( + @tracer_id, + :"next_ls.#{handle}", + metadata, + %{kind: :server, attributes: metadata} + ) + end + + def process([:gen_lsp, _, _, :stop], _measurements, metadata, _config) do + OpentelemetryTelemetry.set_current_telemetry_span(@tracer_id, metadata) + OpentelemetryTelemetry.end_telemetry_span(@tracer_id, metadata) + end + + def process([:gen_lsp, _, :stop], _measurements, metadata, _config) do + OpentelemetryTelemetry.set_current_telemetry_span(@tracer_id, metadata) + OpentelemetryTelemetry.end_telemetry_span(@tracer_id, metadata) + end +end diff --git a/lib/next_ls/opentelemetry/schematic.ex b/lib/next_ls/opentelemetry/schematic.ex new file mode 100644 index 00000000..168e322a --- /dev/null +++ b/lib/next_ls/opentelemetry/schematic.ex @@ -0,0 +1,33 @@ +defmodule NextLS.OpentelemetrySchematic do + @moduledoc false + require Logger + + @tracer_id __MODULE__ + + def setup do + :ok = + :telemetry.attach_many( + "schematic-handler", + [ + [:schematic, :unify, :start], + [:schematic, :unify, :stop] + ], + &__MODULE__.process/4, + nil + ) + end + + def process([:schematic, :unify, :start], _measurements, metadata, _config) do + OpentelemetryTelemetry.start_telemetry_span( + @tracer_id, + :"schematic.unify.#{metadata.kind} #{metadata.dir}", + metadata, + %{kind: :server, attributes: metadata} + ) + end + + def process([:schematic, :unify, :stop], _measurements, metadata, _config) do + OpentelemetryTelemetry.set_current_telemetry_span(@tracer_id, metadata) + OpentelemetryTelemetry.end_telemetry_span(@tracer_id, metadata) + end +end diff --git a/lib/next_ls/runtime.ex b/lib/next_ls/runtime.ex index 6196c250..303e50bb 100644 --- a/lib/next_ls/runtime.ex +++ b/lib/next_ls/runtime.ex @@ -2,6 +2,10 @@ defmodule NextLS.Runtime do @moduledoc false use GenServer + alias OpenTelemetry.Tracer + + require OpenTelemetry.Tracer + @env Mix.env() defguardp is_ready(state) when is_map_key(state, :node) @@ -12,7 +16,10 @@ defmodule NextLS.Runtime do @type mod_fun_arg :: {atom(), atom(), list()} @spec call(pid(), mod_fun_arg()) :: any() - def call(server, mfa), do: GenServer.call(server, {:call, mfa}, :infinity) + def call(server, mfa) do + ctx = OpenTelemetry.Ctx.get_current() + GenServer.call(server, {:call, mfa, ctx}, :infinity) + end @spec ready?(pid()) :: boolean() def ready?(server), do: GenServer.call(server, :ready?) @@ -110,7 +117,7 @@ defmodule NextLS.Runtime do |> Path.join("cmd") |> Path.absname() - NextLS.Logger.log(logger, "Using `elixir` found at: #{elixir_exe}") + NextLS.Logger.info(logger, "Using `elixir` found at: #{elixir_exe}") port = Port.open( @@ -165,7 +172,7 @@ defmodule NextLS.Runtime do {:DOWN, ^ref, :process, ^me, reason} -> case reason do :shutdown -> - NextLS.Logger.log(logger, "The runtime for #{name} has successfully shut down.") + NextLS.Logger.info(logger, "The runtime for #{name} has successfully shut down.") reason -> NextLS.Logger.error(logger, "The runtime for #{name} has crashed with reason: #{inspect(reason)}") @@ -177,7 +184,7 @@ defmodule NextLS.Runtime do with {:ok, host} <- :inet.gethostname(), node <- :"#{sname}@#{host}", true <- connect(node, port, 120) do - NextLS.Logger.log(logger, "Connected to node #{node}") + NextLS.Logger.info(logger, "Connected to node #{node}") :next_ls |> :code.priv_dir() @@ -236,9 +243,17 @@ defmodule NextLS.Runtime do {:reply, {:error, :not_ready}, state} end - def handle_call({:call, {m, f, a}}, _from, %{node: node} = state) do - reply = :rpc.call(node, m, f, a) - {:reply, {:ok, reply}, state} + def handle_call({:call, {m, f, a}, ctx}, _from, %{node: node} = state) do + token = OpenTelemetry.Ctx.attach(ctx) + + try do + Tracer.with_span :"runtime.call", %{attributes: %{mfa: inspect({m, f, a})}} do + reply = :rpc.call(node, m, f, a) + {:reply, {:ok, reply}, state} + end + after + OpenTelemetry.Ctx.detach(token) + end end def handle_call({:compile, opts}, from, %{node: node} = state) do @@ -260,7 +275,7 @@ defmodule NextLS.Runtime do for {pid, _} <- entries, do: send(pid, {:compiler, diagnostics}) end) - NextLS.Logger.log(state.logger, "Compiled #{state.name}!") + NextLS.Logger.info(state.logger, "Compiled #{state.name}!") diagnostics @@ -312,12 +327,12 @@ defmodule NextLS.Runtime do end def handle_info({port, {:data, data}}, %{port: port} = state) do - NextLS.Logger.log(state.logger, data) + NextLS.Logger.info(state.logger, data) {:noreply, state} end def handle_info({port, other}, %{port: port} = state) do - NextLS.Logger.log(state.logger, other) + NextLS.Logger.info(state.logger, other) {:noreply, state} end diff --git a/mix.exs b/mix.exs index acda223e..9838cfad 100644 --- a/mix.exs +++ b/mix.exs @@ -61,10 +61,15 @@ defmodule NextLS.MixProject do defp deps do [ {:exqlite, "~> 0.13.14"}, - {:gen_lsp, "~> 0.6"}, + {:gen_lsp, "~> 0.7"}, {:req, "~> 0.3.11"}, {:schematic, "~> 0.2"}, + {:opentelemetry, "~> 1.3"}, + {:opentelemetry_api, "~> 1.2"}, + {:opentelemetry_exporter, "~> 1.4"}, + {:opentelemetry_process_propagator, "~> 0.2.2"}, + {:opentelemetry_telemetry, "~> 1.0"}, {:burrito, github: "burrito-elixir/burrito", only: [:dev, :prod]}, {:bypass, "~> 2.1", only: :test}, {:dialyxir, ">= 0.0.0", only: [:dev, :test], runtime: false}, diff --git a/mix.lock b/mix.lock index 082ae3a2..60f06bf4 100644 --- a/mix.lock +++ b/mix.lock @@ -1,11 +1,14 @@ %{ + "acceptor_pool": {:hex, :acceptor_pool, "1.0.0", "43c20d2acae35f0c2bcd64f9d2bde267e459f0f3fd23dab26485bf518c281b21", [:rebar3], [], "hexpm", "0cbcd83fdc8b9ad2eee2067ef8b91a14858a5883cb7cd800e6fcd5803e158788"}, "burrito": {:git, "https://github.com/burrito-elixir/burrito.git", "01f4781df21bb6657c68ef9b780daf194dd1aced", []}, "bypass": {:hex, :bypass, "2.1.0", "909782781bf8e20ee86a9cabde36b259d44af8b9f38756173e8f5e2e1fabb9b1", [:mix], [{:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "d9b5df8fa5b7a6efa08384e9bbecfe4ce61c77d28a4282f79e02f1ef78d96b80"}, "castore": {:hex, :castore, "1.0.3", "7130ba6d24c8424014194676d608cb989f62ef8039efd50ff4b3f33286d06db8", [:mix], [], "hexpm", "680ab01ef5d15b161ed6a95449fac5c6b8f60055677a8e79acf01b27baa4390b"}, "cc_precompiler": {:hex, :cc_precompiler, "0.1.8", "933a5f4da3b19ee56539a076076ce4d7716d64efc8db46fd066996a7e46e2bfd", [:mix], [{:elixir_make, "~> 0.7.3", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "176bdf4366956e456bf761b54ad70bc4103d0269ca9558fd7cee93d1b3f116db"}, + "chatterbox": {:hex, :ts_chatterbox, "0.15.1", "5cac4d15dd7ad61fc3c4415ce4826fc563d4643dee897a558ec4ea0b1c835c9c", [:rebar3], [{:hpack, "~> 0.3.0", [hex: :hpack_erl, repo: "hexpm", optional: false]}], "hexpm", "4f75b91451338bc0da5f52f3480fa6ef6e3a2aeecfc33686d6b3d0a0948f31aa"}, "cowboy": {:hex, :cowboy, "2.10.0", "ff9ffeff91dae4ae270dd975642997afe2a1179d94b1887863e43f681a203e26", [:make, :rebar3], [{:cowlib, "2.12.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "3afdccb7183cc6f143cb14d3cf51fa00e53db9ec80cdcd525482f5e99bc41d6b"}, "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, "cowlib": {:hex, :cowlib, "2.12.1", "a9fa9a625f1d2025fe6b462cb865881329b5caff8f1854d1cbc9f9533f00e1e1", [:make, :rebar3], [], "hexpm", "163b73f6367a7341b33c794c4e88e7dbfe6498ac42dcd69ef44c5bc5507c8db0"}, + "ctx": {:hex, :ctx, "0.6.0", "8ff88b70e6400c4df90142e7f130625b82086077a45364a78d208ed3ed53c7fe", [:rebar3], [], "hexpm", "a14ed2d1b67723dbebbe423b28d7615eb0bdcba6ff28f2d1f1b0a7e1d4aa5fc2"}, "db_connection": {:hex, :db_connection, "2.5.0", "bb6d4f30d35ded97b29fe80d8bd6f928a1912ca1ff110831edcd238a1973652c", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c92d5ba26cd69ead1ff7582dbb860adeedfff39774105a4f1c92cbb654b55aa2"}, "dialyxir": {:hex, :dialyxir, "1.3.0", "fd1672f0922b7648ff9ce7b1b26fcf0ef56dda964a459892ad15f6b4410b5284", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "00b2a4bcd6aa8db9dcb0b38c1225b7277dca9bc370b6438715667071a304696f"}, "earmark_parser": {:hex, :earmark_parser, "1.4.32", "fa739a0ecfa34493de19426681b23f6814573faee95dfd4b4aafe15a7b5b32c6", [:mix], [], "hexpm", "b8b0dd77d60373e77a3d7e8afa598f325e49e8663a51bcc2b88ef41838cca755"}, @@ -14,7 +17,10 @@ "ex_doc": {:hex, :ex_doc, "0.29.4", "6257ecbb20c7396b1fe5accd55b7b0d23f44b6aa18017b415cb4c2b91d997729", [: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", "2c6699a737ae46cb61e4ed012af931b57b699643b24dabe2400a8168414bc4f5"}, "exqlite": {:hex, :exqlite, "0.13.15", "a32c0763915e2b0d7ced9dd8638802d38e9569053f3b28b815bd0faef1cbe6d9", [:make, :mix], [{:cc_precompiler, "~> 0.1", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.7", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "4afcc870a33b57781a1e57cd4294eef68815059d26b774c7cd075536b21434b7"}, "finch": {:hex, :finch, "0.16.0", "40733f02c89f94a112518071c0a91fe86069560f5dbdb39f9150042f44dcfb1a", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f660174c4d519e5fec629016054d60edd822cdfe2b7270836739ac2f97735ec5"}, - "gen_lsp": {:hex, :gen_lsp, "0.6.3", "d955460988fcf276a7724573645876fafc7763b1f53160fd3c1e21aad2becdbe", [:mix], [{:jason, "~> 1.3", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.5 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:schematic, "~> 0.2.1", [hex: :schematic, repo: "hexpm", optional: false]}, {:typed_struct, "~> 0.3.0", [hex: :typed_struct, repo: "hexpm", optional: false]}], "hexpm", "f935a933b375d33bee5c6266165ccb0a2fd418e64ab12f62dba56a9b4fdcdd09"}, + "gen_lsp": {:hex, :gen_lsp, "0.7.0", "14a73525c55b6ca7ba08390fe59720788f95e0b6b2ba0ccb43dcd439381d5e37", [:mix], [{:jason, "~> 1.3", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.5 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:schematic, "~> 0.2.1", [hex: :schematic, repo: "hexpm", optional: false]}, {:typed_struct, "~> 0.3.0", [hex: :typed_struct, repo: "hexpm", optional: false]}], "hexpm", "491810806d2c6cce53f0577d96ffdf36dbb104beaba1661cd2950ffc0bbd792c"}, + "gproc": {:hex, :gproc, "0.9.1", "f1df0364423539cf0b80e8201c8b1839e229e5f9b3ccb944c5834626998f5b8c", [:rebar3], [], "hexpm", "905088e32e72127ed9466f0bac0d8e65704ca5e73ee5a62cb073c3117916d507"}, + "grpcbox": {:hex, :grpcbox, "0.17.1", "6e040ab3ef16fe699ffb513b0ef8e2e896da7b18931a1ef817143037c454bcce", [:rebar3], [{:acceptor_pool, "~> 1.0.0", [hex: :acceptor_pool, repo: "hexpm", optional: false]}, {:chatterbox, "~> 0.15.1", [hex: :ts_chatterbox, repo: "hexpm", optional: false]}, {:ctx, "~> 0.6.0", [hex: :ctx, repo: "hexpm", optional: false]}, {:gproc, "~> 0.9.1", [hex: :gproc, repo: "hexpm", optional: false]}], "hexpm", "4a3b5d7111daabc569dc9cbd9b202a3237d81c80bf97212fbc676832cb0ceb17"}, + "hpack": {:hex, :hpack_erl, "0.3.0", "2461899cc4ab6a0ef8e970c1661c5fc6a52d3c25580bc6dd204f84ce94669926", [:rebar3], [], "hexpm", "d6137d7079169d8c485c6962dfe261af5b9ef60fbc557344511c1e65e3d95fb0"}, "hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"}, "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"}, @@ -25,13 +31,22 @@ "nimble_options": {:hex, :nimble_options, "1.0.2", "92098a74df0072ff37d0c12ace58574d26880e522c22801437151a159392270e", [:mix], [], "hexpm", "fd12a8db2021036ce12a309f26f564ec367373265b53e25403f0ee697380f1b8"}, "nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"}, "nimble_pool": {:hex, :nimble_pool, "1.0.0", "5eb82705d138f4dd4423f69ceb19ac667b3b492ae570c9f5c900bb3d2f50a847", [:mix], [], "hexpm", "80be3b882d2d351882256087078e1b1952a28bf98d0a287be87e4a24a710b67a"}, + "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_process_propagator": {:hex, :opentelemetry_process_propagator, "0.2.2", "85244a49f0c32ae1e2f3d58c477c265bd6125ee3480ade82b0fa9324b85ed3f0", [:mix, :rebar3], [{:opentelemetry_api, "~> 1.0", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}], "hexpm", "04db13302a34bea8350a13ed9d49c22dfd32c4bc590d8aa88b6b4b7e4f346c61"}, + "opentelemetry_semantic_conventions": {:hex, :opentelemetry_semantic_conventions, "0.2.0", "b67fe459c2938fcab341cb0951c44860c62347c005ace1b50f8402576f241435", [:mix, :rebar3], [], "hexpm", "d61fa1f5639ee8668d74b527e6806e0503efc55a42db7b5f39939d84c07d6895"}, + "opentelemetry_telemetry": {:hex, :opentelemetry_telemetry, "1.0.0", "d5982a319e725fcd2305b306b65c18a86afdcf7d96821473cf0649ff88877615", [:mix, :rebar3], [{:opentelemetry_api, "~> 1.0", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_registry, "~> 0.3.0", [hex: :telemetry_registry, repo: "hexpm", optional: false]}], "hexpm", "3401d13a1d4b7aa941a77e6b3ec074f0ae77f83b5b2206766ce630123a9291a9"}, "plug": {:hex, :plug, "1.14.2", "cff7d4ec45b4ae176a227acd94a7ab536d9b37b942c8e8fa6dfc0fff98ff4d80", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "842fc50187e13cf4ac3b253d47d9474ed6c296a8732752835ce4a86acdf68d13"}, "plug_cowboy": {:hex, :plug_cowboy, "2.6.1", "9a3bbfceeb65eff5f39dab529e5cd79137ac36e913c02067dba3963a26efe9b2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "de36e1a21f451a18b790f37765db198075c25875c64834bcc82d90b309eb6613"}, "plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"}, "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, "req": {:hex, :req, "0.3.11", "462315e50db6c6e1f61c45e8c0b267b0d22b6bd1f28444c136908dfdca8d515a", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.9", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "0e4b331627fedcf90b29aa8064cd5a95619ef6134d5ab13919b6e1c4d7cccd4b"}, "schematic": {:hex, :schematic, "0.2.1", "0b091df94146fd15a0a343d1bd179a6c5a58562527746dadd09477311698dbb1", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "0b255d65921e38006138201cd4263fd8bb807d9dfc511074615cd264a571b3b1"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "styler": {:hex, :styler, "0.8.1", "f3c0f65023e4bfbf7e7aa752d128b8475fdabfd30f96ee7314b84480cc56e788", [:mix], [], "hexpm", "1aa48d3aa689a639289af3d8254d40e068e98c083d6e5e3d1a695e71a147b344"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, + "telemetry_registry": {:hex, :telemetry_registry, "0.3.1", "14a3319a7d9027bdbff7ebcacf1a438f5f5c903057b93aee484cca26f05bdcba", [:mix, :rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6d0ca77b691cf854ed074b459a93b87f4c7f5512f8f7743c635ca83da81f939e"}, + "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"}, "typed_struct": {:hex, :typed_struct, "0.3.0", "939789e3c1dca39d7170c87f729127469d1315dcf99fee8e152bb774b17e7ff7", [:mix], [], "hexpm", "c50bd5c3a61fe4e198a8504f939be3d3c85903b382bde4865579bc23111d1b6d"}, } diff --git a/otel-collector.yaml b/otel-collector.yaml new file mode 100644 index 00000000..558bc5da --- /dev/null +++ b/otel-collector.yaml @@ -0,0 +1,14 @@ +receivers: + otlp: + protocols: + grpc: +exporters: + otlp: + endpoint: tempo:4317 + tls: + insecure: true +service: + pipelines: + traces: + receivers: [otlp] + exporters: [otlp] diff --git a/prometheus.yaml b/prometheus.yaml new file mode 100644 index 00000000..eda5d026 --- /dev/null +++ b/prometheus.yaml @@ -0,0 +1,11 @@ +global: + scrape_interval: 15s + evaluation_interval: 15s + +scrape_configs: + - job_name: 'prometheus' + static_configs: + - targets: [ 'localhost:9090' ] + - job_name: 'tempo' + static_configs: + - targets: [ 'tempo:3200' ] diff --git a/tempo.yaml b/tempo.yaml new file mode 100644 index 00000000..0afa0364 --- /dev/null +++ b/tempo.yaml @@ -0,0 +1,46 @@ +server: + http_listen_port: 3200 + +distributor: + receivers: # this configuration will listen on all ports and protocols that tempo is capable of. + jaeger: # the receives all come from the OpenTelemetry collector. more configuration information can + protocols: # be found there: https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver + thrift_http: # + grpc: # for a production deployment you should only enable the receivers you need! + thrift_binary: + thrift_compact: + zipkin: + otlp: + protocols: + http: + grpc: + opencensus: + +ingester: + max_block_duration: 5m # cut the headblock when this much time passes. this is being set for demo purposes and should probably be left alone normally + +compactor: + compaction: + block_retention: 1h # overall Tempo trace retention. set for demo purposes + +metrics_generator: + registry: + external_labels: + source: tempo + cluster: docker-compose + storage: + path: /tmp/tempo/generator/wal + remote_write: + - url: http://prometheus:9090/api/v1/write + send_exemplars: true + +storage: + trace: + backend: local # backend configuration to use + wal: + path: /tmp/tempo/wal # where to store the the wal locally + local: + path: /tmp/tempo/blocks + +overrides: + metrics_generator_processors: [service-graphs, span-metrics] # enables metrics generator diff --git a/test/next_ls/extensions/credo_extension_test.exs b/test/next_ls/extensions/credo_extension_test.exs index e050d67d..3af991ed 100644 --- a/test/next_ls/extensions/credo_extension_test.exs +++ b/test/next_ls/extensions/credo_extension_test.exs @@ -47,7 +47,7 @@ defmodule NextLS.CredoExtensionTest do assert_notification "window/logMessage", %{ "message" => "[NextLS] [extension] Credo disabled", - "type" => 4 + "type" => 3 } end @@ -60,7 +60,7 @@ defmodule NextLS.CredoExtensionTest do assert_notification "window/logMessage", %{ "message" => "[NextLS] [extension] Credo initializing with options" <> _, - "type" => 4 + "type" => 3 } uri = uri(foo) @@ -98,7 +98,7 @@ defmodule NextLS.CredoExtensionTest do assert_notification "window/logMessage", %{ "message" => "[NextLS] [extension] Credo initializing with options" <> _, - "type" => 4 + "type" => 3 } uri = uri(foo)