From 1cfb08779ea0e00be69e072a940b3063e049fe6b Mon Sep 17 00:00:00 2001 From: Ofir Sonsino Date: Wed, 31 Jan 2018 17:19:00 +0200 Subject: org.onap migration Change-Id: I52f0b2851f2c765752b6d21f49b32136d7d72a3d Issue-ID: VID-86 Signed-off-by: Ofir Sonsino --- .../org/onap/vid/controller/LoggerController.java | 115 +++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 vid-app-common/src/main/java/org/onap/vid/controller/LoggerController.java (limited to 'vid-app-common/src/main/java/org/onap/vid/controller/LoggerController.java') diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/LoggerController.java b/vid-app-common/src/main/java/org/onap/vid/controller/LoggerController.java new file mode 100644 index 000000000..e70c87115 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/controller/LoggerController.java @@ -0,0 +1,115 @@ +package org.onap.vid.controller; + +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.core.Appender; +import ch.qos.logback.core.FileAppender; +import ch.qos.logback.core.spi.AppenderAttachable; +import org.apache.commons.io.input.ReversedLinesFileReader; +import org.apache.commons.lang3.StringUtils; +import org.openecomp.portalsdk.core.controller.RestrictedBaseController; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.vid.model.ExceptionResponse; +import org.onap.vid.roles.Role; +import org.onap.vid.roles.RoleProvider; +import org.onap.vid.utils.Streams; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.InternalServerErrorException; +import javax.ws.rs.NotAuthorizedException; +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Objects; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static com.att.eelf.configuration.Configuration.GENERAL_LOGGER_NAME; + + +@RestController +@RequestMapping("logger") +public class LoggerController extends RestrictedBaseController { + + private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(LoggerController.class); + + @Autowired + RoleProvider roleProvider; + + @RequestMapping(value = "/{loggerName:audit|error|metrics}", method = RequestMethod.GET) + public String getLog(@PathVariable String loggerName, HttpServletRequest request, + @RequestParam(value="limit", defaultValue = "5000") Integer limit) throws IOException { + + List roles = roleProvider.getUserRoles(request); + boolean userPermitted = roleProvider.userPermissionIsReadLogs(roles); + if (!userPermitted) { + throw new NotAuthorizedException("User not authorized to get logs"); + } + + String logfilePath = getLogfilePath(loggerName); + + try (final ReversedLinesFileReader reader = new ReversedLinesFileReader(new File(logfilePath))) { + Supplier reverseLinesSupplier = () -> { + try { + return reader.readLine(); + } catch (NullPointerException e) { + // EOF Reached + return null; + } catch (IOException e) { + throw new InternalServerErrorException("error while reading " + logfilePath, e); + } + }; + + return Streams.takeWhile( + Stream.generate(reverseLinesSupplier), + line -> !StringUtils.contains(line, "Logging is started")) + .limit(limit) + .limit(5_000) + .filter(Objects::nonNull) + .collect(Collectors.joining("\n")); + } + } + + private String getLogfilePath(String loggerName) { + /* + Find the requested logger, and pull all of it's appenders. + Find the first of the appenders that is a FileAppender, and return it's + write-out filename. + */ + LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + return context.getLoggerList().stream() + .filter(logger -> logger.getName().equals(GENERAL_LOGGER_NAME + "." + loggerName)) + .flatMap(this::pullSubAppenders) + .flatMap(appender -> { + // Appender might be "attachable", if so - roll-up its sub-appenders + return (appender instanceof AppenderAttachable) ? + pullSubAppenders((AppenderAttachable) appender) : Stream.of(appender); + }) + .filter(appender -> appender instanceof FileAppender) + .map(appender -> (FileAppender) appender) + .map(FileAppender::getFile) + .findFirst() + .orElseThrow(() -> new InternalServerErrorException("logfile for " + loggerName + " not found")); + } + + private Stream> pullSubAppenders(AppenderAttachable logger) { + return Streams.fromIterator(logger.iteratorForAppenders()); + } + + @ExceptionHandler({ NotAuthorizedException.class }) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public String notAuthorizedHandler(NotAuthorizedException e) { + return "UNAUTHORIZED"; + } + + @ExceptionHandler({ IOException.class, InternalServerErrorException.class }) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public ExceptionResponse ioExceptionHandler(Exception e) { + return org.onap.vid.controller.ControllersUtils.handleException(e, LOGGER); + } + +} -- cgit 1.2.3-korg