Skip to content

Commit ecce363

Browse files
committed
send telemetry on configuration
1 parent 5d9ab5e commit ecce363

File tree

4 files changed

+136
-39
lines changed

4 files changed

+136
-39
lines changed

apps/elixir_ls_debugger/lib/debugger/server.ex

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -489,13 +489,22 @@ defmodule ElixirLS.Debugger.Server do
489489
1
490490
end
491491

492-
IO.puts(
492+
message =
493493
"Mix task exited with reason\n#{Exception.format_exit(reason)}\nreturning code #{exit_code}"
494-
)
495494

496-
Output.debugger_console(
497-
"Mix task exited with reason\n#{Exception.format_exit(reason)}\nreturning code #{exit_code}"
498-
)
495+
IO.puts(message)
496+
497+
Output.debugger_console(message)
498+
499+
if reason != :normal do
500+
Output.telemetry(
501+
"debuggee_mix_task_error",
502+
%{
503+
"elixir_ls.debuggee_mix_task_error" => message
504+
},
505+
%{}
506+
)
507+
end
499508

500509
Output.send_event("exited", %{"exitCode" => exit_code})
501510
Output.send_event("terminated", %{"restart" => false})
@@ -661,6 +670,29 @@ defmodule ElixirLS.Debugger.Server do
661670
# setBreakpoints, setFunctionBreakpoints and configurationDone
662671
Output.send_event("initialized", %{})
663672
send(self(), :update_threads)
673+
674+
Output.telemetry(
675+
"dap_launch_config",
676+
%{
677+
"elixir_ls.startApps" => to_string(Map.get(config, "startApps", false)),
678+
"elixir_ls.debugAutoInterpretAllModules" =>
679+
to_string(Map.get(config, "debugAutoInterpretAllModules", true)),
680+
"elixir_ls.stackTraceMode" =>
681+
to_string(Map.get(config, "stackTraceMode", "no_tail")),
682+
"elixir_ls.exitAfterTaskReturns" =>
683+
to_string(Map.get(config, "exitAfterTaskReturns", true)),
684+
"elixir_ls.noDebug" => to_string(Map.get(config, "noDebug", false)),
685+
"elixir_ls.breakOnDbg" => to_string(Map.get(config, "breakOnDbg", true)),
686+
"elixir_ls.env" => to_string(Map.has_key?(config, "env")),
687+
"elixir_ls.requireFiles" => to_string(Map.has_key?(config, "requireFiles")),
688+
"elixir_ls.debugInterpretModulesPatterns" =>
689+
to_string(Map.has_key?(config, "debugInterpretModulesPatterns")),
690+
"elixir_ls.excludeModules" => to_string(Map.has_key?(config, "excludeModules")),
691+
"elixir_ls.task" => to_string(Map.get(config, "task", ":default_task"))
692+
},
693+
%{}
694+
)
695+
664696
config
665697

666698
{:DOWN, ^ref, :process, _pid, reason} ->

apps/language_server/lib/language_server/cli.ex

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -108,33 +108,43 @@ defmodule ElixirLS.LanguageServer.CLI do
108108
end
109109

110110
def check_otp_doc_chunks() do
111-
supported = if match?({:error, _}, Code.fetch_docs(:erlang)) do
112-
JsonRpc.show_message(:warning, "OTP compiled without EEP48 documentation chunks")
111+
supported =
112+
if match?({:error, _}, Code.fetch_docs(:erlang)) do
113+
JsonRpc.show_message(:warning, "OTP compiled without EEP48 documentation chunks")
114+
115+
Logger.warning(
116+
"OTP compiled without EEP48 documentation chunks. Language features for erlang modules will run in limited mode. Please reinstall or rebuild OTP with appropriate flags."
117+
)
118+
119+
false
120+
else
121+
true
122+
end
113123

114-
Logger.warning(
115-
"OTP compiled without EEP48 documentation chunks. Language features for erlang modules will run in limited mode. Please reinstall or rebuild OTP with appropriate flags."
116-
)
117-
false
118-
else
119-
true
120-
end
121124
JsonRpc.telemetry("eep48", %{"elixir_ls.eep48" => to_string(supported)}, %{})
122125
end
123126

124127
def check_elixir_sources() do
125128
enum_ex_path = Enum.module_info()[:compile][:source]
126129

127-
elixir_sources_available = unless File.exists?(enum_ex_path, [:raw]) do
128-
dir = Path.join(enum_ex_path, "../../../..") |> Path.expand()
130+
elixir_sources_available =
131+
unless File.exists?(enum_ex_path, [:raw]) do
132+
dir = Path.join(enum_ex_path, "../../../..") |> Path.expand()
129133

130-
Logger.notice(
131-
"Elixir sources not found (checking in #{dir}). Code navigation to Elixir modules disabled."
132-
)
133-
false
134-
else
135-
true
136-
end
137-
JsonRpc.telemetry("elixir_sources", %{"elixir_ls.elixir_sources" => to_string(elixir_sources_available)}, %{})
134+
Logger.notice(
135+
"Elixir sources not found (checking in #{dir}). Code navigation to Elixir modules disabled."
136+
)
137+
138+
false
139+
else
140+
true
141+
end
142+
143+
JsonRpc.telemetry(
144+
"elixir_sources",
145+
%{"elixir_ls.elixir_sources" => to_string(elixir_sources_available)},
146+
%{}
147+
)
138148
end
139149

140150
def check_otp_sources() do
@@ -145,16 +155,23 @@ defmodule ElixirLS.LanguageServer.CLI do
145155
|> to_string
146156
|> String.replace(~r/(.+)\/ebin\/([^\s]+)\.beam$/, "\\1/src/\\2.erl")
147157

148-
otp_sources_available = unless File.exists?(erlang_erl_path, [:raw]) do
149-
dir = Path.join(erlang_erl_path, "../../../..") |> Path.expand()
158+
otp_sources_available =
159+
unless File.exists?(erlang_erl_path, [:raw]) do
160+
dir = Path.join(erlang_erl_path, "../../../..") |> Path.expand()
150161

151-
Logger.notice(
152-
"OTP sources not found (checking in #{dir}). Code navigation to OTP modules disabled."
153-
)
154-
false
155-
else
156-
true
157-
end
158-
JsonRpc.telemetry("otp_sources", %{"elixir_ls.otp_sources" => to_string(otp_sources_available)}, %{})
162+
Logger.notice(
163+
"OTP sources not found (checking in #{dir}). Code navigation to OTP modules disabled."
164+
)
165+
166+
false
167+
else
168+
true
169+
end
170+
171+
JsonRpc.telemetry(
172+
"otp_sources",
173+
%{"elixir_ls.otp_sources" => to_string(otp_sources_available)},
174+
%{}
175+
)
159176
end
160177
end

apps/language_server/lib/language_server/dialyzer.ex

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,14 @@ defmodule ElixirLS.LanguageServer.Dialyzer do
3131

3232
cond do
3333
not Code.ensure_loaded?(:dialyzer) ->
34-
{:error,
34+
# TODO is this check relevant? We check for dialyzer app in CLI
35+
{:error, :no_dialyzer,
3536
"The current Erlang installation does not include Dialyzer. It may be available as a " <>
3637
"separate package."}
3738

3839
not dialyzable?(System) ->
39-
{:error,
40+
# TODO is this relevant anymore? We require OTP 22+ (minimum for elixir 1.13)
41+
{:error, :no_debug_info,
4042
"Dialyzer is disabled because core Elixir modules are missing debug info. " <>
4143
"You may need to recompile Elixir with Erlang >= OTP 20"}
4244

apps/language_server/lib/language_server/server.ex

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,7 +1319,7 @@ defmodule ElixirLS.LanguageServer.Server do
13191319
end
13201320

13211321
defp dialyzer_enabled?(state = %__MODULE__{}) do
1322-
Dialyzer.check_support() == :ok and build_enabled?(state) and state.dialyzer_sup != nil
1322+
state.dialyzer_sup != nil
13231323
end
13241324

13251325
defp safely_read_file(file) do
@@ -1384,8 +1384,27 @@ defmodule ElixirLS.LanguageServer.Server do
13841384
end
13851385

13861386
case Dialyzer.check_support() do
1387-
:ok -> :ok
1388-
{:error, msg} -> JsonRpc.show_message(:warning, msg)
1387+
:ok ->
1388+
JsonRpc.telemetry(
1389+
"dialyzer_support",
1390+
%{
1391+
"elixir_ls.dialyzer_support" => to_string(true),
1392+
"elixir_ls.dialyzer_support_reason" => ""
1393+
},
1394+
%{}
1395+
)
1396+
1397+
{:error, reason, msg} ->
1398+
JsonRpc.show_message(:warning, msg)
1399+
1400+
JsonRpc.telemetry(
1401+
"dialyzer_support",
1402+
%{
1403+
"elixir_ls.dialyzer_support" => to_string(false),
1404+
"elixir_ls.dialyzer_support_reason" => to_string(reason)
1405+
},
1406+
%{}
1407+
)
13891408
end
13901409

13911410
:ok
@@ -1418,6 +1437,33 @@ defmodule ElixirLS.LanguageServer.Server do
14181437
Tracer.set_project_dir(state.project_dir)
14191438
end
14201439

1440+
JsonRpc.telemetry(
1441+
"lsp_config",
1442+
%{
1443+
"elixir_ls.projectDir" => to_string(Map.has_key?(settings, "projectDir")),
1444+
"elixir_ls.autoBuild" => to_string(Map.get(settings, "autoBuild", true)),
1445+
"elixir_ls.dialyzerEnabled" => to_string(Map.get(settings, "dialyzerEnabled", true)),
1446+
"elixir_ls.fetchDeps" => to_string(Map.get(settings, "fetchDeps", false)),
1447+
"elixir_ls.suggestSpecs" => to_string(Map.get(settings, "suggestSpecs", true)),
1448+
"elixir_ls.autoInsertRequiredAlias" =>
1449+
to_string(Map.get(settings, "autoInsertRequiredAlias", true)),
1450+
"elixir_ls.signatureAfterComplete" =>
1451+
to_string(Map.get(settings, "signatureAfterComplete", true)),
1452+
"elixir_ls.enableTestLenses" => to_string(Map.get(settings, "enableTestLenses", false)),
1453+
"elixir_ls.languageServerOverridePath" =>
1454+
to_string(Map.has_key?(settings, "languageServerOverridePath")),
1455+
"elixir_ls.envVariables" => to_string(Map.has_key?(settings, "envVariables")),
1456+
"elixir_ls.mixEnv" => to_string(Map.get(settings, "mixEnv", "test")),
1457+
"elixir_ls.mixTarget" => to_string(Map.get(settings, "mixTarget", "host")),
1458+
"elixir_ls.dialyzerFormat" =>
1459+
if(Map.get(settings, "dialyzerEnabled", true),
1460+
do: Map.get(settings, "dialyzerFormat", "dialyxir_long"),
1461+
else: ""
1462+
)
1463+
},
1464+
%{}
1465+
)
1466+
14211467
trigger_build(%{state | settings: settings})
14221468
end
14231469

0 commit comments

Comments
 (0)