aboutsummaryrefslogtreecommitdiffstats
path: root/src/logging.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/logging.erl')
-rw-r--r--src/logging.erl157
1 files changed, 157 insertions, 0 deletions
diff --git a/src/logging.erl b/src/logging.erl
new file mode 100644
index 0000000..942637d
--- /dev/null
+++ b/src/logging.erl
@@ -0,0 +1,157 @@
+% ============LICENSE_START=======================================================
+% org.onap.dcae
+% ================================================================================
+% Copyright (c) 2017 AT&T Intellectual Property. 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.
+% ============LICENSE_END=========================================================
+%
+% ECOMP is a trademark and service mark of AT&T Intellectual Property.
+
+-module(logging).
+-export([
+ audit/3,
+ metrics/3,
+ err/2
+ ]).
+
+-import(util, [iso/0, iso_elapsed/2, to_str/1, ip_to_str/1]).
+%..lazy macros
+-define(SC(L), util:concat(L)).
+-define(PV(Name, PL), proplists:get_value(Name, PL, "")).
+
+%This module is intended to support the logging format standard for ONAP/ECOMP components. SOmetimes that is reffered to as "EELF".
+
+%levels are none | debug | info | notice | warning | error | critical | alert | emergency.
+
+%%%
+%%%Helper functions
+%%%
+pid() -> pid_to_list(self()).
+%they wanted milleseconds but they are getting seconds rounded to ms because I don't have an erlang BIF that gives me this
+elapsed(Endtime, Starttime) -> to_str(iso_elapsed(Endtime, Starttime)*1000).
+
+start_end_elapsed(ArgPropl) ->
+ %returns start time, end time,... and elapsed time
+ EndT = iso(),
+ StartT = ?PV(bts, ArgPropl),
+ ElapT = elapsed(EndT, StartT),
+ {StartT, EndT, ElapT}.
+
+%things this logging class can compute based on the Req so need not be in every logging function
+server_add(Req) ->
+ {MyUrl, _} = cowboy_req:host_url((leptus_req:get_req(Req))),
+ %discard HTTP portion using Erlang binary matching
+ <<_:7/binary, URL/binary>> = MyUrl,
+ URL.
+
+ip(Req) -> ip_to_str(leptus_req:peer(Req)).
+
+path(Req) ->
+ %get us the method and API path that was hit from the request
+ {Path, {_,_,_,_,_,Method,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_}} = cowboy_req:path(leptus_req:get_req(Req)),
+ ?SC([Method, " ", Path]).
+
+%%%
+%%%External
+%%%
+
+audit(Sev, Req, ArgPropl) ->
+ F = case Sev of
+ info -> fun(M)->audit:info(M) end; %cant use the shorthand "fun -> audit:info/2" because of parse_transform
+ warning -> fun(M)->audit:warning(M) end
+ end,
+ %The audit field list:
+ %
+ %1 BeginTimestamp Implemented (bts)
+ %2 EndTimestamp Auto Injected when this is called
+ %3 RequestID Implemented (xer)
+ %4 serviceInstanceID
+ %5 threadId Auto Injected... however this is a VM language and so this is the Erlang process PID, not the "OS level thread id". Unclear what they want here.
+ %6 physical/virtual server nameĀ 
+ %7 serviceName Implemented (from Req)
+ %8 PartnerName
+ %9 StatusCode
+ %10 ResponseCode Implemented (rcode)
+ %11 Response Description Will not implement. This says "human readable description of the *code*. They don't want the response here. I won't do that because this is a generic function that gets called no matter what the code is, so I can't do that. But since this is supposed to be human readable, they can look up the code in the swagger spec.
+ %12 instanceUUID
+ %13 Category log level Implemented (Sev)
+ %14 Severity
+ %15 Server IP address Implemented (from Req)
+ %16 ElapsedTime Auto Injected but THIS IS SO DUMB TO BE IN THE STANDARD WASTING DISK SPACE THIS IS DIRECTLY COMPUTABLE FROM 1,2 WTF
+ %17 Server
+ %18 ClientIPaddress Implemented (from Req)
+ %19 class name Implemented (mod), though docs say OOP, I am using the Erlang module here
+ %20 Unused Implemented..
+ %21 ProcessKey
+ %22 CustomField1
+ %23 CustomField2
+ %24 CustomField3
+ %25 CustomField4
+ %26 detailMessage Implemented (msg)
+
+ {StartT, EndT, ElapT} = start_end_elapsed(ArgPropl),
+ %compute message
+ Message = ?SC([StartT, "|", EndT, "|", ?PV(xer, ArgPropl), "||", pid(), "||", path(Req), "|||", to_str(?PV(rcode, ArgPropl)), "|see swagger spec||", to_str(Sev), "||", server_add(Req), "|", ElapT, "||", ip(Req), "|", ?PV(mod, ArgPropl), "|||||||", ?PV(msg, ArgPropl)]),
+ F(Message).
+
+metrics(Sev, Req, ArgPropl) ->
+ F = case Sev of
+ debug -> fun(M)->metrics:debug(M) end;
+ info -> fun(M)->metrics:info(M) end;
+ warning -> fun(M)->metrics:warning(M) end
+ end,
+ %The metrics field list:
+ %SAME AS METRICS 1-8
+ %_____
+ %9 TargetEntity Implemented (tgte)
+ %10 TargetServiceName Implemented (tgts)
+ %11 Status Code Implemented (tgtrsc)
+ %_____
+ %SAME AS METRICS 9 ->
+ %total 29 fields
+
+ {StartT, EndT, ElapT} = start_end_elapsed(ArgPropl),
+ %compute message
+ Message = ?SC([StartT, "|", EndT, "|", ?PV(xer, ArgPropl), "||", pid(), "||", path(Req), "||", ?PV(tgte, ArgPropl), "|", ?PV(tgts, ArgPropl), "|", to_str(?PV(tgtrsc, ArgPropl)), "|", to_str(?PV(rcode, ArgPropl)), "|see swagger spec||", to_str(Sev), "||", server_add(Req), "|", ElapT, "||", ip(Req), "|", ?PV(mod, ArgPropl), "||||||||", ?PV(msg, ArgPropl)]),
+ F(Message).
+
+err(Sev, ArgPropl) ->
+ F = case Sev of
+ warning -> fun(M)->error:warning(M) end;
+ error -> fun(M)->error:error(M) end;
+ critical -> fun(M)->error:critical(M) end;
+ alert -> fun(M)->error:alert(M) end;
+ emergency -> fun(M)->error:emergency(M) end
+ end,
+ SevInLog = case Sev of
+ warning -> "WARN";
+ error -> "ERROR";
+ _ -> "FATAL"
+ end,
+ %Error field list:
+ %1 Timestamp Auto Injected when this is called
+ %2 RequestID Implemented
+ %3 ThreadId Auto Injected... however this is a VM language and so this is the Erlang thread PID. Not the "OS level pid". Unclear what they want here.
+ %4 ServiceName Implemented
+ %5 PartnerName
+ %6 TargetEntity
+ %7 TargetServiceName
+ %8 ErrorCategory Implemented
+ %9 ErrorCode
+ %10 ErrorDescription This is what I'm using detailMessage for, these seem to be the same to me.
+ %11 detailMessage Implemented
+
+ Message = ?SC([iso(), "|", ?PV(xer, ArgPropl), "|", pid(), "|", ?PV(servn, ArgPropl), "||||", SevInLog, "|||", ?PV(msg, ArgPropl)]),
+ F(Message).
+