/*
* 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;
}
}