Skip to content

Commit 5da8f25

Browse files
authored
sync-service: only include telemetry dependencies and processes in application target build (#2379)
configure telemetry dependencies to only be included when building the `application` target and do compile-time checks to exclude certain modules when compiling without telemetry uses both checks against Mix.target() and checks for the presence of dependent modules to make compilation and runtime robust when running as docker application, local dev server and when used as a dependency
1 parent 0a95da1 commit 5da8f25

File tree

12 files changed

+1074
-927
lines changed

12 files changed

+1074
-927
lines changed

.changeset/few-trains-kick.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@core/sync-service": patch
3+
---
4+
5+
Only include telemetry in docker build

packages/sync-service/Dockerfile

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,21 @@ ARG DEBIAN_VERSION=bookworm-20241223-slim
44

55
ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}"
66
ARG RUNNER_IMAGE="debian:${DEBIAN_VERSION}"
7+
ARG MIX_TARGET=application
78

89
FROM ${BUILDER_IMAGE} AS builder
910
LABEL maintainer="info@electric-sql.com"
1011

1112
RUN apt-get update -y && \
12-
apt-get install -y build-essential git curl && \
13-
apt-get clean && \
14-
rm -f /var/lib/apt/lists/*_*
13+
apt-get install -y build-essential git curl && \
14+
apt-get clean && \
15+
rm -f /var/lib/apt/lists/*_*
1516

1617
RUN mix local.hex --force && mix local.rebar --force
1718

18-
ENV MIX_ENV=prod
19+
ARG MIX_ENV=prod
20+
ARG ELECTRIC_VERSION
21+
ARG MIX_TARGET
1922

2023
WORKDIR /app
2124

@@ -30,38 +33,45 @@ COPY lib /app/lib/
3033
COPY package.json /app/
3134
COPY config/*.exs /app/config/
3235

33-
ARG ELECTRIC_VERSION
3436

3537
RUN mix compile
3638
RUN mix sentry.package_source_code
3739
RUN mix release
3840

41+
RUN ls -l /app/_build
42+
3943
FROM ${RUNNER_IMAGE} AS runner_setup
4044

4145
RUN apt-get update -y && \
42-
apt-get install -y libstdc++6 openssl libncurses5 locales ca-certificates curl && \
43-
apt-get clean && \
44-
rm -f /var/lib/apt/lists/*_*
46+
apt-get install -y libstdc++6 openssl libncurses5 locales ca-certificates curl && \
47+
apt-get clean && \
48+
rm -f /var/lib/apt/lists/*_*
4549

4650
# Set the locale
4751
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
4852

49-
ENV LANG=en_US.UTF-8
50-
ENV LANGUAGE=en_US:en
51-
ENV LC_ALL=en_US.UTF-8
53+
ENV LANG=en_US.UTF-8 \
54+
LANGUAGE=en_US:en \
55+
LC_ALL=en_US.UTF-8 \
56+
MIX_ENV=prod \
57+
MIX_TARGET=application
5258

5359
WORKDIR "/app"
60+
5461
RUN chown nobody /app
5562

5663
FROM runner_setup AS runner
5764

65+
ARG MIX_TARGET
5866
ARG RELEASE_NAME=electric
59-
## Vaxine configuration via environment variables
60-
COPY --from=builder /app/_build/prod/rel/${RELEASE_NAME} ./
61-
RUN mv /app/bin/${RELEASE_NAME} /app/bin/entrypoint
6267

6368

69+
COPY --from=builder "/app/_build/${MIX_TARGET}_prod/rel/${RELEASE_NAME}" ./
70+
71+
RUN mv /app/bin/${RELEASE_NAME} /app/bin/entrypoint
72+
6473
HEALTHCHECK --start-period=10s CMD curl --fail http://localhost:${ELECTRIC_PORT-3000}/v1/health || exit 1
6574

6675
ENTRYPOINT ["/app/bin/entrypoint"]
76+
6777
CMD ["start"]

packages/sync-service/lib/electric/plug/router.ex

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
defmodule Electric.Plug.Router do
22
use Plug.Router, copy_opts_to_assign: :config
3-
use Sentry.PlugCapture
3+
use Electric.Telemetry
4+
5+
with_telemetry Sentry.PlugCapture do
6+
use Sentry.PlugCapture
7+
end
48

59
alias Electric.Plug.Utils.CORSHeaderPlug
610
alias Electric.Plug.Utils.PassAssignToOptsPlug
@@ -16,7 +20,11 @@ defmodule Electric.Plug.Router do
1620
plug Electric.Plug.TraceContextPlug
1721
plug Plug.Telemetry, event_prefix: [:electric, :routing]
1822
plug Plug.Logger
19-
plug Sentry.PlugContext
23+
24+
with_telemetry Sentry.PlugCapture do
25+
plug Sentry.PlugContext
26+
end
27+
2028
plug :put_cors_headers
2129
plug :dispatch
2230

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
defmodule Electric.Plug.UtilityRouter do
22
use Plug.Router
3+
use Electric.Telemetry
34

45
plug :match
56
plug :dispatch
67

7-
get "/metrics", do: resp(conn, 200, TelemetryMetricsPrometheus.Core.scrape())
8+
with_telemetry TelemetryMetricsPrometheus.Core do
9+
get "/metrics", do: resp(conn, 200, TelemetryMetricsPrometheus.Core.scrape())
10+
else
11+
get "/metrics", do: resp(conn, 200, "[]")
12+
end
813
end
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
defmodule Electric.Telemetry do
2+
require Logger
3+
4+
@enabled Mix.env() == :test || Mix.target() == Electric.MixProject.telemetry_target()
5+
@log_level Application.compile_env(:electric, [Electric.Telemetry, :log_level], false)
6+
7+
defmacro __using__(_opts) do
8+
quote do
9+
import Electric.Telemetry
10+
end
11+
end
12+
13+
# uses the availability of the given dependencies to optionally compile
14+
# the provided block when MIX_TARGET is `:application`.
15+
defmacro with_telemetry(dependencies, do: block, else: else_block) do
16+
include_with_telemetry(__CALLER__, __ENV__, dependencies, block, else_block)
17+
end
18+
19+
defmacro with_telemetry(dependencies, do: block) do
20+
include_with_telemetry(__CALLER__, __ENV__, dependencies, block, nil)
21+
end
22+
23+
defp include_with_telemetry(caller, env, dependencies, block, else_block) do
24+
modules = List.wrap(dependencies) |> Enum.map(&Macro.expand(&1, env))
25+
available? = Enum.all?(modules, &Code.ensure_loaded?/1)
26+
27+
if @enabled && available? do
28+
if @log_level,
29+
do:
30+
Logger.log(
31+
@log_level,
32+
"Enabling telemetry in #{caller.module || Path.relative_to(caller.file, Path.expand("..", __DIR__))}"
33+
)
34+
35+
quote(do: unquote(block))
36+
else
37+
if else_block, do: quote(do: unquote(else_block))
38+
end
39+
end
40+
end

0 commit comments

Comments
 (0)