mirror of https://github.com/apache/activemq.git
188 lines
6.8 KiB
Python
Executable File
188 lines
6.8 KiB
Python
Executable File
"""
|
|
Module LogFile
|
|
"""
|
|
import os
|
|
|
|
class LogFile(object):
|
|
"""
|
|
Class that represents an ActiveMQ log file read by the application.
|
|
It also stores a list of all the LogFile objects.
|
|
|
|
A LogFile object stores the following information:
|
|
-A list of 'outgoing' Connection objects that represent the connections
|
|
created by the JVM that writes this LogFile.
|
|
-A list of 'incoming' Connection objects that represent the connections
|
|
requests received by the JVM that writes this LogFile.
|
|
|
|
-A dictionary of messages that were sent in this file.
|
|
The keys are Message objects and the values
|
|
are lists of timestamps of when the message was sent.
|
|
-A list of messages that were received in this file.
|
|
The keys are Message objects and the values
|
|
are lists of timestamps of when the message was received.
|
|
|
|
-A list of messages that were sent in this file more than 1 time (duplicates)
|
|
The list is made of (message, ntimes, timestamps) tuples.
|
|
-A list of messages that were received in this file more than 1 time (duplicates),
|
|
analogous to the previous structure.
|
|
"""
|
|
|
|
logfiles = []
|
|
|
|
def __init__(self, path):
|
|
"""
|
|
Constructs a LogFile object.
|
|
path: a string with the path to the ActiveMQ log file.
|
|
"""
|
|
|
|
self.__path = os.path.abspath(path)
|
|
self.file = open(self.__path, 'r')
|
|
self.outgoing = []
|
|
self.incoming = []
|
|
|
|
self.sent = {}
|
|
self.received = {}
|
|
|
|
self.duplicateReceived = None
|
|
self.duplicateSent = None
|
|
|
|
self.calculated = False
|
|
|
|
LogFile.logfiles.append(self)
|
|
|
|
@classmethod
|
|
def clearData(cls):
|
|
"""
|
|
Class method erases all the LogFile objects stored in the LogFile class.
|
|
Returns nothing.
|
|
"""
|
|
|
|
del cls.logfiles[:]
|
|
|
|
@classmethod
|
|
def closeFiles(cls):
|
|
"""
|
|
Class method that closes all the LogFile objects stored in the LogFile class.
|
|
Returns nothing.
|
|
"""
|
|
|
|
for logFile in cls.logfiles:
|
|
logFile.file.close()
|
|
|
|
|
|
|
|
def addOutgoingConnection(self, con):
|
|
"""
|
|
Adds an 'outgoing' Connection object to this LogFile.
|
|
Returns nothing.
|
|
"""
|
|
|
|
self.outgoing.append(con)
|
|
|
|
def addIncomingConnection(self, con):
|
|
"""
|
|
Adds an 'incoming' Connection object to this LogFile.
|
|
Returns nothing.
|
|
"""
|
|
|
|
self.incoming.append(con)
|
|
|
|
def addSentMessage(self, message, timestamp):
|
|
"""
|
|
Adds a message to the set of messages that were sent thtough this file.
|
|
If a message gets sent 2 times, it gets added to the set of duplicate sent messages.
|
|
message: a Message object.
|
|
timestamp: a string with the time where this message was sent.
|
|
|
|
Returns nothing.
|
|
"""
|
|
|
|
if message in self.sent:
|
|
self.sent[message].append(timestamp)
|
|
else:
|
|
self.sent[message] = [timestamp]
|
|
|
|
def addReceivedMessage(self, message, timestamp):
|
|
"""
|
|
Adds a message to the set of messages that were received in this file.
|
|
If a message gets sent 2 times, it gets added to the set of duplicate received messages.
|
|
message: a Message object.
|
|
timestamp: a string with the time where this message was sent.
|
|
|
|
Returns nothing.
|
|
"""
|
|
|
|
#message = (shortProdId, prodSeqId, False)
|
|
if message in self.received:
|
|
self.received[message].append(timestamp)
|
|
else:
|
|
self.received[message] = [timestamp]
|
|
|
|
def getErrors(self):
|
|
"""
|
|
Returns a 2-tuple with:
|
|
-a list of (message, ntimes, timestamps) tuples, with the duplicate sent messages
|
|
that appear in more than one connection in this file.
|
|
'message' is a Message object.
|
|
'ntimes' is an integer stating how many times the message was sent ( always >= 2)
|
|
'timestamps' is a list of timestamps with the instants the message was sent.
|
|
|
|
-a list of (message, ntimes, timestamps) tuples, with the duplicate received messages
|
|
that appear in more than one connection in this file.
|
|
Structure analogous to previous one.
|
|
|
|
The data is only calculated once, and then successive calls of this method return always
|
|
the same erros unles self.calculated is set to False.
|
|
"""
|
|
|
|
if not self.calculated:
|
|
|
|
duplicateSentTemp = [(message, len(timestamps), timestamps)
|
|
for message, timestamps in self.sent.iteritems() if len(timestamps) > 1]
|
|
self.duplicateSent = []
|
|
|
|
for message, _, timestamps in duplicateSentTemp:
|
|
connections = []
|
|
for connection, direction in message.sendingConnections:
|
|
if direction and connection.fromFile == self \
|
|
or not direction and connection.toFile == self:
|
|
connections.append(connection)
|
|
if len(connections) > 1:
|
|
self.duplicateSent.append((message, len(timestamps), timestamps))
|
|
|
|
duplicateReceivedTemp = [(message, len(timestamps), timestamps)
|
|
for message, timestamps in self.received.iteritems() if len(timestamps) > 1]
|
|
self.duplicateReceived = []
|
|
|
|
for message, _, timestamps in duplicateReceivedTemp:
|
|
connections = []
|
|
for connection, direction in message.receivingConnections:
|
|
if direction and connection.toFile == self \
|
|
or not direction and connection.fromFile == self:
|
|
connections.append(connection)
|
|
if len(connections) > 1:
|
|
self.duplicateReceived.append((message, len(timestamps), timestamps))
|
|
|
|
self.duplicateSent.sort(key = lambda message: (message[0].producer.shortId, message[0].prodSeqId))
|
|
self.duplicateReceived.sort(key = lambda message: (message[0].producer.shortId, message[0].prodSeqId))
|
|
|
|
self.calculated = True
|
|
|
|
return self.duplicateSent, self.duplicateReceived
|
|
|
|
def close(self):
|
|
"""
|
|
Closes the underlying file.
|
|
Returns nothing.
|
|
"""
|
|
|
|
self.file.close()
|
|
|
|
def __str__(self):
|
|
"""
|
|
Returns a string representation of this object.
|
|
"""
|
|
|
|
return self.__path
|
|
|