将文件记录到 Pandas 数据框
Log file to Pandas Dataframe
我有日志文件,其中有很多行,格式如下:
LogLevel [13/10/2015 00:30:00.650] [Message Text]
我的目标是将日志文件中的每一行转换成一个漂亮的数据框。我已经厌倦了这样做,通过拆分 [ 字符上的行,但是我仍然没有得到一个整洁的数据框。
我的代码:
level = []
time = []
text = []
with open(filename) as inf:
for line in inf:
parts = line.split('[')
if len(parts) > 1:
level = parts[0]
time = parts[1]
text = parts[2]
print (parts[0],parts[1],parts[2])
s1 = pd.Series({'Level':level, 'Time': time, 'Text':text})
df = pd.DataFrame(s1).reset_index()
这是我打印的数据框:
Info 10/08/16 10:56:09.843] In Function CCatalinaPrinter::ItemDescription()]
Info 10/08/16 10:56:09.843] Sending UPC Description Message ]
我如何改进它以去除空格和其他 ']' 字符
谢谢
您可以将 read_csv
与分隔符 \s*\[
一起使用 - 空格与 [
:
import pandas as pd
from pandas.compat import StringIO
temp=u"""LogLevel [13/10/2015 00:30:00.650] [Message Text]
LogLevel [13/10/2015 00:30:00.650] [Message Text]
LogLevel [13/10/2015 00:30:00.650] [Message Text]
LogLevel [13/10/2015 00:30:00.650] [Message Text]"""
#after testing replace StringIO(temp) to filename
df = pd.read_csv(StringIO(temp), sep="\s*\[", names=['Level','Time','Text'], engine='python')
然后通过 strip
and convert column Time
to_datetime
删除 ]
:
df.Time = pd.to_datetime(df.Time.str.strip(']'), format='%d/%m/%Y %H:%M:%S.%f')
df.Text = df.Text.str.strip(']')
print (df)
Level Time Text
0 LogLevel 2015-10-13 00:30:00.650 Message Text
1 LogLevel 2015-10-13 00:30:00.650 Message Text
2 LogLevel 2015-10-13 00:30:00.650 Message Text
3 LogLevel 2015-10-13 00:30:00.650 Message Text
print (df.dtypes)
Level object
Time datetime64[ns]
Text object
dtype: object
我必须手动解析我的分隔符,因为我的分隔符出现在我的消息正文中,并且消息正文也会跨越多行,例如,如果我的 Flask 应用程序抛出异常并记录堆栈跟踪。
这是我的日志创建格式...
logging.basicConfig( filename="%s/%s_MyApp.log" % ( Utilities.logFolder , datetime.datetime.today().strftime("%Y%m%d-%H%M%S")) , level=logging.DEBUG, format="%(asctime)s,%(name)s,%(process)s,%(levelno)u,%(message)s", datefmt="%Y-%m-%d %H:%M:%S" )
以及我的实用程序模块中的解析代码
Utilities.py
import re
import pandas
logFolder = "./Logs"
logLevelToString = { "50" : "CRITICAL",
"40" : "ERROR" ,
"30" : "WARNING" ,
"20" : "INFO" ,
"10" : "DEBUG" ,
"0" : "NOTSET" } # https://docs.python.org/3.6/library/logging.html#logging-levels
def logFile2DataFrame( filePath ) :
dfLog = pandas.DataFrame( columns=[ 'Timestamp' , 'Module' , 'ProcessID' , 'Level' , 'Message' ] )
tsPattern = "^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2},"
with open( filePath , 'r' ) as logFile :
numRows = -1
for line in logFile :
if re.search( tsPattern , line ) :
tokens = line.split(",")
timestamp = tokens[0]
module = tokens[1]
processID = tokens[2]
level = logLevelToString[ tokens[3] ]
message = ",".join( tokens[4:] )
numRows += 1
dfLog.loc[ numRows ] = [ timestamp , module , processID , level , message ]
else :
# Multiline message, integrate it into last record
dfLog.loc[ numRows , 'Message' ] += line
return dfLog
我实际上创建了这个帮助消息,让我可以直接从我的 Flask 应用程序查看我的日志,因为我有一个方便的模板可以呈现 DataFrame。应该加速调试一堆,因为将 flaskapp 封装在 Tornado WSGI 服务器中会阻止在抛出异常时显示从 Flask 可见的正常调试页面。如果有人知道如何在这种情况下恢复该功能,请分享。
我有日志文件,其中有很多行,格式如下:
LogLevel [13/10/2015 00:30:00.650] [Message Text]
我的目标是将日志文件中的每一行转换成一个漂亮的数据框。我已经厌倦了这样做,通过拆分 [ 字符上的行,但是我仍然没有得到一个整洁的数据框。
我的代码:
level = []
time = []
text = []
with open(filename) as inf:
for line in inf:
parts = line.split('[')
if len(parts) > 1:
level = parts[0]
time = parts[1]
text = parts[2]
print (parts[0],parts[1],parts[2])
s1 = pd.Series({'Level':level, 'Time': time, 'Text':text})
df = pd.DataFrame(s1).reset_index()
这是我打印的数据框:
Info 10/08/16 10:56:09.843] In Function CCatalinaPrinter::ItemDescription()]
Info 10/08/16 10:56:09.843] Sending UPC Description Message ]
我如何改进它以去除空格和其他 ']' 字符
谢谢
您可以将 read_csv
与分隔符 \s*\[
一起使用 - 空格与 [
:
import pandas as pd
from pandas.compat import StringIO
temp=u"""LogLevel [13/10/2015 00:30:00.650] [Message Text]
LogLevel [13/10/2015 00:30:00.650] [Message Text]
LogLevel [13/10/2015 00:30:00.650] [Message Text]
LogLevel [13/10/2015 00:30:00.650] [Message Text]"""
#after testing replace StringIO(temp) to filename
df = pd.read_csv(StringIO(temp), sep="\s*\[", names=['Level','Time','Text'], engine='python')
然后通过 strip
and convert column Time
to_datetime
删除 ]
:
df.Time = pd.to_datetime(df.Time.str.strip(']'), format='%d/%m/%Y %H:%M:%S.%f')
df.Text = df.Text.str.strip(']')
print (df)
Level Time Text
0 LogLevel 2015-10-13 00:30:00.650 Message Text
1 LogLevel 2015-10-13 00:30:00.650 Message Text
2 LogLevel 2015-10-13 00:30:00.650 Message Text
3 LogLevel 2015-10-13 00:30:00.650 Message Text
print (df.dtypes)
Level object
Time datetime64[ns]
Text object
dtype: object
我必须手动解析我的分隔符,因为我的分隔符出现在我的消息正文中,并且消息正文也会跨越多行,例如,如果我的 Flask 应用程序抛出异常并记录堆栈跟踪。
这是我的日志创建格式...
logging.basicConfig( filename="%s/%s_MyApp.log" % ( Utilities.logFolder , datetime.datetime.today().strftime("%Y%m%d-%H%M%S")) , level=logging.DEBUG, format="%(asctime)s,%(name)s,%(process)s,%(levelno)u,%(message)s", datefmt="%Y-%m-%d %H:%M:%S" )
以及我的实用程序模块中的解析代码
Utilities.py
import re
import pandas
logFolder = "./Logs"
logLevelToString = { "50" : "CRITICAL",
"40" : "ERROR" ,
"30" : "WARNING" ,
"20" : "INFO" ,
"10" : "DEBUG" ,
"0" : "NOTSET" } # https://docs.python.org/3.6/library/logging.html#logging-levels
def logFile2DataFrame( filePath ) :
dfLog = pandas.DataFrame( columns=[ 'Timestamp' , 'Module' , 'ProcessID' , 'Level' , 'Message' ] )
tsPattern = "^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2},"
with open( filePath , 'r' ) as logFile :
numRows = -1
for line in logFile :
if re.search( tsPattern , line ) :
tokens = line.split(",")
timestamp = tokens[0]
module = tokens[1]
processID = tokens[2]
level = logLevelToString[ tokens[3] ]
message = ",".join( tokens[4:] )
numRows += 1
dfLog.loc[ numRows ] = [ timestamp , module , processID , level , message ]
else :
# Multiline message, integrate it into last record
dfLog.loc[ numRows , 'Message' ] += line
return dfLog
我实际上创建了这个帮助消息,让我可以直接从我的 Flask 应用程序查看我的日志,因为我有一个方便的模板可以呈现 DataFrame。应该加速调试一堆,因为将 flaskapp 封装在 Tornado WSGI 服务器中会阻止在抛出异常时显示从 Flask 可见的正常调试页面。如果有人知道如何在这种情况下恢复该功能,请分享。