Package org.wso2.carbon.logging.util

Source Code of org.wso2.carbon.logging.util.LoggingReader

/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* 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.
*/
package org.wso2.carbon.logging.util;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.axiom.om.OMElement;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.logging.config.ServiceConfigManager;
import org.wso2.carbon.logging.config.SyslogConfigManager;
import org.wso2.carbon.logging.config.SyslogConfiguration;
import org.wso2.carbon.logging.internal.LoggingServiceComponent;
import org.wso2.carbon.logging.service.LogViewerException;
import org.wso2.carbon.logging.service.data.LogInfo;
import org.wso2.carbon.logging.service.data.LogMessage;
import org.wso2.carbon.logging.service.data.SyslogData;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.core.tenant.TenantManager;
import org.wso2.carbon.utils.CarbonUtils;

/**
* This is the Log Reader class to read log messages from remote/local file
* systems
*/
public class LoggingReader {

  private static Log log = LogFactory.getLog(LoggingReader.class);

  private static final LogMessage[] NO_LOGS_MESSAGE = new LogMessage[] { new LogMessage(
      "NO_LOGS", "INFO") };
  private static final LogInfo[] NO_LOGS_INFO = new LogInfo[] { new LogInfo("NO_LOG_FILES",
      "---", "---") };

  public LogInfo[] getLogsIndex(String tenantDomain, String serviceName)
      throws LogViewerException {
    LogInfo[] logIndex;
    int tenantId = getTenantIdForDomain(tenantDomain);
    if (isSysLogAppender(tenantId)) {
      logIndex = getLogInfo(tenantId, serviceName);
    } else {
      if (isSuperTenantUser()) {
        logIndex = getLocalLogInfo();
      } else {
        throw new LogViewerException(
            "Syslog Appender needs to be configured to view the log files");
      }
    }
    return logIndex;
  }

  public LogMessage[] getTenantLogs(String type, String keyword, String logFile, String logIndex,
      int maxLines, int start, int end, String tenantDomain, String serviceName)
      throws LogViewerException {
    int tenantId = getTenantIdForDomain(tenantDomain);
    if (keyword == null || keyword.equals("")) {
      // keyword is null
      if (type == null || type.equals("") || type.equalsIgnoreCase("ALL")) {
        return getHeadLogs(
            logIndex,
            getTenantLogMessages(logFile, maxLines, start - 1, end, tenantId,
                serviceName));
      } else {
        // type is NOT null and NOT equal to ALL
        return getTenantLogsForType(type, logFile, logIndex, maxLines, start, end,
            tenantId, serviceName);
      }
    } else {
      // keyword is NOT null
      if (type == null || type.equals("")) {
        // type is null
        return getTenantLogsForKey(keyword, logFile, logIndex, maxLines, start, end,
            tenantId, serviceName);
      } else {
        // type is NOT null and keyword is NOT null, but type can be
        // equal to ALL
        return searchTenantLog(type, keyword, logFile, logIndex, maxLines, start, end,
            tenantId, serviceName);
      }
    }
  }

  public LogMessage[] getBottomUpTenantLogs(String type, String keyword, String logFile,
      int maxLines, int start, int end, String tenantDomain, String serviceName)
      throws LogViewerException {
    int tenantId = getTenantIdForDomain(tenantDomain);
    if (keyword == null || keyword.equals("")) {
      // keyword is null
      if (type == null || type.equals("") || type.equalsIgnoreCase("ALL")) {
        return getBottomUpLogMessages(logFile, maxLines, start, end, tenantId, serviceName);
      } else {
        // type is NOT null and NOT equal to ALL
        return getBottomUpLogsForType(type, logFile, maxLines, start, end, tenantId,
            serviceName);
      }
    } else {
      // keyword is NOT null
      if (type == null || type.equals("")) {
        // type is null
        return getBottomUpLogsForKey(keyword, logFile, maxLines, start, end, tenantId,
            serviceName);
      } else {
        // type is NOT null and keyword is NOT null, but type can be
        // equal to ALL
        return searchBottomUpLogsTenantLog(type, keyword, logFile, maxLines, start, end,
            tenantId, serviceName);
      }
    }
  }

  @SuppressWarnings("deprecation")
  public String[] getLogLinesFromFile(String logFile, int maxLogs, int start, int end,
      String tenantDomain, String serviceName) throws LogViewerException {
    int tenantId = getTenantIdForDomain(tenantDomain);
    ArrayList<String> logsList = new ArrayList<String>();
    InputStream logStream;
    if (end > maxLogs) {
      end = maxLogs;
    }
    try {
      logStream = getInputStream(logFile, tenantId, serviceName);
    } catch (Exception e) {
      throw new LogViewerException("Cannot find the specified file location to the log file",
          e);
    }
    DataInputStream dataInput = new DataInputStream(logStream);
    int index = 1;
    String line;
    try {
      while ((line = dataInput.readLine()) != null) {
        if (index <= end && index > start) {
          logsList.add(line);
        }
        index++;
      }
      dataInput.close();
    } catch (IOException e) {
      throw new LogViewerException("Cannot read the log file", e);
    }
    return logsList.toArray(new String[logsList.size()]);
  }

  public int getLineNumbers(String logFile, String tenantDomain, String serviceName)
      throws Exception {
    InputStream is;
    int tenantId = getTenantIdForDomain(tenantDomain);
    try {
      is = getInputStream(logFile, tenantId, serviceName);
    } catch (LogViewerException e) {
      throw new LogViewerException("Cannot read InputStream from the file " + logFile, e);
    }
    try {
      byte[] c = new byte[1024];
      int count = 0;
      int readChars = 0;
      while ((readChars = is.read(c)) != -1) {
        for (int i = 0; i < readChars; ++i) {
          if (c[i] == '\n') {
            ++count;
          }
        }
      }
      return count;
    } catch (IOException e) {
      throw new LogViewerException("Cannot read file size from the " + logFile, e);
    } finally {
      try {
        is.close();
      } catch (IOException e) {
        throw new LogViewerException("Cannot close the input stream " + logFile, e);
      }
    }
  }

  @SuppressWarnings("deprecation")
  public String getLogLine(String logFile, int lineNo, String tenantDomain, String serviceName)
      throws LogViewerException {
    String line;
    InputStream is;
    try {
      int tenantId = getTenantIdForDomain(tenantDomain);
      is = getInputStream(logFile, tenantId, serviceName);
    } catch (Exception e) {
      throw new LogViewerException("Cannot read InputStream from the file " + logFile, e);
    }
    DataInputStream dataInput = new DataInputStream(is);
    try {
      int count = 1;
      try {
        while ((line = dataInput.readLine()) != null) {
          if (count == lineNo) {
            return line;
          }
          count++;
        }
      } catch (IOException e) {
        throw new LogViewerException("Cannot read line number from the " + logFile, e);
      }
    } finally {
      try {
        dataInput.close();
        is.close();
      } catch (IOException e) {
        throw new LogViewerException("Cannot close the input stream " + logFile, e);
      }
    }
    return null;
  }

  public boolean isSysLogAppender(int tenantId) throws LogViewerException {
    SyslogData syslogData;
    if (!isSyslogOn()) {
      return false;
    }
    try {
      syslogData = getSyslogData();
      return isValidSyslogEntry(syslogData, tenantId);
    } catch (Exception e) {
      return false;
    }
  }

  public boolean isValidTenantDomain(String tenantDomain) {
    try {
      getTenantIdForDomain(tenantDomain);
      return true;
    } catch (LogViewerException e) {
      return false;
    }
  }

  private String getLogServerURLforTenant(String syslogServerURL, String logFile, int tenantId) {
    String serverurl = "";
    if (isSuperTenantUser()) {
      serverurl = syslogServerURL + LoggingConstants.FILE_SEPARATOR + tenantId
          + LoggingConstants.FILE_SEPARATOR;
    } else {
      serverurl = syslogServerURL + LoggingConstants.FILE_SEPARATOR
          + CarbonContext.getCurrentContext().getTenantId()
          + LoggingConstants.FILE_SEPARATOR;
    }
    return serverurl + logFile;
  }

  private String getLogsServerURLforTenantService(String syslogServerURL, String logFile,
      int tenantId, String serviceName) throws LogViewerException {
    String serverurl = "";
    String lastChar = String.valueOf(syslogServerURL.charAt(syslogServerURL.length() - 1));
    if (lastChar.equals("/")) {
      syslogServerURL = syslogServerURL.substring(0, syslogServerURL.length() - 1);
    }
    if (isSuperTenantUser()) {
      if (isManager()) {
        if (serviceName != null && serviceName.length() > 0) {
          serverurl = syslogServerURL + LoggingConstants.FILE_SEPARATOR + tenantId
              + LoggingConstants.FILE_SEPARATOR + serviceName
              + LoggingConstants.FILE_SEPARATOR;
        } else {
          serverurl = syslogServerURL + LoggingConstants.FILE_SEPARATOR + tenantId
              + LoggingConstants.FILE_SEPARATOR
              + LoggingConstants.WSO2_Stratos_Manager
              + LoggingConstants.FILE_SEPARATOR;
        }
        try {
          if (!isStratosService()) {
            serverurl = syslogServerURL + LoggingConstants.FILE_SEPARATOR + tenantId
                + LoggingConstants.FILE_SEPARATOR
                + ServerConfiguration.getInstance().getFirstProperty("Name")
                + LoggingConstants.FILE_SEPARATOR;
          }
        } catch (Exception e) {
          throw new LogViewerException("Cannot get log ServerURL for Tenant Service", e);
        }
      } else {
        serverurl = syslogServerURL + LoggingConstants.FILE_SEPARATOR + tenantId
            + LoggingConstants.FILE_SEPARATOR
            + ServerConfiguration.getInstance().getFirstProperty("Name")
            + LoggingConstants.FILE_SEPARATOR;
      }

    } else {
      if (isManager()) {
        if (serviceName != null && serviceName.length() > 0) {
          serverurl = syslogServerURL + LoggingConstants.FILE_SEPARATOR
              + CarbonContext.getCurrentContext().getTenantId()
              + LoggingConstants.FILE_SEPARATOR + serviceName
              + LoggingConstants.FILE_SEPARATOR;
        } else {
          serverurl = syslogServerURL + LoggingConstants.FILE_SEPARATOR
              + CarbonContext.getCurrentContext().getTenantId()
              + LoggingConstants.FILE_SEPARATOR
              + LoggingConstants.WSO2_Stratos_Manager
              + LoggingConstants.FILE_SEPARATOR;
        }
      } else {
        serverurl = syslogServerURL + LoggingConstants.FILE_SEPARATOR
            + CarbonContext.getCurrentContext().getTenantId()
            + LoggingConstants.FILE_SEPARATOR
            + ServerConfiguration.getInstance().getFirstProperty("Name")
            + LoggingConstants.FILE_SEPARATOR;
      }
    }
    serverurl = serverurl.replaceAll("\\s", "%20");
    logFile = logFile.replaceAll("\\s", "%20");
    return serverurl + logFile;
  }

  public boolean isStratosService() throws Exception {
    String serviceName = ServerConfiguration.getInstance().getFirstProperty("Name");
    return ServiceConfigManager.isStratosService(serviceName);
  }

  public boolean isManager() {
    if (LoggingConstants.WSO2_Stratos_Manager.equals(ServerConfiguration.getInstance()
        .getFirstProperty("Name"))) {
      return true;
    } else {
      return false;
    }
  }

  private InputStream getLogDataStream(String logFile, int tenantId, String productName)
      throws Exception {
    SyslogData syslogData = getSyslogData();
    String url = "";
    // manager can view all the products tenant information
    url = getLogsServerURLforTenantService(syslogData.getUrl(), logFile, tenantId, productName);
    String password = syslogData.getPassword();
    String userName = syslogData.getUserName();
    int port = Integer.parseInt(syslogData.getPort());
    String realm = syslogData.getRealm();
    URI uri = new URI(url);
    String host = uri.getHost();
    HttpClient client = new HttpClient();
    client.getState().setCredentials(new AuthScope(host, port, realm),
        new UsernamePasswordCredentials(userName, password));
    GetMethod get = new GetMethod(url);
    get.setDoAuthentication(true);
    client.executeMethod(get);
    return get.getResponseBodyAsStream();
  }

  private LogMessage[] getHeadLogs(String logIndex, LogMessage[] allLogs)
      throws LogViewerException {
    try {
      int index = Integer.parseInt(logIndex) + 1;
      int maxLen;
      if (index > allLogs.length || index == -1) {
        maxLen = allLogs.length;
      } else {
        maxLen = index;
      }
      LogMessage[] headLogs = new LogMessage[maxLen];
      for (int i = 0; i < maxLen; i++) {
        headLogs[i] = allLogs[i];
      }
      return headLogs;
    } catch (Exception e) {
      throw new LogViewerException("Cannot retrieve logs for bottom up", e);
    }
  }

  private LogInfo[] getSortedLogInfo(LogInfo logs[]) {
    int maxLen = logs.length;
    if (maxLen > 0) {
      List<LogInfo> logInfoList = Arrays.asList(logs);
      Collections.sort(logInfoList, new Comparator<Object>() {
        public int compare(Object o1, Object o2) {
          LogInfo log1 = (LogInfo) o1;
          LogInfo log2 = (LogInfo) o2;
          return log1.getLogName().compareToIgnoreCase(log2.getLogName());
        }

      });
      return (LogInfo[]) logInfoList.toArray(new LogInfo[logInfoList.size()]);
    } else {
      return NO_LOGS_INFO;
    }
  }

  private LogMessage[] getBottomUpLogsForType(String type, String logFile, int maxLogs,
      int start, int end, int tenantId, String serviceName) throws LogViewerException {
    List<LogMessage> resultList = new ArrayList<LogMessage>();
    LogMessage[] allLogs = getBottomUpLogMessages(logFile, maxLogs, start, end, tenantId,
        serviceName);
    for (int i = 0; i < allLogs.length; i++) {
      LogMessage tempLog = allLogs[i];
      if (tempLog != null && type.equals(tempLog.getType().trim())) {
        resultList.add(tempLog);
      }
    }
    if (resultList.size() > 0) {
      return resultList.toArray(new LogMessage[resultList.size()]);
    } else {
      return NO_LOGS_MESSAGE;
    }

  }

  private LogMessage[] getBottomUpLogsForKey(String keyword, String logFile, int maxLines,
      int start, int end, int tenantId, String serviceName) throws LogViewerException {
    List<LogMessage> resultList = new ArrayList<LogMessage>();
    LogMessage[] allLogs = getBottomUpLogMessages(logFile, maxLines, start, end, tenantId,
        serviceName);
    for (int i = 0; i < allLogs.length; i++) {
      LogMessage tempLog = allLogs[i];
      if (tempLog != null) {
        String message = tempLog.getLogMessage();
        if (message != null && message.toLowerCase().indexOf(keyword.toLowerCase()) > -1) {
          resultList.add(tempLog);
        }
      }
    }
    if (resultList.size() > 0) {
      return resultList.toArray(new LogMessage[resultList.size()]);
    } else {
      return NO_LOGS_MESSAGE;
    }
  }

  public boolean isSuperTenantUser() {
    CarbonContext carbonContext = CarbonContext.getCurrentContext();
    int tenantId = carbonContext.getTenantId();
    if (tenantId == 0) {
      return true;
    } else {
      return false;
    }
  }

  private SyslogData getSyslogData() throws Exception {
    if (isSyslogConfiguredInRegistry()) {
      return LoggingUtil.getSyslogData();
    } else {
      SyslogData syslogData = new SyslogData();
      SyslogConfiguration syslogConfig = SyslogConfigManager.loadSyslogConfiguration();
      syslogData.setUrl(syslogConfig.getSyslogHostURL());
      syslogData.setPort(syslogConfig.getPort());
      syslogData.setRealm(syslogConfig.getRealm());
      syslogData.setUserName(syslogConfig.getUserName());
      syslogData.setPassword(syslogConfig.getPassword());
      return syslogData;
    }
  }

  private boolean isSyslogOn() {
    SyslogConfiguration syslogConfig = SyslogConfigManager.loadSyslogConfiguration();
    return syslogConfig.isSyslogOn();
  }

  private LogMessage[] getTenantLogsForType(String type, String logFile, String logIndex,
      int maxLines, int start, int end, int tenantId, String serviceName)
      throws LogViewerException {
    List<LogMessage> resultList = new ArrayList<LogMessage>();
    LogMessage[] allLogs = getHeadLogs(logIndex,
        getTenantLogMessages(logFile, maxLines, start - 1, end, tenantId, serviceName));
    for (int i = 0; i < allLogs.length; i++) {
      LogMessage tempLog = allLogs[i];
      if (type.equals(tempLog.getType().trim())) {
        resultList.add(tempLog);
      }
    }
    if (resultList.size() > 0) {
      return resultList.toArray(new LogMessage[resultList.size()]);
    } else {
      return NO_LOGS_MESSAGE;
    }

  }

  private LogMessage[] getTenantLogsForKey(String keyword, String logFile, String logIndex,
      int maxLines, int start, int end, int tenantId, String serviceName)
      throws LogViewerException {
    List<LogMessage> resultList = new ArrayList<LogMessage>();
    LogMessage[] allLogs = getHeadLogs(logIndex,
        getTenantLogMessages(logFile, maxLines, start - 1, end, tenantId, serviceName));
    for (int i = 0; i < allLogs.length; i++) {
      LogMessage tempLog = allLogs[i];
      String message = tempLog.getLogMessage();
      if (message != null && message.toLowerCase().indexOf(keyword.toLowerCase()) > -1) {
        resultList.add(tempLog);
      }
    }
    if (resultList.size() > 0) {
      return resultList.toArray(new LogMessage[resultList.size()]);
    } else {
      return NO_LOGS_MESSAGE;
    }
  }

  private String removeSyslogHeader(String line) {
    if (isValidPattern(LoggingConstants.RegexPatterns.SYSLOG_DATE_PATTERN, line)) {
      String lines[] = line.split(LoggingConstants.RegexPatterns.SYSLOG_DATE_PATTERN);
      if (lines.length > 1) {
        return lines[1];
      } else {
        return line;
      }
    } else {
      return line;
    }
  }

  private String cleanLogHeader(String line, int tenantId) {
    String tenantPattern = "";
    if (isSuperTenantUser()) {
      tenantPattern = SyslogConfigManager.getSyslogPattern().replace(
          LoggingConstants.RegexPatterns.TENANT_PATTERN, String.valueOf(tenantId));
    } else {
      tenantPattern = SyslogConfigManager.getSyslogPattern().replace(
          LoggingConstants.RegexPatterns.TENANT_PATTERN,
          String.valueOf(CarbonContext.getCurrentContext().getTenantId()));
    }
    return line.replace(tenantPattern.trim(), "");
  }

  private LogMessage getLogMessageForType(String log) {
    LogMessage logMessage = null;
    if (isTraceHeader(log)) {
      logMessage = new LogMessage(log, LoggingConstants.RegexPatterns.LOG_TRACE);
    } else if (isDebugHeader(log)) {
      logMessage = new LogMessage(log, LoggingConstants.RegexPatterns.LOG_DEBUG);
    } else if (isInfoHeader(log)) {
      logMessage = new LogMessage(log, LoggingConstants.RegexPatterns.LOG_INFO);
    } else if (isWarnHeader(log)) {
      logMessage = new LogMessage(log, LoggingConstants.RegexPatterns.LOG_WARN);
    } else if (isErrorHeader(log)) {
      logMessage = new LogMessage(log, LoggingConstants.RegexPatterns.LOG_ERROR);
    } else if (isFatalHeader(log)) {
      logMessage = new LogMessage(log, LoggingConstants.RegexPatterns.LOG_FATAL);
    }
    return logMessage;
  }

  @SuppressWarnings("deprecation")
  private LogMessage[] getTenantLogMessages(String logFile, int maxLogs, int start, int end,
      int tenantId, String serviceName) throws LogViewerException {
    ArrayList<LogMessage> logsList = new ArrayList<LogMessage>();
    String errorLine = "";
    InputStream logStream;
    if (end > maxLogs) {
      end = maxLogs;
    }
    try {
      logStream = getInputStream(logFile, tenantId, serviceName);
    } catch (Exception e) {
      throw new LogViewerException("Cannot find the specified file location to the log file",
          e);
    }
    DataInputStream dataInput = new DataInputStream(logStream);
    int index = 1;
    String line;
    boolean isSyslogFile;
    try {
      isSyslogFile = isSysLogAppender(tenantId);
    } catch (Exception e1) {
      throw new LogViewerException("Cannot validate syslog appender", e1);
    }
    try {
      while ((line = dataInput.readLine()) != null) {
        if (isSyslogFile) {
          line = removeSyslogHeader(line);
        }
        line = cleanLogHeader(line, tenantId);
        if ((index <= end && index > start)) {
          // When if a log entry has multiple lines (ie exception ect)
          // it waits for valid log header,
          // and add the multiple log lines to the specific log header
          // (since we are reading from bottom up
          // those multiple lines belongs to the next valid log
          // header.
          LogMessage logMessage = null;
          if (isErrorHeader(line)) {
            if (!errorLine.equals("")) {
              errorLine = (String) errorLine.subSequence(0, (errorLine.length() - 1));
              logMessage = getLogMessageForType(errorLine);
              if (logMessage != null) {
                logsList.add(logMessage);
              }
              errorLine = "";
            }
            // when there are log messages with multiple lines one
            // after the other
            // next line is also considered as a error line
            errorLine = line;
          } else if (isFatalHeader(line)) {
            if (!errorLine.equals("")) {
              errorLine = (String) errorLine.subSequence(0, (errorLine.length() - 1));
              logMessage = getLogMessageForType(errorLine);
              if (logMessage != null) {
                logsList.add(logMessage);
              }
              errorLine = "";
            }
            errorLine = line;
          } else if (isTraceHeader(line)) {
            if (!errorLine.equals("")) {
              errorLine = (String) errorLine.subSequence(0, (errorLine.length() - 1));
              logMessage = getLogMessageForType(errorLine);
              if (logMessage != null) {
                logsList.add(logMessage);
              }
              errorLine = "";
            }
            errorLine = line;
          } else if (isInfoHeader(line)) {
            if (!errorLine.equals("")) {
              errorLine = (String) errorLine.subSequence(0, (errorLine.length() - 1));
              logMessage = getLogMessageForType(errorLine);
              if (logMessage != null) {
                logsList.add(logMessage);
              }
              errorLine = "";
            }
            errorLine = line;
          } else if (isWarnHeader(line)) {
            if (!errorLine.equals("")) {
              errorLine = (String) errorLine.subSequence(0, (errorLine.length() - 1));
              logMessage = getLogMessageForType(errorLine);
              if (logMessage != null) {
                logsList.add(logMessage);
              }
              errorLine = "";
            }
            errorLine = line;
          } else if (isDebugHeader(line)) {
            if (!errorLine.equals("")) {
              errorLine = (String) errorLine.subSequence(0, (errorLine.length() - 1));
              logMessage = getLogMessageForType(errorLine);
              if (logMessage != null) {
                logsList.add(logMessage);
              }
              errorLine = "";
            }
            errorLine = line;
          } else if (!isLogHeader(line)) {
            // if a log line has no valid log header that log line
            // is considered as a error line.
            errorLine = errorLine + line + LoggingConstants.RegexPatterns.NEW_LINE;
          } else if (isLogHeader(line)) {
            if (!errorLine.equals("")) {
              errorLine = (String) errorLine.subSequence(0, (errorLine.length() - 1));
              logMessage = getLogMessageForType(errorLine);
              if (logMessage != null) {
                logsList.add(logMessage);
              }
              errorLine = "";
            }
            logMessage = getLogMessageForType(line);
            if (logMessage != null) {
              logsList.add(logMessage);
            }
          } else {
            log.warn("The log message  " + line + " is ignored.");
          }
        }
        index++;
      }
      if (!errorLine.equals("")) {
        LogMessage logMessage = getLogMessageForType(errorLine);
        if (logMessage != null) {
          logsList.add(logMessage);
        } else {
          log.warn("The log message " + errorLine + " is ignored.");
        }
      }
      dataInput.close();
    } catch (IOException e) {
      throw new LogViewerException("Cannot read the log file", e);
    }
    return logsList.toArray(new LogMessage[logsList.size()]);
  }

  private LogMessage[] getBottomUpLogMessages(String logFile, int maxLogs, int start, int end,
      int tenantId, String serviceName) throws LogViewerException {
    start = (maxLogs - start) + 1;
    end = (start - 200);
    if (start > maxLogs) {
      start = maxLogs;
    }
    if (end > maxLogs) {
      end = maxLogs;
    }
    if (end < 0) {
      end = 0;
    }
    LogMessage[] logs = getTenantLogMessages(logFile, maxLogs, end, start, tenantId,
        serviceName);
    int maxLen = logs.length;
    LogMessage[] botomupLogs = new LogMessage[maxLen];
    for (int i = 0, j = maxLen - 1; i < maxLen; i++, j--) {
      botomupLogs[i] = logs[j];
    }
    return botomupLogs;
  }

  private InputStream getLocalInputStream(String logFile) throws FileNotFoundException {
    String fileName = CarbonUtils.getCarbonLogsPath() + LoggingConstants.FILE_SEPARATOR
        + logFile;
    InputStream is = new BufferedInputStream(new FileInputStream(fileName));
    return is;
  }

  private InputStream getInputStream(String logFile, int tenantId, String serviceName)
      throws LogViewerException {
    InputStream inputStream;
    try {
      if (isSysLogAppender(tenantId)) {
        inputStream = getLogDataStream(logFile, tenantId, serviceName);
      } else {
        if (isSuperTenantUser()) {
          inputStream = getLocalInputStream(logFile);
        } else {
          throw new LogViewerException("Syslog Properties are not properly configured");
        }
      }
      return inputStream;
    } catch (Exception e) {
      throw new LogViewerException("Error getting the file inputstream", e);
    }

  }

  private LogInfo[] getLocalLogInfo() {
    String folderPath = CarbonUtils.getCarbonLogsPath();
    LogInfo log = null;
    ArrayList<LogInfo> logs = new ArrayList<LogInfo>();
    File folder = new File(folderPath);
    FileFilter fileFilter = new WildcardFileFilter(
        LoggingConstants.RegexPatterns.LOCAL_CARBON_LOG_PATTERN);
    File[] listOfFiles = folder.listFiles(fileFilter);
    for (File file : listOfFiles) {
      String filename = file.getName();
      String fileDates[] = filename
          .split(LoggingConstants.RegexPatterns.LOG_FILE_DATE_SEPARATOR);
      String filePath = CarbonUtils.getCarbonLogsPath() + LoggingConstants.FILE_SEPARATOR
          + filename;
      File logfile = new File(filePath);
      if (fileDates.length == 2) {
        log = new LogInfo(filename, fileDates[1], getFileSize(logfile));
      } else {
        log = new LogInfo(filename, LoggingConstants.RegexPatterns.CURRENT_LOG,
            getFileSize(logfile));
      }
      if (log != null) {
        logs.add(log);
      }
    }
    return getSortedLogInfo(logs.toArray(new LogInfo[logs.size()]));
  }

  private String getFileSize(File file) {
    long bytes = file.length();
    int unit = 1024;
    if (bytes < unit)
      return bytes + " B";
    int exp = (int) (Math.log(bytes) / Math.log(unit));
    char pre = "KMGTPE".charAt(exp - 1);
    return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
  }

  @SuppressWarnings("deprecation")
  private LogInfo[] getLogInfo(int tenantId, String serviceName) throws LogViewerException {
    InputStream logStream;
    try {
      if (isSysLogAppender(tenantId)) {
        logStream = getLogDataStream("", tenantId, serviceName);
      } else {
        throw new LogViewerException("Syslog Properties are not properly configured");
      }

    } catch (HttpException e) {
      throw new LogViewerException("Cannot establish the connection to the syslog server", e);
    } catch (IOException e) {
      throw new LogViewerException("Cannot find the specified file location to the log file",
          e);
    } catch (Exception e) {
      throw new LogViewerException("Cannot find the specified file location to the log file",
          e);
    }
    DataInputStream dataInput = new DataInputStream(logStream);
    String line;
    ArrayList<LogInfo> logs = new ArrayList<LogInfo>();
    Pattern pattern = Pattern.compile(LoggingConstants.RegexPatterns.SYS_LOG_FILE_NAME_PATTERN);
    try {
      while ((line = dataInput.readLine()) != null) {
        String fileNameLinks[] = line
            .split(LoggingConstants.RegexPatterns.LINK_SEPARATOR_PATTERN);
        String fileDates[] = line
            .split((LoggingConstants.RegexPatterns.SYSLOG_DATE_SEPARATOR_PATTERN));
        String dates[] = null;
        String sizes[] = null;
        if (fileDates.length == 3) {
          dates = fileDates[1]
              .split(LoggingConstants.RegexPatterns.COLUMN_SEPARATOR_PATTERN);
          sizes = fileDates[2]
              .split(LoggingConstants.RegexPatterns.COLUMN_SEPARATOR_PATTERN);
        }
        if (fileNameLinks.length == 2) {
          String logFileName[] = fileNameLinks[1]
              .split(LoggingConstants.RegexPatterns.GT_PATTARN);
          Matcher matcher = pattern.matcher(logFileName[0]);
          if (matcher.find()) {
            if (logFileName != null && dates != null && sizes != null) {
              String logName = logFileName[0].replace(
                  LoggingConstants.RegexPatterns.BACK_SLASH_PATTERN, "");
              logName = logName.replaceAll("%20", " ");
              LogInfo log = new LogInfo(logName, dates[0], sizes[0]);
              logs.add(log);
            }
          }
        }
      }
      dataInput.close();
    } catch (IOException e) {
      throw new LogViewerException("Cannot find the specified file location to the log file",
          e);
    }
    return getSortedLogInfo(logs.toArray(new LogInfo[logs.size()]));
  }

  private boolean isSyslogConfiguredInRegistry() throws LogViewerException {
    try {
      return LoggingUtil.isSyslogConfigured();
    } catch (Exception e) {
      throw new LogViewerException(
          "Cannot access the registry configuration to get syslogappender", e);
    }
  }

  @SuppressWarnings("deprecation")
  public boolean isValidSyslogEntry(SyslogData syslogData, int tenantId)
      throws URISyntaxException {

    String password = syslogData.getPassword();
    String userName = syslogData.getUserName();
    int port = Integer.parseInt(syslogData.getPort());
    String realm = syslogData.getRealm();
    String url = "";
    try {
      url = getLogServerURLforTenant(syslogData.getUrl(), "", tenantId);
    } catch (Exception e) {
      return false;
    }
    URI uri = new URI(syslogData.getUrl());
    String host = uri.getHost();

    HttpClient client = new HttpClient();
    try {
      URL serverUrl = new URL(url);
      URLConnection conn = serverUrl.openConnection();
      conn.connect();
    } catch (MalformedURLException e) {
      return false;
    } catch (IOException e) {
      return false;
    } catch (Exception e) {
      return false;
    }
    try {
      client.getState().setCredentials(new AuthScope(host, port, realm),
          new UsernamePasswordCredentials(userName, password));
      GetMethod get = new GetMethod(url);
      get.setDoAuthentication(true);
      client.executeMethod(get);
      InputStream logStream = get.getResponseBodyAsStream();
      DataInputStream dataInput = new DataInputStream(logStream);
      if (dataInput.readLine() != null) {
        dataInput.close();
        return true;
      } else {
        dataInput.close();
        return false;
      }
    } catch (HttpException e) {
      return false;
    } catch (IOException e) {
      return false;
    }
  }

  private LogMessage[] searchTenantLog(String type, String keyword, String logFile,
      String logIndex, int maxLines, int start, int end, int tenantId, String serviceName)
      throws LogViewerException {

    if ("ALL".equalsIgnoreCase(type)) {
      return getTenantLogsForKey(keyword, logFile, logIndex, maxLines, start, end, tenantId,
          serviceName);

    } else {
      LogMessage[] filerByType = getTenantLogsForType(type, logFile, logIndex, maxLines,
          start, end, tenantId, serviceName);
      List<LogMessage> resultList = new ArrayList<LogMessage>();
      for (int i = 0; i < filerByType.length; i++) {
        String logMessage = filerByType[i].getLogMessage();
        if (logMessage != null
            && logMessage.toLowerCase().indexOf(keyword.toLowerCase()) > -1) {
          resultList.add(filerByType[i]);
        }
      }
      if (resultList.isEmpty()) {
        return NO_LOGS_MESSAGE;
      }
      return resultList.toArray(new LogMessage[resultList.size()]);
    }
  }

  private LogMessage[] searchBottomUpLogsTenantLog(String type, String keyword, String logFile,
      int maxLines, int start, int end, int tenantId, String serviceName)
      throws LogViewerException {
    if ("ALL".equalsIgnoreCase(type)) {
      return getBottomUpLogsForKey(keyword, logFile, maxLines, start, end, tenantId,
          serviceName);

    } else {
      LogMessage[] filerByType = getBottomUpLogsForType(type, logFile, maxLines, start, end,
          tenantId, serviceName);
      List<LogMessage> resultList = new ArrayList<LogMessage>();
      for (int i = 0; i < filerByType.length; i++) {
        String logMessage = filerByType[i].getLogMessage();
        if (logMessage != null
            && logMessage.toLowerCase().indexOf(keyword.toLowerCase()) > -1) {
          resultList.add(filerByType[i]);
        }
      }
      if (resultList.isEmpty()) {
        return NO_LOGS_MESSAGE;
      }
      return resultList.toArray(new LogMessage[resultList.size()]);
    }
  }

  private boolean isValidPattern(String expression, String str) {
    CharSequence inputStr = str;
    Pattern pattern = Pattern.compile(expression);
    Matcher matcher = pattern.matcher(inputStr);
    return matcher.find();
  }

  private boolean isErrorHeader(String line) {
    return isValidPattern(LoggingConstants.RegexPatterns.LOG_ERROR_HEADER_PATTERN, line);
  }

  private boolean isInfoHeader(String line) {
    return isValidPattern(LoggingConstants.RegexPatterns.LOG_INFO_HEADER_PATTERN, line);
  }

  private boolean isDebugHeader(String line) {
    return isValidPattern(LoggingConstants.RegexPatterns.LOG_DEBUG_HEADER_PATTERN, line);
  }

  private boolean isWarnHeader(String line) {
    return isValidPattern(LoggingConstants.RegexPatterns.LOG_WARN_HEADER_PATTERN, line);
  }

  private boolean isTraceHeader(String line) {
    return isValidPattern(LoggingConstants.RegexPatterns.LOG_TRACE_HEADER_PATTERN, line);
  }

  private boolean isFatalHeader(String line) {
    return isValidPattern(LoggingConstants.RegexPatterns.LOG_FATAL_HEADER_PATTERN, line);
  }

  private boolean isLogHeader(String line) {
    return isValidPattern(LoggingConstants.RegexPatterns.LOG_HEADER_PATTERN, line);
  }

  public int getTenantIdForDomain(String tenantDomain) throws LogViewerException {
    int tenantId;
    TenantManager tenantManager = LoggingServiceComponent.getTenantManager();
    if (tenantDomain == null || tenantDomain.equals("")) {
      tenantId = 0;
    } else {

      try {
        tenantId = tenantManager.getTenantId(tenantDomain);
      } catch (UserStoreException e) {
        throw new LogViewerException("Cannot find tenant id for the given tenant domain.");
      }
    }
    return tenantId;
  }

}
TOP

Related Classes of org.wso2.carbon.logging.util.LoggingReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.