nginxはライブダッシュボードに記録する
私の以前のブログの記事の上に構築し、私はNGinxのログ表示を構築することを決めた表示を作成します.
起こるかもしれない問題はログファイルが巨大であるかもしれません、そして、我々はそれをすべてロードして、解析したくありません.私は私たちが十分なデータを得た場合は、ファイルの最後にロードし、チェックしていない場合、我々は十分な負荷まで繰り返してください.
コールバックはファイルを開き、ファイルサイズを取得し、ファイル読み込みを処理する再帰関数に渡します.その後、データを取得した後にソートし、必要な行だけを返します.
あなたのWebアプリに応じて@ avgchin lineountの長さが異なることがあります-それは私たちがファイルの末尾からたびに取得したいどのように多くのバイトを計算するために使用されます.
作業ファイルはgithub
< div >
起こるかもしれない問題はログファイルが巨大であるかもしれません、そして、我々はそれをすべてロードして、解析したくありません.私は私たちが十分なデータを得た場合は、ファイルの最後にロードし、チェックしていない場合、我々は十分な負荷まで繰り返してください.
def fetch_logs(params, node) do
data = :rpc.call(node, __MODULE__, :logs_callback, [params])
{data, length(data)}
end
この関数呼び出しはRPCでラップされます.ので、ライブビューの複数のノードとの互換性を呼び出します.また、ログファイルを使用してノード上でフィルタリングを行うことができますので、並べ替えと検索のparamsを渡す-データに関数を送信します.コールバックはファイルを開き、ファイルサイズを取得し、ファイル読み込みを処理する再帰関数に渡します.その後、データを取得した後にソートし、必要な行だけを返します.
def logs_callback(params) do
%{limit: limit, sort_by: sort_by, sort_dir: sort_dir} = params
with {:ok, pid} <- :file.open(@path, [:binary]),
{:ok, info} <- :file.read_file_info(pid),
{:file_info, file_size, _, _, _, _, _, _, _, _, _, _, _, _} <- info,
{:ok, content} <- get_data([], pid, file_size, 0, params),
:ok <- :file.close(pid) do
content
|> Enum.sort_by(&sort_value(&1, sort_by), sort_dir)
|> Enum.take(limit)
else
error -> IO.puts(error)
end
end
再帰的な関数は、ファイルの末尾からいくつかの量のデータを読み込み、別の行に分割すると、ほとんどの時間が完全な行ではない最初の1つを覚えているので、今のところそれを覚えています.残りの部分をフィルタリングして解析します.それから、我々は十分なデータを得たかどうかチェックします、はい、我々がちょうどそれを返すならば、フロントエンドに表示されます.さもなければ、私たちは現在解析された行と以前に解析されていなかった部分を再帰的な呼び出しに渡します.ファイルの終わりからもう一つのチャンクのデータを取得します.それから、我々はちょうどステップを繰り返します.そのとき、我々は我々が十分なデータを得たかどうかもう一度チェックします.これは、制限に達するまで、またはファイルの内容のすべてを読むまで繰り返されます.あなたのWebアプリに応じて@ avgchin lineountの長さが異なることがあります-それは私たちがファイルの末尾からたびに取得したいどのように多くのバイトを計算するために使用されます.
@avg_line_lenght 200
def get_data(data, _pid, 0 = _load_from, _head_size, _params), do: {:ok, data}
def get_data(data, pid, load_from, last_line_offset, params) do
%{limit: limit, search: search} = params
chunk_size = limit * @avg_line_lenght
{load_from, buffer_size} =
if load_from - chunk_size < 0 do
{0, load_from + last_line_offset}
else
{load_from - chunk_size, chunk_size + last_line_offset}
end
[first_line | full_lines_chunk] = get_data_chunk(pid, load_from, buffer_size)
updated_data = parse_chunk(full_lines_chunk, search) ++ data
newlines = Enum.count(updated_data)
if newlines < limit do
get_data(updated_data, pid, load_from, byte_size(first_line), params)
else
{:ok, updated_data}
end
end
defp get_data_chunk(pid, load_from, buffer_size) do
case :file.pread(pid, [{load_from, buffer_size}]) do
{:ok, [:eof]} -> ""
{:ok, [content]} -> content
_ -> ""
end
|> :binary.split(<<"\n">>, [:global])
end
defp parse_chunk(data, search) do
data
|> filter_rows(search)
|> Stream.map(&String.trim/1)
|> Stream.map(&parse/1)
|> Stream.filter(fn parsed -> parsed |> elem(0) == :ok end)
|> Enum.map(&parsed_line_to_map/1)
end
そして、それは基本的な考えです.作業ファイルはgithub
< div >
Reference
この問題について(nginxはライブダッシュボードに記録する), 我々は、より多くの情報をここで見つけました https://dev.to/dkuku/nginx-logs-in-live-dashboard-jk9テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol