Add Logging support for WF 11/56711/2
authormojahidi <mojahidul.islam@amdocs.com>
Wed, 18 Jul 2018 09:44:50 +0000 (15:14 +0530)
committermojahidi <mojahidul.islam@amdocs.com>
Thu, 19 Jul 2018 08:22:31 +0000 (13:52 +0530)
Reverted changes of application.properties
Added logging supprt for workflow application

Change-Id: Ibdefa1f2bb42c4182821a95f130a7c3f3a01a7d9
Issue-ID: SDC-1530
Signed-off-by: mojahidi <mojahidul.islam@amdocs.com>
workflow/workflow-designer-be/pom.xml
workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/logging/LoggingInterceptor.java [new file with mode: 0644]
workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/logging/config/InterceptorConfig.java [new file with mode: 0644]
workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/logging/utils/LoggingUtils.java [new file with mode: 0644]
workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/logging/utils/Status.java [new file with mode: 0644]
workflow/workflow-designer-be/src/main/resources/logback.xml [new file with mode: 0644]

index b76dc46..3a88d4c 100644 (file)
             <artifactId>springfox-swagger2</artifactId>
             <version>${springfox.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.openecomp.sdc</groupId>
+            <artifactId>openecomp-sdc-logging-core</artifactId>
+            <version>${onap.version}</version>
+            <scope>runtime</scope>
+        </dependency>
         <dependency>
             <groupId>org.openecomp.sdc</groupId>
             <artifactId>openecomp-sdc-versioning-api</artifactId>
diff --git a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/logging/LoggingInterceptor.java b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/logging/LoggingInterceptor.java
new file mode 100644 (file)
index 0000000..f573112
--- /dev/null
@@ -0,0 +1,40 @@
+package org.onap.sdc.workflow.logging;
+
+import org.onap.sdc.workflow.logging.utils.LoggingUtils;
+import org.openecomp.sdc.logging.api.LoggingContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.lang.Nullable;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+import org.springframework.web.util.ContentCachingResponseWrapper;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@Component
+public class LoggingInterceptor extends HandlerInterceptorAdapter {
+
+    @Autowired
+    LoggingUtils loggingUtils;
+
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
+                                @Nullable Exception ex) throws Exception {
+        if (!(response instanceof ContentCachingResponseWrapper)) {
+            response = new ContentCachingResponseWrapper(response);
+        }
+        try {
+            loggingUtils.logResponse(request, response);
+        } finally {
+            LoggingContext.clear();
+        }
+    }
+
+    @Override
+    public boolean preHandle(HttpServletRequest request,
+                             HttpServletResponse response, Object object) throws Exception {
+        request.setAttribute(LoggingUtils.START_TIME_KEY, System.currentTimeMillis());
+        loggingUtils.logRequest(request);
+        return true;
+    }
+
+}
diff --git a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/logging/config/InterceptorConfig.java b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/logging/config/InterceptorConfig.java
new file mode 100644 (file)
index 0000000..a7d4617
--- /dev/null
@@ -0,0 +1,19 @@
+package org.onap.sdc.workflow.logging.config;
+
+import org.onap.sdc.workflow.logging.LoggingInterceptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class InterceptorConfig implements WebMvcConfigurer {
+
+    @Autowired
+    LoggingInterceptor loggingInterceptor;
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        registry.addInterceptor(loggingInterceptor);
+    }
+}
diff --git a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/logging/utils/LoggingUtils.java b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/logging/utils/LoggingUtils.java
new file mode 100644 (file)
index 0000000..10e4fb7
--- /dev/null
@@ -0,0 +1,87 @@
+package org.onap.sdc.workflow.logging.utils;
+
+import org.openecomp.sdc.logging.api.AuditData;
+import org.openecomp.sdc.logging.api.ContextData;
+import org.openecomp.sdc.logging.api.LoggerFactory;
+import org.openecomp.sdc.logging.api.LoggingContext;
+import org.openecomp.sdc.logging.api.StatusCode;
+import org.openecomp.sdc.logging.servlet.HttpHeader;
+import org.springframework.stereotype.Component;
+import  org.openecomp.sdc.logging.api.Logger;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.UUID;
+
+import static org.openecomp.sdc.logging.LoggingConstants.DEFAULT_PARTNER_NAME_HEADER;
+import static org.openecomp.sdc.logging.LoggingConstants.DEFAULT_REQUEST_ID_HEADER;
+import static org.openecomp.sdc.logging.api.StatusCode.COMPLETE;
+import static org.openecomp.sdc.logging.api.StatusCode.ERROR;
+
+@Component
+public class LoggingUtils {
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+    public static final String START_TIME_KEY = "audit.start.time";
+    private HttpHeader requestIdHeader = new HttpHeader(DEFAULT_REQUEST_ID_HEADER);
+    private HttpHeader partnerNameHeader = new HttpHeader(DEFAULT_PARTNER_NAME_HEADER);
+
+    public void logResponse(HttpServletRequest request, HttpServletResponse response) {
+        writeAudit(request, response);
+    }
+
+    private StatusCode getStatusCode(HttpServletResponse response) {
+        return isSuccess(response.getStatus()) ? COMPLETE : ERROR;
+    }
+
+    private String getReasonPhrase(int code) {
+        return Status.getReason(code);
+    }
+
+    private long getStartTime(HttpServletRequest request) {
+        return Long.class.cast(request.getAttribute(START_TIME_KEY));
+    }
+    public void logRequest(HttpServletRequest request) {
+        LoggingContext.clear();
+        ContextData.ContextDataBuilder contextData = ContextData.builder();
+        contextData.serviceName(createServiceName(request));
+
+        String partnerName = partnerNameHeader.getAny(request::getHeader);
+        if (partnerName != null) {
+            contextData.partnerName(partnerName);
+        }
+
+        String requestId = requestIdHeader.getAny(request::getHeader);
+        contextData.requestId(requestId == null ? UUID.randomUUID().toString() : requestId);
+
+        LoggingContext.put(contextData.build());
+    }
+
+    private String createServiceName(HttpServletRequest request) {
+        return request.getMethod() + " " + request.getServletPath();
+    }
+
+    private void writeAudit(HttpServletRequest request,
+                            HttpServletResponse response) {
+
+        if (!logger.isAuditEnabled()) {
+            return;
+        }
+
+        long start = getStartTime(request);
+        long end = System.currentTimeMillis();
+
+        int responseCode = response.getStatus();
+        StatusCode statusCode = getStatusCode(response);
+        AuditData auditData = AuditData.builder()
+                .startTime(start)
+                .endTime(end)
+                .statusCode(statusCode)
+                .responseCode(Integer.toString(responseCode))
+                .responseDescription(getReasonPhrase(responseCode))
+                .clientIpAddress(request.getRemoteAddr()).build();
+        logger.audit(auditData);
+    }
+
+    private boolean isSuccess(int responseCode) {
+        return responseCode > 199 && responseCode < 400;
+    }
+}
diff --git a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/logging/utils/Status.java b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/logging/utils/Status.java
new file mode 100644 (file)
index 0000000..07ca872
--- /dev/null
@@ -0,0 +1,57 @@
+package org.onap.sdc.workflow.logging.utils;
+
+public  enum Status {
+    OK(200, "OK"),
+    CREATED(201, "Created"),
+    ACCEPTED(202, "Accepted"),
+    NO_CONTENT(204, "No Content"),
+    RESET_CONTENT(205, "Reset Content"),
+    PARTIAL_CONTENT(206, "Partial Content"),
+    MOVED_PERMANENTLY(301, "Moved Permanently"),
+    FOUND(302, "Found"),
+    SEE_OTHER(303, "See Other"),
+    NOT_MODIFIED(304, "Not Modified"),
+    USE_PROXY(305, "Use Proxy"),
+    TEMPORARY_REDIRECT(307, "Temporary Redirect"),
+    BAD_REQUEST(400, "Bad Request"),
+    UNAUTHORIZED(401, "Unauthorized"),
+    PAYMENT_REQUIRED(402, "Payment Required"),
+    FORBIDDEN(403, "Forbidden"),
+    NOT_FOUND(404, "Not Found"),
+    METHOD_NOT_ALLOWED(405, "Method Not Allowed"),
+    NOT_ACCEPTABLE(406, "Not Acceptable"),
+    PROXY_AUTHENTICATION_REQUIRED(407, "Proxy Authentication Required"),
+    REQUEST_TIMEOUT(408, "Request Timeout"),
+    CONFLICT(409, "Conflict"),
+    GONE(410, "Gone"),
+    LENGTH_REQUIRED(411, "Length Required"),
+    PRECONDITION_FAILED(412, "Precondition Failed"),
+    REQUEST_ENTITY_TOO_LARGE(413, "Request Entity Too Large"),
+    REQUEST_URI_TOO_LONG(414, "Request-URI Too Long"),
+    UNSUPPORTED_MEDIA_TYPE(415, "Unsupported Media Type"),
+    REQUESTED_RANGE_NOT_SATISFIABLE(416, "Requested Range Not Satisfiable"),
+    EXPECTATION_FAILED(417, "Expectation Failed"),
+    INTERNAL_SERVER_ERROR(500, "Internal Server Error"),
+    NOT_IMPLEMENTED(501, "Not Implemented"),
+    BAD_GATEWAY(502, "Bad Gateway"),
+    SERVICE_UNAVAILABLE(503, "Service Unavailable"),
+    GATEWAY_TIMEOUT(504, "Gateway Timeout"),
+    HTTP_VERSION_NOT_SUPPORTED(505, "HTTP Version Not Supported");
+
+    private final int code;
+    private final String reason;
+
+    Status(int statusCode, String reasonPhrase) {
+        this.code = statusCode;
+        this.reason = reasonPhrase;
+    }
+
+    public static String getReason(int code) {
+        for(Status status : Status.values()) {
+            if(status.code == code)
+                return status.reason;
+        }
+        return null;
+    }
+
+}
diff --git a/workflow/workflow-designer-be/src/main/resources/logback.xml b/workflow/workflow-designer-be/src/main/resources/logback.xml
new file mode 100644 (file)
index 0000000..6f33b86
--- /dev/null
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<configuration scan="true" scanPeriod="5 seconds">
+    <property scope="system" name="ONAP-component-name" value="workflow-designer" />
+         <property scope="system" name="ONAP-subcomponent-name" value="be" />
+    <property name="log.location" value="logs"/>
+
+
+    <!-- Error log -->
+    <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
+
+        <file>${log.location}/error.log</file>
+
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>INFO</level>
+        </filter>
+
+        <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
+            <evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
+                <marker>AUDIT</marker>
+            </evaluator>
+            <onMismatch>NEUTRAL</onMismatch>
+            <onMatch>DENY</onMatch>
+        </filter>
+
+        <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
+            <evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
+                <marker>METRICS</marker>
+            </evaluator>
+            <onMismatch>NEUTRAL</onMismatch>
+            <onMatch>DENY</onMatch>
+        </filter>
+
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>${log.location}/error.log.%i
+            </fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>10</maxIndex>
+        </rollingPolicy>
+
+        <triggeringPolicy
+          class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>20MB</maxFileSize>
+        </triggeringPolicy>
+
+        <encoder>
+            <pattern>
+                %d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%X{RequestId}|%thread||%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%level||%X{ErrorCode}|%X{ErrorDescription}|%msg%n
+            </pattern>
+        </encoder>
+    </appender>
+
+
+    <appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
+
+        <file>${log.location}/debug.log</file>
+
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>DEBUG</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>${log.location}/debug.log.%i
+            </fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>10</maxIndex>
+        </rollingPolicy>
+
+        <triggeringPolicy
+          class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>20MB</maxFileSize>
+        </triggeringPolicy>
+
+        <encoder>
+            <pattern>
+                %d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%X{RequestId}|%msg%n
+            </pattern>
+        </encoder>
+    </appender>
+
+    <!-- Asynchronicity Configurations -->
+    <appender name="ASYNC_DEBUG" class="ch.qos.logback.classic.AsyncAppender">
+        <appender-ref ref="DEBUG" />
+    </appender>
+
+    <appender name="AUDIT" class="ch.qos.logback.core.rolling.RollingFileAppender">
+
+        <file>${log.location}/audit.log</file>
+
+        <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
+            <evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
+                <marker>AUDIT</marker>
+            </evaluator>
+            <onMismatch>DENY</onMismatch>
+            <onMatch>ACCEPT</onMatch>
+        </filter>
+
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>${log.location}/audit.log.%i
+            </fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>10</maxIndex>
+        </rollingPolicy>
+
+        <triggeringPolicy
+          class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>20MB</maxFileSize>
+        </triggeringPolicy>
+
+        <encoder>
+            <pattern>
+                %X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread||%X{ServiceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceId}|%level||%X{ServerIpAddress}|%X{ElapsedTime}|%X{Server}|%X{ClientIpAddress}||||||||%msg%n
+            </pattern>
+        </encoder>
+    </appender>
+
+    <appender name="METRICS" class="ch.qos.logback.core.rolling.RollingFileAppender">
+
+        <file>${log.location}/metrics.log</file>
+
+        <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
+            <evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
+                <marker>METRICS</marker>
+            </evaluator>
+            <onMismatch>DENY</onMismatch>
+            <onMatch>ACCEPT</onMatch>
+        </filter>
+
+        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+            <fileNamePattern>${log.location}/metrics.log.%i
+            </fileNamePattern>
+            <minIndex>1</minIndex>
+            <maxIndex>10</maxIndex>
+        </rollingPolicy>
+
+        <triggeringPolicy
+          class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+            <maxFileSize>20MB</maxFileSize>
+        </triggeringPolicy>
+
+        <encoder>
+            <pattern>
+                %X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread||%X{ServiceName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceId}|%level||%X{ServerIpAddress}|%X{ElapsedTime}|%X{Server}|%X{ClientIpAddress}||||||||||%msg%n
+            </pattern>
+        </encoder>
+    </appender>
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>
+                %X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread||%X{ServiceName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceId}|%level||%X{ServerIpAddress}|%X{ElapsedTime}|%X{Server}|%X{ClientIpAddress}||||||||||%msg%n
+            </pattern>
+        </encoder>
+    </appender>
+
+    <root level="INFO">
+        <appender-ref ref="ERROR"/>
+        <appender-ref ref="ASYNC_DEBUG"/>
+        <appender-ref ref="AUDIT"/>
+        <appender-ref ref="METRICS"/>
+        <appender-ref ref="STDOUT"/>
+    </root>
+    <logger name="org.springframework.web.filter.CommonsRequestLoggingFilter">
+        <level value="DEBUG" />
+    </logger>
+</configuration>
\ No newline at end of file