File: //usr/syno/sbin/syno_disk_log_convert
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys, os, errno, traceback
import sqlite3
import argparse
from datetime import datetime
def get_real_time(time, logtime):
if logtime < time:
return datetime.fromtimestamp(logtime).strftime('%Y/%m/%d %H:%M:%S')
else:
return datetime.fromtimestamp(time).strftime('%Y/%m/%d %H:%M:%S')
def get_logs(cursor, output=None, before=None, after=None, keywords=None, limit=None):
query = 'SELECT * FROM logs WHERE 1=1'
if before:
query += ' AND time <= {}'.format(int((datetime.strptime(before, '%Y/%m/%d %H:%M:%S') - datetime.fromtimestamp(0)).total_seconds()))
if after:
query += ' AND time >= {}'.format(int((datetime.strptime(after, '%Y/%m/%d %H:%M:%S') - datetime.fromtimestamp(0)).total_seconds()))
if keywords:
query += ' AND (1=2{})'.format(''.join(' OR msg GLOB "*{}*"'.format(k.strip().replace("'", "''")) for k in keywords.split(',')))
query += ' ORDER BY LOGTIME DESC, TIME DESC LIMIT {}'.format(limit if limit else 10000)
with open(output, 'w') if output else sys.stdout as out:
log_text = 'level,\ttime,\tpath,\tmodel,\tserial,\tcontainer,\tslot,\tmsg,\terrtype,\traw,\tinfo,\teunit,\tnote\n'
out.write(log_text)
for row in cursor.execute(query):
try:
log_text = '{level},\t{time},\t{path},\t{model},\t{serial},\t{container},\t{slot},\t{msg},\t{errtype},\t{raw},\t{info},\t{eunit},\t{note}\n'.format(
level = row[2],
time = get_real_time(int(row[1]), int(row[15])),
path = row[3],
model = row[4],
serial = row[5],
container = row[6],
slot = row[7],
msg = row[8],
errtype = row[10],
raw = row[11],
info = row[12],
eunit = row[13],
note = row[14])
out.write(log_text)
except:
traceback.print_exc()
sys.stderr.write('row = {}\n'.format(row))
def main():
parser = argparse.ArgumentParser(description='Convert synolog to human readable format.')
parser.add_argument('database', help='Log database path')
parser.add_argument('-o', '--output', help='Save converted log to specified file.')
parser.add_argument('--after', help='Filter logs that after specified time only. Ex: YY/mm/dd HH:MM/SS')
parser.add_argument('--before', help='Filter logs that before specified time only. Ex: YY/mm/dd HH:MM/SS')
parser.add_argument('-k', '--keywords', help='Filter logs that included specified keywords only. '\
+ 'keywords can be splited by comma. Ex: "Log, FTP"')
parser.add_argument('--limit', help='Limit the number of logs. Default: 10000')
args = parser.parse_args()
if not os.path.exists(args.database):
raise OSError(errno.ENOENT, os.strerror(errno.ENOENT), args.database)
with sqlite3.connect(args.database) as conn:
get_logs(conn.cursor(), output=args.output, before=args.before, after=args.after, keywords=args.keywords, limit=args.limit)
if __name__ == '__main__':
main()