-
-
Save yordis/32437cca212f44dbccdc04645fa405e9 to your computer and use it in GitHub Desktop.
Example polling a log file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
# Log Reader - polls log file and sends new lines to channel | |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
defmodule LogReader do | |
use GenServer | |
@log_file "priv/some_log.log" | |
@poll_interval 5 * 1000 # 5 seconds | |
def run_test() do | |
{:ok, _} = LogWriter.start_link() | |
{:ok, _} = LogReader.start_link() | |
end | |
def start_link(_ \\ []) do | |
GenServer.start_link(__MODULE__, :ok, name: LogReader) | |
end | |
def init(:ok) do | |
# open the log file and set the pointer to the end so that we only grab | |
# new log messages | |
{:ok, fp} = File.open(@log_file, [:read]) | |
:file.position(fp, :eof) | |
poll() | |
{:ok, fp} | |
end | |
def handle_info(:read_log_lines, fp) do | |
# consume any new log lines and pass them off the channel | |
fp |> read_til_eof |> send_to_channel | |
poll() | |
{:noreply, fp} | |
end | |
def read_til_eof(fp), | |
do: read_til_eof(IO.binread(fp, :line), fp, []) | |
def read_til_eof(:eof, _fp, buffer), do: buffer | |
def read_til_eof(line, fp, buffer), | |
do: read_til_eof(IO.binread(fp, :line), fp, buffer ++ [line]) | |
# this could be handing off the new lines to some service or sending directly | |
# to the channel or whatever | |
def send_to_channel([]), do: :ok | |
def send_to_channel(lines), | |
do: for line <- lines, do: IO.puts line | |
defp poll(), | |
do: Process.send_after(self(), :read_log_lines, @poll_interval) | |
end | |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
# Log Writer - simulates log writes | |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
defmodule LogWriter do | |
use GenServer | |
@log_file "priv/some_log.log" | |
def start_link(_ \\ []) do | |
GenServer.start_link(__MODULE__, :ok, name: LogWriter) | |
end | |
def init(:ok) do | |
{:ok, fp} = File.open(@log_file, [:append]) | |
poll() | |
{:ok, fp} | |
end | |
def handle_info(:write_log, fp) do | |
for _ <- 0..:rand.uniform(5), do: IO.puts fp, make_log_message() | |
poll() | |
{:noreply, fp} | |
end | |
def make_log_message() do | |
time = :os.system_time(:milli_seconds) |> to_string() | |
body = :crypto.strong_rand_bytes(15) |> Base.url_encode64 | |
"[#{time}] #{body}" | |
end | |
defp poll() do | |
interval = :rand.uniform(10) * 1000 | |
Process.send_after(self(), :write_log, interval) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment