defmodule GRPC.Logger.Server do @moduledoc """ Print log around server rpc calls, like: 17:18:45.151 [info] Handled by HelloServer.say_hello 17:18:45.151 [info] Response :ok in 11µs ## Usage defmodule Your.Endpoint do use GRPC.Endpoint intercept GRPC.Logger.Server, level: :info end """ require Logger @behaviour GRPC.ServerInterceptor def init(opts) do Keyword.get(opts, :level, :info) end def call(req, stream, next, level) do if Logger.compare_levels(level, Logger.level()) != :lt do Logger.log(level, fn -> ["Handled by ", inspect(stream.server), ".", to_string(elem(stream.rpc, 0))] end) start = System.monotonic_time() result = next.(req, stream) stop = System.monotonic_time() status = elem(result, 0) Logger.log(level, fn -> diff = System.convert_time_unit(stop - start, :native, :microsecond) ["Response ", inspect(status), " in ", formatted_diff(diff)] end) result else next.(req, stream) end end def formatted_diff(diff) when diff > 1000, do: [diff |> div(1000) |> Integer.to_string(), "ms"] def formatted_diff(diff), do: [Integer.to_string(diff), "µs"] end defmodule GRPC.Logger.Client do require Logger @moduledoc """ Print log around client rpc calls, like 17:13:33.021 [info] Call say_hello of helloworld.Greeter 17:13:33.079 [info] Got :ok in 58ms ## Usage {:ok, channel} = GRPC.Stub.connect("localhost:50051", interceptors: [GRPC.Logger.Client]) {:ok, channel} = GRPC.Stub.connect("localhost:50051", interceptors: [{GRPC.Logger.Client, level: :info}]) """ def init(opts) do Keyword.get(opts, :level, :info) end def call(%{grpc_type: grpc_type} = stream, req, next, level) do if Logger.compare_levels(level, Logger.level()) != :lt do Logger.log(level, fn -> ["Call ", to_string(elem(stream.rpc, 0)), " of ", stream.service_name] end) start = System.monotonic_time() result = next.(stream, req) stop = System.monotonic_time() if grpc_type == :unary do status = elem(result, 0) Logger.log(level, fn -> diff = System.convert_time_unit(stop - start, :native, :microsecond) ["Got ", inspect(status), " in ", GRPC.Logger.Server.formatted_diff(diff)] end) end result else next.(stream, req) end end end