diff --git a/apps/efka/include/message_pb.hrl b/apps/efka/include/message_pb.hrl index 4368a5a..461a809 100644 --- a/apps/efka/include/message_pb.hrl +++ b/apps/efka/include/message_pb.hrl @@ -83,9 +83,9 @@ -record(data, {service_id = <<>> :: unicode:chardata() | undefined, % = 1, optional device_uuid = <<>> :: unicode:chardata() | undefined, % = 2, optional - format = <<>> :: unicode:chardata() | undefined, % = 3, optional - metric = <<>> :: unicode:chardata() | undefined, % = 4, optional - route_key = <<>> :: unicode:chardata() | undefined % = 5, optional + route_key = <<>> :: unicode:chardata() | undefined, % = 3, optional + format = <<>> :: unicode:chardata() | undefined, % = 4, optional + metric = <<>> :: unicode:chardata() | undefined % = 5, optional }). -endif. diff --git a/apps/efka/src/efka_remote_agent.erl b/apps/efka/src/efka_remote_agent.erl index f3d401d..d35eb80 100644 --- a/apps/efka/src/efka_remote_agent.erl +++ b/apps/efka/src/efka_remote_agent.erl @@ -16,7 +16,7 @@ %% API -export([start_link/0]). --export([metric_data/4, event/3, ping/13, request_service_config/2, await_reply/2]). +-export([metric_data/5, event/3, ping/13, request_service_config/2, await_reply/2]). %% gen_statem callbacks -export([init/1, handle_event/4, terminate/3, code_change/4, callback_mode/0]). @@ -46,9 +46,9 @@ %%%=================================================================== %% 发送数据 --spec metric_data(ServiceId :: binary(), DeviceUUID::binary(), RouteKey :: binary(), LineProtocolData :: binary()) -> no_return(). -metric_data(ServiceId, DeviceUUID, RouteKey, LineProtocolData) when is_binary(ServiceId), is_binary(DeviceUUID), is_binary(RouteKey), is_binary(LineProtocolData) -> - gen_statem:cast(?SERVER, {metric_data, ServiceId, DeviceUUID, RouteKey, LineProtocolData}). +-spec metric_data(ServiceId :: binary(), DeviceUUID::binary(), RouteKey :: binary(), Format :: binary(), Metric :: binary()) -> no_return(). +metric_data(ServiceId, DeviceUUID, RouteKey, Format, Metric) when is_binary(ServiceId), is_binary(DeviceUUID), is_binary(RouteKey), is_binary(Format), is_binary(Metric) -> + gen_statem:cast(?SERVER, {metric_data, ServiceId, DeviceUUID, RouteKey, Format, Metric}). -spec event(ServiceId :: binary(), EventType :: integer(), Params :: binary()) -> no_return(). event(ServiceId, EventType, Params) when is_binary(ServiceId), is_integer(EventType), is_binary(Params) -> @@ -108,12 +108,13 @@ handle_event({call, From}, {request_service_config, _ReceiverPid, _ServiceId}, _ {keep_state, State, [{reply, From, {error, <<"transport is not alive">>}}]}; %% 异步发送数据, 连接存在时候直接发送;否则缓存到mnesia -handle_event(cast, {metric_data, ServiceId, DeviceUUID, RouteKey, LineProtocolData}, ?STATE_ACTIVATED, State = #state{transport_pid = TransportPid}) -> +handle_event(cast, {metric_data, ServiceId, DeviceUUID, RouteKey, Format, Metric}, ?STATE_ACTIVATED, State = #state{transport_pid = TransportPid}) -> Packet = message_pb:encode_msg(#data{ service_id = ServiceId, device_uuid = DeviceUUID, route_key = RouteKey, - metric = LineProtocolData + format = Format, + metric = Metric }), efka_transport:send(TransportPid, ?METHOD_DATA, Packet), {keep_state, State}; diff --git a/apps/efka/src/efka_service.erl b/apps/efka/src/efka_service.erl index 48a2321..a76a52b 100644 --- a/apps/efka/src/efka_service.erl +++ b/apps/efka/src/efka_service.erl @@ -18,7 +18,7 @@ -export([start_link/2]). -export([get_name/1, get_pid/1, attach_channel/2]). -export([push_config/3, request_config/1, invoke/3]). --export([metric_data/4, send_event/3]). +-export([metric_data/5, send_event/3]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). @@ -63,9 +63,9 @@ invoke(Pid, Ref, Payload) when is_pid(Pid), is_reference(Ref), is_binary(Payload request_config(Pid) when is_pid(Pid) -> gen_server:call(Pid, request_config). --spec metric_data(Pid :: pid(), DeviceUUID :: binary(), RouteKey :: binary(), Data :: binary()) -> no_return(). -metric_data(Pid, DeviceUUID, RouteKey, Data) when is_pid(Pid), is_binary(DeviceUUID), is_binary(RouteKey), is_binary(Data) -> - gen_server:cast(Pid, {metric_data, DeviceUUID, RouteKey, Data}). +-spec metric_data(Pid :: pid(), DeviceUUID :: binary(), RouteKey :: binary(), Format :: binary(), Metric :: binary()) -> no_return(). +metric_data(Pid, DeviceUUID, RouteKey, Format, Metric) when is_pid(Pid), is_binary(DeviceUUID), is_binary(RouteKey), is_binary(Format), is_binary(Metric) -> + gen_server:cast(Pid, {metric_data, DeviceUUID, RouteKey, Format, Metric}). -spec send_event(Pid :: pid(), EventType :: integer(), Params :: binary()) -> no_return(). send_event(Pid, EventType, Params) when is_pid(Pid), is_integer(EventType), is_binary(Params) -> @@ -155,9 +155,9 @@ handle_call(_Request, _From, State = #state{}) -> {noreply, NewState :: #state{}} | {noreply, NewState :: #state{}, timeout() | hibernate} | {stop, Reason :: term(), NewState :: #state{}}). -handle_cast({metric_data, DeviceUUID, RouteKey, LineProtocolData}, State = #state{service_id = ServiceId}) -> - lager:debug("[efka_service] metric_data service_id: ~p, device_uuid: ~p, route_key: ~p, metric data: ~p", [ServiceId, DeviceUUID, RouteKey, LineProtocolData]), - efka_remote_agent:metric_data(ServiceId, DeviceUUID, RouteKey, LineProtocolData), +handle_cast({metric_data, DeviceUUID, RouteKey, Format, Metric}, State = #state{service_id = ServiceId}) -> + lager:debug("[efka_service] metric_data service_id: ~p, device_uuid: ~p, route_key: ~p, metric data: ~p", [ServiceId, DeviceUUID, RouteKey, Metric]), + efka_remote_agent:metric_data(ServiceId, DeviceUUID, RouteKey, Format, Metric), {noreply, State}; handle_cast({send_event, EventType, Params}, State = #state{service_id = ServiceId}) -> diff --git a/apps/efka/src/proto/message_pb.erl b/apps/efka/src/proto/message_pb.erl index df0dcab..c6dc024 100644 --- a/apps/efka/src/proto/message_pb.erl +++ b/apps/efka/src/proto/message_pb.erl @@ -382,7 +382,7 @@ encode_msg_push_service_config(#push_service_config{service_id = F1, config_json encode_msg_data(Msg, TrUserData) -> encode_msg_data(Msg, <<>>, TrUserData). -encode_msg_data(#data{service_id = F1, device_uuid = F2, format = F3, metric = F4, route_key = F5}, Bin, TrUserData) -> +encode_msg_data(#data{service_id = F1, device_uuid = F2, route_key = F3, format = F4, metric = F5}, Bin, TrUserData) -> B1 = if F1 == undefined -> Bin; true -> begin @@ -1293,10 +1293,10 @@ decode_msg_data(Bin, TrUserData) -> dfp_read_field_def_data(Bin, 0, 0, 0, id(<<> dfp_read_field_def_data(<<10, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_data_service_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); dfp_read_field_def_data(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_data_device_uuid(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_data(<<26, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_data_format(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_data(<<34, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_data_metric(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_data(<<42, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_data_route_key(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -dfp_read_field_def_data(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, _) -> #data{service_id = F@_1, device_uuid = F@_2, format = F@_3, metric = F@_4, route_key = F@_5}; +dfp_read_field_def_data(<<26, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_data_route_key(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +dfp_read_field_def_data(<<34, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_data_format(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +dfp_read_field_def_data(<<42, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_data_metric(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +dfp_read_field_def_data(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, _) -> #data{service_id = F@_1, device_uuid = F@_2, route_key = F@_3, format = F@_4, metric = F@_5}; dfp_read_field_def_data(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dg_read_field_def_data(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData). dg_read_field_def_data(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 32 - 7 -> dg_read_field_def_data(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); @@ -1305,9 +1305,9 @@ dg_read_field_def_data(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F case Key of 10 -> d_field_data_service_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); 18 -> d_field_data_device_uuid(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 26 -> d_field_data_format(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 34 -> d_field_data_metric(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); - 42 -> d_field_data_route_key(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 26 -> d_field_data_route_key(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 34 -> d_field_data_format(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); + 42 -> d_field_data_metric(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); _ -> case Key band 7 of 0 -> skip_varint_data(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); @@ -1317,7 +1317,7 @@ dg_read_field_def_data(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F 5 -> skip_32_data(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) end end; -dg_read_field_def_data(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, _) -> #data{service_id = F@_1, device_uuid = F@_2, format = F@_3, metric = F@_4, route_key = F@_5}. +dg_read_field_def_data(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, _) -> #data{service_id = F@_1, device_uuid = F@_2, route_key = F@_3, format = F@_4, metric = F@_5}. d_field_data_service_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_data_service_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); d_field_data_service_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, F@_5, TrUserData) -> @@ -1329,18 +1329,18 @@ d_field_data_device_uuid(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@ {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, dfp_read_field_def_data(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, F@_5, TrUserData). -d_field_data_format(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_data_format(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_data_format(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, F@_5, TrUserData) -> +d_field_data_route_key(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_data_route_key(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +d_field_data_route_key(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, F@_5, TrUserData) -> {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, dfp_read_field_def_data(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, F@_5, TrUserData). -d_field_data_metric(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_data_metric(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_data_metric(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, F@_5, TrUserData) -> +d_field_data_format(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_data_format(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +d_field_data_format(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, F@_5, TrUserData) -> {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, dfp_read_field_def_data(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, F@_5, TrUserData). -d_field_data_route_key(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_data_route_key(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); -d_field_data_route_key(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, _, TrUserData) -> +d_field_data_metric(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_data_metric(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData); +d_field_data_metric(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, _, TrUserData) -> {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, dfp_read_field_def_data(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, NewFValue, TrUserData). @@ -1949,8 +1949,8 @@ merge_msg_push_service_config(#push_service_config{service_id = PFservice_id, co end}. -compile({nowarn_unused_function,merge_msg_data/3}). -merge_msg_data(#data{service_id = PFservice_id, device_uuid = PFdevice_uuid, format = PFformat, metric = PFmetric, route_key = PFroute_key}, - #data{service_id = NFservice_id, device_uuid = NFdevice_uuid, format = NFformat, metric = NFmetric, route_key = NFroute_key}, _) -> +merge_msg_data(#data{service_id = PFservice_id, device_uuid = PFdevice_uuid, route_key = PFroute_key, format = PFformat, metric = PFmetric}, + #data{service_id = NFservice_id, device_uuid = NFdevice_uuid, route_key = NFroute_key, format = NFformat, metric = NFmetric}, _) -> #data{service_id = if NFservice_id =:= undefined -> PFservice_id; true -> NFservice_id @@ -1959,6 +1959,10 @@ merge_msg_data(#data{service_id = PFservice_id, device_uuid = PFdevice_uuid, for if NFdevice_uuid =:= undefined -> PFdevice_uuid; true -> NFdevice_uuid end, + route_key = + if NFroute_key =:= undefined -> PFroute_key; + true -> NFroute_key + end, format = if NFformat =:= undefined -> PFformat; true -> NFformat @@ -1966,10 +1970,6 @@ merge_msg_data(#data{service_id = PFservice_id, device_uuid = PFdevice_uuid, for metric = if NFmetric =:= undefined -> PFmetric; true -> NFmetric - end, - route_key = - if NFroute_key =:= undefined -> PFroute_key; - true -> NFroute_key end}. -compile({nowarn_unused_function,merge_msg_ping/3}). @@ -2223,7 +2223,7 @@ v_msg_push_service_config(X, Path, _TrUserData) -> mk_type_error({expected_msg, -compile({nowarn_unused_function,v_msg_data/3}). -dialyzer({nowarn_function,v_msg_data/3}). -v_msg_data(#data{service_id = F1, device_uuid = F2, format = F3, metric = F4, route_key = F5}, Path, TrUserData) -> +v_msg_data(#data{service_id = F1, device_uuid = F2, route_key = F3, format = F4, metric = F5}, Path, TrUserData) -> if F1 == undefined -> ok; true -> v_type_string(F1, [service_id | Path], TrUserData) end, @@ -2231,13 +2231,13 @@ v_msg_data(#data{service_id = F1, device_uuid = F2, format = F3, metric = F4, ro true -> v_type_string(F2, [device_uuid | Path], TrUserData) end, if F3 == undefined -> ok; - true -> v_type_string(F3, [format | Path], TrUserData) + true -> v_type_string(F3, [route_key | Path], TrUserData) end, if F4 == undefined -> ok; - true -> v_type_string(F4, [metric | Path], TrUserData) + true -> v_type_string(F4, [format | Path], TrUserData) end, if F5 == undefined -> ok; - true -> v_type_string(F5, [route_key | Path], TrUserData) + true -> v_type_string(F5, [metric | Path], TrUserData) end, ok; v_msg_data(X, Path, _TrUserData) -> mk_type_error({expected_msg, data}, X, Path). @@ -2436,9 +2436,9 @@ get_msg_defs() -> {{msg, data}, [#field{name = service_id, fnum = 1, rnum = 2, type = string, occurrence = optional, opts = []}, #field{name = device_uuid, fnum = 2, rnum = 3, type = string, occurrence = optional, opts = []}, - #field{name = format, fnum = 3, rnum = 4, type = string, occurrence = optional, opts = []}, - #field{name = metric, fnum = 4, rnum = 5, type = string, occurrence = optional, opts = []}, - #field{name = route_key, fnum = 5, rnum = 6, type = string, occurrence = optional, opts = []}]}, + #field{name = route_key, fnum = 3, rnum = 4, type = string, occurrence = optional, opts = []}, + #field{name = format, fnum = 4, rnum = 5, type = string, occurrence = optional, opts = []}, + #field{name = metric, fnum = 5, rnum = 6, type = string, occurrence = optional, opts = []}]}, {{msg, ping}, [#field{name = adcode, fnum = 1, rnum = 2, type = string, occurrence = optional, opts = []}, #field{name = boot_time, fnum = 2, rnum = 3, type = uint32, occurrence = optional, opts = []}, @@ -2516,9 +2516,9 @@ find_msg_def(push_service_config) -> find_msg_def(data) -> [#field{name = service_id, fnum = 1, rnum = 2, type = string, occurrence = optional, opts = []}, #field{name = device_uuid, fnum = 2, rnum = 3, type = string, occurrence = optional, opts = []}, - #field{name = format, fnum = 3, rnum = 4, type = string, occurrence = optional, opts = []}, - #field{name = metric, fnum = 4, rnum = 5, type = string, occurrence = optional, opts = []}, - #field{name = route_key, fnum = 5, rnum = 6, type = string, occurrence = optional, opts = []}]; + #field{name = route_key, fnum = 3, rnum = 4, type = string, occurrence = optional, opts = []}, + #field{name = format, fnum = 4, rnum = 5, type = string, occurrence = optional, opts = []}, + #field{name = metric, fnum = 5, rnum = 6, type = string, occurrence = optional, opts = []}]; find_msg_def(ping) -> [#field{name = adcode, fnum = 1, rnum = 2, type = string, occurrence = optional, opts = []}, #field{name = boot_time, fnum = 2, rnum = 3, type = uint32, occurrence = optional, opts = []}, diff --git a/message_pb.proto b/message_pb.proto index c042629..9c27553 100644 --- a/message_pb.proto +++ b/message_pb.proto @@ -19,7 +19,7 @@ message AuthReply { // service_id主动订阅消息, 基于广播通讯 message Pub { string topic = 1; - string content = 2; + bytes content = 2; } ///// 服务器主动推送的消息 @@ -46,7 +46,7 @@ message FetchTaskLog { // 需要响应, 云端主动发起的调用; 提供给用户 message Invoke { string service_id = 1; - string payload = 2; + bytes payload = 2; uint32 timeout = 3; } @@ -63,11 +63,9 @@ message PushServiceConfig { message Data { string service_id = 1; string device_uuid = 2; - // 数据格式: json, line - string format = 3; + string route_key = 3; // measurement[,tag_key=tag_value...] field_key=field_value[,field_key2=field_value2...] [timestamp] - string metric = 4; - string route_key = 5; + bytes metric = 4; } //#{<<"adcode">> => 0,<<"boot_time">> => 18256077,<<"city">> => <<>>,