import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.tizen.common.TizenPlatformConstants;
import org.tizen.common.connection.ConnectionPlugin;
import org.tizen.common.connection.preference.TizenLogPreferencePage;
import org.tizen.common.ui.view.console.AnsicodeAdapter;
-import org.tizen.common.util.log.Logger;
import org.tizen.sdblib.IDevice;
import org.tizen.sdblib.receiver.MultiLineReceiver;
import org.tizen.sdblib.util.LogLevel;
public class LogTab
{
+ private final Logger logger = LoggerFactory.getLogger(getClass());
+
private static final int STRING_BUFFER_LENGTH = 5000;
private LogLevel defaultLevel;
private String logTabName = null;
private IDevice device = null;
- private LogTabOuputReceiver logReceiver = null;
+ private LogTabOutputReceiver logReceiver = null;
private LogColors colors;
private Table table;
private static Pattern logPattern = Pattern.compile("^\\[\\s(\\d\\d-\\d\\d\\s\\d\\d:\\d\\d:\\d\\d\\.\\d+)" + "\\s+(\\d*):\\s*(\\d+)\\s([VDIWEF])/(.+)\\s+\\]$");
- // Array to keep all messages from device
+ // Messages not filtered, which have maximum buffer size
private final LogMessage[] allMessages = new LogMessage[STRING_BUFFER_LENGTH];
- // List about filtered messages with pidFilters, tagFilters, msgFilters
+ // Messages filtered by pidFilters, tagFilters, msgFilters
private final List<LogMessage> filteredMessages = new ArrayList<LogMessage>();
- // List about messages need to added table contents
- private final List<LogMessage> newMessages = new ArrayList<LogMessage>();
+ // Messages filtered by keyword which are used to show on log tab table
+ private final List<LogMessage> tableMessages = new ArrayList<LogMessage>();
- private LogMessageInfo lastMessageInfo = null;
+ private LogMessageInfo logMessageInfo = null;
private boolean isDefault = false;
// index for allMessages
- private int indexStart = -1;
- private int indexEnd = -1;
+ private int messageIndex = -1;
private LogFilter logFilter = new LogFilter();
/**
* Get logTab name
- *
+ *
* @return String
*/
public String getLogTabName()
/**
* Returns the UI table object.
- *
+ *
* @return
*/
public Table getTable()
if (device != null)
{
// create a new output receiver
- logReceiver = new LogTabOuputReceiver();
+ logReceiver = new LogTabOutputReceiver();
// start the LogTab in a different thread
new Thread(device.getSerialNumber() + " Logger") { //$NON-NLS-1$
@Override
public void run()
{
- while ( isOnline( device ) == false && logReceiver != null && logReceiver.isCancelled == false)
+ while (isOnline(device) == false && logReceiver != null && logReceiver.isCancelled == false)
{
try
{
sleep(2000);
} catch (InterruptedException e)
{
- Logger.error("LogTab : Device is not online or logger is null/cancelled", e.getMessage(), e);
+ logger.error("LogTab : Device is not online or logger is null/cancelled", e.getMessage(), e);
return;
}
}
device.executeShellCommand(String.format(TizenPlatformConstants.DLOGUTIL_CMD, "-v long *:" + level.getLetter()), logReceiver, 0 /* timeout */); //$NON-NLS-1$
} catch (Exception e)
{
- Logger.error("LogTab", e);
+ logger.error("LogTab", e);
}
}
}.start();
}
/** Stop the current LogTab */
- public void stop(boolean inUiThread)
+ public void stop()
{
if (logReceiver != null)
{
/**
* Stop current logger and start with new level It can be lost some log
* messages in time interval between stop and restart
- *
+ *
* @param level
* start logger with level
*/
public void restart(LogLevel level)
{
IDevice old = device;
- stop(true);
+ stop();
setDevice(old);
start(level);
}
- // add message to filtered message and replace old message to
- // new message
- public void addFilteredMessage(LogMessage newMessage, LogMessage oldMessage)
- {
- synchronized (filteredMessages)
- {
- if (oldMessage != null && filteredMessages.size() >= STRING_BUFFER_LENGTH)
- {
- int index = filteredMessages.indexOf(oldMessage);
- if (index != -1)
- {
- filteredMessages.remove(index);
- }
- }
-
- boolean isValid = logFilter.filteredByDefaultKeyword(newMessage);
-
- if (isValid)
- {
- filteredMessages.add(newMessage);
- if (logFilter.filteredByLogLevelAndKeyword(newMessage))
- {
- newMessages.add(newMessage);
- }
- }
- }
- }
-
/**
- * action when select level icon and input combo and text to TabItem bottom
+ * filter message by log level or keyword
*/
public void filterMessages()
{
{
if (logFilter.filteredByLogLevelAndKeyword(logMsg))
{
- newMessages.add(logMsg);
+ tableMessages.add(logMsg);
}
}
// 3. refill new messages
{
table.setRedraw(false);
- int newCount = newMessages.size();
+ int newCount = tableMessages.size();
try
{
// add the new items
for (int i = 0; i < newCount; i++)
{
- LogMessage msg = newMessages.get(i);
+ LogMessage msg = tableMessages.get(i);
addTableItem(msg);
}
} catch (SWTException e)
{
- Logger.error("LogFilter", e);
+ logger.error("LogFilter", e);
}
// if isScollLocked is false, always shows last table item
table.setRedraw(true);
- newMessages.clear();
+ tableMessages.clear();
}
/**
* Add a TableItem for the index-th item of the buffer
- *
+ *
* @param filter
* The index of the table in which to insert the item.
*/
* objects able to receive the output of a remote shell command,
* specifically a LogTab command in this case
*/
- private final class LogTabOuputReceiver extends MultiLineReceiver
+ private final class LogTabOutputReceiver extends MultiLineReceiver
{
public boolean isCancelled = false;
- public LogTabOuputReceiver()
+ public LogTabOutputReceiver()
{
super();
}
/**
- * Process new Log lines coming from {@link LogCatOuputReceiver}.
- *
+ * Process new Log lines coming from {@link LogTabOuputReceiver}.
+ *
* @param lines
* the new lines
*/
protected void processLogLines(String[] lines)
{
- // WARNING: this will not work if the string contains more line
- // than the buffer holds.
-
+ // WARNING: this will not work if the string contains more line than the
+ // buffer holds.
if (lines.length > STRING_BUFFER_LENGTH)
{
- Logger.error("LogTab : Receiving more lines than " + STRING_BUFFER_LENGTH, "");
+ logger.error("LogTab : Receiving more lines than " + STRING_BUFFER_LENGTH, "");
return;
}
- // parse the lines and create LogMessage that are stored in a temporary
- // list
- final ArrayList<LogMessage> newMessages = new ArrayList<LogMessage>();
-
synchronized (allMessages)
{
for (String line : lines)
{
line = AnsicodeAdapter.getStripAnsiString(line);
- // ignore empty lines.
+ // ignore empty line.
if (line.length() > 0)
{
- // check for header lines.
+ // check if the line is header line.
Matcher matcher = logPattern.matcher(line);
+ // a header line.
if (matcher.matches())
{
- // this is a header line, parse the header and keep it
- // around.
- lastMessageInfo = new LogMessageInfo();
-
- lastMessageInfo.time = matcher.group(1);
- lastMessageInfo.pidString = matcher.group(2);
- lastMessageInfo.tidString = matcher.group(3);
- lastMessageInfo.logLevel = LogLevel.getByLetterString(matcher.group(4));
- lastMessageInfo.tag = matcher.group(5).trim();
+ // create a new LogMessage header
+ logMessageInfo = new LogMessageInfo();
+
+ // parse the header line.
+ logMessageInfo.time = matcher.group(1);
+ logMessageInfo.pidString = matcher.group(2);
+ logMessageInfo.tidString = matcher.group(3);
+ logMessageInfo.logLevel = LogLevel.getByLetterString(matcher.group(4));
+ logMessageInfo.tag = matcher.group(5).trim();
}
+ // not a header line.
else
{
-
- if (lastMessageInfo == null)
+ if (logMessageInfo == null)
{
return;
}
- // This is not a header line.
- // Create a new LogMessage and process it.
- LogMessage mc = new LogMessage();
+ // create a new LogMessage.
+ LogMessage logMessage = new LogMessage();
- // If someone printed a log message with embedded '\n'
- // characters,
- // there will one header line followed by multiple text
- // lines.
- // Use the last header that we saw.
- mc.data = lastMessageInfo;
+ // get log message info.
+ logMessage.data = logMessageInfo;
// tabs seem to display as only 1 tab so we replace the
// leading tabs by 4 spaces.
- mc.msg = line.replaceAll("\t", " "); //$NON-NLS-1$ //$NON-NLS-2$
+ logMessage.msg = line.replaceAll("\t", " "); //$NON-NLS-1$ //NON-NLS-2$
// process the new LogMessage.
- processNewMessage(mc);
-
- // store the new LogMessage
- newMessages.add(mc);
+ processNewMessage(logMessage);
}
}
}
{
Display display = table.getDisplay();
- // run in sync because this will update the
- // buffer start/end indices
+ // run in sync because this will update the buffer start/end
+ // indices
display.asyncExec(new Runnable()
{
@Override
} catch (SWTException e)
{
// display is disposed, stop the LogTab
- stop(false);
+ stop();
}
}
}
/**
- * Processes a new Message.
- * <p/>
- * This adds the new message to the buffer, and gives it to the existing
- * filters.
- *
+ * Process new log message.
+ *
* @param newMessage
*/
private void processNewMessage(LogMessage newMessage)
{
+ // add new message to all message array.
+ LogMessage oldMessage = addAllMessages(newMessage);
+
+ // add new message to filtered message list.
+ addFilteredMessage(newMessage, oldMessage);
+
+ // add new message to table message list.
+ addTableMessage(newMessage);
+ }
+
+ /**
+ * Add new message to all messages array.
+ *
+ * @param newMessage
+ * @return old message assigned before.
+ */
+ private LogMessage addAllMessages(LogMessage newMessage)
+ {
+ // get next message index.
+ if (messageIndex == (STRING_BUFFER_LENGTH - 1))
+ {
+ messageIndex = 0;
+ }
+ else
+ {
+ messageIndex++;
+ }
- // compute the index where the message goes.
- // was the buffer empty?
- int messageIndex = -1;
- if (indexStart == -1)
+ // add new log message
+ if (allMessages[messageIndex] == null)
{
- indexStart = 0;
- messageIndex = indexStart;
- indexEnd = 1;
+ allMessages[messageIndex] = newMessage;
+ return null;
}
else
{
- messageIndex = indexEnd;
+ LogMessage oldMessage = allMessages[messageIndex];
+ allMessages[messageIndex] = newMessage;
+ return oldMessage;
+ }
+ }
- // check we aren't overwriting start
- if (indexEnd == indexStart)
+ // add message to filtered message and replace old message to new message
+ public void addFilteredMessage(LogMessage newMessage, LogMessage oldMessage)
+ {
+ synchronized (filteredMessages)
+ {
+ if (oldMessage != null && filteredMessages.size() >= STRING_BUFFER_LENGTH)
{
- indexStart = (indexStart + 1) % STRING_BUFFER_LENGTH;
+ int index = filteredMessages.indexOf(oldMessage);
+ if (index != -1)
+ {
+ filteredMessages.remove(index);
+ }
}
- // increment the next usable slot index
- indexEnd = (indexEnd + 1) % STRING_BUFFER_LENGTH;
+ boolean isValid = logFilter.filteredByDefaultKeyword(newMessage);
+ if (isValid)
+ {
+ filteredMessages.add(newMessage);
+ }
}
+ }
- LogMessage oldMessage = null;
-
- // record the message that was there before
- if (allMessages[messageIndex] != null)
+ public void addTableMessage(LogMessage newMessage)
+ {
+ synchronized (tableMessages)
{
- oldMessage = allMessages[messageIndex];
+ boolean isValid = logFilter.filteredByLogLevelAndKeyword(newMessage);
+ if (isValid)
+ {
+ tableMessages.add(newMessage);
+ }
}
-
- // then add the new one
- allMessages[messageIndex] = newMessage;
-
- addFilteredMessage(newMessage, oldMessage);
}
/**
}
else
{
- stop(true);
+ stop();
}
}
logFilter.setKeywordFilter(text);
}
- // remove all filtered messages and tableMessages to refill or fill messages
+ // remove all tableMessages to refill or fill messages
public void initialize()
{
- newMessages.clear();
- lastMessageInfo = null;
+ tableMessages.clear();
+ logMessageInfo = null;
resetUI(false);
}
}
}
- indexStart = -1;
- indexEnd = -1;
filteredMessages.clear();
initialize();
}