add log support

This commit is contained in:
安礼成 2023-04-20 20:00:47 +08:00
parent 9bed8c8622
commit 582b819e9f
6 changed files with 118 additions and 7 deletions

View File

@ -246,13 +246,17 @@
status = 0
}).
%%
-define(DEVICE_HOST, 1).
-define(DEVICE_TERMINAL, 2).
%%
-record(log, {
log_id :: integer(),
%%
action_name = <<>>,
%%
assoc_name = <<>>,
device_type :: integer(),
%% ID
assoc_id :: term(),
%%

View File

@ -0,0 +1,41 @@
%%%-------------------------------------------------------------------
%%% @author licheng5
%%% @copyright (C) 2020, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 26. 4 2020 3:36
%%%-------------------------------------------------------------------
-module(http_log_handler).
-author("licheng5").
-include("iot.hrl").
%% API
-export([handle_request/4]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% helper methods
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
handle_request(_, "/log/list", GetParams, _PostParams) ->
Size0 = maps:get(<<"size">>, GetParams, <<"10">>),
Size = binary_to_integer(Size0),
true = Size > 0,
case log_model:get_last_logs(Size) of
{ok, Logs} ->
LogInfos = lists:map(fun log_model:to_map/1, Logs),
{ok, 200, iot_util:json_data(LogInfos)};
{error, Reason} ->
lager:warning("[host_handler] get a error: ~p", [Reason]),
{ok, 200, iot_util:json_error(-1, <<"database error">>)}
end;
handle_request(_, Path, _, _) ->
Path1 = list_to_binary(Path),
{ok, 200, iot_util:json_error(-1, <<"url: ", Path1/binary, " not found">>)}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% helper methods
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View File

@ -64,7 +64,7 @@ supported_gzip(AcceptEncoding) when is_binary(AcceptEncoding) ->
parse_body(Req0) ->
ContentType = cowboy_req:header(<<"content-type">>, Req0),
case ContentType of
<<"application/json">> ->
<<"application/json", _/binary>> ->
{ok, Body, Req1} = read_body(Req0),
{ok, catch jiffy:decode(Body, [return_maps]), Req1};
<<"application/x-www-form-urlencoded">> ->

View File

@ -42,7 +42,10 @@ start_http_server() ->
Dispatcher = cowboy_router:compile([
{'_', [
{"/host/[...]", http_protocol, [http_host_handler]},
{"/api/[...]", http_protocol, [http_api_handler]},
{"/terminal/[...]", http_protocol, [http_terminal_handler]},
{"/scenario/[...]", http_protocol, [http_scenario_handler]},
{"/log/[...]", http_protocol, [http_log_handler]},
{"/iot/[...]", http_protocol, [http_iot_handler]},
{"/router/[...]", http_protocol, [http_router_handler]}
]}
]),

View File

@ -11,7 +11,7 @@
-include("iot.hrl").
%% API
-export([insert_hosts/0, insert_services/1, insert_terminals/1, insert_routers/0]).
-export([insert_hosts/0, insert_services/1, insert_terminals/1, insert_routers/0, insert_logs/0]).
-export([start_router/1]).
-export([rsa_encode/1]).
-export([start_issue/0]).
@ -43,6 +43,18 @@ insert_hosts() ->
host_model:add_host(Host)
end, lists:seq(1, 1)).
insert_logs() ->
lists:foreach(fun(Id0) ->
Log = #log{
log_id = Id0,
device_type = ?DEVICE_HOST,
action_name = <<"主机上线"/utf8>>,
assoc_id = <<"1">>,
create_ts = Id0 + 123456
},
log_model:add_log(Log)
end, lists:seq(1, 500000)).
insert_services(HostId) ->
lists:foreach(fun(Id0) ->
Q0 = queue:new(),

View File

@ -14,10 +14,10 @@
-define(TAB_NAME, log).
%% API
-export([get_logs/1, add_log/1, delete/1, table_size/0]).
-export([get_logs/1, add_log/1, delete/1, table_size/0, get_last_logs/1]).
-export([to_map/1]).
%% app信息
%% app信息,
-spec get_logs(Limit :: integer()) -> {ok, Logs :: list()} | {error, Reason :: any()}.
get_logs(Limit) when is_integer(Limit), Limit > 0 ->
Fun = fun() ->
@ -36,6 +36,20 @@ get_logs(Limit) when is_integer(Limit), Limit > 0 ->
{error, Error}
end.
%% n条记录
-spec get_last_logs(N :: integer()) -> {ok, Logs :: [#log{}]} | {error, Reason :: any()}.
get_last_logs(N) when N > 0 ->
Fun = fun() ->
Keys = read_last_keys(N),
lists:flatmap(fun(Key) -> mnesia:read(?TAB_NAME, Key, read) end, lists:reverse(Keys))
end,
case mnesia:transaction(Fun) of
{atomic, Logs} when is_list(Logs) ->
{ok, Logs};
{aborted, Error} ->
{error, Error}
end.
-spec add_log(Log :: #log{}) -> ok | {error, Reason :: binary()}.
add_log(Log = #log{}) ->
case mnesia:transaction(fun() -> mnesia:write(?TAB_NAME, Log, write) end) of
@ -54,6 +68,24 @@ delete(LogId) when is_binary(LogId) ->
{error, Reason}
end.
%%
read_last_keys(N) when N >= 1 ->
case mnesia:last(?TAB_NAME) of
'$end_of_table' ->
[];
LastKey ->
read_last_keys0(N - 1, LastKey, [LastKey])
end.
read_last_keys0(0, _, Keys) ->
Keys;
read_last_keys0(N, Key, Keys) ->
case mnesia:prev(?TAB_NAME, Key) of
'$end_of_table' ->
Keys;
PrevKey ->
read_last_keys0(N - 1, PrevKey, [PrevKey|Keys])
end.
%% app表的数据大小
table_size() ->
mnesia:table_info(?TAB_NAME, size).
@ -67,9 +99,28 @@ sort(Logs) when is_list(Logs) ->
lists:sort(fun(#log{create_ts = Ts0}, #log{create_ts = Ts1}) -> Ts0 > Ts1 end, Logs).
%% hash
to_map(#log{log_id = LogId, action_name = ActionName, assoc_name = AssocName, assoc_id = AssocId, create_ts = CreateTs}) ->
to_map(#log{log_id = LogId, action_name = ActionName, device_type = DeviceType, assoc_id = AssocId, create_ts = CreateTs}) ->
DeviceInfo = case DeviceType of
?DEVICE_HOST ->
case host_model:get_host(AssocId) of
{ok, Host} ->
host_model:to_map(Host);
_ ->
#{}
end;
?DEVICE_TERMINAL ->
case terminal_model:get_terminal(AssocId) of
{ok, Terminal} ->
terminal_model:to_map(Terminal);
_ ->
#{}
end
end,
#{
<<"log_id">> => LogId,
<<"action_name">> => ActionName,
<<"device_type">> => DeviceType,
<<"device_info">> => DeviceInfo,
<<"create_ts">> => CreateTs
}.