Merge pull request #8044 from DDDHuang/log_format
fix: logger formatter
This commit is contained in:
commit
ed8c61bf8d
|
@ -21,7 +21,7 @@ File format:
|
||||||
Now MQTT clients may be authorized with respect to a specific claim containing publish/subscribe topic whitelists.
|
Now MQTT clients may be authorized with respect to a specific claim containing publish/subscribe topic whitelists.
|
||||||
* Better randomisation of app screts (changed from timestamp seeded sha hash (uuid) to crypto:strong_rand_bytes)
|
* Better randomisation of app screts (changed from timestamp seeded sha hash (uuid) to crypto:strong_rand_bytes)
|
||||||
* Return a client_identifier_not_valid error when username is empty and username_as_clientid is set to true [#7862]
|
* Return a client_identifier_not_valid error when username is empty and username_as_clientid is set to true [#7862]
|
||||||
* Add more rule engine date functions: format_date/3, format_date/4, date_to_unix_ts/4 [#7894]
|
* Add more rule engine date functions: format_date/3, format_date/4, date_to_unix_ts/3, date_to_unix_ts/4 [#7894]
|
||||||
* Add proto_name and proto_ver fields for $event/client_disconnected event.
|
* Add proto_name and proto_ver fields for $event/client_disconnected event.
|
||||||
* Mnesia auth/acl http api support multiple condition queries.
|
* Mnesia auth/acl http api support multiple condition queries.
|
||||||
* Inflight QoS1 Messages for shared topics are now redispatched to another alive subscribers upon chosen subscriber session termination.
|
* Inflight QoS1 Messages for shared topics are now redispatched to another alive subscribers upon chosen subscriber session termination.
|
||||||
|
|
|
@ -201,6 +201,8 @@
|
||||||
, unix_ts_to_rfc3339/2
|
, unix_ts_to_rfc3339/2
|
||||||
, format_date/3
|
, format_date/3
|
||||||
, format_date/4
|
, format_date/4
|
||||||
|
, timezone_to_second/1
|
||||||
|
, date_to_unix_ts/3
|
||||||
, date_to_unix_ts/4
|
, date_to_unix_ts/4
|
||||||
, rfc3339_to_unix_ts/1
|
, rfc3339_to_unix_ts/1
|
||||||
, rfc3339_to_unix_ts/2
|
, rfc3339_to_unix_ts/2
|
||||||
|
@ -923,26 +925,37 @@ now_timestamp(Unit) ->
|
||||||
time_unit(<<"second">>) -> second;
|
time_unit(<<"second">>) -> second;
|
||||||
time_unit(<<"millisecond">>) -> millisecond;
|
time_unit(<<"millisecond">>) -> millisecond;
|
||||||
time_unit(<<"microsecond">>) -> microsecond;
|
time_unit(<<"microsecond">>) -> microsecond;
|
||||||
time_unit(<<"nanosecond">>) -> nanosecond.
|
time_unit(<<"nanosecond">>) -> nanosecond;
|
||||||
|
time_unit(second) -> second;
|
||||||
|
time_unit(millisecond) -> millisecond;
|
||||||
|
time_unit(microsecond) -> microsecond;
|
||||||
|
time_unit(nanosecond) -> nanosecond.
|
||||||
|
|
||||||
format_date(TimeUnit, Offset, FormatString) ->
|
format_date(TimeUnit, Offset, FormatString) ->
|
||||||
emqx_rule_utils:bin(
|
Unit = time_unit(TimeUnit),
|
||||||
emqx_rule_date:date(time_unit(TimeUnit),
|
TimeEpoch = erlang:system_time(Unit),
|
||||||
emqx_rule_utils:str(Offset),
|
format_date(Unit, Offset, FormatString, TimeEpoch).
|
||||||
emqx_rule_utils:str(FormatString))).
|
|
||||||
|
timezone_to_second(TimeZone) ->
|
||||||
|
emqx_calendar:offset_second(TimeZone).
|
||||||
|
|
||||||
format_date(TimeUnit, Offset, FormatString, TimeEpoch) ->
|
format_date(TimeUnit, Offset, FormatString, TimeEpoch) ->
|
||||||
|
Unit = time_unit(TimeUnit),
|
||||||
emqx_rule_utils:bin(
|
emqx_rule_utils:bin(
|
||||||
emqx_rule_date:date(time_unit(TimeUnit),
|
lists:concat(
|
||||||
emqx_rule_utils:str(Offset),
|
emqx_calendar:format(TimeEpoch, Unit, Offset, FormatString))).
|
||||||
emqx_rule_utils:str(FormatString),
|
|
||||||
TimeEpoch)).
|
|
||||||
|
|
||||||
|
%% date string has timezone information, calculate the offset.
|
||||||
|
date_to_unix_ts(TimeUnit, FormatString, InputString) ->
|
||||||
|
Unit = time_unit(TimeUnit),
|
||||||
|
emqx_calendar:parse(InputString, Unit, FormatString).
|
||||||
|
|
||||||
|
%% date string has no timezone information, force add the offset.
|
||||||
date_to_unix_ts(TimeUnit, Offset, FormatString, InputString) ->
|
date_to_unix_ts(TimeUnit, Offset, FormatString, InputString) ->
|
||||||
emqx_rule_date:parse_date(time_unit(TimeUnit),
|
Unit = time_unit(TimeUnit),
|
||||||
emqx_rule_utils:str(Offset),
|
OffsetSecond = emqx_calendar:offset_second(Offset),
|
||||||
emqx_rule_utils:str(FormatString),
|
OffsetDelta = erlang:convert_time_unit(OffsetSecond, second, Unit),
|
||||||
emqx_rule_utils:str(InputString)).
|
date_to_unix_ts(Unit, FormatString, InputString) - OffsetDelta.
|
||||||
|
|
||||||
mongo_date() ->
|
mongo_date() ->
|
||||||
erlang:timestamp().
|
erlang:timestamp().
|
||||||
|
|
|
@ -713,24 +713,29 @@ t_format_date_funcs(_) ->
|
||||||
?PROPTEST(prop_format_date_fun).
|
?PROPTEST(prop_format_date_fun).
|
||||||
|
|
||||||
prop_format_date_fun() ->
|
prop_format_date_fun() ->
|
||||||
Args1 = [<<"second">>, <<"+07:00">>, <<"%m--%d--%y---%H:%M:%S%Z">>],
|
Args1 = [<<"second">>, <<"+07:00">>, <<"%m--%d--%Y---%H:%M:%S%z">>],
|
||||||
?FORALL(S, erlang:system_time(second),
|
?FORALL(S, erlang:system_time(second),
|
||||||
S == apply_func(date_to_unix_ts,
|
S == apply_func(date_to_unix_ts,
|
||||||
Args1 ++ [apply_func(format_date,
|
Args1 ++ [apply_func(format_date,
|
||||||
Args1 ++ [S])])),
|
Args1 ++ [S])])),
|
||||||
Args2 = [<<"millisecond">>, <<"+04:00">>, <<"--%m--%d--%y---%H:%M:%S%Z">>],
|
Args2 = [<<"millisecond">>, <<"+04:00">>, <<"--%m--%d--%Y---%H:%M:%S:%3N%z">>],
|
||||||
|
Args2DTUS = [<<"millisecond">>, <<"--%m--%d--%Y---%H:%M:%S:%3N%z">>],
|
||||||
?FORALL(S, erlang:system_time(millisecond),
|
?FORALL(S, erlang:system_time(millisecond),
|
||||||
S == apply_func(date_to_unix_ts,
|
S == apply_func(date_to_unix_ts,
|
||||||
Args2 ++ [apply_func(format_date,
|
Args2DTUS ++ [apply_func(format_date,
|
||||||
Args2 ++ [S])])),
|
Args2 ++ [S])])),
|
||||||
Args = [<<"second">>, <<"+08:00">>, <<"%y-%m-%d-%H:%M:%S%Z">>],
|
Args = [<<"second">>, <<"+08:00">>, <<"%Y-%m-%d-%H:%M:%S%z">>],
|
||||||
|
ArgsDTUS = [<<"second">>, <<"%Y-%m-%d-%H:%M:%S%z">>],
|
||||||
?FORALL(S, erlang:system_time(second),
|
?FORALL(S, erlang:system_time(second),
|
||||||
S == apply_func(date_to_unix_ts,
|
S == apply_func(date_to_unix_ts,
|
||||||
Args ++ [apply_func(format_date,
|
ArgsDTUS ++ [apply_func(format_date,
|
||||||
Args ++ [S])])).
|
Args ++ [S])])),
|
||||||
%%------------------------------------------------------------------------------
|
% no offset in format string. force add offset
|
||||||
%% Utility functions
|
Second = erlang:system_time(second),
|
||||||
%%------------------------------------------------------------------------------
|
Args3 = [<<"second">>, <<"+04:00">>, <<"--%m--%d--%Y---%H:%M:%S">>, Second],
|
||||||
|
Formatters3 = apply_func(format_date, Args3),
|
||||||
|
Args3DTUS = [<<"second">>, <<"+04:00">>, <<"--%m--%d--%Y---%H:%M:%S">>, Formatters3],
|
||||||
|
Second == apply_func(date_to_unix_ts, Args3DTUS).
|
||||||
|
|
||||||
apply_func(Name, Args) when is_atom(Name) ->
|
apply_func(Name, Args) when is_atom(Name) ->
|
||||||
erlang:apply(emqx_rule_funcs, Name, Args);
|
erlang:apply(emqx_rule_funcs, Name, Args);
|
||||||
|
|
|
@ -458,7 +458,33 @@ log.file = emqx.log
|
||||||
|
|
||||||
## Log formatter
|
## Log formatter
|
||||||
## Value: text | json
|
## Value: text | json
|
||||||
#log.formatter = text
|
log.formatter = text
|
||||||
|
|
||||||
|
## Format of the text logger.
|
||||||
|
##
|
||||||
|
## Value: rfc3339 | FORMAT
|
||||||
|
## Where FORMAT is the format string of the timestamp. Supported specifiers:
|
||||||
|
## %Y: year
|
||||||
|
## %m: month
|
||||||
|
## %d: day
|
||||||
|
## %H: hour
|
||||||
|
## %M: minute
|
||||||
|
## %S: second
|
||||||
|
## %N: nanoseconds (000000000 - 999999999)
|
||||||
|
## %6N: microseconds (00000 - 999999)
|
||||||
|
## %3N: milliseconds (000 - 999)
|
||||||
|
## %z: timezone, [+-]HHMM
|
||||||
|
## %:z: timezone, [+-]HH:MM
|
||||||
|
## %::z: timezone, [+-]HH:MM:SS
|
||||||
|
##
|
||||||
|
## For example:
|
||||||
|
## log.formatter.text.date.format = %Y-%m-%dT%H:%M:%S.%6N %:z
|
||||||
|
##
|
||||||
|
## Before 4.2, the default date format was:
|
||||||
|
## log.formatter.text.date.format = %Y-%m-%d %H:%M:%S.%3N
|
||||||
|
##
|
||||||
|
## Default: rfc3339
|
||||||
|
# log.formatter.text.date.format = rfc3339
|
||||||
|
|
||||||
## Log to single line
|
## Log to single line
|
||||||
## Value: Boolean
|
## Value: Boolean
|
||||||
|
|
|
@ -528,6 +528,12 @@ end}.
|
||||||
{datatype, {enum, [text, json]}}
|
{datatype, {enum, [text, json]}}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
|
%% @doc format logs as text, date format part
|
||||||
|
{mapping, "log.formatter.text.date.format", "kernel.logger", [
|
||||||
|
{default, "rfc3339"},
|
||||||
|
{datatype, string}
|
||||||
|
]}.
|
||||||
|
|
||||||
%% @doc format logs in a single line.
|
%% @doc format logs in a single line.
|
||||||
{mapping, "log.single_line", "kernel.logger", [
|
{mapping, "log.single_line", "kernel.logger", [
|
||||||
{default, true},
|
{default, true},
|
||||||
|
@ -629,9 +635,38 @@ end}.
|
||||||
single_line => SingleLine
|
single_line => SingleLine
|
||||||
}};
|
}};
|
||||||
text ->
|
text ->
|
||||||
|
DateFormat =
|
||||||
|
case cuttlefish:conf_get("log.formatter.text.date.format", Conf, "rfc3339") of
|
||||||
|
"rfc3339" ->
|
||||||
|
rfc3339;
|
||||||
|
DateStr ->
|
||||||
|
DateStrTrans =
|
||||||
|
fun
|
||||||
|
DST(<<>>, Formatter) -> lists:reverse(Formatter);
|
||||||
|
DST(<<"%Y", Tail/binary>>, Formatter) -> DST(Tail, [year | Formatter]);
|
||||||
|
DST(<<"%m", Tail/binary>>, Formatter) -> DST(Tail, [month | Formatter]);
|
||||||
|
DST(<<"%d", Tail/binary>>, Formatter) -> DST(Tail, [day | Formatter]);
|
||||||
|
DST(<<"%H", Tail/binary>>, Formatter) -> DST(Tail, [hour | Formatter]);
|
||||||
|
DST(<<"%M", Tail/binary>>, Formatter) -> DST(Tail, [minute | Formatter]);
|
||||||
|
DST(<<"%S", Tail/binary>>, Formatter) -> DST(Tail, [second | Formatter]);
|
||||||
|
DST(<<"%N", Tail/binary>>, Formatter) -> DST(Tail, [nanosecond | Formatter]);
|
||||||
|
DST(<<"%3N", Tail/binary>>, Formatter) -> DST(Tail, [millisecond | Formatter]);
|
||||||
|
DST(<<"%6N", Tail/binary>>, Formatter) -> DST(Tail, [microsecond | Formatter]);
|
||||||
|
DST(<<"%z", Tail/binary>>, Formatter) -> DST(Tail, [timezone | Formatter]);
|
||||||
|
DST(<<"%:z", Tail/binary>>, Formatter) -> DST(Tail, [timezone1 | Formatter]);
|
||||||
|
DST(<<"%::z", Tail/binary>>, Formatter) -> DST(Tail, [timezone2 | Formatter]);
|
||||||
|
DST(<<Char:8, Tail/binary>>, [Str | Formatter]) when is_list(Str) ->
|
||||||
|
DST(Tail, [lists:append(Str, [Char]) | Formatter]);
|
||||||
|
DST(<<Char:8, Tail/binary>>, Formatter) ->
|
||||||
|
DST(Tail, [[Char] | Formatter])
|
||||||
|
end,
|
||||||
|
DateStrTrans(list_to_binary(DateStr), [])
|
||||||
|
end,
|
||||||
{emqx_logger_textfmt,
|
{emqx_logger_textfmt,
|
||||||
#{template =>
|
#{
|
||||||
[time," [",level,"] ",
|
date_format => DateFormat,
|
||||||
|
template =>
|
||||||
|
[" [",level,"] ",
|
||||||
{clientid,
|
{clientid,
|
||||||
[{peername,
|
[{peername,
|
||||||
[clientid,"@",peername," "],
|
[clientid,"@",peername," "],
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||||
{VSN,
|
{VSN,
|
||||||
[{"4.3.15",
|
[{"4.3.15",
|
||||||
[{load_module,emqx_session,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_session,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_frame,brutal_purge,soft_purge,[]},
|
{load_module,emqx_frame,brutal_purge,soft_purge,[]},
|
||||||
|
@ -16,7 +18,9 @@
|
||||||
{update,emqx_os_mon,{advanced,[]}},
|
{update,emqx_os_mon,{advanced,[]}},
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_app,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.14",
|
{"4.3.14",
|
||||||
[{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_session,brutal_purge,soft_purge,[]},
|
{load_module,emqx_session,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_channel,brutal_purge,soft_purge,[]},
|
{load_module,emqx_channel,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
|
@ -34,7 +38,9 @@
|
||||||
{update,emqx_os_mon,{advanced,[]}},
|
{update,emqx_os_mon,{advanced,[]}},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.13",
|
{"4.3.13",
|
||||||
[{load_module,emqx_session,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_session,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
|
@ -58,7 +64,9 @@
|
||||||
{update,emqx_os_mon,{advanced,[]}},
|
{update,emqx_os_mon,{advanced,[]}},
|
||||||
{load_module,emqx_connection,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_connection,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.12",
|
{"4.3.12",
|
||||||
[{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
||||||
|
@ -86,7 +94,9 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.11",
|
{"4.3.11",
|
||||||
[{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
|
@ -116,7 +126,9 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.10",
|
{"4.3.10",
|
||||||
[{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
|
@ -146,7 +158,9 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.9",
|
{"4.3.9",
|
||||||
[{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
|
@ -180,7 +194,9 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.8",
|
{"4.3.8",
|
||||||
[{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
|
@ -214,7 +230,9 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.7",
|
{"4.3.7",
|
||||||
[{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
||||||
|
@ -248,7 +266,9 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.6",
|
{"4.3.6",
|
||||||
[{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
||||||
|
@ -282,7 +302,9 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.5",
|
{"4.3.5",
|
||||||
[{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
||||||
|
@ -316,7 +338,9 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.4",
|
{"4.3.4",
|
||||||
[{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
@ -350,7 +374,9 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.3",
|
{"4.3.3",
|
||||||
[{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
@ -385,7 +411,9 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.2",
|
{"4.3.2",
|
||||||
[{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
@ -420,7 +448,8 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.1",
|
{"4.3.1",
|
||||||
[{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_calendar},
|
||||||
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_sys,brutal_purge,soft_purge,[]},
|
{load_module,emqx_sys,brutal_purge,soft_purge,[]},
|
||||||
|
@ -458,7 +487,8 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.0",
|
{"4.3.0",
|
||||||
[{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_calendar},
|
||||||
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_sys,brutal_purge,soft_purge,[]},
|
{load_module,emqx_sys,brutal_purge,soft_purge,[]},
|
||||||
|
@ -500,7 +530,9 @@
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{<<".*">>,[]}],
|
{<<".*">>,[]}],
|
||||||
[{"4.3.15",
|
[{"4.3.15",
|
||||||
[{load_module,emqx_alarm,brutal_purge,soft_purge,[]},
|
[{delete_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_alarm,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_session,brutal_purge,soft_purge,[]},
|
{load_module,emqx_session,brutal_purge,soft_purge,[]},
|
||||||
|
@ -513,7 +545,9 @@
|
||||||
{load_module,emqx_os_mon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_os_mon,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_app,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.14",
|
{"4.3.14",
|
||||||
[{load_module,emqx_alarm,brutal_purge,soft_purge,[]},
|
[{delete_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_alarm,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_session,brutal_purge,soft_purge,[]},
|
{load_module,emqx_session,brutal_purge,soft_purge,[]},
|
||||||
|
@ -530,7 +564,9 @@
|
||||||
{load_module,emqx_os_mon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_os_mon,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.13",
|
{"4.3.13",
|
||||||
[{load_module,emqx_alarm,brutal_purge,soft_purge,[]},
|
[{delete_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_alarm,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_session,brutal_purge,soft_purge,[]},
|
{load_module,emqx_session,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
|
@ -553,7 +589,9 @@
|
||||||
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
|
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_connection,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_connection,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.12",
|
{"4.3.12",
|
||||||
[{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
[{delete_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
|
@ -579,7 +617,10 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.11",
|
{"4.3.11",
|
||||||
[{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
[{delete_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_alarm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
|
@ -599,7 +640,6 @@
|
||||||
{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_frame,brutal_purge,soft_purge,[]},
|
{load_module,emqx_frame,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_alarm,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_os_mon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_os_mon,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx,brutal_purge,soft_purge,[]},
|
{load_module,emqx,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
||||||
|
@ -607,7 +647,10 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.10",
|
{"4.3.10",
|
||||||
[{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
[{delete_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_alarm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
|
@ -628,14 +671,16 @@
|
||||||
{load_module,emqx_http_lib,brutal_purge,soft_purge,[]},
|
{load_module,emqx_http_lib,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_frame,brutal_purge,soft_purge,[]},
|
{load_module,emqx_frame,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_alarm,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_os_mon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_os_mon,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx,brutal_purge,soft_purge,[]},
|
{load_module,emqx,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
|
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.9",
|
{"4.3.9",
|
||||||
[{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
[{delete_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_alarm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
|
@ -660,14 +705,16 @@
|
||||||
{load_module,emqx_mqueue,brutal_purge,soft_purge,[]},
|
{load_module,emqx_mqueue,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_frame,brutal_purge,soft_purge,[]},
|
{load_module,emqx_frame,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rpc,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rpc,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_alarm,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_os_mon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_os_mon,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx,brutal_purge,soft_purge,[]},
|
{load_module,emqx,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.8",
|
{"4.3.8",
|
||||||
[{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
[{delete_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_alarm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_alarm_handler,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
|
@ -692,14 +739,15 @@
|
||||||
{load_module,emqx_mqueue,brutal_purge,soft_purge,[]},
|
{load_module,emqx_mqueue,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_frame,brutal_purge,soft_purge,[]},
|
{load_module,emqx_frame,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rpc,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rpc,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_alarm,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_os_mon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_os_mon,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx,brutal_purge,soft_purge,[]},
|
{load_module,emqx,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.7",
|
{"4.3.7",
|
||||||
[{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
[{delete_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
||||||
|
@ -731,7 +779,9 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.6",
|
{"4.3.6",
|
||||||
[{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
[{delete_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
||||||
|
@ -763,7 +813,9 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.5",
|
{"4.3.5",
|
||||||
[{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
[{delete_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
||||||
|
@ -795,7 +847,9 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.4",
|
{"4.3.4",
|
||||||
[{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
[{delete_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
@ -827,7 +881,9 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.3",
|
{"4.3.3",
|
||||||
[{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
[{delete_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
@ -860,7 +916,9 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.2",
|
{"4.3.2",
|
||||||
[{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
[{delete_module,emqx_calendar},
|
||||||
|
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
@ -893,7 +951,8 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.1",
|
{"4.3.1",
|
||||||
[{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
[{delete_module,emqx_calendar},
|
||||||
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_sys,brutal_purge,soft_purge,[]},
|
{load_module,emqx_sys,brutal_purge,soft_purge,[]},
|
||||||
|
@ -929,7 +988,8 @@
|
||||||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.0",
|
{"4.3.0",
|
||||||
[{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
[{delete_module,emqx_calendar},
|
||||||
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
{load_module,emqx_pmon,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_sys,brutal_purge,soft_purge,[]},
|
{load_module,emqx_sys,brutal_purge,soft_purge,[]},
|
||||||
|
|
|
@ -0,0 +1,436 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2019-2022 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
%% you may not use this file except in compliance with the License.
|
||||||
|
%% You may obtain a copy of the License at
|
||||||
|
%%
|
||||||
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_calendar).
|
||||||
|
|
||||||
|
-define(SECONDS_PER_MINUTE, 60).
|
||||||
|
-define(SECONDS_PER_HOUR, 3600).
|
||||||
|
-define(SECONDS_PER_DAY, 86400).
|
||||||
|
-define(DAYS_PER_YEAR, 365).
|
||||||
|
-define(DAYS_PER_LEAP_YEAR, 366).
|
||||||
|
-define(DAYS_FROM_0_TO_1970, 719528).
|
||||||
|
-define(SECONDS_FROM_0_TO_1970, ?DAYS_FROM_0_TO_1970 * ?SECONDS_PER_DAY).
|
||||||
|
|
||||||
|
-export([ formatter/1
|
||||||
|
, format/3
|
||||||
|
, format/4
|
||||||
|
, parse/3
|
||||||
|
, offset_second/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
-define(DATE_PART,
|
||||||
|
[ year
|
||||||
|
, month
|
||||||
|
, day
|
||||||
|
, hour
|
||||||
|
, minute
|
||||||
|
, second
|
||||||
|
, nanosecond
|
||||||
|
, millisecond
|
||||||
|
, microsecond
|
||||||
|
]).
|
||||||
|
|
||||||
|
-define(DATE_ZONE_NAME,
|
||||||
|
[ timezone
|
||||||
|
, timezone1
|
||||||
|
, timezone2
|
||||||
|
]).
|
||||||
|
|
||||||
|
formatter(FormatterStr) when is_list(FormatterStr) ->
|
||||||
|
formatter(list_to_binary(FormatterStr));
|
||||||
|
formatter(FormatterBin) when is_binary(FormatterBin) ->
|
||||||
|
do_formatter(FormatterBin, []).
|
||||||
|
|
||||||
|
offset_second(Offset) ->
|
||||||
|
offset_second_(Offset).
|
||||||
|
|
||||||
|
format(Time, Unit, Formatter) ->
|
||||||
|
format(Time, Unit, undefined, Formatter).
|
||||||
|
|
||||||
|
format(Time, Unit, Offset, FormatterBin) when is_binary(FormatterBin) ->
|
||||||
|
format(Time, Unit, Offset, formatter(FormatterBin));
|
||||||
|
format(Time, Unit, Offset, Formatter) ->
|
||||||
|
do_format(Time, time_unit(Unit), offset_second(Offset), Formatter).
|
||||||
|
|
||||||
|
parse(DateStr, Unit, FormatterBin) when is_binary(FormatterBin) ->
|
||||||
|
parse(DateStr, Unit, formatter(FormatterBin));
|
||||||
|
parse(DateStr, Unit, Formatter) ->
|
||||||
|
do_parse(DateStr, Unit, Formatter).
|
||||||
|
%% -------------------------------------------------------------------------------------------------
|
||||||
|
%% internal
|
||||||
|
|
||||||
|
time_unit(second) -> second;
|
||||||
|
time_unit(millisecond) -> millisecond;
|
||||||
|
time_unit(microsecond) -> microsecond;
|
||||||
|
time_unit(nanosecond) -> nanosecond;
|
||||||
|
time_unit("second") -> second;
|
||||||
|
time_unit("millisecond") -> millisecond;
|
||||||
|
time_unit("microsecond") -> microsecond;
|
||||||
|
time_unit("nanosecond") -> nanosecond;
|
||||||
|
time_unit(<<"second">>) -> second;
|
||||||
|
time_unit(<<"millisecond">>) -> millisecond;
|
||||||
|
time_unit(<<"microsecond">>) -> microsecond;
|
||||||
|
time_unit(<<"nanosecond">>) -> nanosecond.
|
||||||
|
|
||||||
|
%% -------------------------------------------------------------------------------------------------
|
||||||
|
%% internal: format part
|
||||||
|
|
||||||
|
do_formatter(<<>>, Formatter) -> lists:reverse(Formatter);
|
||||||
|
do_formatter(<<"%Y", Tail/binary>>, Formatter) -> do_formatter(Tail, [year | Formatter]);
|
||||||
|
do_formatter(<<"%m", Tail/binary>>, Formatter) -> do_formatter(Tail, [month | Formatter]);
|
||||||
|
do_formatter(<<"%d", Tail/binary>>, Formatter) -> do_formatter(Tail, [day | Formatter]);
|
||||||
|
do_formatter(<<"%H", Tail/binary>>, Formatter) -> do_formatter(Tail, [hour | Formatter]);
|
||||||
|
do_formatter(<<"%M", Tail/binary>>, Formatter) -> do_formatter(Tail, [minute | Formatter]);
|
||||||
|
do_formatter(<<"%S", Tail/binary>>, Formatter) -> do_formatter(Tail, [second | Formatter]);
|
||||||
|
do_formatter(<<"%N", Tail/binary>>, Formatter) -> do_formatter(Tail, [nanosecond | Formatter]);
|
||||||
|
do_formatter(<<"%3N", Tail/binary>>, Formatter) -> do_formatter(Tail, [millisecond | Formatter]);
|
||||||
|
do_formatter(<<"%6N", Tail/binary>>, Formatter) -> do_formatter(Tail, [microsecond | Formatter]);
|
||||||
|
do_formatter(<<"%z", Tail/binary>>, Formatter) -> do_formatter(Tail, [timezone | Formatter]);
|
||||||
|
do_formatter(<<"%:z", Tail/binary>>, Formatter) -> do_formatter(Tail, [timezone1 | Formatter]);
|
||||||
|
do_formatter(<<"%::z", Tail/binary>>, Formatter) -> do_formatter(Tail, [timezone2 | Formatter]);
|
||||||
|
do_formatter(<<Char:8, Tail/binary>>, [Str | Formatter]) when is_list(Str) ->
|
||||||
|
do_formatter(Tail, [lists:append(Str, [Char]) | Formatter]);
|
||||||
|
do_formatter(<<Char:8, Tail/binary>>, Formatter) -> do_formatter(Tail, [[Char] | Formatter]).
|
||||||
|
|
||||||
|
offset_second_(OffsetSecond) when is_integer(OffsetSecond) -> OffsetSecond;
|
||||||
|
offset_second_(undefined) -> 0;
|
||||||
|
offset_second_("local") -> offset_second_(local);
|
||||||
|
offset_second_(<<"local">>) -> offset_second_(local);
|
||||||
|
offset_second_(local) ->
|
||||||
|
UniversalTime = calendar:system_time_to_universal_time(erlang:system_time(second), second),
|
||||||
|
LocalTime = erlang:universaltime_to_localtime(UniversalTime),
|
||||||
|
LocalSecs = calendar:datetime_to_gregorian_seconds(LocalTime),
|
||||||
|
UniversalSecs = calendar:datetime_to_gregorian_seconds(UniversalTime),
|
||||||
|
LocalSecs - UniversalSecs;
|
||||||
|
offset_second_(Offset) when is_binary(Offset) ->
|
||||||
|
offset_second_(erlang:binary_to_list(Offset));
|
||||||
|
offset_second_("Z") -> 0;
|
||||||
|
offset_second_("z") -> 0;
|
||||||
|
offset_second_(Offset) when is_list(Offset) ->
|
||||||
|
Sign = hd(Offset),
|
||||||
|
((Sign == $+) orelse (Sign == $-))
|
||||||
|
orelse error({bad_time_offset, Offset}),
|
||||||
|
Signs = #{$+ => 1, $- => -1},
|
||||||
|
PosNeg = maps:get(Sign, Signs),
|
||||||
|
[Sign | HM] = Offset,
|
||||||
|
{HourStr, MinuteStr, SecondStr} =
|
||||||
|
case string:tokens(HM, ":") of
|
||||||
|
[H, M] ->
|
||||||
|
{H, M, "0"};
|
||||||
|
[H, M, S] ->
|
||||||
|
{H, M, S};
|
||||||
|
[HHMM] when erlang:length(HHMM) == 4 ->
|
||||||
|
{string:sub_string(HHMM, 1,2), string:sub_string(HHMM, 3,4), "0"};
|
||||||
|
_ ->
|
||||||
|
error({bad_time_offset, Offset})
|
||||||
|
end,
|
||||||
|
Hour = erlang:list_to_integer(HourStr),
|
||||||
|
Minute = erlang:list_to_integer(MinuteStr),
|
||||||
|
Second = erlang:list_to_integer(SecondStr),
|
||||||
|
(Hour =< 23) orelse error({bad_time_offset_hour, Hour}),
|
||||||
|
(Minute =< 59) orelse error({bad_time_offset_minute, Minute}),
|
||||||
|
(Second =< 59) orelse error({bad_time_offset_second, Second}),
|
||||||
|
PosNeg * (Hour * 3600 + Minute * 60 + Second).
|
||||||
|
|
||||||
|
do_format(Time, Unit, Offset, Formatter) ->
|
||||||
|
Adjustment = erlang:convert_time_unit(Offset, second, Unit),
|
||||||
|
AdjustedTime = Time + Adjustment,
|
||||||
|
Factor = factor(Unit),
|
||||||
|
Secs = AdjustedTime div Factor,
|
||||||
|
DateTime = system_time_to_datetime(Secs),
|
||||||
|
{{Year, Month, Day}, {Hour, Min, Sec}} = DateTime,
|
||||||
|
Date = #{
|
||||||
|
year => padding(Year, 4),
|
||||||
|
month => padding(Month, 2),
|
||||||
|
day => padding(Day, 2),
|
||||||
|
hour => padding(Hour, 2),
|
||||||
|
minute => padding(Min, 2),
|
||||||
|
second => padding(Sec, 2),
|
||||||
|
millisecond => trans_x_second(Unit, millisecond, Time),
|
||||||
|
microsecond => trans_x_second(Unit, microsecond, Time),
|
||||||
|
nanosecond => trans_x_second(Unit, nanosecond, Time)
|
||||||
|
},
|
||||||
|
Timezones = formatter_timezones(Offset, Formatter, #{}),
|
||||||
|
DateWithZone = maps:merge(Date, Timezones),
|
||||||
|
[maps:get(Key, DateWithZone, Key) || Key <- Formatter].
|
||||||
|
|
||||||
|
formatter_timezones(_Offset, [], Zones) -> Zones;
|
||||||
|
formatter_timezones(Offset, [Timezone | Formatter], Zones) ->
|
||||||
|
case lists:member(Timezone, [timezone, timezone1, timezone2]) of
|
||||||
|
true ->
|
||||||
|
NZones = Zones#{Timezone => offset_to_timezone(Offset, Timezone)},
|
||||||
|
formatter_timezones(Offset, Formatter, NZones);
|
||||||
|
false ->
|
||||||
|
formatter_timezones(Offset, Formatter, Zones)
|
||||||
|
end.
|
||||||
|
|
||||||
|
offset_to_timezone(Offset, Timezone) ->
|
||||||
|
Sign =
|
||||||
|
case Offset >= 0 of
|
||||||
|
true ->
|
||||||
|
$+;
|
||||||
|
false ->
|
||||||
|
$-
|
||||||
|
end,
|
||||||
|
{H, M, S} = seconds_to_time(abs(Offset)),
|
||||||
|
%% TODO: Support zone define %:::z
|
||||||
|
%% Numeric time zone with ":" to necessary precision (e.g., -04, +05:30).
|
||||||
|
case Timezone of
|
||||||
|
timezone ->
|
||||||
|
%% +0800
|
||||||
|
io_lib:format("~c~2.10.0B~2.10.0B", [Sign, H, M]);
|
||||||
|
timezone1 ->
|
||||||
|
%% +08:00
|
||||||
|
io_lib:format("~c~2.10.0B:~2.10.0B", [Sign, H, M]);
|
||||||
|
timezone2 ->
|
||||||
|
%% +08:00:00
|
||||||
|
io_lib:format("~c~2.10.0B:~2.10.0B:~2.10.0B", [Sign, H, M, S])
|
||||||
|
end.
|
||||||
|
|
||||||
|
factor(second) -> 1;
|
||||||
|
factor(millisecond) -> 1000;
|
||||||
|
factor(microsecond) -> 1000000;
|
||||||
|
factor(nanosecond) -> 1000000000.
|
||||||
|
|
||||||
|
system_time_to_datetime(Seconds) ->
|
||||||
|
gregorian_seconds_to_datetime(Seconds + ?SECONDS_FROM_0_TO_1970).
|
||||||
|
|
||||||
|
gregorian_seconds_to_datetime(Secs) when Secs >= 0 ->
|
||||||
|
Days = Secs div ?SECONDS_PER_DAY,
|
||||||
|
Rest = Secs rem ?SECONDS_PER_DAY,
|
||||||
|
{gregorian_days_to_date(Days), seconds_to_time(Rest)}.
|
||||||
|
|
||||||
|
seconds_to_time(Secs) when Secs >= 0, Secs < ?SECONDS_PER_DAY ->
|
||||||
|
Secs0 = Secs rem ?SECONDS_PER_DAY,
|
||||||
|
Hour = Secs0 div ?SECONDS_PER_HOUR,
|
||||||
|
Secs1 = Secs0 rem ?SECONDS_PER_HOUR,
|
||||||
|
Minute = Secs1 div ?SECONDS_PER_MINUTE,
|
||||||
|
Second = Secs1 rem ?SECONDS_PER_MINUTE,
|
||||||
|
{Hour, Minute, Second}.
|
||||||
|
|
||||||
|
gregorian_days_to_date(Days) ->
|
||||||
|
{Year, DayOfYear} = day_to_year(Days),
|
||||||
|
{Month, DayOfMonth} = year_day_to_date(Year, DayOfYear),
|
||||||
|
{Year, Month, DayOfMonth}.
|
||||||
|
|
||||||
|
day_to_year(DayOfEpoch) when DayOfEpoch >= 0 ->
|
||||||
|
YMax = DayOfEpoch div ?DAYS_PER_YEAR,
|
||||||
|
YMin = DayOfEpoch div ?DAYS_PER_LEAP_YEAR,
|
||||||
|
{Y1, D1} = dty(YMin, YMax, DayOfEpoch, dy(YMin), dy(YMax)),
|
||||||
|
{Y1, DayOfEpoch - D1}.
|
||||||
|
|
||||||
|
year_day_to_date(Year, DayOfYear) ->
|
||||||
|
ExtraDay =
|
||||||
|
case is_leap_year(Year) of
|
||||||
|
true ->
|
||||||
|
1;
|
||||||
|
false ->
|
||||||
|
0
|
||||||
|
end,
|
||||||
|
{Month, Day} = year_day_to_date2(ExtraDay, DayOfYear),
|
||||||
|
{Month, Day + 1}.
|
||||||
|
|
||||||
|
dty(Min, Max, _D1, DMin, _DMax) when Min == Max ->
|
||||||
|
{Min, DMin};
|
||||||
|
dty(Min, Max, D1, DMin, DMax) ->
|
||||||
|
Diff = Max - Min,
|
||||||
|
Mid = Min + Diff * (D1 - DMin) div (DMax - DMin),
|
||||||
|
MidLength =
|
||||||
|
case is_leap_year(Mid) of
|
||||||
|
true ->
|
||||||
|
?DAYS_PER_LEAP_YEAR;
|
||||||
|
false ->
|
||||||
|
?DAYS_PER_YEAR
|
||||||
|
end,
|
||||||
|
case dy(Mid) of
|
||||||
|
D2 when D1 < D2 ->
|
||||||
|
NewMax = Mid - 1,
|
||||||
|
dty(Min, NewMax, D1, DMin, dy(NewMax));
|
||||||
|
D2 when D1 - D2 >= MidLength ->
|
||||||
|
NewMin = Mid + 1,
|
||||||
|
dty(NewMin, Max, D1, dy(NewMin), DMax);
|
||||||
|
D2 ->
|
||||||
|
{Mid, D2}
|
||||||
|
end.
|
||||||
|
|
||||||
|
dy(Y) when Y =< 0 ->
|
||||||
|
0;
|
||||||
|
dy(Y) ->
|
||||||
|
X = Y - 1,
|
||||||
|
X div 4 - X div 100 + X div 400 + X * ?DAYS_PER_YEAR + ?DAYS_PER_LEAP_YEAR.
|
||||||
|
|
||||||
|
is_leap_year(Y) when is_integer(Y), Y >= 0 ->
|
||||||
|
is_leap_year1(Y).
|
||||||
|
|
||||||
|
is_leap_year1(Year) when Year rem 4 =:= 0, Year rem 100 > 0 ->
|
||||||
|
true;
|
||||||
|
is_leap_year1(Year) when Year rem 400 =:= 0 ->
|
||||||
|
true;
|
||||||
|
is_leap_year1(_) ->
|
||||||
|
false.
|
||||||
|
|
||||||
|
year_day_to_date2(_, Day) when Day < 31 ->
|
||||||
|
{1, Day};
|
||||||
|
year_day_to_date2(E, Day) when 31 =< Day, Day < 59 + E ->
|
||||||
|
{2, Day - 31};
|
||||||
|
year_day_to_date2(E, Day) when 59 + E =< Day, Day < 90 + E ->
|
||||||
|
{3, Day - (59 + E)};
|
||||||
|
year_day_to_date2(E, Day) when 90 + E =< Day, Day < 120 + E ->
|
||||||
|
{4, Day - (90 + E)};
|
||||||
|
year_day_to_date2(E, Day) when 120 + E =< Day, Day < 151 + E ->
|
||||||
|
{5, Day - (120 + E)};
|
||||||
|
year_day_to_date2(E, Day) when 151 + E =< Day, Day < 181 + E ->
|
||||||
|
{6, Day - (151 + E)};
|
||||||
|
year_day_to_date2(E, Day) when 181 + E =< Day, Day < 212 + E ->
|
||||||
|
{7, Day - (181 + E)};
|
||||||
|
year_day_to_date2(E, Day) when 212 + E =< Day, Day < 243 + E ->
|
||||||
|
{8, Day - (212 + E)};
|
||||||
|
year_day_to_date2(E, Day) when 243 + E =< Day, Day < 273 + E ->
|
||||||
|
{9, Day - (243 + E)};
|
||||||
|
year_day_to_date2(E, Day) when 273 + E =< Day, Day < 304 + E ->
|
||||||
|
{10, Day - (273 + E)};
|
||||||
|
year_day_to_date2(E, Day) when 304 + E =< Day, Day < 334 + E ->
|
||||||
|
{11, Day - (304 + E)};
|
||||||
|
year_day_to_date2(E, Day) when 334 + E =< Day ->
|
||||||
|
{12, Day - (334 + E)}.
|
||||||
|
|
||||||
|
trans_x_second(FromUnit, ToUnit, Time) ->
|
||||||
|
XSecond = do_trans_x_second(FromUnit, ToUnit, Time),
|
||||||
|
Len =
|
||||||
|
case ToUnit of
|
||||||
|
millisecond -> 3;
|
||||||
|
microsecond -> 6;
|
||||||
|
nanosecond -> 9
|
||||||
|
end,
|
||||||
|
padding(XSecond, Len).
|
||||||
|
|
||||||
|
do_trans_x_second(second, second, Time) -> Time div 60;
|
||||||
|
do_trans_x_second(second, _, _Time) -> 0;
|
||||||
|
|
||||||
|
do_trans_x_second(millisecond, millisecond, Time) -> Time rem 1000;
|
||||||
|
do_trans_x_second(millisecond, microsecond, Time) -> (Time rem 1000) * 1000;
|
||||||
|
do_trans_x_second(millisecond, nanosecond, Time) -> (Time rem 1000) * 1000_000;
|
||||||
|
|
||||||
|
do_trans_x_second(microsecond, millisecond, Time) -> Time div 1000 rem 1000;
|
||||||
|
do_trans_x_second(microsecond, microsecond, Time) -> Time rem 1000000;
|
||||||
|
do_trans_x_second(microsecond, nanosecond, Time) -> (Time rem 1000000) * 1000;
|
||||||
|
|
||||||
|
do_trans_x_second(nanosecond, millisecond, Time) -> Time div 1000000 rem 1000;
|
||||||
|
do_trans_x_second(nanosecond, microsecond, Time) -> Time div 1000 rem 1000000;
|
||||||
|
do_trans_x_second(nanosecond, nanosecond, Time) -> Time rem 1000000000.
|
||||||
|
|
||||||
|
padding(Data, Len) when is_integer(Data) ->
|
||||||
|
padding(integer_to_list(Data), Len);
|
||||||
|
padding(Data, Len) when Len > 0 andalso erlang:length(Data) < Len ->
|
||||||
|
[$0 | padding(Data, Len - 1)];
|
||||||
|
padding(Data, _Len) ->
|
||||||
|
Data.
|
||||||
|
|
||||||
|
%% -------------------------------------------------------------------------------------------------
|
||||||
|
%% internal
|
||||||
|
%% parse part
|
||||||
|
|
||||||
|
do_parse(DateStr, Unit, Formatter) ->
|
||||||
|
DateInfo = do_parse_date_str(DateStr, Formatter, #{}),
|
||||||
|
{Precise, PrecisionUnit} = precision(DateInfo),
|
||||||
|
Counter =
|
||||||
|
fun
|
||||||
|
(year, V, Res) ->
|
||||||
|
Res + dy(V) * ?SECONDS_PER_DAY * Precise - (?SECONDS_FROM_0_TO_1970 * Precise);
|
||||||
|
(month, V, Res) ->
|
||||||
|
Res + dm(V) * ?SECONDS_PER_DAY * Precise;
|
||||||
|
(day, V, Res) ->
|
||||||
|
Res + (V * ?SECONDS_PER_DAY * Precise);
|
||||||
|
(hour, V, Res) ->
|
||||||
|
Res + (V * ?SECONDS_PER_HOUR * Precise);
|
||||||
|
(minute, V, Res) ->
|
||||||
|
Res + (V * ?SECONDS_PER_MINUTE * Precise);
|
||||||
|
(second, V, Res) ->
|
||||||
|
Res + V * Precise;
|
||||||
|
(millisecond, V, Res) ->
|
||||||
|
case PrecisionUnit of
|
||||||
|
millisecond ->
|
||||||
|
Res + V;
|
||||||
|
microsecond ->
|
||||||
|
Res + (V * 1000);
|
||||||
|
nanosecond ->
|
||||||
|
Res + (V * 1000000)
|
||||||
|
end;
|
||||||
|
(microsecond, V, Res) ->
|
||||||
|
case PrecisionUnit of
|
||||||
|
microsecond ->
|
||||||
|
Res + V;
|
||||||
|
nanosecond ->
|
||||||
|
Res + (V * 1000)
|
||||||
|
end;
|
||||||
|
(nanosecond, V, Res) ->
|
||||||
|
Res + V;
|
||||||
|
(parsed_offset, V, Res) ->
|
||||||
|
Res - V
|
||||||
|
end,
|
||||||
|
Count = maps:fold(Counter, 0, DateInfo) - (?SECONDS_PER_DAY * Precise),
|
||||||
|
erlang:convert_time_unit(Count, PrecisionUnit, Unit).
|
||||||
|
|
||||||
|
precision(#{nanosecond := _}) -> {1000_000_000, nanosecond};
|
||||||
|
precision(#{microsecond := _}) -> {1000_000, microsecond};
|
||||||
|
precision(#{millisecond := _}) -> {1000, millisecond};
|
||||||
|
precision(#{second := _}) -> {1, second};
|
||||||
|
precision(_) -> {1, second}.
|
||||||
|
|
||||||
|
do_parse_date_str(<<>>, _, Result) -> Result;
|
||||||
|
do_parse_date_str(_, [], Result) -> Result;
|
||||||
|
do_parse_date_str(Date, [Key | Formatter], Result) ->
|
||||||
|
Size = date_size(Key),
|
||||||
|
<<DatePart:Size/binary-unit:8, Tail/binary>> = Date,
|
||||||
|
case lists:member(Key, ?DATE_PART) of
|
||||||
|
true ->
|
||||||
|
do_parse_date_str(Tail, Formatter, Result#{Key => erlang:binary_to_integer(DatePart)});
|
||||||
|
false ->
|
||||||
|
case lists:member(Key, ?DATE_ZONE_NAME) of
|
||||||
|
true ->
|
||||||
|
do_parse_date_str(Tail, Formatter, Result#{parsed_offset => offset_second(DatePart)});
|
||||||
|
false ->
|
||||||
|
do_parse_date_str(Tail, Formatter, Result)
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
date_size(Str) when is_list(Str) -> erlang:length(Str);
|
||||||
|
date_size(year) -> 4;
|
||||||
|
date_size(month) -> 2;
|
||||||
|
date_size(day) -> 2;
|
||||||
|
date_size(hour) -> 2;
|
||||||
|
date_size(minute) -> 2;
|
||||||
|
date_size(second) -> 2;
|
||||||
|
date_size(millisecond) -> 3;
|
||||||
|
date_size(microsecond) -> 6;
|
||||||
|
date_size(nanosecond) -> 9;
|
||||||
|
date_size(timezone) -> 5;
|
||||||
|
date_size(timezone1) -> 6;
|
||||||
|
date_size(timezone2) -> 9.
|
||||||
|
|
||||||
|
dm(1) -> 0;
|
||||||
|
dm(2) -> 31;
|
||||||
|
dm(3) -> 59;
|
||||||
|
dm(4) -> 90;
|
||||||
|
dm(5) -> 120;
|
||||||
|
dm(6) -> 151;
|
||||||
|
dm(7) -> 181;
|
||||||
|
dm(8) -> 212;
|
||||||
|
dm(9) -> 243;
|
||||||
|
dm(10) -> 273;
|
||||||
|
dm(11) -> 304;
|
||||||
|
dm(12) -> 334.
|
||||||
|
|
|
@ -28,11 +28,27 @@
|
||||||
, gl % not interesting
|
, gl % not interesting
|
||||||
]).
|
]).
|
||||||
|
|
||||||
check_config(X) -> logger_formatter:check_config(X).
|
check_config(Config0) ->
|
||||||
|
Config = maps:without([date_format], Config0),
|
||||||
|
logger_formatter:check_config(Config).
|
||||||
|
|
||||||
format(#{msg := Msg0, meta := Meta} = Event, Config) ->
|
format(#{msg := Msg0, meta := Meta} = Event,
|
||||||
|
#{date_format := rfc3339, template := Template0} = Config) ->
|
||||||
Msg = maybe_merge(Msg0, Meta),
|
Msg = maybe_merge(Msg0, Meta),
|
||||||
logger_formatter:format(Event#{msg := Msg}, Config).
|
Template = [time | Template0],
|
||||||
|
logger_formatter:format(Event#{msg := Msg}, Config#{template => Template});
|
||||||
|
format(#{msg := Msg0, meta := Meta} = Event,
|
||||||
|
#{date_format := DFS} = Config) ->
|
||||||
|
Msg = maybe_merge(Msg0, Meta),
|
||||||
|
Time =
|
||||||
|
case maps:get(time, Event, undefined) of
|
||||||
|
undefined ->
|
||||||
|
erlang:system_time(microsecond);
|
||||||
|
T ->
|
||||||
|
T
|
||||||
|
end,
|
||||||
|
Date = emqx_calendar:format(Time, microsecond, local, DFS),
|
||||||
|
[Date | logger_formatter:format(Event#{msg := Msg}, Config)].
|
||||||
|
|
||||||
maybe_merge({report, Report}, Meta) when is_map(Report) ->
|
maybe_merge({report, Report}, Meta) when is_map(Report) ->
|
||||||
{report, maps:merge(Report, filter(Meta))};
|
{report, maps:merge(Report, filter(Meta))};
|
||||||
|
|
Loading…
Reference in New Issue